Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1539,7 +1539,10 @@ private void deleteInternal(Container container, boolean force)
}
// Avoid holding write locks for disk operations
sendICR(container);
long bytesUsed = container.getContainerData().getBytesUsed();
HddsVolume volume = container.getContainerData().getVolume();
container.delete();
volume.decrementUsedSpace(bytesUsed);
}

private void triggerVolumeScanAndThrowException(Container container,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.doCallRealMethod;
import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -432,6 +433,60 @@ public void testDeleteContainer() throws IOException {
}
}

/**
* Tests that deleting a container decrements the cached used space of its volume.
*/
@Test
public void testDeleteDecrementsVolumeUsedSpace() throws IOException {
final long containerID = 1;
final String clusterId = UUID.randomUUID().toString();
final String datanodeId = UUID.randomUUID().toString();
final ContainerSet containerSet = newContainerSet();
final MutableVolumeSet volumeSet = mock(MutableVolumeSet.class);
final HddsVolume hddsVolume = mock(HddsVolume.class);
when(hddsVolume.getDeletedContainerDir()).thenReturn(new File(""));

final ConfigurationSource conf = new OzoneConfiguration();
final ContainerMetrics metrics = ContainerMetrics.create(conf);
final AtomicInteger icrReceived = new AtomicInteger(0);
final long containerBytesUsed = 1024 * 1024;

// We're testing KeyValueHandler in this test, all the other objects are mocked
final KeyValueHandler kvHandler = new KeyValueHandler(conf,
datanodeId, containerSet, volumeSet, metrics,
c -> icrReceived.incrementAndGet());
kvHandler.setClusterID(clusterId);

// Setup ContainerData and Container mocks
KeyValueContainerData containerData = mock(KeyValueContainerData.class);
when(containerData.getContainerID()).thenReturn(containerID);
when(containerData.getVolume()).thenReturn(hddsVolume);
when(containerData.getBytesUsed()).thenReturn(containerBytesUsed);
when(containerData.getState()).thenReturn(ContainerProtos.ContainerDataProto.State.CLOSED);
when(containerData.isOpen()).thenReturn(false);
when(containerData.getLayoutVersion()).thenReturn(ContainerLayoutVersion.FILE_PER_BLOCK);
when(containerData.getDbFile()).thenReturn(new File(tempDir.toFile(), "dummy.db"));
when(containerData.getContainerPath()).thenReturn(tempDir.toString());
when(containerData.getMetadataPath()).thenReturn(tempDir.toString());

KeyValueContainer container = mock(KeyValueContainer.class);
when(container.getContainerData()).thenReturn(containerData);
when(container.hasBlocks()).thenReturn(true);

containerSet.addContainer(container);
assertNotNull(containerSet.getContainer(containerID));

// This is the method we're testing. It should decrement used space in the volume when deleting this container
kvHandler.deleteContainer(container, true);
assertNull(containerSet.getContainer(containerID));

// Verify ICR was sent (once for delete)
assertEquals(1, icrReceived.get(), "ICR should be sent for delete");
verify(container, times(1)).delete();
// Verify decrementUsedSpace was called with the correct amount
verify(hddsVolume, times(1)).decrementUsedSpace(eq(containerBytesUsed));
}

@Test
public void testDeleteContainerTimeout() throws IOException {
final String testDir = tempDir.toString();
Expand Down