/* * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0 * (the "License"). You may not use this work except in compliance with the License, which is * available at www.apache.org/licenses/LICENSE-2.0 * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or implied, as more fully set forth in the License. * * See the NOTICE file distributed with this work for information regarding copyright ownership. */ package alluxio.client; import alluxio.AlluxioURI; import alluxio.IntegrationTestUtils; import alluxio.LocalAlluxioClusterResource; import alluxio.PropertyKey; import alluxio.BaseIntegrationTest; import alluxio.client.file.FileOutStream; import alluxio.client.file.FileSystem; import alluxio.client.file.URIStatus; import alluxio.client.file.options.CreateFileOptions; import alluxio.exception.FileDoesNotExistException; import alluxio.heartbeat.HeartbeatContext; import alluxio.heartbeat.HeartbeatScheduler; import alluxio.heartbeat.ManuallyScheduleHeartbeat; import alluxio.master.block.BlockMaster; import alluxio.master.file.meta.PersistenceState; import alluxio.util.io.PathUtils; import alluxio.wire.BlockInfo; import alluxio.worker.block.BlockWorker; import org.junit.Assert; import org.junit.Before; import org.junit.ClassRule; import org.junit.Rule; import org.junit.Test; import java.util.concurrent.TimeUnit; /** * Integration tests for file free and delete with under storage persisted. * */ public final class FreeAndDeleteIntegrationTest extends BaseIntegrationTest { private static final int USER_QUOTA_UNIT_BYTES = 1000; @ClassRule public static ManuallyScheduleHeartbeat sManuallySchedule = new ManuallyScheduleHeartbeat( HeartbeatContext.WORKER_BLOCK_SYNC, HeartbeatContext.MASTER_LOST_FILES_DETECTION); @Rule public LocalAlluxioClusterResource mLocalAlluxioClusterResource = new LocalAlluxioClusterResource.Builder() .setProperty(PropertyKey.USER_FILE_BUFFER_BYTES, USER_QUOTA_UNIT_BYTES) .build(); private FileSystem mFileSystem = null; private CreateFileOptions mWriteBoth; @Before public final void before() throws Exception { mFileSystem = mLocalAlluxioClusterResource.get().getClient(); mWriteBoth = CreateFileOptions.defaults().setWriteType(WriteType.CACHE_THROUGH); } @Test public void freeAndDeleteIntegration() throws Exception { HeartbeatScheduler.await(HeartbeatContext.WORKER_BLOCK_SYNC, 5, TimeUnit.SECONDS); HeartbeatScheduler.await(HeartbeatContext.MASTER_LOST_FILES_DETECTION, 5, TimeUnit.SECONDS); AlluxioURI filePath = new AlluxioURI(PathUtils.uniqPath()); FileOutStream os = mFileSystem.createFile(filePath, mWriteBoth); os.write((byte) 0); os.write((byte) 1); os.close(); URIStatus status = mFileSystem.getStatus(filePath); Assert.assertEquals(PersistenceState.PERSISTED.toString(), status.getPersistenceState()); final Long blockId = status.getBlockIds().get(0); BlockMaster bm = mLocalAlluxioClusterResource.get().getLocalAlluxioMaster().getMasterProcess() .getMaster(BlockMaster.class); BlockInfo blockInfo = bm.getBlockInfo(blockId); Assert.assertEquals(2, blockInfo.getLength()); Assert.assertFalse(blockInfo.getLocations().isEmpty()); final BlockWorker bw = mLocalAlluxioClusterResource.get().getWorkerProcess().getWorker(BlockWorker.class); Assert.assertTrue(bw.hasBlockMeta(blockId)); Assert.assertTrue(bm.getLostBlocks().isEmpty()); mFileSystem.free(filePath); IntegrationTestUtils.waitForBlocksToBeFreed(bw, blockId); status = mFileSystem.getStatus(filePath); // Verify block metadata in master is still present after block freed. Assert.assertEquals(1, status.getBlockIds().size()); blockInfo = bm.getBlockInfo(status.getBlockIds().get(0)); Assert.assertEquals(2, blockInfo.getLength()); // Verify the block has been removed from all workers. Assert.assertTrue(blockInfo.getLocations().isEmpty()); Assert.assertFalse(bw.hasBlockMeta(blockId)); // Verify the removed block is added to LostBlocks list. Assert.assertTrue(bm.getLostBlocks().contains(blockInfo.getBlockId())); mFileSystem.delete(filePath); try { // File is immediately gone after delete. mFileSystem.getStatus(filePath); Assert.fail(String.format("Expected file %s being deleted but it was not.", filePath)); } catch (FileDoesNotExistException e) { // expected } // Execute the lost files detection. HeartbeatScheduler.execute(HeartbeatContext.MASTER_LOST_FILES_DETECTION); // Verify the blocks are not in mLostBlocks. Assert.assertTrue(bm.getLostBlocks().isEmpty()); } }