@powersync/service-core-tests 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/test-utils/general-utils.d.ts +9 -2
- package/dist/test-utils/general-utils.js +26 -2
- package/dist/test-utils/general-utils.js.map +1 -1
- package/dist/tests/register-compacting-tests.d.ts +1 -1
- package/dist/tests/register-compacting-tests.js +122 -68
- package/dist/tests/register-compacting-tests.js.map +1 -1
- package/dist/tests/register-data-storage-checkpoint-tests.d.ts +1 -1
- package/dist/tests/register-data-storage-checkpoint-tests.js +38 -6
- package/dist/tests/register-data-storage-checkpoint-tests.js.map +1 -1
- package/dist/tests/register-data-storage-data-tests.d.ts +2 -2
- package/dist/tests/register-data-storage-data-tests.js +666 -142
- package/dist/tests/register-data-storage-data-tests.js.map +1 -1
- package/dist/tests/register-data-storage-parameter-tests.d.ts +1 -1
- package/dist/tests/register-data-storage-parameter-tests.js +60 -33
- package/dist/tests/register-data-storage-parameter-tests.js.map +1 -1
- package/dist/tests/register-parameter-compacting-tests.d.ts +1 -1
- package/dist/tests/register-parameter-compacting-tests.js +8 -4
- package/dist/tests/register-parameter-compacting-tests.js.map +1 -1
- package/dist/tests/register-sync-tests.d.ts +2 -1
- package/dist/tests/register-sync-tests.js +40 -18
- package/dist/tests/register-sync-tests.js.map +1 -1
- package/dist/tests/util.d.ts +5 -4
- package/dist/tests/util.js +27 -12
- package/dist/tests/util.js.map +1 -1
- package/package.json +3 -3
- package/src/test-utils/general-utils.ts +41 -3
- package/src/tests/register-compacting-tests.ts +127 -82
- package/src/tests/register-data-storage-checkpoint-tests.ts +64 -11
- package/src/tests/register-data-storage-data-tests.ts +640 -52
- package/src/tests/register-data-storage-parameter-tests.ts +101 -47
- package/src/tests/register-parameter-compacting-tests.ts +9 -4
- package/src/tests/register-sync-tests.ts +45 -19
- package/src/tests/util.ts +46 -17
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -14,14 +14,11 @@ import * as timers from 'timers/promises';
|
|
|
14
14
|
import { fileURLToPath } from 'url';
|
|
15
15
|
import { expect, test } from 'vitest';
|
|
16
16
|
import * as test_utils from '../test-utils/test-utils-index.js';
|
|
17
|
-
import { METRICS_HELPER } from '../test-utils/test-utils-index.js';
|
|
18
|
-
import { bucketRequest } from './util.js';
|
|
17
|
+
import { bucketRequest, METRICS_HELPER } from '../test-utils/test-utils-index.js';
|
|
19
18
|
|
|
20
19
|
const __filename = fileURLToPath(import.meta.url);
|
|
21
20
|
const __dirname = path.dirname(__filename);
|
|
22
21
|
|
|
23
|
-
const TEST_TABLE = test_utils.makeTestTable('test', ['id']);
|
|
24
|
-
|
|
25
22
|
const BASIC_SYNC_RULES = `
|
|
26
23
|
bucket_definitions:
|
|
27
24
|
mybucket:
|
|
@@ -39,7 +36,15 @@ export const SYNC_SNAPSHOT_PATH = path.resolve(__dirname, '../__snapshots/sync.t
|
|
|
39
36
|
* });
|
|
40
37
|
* ```
|
|
41
38
|
*/
|
|
42
|
-
export function registerSyncTests(
|
|
39
|
+
export function registerSyncTests(
|
|
40
|
+
configOrFactory: storage.TestStorageConfig | storage.TestStorageFactory,
|
|
41
|
+
options: { storageVersion?: number; tableIdStrings?: boolean } = {}
|
|
42
|
+
) {
|
|
43
|
+
const config: storage.TestStorageConfig =
|
|
44
|
+
typeof configOrFactory == 'function'
|
|
45
|
+
? { factory: configOrFactory, tableIdStrings: options.tableIdStrings ?? true }
|
|
46
|
+
: configOrFactory;
|
|
47
|
+
const factory = config.factory;
|
|
43
48
|
createCoreAPIMetrics(METRICS_HELPER.metricsEngine);
|
|
44
49
|
const tracker = new sync.RequestTracker(METRICS_HELPER.metricsEngine);
|
|
45
50
|
const syncContext = new sync.SyncContext({
|
|
@@ -48,6 +53,7 @@ export function registerSyncTests(factory: storage.TestStorageFactory, options:
|
|
|
48
53
|
maxDataFetchConcurrency: 2
|
|
49
54
|
});
|
|
50
55
|
|
|
56
|
+
const TEST_TABLE = test_utils.makeTestTable('test', ['id'], config);
|
|
51
57
|
const updateSyncRules = (bucketStorageFactory: storage.BucketStorageFactory, updateOptions: { content: string }) => {
|
|
52
58
|
return bucketStorageFactory.updateSyncRules(
|
|
53
59
|
updateSyncRulesFromYaml(updateOptions.content, {
|
|
@@ -66,7 +72,9 @@ export function registerSyncTests(factory: storage.TestStorageFactory, options:
|
|
|
66
72
|
|
|
67
73
|
const bucketStorage = f.getInstance(syncRules);
|
|
68
74
|
|
|
69
|
-
|
|
75
|
+
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
76
|
+
await batch.markAllSnapshotDone('0/1');
|
|
77
|
+
|
|
70
78
|
await batch.save({
|
|
71
79
|
sourceTable: TEST_TABLE,
|
|
72
80
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -127,7 +135,8 @@ bucket_definitions:
|
|
|
127
135
|
|
|
128
136
|
const bucketStorage = f.getInstance(syncRules);
|
|
129
137
|
|
|
130
|
-
|
|
138
|
+
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
139
|
+
await batch.markAllSnapshotDone('0/1');
|
|
131
140
|
await batch.save({
|
|
132
141
|
sourceTable: TEST_TABLE,
|
|
133
142
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -189,6 +198,7 @@ bucket_definitions:
|
|
|
189
198
|
const bucketStorage = f.getInstance(syncRules);
|
|
190
199
|
|
|
191
200
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
201
|
+
await batch.markAllSnapshotDone('0/1');
|
|
192
202
|
// Initial data: Add one priority row and 10k low-priority rows.
|
|
193
203
|
await batch.save({
|
|
194
204
|
sourceTable: TEST_TABLE,
|
|
@@ -299,6 +309,7 @@ bucket_definitions:
|
|
|
299
309
|
const bucketStorage = f.getInstance(syncRules);
|
|
300
310
|
|
|
301
311
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
312
|
+
await batch.markAllSnapshotDone('0/1');
|
|
302
313
|
// Initial data: Add one priority row and 10k low-priority rows.
|
|
303
314
|
await batch.save({
|
|
304
315
|
sourceTable: TEST_TABLE,
|
|
@@ -440,6 +451,7 @@ bucket_definitions:
|
|
|
440
451
|
const bucketStorage = f.getInstance(syncRules);
|
|
441
452
|
|
|
442
453
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
454
|
+
await batch.markAllSnapshotDone('0/1');
|
|
443
455
|
// Initial data: Add one priority row and 10k low-priority rows.
|
|
444
456
|
await batch.save({
|
|
445
457
|
sourceTable: TEST_TABLE,
|
|
@@ -569,6 +581,7 @@ bucket_definitions:
|
|
|
569
581
|
const bucketStorage = f.getInstance(syncRules);
|
|
570
582
|
|
|
571
583
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
584
|
+
await batch.markAllSnapshotDone('0/1');
|
|
572
585
|
await batch.save({
|
|
573
586
|
sourceTable: TEST_TABLE,
|
|
574
587
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -633,6 +646,7 @@ bucket_definitions:
|
|
|
633
646
|
const bucketStorage = await f.getInstance(syncRules);
|
|
634
647
|
|
|
635
648
|
const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
649
|
+
await batch.markAllSnapshotDone('0/1');
|
|
636
650
|
await batch.save({
|
|
637
651
|
sourceTable: TEST_TABLE,
|
|
638
652
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -704,6 +718,7 @@ bucket_definitions:
|
|
|
704
718
|
const bucketStorage = await f.getInstance(syncRules);
|
|
705
719
|
// Activate
|
|
706
720
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
721
|
+
await batch.markAllSnapshotDone('0/0');
|
|
707
722
|
await batch.keepalive('0/0');
|
|
708
723
|
});
|
|
709
724
|
|
|
@@ -772,12 +787,13 @@ bucket_definitions:
|
|
|
772
787
|
`
|
|
773
788
|
});
|
|
774
789
|
|
|
775
|
-
const usersTable = test_utils.makeTestTable('users', ['id']);
|
|
776
|
-
const listsTable = test_utils.makeTestTable('lists', ['id']);
|
|
790
|
+
const usersTable = test_utils.makeTestTable('users', ['id'], config);
|
|
791
|
+
const listsTable = test_utils.makeTestTable('lists', ['id'], config);
|
|
777
792
|
|
|
778
793
|
const bucketStorage = await f.getInstance(syncRules);
|
|
779
794
|
// Activate
|
|
780
795
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
796
|
+
await batch.markAllSnapshotDone('0/0');
|
|
781
797
|
await batch.keepalive('0/0');
|
|
782
798
|
});
|
|
783
799
|
|
|
@@ -819,10 +835,11 @@ bucket_definitions:
|
|
|
819
835
|
await batch.commit('0/1');
|
|
820
836
|
});
|
|
821
837
|
|
|
838
|
+
const { bucket } = bucketRequest(syncRules, 'by_user["user1"]');
|
|
822
839
|
const checkpoint2 = await getCheckpointLines(iter);
|
|
823
840
|
expect(
|
|
824
841
|
(checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
|
|
825
|
-
).toEqual([
|
|
842
|
+
).toEqual([bucket]);
|
|
826
843
|
expect(checkpoint2).toMatchSnapshot();
|
|
827
844
|
});
|
|
828
845
|
|
|
@@ -838,12 +855,13 @@ bucket_definitions:
|
|
|
838
855
|
`
|
|
839
856
|
});
|
|
840
857
|
|
|
841
|
-
const usersTable = test_utils.makeTestTable('users', ['id']);
|
|
842
|
-
const listsTable = test_utils.makeTestTable('lists', ['id']);
|
|
858
|
+
const usersTable = test_utils.makeTestTable('users', ['id'], config);
|
|
859
|
+
const listsTable = test_utils.makeTestTable('lists', ['id'], config);
|
|
843
860
|
|
|
844
861
|
const bucketStorage = await f.getInstance(syncRules);
|
|
845
862
|
|
|
846
863
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
864
|
+
await batch.markAllSnapshotDone('0/1');
|
|
847
865
|
await batch.save({
|
|
848
866
|
sourceTable: usersTable,
|
|
849
867
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -875,10 +893,9 @@ bucket_definitions:
|
|
|
875
893
|
iter.return?.();
|
|
876
894
|
});
|
|
877
895
|
|
|
896
|
+
const { bucket } = bucketRequest(syncRules, 'by_user["user1"]');
|
|
878
897
|
const checkpoint1 = await getCheckpointLines(iter);
|
|
879
|
-
expect((checkpoint1[0] as StreamingSyncCheckpoint).checkpoint?.buckets?.map((b) => b.bucket)).toEqual([
|
|
880
|
-
bucketRequest(syncRules, 'by_user["user1"]')
|
|
881
|
-
]);
|
|
898
|
+
expect((checkpoint1[0] as StreamingSyncCheckpoint).checkpoint?.buckets?.map((b) => b.bucket)).toEqual([bucket]);
|
|
882
899
|
expect(checkpoint1).toMatchSnapshot();
|
|
883
900
|
|
|
884
901
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
@@ -899,7 +916,7 @@ bucket_definitions:
|
|
|
899
916
|
const checkpoint2 = await getCheckpointLines(iter);
|
|
900
917
|
expect(
|
|
901
918
|
(checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
|
|
902
|
-
).toEqual([
|
|
919
|
+
).toEqual([bucket]);
|
|
903
920
|
expect(checkpoint2).toMatchSnapshot();
|
|
904
921
|
});
|
|
905
922
|
|
|
@@ -915,12 +932,13 @@ bucket_definitions:
|
|
|
915
932
|
`
|
|
916
933
|
});
|
|
917
934
|
|
|
918
|
-
const usersTable = test_utils.makeTestTable('users', ['id']);
|
|
919
|
-
const listsTable = test_utils.makeTestTable('lists', ['id']);
|
|
935
|
+
const usersTable = test_utils.makeTestTable('users', ['id'], config);
|
|
936
|
+
const listsTable = test_utils.makeTestTable('lists', ['id'], config);
|
|
920
937
|
|
|
921
938
|
const bucketStorage = await f.getInstance(syncRules);
|
|
922
939
|
// Activate
|
|
923
940
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
941
|
+
await batch.markAllSnapshotDone('0/0');
|
|
924
942
|
await batch.keepalive('0/0');
|
|
925
943
|
});
|
|
926
944
|
|
|
@@ -946,6 +964,7 @@ bucket_definitions:
|
|
|
946
964
|
expect(await getCheckpointLines(iter)).toMatchSnapshot();
|
|
947
965
|
|
|
948
966
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
967
|
+
await batch.markAllSnapshotDone('0/1');
|
|
949
968
|
await batch.save({
|
|
950
969
|
sourceTable: listsTable,
|
|
951
970
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -970,10 +989,11 @@ bucket_definitions:
|
|
|
970
989
|
await batch.commit('0/1');
|
|
971
990
|
});
|
|
972
991
|
|
|
992
|
+
const { bucket } = bucketRequest(syncRules, 'by_user["user1"]');
|
|
973
993
|
const checkpoint2 = await getCheckpointLines(iter);
|
|
974
994
|
expect(
|
|
975
995
|
(checkpoint2[0] as StreamingSyncCheckpointDiff).checkpoint_diff?.updated_buckets?.map((b) => b.bucket)
|
|
976
|
-
).toEqual([
|
|
996
|
+
).toEqual([bucket]);
|
|
977
997
|
expect(checkpoint2).toMatchSnapshot();
|
|
978
998
|
});
|
|
979
999
|
|
|
@@ -987,6 +1007,7 @@ bucket_definitions:
|
|
|
987
1007
|
const bucketStorage = await f.getInstance(syncRules);
|
|
988
1008
|
// Activate
|
|
989
1009
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
1010
|
+
await batch.markAllSnapshotDone('0/0');
|
|
990
1011
|
await batch.keepalive('0/0');
|
|
991
1012
|
});
|
|
992
1013
|
|
|
@@ -1032,6 +1053,7 @@ bucket_definitions:
|
|
|
1032
1053
|
const bucketStorage = await f.getInstance(syncRules);
|
|
1033
1054
|
|
|
1034
1055
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
1056
|
+
await batch.markAllSnapshotDone('0/1');
|
|
1035
1057
|
await batch.save({
|
|
1036
1058
|
sourceTable: TEST_TABLE,
|
|
1037
1059
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -1087,6 +1109,7 @@ bucket_definitions:
|
|
|
1087
1109
|
// This invalidates the checkpoint we've received above.
|
|
1088
1110
|
|
|
1089
1111
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
1112
|
+
await batch.markAllSnapshotDone('0/1');
|
|
1090
1113
|
await batch.save({
|
|
1091
1114
|
sourceTable: TEST_TABLE,
|
|
1092
1115
|
tag: storage.SaveOperationTag.UPDATE,
|
|
@@ -1175,6 +1198,7 @@ bucket_definitions:
|
|
|
1175
1198
|
const bucketStorage = f.getInstance(syncRules);
|
|
1176
1199
|
|
|
1177
1200
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
1201
|
+
await batch.markAllSnapshotDone('0/1');
|
|
1178
1202
|
// <= the managed write checkpoint LSN below
|
|
1179
1203
|
await batch.commit('0/1');
|
|
1180
1204
|
});
|
|
@@ -1210,6 +1234,7 @@ bucket_definitions:
|
|
|
1210
1234
|
});
|
|
1211
1235
|
|
|
1212
1236
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
1237
|
+
await batch.markAllSnapshotDone('0/1');
|
|
1213
1238
|
// must be >= the managed write checkpoint LSN
|
|
1214
1239
|
await batch.commit('1/0');
|
|
1215
1240
|
});
|
|
@@ -1245,6 +1270,7 @@ config:
|
|
|
1245
1270
|
const bucketStorage = f.getInstance(syncRules);
|
|
1246
1271
|
|
|
1247
1272
|
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
1273
|
+
await batch.markAllSnapshotDone('0/1');
|
|
1248
1274
|
await batch.save({
|
|
1249
1275
|
sourceTable: TEST_TABLE,
|
|
1250
1276
|
tag: storage.SaveOperationTag.INSERT,
|
package/src/tests/util.ts
CHANGED
|
@@ -1,24 +1,53 @@
|
|
|
1
1
|
import { storage } from '@powersync/service-core';
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
ParameterIndexLookupCreator,
|
|
4
|
+
SourceTableInterface,
|
|
5
|
+
SqliteRow,
|
|
6
|
+
TablePattern
|
|
7
|
+
} from '@powersync/service-sync-rules';
|
|
8
|
+
import { ParameterLookupScope } from '@powersync/service-sync-rules/src/HydrationState.js';
|
|
9
|
+
import { bucketRequest } from '../test-utils/general-utils.js';
|
|
3
10
|
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const versionedBuckets = storage.STORAGE_VERSION_CONFIG[syncRules.storageVersion]?.versionedBuckets ?? false;
|
|
12
|
-
return versionedBuckets ? `${syncRules.id}#${bucketName}` : bucketName;
|
|
11
|
+
export function bucketRequestMap(
|
|
12
|
+
syncRules: storage.PersistedSyncRulesContent,
|
|
13
|
+
buckets: Iterable<readonly [string, bigint]>
|
|
14
|
+
): storage.BucketDataRequest[] {
|
|
15
|
+
return Array.from(buckets, ([bucketName, opId]) => bucketRequest(syncRules, bucketName, opId));
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
export function bucketRequests(
|
|
16
|
-
|
|
18
|
+
export function bucketRequests(
|
|
19
|
+
syncRules: storage.PersistedSyncRulesContent,
|
|
20
|
+
bucketNames: string[]
|
|
21
|
+
): storage.BucketChecksumRequest[] {
|
|
22
|
+
return bucketNames.map((bucketName) => {
|
|
23
|
+
const request = bucketRequest(syncRules, bucketName, 0n);
|
|
24
|
+
return { bucket: request.bucket, source: request.source };
|
|
25
|
+
});
|
|
17
26
|
}
|
|
18
27
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
28
|
+
const EMPTY_LOOKUP_SOURCE: ParameterIndexLookupCreator = {
|
|
29
|
+
get defaultLookupScope(): ParameterLookupScope {
|
|
30
|
+
return {
|
|
31
|
+
lookupName: 'lookup',
|
|
32
|
+
queryId: '0',
|
|
33
|
+
source: EMPTY_LOOKUP_SOURCE
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
getSourceTables(): Set<TablePattern> {
|
|
37
|
+
return new Set();
|
|
38
|
+
},
|
|
39
|
+
evaluateParameterRow(_sourceTable: SourceTableInterface, _row: SqliteRow) {
|
|
40
|
+
return [];
|
|
41
|
+
},
|
|
42
|
+
tableSyncsParameters(_table: SourceTableInterface): boolean {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export function parameterLookupScope(
|
|
48
|
+
lookupName: string,
|
|
49
|
+
queryId: string,
|
|
50
|
+
source: ParameterIndexLookupCreator = EMPTY_LOOKUP_SOURCE
|
|
51
|
+
): ParameterLookupScope {
|
|
52
|
+
return { lookupName, queryId, source };
|
|
24
53
|
}
|