2323import org .apache .hadoop .hdds .conf .OzoneConfiguration ;
2424import org .apache .hadoop .hdds .protocol .datanode .proto .ContainerProtos ;
2525import org .apache .hadoop .ozone .MiniOzoneCluster ;
26+ import org .apache .hadoop .ozone .OzoneConfigKeys ;
2627import org .apache .hadoop .ozone .client .CertificateClientTestImpl ;
2728import org .apache .hadoop .ozone .client .ObjectStore ;
2829import org .apache .hadoop .ozone .client .OzoneClient ;
2930import org .apache .hadoop .ozone .client .OzoneClientFactory ;
3031import org .apache .hadoop .ozone .client .io .KeyOutputStream ;
3132import org .apache .hadoop .ozone .client .io .OzoneOutputStream ;
33+ import org .apache .hadoop .ozone .container .ContainerTestHelper ;
34+ import org .apache .hadoop .ozone .container .common .transport .server .ratis .ContainerStateMachine ;
35+ import org .apache .hadoop .ozone .container .common .transport .server .ratis .RatisServerConfiguration ;
3236import org .apache .hadoop .ozone .om .OzoneManager ;
3337import org .apache .hadoop .ozone .om .helpers .OmKeyLocationInfo ;
3438import org .apache .hadoop .test .GenericTestUtils ;
39+ import org .apache .ratis .statemachine .impl .SimpleStateMachineStorage ;
3540import org .junit .AfterClass ;
3641import org .junit .Assert ;
3742import org .junit .BeforeClass ;
3843import org .junit .Test ;
3944
4045import java .io .File ;
4146import java .io .IOException ;
47+ import java .nio .file .Path ;
4248import java .util .HashMap ;
4349import java .util .List ;
4450import java .util .concurrent .TimeUnit ;
@@ -85,7 +91,8 @@ public static void init() throws Exception {
8591 conf .setTimeDuration (OZONE_SCM_STALENODE_INTERVAL , 3 , TimeUnit .SECONDS );
8692 conf .setQuietMode (false );
8793 OzoneManager .setTestSecureOmFlag (true );
88- // conf.set(HADOOP_SECURITY_AUTHENTICATION, KERBEROS.toString());
94+ conf .setLong (OzoneConfigKeys .DFS_RATIS_SNAPSHOT_THRESHOLD_KEY , 1 );
95+ // conf.set(HADOOP_SECURITY_AUTHENTICATION, KERBEROS.toString());
8996 cluster =
9097 MiniOzoneCluster .newBuilder (conf ).setNumDatanodes (1 )
9198 .setHbInterval (200 )
@@ -148,4 +155,57 @@ public void testContainerStateMachineFailures() throws Exception {
148155 .getContainerState ()
149156 == ContainerProtos .ContainerDataProto .State .UNHEALTHY );
150157 }
158+
159+ @ Test
160+ public void testRatisSnapshotRetention () throws Exception {
161+
162+ ContainerStateMachine stateMachine =
163+ (ContainerStateMachine ) ContainerTestHelper .getStateMachine (cluster );
164+ SimpleStateMachineStorage storage =
165+ (SimpleStateMachineStorage ) stateMachine .getStateMachineStorage ();
166+ Assert .assertNull (storage .findLatestSnapshot ());
167+
168+ // Write 10 keys. Num snapshots should be equal to config value.
169+ for (int i = 1 ; i <= 10 ; i ++) {
170+ OzoneOutputStream key =
171+ objectStore .getVolume (volumeName ).getBucket (bucketName )
172+ .createKey (("ratis" + i ), 1024 , ReplicationType .RATIS ,
173+ ReplicationFactor .ONE , new HashMap <>());
174+ // First write and flush creates a container in the datanode
175+ key .write (("ratis" + i ).getBytes ());
176+ key .flush ();
177+ key .write (("ratis" + i ).getBytes ());
178+ }
179+
180+ RatisServerConfiguration ratisServerConfiguration =
181+ conf .getObject (RatisServerConfiguration .class );
182+
183+ stateMachine =
184+ (ContainerStateMachine ) ContainerTestHelper .getStateMachine (cluster );
185+ storage = (SimpleStateMachineStorage ) stateMachine .getStateMachineStorage ();
186+ Path parentPath = storage .findLatestSnapshot ().getFile ().getPath ();
187+ int numSnapshots = parentPath .getParent ().toFile ().listFiles ().length ;
188+ Assert .assertTrue (Math .abs (ratisServerConfiguration
189+ .getNumSnapshotsRetained () - numSnapshots ) <= 1 );
190+
191+ // Write 10 more keys. Num Snapshots should remain the same.
192+ for (int i = 11 ; i <= 20 ; i ++) {
193+ OzoneOutputStream key =
194+ objectStore .getVolume (volumeName ).getBucket (bucketName )
195+ .createKey (("ratis" + i ), 1024 , ReplicationType .RATIS ,
196+ ReplicationFactor .ONE , new HashMap <>());
197+ // First write and flush creates a container in the datanode
198+ key .write (("ratis" + i ).getBytes ());
199+ key .flush ();
200+ key .write (("ratis" + i ).getBytes ());
201+ }
202+ stateMachine =
203+ (ContainerStateMachine ) ContainerTestHelper .getStateMachine (cluster );
204+ storage = (SimpleStateMachineStorage ) stateMachine .getStateMachineStorage ();
205+ parentPath = storage .findLatestSnapshot ().getFile ().getPath ();
206+ numSnapshots = parentPath .getParent ().toFile ().listFiles ().length ;
207+ Assert .assertTrue (Math .abs (ratisServerConfiguration
208+ .getNumSnapshotsRetained () - numSnapshots ) <= 1 );
209+ }
210+
151211}
0 commit comments