From 55908f1695e59163dad81d893bb0bb548a032fcc Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Mon, 12 Aug 2024 11:29:52 +0200 Subject: [PATCH 1/3] Update tests covering powersync-sqlite-core. --- .../powersync/test/bucket_storage_test.dart | 108 +++++++++++++++--- 1 file changed, 94 insertions(+), 14 deletions(-) diff --git a/packages/powersync/test/bucket_storage_test.dart b/packages/powersync/test/bucket_storage_test.dart index 4ae26b26..22776ee9 100644 --- a/packages/powersync/test/bucket_storage_test.dart +++ b/packages/powersync/test/bucket_storage_test.dart @@ -304,23 +304,10 @@ void main() { await bucketStorage.saveSyncData(SyncDataBatch([ SyncBucketData( bucket: 'bucket1', - data: [ - OplogEntry( - opId: '1', - op: OpType.move, - checksum: 1, - data: '{"target": "3"}') - ], + data: [OplogEntry(opId: '1', op: OpType.move, checksum: 1)], ), ])); - // At this point, we have target: 3, but don't have that op yet, so we cannot sync. - final result = await bucketStorage.syncLocalDatabase(Checkpoint( - lastOpId: '2', - checksums: [BucketChecksum(bucket: 'bucket1', checksum: 1)])); - // Checksum passes, but we don't have a complete checkpoint - expect(result, equals(SyncLocalDatabaseResult(ready: false))); - await bucketStorage.saveSyncData(SyncDataBatch([ SyncBucketData( bucket: 'bucket1', @@ -480,6 +467,99 @@ void main() { ])); }); + test('should compact with checksum wrapping', () async { + await bucketStorage.saveSyncData(SyncDataBatch([ + SyncBucketData(bucket: 'bucket1', data: [ + OplogEntry( + opId: '1', + op: OpType.put, + rowType: 'assets', + rowId: 'O1', + data: '{"description": "b1"}', + checksum: 2147483647), + OplogEntry( + opId: '2', + op: OpType.put, + rowType: 'assets', + rowId: 'O1', + data: '{"description": "b2"}', + checksum: 2147483646), + OplogEntry( + opId: '3', + op: OpType.put, + rowType: 'assets', + rowId: 'O1', + data: '{"description": "b3"}', + checksum: 2147483645) + ]) + ])); + + await syncLocalChecked(Checkpoint( + lastOpId: '4', + writeCheckpoint: '4', + checksums: [ + BucketChecksum(bucket: 'bucket1', checksum: 2147483642) + ])); + + await bucketStorage.forceCompact(); + + await syncLocalChecked(Checkpoint( + lastOpId: '4', + writeCheckpoint: '4', + checksums: [ + BucketChecksum(bucket: 'bucket1', checksum: 2147483642) + ])); + + final stats = db.select( + 'SELECT row_type as type, row_id as id, count(*) as count FROM ps_oplog GROUP BY row_type, row_id ORDER BY row_type, row_id'); + expect( + stats, + equals([ + {'type': 'assets', 'id': 'O1', 'count': 1} + ])); + }); + + test('should compact with checksum wrapping (2)', () async { + await bucketStorage.saveSyncData(SyncDataBatch([ + SyncBucketData(bucket: 'bucket1', data: [ + OplogEntry( + opId: '1', + op: OpType.put, + rowType: 'assets', + rowId: 'O1', + data: '{"description": "b1"}', + checksum: 2147483647), + OplogEntry( + opId: '2', + op: OpType.put, + rowType: 'assets', + rowId: 'O1', + data: '{"description": "b2"}', + checksum: 2147483646), + ]) + ])); + + await syncLocalChecked(Checkpoint( + lastOpId: '4', + writeCheckpoint: '4', + checksums: [BucketChecksum(bucket: 'bucket1', checksum: -3)])); + + await bucketStorage.forceCompact(); + + await syncLocalChecked(Checkpoint( + lastOpId: '4', + writeCheckpoint: '4', + checksums: [BucketChecksum(bucket: 'bucket1', checksum: -3)])); + + final stats = db.select( + 'SELECT row_type as type, row_id as id, count(*) as count FROM ps_oplog GROUP BY row_type, row_id ORDER BY row_type, row_id'); + expect( + stats, + equals([ + {'type': 'assets', 'id': 'O1', 'count': 1} + ])); + }); + test('should not sync local db with pending crud - server removed', () async { await bucketStorage.saveSyncData(SyncDataBatch([ From 5b94ff01ce0ece2395095bbb5e59e2d4f80c91c1 Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Mon, 12 Aug 2024 11:51:29 +0200 Subject: [PATCH 2/3] Fix merge conflicts. --- packages/powersync/test/bucket_storage_test.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/powersync/test/bucket_storage_test.dart b/packages/powersync/test/bucket_storage_test.dart index d7427a9c..2877a537 100644 --- a/packages/powersync/test/bucket_storage_test.dart +++ b/packages/powersync/test/bucket_storage_test.dart @@ -521,7 +521,7 @@ void main() { BucketChecksum(bucket: 'bucket1', checksum: 2147483642) ])); - final stats = db.select( + final stats = await powersync.execute( 'SELECT row_type as type, row_id as id, count(*) as count FROM ps_oplog GROUP BY row_type, row_id ORDER BY row_type, row_id'); expect( stats, @@ -562,7 +562,7 @@ void main() { writeCheckpoint: '4', checksums: [BucketChecksum(bucket: 'bucket1', checksum: -3)])); - final stats = db.select( + final stats = await powersync.execute( 'SELECT row_type as type, row_id as id, count(*) as count FROM ps_oplog GROUP BY row_type, row_id ORDER BY row_type, row_id'); expect( stats, From b612549ae2a54e9ab3c0bbb9f0f4c62db862bb7c Mon Sep 17 00:00:00 2001 From: Ralf Kistner Date: Mon, 12 Aug 2024 15:39:35 +0200 Subject: [PATCH 3/3] Additional tests for REMOVE operations. --- .../powersync/test/bucket_storage_test.dart | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/packages/powersync/test/bucket_storage_test.dart b/packages/powersync/test/bucket_storage_test.dart index 2877a537..5fb123f9 100644 --- a/packages/powersync/test/bucket_storage_test.dart +++ b/packages/powersync/test/bucket_storage_test.dart @@ -170,6 +170,50 @@ void main() { await expectNoAssets(); }); + test('put then remove', () async { + await bucketStorage.saveSyncData(SyncDataBatch([ + SyncBucketData(bucket: 'bucket1', data: [putAsset1_3]), + ])); + + await syncLocalChecked(Checkpoint(lastOpId: '3', checksums: [ + BucketChecksum(bucket: 'bucket1', checksum: 3), + ])); + + await expectAsset1_3(); + + await bucketStorage.saveSyncData(SyncDataBatch([ + SyncBucketData(bucket: 'bucket1', data: [removeAsset1_5]) + ])); + + await syncLocalChecked(Checkpoint(lastOpId: '5', checksums: [ + BucketChecksum(bucket: 'bucket1', checksum: 8), + ])); + + await expectNoAssets(); + }); + + test('blank remove', () async { + await bucketStorage.saveSyncData(SyncDataBatch([ + SyncBucketData(bucket: 'bucket1', data: [putAsset1_3, removeAsset1_4]), + ])); + + await syncLocalChecked(Checkpoint(lastOpId: '4', checksums: [ + BucketChecksum(bucket: 'bucket1', checksum: 7), + ])); + + await expectNoAssets(); + + await bucketStorage.saveSyncData(SyncDataBatch([ + SyncBucketData(bucket: 'bucket1', data: [removeAsset1_5]) + ])); + + await syncLocalChecked(Checkpoint(lastOpId: '5', checksums: [ + BucketChecksum(bucket: 'bucket1', checksum: 12), + ])); + + await expectNoAssets(); + }); + test('should use subkeys', () async { // subkeys cause this to be treated as a separate entity in the oplog, // but same entity in the local db.