|
35 | 35 | import java.util.Set; |
36 | 36 | import java.util.UUID; |
37 | 37 | import org.apache.hadoop.hdds.conf.OzoneConfiguration; |
| 38 | +import org.apache.hadoop.hdds.conf.StorageUnit; |
38 | 39 | import org.apache.hadoop.hdds.fs.MockSpaceUsageCheckFactory; |
39 | 40 | import org.apache.hadoop.hdds.fs.MockSpaceUsageSource; |
40 | 41 | import org.apache.hadoop.hdds.fs.SpaceUsageCheckFactory; |
41 | 42 | import org.apache.hadoop.hdds.fs.SpaceUsagePersistence; |
42 | 43 | import org.apache.hadoop.hdds.fs.SpaceUsageSource; |
43 | 44 | import org.apache.hadoop.hdds.protocol.datanode.proto.ContainerProtos.ContainerDataProto; |
| 45 | +import org.apache.hadoop.hdds.scm.ScmConfigKeys; |
44 | 46 | import org.apache.hadoop.hdds.scm.container.ContainerID; |
45 | 47 | import org.apache.hadoop.ozone.container.common.impl.ContainerData; |
46 | 48 | import org.apache.hadoop.ozone.container.common.impl.ContainerLayoutVersion; |
@@ -154,14 +156,7 @@ private HddsVolume createVolume(String dir, double utilization) |
154 | 156 | */ |
155 | 157 | private void createContainer(long id, long size, HddsVolume vol) |
156 | 158 | throws IOException { |
157 | | - KeyValueContainerData containerData = new KeyValueContainerData(id, |
158 | | - ContainerLayoutVersion.FILE_PER_BLOCK, size, |
159 | | - UUID.randomUUID().toString(), UUID.randomUUID().toString()); |
160 | | - containerData.setState(ContainerDataProto.State.CLOSED); |
161 | | - containerData.setVolume(vol); |
162 | | - containerData.getStatistics().setBlockBytesForTesting(size); |
163 | | - KeyValueContainer container = new KeyValueContainer(containerData, CONF); |
164 | | - containerSet.addContainer(container); |
| 159 | + createContainer(id, size, vol, containerSet); |
165 | 160 | } |
166 | 161 |
|
167 | 162 | @Test |
@@ -200,4 +195,56 @@ public void testContainerNotChosen() { |
200 | 195 | // No containers should not be chosen |
201 | 196 | assertNull(chosenContainer); |
202 | 197 | } |
| 198 | + |
| 199 | + @Test |
| 200 | + public void testSizeZeroContainersSkipped() throws IOException { |
| 201 | + // Create a new container set with containers that have size 0 |
| 202 | + ContainerSet testContainerSet = newContainerSet(); |
| 203 | + |
| 204 | + // Create containers with size 0 (should be skipped) |
| 205 | + createContainer(10L, 0L, sourceVolume, testContainerSet); |
| 206 | + createContainer(11L, 0L, sourceVolume, testContainerSet); |
| 207 | + |
| 208 | + // Create a container with non-zero size (should be chosen) |
| 209 | + createContainer(12L, 200L * MB, sourceVolume, testContainerSet); |
| 210 | + |
| 211 | + // Mock OzoneContainer to return our test container set |
| 212 | + OzoneContainer testOzoneContainer = mock(OzoneContainer.class); |
| 213 | + ContainerController testController = new ContainerController(testContainerSet, null); |
| 214 | + when(testOzoneContainer.getController()).thenReturn(testController); |
| 215 | + |
| 216 | + // The policy should skip containers 10 and 11 (size 0) and choose container 12 |
| 217 | + ContainerData chosenContainer = policy.chooseContainer(testOzoneContainer, |
| 218 | + sourceVolume, destVolume1, inProgressContainerIDs, THRESHOLD, volumeSet, deltaMap); |
| 219 | + |
| 220 | + // Container 12 (non-zero size) should be chosen, skipping containers 10 and 11 (size 0) |
| 221 | + assertNotNull(chosenContainer); |
| 222 | + assertEquals(12L, chosenContainer.getContainerID()); |
| 223 | + assertEquals(200L * MB, chosenContainer.getBytesUsed()); |
| 224 | + } |
| 225 | + |
| 226 | + /** |
| 227 | + * Create KeyValueContainers and add it to the specified containerSet. |
| 228 | + * @param id container ID |
| 229 | + * @param usedBytes bytes used by the container (can be 0) |
| 230 | + * @param vol volume where container is located |
| 231 | + * @param targetContainerSet container set to add the container to |
| 232 | + */ |
| 233 | + private void createContainer(long id, long usedBytes, HddsVolume vol, |
| 234 | + ContainerSet targetContainerSet) throws IOException { |
| 235 | + // Use maxSize as the container capacity (must be > 0) |
| 236 | + // If usedBytes is 0, we still need a valid maxSize for container creation |
| 237 | + long maxSize = usedBytes > 0 ? usedBytes : (long) CONF.getStorageSize( |
| 238 | + ScmConfigKeys.OZONE_SCM_CONTAINER_SIZE, |
| 239 | + ScmConfigKeys.OZONE_SCM_CONTAINER_SIZE_DEFAULT, StorageUnit.BYTES); |
| 240 | + KeyValueContainerData containerData = new KeyValueContainerData(id, |
| 241 | + ContainerLayoutVersion.FILE_PER_BLOCK, maxSize, |
| 242 | + UUID.randomUUID().toString(), UUID.randomUUID().toString()); |
| 243 | + containerData.setState(ContainerDataProto.State.CLOSED); |
| 244 | + containerData.setVolume(vol); |
| 245 | + // Set the actual used bytes (can be 0) |
| 246 | + containerData.getStatistics().setBlockBytesForTesting(usedBytes); |
| 247 | + KeyValueContainer container = new KeyValueContainer(containerData, CONF); |
| 248 | + targetContainerSet.addContainer(container); |
| 249 | + } |
203 | 250 | } |
0 commit comments