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