@@ -1296,321 +1296,6 @@ func TestFjallStore(t *testing.T) {
12961296 }
12971297}
12981298
1299- type kvIter interface {
1300- SetBatchSize (int )
1301- Next () bool
1302- Key () []byte
1303- Value () []byte
1304- Err () error
1305- Drop () error
1306- }
1307- type borrowIter struct { it * Iterator }
1308-
1309- func (b * borrowIter ) SetBatchSize (batchSize int ) { b .it .SetBatchSize (batchSize ) }
1310- func (b * borrowIter ) Next () bool { return b .it .NextBorrowed () }
1311- func (b * borrowIter ) Key () []byte { return b .it .Key () }
1312- func (b * borrowIter ) Value () []byte { return b .it .Value () }
1313- func (b * borrowIter ) Err () error { return b .it .Err () }
1314- func (b * borrowIter ) Drop () error { return b .it .Drop () }
1315-
1316- func assertIteratorYields (r * require.Assertions , it kvIter , keys [][]byte , vals [][]byte ) {
1317- i := 0
1318- for ; it .Next (); i += 1 {
1319- r .Equal (keys [i ], it .Key ())
1320- r .Equal (vals [i ], it .Value ())
1321- }
1322- r .NoError (it .Err ())
1323- r .Equal (len (keys ), i )
1324- }
1325-
1326- type iteratorConfigFn = func (it kvIter ) kvIter
1327-
1328- var iterConfigs = map [string ]iteratorConfigFn {
1329- "Owned" : func (it kvIter ) kvIter { return it },
1330- "Borrowed" : func (it kvIter ) kvIter { return & borrowIter {it : it .(* Iterator )} },
1331- "Single" : func (it kvIter ) kvIter {
1332- it .SetBatchSize (1 )
1333- return it
1334- },
1335- "Batched" : func (it kvIter ) kvIter {
1336- it .SetBatchSize (100 )
1337- return it
1338- },
1339- }
1340-
1341- func runIteratorTestForModes (t * testing.T , fn func (* testing.T , iteratorConfigFn ), modes ... string ) {
1342- testName := strings .Join (modes , "/" )
1343- t .Run (testName , func (t * testing.T ) {
1344- r := require .New (t )
1345- fn (t , func (it kvIter ) kvIter {
1346- for _ , m := range modes {
1347- config , ok := iterConfigs [m ]
1348- r .Truef (ok , "specified config mode %s does not exist" , m )
1349- it = config (it )
1350- }
1351- return it
1352- })
1353- })
1354- }
1355-
1356- func runIteratorTestForAllModes (parentT * testing.T , fn func (* testing.T , iteratorConfigFn )) {
1357- for _ , dataMode := range []string {"Owned" , "Borrowed" } {
1358- for _ , batchMode := range []string {"Single" , "Batched" } {
1359- runIteratorTestForModes (parentT , fn , batchMode , dataMode )
1360- }
1361- }
1362- }
1363-
1364- // Tests that basic iterator functionality works
1365- func TestIter (t * testing.T ) {
1366- r := require .New (t )
1367- db := newTestDatabase (t )
1368- keys , vals := kvForTest (100 )
1369- _ , err := db .Update (keys , vals )
1370- r .NoError (err )
1371-
1372- runIteratorTestForAllModes (t , func (t * testing.T , cfn iteratorConfigFn ) {
1373- r := require .New (t )
1374- rev , err := db .LatestRevision ()
1375- r .NoError (err )
1376- it , err := rev .Iter (nil )
1377- r .NoError (err )
1378- t .Cleanup (func () {
1379- r .NoError (it .Drop ())
1380- r .NoError (rev .Drop ())
1381- })
1382-
1383- assertIteratorYields (r , cfn (it ), keys , vals )
1384- })
1385- }
1386-
1387- func TestIterOnRoot (t * testing.T ) {
1388- r := require .New (t )
1389- db := newTestDatabase (t )
1390- keys , vals := kvForTest (240 )
1391- firstRoot , err := db .Update (keys [:80 ], vals [:80 ])
1392- r .NoError (err )
1393- secondRoot , err := db .Update (keys [80 :160 ], vals [80 :160 ])
1394- r .NoError (err )
1395- thirdRoot , err := db .Update (keys [160 :], vals [160 :])
1396- r .NoError (err )
1397-
1398- runIteratorTestForAllModes (t , func (t * testing.T , cfn iteratorConfigFn ) {
1399- r := require .New (t )
1400- r1 , err := db .Revision (firstRoot )
1401- r .NoError (err )
1402- h1 , err := r1 .Iter (nil )
1403- r .NoError (err )
1404- t .Cleanup (func () {
1405- r .NoError (h1 .Drop ())
1406- r .NoError (r1 .Drop ())
1407- })
1408-
1409- r2 , err := db .Revision (secondRoot )
1410- r .NoError (err )
1411- h2 , err := r2 .Iter (nil )
1412- r .NoError (err )
1413- t .Cleanup (func () {
1414- r .NoError (h2 .Drop ())
1415- r .NoError (r2 .Drop ())
1416- })
1417-
1418- r3 , err := db .Revision (thirdRoot )
1419- r .NoError (err )
1420- h3 , err := r3 .Iter (nil )
1421- r .NoError (err )
1422- t .Cleanup (func () {
1423- r .NoError (h3 .Drop ())
1424- r .NoError (r3 .Drop ())
1425- })
1426-
1427- assertIteratorYields (r , cfn (h1 ), keys [:80 ], vals [:80 ])
1428- assertIteratorYields (r , cfn (h2 ), keys [:160 ], vals [:160 ])
1429- assertIteratorYields (r , cfn (h3 ), keys , vals )
1430- })
1431- }
1432-
1433- func TestIterOnProposal (t * testing.T ) {
1434- r := require .New (t )
1435- db := newTestDatabase (t )
1436- keys , vals := kvForTest (240 )
1437- _ , err := db .Update (keys , vals )
1438- r .NoError (err )
1439-
1440- runIteratorTestForAllModes (t , func (t * testing.T , cfn iteratorConfigFn ) {
1441- r := require .New (t )
1442- updatedValues := make ([][]byte , len (vals ))
1443- copy (updatedValues , vals )
1444-
1445- changedKeys := make ([][]byte , 0 )
1446- changedVals := make ([][]byte , 0 )
1447- for i := 0 ; i < len (vals ); i += 4 {
1448- changedKeys = append (changedKeys , keys [i ])
1449- newVal := []byte {byte (i )}
1450- changedVals = append (changedVals , newVal )
1451- updatedValues [i ] = newVal
1452- }
1453- p , err := db .Propose (changedKeys , changedVals )
1454- r .NoError (err )
1455- it , err := p .Iter (nil )
1456- r .NoError (err )
1457- t .Cleanup (func () {
1458- r .NoError (it .Drop ())
1459- })
1460-
1461- assertIteratorYields (r , cfn (it ), keys , updatedValues )
1462- })
1463- }
1464-
1465- // Tests that the iterator still works after proposal is committed
1466- func TestIterAfterProposalCommit (t * testing.T ) {
1467- r := require .New (t )
1468- db := newTestDatabase (t )
1469-
1470- keys , vals := kvForTest (10 )
1471- p , err := db .Propose (keys , vals )
1472- r .NoError (err )
1473-
1474- it , err := p .Iter (nil )
1475- r .NoError (err )
1476- t .Cleanup (func () {
1477- r .NoError (it .Drop ())
1478- })
1479-
1480- err = p .Commit ()
1481- r .NoError (err )
1482-
1483- // iterate after commit
1484- // because iterator hangs on the nodestore reference of proposal
1485- // the nodestore won't be dropped until we drop the iterator
1486- assertIteratorYields (r , it , keys , vals )
1487- }
1488-
1489- // Tests that the iterator on latest revision works properly after a proposal commit
1490- func TestIterUpdate (t * testing.T ) {
1491- r := require .New (t )
1492- db := newTestDatabase (t )
1493-
1494- keys , vals := kvForTest (10 )
1495- _ , err := db .Update (keys , vals )
1496- r .NoError (err )
1497-
1498- // get an iterator on latest revision
1499- rev , err := db .LatestRevision ()
1500- r .NoError (err )
1501- it , err := rev .Iter (nil )
1502- r .NoError (err )
1503- t .Cleanup (func () {
1504- r .NoError (it .Drop ())
1505- r .NoError (rev .Drop ())
1506- })
1507-
1508- // update the database
1509- keys2 , vals2 := kvForTest (10 )
1510- _ , err = db .Update (keys2 , vals2 )
1511- r .NoError (err )
1512-
1513- // iterate after commit
1514- // because iterator is fixed on the revision hash, it should return the initial values
1515- assertIteratorYields (r , it , keys , vals )
1516- }
1517-
1518- // Tests the iterator's behavior after exhaustion, should safely return empty item/batch, indicating done
1519- func TestIterDone (t * testing.T ) {
1520- r := require .New (t )
1521- db := newTestDatabase (t )
1522-
1523- keys , vals := kvForTest (18 )
1524- _ , err := db .Update (keys , vals )
1525- r .NoError (err )
1526-
1527- // get an iterator on latest revision
1528- rev , err := db .LatestRevision ()
1529- r .NoError (err )
1530- it , err := rev .Iter (nil )
1531- r .NoError (err )
1532- t .Cleanup (func () {
1533- r .NoError (it .Drop ())
1534- r .NoError (rev .Drop ())
1535- })
1536- // consume the iterator
1537- assertIteratorYields (r , it , keys , vals )
1538- // calling next again should be safe and return false
1539- r .False (it .Next ())
1540- r .NoError (it .Err ())
1541-
1542- // get a new iterator
1543- it2 , err := rev .Iter (nil )
1544- r .NoError (err )
1545- // set batch size to 5
1546- it2 .SetBatchSize (5 )
1547- // consume the iterator
1548- assertIteratorYields (r , it2 , keys , vals )
1549- // calling next again should be safe and return false
1550- r .False (it .Next ())
1551- r .NoError (it .Err ())
1552- }
1553-
1554- // Tests the iterator's behavior after revision is dropped, should safely
1555- // outlive the revision as it owns a reference to the revision in Rust.
1556- func TestIterOutlivesRevision (t * testing.T ) {
1557- r := require .New (t )
1558- db := newTestDatabase (t , func (config * config ) {
1559- config .revisions = 2
1560- })
1561-
1562- keys , vals := kvForTest (30 )
1563- _ , err := db .Update (keys [:10 ], vals [:10 ])
1564- r .NoErrorf (err , "%T.Update(...)" , db )
1565- rev , err := db .LatestRevision ()
1566- r .NoErrorf (err , "%T.LatestRevision()" , db )
1567- it , err := rev .Iter (nil )
1568- r .NoErrorf (err , "%T.Iter()" , rev )
1569- t .Cleanup (func () {
1570- r .NoErrorf (it .Drop (), "%T.Drop()" , it )
1571- })
1572-
1573- // Drop the revision right away to ensure reaping
1574- r .NoErrorf (rev .Drop (), "%T.Drop()" , rev )
1575-
1576- // Commit two more times to force reaping of the first revision
1577- _ , err = db .Update (keys [10 :20 ], vals [10 :20 ])
1578- r .NoErrorf (err , "%T.Update(...)" , db )
1579- _ , err = db .Update (keys [20 :], vals [20 :])
1580- r .NoErrorf (err , "%T.Update(...)" , db )
1581-
1582- // iterate after reaping
1583- assertIteratorYields (r , it , keys [:10 ], vals [:10 ])
1584- }
1585-
1586- // Tests the iterator's behavior after proposal is dropped, should safely
1587- // outlive the proposal as it owns a reference to the view in Rust.
1588- func TestIterOutlivesProposal (t * testing.T ) {
1589- r := require .New (t )
1590- db := newTestDatabase (t )
1591-
1592- keys , vals := kvForTest (4 )
1593- p , err := db .Propose (keys [:2 ], vals [:2 ])
1594- r .NoErrorf (err , "%T.Propose(...)" , db )
1595-
1596- it , err := p .Iter (nil )
1597- r .NoErrorf (err , "%T.Iter()" , p )
1598- t .Cleanup (func () {
1599- r .NoErrorf (it .Drop (), "%T.Drop()" , it )
1600- })
1601- r .NoErrorf (p .Drop (), "%T.Drop()" , p )
1602-
1603- // This is necessary because the dropped proposal is referenced in
1604- // the revision manager and cleanup only runs when commit is called.
1605- // So here we create a new proposal with different keys, and commit
1606- // to trigger cleanup of the dropped proposal.
1607- p2 , err := db .Propose (keys [2 :], vals [2 :])
1608- r .NoErrorf (err , "%T.Propose(...)" , db )
1609- r .NoErrorf (p2 .Commit (), "%T.Commit(...)" , db )
1610-
1611- assertIteratorYields (r , it , keys [:2 ], vals [:2 ])
1612- }
1613-
16141299// TestNilVsEmptyValue tests that nil values cause delete operations while
16151300// empty []byte{} values result in inserts with empty values.
16161301func TestNilVsEmptyValue (t * testing.T ) {
0 commit comments