@powersync/service-core-tests 0.13.2 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/dist/test-utils/general-utils.d.ts +9 -3
- package/dist/test-utils/general-utils.js +26 -26
- package/dist/test-utils/general-utils.js.map +1 -1
- package/dist/tests/register-compacting-tests.d.ts +1 -1
- package/dist/tests/register-compacting-tests.js +136 -93
- package/dist/tests/register-compacting-tests.js.map +1 -1
- package/dist/tests/register-data-storage-checkpoint-tests.d.ts +1 -1
- package/dist/tests/register-data-storage-checkpoint-tests.js +44 -27
- package/dist/tests/register-data-storage-checkpoint-tests.js.map +1 -1
- package/dist/tests/register-data-storage-data-tests.d.ts +2 -2
- package/dist/tests/register-data-storage-data-tests.js +715 -207
- package/dist/tests/register-data-storage-data-tests.js.map +1 -1
- package/dist/tests/register-data-storage-parameter-tests.d.ts +1 -1
- package/dist/tests/register-data-storage-parameter-tests.js +123 -58
- package/dist/tests/register-data-storage-parameter-tests.js.map +1 -1
- package/dist/tests/register-parameter-compacting-tests.d.ts +1 -1
- package/dist/tests/register-parameter-compacting-tests.js +13 -13
- package/dist/tests/register-parameter-compacting-tests.js.map +1 -1
- package/dist/tests/register-sync-tests.d.ts +4 -1
- package/dist/tests/register-sync-tests.js +63 -34
- package/dist/tests/register-sync-tests.js.map +1 -1
- package/dist/tests/util.d.ts +6 -1
- package/dist/tests/util.js +31 -2
- package/dist/tests/util.js.map +1 -1
- package/package.json +3 -3
- package/src/test-utils/general-utils.ts +42 -28
- package/src/tests/register-compacting-tests.ts +153 -103
- package/src/tests/register-data-storage-checkpoint-tests.ts +70 -22
- package/src/tests/register-data-storage-data-tests.ts +732 -110
- package/src/tests/register-data-storage-parameter-tests.ts +168 -59
- package/src/tests/register-parameter-compacting-tests.ts +18 -13
- package/src/tests/register-sync-tests.ts +71 -35
- package/src/tests/util.ts +52 -2
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# @powersync/service-core-tests
|
|
2
2
|
|
|
3
|
+
## 0.15.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 8c5bb3b: [Internal] Allow using multiple BucketStorageBatch instances concurrently.
|
|
8
|
+
- c15efc7: [Internal] Track and propagate source on buckets and parameter indexes to storage APIs.
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- 642cb11: [Postgres Storage] Fix concurrency issue in compacting, leading to "[PSYNC_S1101] Unexpected PUT operation".
|
|
13
|
+
- Updated dependencies [8c5bb3b]
|
|
14
|
+
- Updated dependencies [dcddcf1]
|
|
15
|
+
- Updated dependencies [c15efc7]
|
|
16
|
+
- Updated dependencies [e7152ce]
|
|
17
|
+
- Updated dependencies [e150c5c]
|
|
18
|
+
- Updated dependencies [b410924]
|
|
19
|
+
- @powersync/service-core@1.20.1
|
|
20
|
+
- @powersync/service-sync-rules@0.33.0
|
|
21
|
+
|
|
22
|
+
## 0.14.0
|
|
23
|
+
|
|
24
|
+
### Minor Changes
|
|
25
|
+
|
|
26
|
+
- 8a4c34e: Refactor `BucketStorageFactory` and `PersistedSyncRulesContent` to be abstract classes instead of interfaces.
|
|
27
|
+
- 8bd83e8: Introduce storage versions.
|
|
28
|
+
|
|
29
|
+
### Patch Changes
|
|
30
|
+
|
|
31
|
+
- Updated dependencies [0998251]
|
|
32
|
+
- Updated dependencies [65f3c89]
|
|
33
|
+
- Updated dependencies [1c45667]
|
|
34
|
+
- Updated dependencies [8785a3f]
|
|
35
|
+
- Updated dependencies [8a4c34e]
|
|
36
|
+
- Updated dependencies [b440093]
|
|
37
|
+
- Updated dependencies [d7ff4ad]
|
|
38
|
+
- Updated dependencies [c683322]
|
|
39
|
+
- Updated dependencies [8bd83e8]
|
|
40
|
+
- Updated dependencies [83989b2]
|
|
41
|
+
- Updated dependencies [79a9729]
|
|
42
|
+
- Updated dependencies [5edd95f]
|
|
43
|
+
- @powersync/service-core@1.20.0
|
|
44
|
+
- @powersync/service-sync-rules@0.32.0
|
|
45
|
+
|
|
3
46
|
## 0.13.2
|
|
4
47
|
|
|
5
48
|
### Patch Changes
|
|
@@ -1,17 +1,23 @@
|
|
|
1
|
-
import { storage, utils } from '@powersync/service-core';
|
|
1
|
+
import { BucketDataRequest, InternalOpId, storage, utils } from '@powersync/service-core';
|
|
2
2
|
import { GetQuerierOptions, RequestParameters } from '@powersync/service-sync-rules';
|
|
3
3
|
import * as bson from 'bson';
|
|
4
4
|
export declare const ZERO_LSN = "0/0";
|
|
5
5
|
export declare const PARSE_OPTIONS: storage.ParseSyncRulesOptions;
|
|
6
6
|
export declare const BATCH_OPTIONS: storage.StartBatchOptions;
|
|
7
|
-
export declare function
|
|
8
|
-
|
|
7
|
+
export declare function makeTestTable(name: string, replicaIdColumns?: string[] | undefined, options?: {
|
|
8
|
+
tableIdStrings: boolean;
|
|
9
|
+
}): storage.SourceTable;
|
|
9
10
|
export declare function getBatchData(batch: utils.SyncBucketData[] | storage.SyncBucketDataChunk[] | storage.SyncBucketDataChunk): {
|
|
10
11
|
op_id: string;
|
|
11
12
|
op: "PUT" | "REMOVE" | "MOVE" | "CLEAR";
|
|
12
13
|
object_id: string | undefined;
|
|
13
14
|
checksum: number | bigint;
|
|
14
15
|
}[];
|
|
16
|
+
/**
|
|
17
|
+
* Bucket names no longer purely depend on the sync rules.
|
|
18
|
+
* This converts a bucket name like "global[]" into the actual bucket name, for use in tests.
|
|
19
|
+
*/
|
|
20
|
+
export declare function bucketRequest(syncRules: storage.PersistedSyncRulesContent | storage.PersistedSyncRules, bucket: string, start?: InternalOpId | string | number): BucketDataRequest;
|
|
15
21
|
export declare function getBatchMeta(batch: utils.SyncBucketData[] | storage.SyncBucketDataChunk[] | storage.SyncBucketDataChunk): {
|
|
16
22
|
has_more: boolean;
|
|
17
23
|
after: string;
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import { storage, utils } from '@powersync/service-core';
|
|
2
|
-
import { SqlSyncRules } from '@powersync/service-sync-rules';
|
|
3
|
-
import { versionedHydrationState } from '@powersync/service-sync-rules/src/HydrationState.js';
|
|
4
2
|
import * as bson from 'bson';
|
|
5
3
|
export const ZERO_LSN = '0/0';
|
|
6
4
|
export const PARSE_OPTIONS = {
|
|
@@ -11,31 +9,9 @@ export const BATCH_OPTIONS = {
|
|
|
11
9
|
zeroLSN: ZERO_LSN,
|
|
12
10
|
storeCurrentData: true
|
|
13
11
|
};
|
|
14
|
-
export function
|
|
15
|
-
return {
|
|
16
|
-
id: 1,
|
|
17
|
-
sync_rules_content: content,
|
|
18
|
-
slot_name: 'test',
|
|
19
|
-
active: true,
|
|
20
|
-
last_checkpoint_lsn: '',
|
|
21
|
-
parsed(options) {
|
|
22
|
-
return {
|
|
23
|
-
id: 1,
|
|
24
|
-
sync_rules: SqlSyncRules.fromYaml(content, options),
|
|
25
|
-
slot_name: 'test',
|
|
26
|
-
hydratedSyncRules() {
|
|
27
|
-
return this.sync_rules.config.hydrate({ hydrationState: versionedHydrationState(1) });
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
},
|
|
31
|
-
lock() {
|
|
32
|
-
throw new Error('Not implemented');
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
export function makeTestTable(name, replicaIdColumns) {
|
|
12
|
+
export function makeTestTable(name, replicaIdColumns, options) {
|
|
37
13
|
const relId = utils.hashData('table', name, (replicaIdColumns ?? ['id']).join(','));
|
|
38
|
-
const id = new bson.ObjectId('6544e3899293153fa7b38331');
|
|
14
|
+
const id = options?.tableIdStrings == false ? new bson.ObjectId('6544e3899293153fa7b38331') : '6544e3899293153fa7b38331';
|
|
39
15
|
return new storage.SourceTable({
|
|
40
16
|
id: id,
|
|
41
17
|
connectionTag: storage.SourceTable.DEFAULT_TAG,
|
|
@@ -60,6 +36,30 @@ export function getBatchData(batch) {
|
|
|
60
36
|
};
|
|
61
37
|
});
|
|
62
38
|
}
|
|
39
|
+
function isParsedSyncRules(syncRules) {
|
|
40
|
+
return syncRules.sync_rules !== undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Bucket names no longer purely depend on the sync rules.
|
|
44
|
+
* This converts a bucket name like "global[]" into the actual bucket name, for use in tests.
|
|
45
|
+
*/
|
|
46
|
+
export function bucketRequest(syncRules, bucket, start) {
|
|
47
|
+
const parsed = isParsedSyncRules(syncRules) ? syncRules : syncRules.parsed(PARSE_OPTIONS);
|
|
48
|
+
const hydrationState = parsed.hydrationState;
|
|
49
|
+
const parameterStart = bucket.indexOf('[');
|
|
50
|
+
const definitionName = bucket.substring(0, parameterStart);
|
|
51
|
+
const parameters = bucket.substring(parameterStart);
|
|
52
|
+
const source = parsed.sync_rules.config.bucketDataSources.find((b) => b.uniqueName === definitionName);
|
|
53
|
+
if (source == null) {
|
|
54
|
+
throw new Error(`Failed to find global bucket ${bucket}`);
|
|
55
|
+
}
|
|
56
|
+
const bucketName = hydrationState.getBucketSourceScope(source).bucketPrefix + parameters;
|
|
57
|
+
return {
|
|
58
|
+
bucket: bucketName,
|
|
59
|
+
start: BigInt(start ?? 0n),
|
|
60
|
+
source: source
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
63
|
export function getBatchMeta(batch) {
|
|
64
64
|
const first = getFirst(batch);
|
|
65
65
|
if (first == null) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"general-utils.js","sourceRoot":"","sources":["../../src/test-utils/general-utils.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"general-utils.js","sourceRoot":"","sources":["../../src/test-utils/general-utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { storage } from '@powersync/service-core';
|
|
2
|
-
export declare function registerCompactTests(
|
|
2
|
+
export declare function registerCompactTests(config: storage.TestStorageConfig): void;
|
|
@@ -50,24 +50,26 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
|
|
|
50
50
|
var e = new Error(message);
|
|
51
51
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
52
52
|
});
|
|
53
|
-
import { storage } from '@powersync/service-core';
|
|
53
|
+
import { addChecksums, storage, updateSyncRulesFromYaml } from '@powersync/service-core';
|
|
54
54
|
import { expect, test } from 'vitest';
|
|
55
55
|
import * as test_utils from '../test-utils/test-utils-index.js';
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
import { bucketRequest } from '../test-utils/test-utils-index.js';
|
|
57
|
+
import { bucketRequestMap, bucketRequests } from './util.js';
|
|
58
|
+
export function registerCompactTests(config) {
|
|
59
|
+
const generateStorageFactory = config.factory;
|
|
60
|
+
const TEST_TABLE = test_utils.makeTestTable('test', ['id'], config);
|
|
58
61
|
test('compacting (1)', async () => {
|
|
59
62
|
const env_1 = { stack: [], error: void 0, hasError: false };
|
|
60
63
|
try {
|
|
61
64
|
const factory = __addDisposableResource(env_1, await generateStorageFactory(), true);
|
|
62
|
-
const syncRules = await factory.updateSyncRules(
|
|
63
|
-
content: `
|
|
65
|
+
const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(`
|
|
64
66
|
bucket_definitions:
|
|
65
67
|
global:
|
|
66
68
|
data: [select * from test]
|
|
67
|
-
`
|
|
68
|
-
});
|
|
69
|
+
`));
|
|
69
70
|
const bucketStorage = factory.getInstance(syncRules);
|
|
70
71
|
const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
72
|
+
await batch.markAllSnapshotDone('1/1');
|
|
71
73
|
await batch.save({
|
|
72
74
|
sourceTable: TEST_TABLE,
|
|
73
75
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -95,24 +97,22 @@ bucket_definitions:
|
|
|
95
97
|
await batch.commit('1/1');
|
|
96
98
|
});
|
|
97
99
|
const checkpoint = result.flushed_op;
|
|
98
|
-
const
|
|
100
|
+
const request = bucketRequest(syncRules, 'global[]');
|
|
101
|
+
const batchBefore = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
99
102
|
const dataBefore = batchBefore.chunkData.data;
|
|
100
|
-
const checksumBefore = await bucketStorage.getChecksums(checkpoint, [
|
|
103
|
+
const checksumBefore = await bucketStorage.getChecksums(checkpoint, [request]);
|
|
101
104
|
expect(dataBefore).toMatchObject([
|
|
102
105
|
{
|
|
103
|
-
checksum: 2634521662,
|
|
104
106
|
object_id: 't1',
|
|
105
107
|
op: 'PUT',
|
|
106
108
|
op_id: '1'
|
|
107
109
|
},
|
|
108
110
|
{
|
|
109
|
-
checksum: 4243212114,
|
|
110
111
|
object_id: 't2',
|
|
111
112
|
op: 'PUT',
|
|
112
113
|
op_id: '2'
|
|
113
114
|
},
|
|
114
115
|
{
|
|
115
|
-
checksum: 4243212114,
|
|
116
116
|
object_id: 't2',
|
|
117
117
|
op: 'PUT',
|
|
118
118
|
op_id: '3'
|
|
@@ -126,33 +126,28 @@ bucket_definitions:
|
|
|
126
126
|
minBucketChanges: 1,
|
|
127
127
|
minChangeRatio: 0
|
|
128
128
|
});
|
|
129
|
-
const batchAfter = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint,
|
|
129
|
+
const batchAfter = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
130
130
|
const dataAfter = batchAfter.chunkData.data;
|
|
131
|
-
const checksumAfter = await bucketStorage.getChecksums(checkpoint, [
|
|
131
|
+
const checksumAfter = await bucketStorage.getChecksums(checkpoint, [request]);
|
|
132
132
|
bucketStorage.clearChecksumCache();
|
|
133
|
-
const checksumAfter2 = await bucketStorage.getChecksums(checkpoint, [
|
|
133
|
+
const checksumAfter2 = await bucketStorage.getChecksums(checkpoint, [request]);
|
|
134
134
|
expect(batchAfter.targetOp).toEqual(3n);
|
|
135
135
|
expect(dataAfter).toMatchObject([
|
|
136
|
+
dataBefore[0],
|
|
136
137
|
{
|
|
137
|
-
checksum:
|
|
138
|
-
object_id: 't1',
|
|
139
|
-
op: 'PUT',
|
|
140
|
-
op_id: '1'
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
checksum: 4243212114,
|
|
138
|
+
checksum: dataBefore[1].checksum,
|
|
144
139
|
op: 'MOVE',
|
|
145
140
|
op_id: '2'
|
|
146
141
|
},
|
|
147
142
|
{
|
|
148
|
-
checksum:
|
|
143
|
+
checksum: dataBefore[2].checksum,
|
|
149
144
|
object_id: 't2',
|
|
150
145
|
op: 'PUT',
|
|
151
146
|
op_id: '3'
|
|
152
147
|
}
|
|
153
148
|
]);
|
|
154
|
-
expect(checksumAfter.get(
|
|
155
|
-
expect(checksumAfter2.get(
|
|
149
|
+
expect(checksumAfter.get(request.bucket)).toEqual(checksumBefore.get(request.bucket));
|
|
150
|
+
expect(checksumAfter2.get(request.bucket)).toEqual(checksumBefore.get(request.bucket));
|
|
156
151
|
test_utils.validateCompactedBucket(dataBefore, dataAfter);
|
|
157
152
|
}
|
|
158
153
|
catch (e_1) {
|
|
@@ -169,15 +164,14 @@ bucket_definitions:
|
|
|
169
164
|
const env_2 = { stack: [], error: void 0, hasError: false };
|
|
170
165
|
try {
|
|
171
166
|
const factory = __addDisposableResource(env_2, await generateStorageFactory(), true);
|
|
172
|
-
const syncRules = await factory.updateSyncRules(
|
|
173
|
-
content: `
|
|
167
|
+
const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(`
|
|
174
168
|
bucket_definitions:
|
|
175
169
|
global:
|
|
176
170
|
data: [select * from test]
|
|
177
|
-
`
|
|
178
|
-
});
|
|
171
|
+
`));
|
|
179
172
|
const bucketStorage = factory.getInstance(syncRules);
|
|
180
173
|
const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
174
|
+
await batch.markAllSnapshotDone('1/1');
|
|
181
175
|
await batch.save({
|
|
182
176
|
sourceTable: TEST_TABLE,
|
|
183
177
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -213,33 +207,27 @@ bucket_definitions:
|
|
|
213
207
|
await batch.commit('1/1');
|
|
214
208
|
});
|
|
215
209
|
const checkpoint = result.flushed_op;
|
|
216
|
-
const
|
|
210
|
+
const request = bucketRequest(syncRules, 'global[]');
|
|
211
|
+
const batchBefore = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
217
212
|
const dataBefore = batchBefore.chunkData.data;
|
|
218
|
-
const checksumBefore = await bucketStorage.getChecksums(checkpoint, [
|
|
213
|
+
const checksumBefore = await bucketStorage.getChecksums(checkpoint, [request]);
|
|
214
|
+
// op_id sequence depends on the storage implementation
|
|
219
215
|
expect(dataBefore).toMatchObject([
|
|
220
216
|
{
|
|
221
|
-
checksum: 2634521662,
|
|
222
217
|
object_id: 't1',
|
|
223
|
-
op: 'PUT'
|
|
224
|
-
op_id: '1'
|
|
218
|
+
op: 'PUT'
|
|
225
219
|
},
|
|
226
220
|
{
|
|
227
|
-
checksum: 4243212114,
|
|
228
221
|
object_id: 't2',
|
|
229
|
-
op: 'PUT'
|
|
230
|
-
op_id: '2'
|
|
222
|
+
op: 'PUT'
|
|
231
223
|
},
|
|
232
224
|
{
|
|
233
|
-
checksum: 4228978084,
|
|
234
225
|
object_id: 't1',
|
|
235
|
-
op: 'REMOVE'
|
|
236
|
-
op_id: '3'
|
|
226
|
+
op: 'REMOVE'
|
|
237
227
|
},
|
|
238
228
|
{
|
|
239
|
-
checksum: 4243212114,
|
|
240
229
|
object_id: 't2',
|
|
241
|
-
op: 'PUT'
|
|
242
|
-
op_id: '4'
|
|
230
|
+
op: 'PUT'
|
|
243
231
|
}
|
|
244
232
|
]);
|
|
245
233
|
await bucketStorage.compact({
|
|
@@ -249,26 +237,24 @@ bucket_definitions:
|
|
|
249
237
|
minBucketChanges: 1,
|
|
250
238
|
minChangeRatio: 0
|
|
251
239
|
});
|
|
252
|
-
const batchAfter = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint,
|
|
240
|
+
const batchAfter = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint, [request]));
|
|
253
241
|
const dataAfter = batchAfter.chunkData.data;
|
|
254
242
|
bucketStorage.clearChecksumCache();
|
|
255
|
-
const checksumAfter = await bucketStorage.getChecksums(checkpoint, [
|
|
256
|
-
expect(batchAfter.targetOp).
|
|
243
|
+
const checksumAfter = await bucketStorage.getChecksums(checkpoint, [request]);
|
|
244
|
+
expect(batchAfter.targetOp).toBeLessThanOrEqual(checkpoint);
|
|
257
245
|
expect(dataAfter).toMatchObject([
|
|
258
246
|
{
|
|
259
|
-
checksum:
|
|
260
|
-
op: 'CLEAR'
|
|
261
|
-
op_id: '3'
|
|
247
|
+
checksum: addChecksums(addChecksums(dataBefore[0].checksum, dataBefore[1].checksum), dataBefore[2].checksum),
|
|
248
|
+
op: 'CLEAR'
|
|
262
249
|
},
|
|
263
250
|
{
|
|
264
|
-
checksum:
|
|
251
|
+
checksum: dataBefore[3].checksum,
|
|
265
252
|
object_id: 't2',
|
|
266
|
-
op: 'PUT'
|
|
267
|
-
op_id: '4'
|
|
253
|
+
op: 'PUT'
|
|
268
254
|
}
|
|
269
255
|
]);
|
|
270
|
-
expect(checksumAfter.get(
|
|
271
|
-
...checksumBefore.get(
|
|
256
|
+
expect(checksumAfter.get(request.bucket)).toEqual({
|
|
257
|
+
...checksumBefore.get(request.bucket),
|
|
272
258
|
count: 2
|
|
273
259
|
});
|
|
274
260
|
test_utils.validateCompactedBucket(dataBefore, dataAfter);
|
|
@@ -287,15 +273,14 @@ bucket_definitions:
|
|
|
287
273
|
const env_3 = { stack: [], error: void 0, hasError: false };
|
|
288
274
|
try {
|
|
289
275
|
const factory = __addDisposableResource(env_3, await generateStorageFactory(), true);
|
|
290
|
-
const syncRules = await factory.updateSyncRules(
|
|
291
|
-
content: `
|
|
276
|
+
const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(`
|
|
292
277
|
bucket_definitions:
|
|
293
278
|
global:
|
|
294
279
|
data: [select * from test]
|
|
295
|
-
`
|
|
296
|
-
});
|
|
280
|
+
`));
|
|
297
281
|
const bucketStorage = factory.getInstance(syncRules);
|
|
298
282
|
const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
283
|
+
await batch.markAllSnapshotDone('1/1');
|
|
299
284
|
await batch.save({
|
|
300
285
|
sourceTable: TEST_TABLE,
|
|
301
286
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -323,7 +308,8 @@ bucket_definitions:
|
|
|
323
308
|
await batch.commit('1/1');
|
|
324
309
|
});
|
|
325
310
|
const checkpoint1 = result.flushed_op;
|
|
326
|
-
const
|
|
311
|
+
const request = bucketRequest(syncRules, 'global[]');
|
|
312
|
+
const checksumBefore = await bucketStorage.getChecksums(checkpoint1, [request]);
|
|
327
313
|
const result2 = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
328
314
|
await batch.save({
|
|
329
315
|
sourceTable: TEST_TABLE,
|
|
@@ -343,22 +329,19 @@ bucket_definitions:
|
|
|
343
329
|
minBucketChanges: 1,
|
|
344
330
|
minChangeRatio: 0
|
|
345
331
|
});
|
|
346
|
-
const batchAfter = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint2,
|
|
332
|
+
const batchAfter = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint2, [request]));
|
|
347
333
|
const dataAfter = batchAfter.chunkData.data;
|
|
348
334
|
await bucketStorage.clearChecksumCache();
|
|
349
|
-
const checksumAfter = await bucketStorage.getChecksums(checkpoint2, [
|
|
350
|
-
expect(batchAfter.targetOp).toEqual(4n);
|
|
335
|
+
const checksumAfter = await bucketStorage.getChecksums(checkpoint2, [request]);
|
|
351
336
|
expect(dataAfter).toMatchObject([
|
|
352
337
|
{
|
|
353
|
-
|
|
354
|
-
op: 'CLEAR',
|
|
355
|
-
op_id: '4'
|
|
338
|
+
op: 'CLEAR'
|
|
356
339
|
}
|
|
357
340
|
]);
|
|
358
|
-
expect(checksumAfter.get(
|
|
359
|
-
bucket:
|
|
341
|
+
expect(checksumAfter.get(request.bucket)).toEqual({
|
|
342
|
+
bucket: request.bucket,
|
|
360
343
|
count: 1,
|
|
361
|
-
checksum:
|
|
344
|
+
checksum: dataAfter[0].checksum
|
|
362
345
|
});
|
|
363
346
|
}
|
|
364
347
|
catch (e_3) {
|
|
@@ -375,18 +358,17 @@ bucket_definitions:
|
|
|
375
358
|
const env_4 = { stack: [], error: void 0, hasError: false };
|
|
376
359
|
try {
|
|
377
360
|
const factory = __addDisposableResource(env_4, await generateStorageFactory(), true);
|
|
378
|
-
const syncRules = await factory.updateSyncRules(
|
|
379
|
-
/* yaml */ content: ` bucket_definitions:
|
|
361
|
+
const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(` bucket_definitions:
|
|
380
362
|
grouped:
|
|
381
363
|
# The parameter query here is not important
|
|
382
364
|
# We specifically don't want to create bucket_parameter records here
|
|
383
365
|
# since the op_ids for bucket_data could vary between storage implementations.
|
|
384
366
|
parameters: select 'b' as b
|
|
385
367
|
data:
|
|
386
|
-
- select * from test where b = bucket.b`
|
|
387
|
-
});
|
|
368
|
+
- select * from test where b = bucket.b`));
|
|
388
369
|
const bucketStorage = factory.getInstance(syncRules);
|
|
389
370
|
const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
371
|
+
await batch.markAllSnapshotDone('1/1');
|
|
390
372
|
/**
|
|
391
373
|
* Repeatedly create operations which fall into different buckets.
|
|
392
374
|
* The bucket operations are purposely interleaved as the op_id increases.
|
|
@@ -456,7 +438,7 @@ bucket_definitions:
|
|
|
456
438
|
minBucketChanges: 1,
|
|
457
439
|
minChangeRatio: 0
|
|
458
440
|
});
|
|
459
|
-
const batchAfter = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint,
|
|
441
|
+
const batchAfter = await test_utils.fromAsync(bucketStorage.getBucketDataBatch(checkpoint, bucketRequestMap(syncRules, [
|
|
460
442
|
['grouped["b1"]', 0n],
|
|
461
443
|
['grouped["b2"]', 0n]
|
|
462
444
|
])));
|
|
@@ -499,15 +481,14 @@ bucket_definitions:
|
|
|
499
481
|
const env_5 = { stack: [], error: void 0, hasError: false };
|
|
500
482
|
try {
|
|
501
483
|
const factory = __addDisposableResource(env_5, await generateStorageFactory(), true);
|
|
502
|
-
const syncRules = await factory.updateSyncRules(
|
|
503
|
-
content: `
|
|
484
|
+
const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(`
|
|
504
485
|
bucket_definitions:
|
|
505
486
|
global:
|
|
506
487
|
data: [select * from test]
|
|
507
|
-
`
|
|
508
|
-
});
|
|
488
|
+
`));
|
|
509
489
|
const bucketStorage = factory.getInstance(syncRules);
|
|
510
|
-
|
|
490
|
+
await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
491
|
+
await batch.markAllSnapshotDone('1/1');
|
|
511
492
|
await batch.save({
|
|
512
493
|
sourceTable: TEST_TABLE,
|
|
513
494
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -553,13 +534,16 @@ bucket_definitions:
|
|
|
553
534
|
await batch.commit('2/1');
|
|
554
535
|
});
|
|
555
536
|
const checkpoint2 = result2.flushed_op;
|
|
537
|
+
const request = bucketRequest(syncRules, 'global[]');
|
|
556
538
|
await bucketStorage.clearChecksumCache();
|
|
557
|
-
const checksumAfter = await bucketStorage.getChecksums(checkpoint2, [
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
539
|
+
const checksumAfter = await bucketStorage.getChecksums(checkpoint2, [request]);
|
|
540
|
+
const globalChecksum = checksumAfter.get(request.bucket);
|
|
541
|
+
expect(globalChecksum).toMatchObject({
|
|
542
|
+
bucket: request.bucket,
|
|
543
|
+
count: 4
|
|
562
544
|
});
|
|
545
|
+
// storage-specific checksum - just check that it does not change
|
|
546
|
+
expect(globalChecksum).toMatchSnapshot();
|
|
563
547
|
}
|
|
564
548
|
catch (e_5) {
|
|
565
549
|
env_5.error = e_5;
|
|
@@ -575,15 +559,14 @@ bucket_definitions:
|
|
|
575
559
|
const env_6 = { stack: [], error: void 0, hasError: false };
|
|
576
560
|
try {
|
|
577
561
|
const factory = __addDisposableResource(env_6, await generateStorageFactory(), true);
|
|
578
|
-
const syncRules = await factory.updateSyncRules(
|
|
579
|
-
content: `
|
|
562
|
+
const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(`
|
|
580
563
|
bucket_definitions:
|
|
581
564
|
global:
|
|
582
565
|
data: [select * from test]
|
|
583
|
-
`
|
|
584
|
-
});
|
|
566
|
+
`));
|
|
585
567
|
const bucketStorage = factory.getInstance(syncRules);
|
|
586
568
|
const result = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
569
|
+
await batch.markAllSnapshotDone('1/1');
|
|
587
570
|
await batch.save({
|
|
588
571
|
sourceTable: TEST_TABLE,
|
|
589
572
|
tag: storage.SaveOperationTag.INSERT,
|
|
@@ -603,7 +586,7 @@ bucket_definitions:
|
|
|
603
586
|
await batch.commit('1/1');
|
|
604
587
|
});
|
|
605
588
|
// Get checksums here just to populate the cache
|
|
606
|
-
await bucketStorage.getChecksums(result.flushed_op, ['global[]']);
|
|
589
|
+
await bucketStorage.getChecksums(result.flushed_op, bucketRequests(syncRules, ['global[]']));
|
|
607
590
|
const result2 = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
608
591
|
await batch.save({
|
|
609
592
|
sourceTable: TEST_TABLE,
|
|
@@ -623,13 +606,16 @@ bucket_definitions:
|
|
|
623
606
|
minChangeRatio: 0
|
|
624
607
|
});
|
|
625
608
|
const checkpoint2 = result2.flushed_op;
|
|
609
|
+
const request = bucketRequest(syncRules, 'global[]');
|
|
626
610
|
// Check that the checksum was correctly updated with the clear operation after having a cached checksum
|
|
627
|
-
const checksumAfter = await bucketStorage.getChecksums(checkpoint2, [
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
611
|
+
const checksumAfter = await bucketStorage.getChecksums(checkpoint2, [request]);
|
|
612
|
+
const globalChecksum = checksumAfter.get(request.bucket);
|
|
613
|
+
expect(globalChecksum).toMatchObject({
|
|
614
|
+
bucket: request.bucket,
|
|
615
|
+
count: 1
|
|
632
616
|
});
|
|
617
|
+
// storage-specific checksum - just check that it does not change
|
|
618
|
+
expect(globalChecksum).toMatchSnapshot();
|
|
633
619
|
}
|
|
634
620
|
catch (e_6) {
|
|
635
621
|
env_6.error = e_6;
|
|
@@ -641,5 +627,62 @@ bucket_definitions:
|
|
|
641
627
|
await result_6;
|
|
642
628
|
}
|
|
643
629
|
});
|
|
630
|
+
test('defaults maxOpId to current checkpoint', async () => {
|
|
631
|
+
const env_7 = { stack: [], error: void 0, hasError: false };
|
|
632
|
+
try {
|
|
633
|
+
const factory = __addDisposableResource(env_7, await generateStorageFactory(), true);
|
|
634
|
+
const syncRules = await factory.updateSyncRules(updateSyncRulesFromYaml(`
|
|
635
|
+
bucket_definitions:
|
|
636
|
+
global:
|
|
637
|
+
data: [select * from test]
|
|
638
|
+
`));
|
|
639
|
+
const bucketStorage = factory.getInstance(syncRules);
|
|
640
|
+
const result1 = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
641
|
+
await batch.markAllSnapshotDone('1/1');
|
|
642
|
+
await batch.save({
|
|
643
|
+
sourceTable: TEST_TABLE,
|
|
644
|
+
tag: storage.SaveOperationTag.INSERT,
|
|
645
|
+
after: { id: 't1' },
|
|
646
|
+
afterReplicaId: test_utils.rid('t1')
|
|
647
|
+
});
|
|
648
|
+
await batch.commit('1/1');
|
|
649
|
+
});
|
|
650
|
+
const checkpoint1 = result1.flushed_op;
|
|
651
|
+
const result2 = await bucketStorage.startBatch(test_utils.BATCH_OPTIONS, async (batch) => {
|
|
652
|
+
// This is flushed but not committed (does not advance the checkpoint)
|
|
653
|
+
await batch.save({
|
|
654
|
+
sourceTable: TEST_TABLE,
|
|
655
|
+
tag: storage.SaveOperationTag.UPDATE,
|
|
656
|
+
after: { id: 't1' },
|
|
657
|
+
afterReplicaId: test_utils.rid('t1')
|
|
658
|
+
});
|
|
659
|
+
});
|
|
660
|
+
const checkpoint2 = result2.flushed_op;
|
|
661
|
+
const checkpointBeforeCompact = await bucketStorage.getCheckpoint();
|
|
662
|
+
expect(checkpointBeforeCompact.checkpoint).toEqual(checkpoint1);
|
|
663
|
+
// With default options, Postgres compaction should use the active checkpoint.
|
|
664
|
+
await bucketStorage.compact({
|
|
665
|
+
moveBatchLimit: 1,
|
|
666
|
+
moveBatchQueryLimit: 1,
|
|
667
|
+
minBucketChanges: 1,
|
|
668
|
+
minChangeRatio: 0
|
|
669
|
+
});
|
|
670
|
+
const batchAfterDefaultCompact = await test_utils.oneFromAsync(bucketStorage.getBucketDataBatch(checkpoint2, bucketRequestMap(syncRules, [['global[]', 0n]])));
|
|
671
|
+
// Operation 1 should remain a PUT because op_id=2 is above the default maxOpId checkpoint.
|
|
672
|
+
expect(batchAfterDefaultCompact.chunkData.data).toMatchObject([
|
|
673
|
+
{ op_id: '1', op: 'PUT', object_id: 't1' },
|
|
674
|
+
{ op_id: '2', op: 'PUT', object_id: 't1' }
|
|
675
|
+
]);
|
|
676
|
+
}
|
|
677
|
+
catch (e_7) {
|
|
678
|
+
env_7.error = e_7;
|
|
679
|
+
env_7.hasError = true;
|
|
680
|
+
}
|
|
681
|
+
finally {
|
|
682
|
+
const result_7 = __disposeResources(env_7);
|
|
683
|
+
if (result_7)
|
|
684
|
+
await result_7;
|
|
685
|
+
}
|
|
686
|
+
});
|
|
644
687
|
}
|
|
645
688
|
//# sourceMappingURL=register-compacting-tests.js.map
|