1818
1919package org .apache .hadoop .hdfs .server .namenode ;
2020
21+ import static org .junit .Assert .*;
22+
2123import java .io .BufferedReader ;
2224import java .io .ByteArrayOutputStream ;
2325import java .io .File ;
2426import java .io .FileReader ;
2527import java .io .IOException ;
2628import java .io .PrintStream ;
29+ import java .io .PrintWriter ;
2730import java .io .RandomAccessFile ;
31+ import java .io .StringWriter ;
32+ import java .io .Writer ;
33+ import java .net .InetAddress ;
2834import java .net .InetSocketAddress ;
2935import java .nio .channels .FileChannel ;
3036import java .security .PrivilegedExceptionAction ;
37+ import java .util .HashMap ;
38+ import java .util .Map ;
3139import java .util .Random ;
3240import java .util .regex .Pattern ;
3341
34- import junit .framework .TestCase ;
35-
3642import org .apache .commons .logging .impl .Log4JLogger ;
3743import org .apache .hadoop .conf .Configuration ;
3844import org .apache .hadoop .fs .FSDataOutputStream ;
4248import org .apache .hadoop .hdfs .DFSClient ;
4349import org .apache .hadoop .hdfs .DFSConfigKeys ;
4450import org .apache .hadoop .hdfs .DFSTestUtil ;
51+ import org .apache .hadoop .hdfs .DistributedFileSystem ;
4552import org .apache .hadoop .hdfs .HdfsConfiguration ;
4653import org .apache .hadoop .hdfs .MiniDFSCluster ;
47- import org .apache .hadoop .hdfs .protocol .ExtendedBlock ;
4854import org .apache .hadoop .hdfs .protocol .CorruptFileBlocks ;
55+ import org .apache .hadoop .hdfs .protocol .ExtendedBlock ;
56+ import org .apache .hadoop .hdfs .protocol .HdfsFileStatus ;
4957import org .apache .hadoop .hdfs .protocol .LocatedBlocks ;
58+ import org .apache .hadoop .hdfs .server .namenode .NamenodeFsck .Result ;
5059import org .apache .hadoop .hdfs .server .protocol .NamenodeProtocols ;
5160import org .apache .hadoop .hdfs .tools .DFSck ;
5261import org .apache .hadoop .io .IOUtils ;
62+ import org .apache .hadoop .net .NetworkTopology ;
5363import org .apache .hadoop .security .UserGroupInformation ;
5464import org .apache .hadoop .util .ToolRunner ;
5565import org .apache .log4j .Level ;
5666import org .apache .log4j .Logger ;
5767import org .apache .log4j .PatternLayout ;
5868import org .apache .log4j .RollingFileAppender ;
69+ import org .junit .Test ;
5970
6071/**
6172 * A JUnit test for doing fsck
6273 */
63- public class TestFsck extends TestCase {
74+ public class TestFsck {
6475 static final String auditLogFile = System .getProperty ("test.build.dir" ,
6576 "build/test" ) + "/audit.log" ;
6677
@@ -79,13 +90,15 @@ static String runFsck(Configuration conf, int expectedErrCode,
7990 PrintStream out = new PrintStream (bStream , true );
8091 ((Log4JLogger )FSPermissionChecker .LOG ).getLogger ().setLevel (Level .ALL );
8192 int errCode = ToolRunner .run (new DFSck (conf , out ), path );
82- if (checkErrorCode )
93+ if (checkErrorCode ) {
8394 assertEquals (expectedErrCode , errCode );
95+ }
8496 ((Log4JLogger )FSPermissionChecker .LOG ).getLogger ().setLevel (Level .INFO );
8597 return bStream .toString ();
8698 }
8799
88100 /** do fsck */
101+ @ Test
89102 public void testFsck () throws Exception {
90103 DFSTestUtil util = new DFSTestUtil ("TestFsck" , 20 , 3 , 8 *1024 );
91104 MiniDFSCluster cluster = null ;
@@ -158,6 +171,7 @@ private void verifyAuditLogs() throws IOException {
158171 assertNull ("Unexpected event in audit log" , reader .readLine ());
159172 }
160173
174+ @ Test
161175 public void testFsckNonExistent () throws Exception {
162176 DFSTestUtil util = new DFSTestUtil ("TestFsck" , 20 , 3 , 8 *1024 );
163177 MiniDFSCluster cluster = null ;
@@ -180,6 +194,7 @@ public void testFsckNonExistent() throws Exception {
180194 }
181195
182196 /** Test fsck with permission set on inodes */
197+ @ Test
183198 public void testFsckPermission () throws Exception {
184199 final DFSTestUtil util = new DFSTestUtil (getClass ().getSimpleName (), 20 , 3 , 8 *1024 );
185200 final Configuration conf = new HdfsConfiguration ();
@@ -227,6 +242,7 @@ public Object run() throws Exception {
227242 }
228243 }
229244
245+ @ Test
230246 public void testFsckMoveAndDelete () throws Exception {
231247 final int MAX_MOVE_TRIES = 5 ;
232248 DFSTestUtil util = new DFSTestUtil ("TestFsck" , 5 , 3 , 8 *1024 );
@@ -300,6 +316,7 @@ public void testFsckMoveAndDelete() throws Exception {
300316 }
301317 }
302318
319+ @ Test
303320 public void testFsckOpenFiles () throws Exception {
304321 DFSTestUtil util = new DFSTestUtil ("TestFsck" , 4 , 3 , 8 *1024 );
305322 MiniDFSCluster cluster = null ;
@@ -350,6 +367,7 @@ public void testFsckOpenFiles() throws Exception {
350367 }
351368 }
352369
370+ @ Test
353371 public void testCorruptBlock () throws Exception {
354372 Configuration conf = new HdfsConfiguration ();
355373 conf .setLong (DFSConfigKeys .DFS_BLOCKREPORT_INTERVAL_MSEC_KEY , 1000 );
@@ -426,6 +444,7 @@ public void testCorruptBlock() throws Exception {
426444 *
427445 * @throws Exception
428446 */
447+ @ Test
429448 public void testFsckError () throws Exception {
430449 MiniDFSCluster cluster = null ;
431450 try {
@@ -460,6 +479,7 @@ public void testFsckError() throws Exception {
460479 }
461480
462481 /** check if option -list-corruptfiles of fsck command works properly */
482+ @ Test
463483 public void testFsckListCorruptFilesBlocks () throws Exception {
464484 Configuration conf = new Configuration ();
465485 conf .setLong (DFSConfigKeys .DFS_BLOCKREPORT_INTERVAL_MSEC_KEY , 1000 );
@@ -529,6 +549,7 @@ public void testFsckListCorruptFilesBlocks() throws Exception {
529549 * Test for checking fsck command on illegal arguments should print the proper
530550 * usage.
531551 */
552+ @ Test
532553 public void testToCheckTheFsckCommandOnIllegalArguments () throws Exception {
533554 MiniDFSCluster cluster = null ;
534555 try {
@@ -560,4 +581,73 @@ public void testToCheckTheFsckCommandOnIllegalArguments() throws Exception {
560581 }
561582 }
562583 }
584+
585+ /**
586+ * Tests that the # of missing block replicas and expected replicas is correct
587+ * @throws IOException
588+ */
589+ @ Test
590+ public void testFsckMissingReplicas () throws IOException {
591+ // Desired replication factor
592+ // Set this higher than NUM_REPLICAS so it's under-replicated
593+ final short REPL_FACTOR = 2 ;
594+ // Number of replicas to actually start
595+ final short NUM_REPLICAS = 1 ;
596+ // Number of blocks to write
597+ final short NUM_BLOCKS = 3 ;
598+ // Set a small-ish blocksize
599+ final long blockSize = 512 ;
600+
601+ Configuration conf = new Configuration ();
602+ conf .setLong (DFSConfigKeys .DFS_BLOCK_SIZE_KEY , blockSize );
603+
604+ MiniDFSCluster cluster = null ;
605+ DistributedFileSystem dfs = null ;
606+
607+ try {
608+ // Startup a minicluster
609+ cluster =
610+ new MiniDFSCluster .Builder (conf ).numDataNodes (NUM_REPLICAS ).build ();
611+ assertNotNull ("Failed Cluster Creation" , cluster );
612+ cluster .waitClusterUp ();
613+ dfs = (DistributedFileSystem ) cluster .getFileSystem ();
614+ assertNotNull ("Failed to get FileSystem" , dfs );
615+
616+ // Create a file that will be intentionally under-replicated
617+ final String pathString = new String ("/testfile" );
618+ final Path path = new Path (pathString );
619+ long fileLen = blockSize * NUM_BLOCKS ;
620+ DFSTestUtil .createFile (dfs , path , fileLen , REPL_FACTOR , 1 );
621+
622+ // Create an under-replicated file
623+ NameNode namenode = cluster .getNameNode ();
624+ NetworkTopology nettop = cluster .getNamesystem ().getBlockManager ()
625+ .getDatanodeManager ().getNetworkTopology ();
626+ Map <String ,String []> pmap = new HashMap <String , String []>();
627+ Writer result = new StringWriter ();
628+ PrintWriter out = new PrintWriter (result , true );
629+ InetAddress remoteAddress = InetAddress .getLocalHost ();
630+ NamenodeFsck fsck = new NamenodeFsck (conf , namenode , nettop , pmap , out ,
631+ NUM_REPLICAS , (short )1 , remoteAddress );
632+
633+ // Run the fsck and check the Result
634+ final HdfsFileStatus file =
635+ namenode .getRpcServer ().getFileInfo (pathString );
636+ assertNotNull (file );
637+ Result res = new Result (conf );
638+ fsck .check (pathString , file , res );
639+ // Also print the output from the fsck, for ex post facto sanity checks
640+ System .out .println (result .toString ());
641+ assertEquals (res .missingReplicas ,
642+ (NUM_BLOCKS *REPL_FACTOR ) - (NUM_BLOCKS *NUM_REPLICAS ));
643+ assertEquals (res .numExpectedReplicas , NUM_BLOCKS *REPL_FACTOR );
644+ } finally {
645+ if (dfs != null ) {
646+ dfs .close ();
647+ }
648+ if (cluster != null ) {
649+ cluster .shutdown ();
650+ }
651+ }
652+ }
563653}
0 commit comments