@powersync/service-core-tests 0.16.0 → 0.17.1
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 +34 -0
- package/dist/test-utils/AbstractStreamTestContext.d.ts +6 -5
- package/dist/test-utils/AbstractStreamTestContext.js +26 -22
- package/dist/test-utils/AbstractStreamTestContext.js.map +1 -1
- package/dist/test-utils/StorageDataHelpers.d.ts +5 -5
- 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 +13 -2
- package/dist/test-utils/general-utils.js +24 -3
- package/dist/test-utils/general-utils.js.map +1 -1
- package/dist/tests/register-compacting-tests.js +28 -21
- package/dist/tests/register-compacting-tests.js.map +1 -1
- package/dist/tests/register-data-storage-checkpoint-tests.js +8 -2
- package/dist/tests/register-data-storage-checkpoint-tests.js.map +1 -1
- package/dist/tests/register-data-storage-data-tests.js +148 -101
- 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-sync-tests.js +141 -8
- package/dist/tests/register-sync-tests.js.map +1 -1
- package/dist/tests/util.d.ts +2 -2
- package/dist/tests/util.js.map +1 -1
- package/package.json +6 -7
- package/src/test-utils/AbstractStreamTestContext.ts +29 -24
- package/src/test-utils/StorageDataHelpers.ts +7 -6
- package/src/test-utils/bucket-validation.ts +3 -3
- package/src/test-utils/general-utils.ts +35 -7
- package/src/tests/register-compacting-tests.ts +45 -22
- package/src/tests/register-data-storage-checkpoint-tests.ts +12 -2
- package/src/tests/register-data-storage-data-tests.ts +210 -107
- package/src/tests/register-data-storage-parameter-tests.ts +58 -42
- package/src/tests/register-sync-tests.ts +159 -8
- package/src/tests/util.ts +2 -2
- package/tsconfig.json +1 -4
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -27,13 +27,13 @@ export function registerDataStorageDataTests(config) {
|
|
|
27
27
|
const storageVersion = config.storageVersion ?? storage.CURRENT_STORAGE_VERSION;
|
|
28
28
|
test('removing row', async () => {
|
|
29
29
|
await using factory = await generateStorageFactory();
|
|
30
|
-
const syncRules = await
|
|
30
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
31
31
|
bucket_definitions:
|
|
32
32
|
global:
|
|
33
33
|
data:
|
|
34
34
|
- SELECT id, description FROM "%"
|
|
35
35
|
`, { storageVersion }));
|
|
36
|
-
const bucketStorage = factory.getInstance(
|
|
36
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
37
37
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
38
38
|
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
39
39
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -54,7 +54,7 @@ bucket_definitions:
|
|
|
54
54
|
await writer.commit('1/1');
|
|
55
55
|
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
56
56
|
const request = bucketRequest(syncRules, 'global[]');
|
|
57
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
57
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [request]));
|
|
58
58
|
const data = batch[0].chunkData.data.map((d) => {
|
|
59
59
|
return {
|
|
60
60
|
op: d.op,
|
|
@@ -68,7 +68,9 @@ bucket_definitions:
|
|
|
68
68
|
{ op: 'PUT', object_id: 'test1', checksum: c1 },
|
|
69
69
|
{ op: 'REMOVE', object_id: 'test1', checksum: c2 }
|
|
70
70
|
]);
|
|
71
|
-
const checksums = [
|
|
71
|
+
const checksums = [
|
|
72
|
+
...(await bucketStorage.getChecksums(test_utils.testCheckpoint(checkpoint), [request])).values()
|
|
73
|
+
];
|
|
72
74
|
expect(checksums).toEqual([
|
|
73
75
|
{
|
|
74
76
|
bucket: request.bucket,
|
|
@@ -79,13 +81,13 @@ bucket_definitions:
|
|
|
79
81
|
});
|
|
80
82
|
test('insert after delete in new batch', async () => {
|
|
81
83
|
await using factory = await generateStorageFactory();
|
|
82
|
-
const syncRules = await
|
|
84
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
83
85
|
bucket_definitions:
|
|
84
86
|
global:
|
|
85
87
|
data:
|
|
86
88
|
- SELECT id, description FROM "%"
|
|
87
89
|
`, { storageVersion }));
|
|
88
|
-
const bucketStorage = factory.getInstance(
|
|
90
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
89
91
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
90
92
|
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
91
93
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -107,7 +109,7 @@ bucket_definitions:
|
|
|
107
109
|
await writer.commit('2/1');
|
|
108
110
|
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
109
111
|
const request = bucketRequest(syncRules, 'global[]');
|
|
110
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
112
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [request]));
|
|
111
113
|
const data = batch[0].chunkData.data.map((d) => {
|
|
112
114
|
return {
|
|
113
115
|
op: d.op,
|
|
@@ -117,7 +119,9 @@ bucket_definitions:
|
|
|
117
119
|
});
|
|
118
120
|
const c1 = 2871785649;
|
|
119
121
|
expect(data).toEqual([{ op: 'PUT', object_id: 'test1', checksum: c1 }]);
|
|
120
|
-
const checksums = [
|
|
122
|
+
const checksums = [
|
|
123
|
+
...(await bucketStorage.getChecksums(test_utils.testCheckpoint(checkpoint), [request])).values()
|
|
124
|
+
];
|
|
121
125
|
expect(checksums).toEqual([
|
|
122
126
|
{
|
|
123
127
|
bucket: request.bucket,
|
|
@@ -129,13 +133,13 @@ bucket_definitions:
|
|
|
129
133
|
test('update after delete in new batch', async () => {
|
|
130
134
|
// Update after delete may not be common, but the storage layer should handle it in an eventually-consistent way.
|
|
131
135
|
await using factory = await generateStorageFactory();
|
|
132
|
-
const syncRules = await
|
|
136
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
133
137
|
bucket_definitions:
|
|
134
138
|
global:
|
|
135
139
|
data:
|
|
136
140
|
- SELECT id, description FROM "%"
|
|
137
141
|
`, { storageVersion }));
|
|
138
|
-
const bucketStorage = factory.getInstance(
|
|
142
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
139
143
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
140
144
|
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
141
145
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -161,7 +165,7 @@ bucket_definitions:
|
|
|
161
165
|
await writer.commit('2/1');
|
|
162
166
|
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
163
167
|
const request = bucketRequest(syncRules, 'global[]');
|
|
164
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
168
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [request]));
|
|
165
169
|
const data = batch[0].chunkData.data.map((d) => {
|
|
166
170
|
return {
|
|
167
171
|
op: d.op,
|
|
@@ -171,7 +175,9 @@ bucket_definitions:
|
|
|
171
175
|
});
|
|
172
176
|
const c1 = 2871785649;
|
|
173
177
|
expect(data).toEqual([{ op: 'PUT', object_id: 'test1', checksum: c1 }]);
|
|
174
|
-
const checksums = [
|
|
178
|
+
const checksums = [
|
|
179
|
+
...(await bucketStorage.getChecksums(test_utils.testCheckpoint(checkpoint), [request])).values()
|
|
180
|
+
];
|
|
175
181
|
expect(checksums).toEqual([
|
|
176
182
|
{
|
|
177
183
|
bucket: request.bucket,
|
|
@@ -182,7 +188,7 @@ bucket_definitions:
|
|
|
182
188
|
});
|
|
183
189
|
test('insert after delete in same batch', async () => {
|
|
184
190
|
await using factory = await generateStorageFactory();
|
|
185
|
-
const syncRules = await
|
|
191
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
186
192
|
bucket_definitions:
|
|
187
193
|
global:
|
|
188
194
|
data:
|
|
@@ -190,7 +196,7 @@ bucket_definitions:
|
|
|
190
196
|
`, {
|
|
191
197
|
storageVersion
|
|
192
198
|
}));
|
|
193
|
-
const bucketStorage = factory.getInstance(
|
|
199
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
194
200
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
195
201
|
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
196
202
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -211,7 +217,7 @@ bucket_definitions:
|
|
|
211
217
|
await writer.commit('1/1');
|
|
212
218
|
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
213
219
|
const request = bucketRequest(syncRules, 'global[]');
|
|
214
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
220
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [request]));
|
|
215
221
|
const data = batch[0].chunkData.data.map((d) => {
|
|
216
222
|
return {
|
|
217
223
|
op: d.op,
|
|
@@ -221,7 +227,9 @@ bucket_definitions:
|
|
|
221
227
|
});
|
|
222
228
|
const c1 = 2871785649;
|
|
223
229
|
expect(data).toEqual([{ op: 'PUT', object_id: 'test1', checksum: c1 }]);
|
|
224
|
-
const checksums = [
|
|
230
|
+
const checksums = [
|
|
231
|
+
...(await bucketStorage.getChecksums(test_utils.testCheckpoint(checkpoint), [request])).values()
|
|
232
|
+
];
|
|
225
233
|
expect(checksums).toEqual([
|
|
226
234
|
{
|
|
227
235
|
bucket: request.bucket,
|
|
@@ -232,7 +240,7 @@ bucket_definitions:
|
|
|
232
240
|
});
|
|
233
241
|
test('(insert, delete, insert), (delete)', async () => {
|
|
234
242
|
await using factory = await generateStorageFactory();
|
|
235
|
-
const syncRules = await
|
|
243
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
236
244
|
bucket_definitions:
|
|
237
245
|
global:
|
|
238
246
|
data:
|
|
@@ -240,7 +248,7 @@ bucket_definitions:
|
|
|
240
248
|
`, {
|
|
241
249
|
storageVersion
|
|
242
250
|
}));
|
|
243
|
-
const bucketStorage = factory.getInstance(
|
|
251
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
244
252
|
{
|
|
245
253
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
246
254
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
@@ -283,7 +291,7 @@ bucket_definitions:
|
|
|
283
291
|
}
|
|
284
292
|
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
285
293
|
const request = bucketRequest(syncRules, 'global[]');
|
|
286
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
294
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [request]));
|
|
287
295
|
expect(reduceBucket(batch[0].chunkData.data).slice(1)).toEqual([]);
|
|
288
296
|
const data = batch[0].chunkData.data.map((d) => {
|
|
289
297
|
return {
|
|
@@ -296,7 +304,7 @@ bucket_definitions:
|
|
|
296
304
|
});
|
|
297
305
|
test('changing client ids', async () => {
|
|
298
306
|
await using factory = await generateStorageFactory();
|
|
299
|
-
const syncRules = await
|
|
307
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
300
308
|
bucket_definitions:
|
|
301
309
|
global:
|
|
302
310
|
data:
|
|
@@ -304,7 +312,7 @@ bucket_definitions:
|
|
|
304
312
|
`, {
|
|
305
313
|
storageVersion
|
|
306
314
|
}));
|
|
307
|
-
const bucketStorage = factory.getInstance(
|
|
315
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
308
316
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
309
317
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
310
318
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -340,7 +348,7 @@ bucket_definitions:
|
|
|
340
348
|
});
|
|
341
349
|
await writer.commit('1/1');
|
|
342
350
|
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
343
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [bucketRequest(syncRules, 'global[]')]));
|
|
351
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [bucketRequest(syncRules, 'global[]')]));
|
|
344
352
|
const data = batch[0].chunkData.data.map((d) => {
|
|
345
353
|
return {
|
|
346
354
|
op: d.op,
|
|
@@ -356,7 +364,7 @@ bucket_definitions:
|
|
|
356
364
|
});
|
|
357
365
|
test('re-apply delete', async () => {
|
|
358
366
|
await using factory = await generateStorageFactory();
|
|
359
|
-
const syncRules = await
|
|
367
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
360
368
|
bucket_definitions:
|
|
361
369
|
global:
|
|
362
370
|
data:
|
|
@@ -364,7 +372,7 @@ bucket_definitions:
|
|
|
364
372
|
`, {
|
|
365
373
|
storageVersion
|
|
366
374
|
}));
|
|
367
|
-
const bucketStorage = factory.getInstance(
|
|
375
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
368
376
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
369
377
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
370
378
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -392,7 +400,7 @@ bucket_definitions:
|
|
|
392
400
|
await writer.flush();
|
|
393
401
|
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
394
402
|
const request = bucketRequest(syncRules, 'global[]');
|
|
395
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
403
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [request]));
|
|
396
404
|
const data = batch[0].chunkData.data.map((d) => {
|
|
397
405
|
return {
|
|
398
406
|
op: d.op,
|
|
@@ -406,7 +414,9 @@ bucket_definitions:
|
|
|
406
414
|
{ op: 'PUT', object_id: 'test1', checksum: c1 },
|
|
407
415
|
{ op: 'REMOVE', object_id: 'test1', checksum: c2 }
|
|
408
416
|
]);
|
|
409
|
-
const checksums = [
|
|
417
|
+
const checksums = [
|
|
418
|
+
...(await bucketStorage.getChecksums(test_utils.testCheckpoint(checkpoint), [request])).values()
|
|
419
|
+
];
|
|
410
420
|
expect(checksums).toEqual([
|
|
411
421
|
{
|
|
412
422
|
bucket: bucketRequest(syncRules, 'global[]').bucket,
|
|
@@ -417,13 +427,13 @@ bucket_definitions:
|
|
|
417
427
|
});
|
|
418
428
|
test('re-apply update + delete', async () => {
|
|
419
429
|
await using factory = await generateStorageFactory();
|
|
420
|
-
const syncRules = await
|
|
430
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
421
431
|
bucket_definitions:
|
|
422
432
|
global:
|
|
423
433
|
data:
|
|
424
434
|
- SELECT id, description FROM "%"
|
|
425
435
|
`, { storageVersion }));
|
|
426
|
-
const bucketStorage = factory.getInstance(
|
|
436
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
427
437
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
428
438
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
429
439
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -489,7 +499,7 @@ bucket_definitions:
|
|
|
489
499
|
await writer.commit('2/1');
|
|
490
500
|
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
491
501
|
const request = bucketRequest(syncRules, 'global[]');
|
|
492
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
502
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [request]));
|
|
493
503
|
const data = batch[0].chunkData.data.map((d) => {
|
|
494
504
|
return {
|
|
495
505
|
op: d.op,
|
|
@@ -505,7 +515,9 @@ bucket_definitions:
|
|
|
505
515
|
{ op: 'PUT', object_id: 'test1', checksum: c1 },
|
|
506
516
|
{ op: 'REMOVE', object_id: 'test1', checksum: c2 }
|
|
507
517
|
]);
|
|
508
|
-
const checksums = [
|
|
518
|
+
const checksums = [
|
|
519
|
+
...(await bucketStorage.getChecksums(test_utils.testCheckpoint(checkpoint), [request])).values()
|
|
520
|
+
];
|
|
509
521
|
expect(checksums).toEqual([
|
|
510
522
|
{
|
|
511
523
|
bucket: bucketRequest(syncRules, 'global[]').bucket,
|
|
@@ -523,13 +535,13 @@ bucket_definitions:
|
|
|
523
535
|
// 1. Not getting the correct "current_data" state for each operation.
|
|
524
536
|
// 2. Output order not being correct.
|
|
525
537
|
await using factory = await generateStorageFactory();
|
|
526
|
-
const syncRules = await
|
|
538
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
527
539
|
bucket_definitions:
|
|
528
540
|
global:
|
|
529
541
|
data:
|
|
530
542
|
- SELECT id, description FROM "test"
|
|
531
543
|
`, { storageVersion }));
|
|
532
|
-
const bucketStorage = factory.getInstance(
|
|
544
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
533
545
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
534
546
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
535
547
|
// Pre-setup
|
|
@@ -627,7 +639,7 @@ bucket_definitions:
|
|
|
627
639
|
const result2 = await writer.flush();
|
|
628
640
|
const checkpoint2 = result2.flushed_op;
|
|
629
641
|
const request = bucketRequest(syncRules, 'global[]', checkpoint1);
|
|
630
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint2, [request]));
|
|
642
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint2), [request]));
|
|
631
643
|
const data = batch[0].chunkData.data.map((d) => {
|
|
632
644
|
return {
|
|
633
645
|
op: d.op,
|
|
@@ -659,7 +671,7 @@ bucket_definitions:
|
|
|
659
671
|
]);
|
|
660
672
|
}
|
|
661
673
|
await using factory = await generateStorageFactory();
|
|
662
|
-
const syncRules = await
|
|
674
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
663
675
|
bucket_definitions:
|
|
664
676
|
global:
|
|
665
677
|
data:
|
|
@@ -667,7 +679,7 @@ bucket_definitions:
|
|
|
667
679
|
`, {
|
|
668
680
|
storageVersion
|
|
669
681
|
}));
|
|
670
|
-
const bucketStorage = factory.getInstance(
|
|
682
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
671
683
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
672
684
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id', 'description'], config);
|
|
673
685
|
// Pre-setup
|
|
@@ -713,7 +725,7 @@ bucket_definitions:
|
|
|
713
725
|
const result3 = await writer.flush();
|
|
714
726
|
const checkpoint3 = result3.flushed_op;
|
|
715
727
|
const request = bucketRequest(syncRules, 'global[]');
|
|
716
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint3, [{ ...request, start: checkpoint1 }]));
|
|
728
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint3), [{ ...request, start: checkpoint1 }]));
|
|
717
729
|
const data = batch[0].chunkData.data.map((d) => {
|
|
718
730
|
return {
|
|
719
731
|
op: d.op,
|
|
@@ -755,7 +767,7 @@ bucket_definitions:
|
|
|
755
767
|
]);
|
|
756
768
|
}
|
|
757
769
|
await using factory = await generateStorageFactory();
|
|
758
|
-
const syncRules = await
|
|
770
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
759
771
|
bucket_definitions:
|
|
760
772
|
global:
|
|
761
773
|
data:
|
|
@@ -763,7 +775,7 @@ bucket_definitions:
|
|
|
763
775
|
`, {
|
|
764
776
|
storageVersion
|
|
765
777
|
}));
|
|
766
|
-
const bucketStorage = factory.getInstance(
|
|
778
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
767
779
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
768
780
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id', 'description'], config);
|
|
769
781
|
// Pre-setup
|
|
@@ -809,7 +821,7 @@ bucket_definitions:
|
|
|
809
821
|
const result3 = await writer.flush();
|
|
810
822
|
const checkpoint3 = result3.flushed_op;
|
|
811
823
|
const request = bucketRequest(syncRules, 'global[]');
|
|
812
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint3, [{ ...request, start: checkpoint1 }]));
|
|
824
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint3), [{ ...request, start: checkpoint1 }]));
|
|
813
825
|
const data = batch[0].chunkData.data.map((d) => {
|
|
814
826
|
return {
|
|
815
827
|
op: d.op,
|
|
@@ -842,7 +854,7 @@ bucket_definitions:
|
|
|
842
854
|
// The specific batch splits is an implementation detail of the storage driver,
|
|
843
855
|
// and the test will have to updated when other implementations are added.
|
|
844
856
|
await using factory = await generateStorageFactory();
|
|
845
|
-
const syncRules = await
|
|
857
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
846
858
|
bucket_definitions:
|
|
847
859
|
global:
|
|
848
860
|
data:
|
|
@@ -850,7 +862,7 @@ bucket_definitions:
|
|
|
850
862
|
`, {
|
|
851
863
|
storageVersion
|
|
852
864
|
}));
|
|
853
|
-
const bucketStorage = factory.getInstance(
|
|
865
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
854
866
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
855
867
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
856
868
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -898,7 +910,7 @@ bucket_definitions:
|
|
|
898
910
|
chunkLimitBytes: 16 * 1024 * 1024
|
|
899
911
|
};
|
|
900
912
|
const request = bucketRequest(syncRules, 'global[]');
|
|
901
|
-
const batch1 = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request], options));
|
|
913
|
+
const batch1 = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [request], options));
|
|
902
914
|
expect(test_utils.getBatchData(batch1)).toEqual([
|
|
903
915
|
{ op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 },
|
|
904
916
|
{ op_id: '2', op: 'PUT', object_id: 'large1', checksum: 454746904 }
|
|
@@ -908,7 +920,7 @@ bucket_definitions:
|
|
|
908
920
|
has_more: true,
|
|
909
921
|
next_after: '2'
|
|
910
922
|
});
|
|
911
|
-
const batch2 = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [{ ...request, start: BigInt(batch1[0].chunkData.next_after) }], options));
|
|
923
|
+
const batch2 = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [{ ...request, start: BigInt(batch1[0].chunkData.next_after) }], options));
|
|
912
924
|
expect(test_utils.getBatchData(batch2)).toEqual([
|
|
913
925
|
{ op_id: '3', op: 'PUT', object_id: 'large2', checksum: 1795508474 },
|
|
914
926
|
{ op_id: '4', op: 'PUT', object_id: 'test3', checksum: 1359888332 }
|
|
@@ -918,14 +930,14 @@ bucket_definitions:
|
|
|
918
930
|
has_more: false,
|
|
919
931
|
next_after: '4'
|
|
920
932
|
});
|
|
921
|
-
const batch3 = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [{ ...request, start: BigInt(batch2[0].chunkData.next_after) }], options));
|
|
933
|
+
const batch3 = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [{ ...request, start: BigInt(batch2[0].chunkData.next_after) }], options));
|
|
922
934
|
expect(test_utils.getBatchData(batch3)).toEqual([]);
|
|
923
935
|
expect(test_utils.getBatchMeta(batch3)).toEqual(null);
|
|
924
936
|
});
|
|
925
937
|
test('long batch', async () => {
|
|
926
938
|
// Test syncing a batch of data that is limited by count.
|
|
927
939
|
await using factory = await generateStorageFactory();
|
|
928
|
-
const syncRules = await
|
|
940
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
929
941
|
bucket_definitions:
|
|
930
942
|
global:
|
|
931
943
|
data:
|
|
@@ -933,7 +945,7 @@ bucket_definitions:
|
|
|
933
945
|
`, {
|
|
934
946
|
storageVersion
|
|
935
947
|
}));
|
|
936
|
-
const bucketStorage = factory.getInstance(
|
|
948
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
937
949
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
938
950
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
939
951
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -951,7 +963,7 @@ bucket_definitions:
|
|
|
951
963
|
await writer.commit('1/1');
|
|
952
964
|
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
953
965
|
const request = bucketRequest(syncRules, 'global[]');
|
|
954
|
-
const batch1 = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request], { limit: 4 }));
|
|
966
|
+
const batch1 = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [request], { limit: 4 }));
|
|
955
967
|
expect(test_utils.getBatchData(batch1)).toEqual([
|
|
956
968
|
{ op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 },
|
|
957
969
|
{ op_id: '2', op: 'PUT', object_id: 'test2', checksum: 730027011 },
|
|
@@ -963,7 +975,7 @@ bucket_definitions:
|
|
|
963
975
|
has_more: true,
|
|
964
976
|
next_after: '4'
|
|
965
977
|
});
|
|
966
|
-
const batch2 = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint, [{ ...request, start: BigInt(batch1.chunkData.next_after) }], {
|
|
978
|
+
const batch2 = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [{ ...request, start: BigInt(batch1.chunkData.next_after) }], {
|
|
967
979
|
limit: 4
|
|
968
980
|
}));
|
|
969
981
|
expect(test_utils.getBatchData(batch2)).toEqual([
|
|
@@ -975,7 +987,7 @@ bucket_definitions:
|
|
|
975
987
|
has_more: false,
|
|
976
988
|
next_after: '6'
|
|
977
989
|
});
|
|
978
|
-
const batch3 = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [{ ...request, start: BigInt(batch2.chunkData.next_after) }], {
|
|
990
|
+
const batch3 = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [{ ...request, start: BigInt(batch2.chunkData.next_after) }], {
|
|
979
991
|
limit: 4
|
|
980
992
|
}));
|
|
981
993
|
expect(test_utils.getBatchData(batch3)).toEqual([]);
|
|
@@ -984,7 +996,7 @@ bucket_definitions:
|
|
|
984
996
|
describe('batch has_more', () => {
|
|
985
997
|
const setup = async (options) => {
|
|
986
998
|
await using factory = await generateStorageFactory();
|
|
987
|
-
const syncRules = await
|
|
999
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
988
1000
|
bucket_definitions:
|
|
989
1001
|
global1:
|
|
990
1002
|
data:
|
|
@@ -993,7 +1005,7 @@ bucket_definitions:
|
|
|
993
1005
|
data:
|
|
994
1006
|
- SELECT id, description FROM test WHERE bucket = 'global2'
|
|
995
1007
|
`, { storageVersion }));
|
|
996
|
-
const bucketStorage = factory.getInstance(
|
|
1008
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
997
1009
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
998
1010
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
999
1011
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -1013,7 +1025,7 @@ bucket_definitions:
|
|
|
1013
1025
|
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
1014
1026
|
const global1Request = bucketRequest(syncRules, 'global1[]', 0n);
|
|
1015
1027
|
const global2Request = bucketRequest(syncRules, 'global2[]', 0n);
|
|
1016
|
-
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, [global1Request, global2Request], options));
|
|
1028
|
+
const batch = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(checkpoint), [global1Request, global2Request], options));
|
|
1017
1029
|
return { batch, global1Request, global2Request };
|
|
1018
1030
|
};
|
|
1019
1031
|
test('batch has_more (1)', async () => {
|
|
@@ -1074,34 +1086,59 @@ bucket_definitions:
|
|
|
1074
1086
|
test('batch has_more (3)', async () => {
|
|
1075
1087
|
// 50 bytes is more than 1 row, less than 2 rows
|
|
1076
1088
|
const { batch, global1Request, global2Request } = await setup({ limit: 3, chunkLimitBytes: 50 });
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1089
|
+
if (config.compressedBucketStorage) {
|
|
1090
|
+
// In v3+, ops in the same bucket share a document, so ops 2 and 3 (global2) are batched together
|
|
1091
|
+
expect(batch.length).toEqual(2);
|
|
1092
|
+
expect(batch[0].chunkData.bucket).toEqual(global1Request.bucket);
|
|
1093
|
+
expect(batch[1].chunkData.bucket).toEqual(global2Request.bucket);
|
|
1094
|
+
expect(test_utils.getBatchData(batch[0])).toEqual([
|
|
1095
|
+
{ op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 }
|
|
1096
|
+
]);
|
|
1097
|
+
expect(test_utils.getBatchData(batch[1])).toEqual([
|
|
1098
|
+
{ op_id: '2', op: 'PUT', object_id: 'test2', checksum: 730027011 },
|
|
1099
|
+
{ op_id: '3', op: 'PUT', object_id: 'test3', checksum: 1359888332 }
|
|
1100
|
+
]);
|
|
1101
|
+
expect(test_utils.getBatchMeta(batch[0])).toEqual({
|
|
1102
|
+
after: '0',
|
|
1103
|
+
has_more: false,
|
|
1104
|
+
next_after: '1'
|
|
1105
|
+
});
|
|
1106
|
+
expect(test_utils.getBatchMeta(batch[1])).toEqual({
|
|
1107
|
+
after: '0',
|
|
1108
|
+
has_more: true,
|
|
1109
|
+
next_after: '3'
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
1112
|
+
else {
|
|
1113
|
+
expect(batch.length).toEqual(3);
|
|
1114
|
+
expect(batch[0].chunkData.bucket).toEqual(global1Request.bucket);
|
|
1115
|
+
expect(batch[1].chunkData.bucket).toEqual(global2Request.bucket);
|
|
1116
|
+
expect(batch[2].chunkData.bucket).toEqual(global2Request.bucket);
|
|
1117
|
+
expect(test_utils.getBatchData(batch[0])).toEqual([
|
|
1118
|
+
{ op_id: '1', op: 'PUT', object_id: 'test1', checksum: 2871785649 }
|
|
1119
|
+
]);
|
|
1120
|
+
expect(test_utils.getBatchData(batch[1])).toEqual([
|
|
1121
|
+
{ op_id: '2', op: 'PUT', object_id: 'test2', checksum: 730027011 }
|
|
1122
|
+
]);
|
|
1123
|
+
expect(test_utils.getBatchData(batch[2])).toEqual([
|
|
1124
|
+
{ op_id: '3', op: 'PUT', object_id: 'test3', checksum: 1359888332 }
|
|
1125
|
+
]);
|
|
1126
|
+
expect(test_utils.getBatchMeta(batch[0])).toEqual({
|
|
1127
|
+
after: '0',
|
|
1128
|
+
has_more: false,
|
|
1129
|
+
next_after: '1'
|
|
1130
|
+
});
|
|
1131
|
+
expect(test_utils.getBatchMeta(batch[1])).toEqual({
|
|
1132
|
+
after: '0',
|
|
1133
|
+
has_more: true,
|
|
1134
|
+
next_after: '2'
|
|
1135
|
+
});
|
|
1136
|
+
expect(test_utils.getBatchMeta(batch[2])).toEqual({
|
|
1137
|
+
after: '2',
|
|
1138
|
+
has_more: true,
|
|
1139
|
+
next_after: '3'
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1105
1142
|
});
|
|
1106
1143
|
});
|
|
1107
1144
|
test('empty storage metrics', async () => {
|
|
@@ -1125,7 +1162,7 @@ bucket_definitions:
|
|
|
1125
1162
|
// but large enough in size to be split over multiple returned chunks.
|
|
1126
1163
|
// Similar to the above test, but splits over 1MB chunks.
|
|
1127
1164
|
await using factory = await generateStorageFactory();
|
|
1128
|
-
const syncRules = await
|
|
1165
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
1129
1166
|
bucket_definitions:
|
|
1130
1167
|
global:
|
|
1131
1168
|
data:
|
|
@@ -1134,7 +1171,7 @@ bucket_definitions:
|
|
|
1134
1171
|
`, {
|
|
1135
1172
|
storageVersion
|
|
1136
1173
|
}));
|
|
1137
|
-
const bucketStorage = factory.getInstance(
|
|
1174
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1138
1175
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1139
1176
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config, 1);
|
|
1140
1177
|
const sourceTableIgnore = await test_utils.resolveTestTable(writer, 'test_ignore', ['id'], config, 2);
|
|
@@ -1166,7 +1203,7 @@ bucket_definitions:
|
|
|
1166
1203
|
});
|
|
1167
1204
|
test('unchanged checksums', async () => {
|
|
1168
1205
|
await using factory = await generateStorageFactory();
|
|
1169
|
-
const syncRules = await
|
|
1206
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
1170
1207
|
bucket_definitions:
|
|
1171
1208
|
global:
|
|
1172
1209
|
data:
|
|
@@ -1174,7 +1211,7 @@ bucket_definitions:
|
|
|
1174
1211
|
`, {
|
|
1175
1212
|
storageVersion
|
|
1176
1213
|
}));
|
|
1177
|
-
const bucketStorage = factory.getInstance(
|
|
1214
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1178
1215
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1179
1216
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
1180
1217
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -1190,21 +1227,25 @@ bucket_definitions:
|
|
|
1190
1227
|
await writer.commit('1/1');
|
|
1191
1228
|
const { checkpoint } = await bucketStorage.getCheckpoint();
|
|
1192
1229
|
const request = bucketRequest(syncRules, 'global[]');
|
|
1193
|
-
const checksums = [
|
|
1230
|
+
const checksums = [
|
|
1231
|
+
...(await bucketStorage.getChecksums(test_utils.testCheckpoint(checkpoint), [request])).values()
|
|
1232
|
+
];
|
|
1194
1233
|
expect(checksums).toEqual([{ bucket: request.bucket, checksum: 1917136889, count: 1 }]);
|
|
1195
|
-
const checksums2 = [
|
|
1234
|
+
const checksums2 = [
|
|
1235
|
+
...(await bucketStorage.getChecksums(test_utils.testCheckpoint(checkpoint + 1n), [request])).values()
|
|
1236
|
+
];
|
|
1196
1237
|
expect(checksums2).toEqual([{ bucket: request.bucket, checksum: 1917136889, count: 1 }]);
|
|
1197
1238
|
});
|
|
1198
1239
|
testChecksumBatching(config);
|
|
1199
1240
|
test('empty checkpoints (1)', async () => {
|
|
1200
1241
|
await using factory = await generateStorageFactory();
|
|
1201
|
-
const syncRules = await
|
|
1242
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
1202
1243
|
bucket_definitions:
|
|
1203
1244
|
global:
|
|
1204
1245
|
data:
|
|
1205
1246
|
- SELECT id, description FROM "%"
|
|
1206
1247
|
`, { storageVersion }));
|
|
1207
|
-
const bucketStorage = factory.getInstance(
|
|
1248
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1208
1249
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1209
1250
|
await writer.markAllSnapshotDone('1/1');
|
|
1210
1251
|
await writer.commit('1/1');
|
|
@@ -1224,7 +1265,7 @@ bucket_definitions:
|
|
|
1224
1265
|
});
|
|
1225
1266
|
test('empty checkpoints (2)', async () => {
|
|
1226
1267
|
await using factory = await generateStorageFactory();
|
|
1227
|
-
const syncRules = await
|
|
1268
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
1228
1269
|
bucket_definitions:
|
|
1229
1270
|
global:
|
|
1230
1271
|
data:
|
|
@@ -1232,7 +1273,7 @@ bucket_definitions:
|
|
|
1232
1273
|
`, {
|
|
1233
1274
|
storageVersion
|
|
1234
1275
|
}));
|
|
1235
|
-
const bucketStorage = factory.getInstance(
|
|
1276
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1236
1277
|
await using writer1 = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1237
1278
|
await using writer2 = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1238
1279
|
const sourceTable = await test_utils.resolveTestTable(writer2, 'test', ['id'], config);
|
|
@@ -1263,7 +1304,7 @@ bucket_definitions:
|
|
|
1263
1304
|
});
|
|
1264
1305
|
test('empty checkpoints (sync rule activation)', async () => {
|
|
1265
1306
|
await using factory = await generateStorageFactory();
|
|
1266
|
-
const syncRules = await
|
|
1307
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
1267
1308
|
bucket_definitions:
|
|
1268
1309
|
global:
|
|
1269
1310
|
data:
|
|
@@ -1271,7 +1312,7 @@ bucket_definitions:
|
|
|
1271
1312
|
`, {
|
|
1272
1313
|
storageVersion
|
|
1273
1314
|
}));
|
|
1274
|
-
const bucketStorage = factory.getInstance(
|
|
1315
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1275
1316
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1276
1317
|
const result1 = await writer.commit('1/1', { createEmptyCheckpoints: false });
|
|
1277
1318
|
expect(result1).toEqual({ checkpointBlocked: true, checkpointCreated: false });
|
|
@@ -1290,8 +1331,8 @@ bucket_definitions:
|
|
|
1290
1331
|
// Now, the checkpoint should advance the sync rules active.
|
|
1291
1332
|
const cp2 = await bucketStorage.getCheckpoint();
|
|
1292
1333
|
expect(cp2.lsn).toEqual('3/1');
|
|
1293
|
-
const activeSyncRules = await factory.
|
|
1294
|
-
expect(activeSyncRules?.
|
|
1334
|
+
const activeSyncRules = await factory.getActiveSyncConfig();
|
|
1335
|
+
expect(activeSyncRules?.content.replicationStreamId).toEqual(syncRules.replicationStreamId);
|
|
1295
1336
|
// At this point, it should be a truely empty checkpoint
|
|
1296
1337
|
const result4 = await writer.commit('4/1', { createEmptyCheckpoints: false });
|
|
1297
1338
|
expect(result4).toEqual({ checkpointBlocked: false, checkpointCreated: false });
|
|
@@ -1301,7 +1342,7 @@ bucket_definitions:
|
|
|
1301
1342
|
});
|
|
1302
1343
|
test.runIf(storageVersion >= 3)('deleting while streaming', async () => {
|
|
1303
1344
|
await using factory = await generateStorageFactory();
|
|
1304
|
-
const syncRules = await
|
|
1345
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
1305
1346
|
bucket_definitions:
|
|
1306
1347
|
global:
|
|
1307
1348
|
data:
|
|
@@ -1309,7 +1350,7 @@ bucket_definitions:
|
|
|
1309
1350
|
`, {
|
|
1310
1351
|
storageVersion
|
|
1311
1352
|
}));
|
|
1312
|
-
const bucketStorage = factory.getInstance(
|
|
1353
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1313
1354
|
await using snapshotWriter = await bucketStorage.createWriter({
|
|
1314
1355
|
...test_utils.BATCH_OPTIONS,
|
|
1315
1356
|
skipExistingRows: true
|
|
@@ -1344,7 +1385,7 @@ bucket_definitions:
|
|
|
1344
1385
|
await streamingWriter.keepalive('3/1');
|
|
1345
1386
|
const cp = await bucketStorage.getCheckpoint();
|
|
1346
1387
|
expect(cp.lsn).toEqual('3/1');
|
|
1347
|
-
const data = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(cp.checkpoint, [bucketRequest(syncRules, 'global[]')]));
|
|
1388
|
+
const data = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(test_utils.testCheckpoint(cp.checkpoint), [bucketRequest(syncRules, 'global[]')]));
|
|
1348
1389
|
expect(data).toEqual([]);
|
|
1349
1390
|
});
|
|
1350
1391
|
}
|
|
@@ -1357,7 +1398,7 @@ export function testChecksumBatching(config) {
|
|
|
1357
1398
|
const storageVersion = config.storageVersion ?? CURRENT_STORAGE_VERSION;
|
|
1358
1399
|
test('checksums for multiple buckets', async () => {
|
|
1359
1400
|
await using factory = await config.factory();
|
|
1360
|
-
const syncRules = await
|
|
1401
|
+
const { stream: replicationStream, content: syncRules } = await test_utils.deploySyncRules(factory, updateSyncRulesFromYaml(`
|
|
1361
1402
|
bucket_definitions:
|
|
1362
1403
|
user:
|
|
1363
1404
|
parameters: select request.user_id() as user_id
|
|
@@ -1366,7 +1407,7 @@ bucket_definitions:
|
|
|
1366
1407
|
`, {
|
|
1367
1408
|
storageVersion
|
|
1368
1409
|
}));
|
|
1369
|
-
const bucketStorage = factory.getInstance(
|
|
1410
|
+
const bucketStorage = factory.getInstance(replicationStream);
|
|
1370
1411
|
await using writer = await bucketStorage.createWriter(test_utils.BATCH_OPTIONS);
|
|
1371
1412
|
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
1372
1413
|
await writer.markAllSnapshotDone('1/1');
|
|
@@ -1391,7 +1432,9 @@ bucket_definitions:
|
|
|
1391
1432
|
const users = ['u1', 'u2', 'u3', 'u4'];
|
|
1392
1433
|
const expectedChecksums = [346204588, 5261081, 134760718, -302639724];
|
|
1393
1434
|
const bucketRequests = users.map((user) => bucketRequest(syncRules, `user["${user}"]`));
|
|
1394
|
-
const checksums = [
|
|
1435
|
+
const checksums = [
|
|
1436
|
+
...(await bucketStorage.getChecksums(test_utils.testCheckpoint(checkpoint), bucketRequests)).values()
|
|
1437
|
+
];
|
|
1395
1438
|
checksums.sort((a, b) => a.bucket.localeCompare(b.bucket));
|
|
1396
1439
|
const expected = bucketRequests.map((request, index) => ({
|
|
1397
1440
|
bucket: request.bucket,
|
|
@@ -1411,7 +1454,11 @@ streams:
|
|
|
1411
1454
|
invalid:
|
|
1412
1455
|
query: UPDATE test SET foo = 'bar' RETURNING *
|
|
1413
1456
|
`));
|
|
1414
|
-
const
|
|
1457
|
+
const [deployedContent] = deployed.syncConfigContent;
|
|
1458
|
+
expect(deployedContent).toBeDefined();
|
|
1459
|
+
const [deployedConfig] = deployedContent.parsed({ defaultSchema: 'ignored' }).syncConfigs;
|
|
1460
|
+
expect(deployedConfig).toBeDefined();
|
|
1461
|
+
const { errors } = deployedConfig;
|
|
1415
1462
|
expect(errors).toHaveLength(1);
|
|
1416
1463
|
expect(errors[0].message).toStrictEqual('Expected a SELECT statement');
|
|
1417
1464
|
expect(errors[0].location).toStrictEqual({
|