@@ -11,14 +11,22 @@ use common::{
11
11
bdev:: ListBdevOptions ,
12
12
pool:: CreatePoolRequest ,
13
13
replica:: { CreateReplicaRequest , ListReplicaOptions } ,
14
- snapshot:: { ListSnapshotsRequest , SnapshotInfo } ,
14
+ snapshot:: {
15
+ ListSnapshotsRequest ,
16
+ NexusCreateSnapshotReplicaDescriptor ,
17
+ SnapshotInfo ,
18
+ } ,
15
19
GrpcConnect ,
16
20
} ,
21
+ Binary ,
17
22
Builder ,
18
23
ComposeTest ,
19
24
MayastorTest ,
20
25
} ,
26
+ nexus:: NexusBuilder ,
21
27
nvme:: { list_mayastor_nvme_devices, nvme_connect, nvme_disconnect_all} ,
28
+ pool:: PoolBuilder ,
29
+ replica:: ReplicaBuilder ,
22
30
} ;
23
31
24
32
use io_engine:: {
@@ -319,47 +327,6 @@ async fn test_replica_handle_snapshot() {
319
327
) ;
320
328
}
321
329
322
- #[ tokio:: test]
323
- async fn test_multireplica_nexus_snapshot ( ) {
324
- let ms = get_ms ( ) ;
325
- let ( _test, urls) = launch_instance ( true ) . await ;
326
-
327
- ms. spawn ( async move {
328
- let nexus = create_nexus ( & urls) . await ;
329
-
330
- let snapshot_params = SnapshotParams :: new (
331
- Some ( String :: from ( "e1" ) ) ,
332
- Some ( String :: from ( "p1" ) ) ,
333
- Some ( Uuid :: new_v4 ( ) . to_string ( ) ) ,
334
- Some ( String :: from ( "s1" ) ) ,
335
- Some ( Uuid :: new_v4 ( ) . to_string ( ) ) ,
336
- Some ( Utc :: now ( ) . to_string ( ) ) ,
337
- false ,
338
- ) ;
339
-
340
- let replicas = vec ! [
341
- NexusReplicaSnapshotDescriptor {
342
- replica_uuid: replica1_uuid( ) ,
343
- skip: false ,
344
- snapshot_uuid: Some ( Uuid :: new_v4( ) . to_string( ) ) ,
345
- } ,
346
- NexusReplicaSnapshotDescriptor {
347
- replica_uuid: replica2_uuid( ) ,
348
- skip: false ,
349
- snapshot_uuid: Some ( Uuid :: new_v4( ) . to_string( ) ) ,
350
- } ,
351
- ] ;
352
-
353
- nexus
354
- . create_snapshot ( snapshot_params, replicas)
355
- . await
356
- . expect_err (
357
- "Snapshot successfully created for a multireplica nexus" ,
358
- ) ;
359
- } )
360
- . await ;
361
- }
362
-
363
330
#[ tokio:: test]
364
331
async fn test_list_no_snapshots ( ) {
365
332
let ( test, _urls) = launch_instance ( false ) . await ;
@@ -1282,3 +1249,152 @@ async fn test_replica_listing_with_query() {
1282
1249
assert ! ( !replicas[ 0 ] . is_clone && !replicas[ 0 ] . is_snapshot) ;
1283
1250
assert ! ( !replicas[ 1 ] . is_clone && !replicas[ 1 ] . is_snapshot) ;
1284
1251
}
1252
+
1253
+ #[ tokio:: test]
1254
+ async fn test_multireplica_nexus_snapshot ( ) {
1255
+ const POOL_SIZE : u64 = 60 ;
1256
+ const REPL_SIZE : u64 = 22 ;
1257
+
1258
+ common:: composer_init ( ) ;
1259
+ let test = Builder :: new ( )
1260
+ . name ( "cargo-test" )
1261
+ . network ( "10.1.0.0/16" )
1262
+ . unwrap ( )
1263
+ . add_container_bin (
1264
+ "ms_nexus" ,
1265
+ Binary :: from_dbg ( "io-engine" ) . with_args ( vec ! [ "-l" , "1" ] ) ,
1266
+ )
1267
+ . add_container_bin (
1268
+ "ms_repl_1" ,
1269
+ Binary :: from_dbg ( "io-engine" ) . with_args ( vec ! [ "-l" , "2" ] ) ,
1270
+ )
1271
+ . add_container_bin (
1272
+ "ms_repl_2" ,
1273
+ Binary :: from_dbg ( "io-engine" ) . with_args ( vec ! [ "-l" , "3" ] ) ,
1274
+ )
1275
+ . add_container_bin (
1276
+ "ms_repl_3" ,
1277
+ Binary :: from_dbg ( "io-engine" ) . with_args ( vec ! [ "-l" , "4" ] ) ,
1278
+ )
1279
+ . with_clean ( true )
1280
+ . build ( )
1281
+ . await
1282
+ . unwrap ( ) ;
1283
+
1284
+ let conn = GrpcConnect :: new ( & test) ;
1285
+ let ms_nexus = conn. grpc_handle_shared ( "ms_nexus" ) . await . unwrap ( ) ;
1286
+ let ms_repl_1 = conn. grpc_handle_shared ( "ms_repl_1" ) . await . unwrap ( ) ;
1287
+ let ms_repl_2 = conn. grpc_handle_shared ( "ms_repl_2" ) . await . unwrap ( ) ;
1288
+ let ms_repl_3 = conn. grpc_handle_shared ( "ms_repl_3" ) . await . unwrap ( ) ;
1289
+ // Create Pool-1 and Replica-1.
1290
+ let mut pool_1 = PoolBuilder :: new ( ms_repl_1. clone ( ) )
1291
+ . with_name ( "pool1" )
1292
+ . with_new_uuid ( )
1293
+ . with_malloc ( "mem1" , POOL_SIZE ) ;
1294
+
1295
+ let mut repl_1 = ReplicaBuilder :: new ( ms_repl_1. clone ( ) )
1296
+ . with_pool ( & pool_1)
1297
+ . with_name ( "r1" )
1298
+ . with_new_uuid ( )
1299
+ . with_size_mb ( REPL_SIZE )
1300
+ . with_thin ( true ) ;
1301
+
1302
+ pool_1. create ( ) . await . unwrap ( ) ;
1303
+ repl_1. create ( ) . await . unwrap ( ) ;
1304
+ repl_1. share ( ) . await . unwrap ( ) ;
1305
+
1306
+ // Create Pool-2 and Replica-2.
1307
+ let mut pool_2 = PoolBuilder :: new ( ms_repl_2. clone ( ) )
1308
+ . with_name ( "pool2" )
1309
+ . with_new_uuid ( )
1310
+ . with_malloc ( "mem2" , POOL_SIZE ) ;
1311
+
1312
+ let mut repl_2 = ReplicaBuilder :: new ( ms_repl_2. clone ( ) )
1313
+ . with_pool ( & pool_2)
1314
+ . with_name ( "r2" )
1315
+ . with_new_uuid ( )
1316
+ . with_size_mb ( REPL_SIZE )
1317
+ . with_thin ( true ) ;
1318
+
1319
+ pool_2. create ( ) . await . unwrap ( ) ;
1320
+ repl_2. create ( ) . await . unwrap ( ) ;
1321
+ repl_2. share ( ) . await . unwrap ( ) ;
1322
+ // Create Pool-3 and Replica-3.
1323
+ let mut pool_3 = PoolBuilder :: new ( ms_repl_3. clone ( ) )
1324
+ . with_name ( "pool3" )
1325
+ . with_new_uuid ( )
1326
+ . with_malloc ( "mem3" , POOL_SIZE ) ;
1327
+
1328
+ let mut repl_3 = ReplicaBuilder :: new ( ms_repl_3. clone ( ) )
1329
+ . with_pool ( & pool_3)
1330
+ . with_name ( "r3" )
1331
+ . with_new_uuid ( )
1332
+ . with_size_mb ( REPL_SIZE )
1333
+ . with_thin ( true ) ;
1334
+
1335
+ pool_3. create ( ) . await . unwrap ( ) ;
1336
+ repl_3. create ( ) . await . unwrap ( ) ;
1337
+ repl_3. share ( ) . await . unwrap ( ) ;
1338
+
1339
+ // Create nexus.
1340
+ let mut nex_0 = NexusBuilder :: new ( ms_nexus. clone ( ) )
1341
+ . with_name ( "nexus0" )
1342
+ . with_new_uuid ( )
1343
+ . with_size_mb ( REPL_SIZE )
1344
+ . with_replica ( & repl_1)
1345
+ . with_replica ( & repl_2)
1346
+ . with_replica ( & repl_3) ;
1347
+
1348
+ nex_0. create ( ) . await . unwrap ( ) ;
1349
+ nex_0. publish ( ) . await . unwrap ( ) ;
1350
+
1351
+ let snapshot_params = SnapshotParams :: new (
1352
+ Some ( String :: from ( "e1" ) ) ,
1353
+ Some ( String :: from ( "p1" ) ) ,
1354
+ Some ( Uuid :: new_v4 ( ) . to_string ( ) ) ,
1355
+ Some ( String :: from ( "s1" ) ) ,
1356
+ Some ( Uuid :: new_v4 ( ) . to_string ( ) ) ,
1357
+ Some ( Utc :: now ( ) . to_string ( ) ) ,
1358
+ false ,
1359
+ ) ;
1360
+
1361
+ let mut replicas = vec ! [
1362
+ NexusCreateSnapshotReplicaDescriptor {
1363
+ replica_uuid: repl_1. uuid( ) ,
1364
+ snapshot_uuid: Some ( Uuid :: new_v4( ) . to_string( ) ) ,
1365
+ skip: false ,
1366
+ } ,
1367
+ NexusCreateSnapshotReplicaDescriptor {
1368
+ replica_uuid: repl_2. uuid( ) ,
1369
+ snapshot_uuid: Some ( Uuid :: new_v4( ) . to_string( ) ) ,
1370
+ skip: false ,
1371
+ } ,
1372
+ ] ;
1373
+ // check for error when snapshot uuid is not provided for all replicas.
1374
+ let result = nex_0
1375
+ . create_nexus_snapshot ( & snapshot_params, & replicas)
1376
+ . await ;
1377
+ assert ! ( result. is_err( ) ) ;
1378
+
1379
+ replicas. push ( NexusCreateSnapshotReplicaDescriptor {
1380
+ replica_uuid : repl_2. uuid ( ) ,
1381
+ snapshot_uuid : replicas[ 1 ] . snapshot_uuid . clone ( ) ,
1382
+ skip : false ,
1383
+ } ) ;
1384
+ // check for error when snapshot uuid is duplicated.
1385
+ let result = nex_0
1386
+ . create_nexus_snapshot ( & snapshot_params, & replicas)
1387
+ . await ;
1388
+ assert ! ( result. is_err( ) ) ;
1389
+ replicas. pop ( ) ;
1390
+ replicas. push ( NexusCreateSnapshotReplicaDescriptor {
1391
+ replica_uuid : repl_3. uuid ( ) ,
1392
+ snapshot_uuid : Some ( Uuid :: new_v4 ( ) . to_string ( ) ) ,
1393
+ skip : false ,
1394
+ } ) ;
1395
+ let snap_list = nex_0
1396
+ . create_nexus_snapshot ( & snapshot_params, & replicas)
1397
+ . await
1398
+ . unwrap ( ) ;
1399
+ assert_eq ! ( snap_list. len( ) , 3 ) ;
1400
+ }
0 commit comments