@@ -39,6 +39,8 @@ var defaultTimeoutRetry = 500 * time.Millisecond
39
39
40
40
var instances []test_helpers.TarantoolInstance
41
41
42
+ var tarantoolVersionIsLess bool
43
+
42
44
func TestConnError_IncorrectParams (t * testing.T ) {
43
45
connPool , err := connection_pool .Connect ([]string {}, tarantool.Opts {})
44
46
require .Nilf (t , connPool , "conn is not nil with incorrect param" )
@@ -1276,6 +1278,203 @@ func TestDo(t *testing.T) {
1276
1278
require .NotNilf (t , resp , "response is nil after Ping" )
1277
1279
}
1278
1280
1281
+ func TestStream_Commit (t * testing.T ) {
1282
+ var req tarantool.Request
1283
+ var resp * tarantool.Response
1284
+ var err error
1285
+
1286
+ // Tarantool supports streams and interactive transactions since version 2.10.0
1287
+ if tarantoolVersionIsLess {
1288
+ t .Skip ()
1289
+ }
1290
+
1291
+ roles := []bool {true , true , false , true , true }
1292
+
1293
+ err = test_helpers .SetClusterRO (servers , connOpts , roles )
1294
+ require .Nilf (t , err , "fail to set roles for cluster" )
1295
+
1296
+ connPool , err := connection_pool .Connect (servers , connOpts )
1297
+ require .Nilf (t , err , "failed to connect" )
1298
+ require .NotNilf (t , connPool , "conn is nil after Connect" )
1299
+ defer connPool .Close ()
1300
+
1301
+ stream , err := connPool .NewStream (connection_pool .PreferRW )
1302
+ require .Nilf (t , err , "failed to create stream" )
1303
+ require .NotNilf (t , connPool , "stream is nil after NewStream" )
1304
+
1305
+ // Begin transaction
1306
+ resp , err = stream .Begin ()
1307
+ require .Nilf (t , err , "failed to Begin" )
1308
+ require .NotNilf (t , resp , "response is nil after Begin" )
1309
+ require .Equalf (t , tarantool .OkCode , resp .Code , "failed to Begin: wrong code returned" )
1310
+
1311
+ // Insert in stream
1312
+ req = tarantool .NewInsertRequest (spaceName ).
1313
+ Tuple ([]interface {}{"commit_key" , "commit_value" })
1314
+ resp , err = stream .Do (req ).Get ()
1315
+ require .Nilf (t , err , "failed to Insert" )
1316
+ require .NotNilf (t , resp , "response is nil after Insert" )
1317
+ require .Equalf (t , tarantool .OkCode , resp .Code , "failed to Insert: wrong code returned" )
1318
+
1319
+ // Connect to servers[2] to check if tuple
1320
+ // was inserted outside of stream on RW instance
1321
+ // before transaction commit
1322
+ conn , err := tarantool .Connect (servers [2 ], connOpts )
1323
+ require .Nilf (t , err , "failed to connect %s" , servers [2 ])
1324
+ require .NotNilf (t , conn , "conn is nil after Connect" )
1325
+
1326
+ // Select not related to the transaction
1327
+ // while transaction is not committed
1328
+ // result of select is empty
1329
+ req = tarantool .NewSelectRequest (spaceNo ).
1330
+ Index (indexNo ).
1331
+ Offset (0 ).
1332
+ Limit (1 ).
1333
+ Iterator (tarantool .IterEq ).
1334
+ Key ([]interface {}{"commit_key" })
1335
+ resp , err = conn .Do (req ).Get ()
1336
+ require .Nilf (t , err , "failed to Select" )
1337
+ require .NotNilf (t , resp , "response is nil after Select" )
1338
+ require .Equalf (t , 0 , len (resp .Data ), "response Data len != 0" )
1339
+
1340
+ // Select in stream
1341
+ resp , err = stream .Do (req ).Get ()
1342
+ require .Nilf (t , err , "failed to Select" )
1343
+ require .NotNilf (t , resp , "response is nil after Select" )
1344
+ require .Equalf (t , 1 , len (resp .Data ), "response Body len != 1 after Select" )
1345
+
1346
+ tpl , ok := resp .Data [0 ].([]interface {})
1347
+ require .Truef (t , ok , "unexpected body of Select" )
1348
+ require .Equalf (t , 2 , len (tpl ), "unexpected body of Select" )
1349
+
1350
+ key , ok := tpl [0 ].(string )
1351
+ require .Truef (t , ok , "unexpected body of Select (0)" )
1352
+ require .Equalf (t , "commit_key" , key , "unexpected body of Select (0)" )
1353
+
1354
+ value , ok := tpl [1 ].(string )
1355
+ require .Truef (t , ok , "unexpected body of Select (1)" )
1356
+ require .Equalf (t , "commit_value" , value , "unexpected body of Select (1)" )
1357
+
1358
+ // Commit transaction
1359
+ resp , err = stream .Commit ()
1360
+ require .Nilf (t , err , "failed to Commit" )
1361
+ require .NotNilf (t , resp , "response is nil after Commit" )
1362
+ require .Equalf (t , tarantool .OkCode , resp .Code , "failed to Commit: wrong code returned" )
1363
+
1364
+ // Select outside of transaction
1365
+ resp , err = conn .Do (req ).Get ()
1366
+ require .Nilf (t , err , "failed to Select" )
1367
+ require .NotNilf (t , resp , "response is nil after Select" )
1368
+ require .Equalf (t , len (resp .Data ), 1 , "response Body len != 1 after Select" )
1369
+
1370
+ tpl , ok = resp .Data [0 ].([]interface {})
1371
+ require .Truef (t , ok , "unexpected body of Select" )
1372
+ require .Equalf (t , 2 , len (tpl ), "unexpected body of Select" )
1373
+
1374
+ key , ok = tpl [0 ].(string )
1375
+ require .Truef (t , ok , "unexpected body of Select (0)" )
1376
+ require .Equalf (t , "commit_key" , key , "unexpected body of Select (0)" )
1377
+
1378
+ value , ok = tpl [1 ].(string )
1379
+ require .Truef (t , ok , "unexpected body of Select (1)" )
1380
+ require .Equalf (t , "commit_value" , value , "unexpected body of Select (1)" )
1381
+ }
1382
+
1383
+ func TestStream_Rollback (t * testing.T ) {
1384
+ var req tarantool.Request
1385
+ var resp * tarantool.Response
1386
+ var err error
1387
+
1388
+ // Tarantool supports streams and interactive transactions since version 2.10.0
1389
+ if tarantoolVersionIsLess {
1390
+ t .Skip ()
1391
+ }
1392
+
1393
+ roles := []bool {true , true , false , true , true }
1394
+
1395
+ err = test_helpers .SetClusterRO (servers , connOpts , roles )
1396
+ require .Nilf (t , err , "fail to set roles for cluster" )
1397
+
1398
+ connPool , err := connection_pool .Connect (servers , connOpts )
1399
+ require .Nilf (t , err , "failed to connect" )
1400
+ require .NotNilf (t , connPool , "conn is nil after Connect" )
1401
+ defer connPool .Close ()
1402
+
1403
+ stream , err := connPool .NewStream (connection_pool .PreferRW )
1404
+ require .Nilf (t , err , "failed to create stream" )
1405
+ require .NotNilf (t , connPool , "stream is nil after NewStream" )
1406
+
1407
+ // Begin transaction
1408
+ resp , err = stream .Begin ()
1409
+ require .Nilf (t , err , "failed to Begin" )
1410
+ require .NotNilf (t , resp , "response is nil after Begin" )
1411
+ require .Equalf (t , tarantool .OkCode , resp .Code , "failed to Begin: wrong code returned" )
1412
+
1413
+ // Insert in stream
1414
+ req = tarantool .NewInsertRequest (spaceName ).
1415
+ Tuple ([]interface {}{"rollback_key" , "rollback_value" })
1416
+ resp , err = stream .Do (req ).Get ()
1417
+ require .Nilf (t , err , "failed to Insert" )
1418
+ require .NotNilf (t , resp , "response is nil after Insert" )
1419
+ require .Equalf (t , tarantool .OkCode , resp .Code , "failed to Insert: wrong code returned" )
1420
+
1421
+ // Connect to servers[2] to check if tuple
1422
+ // was not inserted outside of stream on RW instance
1423
+ conn , err := tarantool .Connect (servers [2 ], connOpts )
1424
+ require .Nilf (t , err , "failed to connect %s" , servers [2 ])
1425
+ require .NotNilf (t , conn , "conn is nil after Connect" )
1426
+
1427
+ // Select not related to the transaction
1428
+ // while transaction is not committed
1429
+ // result of select is empty
1430
+ req = tarantool .NewSelectRequest (spaceNo ).
1431
+ Index (indexNo ).
1432
+ Offset (0 ).
1433
+ Limit (1 ).
1434
+ Iterator (tarantool .IterEq ).
1435
+ Key ([]interface {}{"rollback_key" })
1436
+ resp , err = conn .Do (req ).Get ()
1437
+ require .Nilf (t , err , "failed to Select" )
1438
+ require .NotNilf (t , resp , "response is nil after Select" )
1439
+ require .Equalf (t , 0 , len (resp .Data ), "response Data len != 0" )
1440
+
1441
+ // Select in stream
1442
+ resp , err = stream .Do (req ).Get ()
1443
+ require .Nilf (t , err , "failed to Select" )
1444
+ require .NotNilf (t , resp , "response is nil after Select" )
1445
+ require .Equalf (t , 1 , len (resp .Data ), "response Body len != 1 after Select" )
1446
+
1447
+ tpl , ok := resp .Data [0 ].([]interface {})
1448
+ require .Truef (t , ok , "unexpected body of Select" )
1449
+ require .Equalf (t , 2 , len (tpl ), "unexpected body of Select" )
1450
+
1451
+ key , ok := tpl [0 ].(string )
1452
+ require .Truef (t , ok , "unexpected body of Select (0)" )
1453
+ require .Equalf (t , "rollback_key" , key , "unexpected body of Select (0)" )
1454
+
1455
+ value , ok := tpl [1 ].(string )
1456
+ require .Truef (t , ok , "unexpected body of Select (1)" )
1457
+ require .Equalf (t , "rollback_value" , value , "unexpected body of Select (1)" )
1458
+
1459
+ // Rollback transaction
1460
+ resp , err = stream .Rollback ()
1461
+ require .Nilf (t , err , "failed to Rollback" )
1462
+ require .NotNilf (t , resp , "response is nil after Rollback" )
1463
+ require .Equalf (t , tarantool .OkCode , resp .Code , "failed to Rollback: wrong code returned" )
1464
+
1465
+ // Select outside of transaction
1466
+ resp , err = conn .Do (req ).Get ()
1467
+ require .Nilf (t , err , "failed to Select" )
1468
+ require .NotNilf (t , resp , "response is nil after Select" )
1469
+ require .Equalf (t , 0 , len (resp .Data ), "response Body len != 0 after Select" )
1470
+
1471
+ // Select inside of stream after rollback
1472
+ resp , err = stream .Do (req ).Get ()
1473
+ require .Nilf (t , err , "failed to Select" )
1474
+ require .NotNilf (t , resp , "response is nil after Select" )
1475
+ require .Equalf (t , 0 , len (resp .Data ), "response Body len != 0 after Select" )
1476
+ }
1477
+
1279
1478
// runTestMain is a body of TestMain function
1280
1479
// (see https://pkg.go.dev/testing#hdr-Main).
1281
1480
// Using defer + os.Exit is not works so TestMain body
@@ -1292,13 +1491,25 @@ func runTestMain(m *testing.M) int {
1292
1491
"work_dir5" }
1293
1492
var err error
1294
1493
1494
+ memtxUseMvccEngine := true
1495
+
1496
+ // Tarantool supports streams and interactive transactions since version 2.10.0
1497
+ tarantoolVersionIsLess , err = test_helpers .IsTarantoolVersionLess (2 , 10 , 0 )
1498
+ if err != nil {
1499
+ log .Fatalf ("Could not check the Tarantool version" )
1500
+ }
1501
+ if tarantoolVersionIsLess {
1502
+ memtxUseMvccEngine = false
1503
+ }
1504
+
1295
1505
instances , err = test_helpers .StartTarantoolInstances (servers , workDirs , test_helpers.StartOpts {
1296
- InitScript : initScript ,
1297
- User : connOpts .User ,
1298
- Pass : connOpts .Pass ,
1299
- WaitStart : waitStart ,
1300
- ConnectRetry : connectRetry ,
1301
- RetryTimeout : retryTimeout ,
1506
+ InitScript : initScript ,
1507
+ User : connOpts .User ,
1508
+ Pass : connOpts .Pass ,
1509
+ WaitStart : waitStart ,
1510
+ ConnectRetry : connectRetry ,
1511
+ RetryTimeout : retryTimeout ,
1512
+ MemtxUseMvccEngine : memtxUseMvccEngine ,
1302
1513
})
1303
1514
1304
1515
if err != nil {
0 commit comments