Source:
<code>public void testMigration() throws InterruptedException { final ExecutorService executor = Executors.newFixedThreadPool(NUM_THREAD); final AtomicInteger operationIdCounter = new AtomicInteger(0); final CountDownLatch movedLatch = new CountDownLatch(2 * NUM_REQUESTS); final FinishedCallback finishedCallback0 = new FinishedCallback(movedLatch); final FinishedCallback finishedCallback1 = new FinishedCallback(movedLatch); final int numInitBlocksIn0 = blockManager.getNumBlocks(EVAL_PREFIX + 0); final int numInitBlocksIn1 = blockManager.getNumBlocks(EVAL_PREFIX + 1); for (int i = 0; i < NUM_REQUESTS; i++) { final int numBlocksInSrcEval = blockManager.getNumBlocks(EVAL_PREFIX + 0); final int numBlocksToMove = numBlocksInSrcEval / NUM_REQUESTS; executor.execute(new MigrationThread(operationIdCounter.getAndIncrement(), EVAL_PREFIX + 0, EVAL_PREFIX + 1, numBlocksToMove, finishedCallback0, migrationManager)); } for (int i = 0; i < NUM_REQUESTS; i++) { final int numBlocksInSrcEval = blockManager.getNumBlocks(EVAL_PREFIX + 1); final int numBlocksToMove = numBlocksInSrcEval / NUM_REQUESTS; executor.execute(new MigrationThread(operationIdCounter.getAndIncrement(), EVAL_PREFIX + 1, EVAL_PREFIX + 0, numBlocksToMove, finishedCallback1, migrationManager)); } <START> assertTrue("Move does not finish within time", movedLatch.await(20000, TimeUnit.MILLISECONDS)); <END> final int numMovedBlocksFrom0To1 = finishedCallback0.getNumMovedBlocks(); final int numMovedBlocksFrom1To0 = finishedCallback1.getNumMovedBlocks(); final int numBlocksIn0 = numInitBlocksIn0 + numMovedBlocksFrom1To0 - numMovedBlocksFrom0To1; final int numBlocksIn1 = numInitBlocksIn1 + numMovedBlocksFrom0To1 - numMovedBlocksFrom1To0; assertEquals("The number of blocks are different from expectation", numBlocksIn0, blockManager.getNumBlocks(EVAL_PREFIX + 0)); assertEquals("The number of blocks are different from expectation", numBlocksIn1, blockManager.getNumBlocks(EVAL_PREFIX + 1)); }</code><technical_language>good mention movedLatch is countdown</technical_language>

Target:
public void testMigration() throws InterruptedException { final ExecutorService executor = Executors.newFixedThreadPool(NUM_THREAD); final AtomicInteger operationIdCounter = new AtomicInteger(0); final CountDownLatch movedLatch = new CountDownLatch(2 * NUM_REQUESTS_PER_EVAL); final FinishedCallback finishedCallback0 = new FinishedCallback(movedLatch); final FinishedCallback finishedCallback1 = new FinishedCallback(movedLatch); final int numInitBlocksIn0 = blockManager.getNumBlocks(EVAL_PREFIX + 0); final int numInitBlocksIn1 = blockManager.getNumBlocks(EVAL_PREFIX + 1); for (int i = 0; i < NUM_REQUESTS_PER_EVAL; i++) { final int numBlocksInSrcEval0 = blockManager.getNumBlocks(EVAL_PREFIX + 0); final int numBlocksInSrcEval1 = blockManager.getNumBlocks(EVAL_PREFIX + 1); final int numBlocksToMoveFromEval0 = numBlocksInSrcEval0 / NUM_REQUESTS_PER_EVAL; final int numBlocksToMoveFromEval1 = numBlocksInSrcEval1 / NUM_REQUESTS_PER_EVAL; executor.execute(new MigrationThread(operationIdCounter.getAndIncrement(), EVAL_PREFIX + 0, EVAL_PREFIX + 1, numBlocksToMoveFromEval0, finishedCallback0, migrationManager)); executor.execute(new MigrationThread(operationIdCounter.getAndIncrement(), EVAL_PREFIX + 1, EVAL_PREFIX + 0, numBlocksToMoveFromEval1, finishedCallback1, migrationManager)); } assertTrue("Move does not finish within time", movedLatch.await(20000, TimeUnit.MILLISECONDS)); final int numMovedBlocksFrom0To1 = finishedCallback0.getNumMovedBlocks(); final int numMovedBlocksFrom1To0 = finishedCallback1.getNumMovedBlocks(); final int numBlocksIn0 = numInitBlocksIn0 + numMovedBlocksFrom1To0 - numMovedBlocksFrom0To1; final int numBlocksIn1 = numInitBlocksIn1 + numMovedBlocksFrom0To1 - numMovedBlocksFrom1To0; assertEquals("The number of blocks is different from expectation", numBlocksIn0, blockManager.getNumBlocks(EVAL_PREFIX + 0)); assertEquals("The number of blocks is different from expectation", numBlocksIn1, blockManager.getNumBlocks(EVAL_PREFIX + 1)); }