2121import org .apache .hadoop .fs .Path ;
2222import org .apache .hadoop .hdfs .DistributedFileSystem ;
2323import org .apache .hadoop .hdfs .MiniDFSCluster ;
24+ import org .apache .hadoop .hdfs .server .common .Storage ;
25+ import org .apache .hadoop .hdfs .server .namenode .FSImage ;
26+ import org .apache .hadoop .hdfs .server .namenode .FSImageTestUtil ;
27+ import org .apache .hadoop .hdfs .server .namenode .FSNamesystem ;
28+ import org .apache .hadoop .hdfs .server .namenode .NNStorage ;
29+ import org .apache .hadoop .hdfs .server .namenode .FSEditLogOpCodes ;
30+ import org .apache .hadoop .hdfs .util .Holder ;
2431import org .apache .hadoop .test .GenericTestUtils ;
2532import org .junit .After ;
2633import org .junit .Assert ;
2734import org .junit .Before ;
2835import org .junit .Test ;
2936import org .slf4j .event .Level ;
3037
38+ import java .io .File ;
3139import java .io .FileNotFoundException ;
3240import java .io .IOException ;
33- import java .util .ArrayList ;
3441import java .util .Arrays ;
3542import java .util .Collections ;
3643import java .util .Iterator ;
3744import java .util .List ;
3845import java .util .Random ;
46+ import java .util .EnumMap ;
47+ import java .util .ArrayList ;
3948
4049import static org .apache .hadoop .hdfs .server .namenode .snapshot .SnapshotManager .DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED ;
4150import static org .apache .hadoop .hdfs .server .namenode .snapshot .SnapshotManager .DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED_GC_PERIOD_MS ;
4251import static org .apache .hadoop .hdfs .server .namenode .snapshot .TestOrderedSnapshotDeletion .assertMarkedAsDeleted ;
4352import static org .apache .hadoop .hdfs .server .namenode .snapshot .TestOrderedSnapshotDeletion .assertNotMarkedAsDeleted ;
53+ import static org .junit .Assert .assertEquals ;
54+ import static org .junit .Assert .assertTrue ;
4455
4556/**
4657 * Test {@link SnapshotDeletionGc}.
4758 */
4859public class TestOrderedSnapshotDeletionGc {
4960 private static final int GC_PERIOD = 10 ;
50-
61+ private static final int NUM_DATANODES = 0 ;
5162 private MiniDFSCluster cluster ;
5263
5364 @ Before
@@ -56,7 +67,8 @@ public void setUp() throws Exception {
5667 conf .setBoolean (DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED , true );
5768 conf .setInt (DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED_GC_PERIOD_MS , GC_PERIOD );
5869
59- cluster = new MiniDFSCluster .Builder (conf ).numDataNodes (0 ).build ();
70+ cluster = new MiniDFSCluster .Builder (conf ).numDataNodes (NUM_DATANODES )
71+ .build ();
6072 cluster .waitActive ();
6173
6274 GenericTestUtils .setLogLevel (SnapshotDeletionGc .LOG , Level .TRACE );
@@ -117,6 +129,38 @@ public void testSingleDir() throws Exception {
117129 Assert .assertFalse (exist (s0path , hdfs ));
118130
119131 waitForGc (Arrays .asList (s1path , s2path ), hdfs );
132+ // total no of edit log records created for delete snapshot will be equal
133+ // to sum of no of user deleted snapshots and no of snapshots gc'ed with
134+ // snapshotDeletion gc thread
135+ doEditLogValidation (cluster , 5 );
136+ }
137+
138+ static void doEditLogValidation (MiniDFSCluster cluster ,
139+ int editLogOpCount ) throws Exception {
140+ final FSNamesystem namesystem = cluster .getNamesystem ();
141+ Configuration conf = cluster .getNameNode ().getConf ();
142+ FSImage fsimage = namesystem .getFSImage ();
143+ Storage .StorageDirectory sd = fsimage .getStorage ().
144+ dirIterator (NNStorage .NameNodeDirType .EDITS ).next ();
145+ cluster .shutdown ();
146+
147+ File editFile = FSImageTestUtil .findLatestEditsLog (sd ).getFile ();
148+ assertTrue ("Should exist: " + editFile , editFile .exists ());
149+ EnumMap <FSEditLogOpCodes , Holder <Integer >> counts ;
150+ counts = FSImageTestUtil .countEditLogOpTypes (editFile );
151+ if (editLogOpCount > 0 ) {
152+ assertEquals (editLogOpCount , (int ) counts .get (FSEditLogOpCodes .
153+ OP_DELETE_SNAPSHOT ).held );
154+ }
155+ // make sure the gc thread doesn't start for a long time after the restart
156+ conf .setInt (DFS_NAMENODE_SNAPSHOT_DELETION_ORDERED_GC_PERIOD_MS ,
157+ (int )(24 * 60_000L ));
158+ cluster = new MiniDFSCluster .Builder (conf ).numDataNodes (NUM_DATANODES )
159+ .build ();
160+ cluster .waitActive ();
161+ // ensure after the edits get replayed , all the snapshots are deleted
162+ Assert .assertEquals (0 ,
163+ cluster .getNamesystem ().getSnapshotManager ().getNumSnapshots ());
120164 }
121165
122166 static boolean exist (Path snapshotRoot , DistributedFileSystem hdfs )
@@ -168,6 +212,9 @@ public void testMultipleDirs() throws Exception {
168212 }
169213
170214 waitForGc (snapshotPaths , hdfs );
215+ // don't do edit log count validation here as gc snapshot
216+ // deletion count will be random here
217+ doEditLogValidation (cluster , -1 );
171218 }
172219
173220 static void createSnapshots (Path snapshottableDir , int numSnapshots ,
0 commit comments