@powersync/service-core-tests 0.0.0-dev-20260602073133 → 0.0.0-dev-20260909133214
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 +112 -4
- package/dist/test-utils/AbstractStreamTestContext.d.ts +7 -6
- package/dist/test-utils/AbstractStreamTestContext.js +28 -25
- package/dist/test-utils/AbstractStreamTestContext.js.map +1 -1
- package/dist/test-utils/StorageDataHelpers.d.ts +6 -5
- package/dist/test-utils/StorageDataHelpers.js +40 -2
- package/dist/test-utils/StorageDataHelpers.js.map +1 -1
- package/dist/test-utils/bucket-validation.d.ts +3 -3
- package/dist/test-utils/bucket-validation.js +3 -3
- package/dist/test-utils/general-utils.d.ts +16 -3
- package/dist/test-utils/general-utils.js +37 -4
- package/dist/test-utils/general-utils.js.map +1 -1
- package/dist/test-utils/storage-combinations.d.ts +13 -0
- package/dist/test-utils/storage-combinations.js +26 -0
- package/dist/test-utils/storage-combinations.js.map +1 -0
- package/dist/test-utils/stream_utils.d.ts +0 -1
- package/dist/test-utils/stream_utils.js +0 -10
- package/dist/test-utils/stream_utils.js.map +1 -1
- package/dist/test-utils/test-utils-index.d.ts +1 -0
- package/dist/test-utils/test-utils-index.js +1 -0
- package/dist/test-utils/test-utils-index.js.map +1 -1
- package/dist/tests/register-compacting-tests.js +36 -29
- package/dist/tests/register-compacting-tests.js.map +1 -1
- package/dist/tests/register-data-storage-checkpoint-tests.js +138 -14
- package/dist/tests/register-data-storage-checkpoint-tests.js.map +1 -1
- package/dist/tests/register-data-storage-data-tests.js +205 -138
- package/dist/tests/register-data-storage-data-tests.js.map +1 -1
- package/dist/tests/register-data-storage-parameter-tests.js +44 -42
- package/dist/tests/register-data-storage-parameter-tests.js.map +1 -1
- package/dist/tests/register-parameter-compacting-tests.js +3 -2
- package/dist/tests/register-parameter-compacting-tests.js.map +1 -1
- package/dist/tests/register-sync-tests.js +404 -86
- package/dist/tests/register-sync-tests.js.map +1 -1
- package/dist/tests/util.d.ts +8 -2
- package/dist/tests/util.js +12 -0
- package/dist/tests/util.js.map +1 -1
- package/package.json +5 -6
- package/src/test-utils/AbstractStreamTestContext.ts +31 -27
- package/src/test-utils/StorageDataHelpers.ts +52 -8
- package/src/test-utils/bucket-validation.ts +3 -3
- package/src/test-utils/general-utils.ts +62 -10
- package/src/test-utils/storage-combinations.ts +51 -0
- package/src/test-utils/stream_utils.ts +0 -11
- package/src/test-utils/test-utils-index.ts +1 -0
- package/src/tests/register-compacting-tests.ts +55 -32
- package/src/tests/register-data-storage-checkpoint-tests.ts +171 -14
- package/src/tests/register-data-storage-data-tests.ts +251 -150
- package/src/tests/register-data-storage-parameter-tests.ts +58 -42
- package/src/tests/register-parameter-compacting-tests.ts +3 -2
- package/src/tests/register-sync-tests.ts +443 -88
- package/src/tests/util.ts +15 -2
- package/tsconfig.json +1 -4
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -38,7 +38,8 @@ export function registerDataStorageDataTests(config: storage.TestStorageConfig)
|
|
|
38
38
|
|
|
39
39
|
test('removing row', async () => {
|
|
40
40
|
await using factory = await generateStorageFactory();
|
|
41
|
-
const syncRules = await
|
|
41
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
42
|
+
factory,
|
|
42
43
|
updateSyncRulesFromYaml(
|
|
43
44
|
`
|
|
44
45
|
bucket_definitions:
|
|
@@ -49,7 +50,7 @@ bucket_definitions:
|
|
|
49
50
|
{ storageVersion }
|
|
50
51
|
)
|
|
51
52
|
);
|
|
52
|
-
const bucketStorage = factory.getInstance(
|
|
53
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
53
54
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
54
55
|
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
55
56
|
|
|
@@ -71,10 +72,10 @@ bucket_definitions:
|
|
|
71
72
|
});
|
|
72
73
|
await writer.commit('1/1');
|
|
73
74
|
|
|
74
|
-
const
|
|
75
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
75
76
|
|
|
76
77
|
const request = bucketRequest(syncRules, 'global[]');
|
|
77
|
-
const batch = await test_utils.
|
|
78
|
+
const batch = await test_utils.getBatchArray(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
78
79
|
const data = batch[0].chunkData.data.map((d) => {
|
|
79
80
|
return {
|
|
80
81
|
op: d.op,
|
|
@@ -103,7 +104,8 @@ bucket_definitions:
|
|
|
103
104
|
|
|
104
105
|
test('insert after delete in new batch', async () => {
|
|
105
106
|
await using factory = await generateStorageFactory();
|
|
106
|
-
const syncRules = await
|
|
107
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
108
|
+
factory,
|
|
107
109
|
updateSyncRulesFromYaml(
|
|
108
110
|
`
|
|
109
111
|
bucket_definitions:
|
|
@@ -114,7 +116,7 @@ bucket_definitions:
|
|
|
114
116
|
{ storageVersion }
|
|
115
117
|
)
|
|
116
118
|
);
|
|
117
|
-
const bucketStorage = factory.getInstance(
|
|
119
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
118
120
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
119
121
|
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
120
122
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -138,10 +140,10 @@ bucket_definitions:
|
|
|
138
140
|
});
|
|
139
141
|
await writer.commit('2/1');
|
|
140
142
|
|
|
141
|
-
const
|
|
143
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
142
144
|
|
|
143
145
|
const request = bucketRequest(syncRules, 'global[]');
|
|
144
|
-
const batch = await test_utils.
|
|
146
|
+
const batch = await test_utils.getBatchArray(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
145
147
|
const data = batch[0].chunkData.data.map((d) => {
|
|
146
148
|
return {
|
|
147
149
|
op: d.op,
|
|
@@ -167,7 +169,8 @@ bucket_definitions:
|
|
|
167
169
|
test('update after delete in new batch', async () => {
|
|
168
170
|
// Update after delete may not be common, but the storage layer should handle it in an eventually-consistent way.
|
|
169
171
|
await using factory = await generateStorageFactory();
|
|
170
|
-
const syncRules = await
|
|
172
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
173
|
+
factory,
|
|
171
174
|
updateSyncRulesFromYaml(
|
|
172
175
|
`
|
|
173
176
|
bucket_definitions:
|
|
@@ -178,7 +181,7 @@ bucket_definitions:
|
|
|
178
181
|
{ storageVersion }
|
|
179
182
|
)
|
|
180
183
|
);
|
|
181
|
-
const bucketStorage = factory.getInstance(
|
|
184
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
182
185
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
183
186
|
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
184
187
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -206,10 +209,10 @@ bucket_definitions:
|
|
|
206
209
|
});
|
|
207
210
|
await writer.commit('2/1');
|
|
208
211
|
|
|
209
|
-
const
|
|
212
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
210
213
|
|
|
211
214
|
const request = bucketRequest(syncRules, 'global[]');
|
|
212
|
-
const batch = await test_utils.
|
|
215
|
+
const batch = await test_utils.getBatchArray(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
213
216
|
const data = batch[0].chunkData.data.map((d) => {
|
|
214
217
|
return {
|
|
215
218
|
op: d.op,
|
|
@@ -234,7 +237,8 @@ bucket_definitions:
|
|
|
234
237
|
|
|
235
238
|
test('insert after delete in same batch', async () => {
|
|
236
239
|
await using factory = await generateStorageFactory();
|
|
237
|
-
const syncRules = await
|
|
240
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
241
|
+
factory,
|
|
238
242
|
updateSyncRulesFromYaml(
|
|
239
243
|
`
|
|
240
244
|
bucket_definitions:
|
|
@@ -247,7 +251,7 @@ bucket_definitions:
|
|
|
247
251
|
}
|
|
248
252
|
)
|
|
249
253
|
);
|
|
250
|
-
const bucketStorage = factory.getInstance(
|
|
254
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
251
255
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
252
256
|
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
253
257
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -268,10 +272,10 @@ bucket_definitions:
|
|
|
268
272
|
});
|
|
269
273
|
await writer.commit('1/1');
|
|
270
274
|
|
|
271
|
-
const
|
|
275
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
272
276
|
|
|
273
277
|
const request = bucketRequest(syncRules, 'global[]');
|
|
274
|
-
const batch = await test_utils.
|
|
278
|
+
const batch = await test_utils.getBatchArray(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
275
279
|
const data = batch[0].chunkData.data.map((d) => {
|
|
276
280
|
return {
|
|
277
281
|
op: d.op,
|
|
@@ -296,7 +300,8 @@ bucket_definitions:
|
|
|
296
300
|
|
|
297
301
|
test('(insert, delete, insert), (delete)', async () => {
|
|
298
302
|
await using factory = await generateStorageFactory();
|
|
299
|
-
const syncRules = await
|
|
303
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
304
|
+
factory,
|
|
300
305
|
updateSyncRulesFromYaml(
|
|
301
306
|
`
|
|
302
307
|
bucket_definitions:
|
|
@@ -309,7 +314,7 @@ bucket_definitions:
|
|
|
309
314
|
}
|
|
310
315
|
)
|
|
311
316
|
);
|
|
312
|
-
const bucketStorage = factory.getInstance(
|
|
317
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
313
318
|
{
|
|
314
319
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
315
320
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
@@ -354,10 +359,10 @@ bucket_definitions:
|
|
|
354
359
|
await writer.commit('2/1');
|
|
355
360
|
}
|
|
356
361
|
|
|
357
|
-
const
|
|
362
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
358
363
|
|
|
359
364
|
const request = bucketRequest(syncRules, 'global[]');
|
|
360
|
-
const batch = await test_utils.
|
|
365
|
+
const batch = await test_utils.getBatchArray(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
361
366
|
|
|
362
367
|
expect(reduceBucket(batch[0].chunkData.data).slice(1)).toEqual([]);
|
|
363
368
|
|
|
@@ -374,7 +379,8 @@ bucket_definitions:
|
|
|
374
379
|
|
|
375
380
|
test('changing client ids', async () => {
|
|
376
381
|
await using factory = await generateStorageFactory();
|
|
377
|
-
const syncRules = await
|
|
382
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
383
|
+
factory,
|
|
378
384
|
updateSyncRulesFromYaml(
|
|
379
385
|
`
|
|
380
386
|
bucket_definitions:
|
|
@@ -387,7 +393,7 @@ bucket_definitions:
|
|
|
387
393
|
}
|
|
388
394
|
)
|
|
389
395
|
);
|
|
390
|
-
const bucketStorage = factory.getInstance(
|
|
396
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
391
397
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
392
398
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
393
399
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -424,8 +430,8 @@ bucket_definitions:
|
|
|
424
430
|
});
|
|
425
431
|
|
|
426
432
|
await writer.commit('1/1');
|
|
427
|
-
const
|
|
428
|
-
const batch = await test_utils.
|
|
433
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
434
|
+
const batch = await test_utils.getBatchArray(
|
|
429
435
|
bucketStorage.getBucketDataBatch(checkpoint, [bucketRequest(syncRules, 'global[]')])
|
|
430
436
|
);
|
|
431
437
|
const data = batch[0].chunkData.data.map((d) => {
|
|
@@ -445,7 +451,8 @@ bucket_definitions:
|
|
|
445
451
|
|
|
446
452
|
test('re-apply delete', async () => {
|
|
447
453
|
await using factory = await generateStorageFactory();
|
|
448
|
-
const syncRules = await
|
|
454
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
455
|
+
factory,
|
|
449
456
|
updateSyncRulesFromYaml(
|
|
450
457
|
`
|
|
451
458
|
bucket_definitions:
|
|
@@ -458,7 +465,7 @@ bucket_definitions:
|
|
|
458
465
|
}
|
|
459
466
|
)
|
|
460
467
|
);
|
|
461
|
-
const bucketStorage = factory.getInstance(
|
|
468
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
462
469
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
463
470
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
464
471
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -489,10 +496,10 @@ bucket_definitions:
|
|
|
489
496
|
});
|
|
490
497
|
await writer.flush();
|
|
491
498
|
|
|
492
|
-
const
|
|
499
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
493
500
|
|
|
494
501
|
const request = bucketRequest(syncRules, 'global[]');
|
|
495
|
-
const batch = await test_utils.
|
|
502
|
+
const batch = await test_utils.getBatchArray(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
496
503
|
const data = batch[0].chunkData.data.map((d) => {
|
|
497
504
|
return {
|
|
498
505
|
op: d.op,
|
|
@@ -521,7 +528,8 @@ bucket_definitions:
|
|
|
521
528
|
|
|
522
529
|
test('re-apply update + delete', async () => {
|
|
523
530
|
await using factory = await generateStorageFactory();
|
|
524
|
-
const syncRules = await
|
|
531
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
532
|
+
factory,
|
|
525
533
|
updateSyncRulesFromYaml(
|
|
526
534
|
`
|
|
527
535
|
bucket_definitions:
|
|
@@ -532,7 +540,7 @@ bucket_definitions:
|
|
|
532
540
|
{ storageVersion }
|
|
533
541
|
)
|
|
534
542
|
);
|
|
535
|
-
const bucketStorage = factory.getInstance(
|
|
543
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
536
544
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
537
545
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
538
546
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -608,10 +616,10 @@ bucket_definitions:
|
|
|
608
616
|
|
|
609
617
|
await writer.commit('2/1');
|
|
610
618
|
|
|
611
|
-
const
|
|
619
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
612
620
|
|
|
613
621
|
const request = bucketRequest(syncRules, 'global[]');
|
|
614
|
-
const batch = await test_utils.
|
|
622
|
+
const batch = await test_utils.getBatchArray(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
615
623
|
|
|
616
624
|
const data = batch[0].chunkData.data.map((d) => {
|
|
617
625
|
return {
|
|
@@ -651,7 +659,8 @@ bucket_definitions:
|
|
|
651
659
|
// 2. Output order not being correct.
|
|
652
660
|
|
|
653
661
|
await using factory = await generateStorageFactory();
|
|
654
|
-
const syncRules = await
|
|
662
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
663
|
+
factory,
|
|
655
664
|
updateSyncRulesFromYaml(
|
|
656
665
|
`
|
|
657
666
|
bucket_definitions:
|
|
@@ -662,7 +671,7 @@ bucket_definitions:
|
|
|
662
671
|
{ storageVersion }
|
|
663
672
|
)
|
|
664
673
|
);
|
|
665
|
-
const bucketStorage = factory.getInstance(
|
|
674
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
666
675
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
667
676
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
668
677
|
|
|
@@ -773,7 +782,9 @@ bucket_definitions:
|
|
|
773
782
|
const checkpoint2 = result2!.flushed_op;
|
|
774
783
|
|
|
775
784
|
const request = bucketRequest(syncRules, 'global[]', checkpoint1);
|
|
776
|
-
const batch = await test_utils.
|
|
785
|
+
const batch = await test_utils.getBatchArray(
|
|
786
|
+
bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint2), [request])
|
|
787
|
+
);
|
|
777
788
|
|
|
778
789
|
const data = batch[0].chunkData.data.map((d) => {
|
|
779
790
|
return {
|
|
@@ -810,7 +821,8 @@ bucket_definitions:
|
|
|
810
821
|
]);
|
|
811
822
|
}
|
|
812
823
|
await using factory = await generateStorageFactory();
|
|
813
|
-
const syncRules = await
|
|
824
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
825
|
+
factory,
|
|
814
826
|
updateSyncRulesFromYaml(
|
|
815
827
|
`
|
|
816
828
|
bucket_definitions:
|
|
@@ -823,7 +835,7 @@ bucket_definitions:
|
|
|
823
835
|
}
|
|
824
836
|
)
|
|
825
837
|
);
|
|
826
|
-
const bucketStorage = factory.getInstance(
|
|
838
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
827
839
|
|
|
828
840
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
829
841
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id', 'description'], config);
|
|
@@ -876,8 +888,8 @@ bucket_definitions:
|
|
|
876
888
|
const checkpoint3 = result3!.flushed_op;
|
|
877
889
|
|
|
878
890
|
const request = bucketRequest(syncRules, 'global[]');
|
|
879
|
-
const batch = await test_utils.
|
|
880
|
-
bucketStorage.getBucketDataBatch(checkpoint3, [{ ...request, start: checkpoint1 }])
|
|
891
|
+
const batch = await test_utils.getBatchArray(
|
|
892
|
+
bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint3), [{ ...request, start: checkpoint1 }])
|
|
881
893
|
);
|
|
882
894
|
const data = batch[0].chunkData.data.map((d) => {
|
|
883
895
|
return {
|
|
@@ -923,7 +935,8 @@ bucket_definitions:
|
|
|
923
935
|
}
|
|
924
936
|
|
|
925
937
|
await using factory = await generateStorageFactory();
|
|
926
|
-
const syncRules = await
|
|
938
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
939
|
+
factory,
|
|
927
940
|
updateSyncRulesFromYaml(
|
|
928
941
|
`
|
|
929
942
|
bucket_definitions:
|
|
@@ -936,7 +949,7 @@ bucket_definitions:
|
|
|
936
949
|
}
|
|
937
950
|
)
|
|
938
951
|
);
|
|
939
|
-
const bucketStorage = factory.getInstance(
|
|
952
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
940
953
|
|
|
941
954
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
942
955
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id', 'description'], config);
|
|
@@ -989,8 +1002,8 @@ bucket_definitions:
|
|
|
989
1002
|
const checkpoint3 = result3!.flushed_op;
|
|
990
1003
|
|
|
991
1004
|
const request = bucketRequest(syncRules, 'global[]');
|
|
992
|
-
const batch = await test_utils.
|
|
993
|
-
bucketStorage.getBucketDataBatch(checkpoint3, [{ ...request, start: checkpoint1 }])
|
|
1005
|
+
const batch = await test_utils.getBatchArray(
|
|
1006
|
+
bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint3), [{ ...request, start: checkpoint1 }])
|
|
994
1007
|
);
|
|
995
1008
|
const data = batch[0].chunkData.data.map((d) => {
|
|
996
1009
|
return {
|
|
@@ -1026,7 +1039,8 @@ bucket_definitions:
|
|
|
1026
1039
|
// The specific batch splits is an implementation detail of the storage driver,
|
|
1027
1040
|
// and the test will have to updated when other implementations are added.
|
|
1028
1041
|
await using factory = await generateStorageFactory();
|
|
1029
|
-
const syncRules = await
|
|
1042
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
1043
|
+
factory,
|
|
1030
1044
|
updateSyncRulesFromYaml(
|
|
1031
1045
|
`
|
|
1032
1046
|
bucket_definitions:
|
|
@@ -1039,7 +1053,7 @@ bucket_definitions:
|
|
|
1039
1053
|
}
|
|
1040
1054
|
)
|
|
1041
1055
|
);
|
|
1042
|
-
const bucketStorage = factory.getInstance(
|
|
1056
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1043
1057
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1044
1058
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
1045
1059
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -1089,14 +1103,14 @@ bucket_definitions:
|
|
|
1089
1103
|
|
|
1090
1104
|
await writer.commit('1/1');
|
|
1091
1105
|
|
|
1092
|
-
const
|
|
1106
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
1093
1107
|
|
|
1094
1108
|
const options: storage.BucketDataBatchOptions = {
|
|
1095
1109
|
chunkLimitBytes: 16 * 1024 * 1024
|
|
1096
1110
|
};
|
|
1097
1111
|
|
|
1098
1112
|
const request = bucketRequest(syncRules, 'global[]');
|
|
1099
|
-
const batch1 = await test_utils.
|
|
1113
|
+
const batch1 = await test_utils.getBatchArray(bucketStorage.getBucketDataBatch(checkpoint, [request], options));
|
|
1100
1114
|
expect(test_utils.getBatchData(batch1)).toEqual([
|
|
1101
1115
|
{ op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 },
|
|
1102
1116
|
{ op_id: '2', op: 'PUT', object_id: 'large1', checksum: 454746904 }
|
|
@@ -1107,7 +1121,7 @@ bucket_definitions:
|
|
|
1107
1121
|
next_after: '2'
|
|
1108
1122
|
});
|
|
1109
1123
|
|
|
1110
|
-
const batch2 = await test_utils.
|
|
1124
|
+
const batch2 = await test_utils.getBatchArray(
|
|
1111
1125
|
bucketStorage.getBucketDataBatch(
|
|
1112
1126
|
checkpoint,
|
|
1113
1127
|
[{ ...request, start: BigInt(batch1[0].chunkData.next_after) }],
|
|
@@ -1124,7 +1138,7 @@ bucket_definitions:
|
|
|
1124
1138
|
next_after: '4'
|
|
1125
1139
|
});
|
|
1126
1140
|
|
|
1127
|
-
const batch3 = await test_utils.
|
|
1141
|
+
const batch3 = await test_utils.getBatchArray(
|
|
1128
1142
|
bucketStorage.getBucketDataBatch(
|
|
1129
1143
|
checkpoint,
|
|
1130
1144
|
[{ ...request, start: BigInt(batch2[0].chunkData.next_after) }],
|
|
@@ -1136,9 +1150,11 @@ bucket_definitions:
|
|
|
1136
1150
|
});
|
|
1137
1151
|
|
|
1138
1152
|
test('long batch', async () => {
|
|
1139
|
-
// Test syncing a batch of data that is limited by count.
|
|
1153
|
+
// Test syncing a batch of data that is limited by count. Compressed storage limits persisted
|
|
1154
|
+
// documents and finishes yielding all operations from a document once it has been hydrated.
|
|
1140
1155
|
await using factory = await generateStorageFactory();
|
|
1141
|
-
const syncRules = await
|
|
1156
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
1157
|
+
factory,
|
|
1142
1158
|
updateSyncRulesFromYaml(
|
|
1143
1159
|
`
|
|
1144
1160
|
bucket_definitions:
|
|
@@ -1151,7 +1167,7 @@ bucket_definitions:
|
|
|
1151
1167
|
}
|
|
1152
1168
|
)
|
|
1153
1169
|
);
|
|
1154
|
-
const bucketStorage = factory.getInstance(
|
|
1170
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1155
1171
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1156
1172
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
1157
1173
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -1170,54 +1186,74 @@ bucket_definitions:
|
|
|
1170
1186
|
|
|
1171
1187
|
await writer.commit('1/1');
|
|
1172
1188
|
|
|
1173
|
-
const
|
|
1189
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
1174
1190
|
|
|
1175
1191
|
const request = bucketRequest(syncRules, 'global[]');
|
|
1176
|
-
const batch1 = await test_utils.
|
|
1192
|
+
const batch1 = await test_utils.getSingleBatchItem(
|
|
1193
|
+
bucketStorage.getBucketDataBatch(checkpoint, [request], { limit: 4 })
|
|
1194
|
+
);
|
|
1177
1195
|
|
|
1178
|
-
|
|
1196
|
+
const allOperations = [
|
|
1179
1197
|
{ op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 },
|
|
1180
1198
|
{ op_id: '2', op: 'PUT', object_id: 'test2', checksum: 730027011 },
|
|
1181
1199
|
{ op_id: '3', op: 'PUT', object_id: 'test3', checksum: 1359888332 },
|
|
1182
|
-
{ op_id: '4', op: 'PUT', object_id: 'test4', checksum: 2049153252 }
|
|
1183
|
-
]);
|
|
1184
|
-
|
|
1185
|
-
expect(test_utils.getBatchMeta(batch1)).toEqual({
|
|
1186
|
-
after: '0',
|
|
1187
|
-
has_more: true,
|
|
1188
|
-
next_after: '4'
|
|
1189
|
-
});
|
|
1190
|
-
|
|
1191
|
-
const batch2 = await test_utils.oneFromAsync(
|
|
1192
|
-
bucketStorage.getBucketDataBatch(checkpoint, [{ ...request, start: BigInt(batch1.chunkData.next_after) }], {
|
|
1193
|
-
limit: 4
|
|
1194
|
-
})
|
|
1195
|
-
);
|
|
1196
|
-
expect(test_utils.getBatchData(batch2)).toEqual([
|
|
1200
|
+
{ op_id: '4', op: 'PUT', object_id: 'test4', checksum: 2049153252 },
|
|
1197
1201
|
{ op_id: '5', op: 'PUT', object_id: 'test5', checksum: 3686902721 },
|
|
1198
1202
|
{ op_id: '6', op: 'PUT', object_id: 'test6', checksum: 1974820016 }
|
|
1199
|
-
]
|
|
1203
|
+
];
|
|
1200
1204
|
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1205
|
+
if (config.compressedBucketStorage) {
|
|
1206
|
+
expect(test_utils.getBatchData(batch1)).toEqual(allOperations);
|
|
1207
|
+
expect(test_utils.getBatchMeta(batch1)).toEqual({
|
|
1208
|
+
after: '0',
|
|
1209
|
+
has_more: false,
|
|
1210
|
+
next_after: '6'
|
|
1211
|
+
});
|
|
1206
1212
|
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
+
const batch2 = await test_utils.getBatchArray(
|
|
1214
|
+
bucketStorage.getBucketDataBatch(checkpoint, [{ ...request, start: BigInt(batch1.chunkData.next_after) }], {
|
|
1215
|
+
limit: 4
|
|
1216
|
+
})
|
|
1217
|
+
);
|
|
1218
|
+
expect(test_utils.getBatchData(batch2)).toEqual([]);
|
|
1219
|
+
expect(test_utils.getBatchMeta(batch2)).toEqual(null);
|
|
1220
|
+
} else {
|
|
1221
|
+
expect(test_utils.getBatchData(batch1)).toEqual(allOperations.slice(0, 4));
|
|
1213
1222
|
|
|
1214
|
-
|
|
1223
|
+
expect(test_utils.getBatchMeta(batch1)).toEqual({
|
|
1224
|
+
after: '0',
|
|
1225
|
+
has_more: true,
|
|
1226
|
+
next_after: '4'
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
const batch2 = await test_utils.getSingleBatchItem(
|
|
1230
|
+
bucketStorage.getBucketDataBatch(checkpoint, [{ ...request, start: BigInt(batch1.chunkData.next_after) }], {
|
|
1231
|
+
limit: 4
|
|
1232
|
+
})
|
|
1233
|
+
);
|
|
1234
|
+
expect(test_utils.getBatchData(batch2)).toEqual(allOperations.slice(4));
|
|
1235
|
+
|
|
1236
|
+
expect(test_utils.getBatchMeta(batch2)).toEqual({
|
|
1237
|
+
after: '4',
|
|
1238
|
+
has_more: false,
|
|
1239
|
+
next_after: '6'
|
|
1240
|
+
});
|
|
1241
|
+
|
|
1242
|
+
const batch3 = await test_utils.getBatchArray(
|
|
1243
|
+
bucketStorage.getBucketDataBatch(checkpoint, [{ ...request, start: BigInt(batch2.chunkData.next_after) }], {
|
|
1244
|
+
limit: 4
|
|
1245
|
+
})
|
|
1246
|
+
);
|
|
1247
|
+
expect(test_utils.getBatchData(batch3)).toEqual([]);
|
|
1248
|
+
expect(test_utils.getBatchMeta(batch3)).toEqual(null);
|
|
1249
|
+
}
|
|
1215
1250
|
});
|
|
1216
1251
|
|
|
1217
1252
|
describe('batch has_more', () => {
|
|
1218
|
-
const setup = async (options: BucketDataBatchOptions) => {
|
|
1253
|
+
const setup = async (options: BucketDataBatchOptions, commitAfter?: number) => {
|
|
1219
1254
|
await using factory = await generateStorageFactory();
|
|
1220
|
-
const syncRules = await
|
|
1255
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
1256
|
+
factory,
|
|
1221
1257
|
updateSyncRulesFromYaml(
|
|
1222
1258
|
`
|
|
1223
1259
|
bucket_definitions:
|
|
@@ -1231,7 +1267,7 @@ bucket_definitions:
|
|
|
1231
1267
|
{ storageVersion }
|
|
1232
1268
|
)
|
|
1233
1269
|
);
|
|
1234
|
-
const bucketStorage = factory.getInstance(
|
|
1270
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1235
1271
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1236
1272
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
1237
1273
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -1247,23 +1283,30 @@ bucket_definitions:
|
|
|
1247
1283
|
},
|
|
1248
1284
|
afterReplicaId: `test${i}`
|
|
1249
1285
|
});
|
|
1286
|
+
if (i == commitAfter) {
|
|
1287
|
+
await writer.commit('1/1');
|
|
1288
|
+
}
|
|
1250
1289
|
}
|
|
1251
1290
|
|
|
1252
|
-
await writer.commit('1/1');
|
|
1291
|
+
await writer.commit(commitAfter == null ? '1/1' : '1/2');
|
|
1253
1292
|
|
|
1254
|
-
const
|
|
1293
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
1255
1294
|
const global1Request = bucketRequest(syncRules, 'global1[]', 0n);
|
|
1256
1295
|
const global2Request = bucketRequest(syncRules, 'global2[]', 0n);
|
|
1257
|
-
const batch = await test_utils.
|
|
1258
|
-
|
|
1296
|
+
const batch = await new test_utils.StorageDataHelpers(bucketStorage, syncRules).getAllBucketData(
|
|
1297
|
+
[global1Request, global2Request],
|
|
1298
|
+
checkpoint,
|
|
1299
|
+
options
|
|
1259
1300
|
);
|
|
1260
1301
|
|
|
1261
1302
|
return { batch, global1Request, global2Request };
|
|
1262
1303
|
};
|
|
1263
1304
|
|
|
1264
1305
|
test('batch has_more (1)', async () => {
|
|
1265
|
-
|
|
1266
|
-
|
|
1306
|
+
// The commit boundary creates two compressed documents for global2. The limit selects the global1
|
|
1307
|
+
// document and the first global2 document, leaving the second global2 document for the next batch.
|
|
1308
|
+
const { batch, global1Request, global2Request } = await setup({ limit: 2 }, 5);
|
|
1309
|
+
expect(batch.length).toBeGreaterThanOrEqual(2);
|
|
1267
1310
|
|
|
1268
1311
|
expect(batch[0].chunkData.bucket).toEqual(global1Request.bucket);
|
|
1269
1312
|
expect(batch[1].chunkData.bucket).toEqual(global2Request.bucket);
|
|
@@ -1272,12 +1315,20 @@ bucket_definitions:
|
|
|
1272
1315
|
{ op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 }
|
|
1273
1316
|
]);
|
|
1274
1317
|
|
|
1275
|
-
|
|
1318
|
+
const global2Operations = [
|
|
1276
1319
|
{ op_id: '2', op: 'PUT', object_id: 'test2', checksum: 730027011 },
|
|
1277
1320
|
{ op_id: '3', op: 'PUT', object_id: 'test3', checksum: 1359888332 },
|
|
1278
1321
|
{ op_id: '4', op: 'PUT', object_id: 'test4', checksum: 2049153252 },
|
|
1279
|
-
{ op_id: '5', op: 'PUT', object_id: 'test5', checksum: 3686902721 }
|
|
1280
|
-
|
|
1322
|
+
{ op_id: '5', op: 'PUT', object_id: 'test5', checksum: 3686902721 },
|
|
1323
|
+
{ op_id: '6', op: 'PUT', object_id: 'test6', checksum: 1974820016 },
|
|
1324
|
+
{ op_id: '7', op: 'PUT', object_id: 'test7', checksum: 2477637855 },
|
|
1325
|
+
{ op_id: '8', op: 'PUT', object_id: 'test8', checksum: 3644033632 },
|
|
1326
|
+
{ op_id: '9', op: 'PUT', object_id: 'test9', checksum: 1011055869 },
|
|
1327
|
+
{ op_id: '10', op: 'PUT', object_id: 'test10', checksum: 1331456365 }
|
|
1328
|
+
];
|
|
1329
|
+
expect(test_utils.getBatchData(batch[1])).toEqual(
|
|
1330
|
+
config.compressedBucketStorage ? global2Operations.slice(0, 4) : global2Operations.slice(0, 1)
|
|
1331
|
+
);
|
|
1281
1332
|
|
|
1282
1333
|
expect(test_utils.getBatchMeta(batch[0])).toEqual({
|
|
1283
1334
|
after: '0',
|
|
@@ -1288,7 +1339,7 @@ bucket_definitions:
|
|
|
1288
1339
|
expect(test_utils.getBatchMeta(batch[1])).toEqual({
|
|
1289
1340
|
after: '0',
|
|
1290
1341
|
has_more: true,
|
|
1291
|
-
next_after: '5'
|
|
1342
|
+
next_after: config.compressedBucketStorage ? '5' : '2'
|
|
1292
1343
|
});
|
|
1293
1344
|
});
|
|
1294
1345
|
|
|
@@ -1332,49 +1383,86 @@ bucket_definitions:
|
|
|
1332
1383
|
// 50 bytes is more than 1 row, less than 2 rows
|
|
1333
1384
|
const { batch, global1Request, global2Request } = await setup({ limit: 3, chunkLimitBytes: 50 });
|
|
1334
1385
|
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1386
|
+
if (config.compressedBucketStorage) {
|
|
1387
|
+
// In v3+, ops in the same bucket share a document. Once hydrated, the entire document is yielded even
|
|
1388
|
+
// when it exceeds the byte limit; the byte limit controls whether another document is fetched.
|
|
1389
|
+
expect(batch.length).toEqual(2);
|
|
1390
|
+
expect(batch[0].chunkData.bucket).toEqual(global1Request.bucket);
|
|
1391
|
+
expect(batch[1].chunkData.bucket).toEqual(global2Request.bucket);
|
|
1392
|
+
|
|
1393
|
+
expect(test_utils.getBatchData(batch[0])).toEqual([
|
|
1394
|
+
{ op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 }
|
|
1395
|
+
]);
|
|
1396
|
+
|
|
1397
|
+
expect(test_utils.getBatchData(batch[1])).toEqual([
|
|
1398
|
+
{ op_id: '2', op: 'PUT', object_id: 'test2', checksum: 730027011 },
|
|
1399
|
+
{ op_id: '3', op: 'PUT', object_id: 'test3', checksum: 1359888332 },
|
|
1400
|
+
{ op_id: '4', op: 'PUT', object_id: 'test4', checksum: 2049153252 },
|
|
1401
|
+
{ op_id: '5', op: 'PUT', object_id: 'test5', checksum: 3686902721 },
|
|
1402
|
+
{ op_id: '6', op: 'PUT', object_id: 'test6', checksum: 1974820016 },
|
|
1403
|
+
{ op_id: '7', op: 'PUT', object_id: 'test7', checksum: 2477637855 },
|
|
1404
|
+
{ op_id: '8', op: 'PUT', object_id: 'test8', checksum: 3644033632 },
|
|
1405
|
+
{ op_id: '9', op: 'PUT', object_id: 'test9', checksum: 1011055869 },
|
|
1406
|
+
{ op_id: '10', op: 'PUT', object_id: 'test10', checksum: 1331456365 }
|
|
1407
|
+
]);
|
|
1408
|
+
|
|
1409
|
+
expect(test_utils.getBatchMeta(batch[0])).toEqual({
|
|
1410
|
+
after: '0',
|
|
1411
|
+
has_more: false,
|
|
1412
|
+
next_after: '1'
|
|
1413
|
+
});
|
|
1350
1414
|
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1415
|
+
expect(test_utils.getBatchMeta(batch[1])).toEqual({
|
|
1416
|
+
after: '0',
|
|
1417
|
+
has_more: false,
|
|
1418
|
+
next_after: '10'
|
|
1419
|
+
});
|
|
1420
|
+
} else {
|
|
1421
|
+
expect(batch.length).toBeGreaterThanOrEqual(3);
|
|
1422
|
+
expect(batch[0].chunkData.bucket).toEqual(global1Request.bucket);
|
|
1423
|
+
expect(batch[1].chunkData.bucket).toEqual(global2Request.bucket);
|
|
1424
|
+
expect(batch[2].chunkData.bucket).toEqual(global2Request.bucket);
|
|
1425
|
+
|
|
1426
|
+
expect(test_utils.getBatchData(batch[0])).toEqual([
|
|
1427
|
+
{ op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 }
|
|
1428
|
+
]);
|
|
1429
|
+
|
|
1430
|
+
expect(test_utils.getBatchData(batch[1])).toEqual([
|
|
1431
|
+
{ op_id: '2', op: 'PUT', object_id: 'test2', checksum: 730027011 }
|
|
1432
|
+
]);
|
|
1433
|
+
expect(test_utils.getBatchData(batch[2])).toEqual([
|
|
1434
|
+
{ op_id: '3', op: 'PUT', object_id: 'test3', checksum: 1359888332 }
|
|
1435
|
+
]);
|
|
1436
|
+
|
|
1437
|
+
expect(test_utils.getBatchMeta(batch[0])).toEqual({
|
|
1438
|
+
after: '0',
|
|
1439
|
+
has_more: false,
|
|
1440
|
+
next_after: '1'
|
|
1441
|
+
});
|
|
1356
1442
|
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1443
|
+
expect(test_utils.getBatchMeta(batch[1])).toEqual({
|
|
1444
|
+
after: '0',
|
|
1445
|
+
has_more: true,
|
|
1446
|
+
next_after: '2'
|
|
1447
|
+
});
|
|
1362
1448
|
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1449
|
+
expect(test_utils.getBatchMeta(batch[2])).toEqual({
|
|
1450
|
+
after: '2',
|
|
1451
|
+
has_more: true,
|
|
1452
|
+
next_after: '3'
|
|
1453
|
+
});
|
|
1454
|
+
}
|
|
1368
1455
|
});
|
|
1369
1456
|
});
|
|
1370
1457
|
|
|
1371
1458
|
test('empty storage metrics', async () => {
|
|
1372
1459
|
await using f = await generateStorageFactory({ dropAll: true });
|
|
1373
1460
|
const metrics = await f.getStorageMetrics();
|
|
1374
|
-
expect(metrics).
|
|
1461
|
+
expect(metrics).toMatchObject({
|
|
1375
1462
|
operations_size_bytes: 0,
|
|
1376
1463
|
parameters_size_bytes: 0,
|
|
1377
|
-
replication_size_bytes: 0
|
|
1464
|
+
replication_size_bytes: 0,
|
|
1465
|
+
object_storage_size_bytes: 0
|
|
1378
1466
|
});
|
|
1379
1467
|
|
|
1380
1468
|
const r = await f.configureSyncRules(updateSyncRulesFromYaml('bucket_definitions: {}'));
|
|
@@ -1392,7 +1480,8 @@ bucket_definitions:
|
|
|
1392
1480
|
// but large enough in size to be split over multiple returned chunks.
|
|
1393
1481
|
// Similar to the above test, but splits over 1MB chunks.
|
|
1394
1482
|
await using factory = await generateStorageFactory();
|
|
1395
|
-
const syncRules = await
|
|
1483
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
1484
|
+
factory,
|
|
1396
1485
|
updateSyncRulesFromYaml(
|
|
1397
1486
|
`
|
|
1398
1487
|
bucket_definitions:
|
|
@@ -1406,7 +1495,7 @@ bucket_definitions:
|
|
|
1406
1495
|
}
|
|
1407
1496
|
)
|
|
1408
1497
|
);
|
|
1409
|
-
const bucketStorage = factory.getInstance(
|
|
1498
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1410
1499
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1411
1500
|
|
|
1412
1501
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config, 1);
|
|
@@ -1444,7 +1533,8 @@ bucket_definitions:
|
|
|
1444
1533
|
|
|
1445
1534
|
test('unchanged checksums', async () => {
|
|
1446
1535
|
await using factory = await generateStorageFactory();
|
|
1447
|
-
const syncRules = await
|
|
1536
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
1537
|
+
factory,
|
|
1448
1538
|
updateSyncRulesFromYaml(
|
|
1449
1539
|
`
|
|
1450
1540
|
bucket_definitions:
|
|
@@ -1457,7 +1547,7 @@ bucket_definitions:
|
|
|
1457
1547
|
}
|
|
1458
1548
|
)
|
|
1459
1549
|
);
|
|
1460
|
-
const bucketStorage = factory.getInstance(
|
|
1550
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1461
1551
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1462
1552
|
|
|
1463
1553
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
@@ -1472,12 +1562,14 @@ bucket_definitions:
|
|
|
1472
1562
|
afterReplicaId: test_utils.rid('test1')
|
|
1473
1563
|
});
|
|
1474
1564
|
await writer.commit('1/1');
|
|
1475
|
-
const
|
|
1565
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
1476
1566
|
|
|
1477
1567
|
const request = bucketRequest(syncRules, 'global[]');
|
|
1478
1568
|
const checksums = [...(await bucketStorage.getChecksums(checkpoint, [request])).values()];
|
|
1479
1569
|
expect(checksums).toEqual([{ bucket: request.bucket, checksum: 1917136889, count: 1 }]);
|
|
1480
|
-
const checksums2 = [
|
|
1570
|
+
const checksums2 = [
|
|
1571
|
+
...(await bucketStorage.getChecksums(test_utils.testCheckpoint(checkpoint.checkpoint + 1n), [request])).values()
|
|
1572
|
+
];
|
|
1481
1573
|
expect(checksums2).toEqual([{ bucket: request.bucket, checksum: 1917136889, count: 1 }]);
|
|
1482
1574
|
});
|
|
1483
1575
|
|
|
@@ -1485,7 +1577,8 @@ bucket_definitions:
|
|
|
1485
1577
|
|
|
1486
1578
|
test('empty checkpoints (1)', async () => {
|
|
1487
1579
|
await using factory = await generateStorageFactory();
|
|
1488
|
-
const
|
|
1580
|
+
const { stream: replicationStream } = await test_utils.deploySyncRules(
|
|
1581
|
+
factory,
|
|
1489
1582
|
updateSyncRulesFromYaml(
|
|
1490
1583
|
`
|
|
1491
1584
|
bucket_definitions:
|
|
@@ -1496,7 +1589,7 @@ bucket_definitions:
|
|
|
1496
1589
|
{ storageVersion }
|
|
1497
1590
|
)
|
|
1498
1591
|
);
|
|
1499
|
-
const bucketStorage = factory.getInstance(
|
|
1592
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1500
1593
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1501
1594
|
await writer.markAllSnapshotDone('1/1');
|
|
1502
1595
|
await writer.commit('1/1');
|
|
@@ -1521,7 +1614,8 @@ bucket_definitions:
|
|
|
1521
1614
|
|
|
1522
1615
|
test('empty checkpoints (2)', async () => {
|
|
1523
1616
|
await using factory = await generateStorageFactory();
|
|
1524
|
-
const
|
|
1617
|
+
const { stream: replicationStream } = await test_utils.deploySyncRules(
|
|
1618
|
+
factory,
|
|
1525
1619
|
updateSyncRulesFromYaml(
|
|
1526
1620
|
`
|
|
1527
1621
|
bucket_definitions:
|
|
@@ -1534,7 +1628,7 @@ bucket_definitions:
|
|
|
1534
1628
|
}
|
|
1535
1629
|
)
|
|
1536
1630
|
);
|
|
1537
|
-
const bucketStorage = factory.getInstance(
|
|
1631
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1538
1632
|
await using writer1 = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1539
1633
|
await using writer2 = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1540
1634
|
const sourceTable = await test_utils.resolveTestTable(writer2, 'test', ['id'], config);
|
|
@@ -1571,7 +1665,8 @@ bucket_definitions:
|
|
|
1571
1665
|
|
|
1572
1666
|
test('empty checkpoints (sync rule activation)', async () => {
|
|
1573
1667
|
await using factory = await generateStorageFactory();
|
|
1574
|
-
const syncRules = await
|
|
1668
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
1669
|
+
factory,
|
|
1575
1670
|
updateSyncRulesFromYaml(
|
|
1576
1671
|
`
|
|
1577
1672
|
bucket_definitions:
|
|
@@ -1584,7 +1679,7 @@ bucket_definitions:
|
|
|
1584
1679
|
}
|
|
1585
1680
|
)
|
|
1586
1681
|
);
|
|
1587
|
-
const bucketStorage = factory.getInstance(
|
|
1682
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1588
1683
|
|
|
1589
1684
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1590
1685
|
const result1 = await writer.commit('1/1', { createEmptyCheckpoints: false });
|
|
@@ -1609,8 +1704,8 @@ bucket_definitions:
|
|
|
1609
1704
|
const cp2 = await bucketStorage.getCheckpoint();
|
|
1610
1705
|
expect(cp2.lsn).toEqual('3/1');
|
|
1611
1706
|
|
|
1612
|
-
const activeSyncRules = await factory.
|
|
1613
|
-
expect(activeSyncRules?.
|
|
1707
|
+
const activeSyncRules = await factory.getActiveSyncConfig();
|
|
1708
|
+
expect(activeSyncRules?.content.replicationStreamId).toEqual(syncRules.replicationStreamId);
|
|
1614
1709
|
|
|
1615
1710
|
// At this point, it should be a truely empty checkpoint
|
|
1616
1711
|
const result4 = await writer.commit('4/1', { createEmptyCheckpoints: false });
|
|
@@ -1623,7 +1718,8 @@ bucket_definitions:
|
|
|
1623
1718
|
|
|
1624
1719
|
test.runIf(storageVersion >= 3)('deleting while streaming', async () => {
|
|
1625
1720
|
await using factory = await generateStorageFactory();
|
|
1626
|
-
const syncRules = await
|
|
1721
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
1722
|
+
factory,
|
|
1627
1723
|
updateSyncRulesFromYaml(
|
|
1628
1724
|
`
|
|
1629
1725
|
bucket_definitions:
|
|
@@ -1636,7 +1732,7 @@ bucket_definitions:
|
|
|
1636
1732
|
}
|
|
1637
1733
|
)
|
|
1638
1734
|
);
|
|
1639
|
-
const bucketStorage = factory.getInstance(
|
|
1735
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1640
1736
|
await using snapshotWriter = await bucketStorage.createWriter({
|
|
1641
1737
|
...test_utils.BATCH_OPTIONS,
|
|
1642
1738
|
skipExistingRows: true
|
|
@@ -1675,8 +1771,8 @@ bucket_definitions:
|
|
|
1675
1771
|
|
|
1676
1772
|
const cp = await bucketStorage.getCheckpoint();
|
|
1677
1773
|
expect(cp.lsn).toEqual('3/1');
|
|
1678
|
-
const data = await test_utils.
|
|
1679
|
-
bucketStorage.getBucketDataBatch(cp
|
|
1774
|
+
const data = await test_utils.getBatchArray(
|
|
1775
|
+
bucketStorage.getBucketDataBatch(cp, [bucketRequest(syncRules, 'global[]')])
|
|
1680
1776
|
);
|
|
1681
1777
|
|
|
1682
1778
|
expect(data).toEqual([]);
|
|
@@ -1692,7 +1788,8 @@ export function testChecksumBatching(config: storage.TestStorageConfig) {
|
|
|
1692
1788
|
const storageVersion = config.storageVersion ?? CURRENT_STORAGE_VERSION;
|
|
1693
1789
|
test('checksums for multiple buckets', async () => {
|
|
1694
1790
|
await using factory = await config.factory();
|
|
1695
|
-
const syncRules = await
|
|
1791
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(
|
|
1792
|
+
factory,
|
|
1696
1793
|
updateSyncRulesFromYaml(
|
|
1697
1794
|
`
|
|
1698
1795
|
bucket_definitions:
|
|
@@ -1706,7 +1803,7 @@ bucket_definitions:
|
|
|
1706
1803
|
}
|
|
1707
1804
|
)
|
|
1708
1805
|
);
|
|
1709
|
-
const bucketStorage = factory.getInstance(
|
|
1806
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1710
1807
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1711
1808
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
1712
1809
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -1726,7 +1823,7 @@ bucket_definitions:
|
|
|
1726
1823
|
}
|
|
1727
1824
|
}
|
|
1728
1825
|
await writer.commit('1/1');
|
|
1729
|
-
const
|
|
1826
|
+
const checkpoint = await bucketStorage.getCheckpoint();
|
|
1730
1827
|
|
|
1731
1828
|
bucketStorage.clearChecksumCache();
|
|
1732
1829
|
const users = ['u1', 'u2', 'u3', 'u4'];
|
|
@@ -1756,7 +1853,11 @@ streams:
|
|
|
1756
1853
|
`)
|
|
1757
1854
|
);
|
|
1758
1855
|
|
|
1759
|
-
const
|
|
1856
|
+
const [deployedContent] = deployed.syncConfigContent;
|
|
1857
|
+
expect(deployedContent).toBeDefined();
|
|
1858
|
+
const [deployedConfig] = deployedContent.parsed({ defaultSchema: 'ignored' }).syncConfigs;
|
|
1859
|
+
expect(deployedConfig).toBeDefined();
|
|
1860
|
+
const { errors } = deployedConfig;
|
|
1760
1861
|
expect(errors).toHaveLength(1);
|
|
1761
1862
|
expect(errors[0].message).toStrictEqual('Expected a SELECT statement');
|
|
1762
1863
|
expect(errors[0].location).toStrictEqual({
|