|
33 | 33 | import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_BLOCK_DELETING_SERVICE_INTERVAL; |
34 | 34 | import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_SCM_BLOCK_SIZE; |
35 | 35 | import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_SCM_BLOCK_SIZE_DEFAULT; |
| 36 | +import static org.apache.hadoop.ozone.OzoneConfigKeys.OZONE_SNAPSHOT_DELETING_SERVICE_INTERVAL; |
36 | 37 | import static org.apache.hadoop.ozone.OzoneConsts.DEFAULT_OM_UPDATE_ID; |
37 | 38 | import static org.apache.hadoop.ozone.OzoneConsts.ETAG; |
38 | 39 | import static org.apache.hadoop.ozone.OzoneConsts.GB; |
|
211 | 212 | import org.junit.jupiter.params.provider.CsvSource; |
212 | 213 | import org.junit.jupiter.params.provider.EnumSource; |
213 | 214 | import org.junit.jupiter.params.provider.MethodSource; |
| 215 | +import org.junit.jupiter.params.provider.ValueSource; |
214 | 216 | import org.slf4j.Logger; |
215 | 217 | import org.slf4j.LoggerFactory; |
216 | 218 |
|
@@ -263,6 +265,7 @@ static void startCluster(OzoneConfiguration conf, MiniOzoneCluster.Builder build |
263 | 265 | conf.setInt(OZONE_SCM_RATIS_PIPELINE_LIMIT, 10); |
264 | 266 | conf.setTimeDuration(OZONE_BLOCK_DELETING_SERVICE_INTERVAL, 1, TimeUnit.SECONDS); |
265 | 267 | conf.setTimeDuration(OZONE_DIR_DELETING_SERVICE_INTERVAL, 1, TimeUnit.SECONDS); |
| 268 | + conf.setTimeDuration(OZONE_SNAPSHOT_DELETING_SERVICE_INTERVAL, 1, TimeUnit.SECONDS); |
266 | 269 |
|
267 | 270 | ClientConfigForTesting.newBuilder(StorageUnit.MB) |
268 | 271 | .setDataStreamMinPacketSize(1) |
@@ -1151,6 +1154,71 @@ public void testDeleteAuditLog() throws Exception { |
1151 | 1154 | ", replicationConfig=EC{rs-3-2-1024k}}\",\"unDeletedKeysList\""); |
1152 | 1155 | } |
1153 | 1156 |
|
| 1157 | + /** |
| 1158 | + * Verifies pendingDelete* fields are populated after key delete, |
| 1159 | + * with/without snapshot retention. |
| 1160 | + * |
| 1161 | + * @param withSnapshot whether to create a snapshot before deleting the key |
| 1162 | + * @throws Exception on failure |
| 1163 | + */ |
| 1164 | + @ParameterizedTest |
| 1165 | + @ValueSource(booleans = {false, true}) |
| 1166 | + public void testBucketPendingDeleteBytes(boolean withSnapshot) throws Exception { |
| 1167 | + String volumeName = UUID.randomUUID().toString(); |
| 1168 | + String bucketName = UUID.randomUUID().toString(); |
| 1169 | + String keyName = UUID.randomUUID().toString(); |
| 1170 | + String snapshotName = "snap-" + UUID.randomUUID(); |
| 1171 | + String value = "sample value"; |
| 1172 | + int valueLength = value.getBytes(UTF_8).length; |
| 1173 | + |
| 1174 | + store.createVolume(volumeName); |
| 1175 | + OzoneVolume volume = store.getVolume(volumeName); |
| 1176 | + volume.createBucket(bucketName); |
| 1177 | + OzoneBucket bucket = volume.getBucket(bucketName); |
| 1178 | + |
| 1179 | + writeKey(bucket, keyName, ONE, value, valueLength); |
| 1180 | + |
| 1181 | + OzoneBucket bucketAfterKeyWrite = store.getVolume(volumeName) |
| 1182 | + .getBucket(bucketName); |
| 1183 | + assertThat(bucketAfterKeyWrite.getUsedBytes()).isEqualTo(valueLength); |
| 1184 | + assertThat(bucketAfterKeyWrite.getUsedNamespace()).isEqualTo(1); |
| 1185 | + assertThat(bucketAfterKeyWrite.getPendingDeleteBytes()).isEqualTo(0); |
| 1186 | + assertThat(bucketAfterKeyWrite.getPendingDeleteNamespace()).isEqualTo(0); |
| 1187 | + |
| 1188 | + if (withSnapshot) { |
| 1189 | + store.createSnapshot(volumeName, bucketName, snapshotName); |
| 1190 | + } |
| 1191 | + bucket.deleteKey(keyName); |
| 1192 | + // After delete: usedBytes should still be totalBucketSpace. |
| 1193 | + OzoneBucket bucketAfterKeyDelete = store.getVolume(volumeName) |
| 1194 | + .getBucket(bucketName); |
| 1195 | + assertThat(bucketAfterKeyDelete.getUsedBytes()).isEqualTo(valueLength); |
| 1196 | + assertThat(bucketAfterKeyDelete.getUsedNamespace()).isEqualTo(1); |
| 1197 | + assertThat(bucketAfterKeyDelete.getPendingDeleteBytes()).isEqualTo(valueLength); |
| 1198 | + assertThat(bucketAfterKeyDelete.getPendingDeleteNamespace()).isEqualTo(1); |
| 1199 | + |
| 1200 | + if (withSnapshot) { |
| 1201 | + // if snapshot is present bytes won't be released until snapshot is deleted. |
| 1202 | + store.deleteSnapshot(volumeName, bucketName, snapshotName); |
| 1203 | + } |
| 1204 | + |
| 1205 | + GenericTestUtils.waitFor(() -> { |
| 1206 | + OzoneBucket buck = null; |
| 1207 | + try { |
| 1208 | + buck = store.getVolume(volumeName).getBucket(bucketName); |
| 1209 | + } catch (IOException e) { |
| 1210 | + fail("Failed to get bucket details", e); |
| 1211 | + } |
| 1212 | + return buck.getUsedBytes() == 0 && buck.getUsedNamespace() == 0; |
| 1213 | + }, 1000, 30000); |
| 1214 | + OzoneBucket bucketAfterKeyPurge = store.getVolume(volumeName) |
| 1215 | + .getBucket(bucketName); |
| 1216 | + assertThat(bucketAfterKeyPurge.getUsedBytes()).isEqualTo(0); |
| 1217 | + assertThat(bucketAfterKeyPurge.getUsedNamespace()).isEqualTo(0); |
| 1218 | + assertThat(bucketAfterKeyPurge.getPendingDeleteBytes()).isEqualTo(0); |
| 1219 | + assertThat(bucketAfterKeyPurge.getPendingDeleteNamespace()).isEqualTo(0); |
| 1220 | + } |
| 1221 | + |
1154 | 1222 | protected void verifyReplication(String volumeName, String bucketName, |
1155 | 1223 | String keyName, ReplicationConfig replication) |
1156 | 1224 | throws IOException { |
|
0 commit comments