@powersync/service-core-tests 0.15.0 → 0.15.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 +21 -0
- package/dist/test-utils/general-utils.d.ts +13 -1
- package/dist/test-utils/general-utils.js +30 -1
- package/dist/test-utils/general-utils.js.map +1 -1
- package/dist/test-utils/stream_utils.js +2 -2
- package/dist/test-utils/stream_utils.js.map +1 -1
- package/dist/tests/register-compacting-tests.js +266 -257
- package/dist/tests/register-compacting-tests.js.map +1 -1
- package/dist/tests/register-data-storage-checkpoint-tests.js +36 -57
- package/dist/tests/register-data-storage-checkpoint-tests.js.map +1 -1
- package/dist/tests/register-data-storage-data-tests.js +839 -863
- package/dist/tests/register-data-storage-data-tests.js.map +1 -1
- package/dist/tests/register-data-storage-parameter-tests.js +228 -236
- package/dist/tests/register-data-storage-parameter-tests.js.map +1 -1
- package/dist/tests/register-parameter-compacting-tests.js +81 -89
- package/dist/tests/register-parameter-compacting-tests.js.map +1 -1
- package/dist/tests/register-sync-tests.js +468 -462
- package/dist/tests/register-sync-tests.js.map +1 -1
- package/package.json +3 -3
- package/src/test-utils/general-utils.ts +41 -2
- package/src/test-utils/stream_utils.ts +2 -2
- package/src/tests/register-compacting-tests.ts +279 -270
- package/src/tests/register-data-storage-checkpoint-tests.ts +36 -57
- package/src/tests/register-data-storage-data-tests.ts +673 -770
- package/src/tests/register-data-storage-parameter-tests.ts +245 -257
- package/src/tests/register-parameter-compacting-tests.ts +84 -92
- package/src/tests/register-sync-tests.ts +375 -391
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -87,7 +87,6 @@ export function registerSyncTests(configOrFactory, options = {}) {
|
|
|
87
87
|
maxParameterQueryResults: 10,
|
|
88
88
|
maxDataFetchConcurrency: 2
|
|
89
89
|
});
|
|
90
|
-
const TEST_TABLE = test_utils.makeTestTable('test', ['id'], config);
|
|
91
90
|
const updateSyncRules = (bucketStorageFactory, updateOptions) => {
|
|
92
91
|
return bucketStorageFactory.updateSyncRules(updateSyncRulesFromYaml(updateOptions.content, {
|
|
93
92
|
validate: true,
|
|
@@ -102,28 +101,28 @@ export function registerSyncTests(configOrFactory, options = {}) {
|
|
|
102
101
|
content: BASIC_SYNC_RULES
|
|
103
102
|
});
|
|
104
103
|
const bucketStorage = f.getInstance(syncRules);
|
|
105
|
-
await bucketStorage.
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
await batch.commit('0/1');
|
|
104
|
+
const writer = __addDisposableResource(env_1, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
105
|
+
const sourceTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
106
|
+
await writer.markAllSnapshotDone('0/1');
|
|
107
|
+
await writer.save({
|
|
108
|
+
sourceTable,
|
|
109
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
110
|
+
after: {
|
|
111
|
+
id: 't1',
|
|
112
|
+
description: 'Test 1'
|
|
113
|
+
},
|
|
114
|
+
afterReplicaId: 't1'
|
|
115
|
+
});
|
|
116
|
+
await writer.save({
|
|
117
|
+
sourceTable,
|
|
118
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
119
|
+
after: {
|
|
120
|
+
id: 't2',
|
|
121
|
+
description: 'Test 2'
|
|
122
|
+
},
|
|
123
|
+
afterReplicaId: 't2'
|
|
126
124
|
});
|
|
125
|
+
await writer.commit('0/1');
|
|
127
126
|
const stream = sync.streamResponse({
|
|
128
127
|
syncContext,
|
|
129
128
|
bucketStorage: bucketStorage,
|
|
@@ -168,28 +167,28 @@ bucket_definitions:
|
|
|
168
167
|
`
|
|
169
168
|
});
|
|
170
169
|
const bucketStorage = f.getInstance(syncRules);
|
|
171
|
-
await bucketStorage.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
await batch.commit('0/1');
|
|
170
|
+
const writer = __addDisposableResource(env_2, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
171
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
172
|
+
await writer.markAllSnapshotDone('0/1');
|
|
173
|
+
await writer.save({
|
|
174
|
+
sourceTable: testTable,
|
|
175
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
176
|
+
after: {
|
|
177
|
+
id: 't1',
|
|
178
|
+
description: 'Test 1'
|
|
179
|
+
},
|
|
180
|
+
afterReplicaId: 't1'
|
|
181
|
+
});
|
|
182
|
+
await writer.save({
|
|
183
|
+
sourceTable: testTable,
|
|
184
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
185
|
+
after: {
|
|
186
|
+
id: 'earlier',
|
|
187
|
+
description: 'Test 2'
|
|
188
|
+
},
|
|
189
|
+
afterReplicaId: 'earlier'
|
|
192
190
|
});
|
|
191
|
+
await writer.commit('0/1');
|
|
193
192
|
const stream = sync.streamResponse({
|
|
194
193
|
syncContext,
|
|
195
194
|
bucketStorage,
|
|
@@ -234,31 +233,31 @@ bucket_definitions:
|
|
|
234
233
|
`
|
|
235
234
|
});
|
|
236
235
|
const bucketStorage = f.getInstance(syncRules);
|
|
237
|
-
await bucketStorage.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
236
|
+
const writer = __addDisposableResource(env_3, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
237
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
238
|
+
await writer.markAllSnapshotDone('0/1');
|
|
239
|
+
// Initial data: Add one priority row and 10k low-priority rows.
|
|
240
|
+
await writer.save({
|
|
241
|
+
sourceTable: testTable,
|
|
242
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
243
|
+
after: {
|
|
244
|
+
id: 'highprio',
|
|
245
|
+
description: 'High priority row'
|
|
246
|
+
},
|
|
247
|
+
afterReplicaId: 'highprio'
|
|
248
|
+
});
|
|
249
|
+
for (let i = 0; i < 10_000; i++) {
|
|
250
|
+
await writer.save({
|
|
251
|
+
sourceTable: testTable,
|
|
242
252
|
tag: storage.SaveOperationTag.INSERT,
|
|
243
253
|
after: {
|
|
244
|
-
id:
|
|
245
|
-
description: '
|
|
254
|
+
id: `${i}`,
|
|
255
|
+
description: 'low prio'
|
|
246
256
|
},
|
|
247
|
-
afterReplicaId:
|
|
257
|
+
afterReplicaId: `${i}`
|
|
248
258
|
});
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
sourceTable: TEST_TABLE,
|
|
252
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
253
|
-
after: {
|
|
254
|
-
id: `${i}`,
|
|
255
|
-
description: 'low prio'
|
|
256
|
-
},
|
|
257
|
-
afterReplicaId: `${i}`
|
|
258
|
-
});
|
|
259
|
-
}
|
|
260
|
-
await batch.commit('0/1');
|
|
261
|
-
});
|
|
259
|
+
}
|
|
260
|
+
await writer.commit('0/1');
|
|
262
261
|
const stream = sync.streamResponse({
|
|
263
262
|
syncContext,
|
|
264
263
|
bucketStorage,
|
|
@@ -282,19 +281,17 @@ bucket_definitions:
|
|
|
282
281
|
if ('partial_checkpoint_complete' in next) {
|
|
283
282
|
if (sentCheckpoints == 1) {
|
|
284
283
|
// Save new data to interrupt the low-priority sync.
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
afterReplicaId: 'highprio2'
|
|
295
|
-
});
|
|
296
|
-
await batch.commit('0/2');
|
|
284
|
+
// Add another high-priority row. This should interrupt the long-running low-priority sync.
|
|
285
|
+
await writer.save({
|
|
286
|
+
sourceTable: testTable,
|
|
287
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
288
|
+
after: {
|
|
289
|
+
id: 'highprio2',
|
|
290
|
+
description: 'Another high-priority row'
|
|
291
|
+
},
|
|
292
|
+
afterReplicaId: 'highprio2'
|
|
297
293
|
});
|
|
294
|
+
await writer.commit('0/2');
|
|
298
295
|
}
|
|
299
296
|
else {
|
|
300
297
|
// Low-priority sync from the first checkpoint was interrupted. This should not happen before
|
|
@@ -346,31 +343,31 @@ bucket_definitions:
|
|
|
346
343
|
`
|
|
347
344
|
});
|
|
348
345
|
const bucketStorage = f.getInstance(syncRules);
|
|
349
|
-
await bucketStorage.
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
346
|
+
const writer = __addDisposableResource(env_4, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
347
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
348
|
+
await writer.markAllSnapshotDone('0/1');
|
|
349
|
+
// Initial data: Add one priority row and 10k low-priority rows.
|
|
350
|
+
await writer.save({
|
|
351
|
+
sourceTable: testTable,
|
|
352
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
353
|
+
after: {
|
|
354
|
+
id: 'highprio',
|
|
355
|
+
description: 'user_one'
|
|
356
|
+
},
|
|
357
|
+
afterReplicaId: 'highprio'
|
|
358
|
+
});
|
|
359
|
+
for (let i = 0; i < 10_000; i++) {
|
|
360
|
+
await writer.save({
|
|
361
|
+
sourceTable: testTable,
|
|
354
362
|
tag: storage.SaveOperationTag.INSERT,
|
|
355
363
|
after: {
|
|
356
|
-
id:
|
|
357
|
-
description: '
|
|
364
|
+
id: `${i}`,
|
|
365
|
+
description: 'low prio'
|
|
358
366
|
},
|
|
359
|
-
afterReplicaId:
|
|
367
|
+
afterReplicaId: `${i}`
|
|
360
368
|
});
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
sourceTable: TEST_TABLE,
|
|
364
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
365
|
-
after: {
|
|
366
|
-
id: `${i}`,
|
|
367
|
-
description: 'low prio'
|
|
368
|
-
},
|
|
369
|
-
afterReplicaId: `${i}`
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
await batch.commit('0/1');
|
|
373
|
-
});
|
|
369
|
+
}
|
|
370
|
+
await writer.commit('0/1');
|
|
374
371
|
const stream = sync.streamResponse({
|
|
375
372
|
syncContext,
|
|
376
373
|
bucketStorage,
|
|
@@ -399,19 +396,17 @@ bucket_definitions:
|
|
|
399
396
|
if (typeof next === 'object' && next !== null) {
|
|
400
397
|
if ('partial_checkpoint_complete' in next) {
|
|
401
398
|
if (sentCheckpoints == 1) {
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
afterReplicaId: 'highprio2'
|
|
412
|
-
});
|
|
413
|
-
await batch.commit('0/2');
|
|
399
|
+
// Add a high-priority row that doesn't affect this sync stream.
|
|
400
|
+
await writer.save({
|
|
401
|
+
sourceTable: testTable,
|
|
402
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
403
|
+
after: {
|
|
404
|
+
id: 'highprio2',
|
|
405
|
+
description: 'user_two'
|
|
406
|
+
},
|
|
407
|
+
afterReplicaId: 'highprio2'
|
|
414
408
|
});
|
|
409
|
+
await writer.commit('0/2');
|
|
415
410
|
}
|
|
416
411
|
else {
|
|
417
412
|
expect(sentCheckpoints).toBe(2);
|
|
@@ -431,19 +426,17 @@ bucket_definitions:
|
|
|
431
426
|
}
|
|
432
427
|
if (completedCheckpoints == 1) {
|
|
433
428
|
expect(sentRows).toBe(10001);
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
afterReplicaId: 'highprio3'
|
|
444
|
-
});
|
|
445
|
-
await batch.commit('0/3');
|
|
429
|
+
// Add a high-priority row that affects this sync stream.
|
|
430
|
+
await writer.save({
|
|
431
|
+
sourceTable: testTable,
|
|
432
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
433
|
+
after: {
|
|
434
|
+
id: 'highprio3',
|
|
435
|
+
description: 'user_one'
|
|
436
|
+
},
|
|
437
|
+
afterReplicaId: 'highprio3'
|
|
446
438
|
});
|
|
439
|
+
await writer.commit('0/3');
|
|
447
440
|
}
|
|
448
441
|
}
|
|
449
442
|
}
|
|
@@ -486,31 +479,31 @@ bucket_definitions:
|
|
|
486
479
|
`
|
|
487
480
|
});
|
|
488
481
|
const bucketStorage = f.getInstance(syncRules);
|
|
489
|
-
await bucketStorage.
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
482
|
+
const writer = __addDisposableResource(env_5, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
483
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
484
|
+
await writer.markAllSnapshotDone('0/1');
|
|
485
|
+
// Initial data: Add one priority row and 10k low-priority rows.
|
|
486
|
+
await writer.save({
|
|
487
|
+
sourceTable: testTable,
|
|
488
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
489
|
+
after: {
|
|
490
|
+
id: 'highprio',
|
|
491
|
+
description: 'High priority row'
|
|
492
|
+
},
|
|
493
|
+
afterReplicaId: 'highprio'
|
|
494
|
+
});
|
|
495
|
+
for (let i = 0; i < 2_000; i++) {
|
|
496
|
+
await writer.save({
|
|
497
|
+
sourceTable: testTable,
|
|
494
498
|
tag: storage.SaveOperationTag.INSERT,
|
|
495
499
|
after: {
|
|
496
|
-
id:
|
|
497
|
-
description: '
|
|
500
|
+
id: `${i}`,
|
|
501
|
+
description: 'low prio'
|
|
498
502
|
},
|
|
499
|
-
afterReplicaId:
|
|
503
|
+
afterReplicaId: `${i}`
|
|
500
504
|
});
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
sourceTable: TEST_TABLE,
|
|
504
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
505
|
-
after: {
|
|
506
|
-
id: `${i}`,
|
|
507
|
-
description: 'low prio'
|
|
508
|
-
},
|
|
509
|
-
afterReplicaId: `${i}`
|
|
510
|
-
});
|
|
511
|
-
}
|
|
512
|
-
await batch.commit('0/1');
|
|
513
|
-
});
|
|
505
|
+
}
|
|
506
|
+
await writer.commit('0/1');
|
|
514
507
|
const stream = sync.streamResponse({
|
|
515
508
|
syncContext,
|
|
516
509
|
bucketStorage,
|
|
@@ -542,29 +535,27 @@ bucket_definitions:
|
|
|
542
535
|
sentRows += next.data.data.length;
|
|
543
536
|
if (sentRows == 1001) {
|
|
544
537
|
// Save new data to interrupt the low-priority sync.
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
afterReplicaId: '2001'
|
|
565
|
-
});
|
|
566
|
-
await batch.commit('0/2');
|
|
538
|
+
// Add another high-priority row. This should interrupt the long-running low-priority sync.
|
|
539
|
+
await writer.save({
|
|
540
|
+
sourceTable: testTable,
|
|
541
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
542
|
+
after: {
|
|
543
|
+
id: 'highprio2',
|
|
544
|
+
description: 'Another high-priority row'
|
|
545
|
+
},
|
|
546
|
+
afterReplicaId: 'highprio2'
|
|
547
|
+
});
|
|
548
|
+
// Also add a low-priority row
|
|
549
|
+
await writer.save({
|
|
550
|
+
sourceTable: testTable,
|
|
551
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
552
|
+
after: {
|
|
553
|
+
id: '2001',
|
|
554
|
+
description: 'Another low-priority row'
|
|
555
|
+
},
|
|
556
|
+
afterReplicaId: '2001'
|
|
567
557
|
});
|
|
558
|
+
await writer.commit('0/2');
|
|
568
559
|
}
|
|
569
560
|
if (sentRows >= 1000 && sentRows <= 2001) {
|
|
570
561
|
// pause for a bit to give the stream time to process interruptions.
|
|
@@ -615,19 +606,19 @@ bucket_definitions:
|
|
|
615
606
|
content: BASIC_SYNC_RULES
|
|
616
607
|
});
|
|
617
608
|
const bucketStorage = f.getInstance(syncRules);
|
|
618
|
-
await bucketStorage.
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
await batch.commit('0/1');
|
|
609
|
+
const writer = __addDisposableResource(env_6, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
610
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
611
|
+
await writer.markAllSnapshotDone('0/1');
|
|
612
|
+
await writer.save({
|
|
613
|
+
sourceTable: testTable,
|
|
614
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
615
|
+
after: {
|
|
616
|
+
id: 't1',
|
|
617
|
+
description: 'sync'
|
|
618
|
+
},
|
|
619
|
+
afterReplicaId: 't1'
|
|
630
620
|
});
|
|
621
|
+
await writer.commit('0/1');
|
|
631
622
|
const stream = sync.streamResponse({
|
|
632
623
|
syncContext,
|
|
633
624
|
bucketStorage,
|
|
@@ -654,9 +645,7 @@ bucket_definitions:
|
|
|
654
645
|
if (receivedCompletions == 1) {
|
|
655
646
|
// Trigger an empty bucket update.
|
|
656
647
|
await bucketStorage.createManagedWriteCheckpoint({ user_id: '', heads: { '1': '1/0' } });
|
|
657
|
-
await
|
|
658
|
-
await batch.commit('1/0');
|
|
659
|
-
});
|
|
648
|
+
await writer.commit('1/0');
|
|
660
649
|
}
|
|
661
650
|
else {
|
|
662
651
|
break;
|
|
@@ -677,15 +666,18 @@ bucket_definitions:
|
|
|
677
666
|
}
|
|
678
667
|
});
|
|
679
668
|
test('sync legacy non-raw data', async () => {
|
|
680
|
-
const
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
await
|
|
687
|
-
await
|
|
688
|
-
|
|
669
|
+
const env_7 = { stack: [], error: void 0, hasError: false };
|
|
670
|
+
try {
|
|
671
|
+
const f = __addDisposableResource(env_7, await factory(), true);
|
|
672
|
+
const syncRules = await updateSyncRules(f, {
|
|
673
|
+
content: BASIC_SYNC_RULES
|
|
674
|
+
});
|
|
675
|
+
const bucketStorage = await f.getInstance(syncRules);
|
|
676
|
+
const writer = __addDisposableResource(env_7, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
677
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
678
|
+
await writer.markAllSnapshotDone('0/1');
|
|
679
|
+
await writer.save({
|
|
680
|
+
sourceTable: testTable,
|
|
689
681
|
tag: storage.SaveOperationTag.INSERT,
|
|
690
682
|
after: {
|
|
691
683
|
id: 't1',
|
|
@@ -694,30 +686,39 @@ bucket_definitions:
|
|
|
694
686
|
},
|
|
695
687
|
afterReplicaId: 't1'
|
|
696
688
|
});
|
|
697
|
-
await
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
689
|
+
await writer.commit('0/1');
|
|
690
|
+
const stream = sync.streamResponse({
|
|
691
|
+
syncContext,
|
|
692
|
+
bucketStorage,
|
|
693
|
+
syncRules: bucketStorage.getParsedSyncRules(test_utils.PARSE_OPTIONS),
|
|
694
|
+
params: {
|
|
695
|
+
buckets: [],
|
|
696
|
+
include_checksum: true,
|
|
697
|
+
raw_data: false
|
|
698
|
+
},
|
|
699
|
+
tracker,
|
|
700
|
+
token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
|
|
701
|
+
isEncodingAsBson: false
|
|
702
|
+
});
|
|
703
|
+
const lines = await consumeCheckpointLines(stream);
|
|
704
|
+
expect(lines).toMatchSnapshot();
|
|
705
|
+
// Specifically check the number - this is the important part of the test
|
|
706
|
+
expect(lines[1].data.data[0].data.large_num).toEqual(12345678901234567890n);
|
|
707
|
+
}
|
|
708
|
+
catch (e_7) {
|
|
709
|
+
env_7.error = e_7;
|
|
710
|
+
env_7.hasError = true;
|
|
711
|
+
}
|
|
712
|
+
finally {
|
|
713
|
+
const result_7 = __disposeResources(env_7);
|
|
714
|
+
if (result_7)
|
|
715
|
+
await result_7;
|
|
716
|
+
}
|
|
716
717
|
});
|
|
717
718
|
test('expired token', async () => {
|
|
718
|
-
const
|
|
719
|
+
const env_8 = { stack: [], error: void 0, hasError: false };
|
|
719
720
|
try {
|
|
720
|
-
const f = __addDisposableResource(
|
|
721
|
+
const f = __addDisposableResource(env_8, await factory(), true);
|
|
721
722
|
const syncRules = await updateSyncRules(f, {
|
|
722
723
|
content: BASIC_SYNC_RULES
|
|
723
724
|
});
|
|
@@ -738,29 +739,29 @@ bucket_definitions:
|
|
|
738
739
|
const lines = await consumeCheckpointLines(stream);
|
|
739
740
|
expect(lines).toMatchSnapshot();
|
|
740
741
|
}
|
|
741
|
-
catch (
|
|
742
|
-
|
|
743
|
-
|
|
742
|
+
catch (e_8) {
|
|
743
|
+
env_8.error = e_8;
|
|
744
|
+
env_8.hasError = true;
|
|
744
745
|
}
|
|
745
746
|
finally {
|
|
746
|
-
const
|
|
747
|
-
if (
|
|
748
|
-
await
|
|
747
|
+
const result_8 = __disposeResources(env_8);
|
|
748
|
+
if (result_8)
|
|
749
|
+
await result_8;
|
|
749
750
|
}
|
|
750
751
|
});
|
|
751
752
|
test('sync updates to global data', async (context) => {
|
|
752
|
-
const
|
|
753
|
+
const env_9 = { stack: [], error: void 0, hasError: false };
|
|
753
754
|
try {
|
|
754
|
-
const f = __addDisposableResource(
|
|
755
|
+
const f = __addDisposableResource(env_9, await factory(), true);
|
|
755
756
|
const syncRules = await updateSyncRules(f, {
|
|
756
757
|
content: BASIC_SYNC_RULES
|
|
757
758
|
});
|
|
758
759
|
const bucketStorage = await f.getInstance(syncRules);
|
|
760
|
+
const writer = __addDisposableResource(env_9, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
761
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
759
762
|
// Activate
|
|
760
|
-
await
|
|
761
|
-
|
|
762
|
-
await batch.keepalive('0/0');
|
|
763
|
-
});
|
|
763
|
+
await writer.markAllSnapshotDone('0/0');
|
|
764
|
+
await writer.keepalive('0/0');
|
|
764
765
|
const stream = sync.streamResponse({
|
|
765
766
|
syncContext,
|
|
766
767
|
bucketStorage,
|
|
@@ -779,47 +780,43 @@ bucket_definitions:
|
|
|
779
780
|
iter.return?.();
|
|
780
781
|
});
|
|
781
782
|
expect(await getCheckpointLines(iter)).toMatchSnapshot();
|
|
782
|
-
await
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
afterReplicaId: 't1'
|
|
791
|
-
});
|
|
792
|
-
await batch.commit('0/1');
|
|
783
|
+
await writer.save({
|
|
784
|
+
sourceTable: testTable,
|
|
785
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
786
|
+
after: {
|
|
787
|
+
id: 't1',
|
|
788
|
+
description: 'Test 1'
|
|
789
|
+
},
|
|
790
|
+
afterReplicaId: 't1'
|
|
793
791
|
});
|
|
792
|
+
await writer.commit('0/1');
|
|
794
793
|
expect(await getCheckpointLines(iter)).toMatchSnapshot();
|
|
795
|
-
await
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
afterReplicaId: 't2'
|
|
804
|
-
});
|
|
805
|
-
await batch.commit('0/2');
|
|
794
|
+
await writer.save({
|
|
795
|
+
sourceTable: testTable,
|
|
796
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
797
|
+
after: {
|
|
798
|
+
id: 't2',
|
|
799
|
+
description: 'Test 2'
|
|
800
|
+
},
|
|
801
|
+
afterReplicaId: 't2'
|
|
806
802
|
});
|
|
803
|
+
await writer.commit('0/2');
|
|
807
804
|
expect(await getCheckpointLines(iter)).toMatchSnapshot();
|
|
808
805
|
}
|
|
809
|
-
catch (
|
|
810
|
-
|
|
811
|
-
|
|
806
|
+
catch (e_9) {
|
|
807
|
+
env_9.error = e_9;
|
|
808
|
+
env_9.hasError = true;
|
|
812
809
|
}
|
|
813
810
|
finally {
|
|
814
|
-
const
|
|
815
|
-
if (
|
|
816
|
-
await
|
|
811
|
+
const result_9 = __disposeResources(env_9);
|
|
812
|
+
if (result_9)
|
|
813
|
+
await result_9;
|
|
817
814
|
}
|
|
818
815
|
});
|
|
819
816
|
test('sync updates to parameter query only', async (context) => {
|
|
820
|
-
const
|
|
817
|
+
const env_10 = { stack: [], error: void 0, hasError: false };
|
|
821
818
|
try {
|
|
822
|
-
const f = __addDisposableResource(
|
|
819
|
+
const f = __addDisposableResource(env_10, await factory(), true);
|
|
823
820
|
const syncRules = await updateSyncRules(f, {
|
|
824
821
|
content: `bucket_definitions:
|
|
825
822
|
by_user:
|
|
@@ -828,14 +825,12 @@ bucket_definitions:
|
|
|
828
825
|
- select * from lists where user_id = bucket.user_id
|
|
829
826
|
`
|
|
830
827
|
});
|
|
831
|
-
const usersTable = test_utils.makeTestTable('users', ['id'], config);
|
|
832
|
-
const listsTable = test_utils.makeTestTable('lists', ['id'], config);
|
|
833
828
|
const bucketStorage = await f.getInstance(syncRules);
|
|
829
|
+
const writer = __addDisposableResource(env_10, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
830
|
+
const usersTable = await test_utils.resolveTestTable(writer, 'users', ['id'], config, 1);
|
|
834
831
|
// Activate
|
|
835
|
-
await
|
|
836
|
-
|
|
837
|
-
await batch.keepalive('0/0');
|
|
838
|
-
});
|
|
832
|
+
await writer.markAllSnapshotDone('0/0');
|
|
833
|
+
await writer.keepalive('0/0');
|
|
839
834
|
const stream = sync.streamResponse({
|
|
840
835
|
syncContext,
|
|
841
836
|
bucketStorage,
|
|
@@ -858,37 +853,35 @@ bucket_definitions:
|
|
|
858
853
|
expect(checkpoint1[0].checkpoint?.buckets?.map((b) => b.bucket)).toEqual([]);
|
|
859
854
|
expect(checkpoint1).toMatchSnapshot();
|
|
860
855
|
// Add user
|
|
861
|
-
await
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
afterReplicaId: 'user1'
|
|
870
|
-
});
|
|
871
|
-
await batch.commit('0/1');
|
|
856
|
+
await writer.save({
|
|
857
|
+
sourceTable: usersTable,
|
|
858
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
859
|
+
after: {
|
|
860
|
+
id: 'user1',
|
|
861
|
+
name: 'User 1'
|
|
862
|
+
},
|
|
863
|
+
afterReplicaId: 'user1'
|
|
872
864
|
});
|
|
873
|
-
|
|
865
|
+
await writer.commit('0/1');
|
|
874
866
|
const checkpoint2 = await getCheckpointLines(iter);
|
|
867
|
+
const { bucket } = test_utils.bucketRequest(syncRules, 'by_user["user1"]');
|
|
875
868
|
expect(checkpoint2[0].checkpoint_diff?.updated_buckets?.map((b) => b.bucket)).toEqual([bucket]);
|
|
876
869
|
expect(checkpoint2).toMatchSnapshot();
|
|
877
870
|
}
|
|
878
|
-
catch (
|
|
879
|
-
|
|
880
|
-
|
|
871
|
+
catch (e_10) {
|
|
872
|
+
env_10.error = e_10;
|
|
873
|
+
env_10.hasError = true;
|
|
881
874
|
}
|
|
882
875
|
finally {
|
|
883
|
-
const
|
|
884
|
-
if (
|
|
885
|
-
await
|
|
876
|
+
const result_10 = __disposeResources(env_10);
|
|
877
|
+
if (result_10)
|
|
878
|
+
await result_10;
|
|
886
879
|
}
|
|
887
880
|
});
|
|
888
881
|
test('sync updates to data query only', async (context) => {
|
|
889
|
-
const
|
|
882
|
+
const env_11 = { stack: [], error: void 0, hasError: false };
|
|
890
883
|
try {
|
|
891
|
-
const f = __addDisposableResource(
|
|
884
|
+
const f = __addDisposableResource(env_11, await factory(), true);
|
|
892
885
|
const syncRules = await updateSyncRules(f, {
|
|
893
886
|
content: `bucket_definitions:
|
|
894
887
|
by_user:
|
|
@@ -897,22 +890,21 @@ bucket_definitions:
|
|
|
897
890
|
- select * from lists where user_id = bucket.user_id
|
|
898
891
|
`
|
|
899
892
|
});
|
|
900
|
-
const usersTable = test_utils.makeTestTable('users', ['id'], config);
|
|
901
|
-
const listsTable = test_utils.makeTestTable('lists', ['id'], config);
|
|
902
893
|
const bucketStorage = await f.getInstance(syncRules);
|
|
903
|
-
await bucketStorage.
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
}
|
|
914
|
-
|
|
894
|
+
const writer = __addDisposableResource(env_11, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
895
|
+
const usersTable = await test_utils.resolveTestTable(writer, 'users', ['id'], config, 1);
|
|
896
|
+
const listsTable = await test_utils.resolveTestTable(writer, 'lists', ['id'], config, 2);
|
|
897
|
+
await writer.markAllSnapshotDone('0/1');
|
|
898
|
+
await writer.save({
|
|
899
|
+
sourceTable: usersTable,
|
|
900
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
901
|
+
after: {
|
|
902
|
+
id: 'user1',
|
|
903
|
+
name: 'User 1'
|
|
904
|
+
},
|
|
905
|
+
afterReplicaId: 'user1'
|
|
915
906
|
});
|
|
907
|
+
await writer.commit('0/1');
|
|
916
908
|
const stream = sync.streamResponse({
|
|
917
909
|
syncContext,
|
|
918
910
|
bucketStorage,
|
|
@@ -934,37 +926,35 @@ bucket_definitions:
|
|
|
934
926
|
const checkpoint1 = await getCheckpointLines(iter);
|
|
935
927
|
expect(checkpoint1[0].checkpoint?.buckets?.map((b) => b.bucket)).toEqual([bucket]);
|
|
936
928
|
expect(checkpoint1).toMatchSnapshot();
|
|
937
|
-
await
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
afterReplicaId: 'list1'
|
|
947
|
-
});
|
|
948
|
-
await batch.commit('0/1');
|
|
929
|
+
await writer.save({
|
|
930
|
+
sourceTable: listsTable,
|
|
931
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
932
|
+
after: {
|
|
933
|
+
id: 'list1',
|
|
934
|
+
user_id: 'user1',
|
|
935
|
+
name: 'User 1'
|
|
936
|
+
},
|
|
937
|
+
afterReplicaId: 'list1'
|
|
949
938
|
});
|
|
939
|
+
await writer.commit('0/1');
|
|
950
940
|
const checkpoint2 = await getCheckpointLines(iter);
|
|
951
941
|
expect(checkpoint2[0].checkpoint_diff?.updated_buckets?.map((b) => b.bucket)).toEqual([bucket]);
|
|
952
942
|
expect(checkpoint2).toMatchSnapshot();
|
|
953
943
|
}
|
|
954
|
-
catch (
|
|
955
|
-
|
|
956
|
-
|
|
944
|
+
catch (e_11) {
|
|
945
|
+
env_11.error = e_11;
|
|
946
|
+
env_11.hasError = true;
|
|
957
947
|
}
|
|
958
948
|
finally {
|
|
959
|
-
const
|
|
960
|
-
if (
|
|
961
|
-
await
|
|
949
|
+
const result_11 = __disposeResources(env_11);
|
|
950
|
+
if (result_11)
|
|
951
|
+
await result_11;
|
|
962
952
|
}
|
|
963
953
|
});
|
|
964
954
|
test('sync updates to parameter query + data', async (context) => {
|
|
965
|
-
const
|
|
955
|
+
const env_12 = { stack: [], error: void 0, hasError: false };
|
|
966
956
|
try {
|
|
967
|
-
const f = __addDisposableResource(
|
|
957
|
+
const f = __addDisposableResource(env_12, await factory(), true);
|
|
968
958
|
const syncRules = await updateSyncRules(f, {
|
|
969
959
|
content: `bucket_definitions:
|
|
970
960
|
by_user:
|
|
@@ -973,14 +963,13 @@ bucket_definitions:
|
|
|
973
963
|
- select * from lists where user_id = bucket.user_id
|
|
974
964
|
`
|
|
975
965
|
});
|
|
976
|
-
const usersTable = test_utils.makeTestTable('users', ['id'], config);
|
|
977
|
-
const listsTable = test_utils.makeTestTable('lists', ['id'], config);
|
|
978
966
|
const bucketStorage = await f.getInstance(syncRules);
|
|
967
|
+
const writer = __addDisposableResource(env_12, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
968
|
+
const usersTable = await test_utils.resolveTestTable(writer, 'users', ['id'], config, 1);
|
|
969
|
+
const listsTable = await test_utils.resolveTestTable(writer, 'lists', ['id'], config, 2);
|
|
979
970
|
// Activate
|
|
980
|
-
await
|
|
981
|
-
|
|
982
|
-
await batch.keepalive('0/0');
|
|
983
|
-
});
|
|
971
|
+
await writer.markAllSnapshotDone('0/0');
|
|
972
|
+
await writer.keepalive('0/0');
|
|
984
973
|
const stream = sync.streamResponse({
|
|
985
974
|
syncContext,
|
|
986
975
|
bucketStorage,
|
|
@@ -1000,57 +989,54 @@ bucket_definitions:
|
|
|
1000
989
|
});
|
|
1001
990
|
// Initial empty checkpoint
|
|
1002
991
|
expect(await getCheckpointLines(iter)).toMatchSnapshot();
|
|
1003
|
-
await
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
afterReplicaId: 'list1'
|
|
1014
|
-
});
|
|
1015
|
-
await batch.save({
|
|
1016
|
-
sourceTable: usersTable,
|
|
1017
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
1018
|
-
after: {
|
|
1019
|
-
id: 'user1',
|
|
1020
|
-
name: 'User 1'
|
|
1021
|
-
},
|
|
1022
|
-
afterReplicaId: 'user1'
|
|
1023
|
-
});
|
|
1024
|
-
await batch.commit('0/1');
|
|
992
|
+
await writer.markAllSnapshotDone('0/1');
|
|
993
|
+
await writer.save({
|
|
994
|
+
sourceTable: listsTable,
|
|
995
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
996
|
+
after: {
|
|
997
|
+
id: 'list1',
|
|
998
|
+
user_id: 'user1',
|
|
999
|
+
name: 'User 1'
|
|
1000
|
+
},
|
|
1001
|
+
afterReplicaId: 'list1'
|
|
1025
1002
|
});
|
|
1026
|
-
|
|
1003
|
+
await writer.save({
|
|
1004
|
+
sourceTable: usersTable,
|
|
1005
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
1006
|
+
after: {
|
|
1007
|
+
id: 'user1',
|
|
1008
|
+
name: 'User 1'
|
|
1009
|
+
},
|
|
1010
|
+
afterReplicaId: 'user1'
|
|
1011
|
+
});
|
|
1012
|
+
await writer.commit('0/1');
|
|
1013
|
+
const { bucket } = test_utils.bucketRequest(syncRules, 'by_user["user1"]');
|
|
1027
1014
|
const checkpoint2 = await getCheckpointLines(iter);
|
|
1028
1015
|
expect(checkpoint2[0].checkpoint_diff?.updated_buckets?.map((b) => b.bucket)).toEqual([bucket]);
|
|
1029
1016
|
expect(checkpoint2).toMatchSnapshot();
|
|
1030
1017
|
}
|
|
1031
|
-
catch (
|
|
1032
|
-
|
|
1033
|
-
|
|
1018
|
+
catch (e_12) {
|
|
1019
|
+
env_12.error = e_12;
|
|
1020
|
+
env_12.hasError = true;
|
|
1034
1021
|
}
|
|
1035
1022
|
finally {
|
|
1036
|
-
const
|
|
1037
|
-
if (
|
|
1038
|
-
await
|
|
1023
|
+
const result_12 = __disposeResources(env_12);
|
|
1024
|
+
if (result_12)
|
|
1025
|
+
await result_12;
|
|
1039
1026
|
}
|
|
1040
1027
|
});
|
|
1041
1028
|
test('expiring token', async (context) => {
|
|
1042
|
-
const
|
|
1029
|
+
const env_13 = { stack: [], error: void 0, hasError: false };
|
|
1043
1030
|
try {
|
|
1044
|
-
const f = __addDisposableResource(
|
|
1031
|
+
const f = __addDisposableResource(env_13, await factory(), true);
|
|
1045
1032
|
const syncRules = await updateSyncRules(f, {
|
|
1046
1033
|
content: BASIC_SYNC_RULES
|
|
1047
1034
|
});
|
|
1048
1035
|
const bucketStorage = await f.getInstance(syncRules);
|
|
1036
|
+
const writer = __addDisposableResource(env_13, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
1049
1037
|
// Activate
|
|
1050
|
-
await
|
|
1051
|
-
|
|
1052
|
-
await batch.keepalive('0/0');
|
|
1053
|
-
});
|
|
1038
|
+
await writer.markAllSnapshotDone('0/0');
|
|
1039
|
+
await writer.keepalive('0/0');
|
|
1054
1040
|
const exp = Date.now() / 1000 + 0.1;
|
|
1055
1041
|
const stream = sync.streamResponse({
|
|
1056
1042
|
syncContext,
|
|
@@ -1074,50 +1060,50 @@ bucket_definitions:
|
|
|
1074
1060
|
const expLines = await getCheckpointLines(iter);
|
|
1075
1061
|
expect(expLines).toMatchSnapshot();
|
|
1076
1062
|
}
|
|
1077
|
-
catch (
|
|
1078
|
-
|
|
1079
|
-
|
|
1063
|
+
catch (e_13) {
|
|
1064
|
+
env_13.error = e_13;
|
|
1065
|
+
env_13.hasError = true;
|
|
1080
1066
|
}
|
|
1081
1067
|
finally {
|
|
1082
|
-
const
|
|
1083
|
-
if (
|
|
1084
|
-
await
|
|
1068
|
+
const result_13 = __disposeResources(env_13);
|
|
1069
|
+
if (result_13)
|
|
1070
|
+
await result_13;
|
|
1085
1071
|
}
|
|
1086
1072
|
});
|
|
1087
1073
|
test('compacting data - invalidate checkpoint', async (context) => {
|
|
1088
|
-
const
|
|
1074
|
+
const env_14 = { stack: [], error: void 0, hasError: false };
|
|
1089
1075
|
try {
|
|
1090
1076
|
// This tests a case of a compact operation invalidating a checkpoint in the
|
|
1091
1077
|
// middle of syncing data.
|
|
1092
1078
|
// This is expected to be rare in practice, but it is important to handle
|
|
1093
1079
|
// this case correctly to maintain consistency on the client.
|
|
1094
|
-
const f = __addDisposableResource(
|
|
1080
|
+
const f = __addDisposableResource(env_14, await factory(), true);
|
|
1095
1081
|
const syncRules = await updateSyncRules(f, {
|
|
1096
1082
|
content: BASIC_SYNC_RULES
|
|
1097
1083
|
});
|
|
1098
1084
|
const bucketStorage = await f.getInstance(syncRules);
|
|
1099
|
-
await bucketStorage.
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
await batch.save({
|
|
1111
|
-
sourceTable: TEST_TABLE,
|
|
1112
|
-
tag: storage.SaveOperationTag.INSERT,
|
|
1113
|
-
after: {
|
|
1114
|
-
id: 't2',
|
|
1115
|
-
description: 'Test 2'
|
|
1116
|
-
},
|
|
1117
|
-
afterReplicaId: 't2'
|
|
1118
|
-
});
|
|
1119
|
-
await batch.commit('0/1');
|
|
1085
|
+
const writer = __addDisposableResource(env_14, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
1086
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config);
|
|
1087
|
+
await writer.markAllSnapshotDone('0/1');
|
|
1088
|
+
await writer.save({
|
|
1089
|
+
sourceTable: testTable,
|
|
1090
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
1091
|
+
after: {
|
|
1092
|
+
id: 't1',
|
|
1093
|
+
description: 'Test 1'
|
|
1094
|
+
},
|
|
1095
|
+
afterReplicaId: 't1'
|
|
1120
1096
|
});
|
|
1097
|
+
await writer.save({
|
|
1098
|
+
sourceTable: testTable,
|
|
1099
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
1100
|
+
after: {
|
|
1101
|
+
id: 't2',
|
|
1102
|
+
description: 'Test 2'
|
|
1103
|
+
},
|
|
1104
|
+
afterReplicaId: 't2'
|
|
1105
|
+
});
|
|
1106
|
+
await writer.commit('0/1');
|
|
1121
1107
|
const stream = sync.streamResponse({
|
|
1122
1108
|
syncContext,
|
|
1123
1109
|
bucketStorage,
|
|
@@ -1145,28 +1131,26 @@ bucket_definitions:
|
|
|
1145
1131
|
});
|
|
1146
1132
|
// Now we save additional data AND compact before continuing.
|
|
1147
1133
|
// This invalidates the checkpoint we've received above.
|
|
1148
|
-
await
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
afterReplicaId: 't2'
|
|
1167
|
-
});
|
|
1168
|
-
await batch.commit('0/2');
|
|
1134
|
+
await writer.markAllSnapshotDone('0/1');
|
|
1135
|
+
await writer.save({
|
|
1136
|
+
sourceTable: testTable,
|
|
1137
|
+
tag: storage.SaveOperationTag.UPDATE,
|
|
1138
|
+
after: {
|
|
1139
|
+
id: 't1',
|
|
1140
|
+
description: 'Test 1b'
|
|
1141
|
+
},
|
|
1142
|
+
afterReplicaId: 't1'
|
|
1143
|
+
});
|
|
1144
|
+
await writer.save({
|
|
1145
|
+
sourceTable: testTable,
|
|
1146
|
+
tag: storage.SaveOperationTag.UPDATE,
|
|
1147
|
+
after: {
|
|
1148
|
+
id: 't2',
|
|
1149
|
+
description: 'Test 2b'
|
|
1150
|
+
},
|
|
1151
|
+
afterReplicaId: 't2'
|
|
1169
1152
|
});
|
|
1153
|
+
await writer.commit('0/2');
|
|
1170
1154
|
await bucketStorage.compact({
|
|
1171
1155
|
minBucketChanges: 1,
|
|
1172
1156
|
minChangeRatio: 0
|
|
@@ -1214,29 +1198,28 @@ bucket_definitions:
|
|
|
1214
1198
|
})
|
|
1215
1199
|
});
|
|
1216
1200
|
}
|
|
1217
|
-
catch (
|
|
1218
|
-
|
|
1219
|
-
|
|
1201
|
+
catch (e_14) {
|
|
1202
|
+
env_14.error = e_14;
|
|
1203
|
+
env_14.hasError = true;
|
|
1220
1204
|
}
|
|
1221
1205
|
finally {
|
|
1222
|
-
const
|
|
1223
|
-
if (
|
|
1224
|
-
await
|
|
1206
|
+
const result_14 = __disposeResources(env_14);
|
|
1207
|
+
if (result_14)
|
|
1208
|
+
await result_14;
|
|
1225
1209
|
}
|
|
1226
1210
|
});
|
|
1227
1211
|
test('write checkpoint', async () => {
|
|
1228
|
-
const
|
|
1212
|
+
const env_15 = { stack: [], error: void 0, hasError: false };
|
|
1229
1213
|
try {
|
|
1230
|
-
const f = __addDisposableResource(
|
|
1214
|
+
const f = __addDisposableResource(env_15, await factory(), true);
|
|
1231
1215
|
const syncRules = await updateSyncRules(f, {
|
|
1232
1216
|
content: BASIC_SYNC_RULES
|
|
1233
1217
|
});
|
|
1234
1218
|
const bucketStorage = f.getInstance(syncRules);
|
|
1235
|
-
await bucketStorage.
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
});
|
|
1219
|
+
const writer = __addDisposableResource(env_15, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
1220
|
+
await writer.markAllSnapshotDone('0/1');
|
|
1221
|
+
// <= the managed write checkpoint LSN below
|
|
1222
|
+
await writer.commit('0/1');
|
|
1240
1223
|
const checkpoint = await bucketStorage.createManagedWriteCheckpoint({
|
|
1241
1224
|
user_id: 'test',
|
|
1242
1225
|
heads: { '1': '1/0' }
|
|
@@ -1264,11 +1247,9 @@ bucket_definitions:
|
|
|
1264
1247
|
write_checkpoint: undefined
|
|
1265
1248
|
})
|
|
1266
1249
|
});
|
|
1267
|
-
await
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
await batch.commit('1/0');
|
|
1271
|
-
});
|
|
1250
|
+
await writer.markAllSnapshotDone('0/1');
|
|
1251
|
+
// must be >= the managed write checkpoint LSN
|
|
1252
|
+
await writer.commit('1/0');
|
|
1272
1253
|
// At this point the LSN has advanced, so the write checkpoint should be
|
|
1273
1254
|
// included in the next checkpoint message.
|
|
1274
1255
|
const stream2 = sync.streamResponse(params);
|
|
@@ -1280,21 +1261,24 @@ bucket_definitions:
|
|
|
1280
1261
|
})
|
|
1281
1262
|
});
|
|
1282
1263
|
}
|
|
1283
|
-
catch (
|
|
1284
|
-
|
|
1285
|
-
|
|
1264
|
+
catch (e_15) {
|
|
1265
|
+
env_15.error = e_15;
|
|
1266
|
+
env_15.hasError = true;
|
|
1286
1267
|
}
|
|
1287
1268
|
finally {
|
|
1288
|
-
const
|
|
1289
|
-
if (
|
|
1290
|
-
await
|
|
1269
|
+
const result_15 = __disposeResources(env_15);
|
|
1270
|
+
if (result_15)
|
|
1271
|
+
await result_15;
|
|
1291
1272
|
}
|
|
1292
1273
|
});
|
|
1293
|
-
test('encodes sync rules id in
|
|
1294
|
-
const
|
|
1274
|
+
test('encodes sync rules id in buckets for streams', async () => {
|
|
1275
|
+
const env_16 = { stack: [], error: void 0, hasError: false };
|
|
1295
1276
|
try {
|
|
1296
|
-
const f = __addDisposableResource(
|
|
1297
|
-
|
|
1277
|
+
const f = __addDisposableResource(env_16, await factory(), true);
|
|
1278
|
+
// This test relies making an actual update to sync rules to test the different bucket names.
|
|
1279
|
+
// The actual naming scheme may change, as long as the two buckets have different names.
|
|
1280
|
+
const rules = [
|
|
1281
|
+
`
|
|
1298
1282
|
streams:
|
|
1299
1283
|
test:
|
|
1300
1284
|
auto_subscribe: true
|
|
@@ -1302,16 +1286,29 @@ streams:
|
|
|
1302
1286
|
|
|
1303
1287
|
config:
|
|
1304
1288
|
edition: 2
|
|
1305
|
-
|
|
1289
|
+
`,
|
|
1290
|
+
`
|
|
1291
|
+
streams:
|
|
1292
|
+
test2:
|
|
1293
|
+
auto_subscribe: true
|
|
1294
|
+
query: SELECT * FROM test WHERE 1;
|
|
1295
|
+
|
|
1296
|
+
config:
|
|
1297
|
+
edition: 2
|
|
1298
|
+
`
|
|
1299
|
+
];
|
|
1306
1300
|
for (let i = 0; i < 2; i++) {
|
|
1307
|
-
const
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
await
|
|
1314
|
-
|
|
1301
|
+
const env_17 = { stack: [], error: void 0, hasError: false };
|
|
1302
|
+
try {
|
|
1303
|
+
const syncRules = await updateSyncRules(f, {
|
|
1304
|
+
content: rules[i]
|
|
1305
|
+
});
|
|
1306
|
+
const bucketStorage = f.getInstance(syncRules);
|
|
1307
|
+
const writer = __addDisposableResource(env_17, await bucketStorage.createWriter(test_utils.BATCH_OPTIONS), true);
|
|
1308
|
+
const testTable = await test_utils.resolveTestTable(writer, 'test', ['id'], config, i + 1);
|
|
1309
|
+
await writer.markAllSnapshotDone('0/1');
|
|
1310
|
+
await writer.save({
|
|
1311
|
+
sourceTable: testTable,
|
|
1315
1312
|
tag: storage.SaveOperationTag.INSERT,
|
|
1316
1313
|
after: {
|
|
1317
1314
|
id: 't1',
|
|
@@ -1319,33 +1316,42 @@ config:
|
|
|
1319
1316
|
},
|
|
1320
1317
|
afterReplicaId: 't1'
|
|
1321
1318
|
});
|
|
1322
|
-
await
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1319
|
+
await writer.commit('0/1');
|
|
1320
|
+
const stream = sync.streamResponse({
|
|
1321
|
+
syncContext,
|
|
1322
|
+
bucketStorage: bucketStorage,
|
|
1323
|
+
syncRules: bucketStorage.getParsedSyncRules(test_utils.PARSE_OPTIONS),
|
|
1324
|
+
params: {
|
|
1325
|
+
buckets: [],
|
|
1326
|
+
include_checksum: true,
|
|
1327
|
+
raw_data: true
|
|
1328
|
+
},
|
|
1329
|
+
tracker,
|
|
1330
|
+
token: new JwtPayload({ sub: '', exp: Date.now() / 1000 + 10 }),
|
|
1331
|
+
isEncodingAsBson: false
|
|
1332
|
+
});
|
|
1333
|
+
const lines = await consumeCheckpointLines(stream);
|
|
1334
|
+
expect(lines).toMatchSnapshot();
|
|
1335
|
+
}
|
|
1336
|
+
catch (e_16) {
|
|
1337
|
+
env_17.error = e_16;
|
|
1338
|
+
env_17.hasError = true;
|
|
1339
|
+
}
|
|
1340
|
+
finally {
|
|
1341
|
+
const result_16 = __disposeResources(env_17);
|
|
1342
|
+
if (result_16)
|
|
1343
|
+
await result_16;
|
|
1344
|
+
}
|
|
1339
1345
|
}
|
|
1340
1346
|
}
|
|
1341
|
-
catch (
|
|
1342
|
-
|
|
1343
|
-
|
|
1347
|
+
catch (e_17) {
|
|
1348
|
+
env_16.error = e_17;
|
|
1349
|
+
env_16.hasError = true;
|
|
1344
1350
|
}
|
|
1345
1351
|
finally {
|
|
1346
|
-
const
|
|
1347
|
-
if (
|
|
1348
|
-
await
|
|
1352
|
+
const result_17 = __disposeResources(env_16);
|
|
1353
|
+
if (result_17)
|
|
1354
|
+
await result_17;
|
|
1349
1355
|
}
|
|
1350
1356
|
});
|
|
1351
1357
|
}
|