|
21 | 21 | import org.apache.hadoop.thirdparty.com.google.common.collect.ImmutableList; |
22 | 22 | import org.apache.hadoop.thirdparty.com.google.common.collect.LinkedListMultimap; |
23 | 23 | import org.apache.hadoop.thirdparty.com.google.common.collect.Lists; |
| 24 | + |
24 | 25 | import org.apache.hadoop.hdfs.client.HdfsClientConfigKeys; |
25 | 26 | import org.apache.hadoop.hdfs.protocol.SystemErasureCodingPolicies; |
26 | 27 | import org.apache.hadoop.hdfs.server.datanode.DataNodeTestUtils; |
|
94 | 95 | import java.io.IOException; |
95 | 96 | import java.io.InputStreamReader; |
96 | 97 | import java.io.PrintWriter; |
| 98 | +import java.nio.file.Files; |
| 99 | +import java.nio.file.Paths; |
97 | 100 | import java.util.ArrayList; |
98 | 101 | import java.util.Arrays; |
| 102 | +import java.util.Collections; |
99 | 103 | import java.util.EnumSet; |
100 | 104 | import java.util.Iterator; |
101 | 105 | import java.util.LinkedList; |
@@ -144,6 +148,7 @@ public class TestBlockManager { |
144 | 148 | */ |
145 | 149 | private static final int NUM_TEST_ITERS = 30; |
146 | 150 | private static final int BLOCK_SIZE = 64*1024; |
| 151 | + private static final int DN_DIRECTORYSCAN_INTERVAL = 10; |
147 | 152 | private static final org.slf4j.Logger LOG = |
148 | 153 | LoggerFactory.getLogger(TestBlockManager.class); |
149 | 154 |
|
@@ -452,6 +457,71 @@ private void doTestSingleRackClusterHasSufficientRedundancy(int testIndex, |
452 | 457 | assertFalse(bm.isNeededReconstruction(block, |
453 | 458 | bm.countNodes(block, fsn.isInStartupSafeMode()))); |
454 | 459 | } |
| 460 | + |
| 461 | + @Test(timeout = 60000) |
| 462 | + public void testMiniClusterCannotReconstructionWhileReplicaAnomaly() |
| 463 | + throws IOException, InterruptedException, TimeoutException { |
| 464 | + Configuration conf = new HdfsConfiguration(); |
| 465 | + conf.setInt("dfs.datanode.directoryscan.interval", DN_DIRECTORYSCAN_INTERVAL); |
| 466 | + conf.setInt("dfs.namenode.replication.interval", 1); |
| 467 | + conf.setInt("dfs.heartbeat.interval", 1); |
| 468 | + String src = "/test-reconstruction"; |
| 469 | + Path file = new Path(src); |
| 470 | + MiniDFSCluster cluster = new MiniDFSCluster.Builder(conf).numDataNodes(3).build(); |
| 471 | + try { |
| 472 | + cluster.waitActive(); |
| 473 | + FSNamesystem fsn = cluster.getNamesystem(); |
| 474 | + BlockManager bm = fsn.getBlockManager(); |
| 475 | + FSDataOutputStream out = null; |
| 476 | + FileSystem fs = cluster.getFileSystem(); |
| 477 | + try { |
| 478 | + out = fs.create(file); |
| 479 | + for (int i = 0; i < 1024 * 1; i++) { |
| 480 | + out.write(i); |
| 481 | + } |
| 482 | + out.hflush(); |
| 483 | + } finally { |
| 484 | + IOUtils.closeStream(out); |
| 485 | + } |
| 486 | + FSDataInputStream in = null; |
| 487 | + ExtendedBlock oldBlock = null; |
| 488 | + try { |
| 489 | + in = fs.open(file); |
| 490 | + oldBlock = DFSTestUtil.getAllBlocks(in).get(0).getBlock(); |
| 491 | + } finally { |
| 492 | + IOUtils.closeStream(in); |
| 493 | + } |
| 494 | + DataNode dn = cluster.getDataNodes().get(0); |
| 495 | + String blockPath = dn.getFSDataset().getBlockLocalPathInfo(oldBlock).getBlockPath(); |
| 496 | + String metaBlockPath = dn.getFSDataset().getBlockLocalPathInfo(oldBlock).getMetaPath(); |
| 497 | + Files.write(Paths.get(blockPath), Collections.emptyList()); |
| 498 | + Files.write(Paths.get(metaBlockPath), Collections.emptyList()); |
| 499 | + cluster.restartDataNode(0, true); |
| 500 | + cluster.waitDatanodeConnectedToActive(dn, 60000); |
| 501 | + while(!dn.isDatanodeFullyStarted()) { |
| 502 | + Thread.sleep(1000); |
| 503 | + } |
| 504 | + Thread.sleep(DN_DIRECTORYSCAN_INTERVAL * 1000); |
| 505 | + cluster.triggerBlockReports(); |
| 506 | + BlockInfo bi = bm.getStoredBlock(oldBlock.getLocalBlock()); |
| 507 | + boolean isNeededReconstruction = bm.isNeededReconstruction(bi, |
| 508 | + bm.countNodes(bi, cluster.getNamesystem().isInStartupSafeMode())); |
| 509 | + if (isNeededReconstruction) { |
| 510 | + BlockReconstructionWork reconstructionWork = null; |
| 511 | + fsn.readLock(); |
| 512 | + try { |
| 513 | + reconstructionWork = bm.scheduleReconstruction(bi, 3); |
| 514 | + } finally { |
| 515 | + fsn.readUnlock(); |
| 516 | + } |
| 517 | + assertNull(reconstructionWork); |
| 518 | + } |
| 519 | + } finally { |
| 520 | + if (cluster != null) { |
| 521 | + cluster.shutdown(); |
| 522 | + } |
| 523 | + } |
| 524 | + } |
455 | 525 |
|
456 | 526 | @Test(timeout = 60000) |
457 | 527 | public void testNeededReconstructionWhileAppending() throws IOException { |
|
0 commit comments