@agoric/swing-store 0.9.1 → 0.9.2-calypso-dev-84eb287.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.
@@ -0,0 +1,350 @@
1
+ import test from 'ava';
2
+
3
+ import { buffer } from '../src/util.js';
4
+ import { initSwingStore, makeSwingStoreExporter } from '../src/index.js';
5
+
6
+ import { tmpDir, getSnapshotStream, makeB0ID } from './util.js';
7
+
8
+ const rank = {
9
+ operational: 1,
10
+ replay: 2,
11
+ archival: 3,
12
+ debug: 4,
13
+ 'debug-on-pruned': 4,
14
+ };
15
+
16
+ const snapshotData = 'snapshot data';
17
+ // this snapHash was computed manually
18
+ const snapHash =
19
+ 'e7dee7266896538616b630a5da40a90e007726a383e005a9c9c5dd0c2daf9329';
20
+
21
+ /** @type {import('../src/bundleStore.js').Bundle} */
22
+ const bundle0 = { moduleFormat: 'nestedEvaluate', source: '1+1' };
23
+ const bundle0ID = makeB0ID(bundle0);
24
+
25
+ const exportTest = test.macro(async (t, mode) => {
26
+ const [dbDir, cleanup] = await tmpDir('testdb');
27
+ t.teardown(cleanup);
28
+ // const dbDir = 't-db';
29
+
30
+ const options = {};
31
+ if (mode === 'debug') {
32
+ options.keepSnapshots = true; // else old snapshots are deleted
33
+ }
34
+ const ss1 = initSwingStore(dbDir, options);
35
+ const ks = ss1.kernelStorage;
36
+
37
+ ss1.hostStorage.kvStore.set('host.h1', 'hostvalue1');
38
+
39
+ // build a DB with four spans (one in an old incarnation, two
40
+ // historical but current incarnation, only one inUse) and two
41
+ // snapshots (only one inUSe)
42
+
43
+ ks.kvStore.set('key1', 'value1');
44
+ ks.bundleStore.addBundle(bundle0ID, bundle0);
45
+ ks.transcriptStore.initTranscript('v1');
46
+
47
+ // incarnation 0
48
+ ks.transcriptStore.addItem('v1', 'start-worker'); // 0
49
+ ks.transcriptStore.addItem('v1', 'shutdown-worker'); // 1
50
+ ks.transcriptStore.rolloverIncarnation('v1');
51
+ const spanHash0 =
52
+ '5bee0f44eca02f23eab03703e84ed2647d5d117fed99e1c30a3b424b7f082ab9';
53
+
54
+ // incarnation 1
55
+ ks.transcriptStore.addItem('v1', 'start-worker'); // 2
56
+ ks.transcriptStore.addItem('v1', 'delivery1'); // 3
57
+ await ks.snapStore.saveSnapshot('v1', 4, getSnapshotStream(snapshotData));
58
+ ks.transcriptStore.addItem('v1', 'save-snapshot'); // 4
59
+ ks.transcriptStore.rolloverSpan('v1'); // range= 2..5
60
+ const spanHash1 =
61
+ '57152efdd7fdf75c03371d2b4f1088d5bf3eae7fe643babce527ff81df38998c';
62
+
63
+ ks.transcriptStore.addItem('v1', 'load-snapshot'); // 5
64
+ ks.transcriptStore.addItem('v1', 'delivery2'); // 6
65
+ await ks.snapStore.saveSnapshot('v1', 7, getSnapshotStream(snapshotData));
66
+ ks.transcriptStore.addItem('v1', 'save-snapshot'); // 7
67
+ ks.transcriptStore.rolloverSpan('v1'); // range= 5..8
68
+ const spanHash2 =
69
+ '1947001e78e01bd1e773feb22b4ffc530447373b9de9274d5d5fbda3f23dbf2b';
70
+
71
+ ks.transcriptStore.addItem('v1', 'load-snapshot'); // 8
72
+ ks.transcriptStore.addItem('v1', 'delivery3'); // 9
73
+ const spanHash3 =
74
+ 'e6b42c6a3fb94285a93162f25a9fc0145fd4c5bb144917dc572c50ae2d02ee69';
75
+ // current range= 8..10
76
+
77
+ await ss1.hostStorage.commit();
78
+
79
+ // create an export, and assert that the pieces match what we
80
+ // expect. artifactMode='operational' means we get all metadata, no
81
+ // historical transcript spans, and no historical snapshots
82
+
83
+ assert.typeof(mode, 'string');
84
+ /** @import {ArtifactMode} from '../src/internal.js' */
85
+ let artifactMode = /** @type {ArtifactMode} */ (mode);
86
+ if (mode === 'debug-on-pruned') {
87
+ artifactMode = 'debug';
88
+ }
89
+ const exporter = makeSwingStoreExporter(dbDir, { artifactMode });
90
+
91
+ // hostKV
92
+ t.is(exporter.getHostKV('host.h1'), 'hostvalue1');
93
+ t.is(exporter.getHostKV('host.hmissing'), undefined);
94
+ t.throws(() => exporter.getHostKV('nonhost'), {
95
+ message: 'getHostKV requires host keys',
96
+ });
97
+
98
+ // exportData
99
+ {
100
+ const exportData = new Map();
101
+ for await (const [key, value] of exporter.getExportData()) {
102
+ exportData.set(key, value);
103
+ }
104
+ // console.log('exportData:', exportData);
105
+
106
+ const check = (key, expected) => {
107
+ t.true(exportData.has(key));
108
+ let value = exportData.get(key);
109
+ exportData.delete(key);
110
+ if (typeof expected === 'object') {
111
+ value = JSON.parse(value);
112
+ }
113
+ t.deepEqual(value, expected);
114
+ };
115
+
116
+ check('kv.key1', 'value1');
117
+ check('snapshot.v1.4', {
118
+ vatID: 'v1',
119
+ snapPos: 4,
120
+ inUse: 0,
121
+ hash: snapHash,
122
+ });
123
+ check('snapshot.v1.7', {
124
+ vatID: 'v1',
125
+ snapPos: 7,
126
+ inUse: 1,
127
+ hash: snapHash,
128
+ });
129
+ check('snapshot.v1.current', 'snapshot.v1.7');
130
+ const base = { vatID: 'v1', isCurrent: 0 };
131
+ check('transcript.v1.0', {
132
+ ...base,
133
+ incarnation: 0,
134
+ startPos: 0,
135
+ endPos: 2,
136
+ hash: spanHash0,
137
+ });
138
+ check('transcript.v1.2', {
139
+ ...base,
140
+ incarnation: 1,
141
+ startPos: 2,
142
+ endPos: 5,
143
+ hash: spanHash1,
144
+ });
145
+ check('transcript.v1.5', {
146
+ ...base,
147
+ incarnation: 1,
148
+ startPos: 5,
149
+ endPos: 8,
150
+ hash: spanHash2,
151
+ });
152
+ check('transcript.v1.current', {
153
+ ...base,
154
+ incarnation: 1,
155
+ startPos: 8,
156
+ endPos: 10,
157
+ isCurrent: 1,
158
+ hash: spanHash3,
159
+ });
160
+ check(`bundle.${bundle0ID}`, bundle0ID);
161
+
162
+ // the above list is supposed to be exhaustive
163
+ if (exportData.size) {
164
+ console.log('unexpected exportData keys');
165
+ console.log(exportData);
166
+ t.fail('unexpected exportData keys');
167
+ }
168
+ }
169
+
170
+ // artifacts
171
+ {
172
+ const names = new Set();
173
+ const contents = new Map();
174
+ for await (const name of exporter.getArtifactNames()) {
175
+ names.add(name);
176
+ contents.set(name, (await buffer(exporter.getArtifact(name))).toString());
177
+ }
178
+ // console.log('artifacts:', contents);
179
+
180
+ const check = async (name, expected) => {
181
+ t.true(names.has(name));
182
+ names.delete(name);
183
+ let data = contents.get(name);
184
+ if (typeof expected === 'object') {
185
+ data = JSON.parse(data);
186
+ }
187
+ t.deepEqual(data, expected);
188
+ };
189
+
190
+ // export mode 'operational' means we omit historical snapshots and
191
+ // transcript spans
192
+
193
+ await check('snapshot.v1.7', 'snapshot data');
194
+ await check('transcript.v1.8.10', 'load-snapshot\ndelivery3\n');
195
+ await check(`bundle.${bundle0ID}`, bundle0);
196
+
197
+ t.true(rank[mode] > 0);
198
+ if (rank[mode] >= rank.replay) {
199
+ // add the old transcript spans of the current incarnation
200
+ await check(
201
+ 'transcript.v1.2.5',
202
+ 'start-worker\ndelivery1\nsave-snapshot\n',
203
+ );
204
+ await check(
205
+ 'transcript.v1.5.8',
206
+ 'load-snapshot\ndelivery2\nsave-snapshot\n',
207
+ );
208
+ }
209
+
210
+ if (rank[mode] >= rank.archival) {
211
+ // add the spans of the old incarnation
212
+ await check('transcript.v1.0.2', 'start-worker\nshutdown-worker\n');
213
+ }
214
+
215
+ if (mode === 'debug') {
216
+ // adds the old snapshots, which are only present if
217
+ // initSwingStore() was given {keepSnapshots: true}
218
+ await check('snapshot.v1.4', 'snapshot data');
219
+ // mode='debug-on-pruned' exercises the keepSnapshots:false case
220
+ }
221
+
222
+ if (names.size) {
223
+ console.log(`unexpected artifacts:`);
224
+ console.log(names);
225
+ t.fail('unexpected artifacts');
226
+ }
227
+ }
228
+ });
229
+
230
+ test('export operational', exportTest, 'operational');
231
+ test('export replay', exportTest, 'replay');
232
+ test('export archival', exportTest, 'archival');
233
+ test('export debug', exportTest, 'debug');
234
+ test('export debug-on-pruned', exportTest, 'debug-on-pruned');
235
+
236
+ test('export omits pruned span artifacts', async t => {
237
+ const [dbDir, cleanup] = await tmpDir('testdb');
238
+ t.teardown(cleanup);
239
+ // const dbDir = 't-db';
240
+
241
+ // use keepTranscripts=false to simulate an explicit prune of the
242
+ // old span
243
+ const options = { keepTranscripts: false };
244
+ const ss1 = initSwingStore(dbDir, options);
245
+ const ks = ss1.kernelStorage;
246
+
247
+ // build a DB with two spans, one is inUse, other is pruned
248
+
249
+ ks.transcriptStore.initTranscript('v1');
250
+ ks.transcriptStore.addItem('v1', 'start-worker'); // 0
251
+ ks.transcriptStore.addItem('v1', 'delivery1'); // 1
252
+ await ks.snapStore.saveSnapshot('v1', 2, getSnapshotStream(snapshotData));
253
+ ks.transcriptStore.addItem('v1', 'save-snapshot'); // 2
254
+ ks.transcriptStore.rolloverSpan('v1'); // range= 0..3
255
+ const spanHash1 =
256
+ '57152efdd7fdf75c03371d2b4f1088d5bf3eae7fe643babce527ff81df38998c';
257
+ // rolloverSpan prunes the contents of the old span
258
+
259
+ ks.transcriptStore.addItem('v1', 'load-snapshot'); // 3
260
+ ks.transcriptStore.addItem('v1', 'delivery2'); // 4
261
+ const spanHash2 =
262
+ 'b26c8faf425c3c2738e0c5a5e9a7cd71075c68f0c9f2d6cdfd83c68204801dbb';
263
+
264
+ await ss1.hostStorage.commit();
265
+
266
+ const artifactMode = 'debug';
267
+ const exporter = makeSwingStoreExporter(dbDir, { artifactMode });
268
+
269
+ // exportData
270
+ {
271
+ const exportData = new Map();
272
+ for await (const [key, value] of exporter.getExportData()) {
273
+ exportData.set(key, value);
274
+ }
275
+ // console.log('exportData:', exportData);
276
+
277
+ const check = (key, expected) => {
278
+ t.true(exportData.has(key));
279
+ let value = exportData.get(key);
280
+ exportData.delete(key);
281
+ if (typeof expected === 'object') {
282
+ value = JSON.parse(value);
283
+ }
284
+ t.deepEqual(value, expected);
285
+ };
286
+
287
+ check('snapshot.v1.2', {
288
+ vatID: 'v1',
289
+ snapPos: 2,
290
+ inUse: 1,
291
+ hash: snapHash,
292
+ });
293
+ check('snapshot.v1.current', 'snapshot.v1.2');
294
+ const base = { vatID: 'v1', incarnation: 0, isCurrent: 0 };
295
+ check('transcript.v1.0', {
296
+ ...base,
297
+ startPos: 0,
298
+ endPos: 3,
299
+ hash: spanHash1,
300
+ });
301
+ check('transcript.v1.current', {
302
+ ...base,
303
+ startPos: 3,
304
+ endPos: 5,
305
+ isCurrent: 1,
306
+ hash: spanHash2,
307
+ });
308
+
309
+ // the above list is supposed to be exhaustive
310
+ if (exportData.size) {
311
+ console.log('unexpected exportData keys');
312
+ console.log(exportData);
313
+ t.fail('unexpected exportData keys');
314
+ }
315
+ }
316
+
317
+ // artifacts
318
+ {
319
+ const names = new Set();
320
+ const contents = new Map();
321
+ for await (const name of exporter.getArtifactNames()) {
322
+ names.add(name);
323
+ contents.set(name, (await buffer(exporter.getArtifact(name))).toString());
324
+ }
325
+ // console.log('artifacts:', contents);
326
+
327
+ const check = async (name, expected) => {
328
+ t.true(names.has(name));
329
+ names.delete(name);
330
+ let data = contents.get(name);
331
+ if (typeof expected === 'object') {
332
+ data = JSON.parse(data);
333
+ }
334
+ t.deepEqual(data, expected);
335
+ };
336
+
337
+ // export mode 'archival' means we include all available
338
+ // historical snapshots and transcript spans
339
+
340
+ await check('snapshot.v1.2', 'snapshot data');
341
+ // no transcript.v1.0.3 because the contents were pruned
342
+ await check('transcript.v1.3.5', 'load-snapshot\ndelivery2\n');
343
+
344
+ if (names.size) {
345
+ console.log(`unexpected artifacts:`);
346
+ console.log(names);
347
+ t.fail('unexpected artifacts');
348
+ }
349
+ }
350
+ });
@@ -1,19 +1,14 @@
1
1
  // @ts-check
2
2
 
3
- import '@endo/init/debug.js';
4
3
  import { Buffer } from 'node:buffer';
5
4
 
6
- // eslint-disable-next-line import/no-extraneous-dependencies
7
5
  import test from 'ava';
8
- // eslint-disable-next-line import/no-extraneous-dependencies
9
6
  import tmp from 'tmp';
10
7
  import bundleSource from '@endo/bundle-source';
11
8
 
12
- import {
13
- initSwingStore,
14
- makeSwingStoreExporter,
15
- importSwingStore,
16
- } from '../src/swingStore.js';
9
+ import { initSwingStore } from '../src/swingStore.js';
10
+ import { makeSwingStoreExporter } from '../src/exporter.js';
11
+ import { importSwingStore } from '../src/importer.js';
17
12
 
18
13
  function makeExportLog() {
19
14
  const exportLog = [];
@@ -57,7 +52,7 @@ async function embundle(filename) {
57
52
  const bundleFile = new URL(filename, import.meta.url).pathname;
58
53
  const bundle = await bundleSource(bundleFile);
59
54
  const bundleID = `b1-${bundle.endoZipBase64Sha512}`;
60
- return [bundleID, bundle];
55
+ return /** @type {const} */ ([bundleID, bundle]);
61
56
  }
62
57
 
63
58
  function actLikeAVatRunningACrank(vat, ks, crank, doFail) {
@@ -88,6 +83,7 @@ async function fakeAVatSnapshot(vat, ks) {
88
83
  async function* getSnapshotStream() {
89
84
  yield Buffer.from(`snapshot of vat ${vat.vatID} as of ${vat.endPos}`);
90
85
  }
86
+ harden(getSnapshotStream);
91
87
  await ks.snapStore.saveSnapshot(vat.vatID, vat.endPos, getSnapshotStream());
92
88
  ks.transcriptStore.addItem(vat.vatID, 'save-snapshot');
93
89
  vat.endPos += 1;
@@ -124,11 +120,11 @@ test('crank abort leaves no debris in export log', async t => {
124
120
  crankNum % 3 === 0,
125
121
  );
126
122
  }
127
- // eslint-disable-next-line no-await-in-loop
128
123
  await ssOut.hostStorage.commit();
129
124
  }
130
125
 
131
- const exporter = makeSwingStoreExporter(dbDir, 'current');
126
+ const artifactMode = 'operational';
127
+ const exporter = makeSwingStoreExporter(dbDir, { artifactMode });
132
128
 
133
129
  const exportData = [];
134
130
  for await (const elem of exporter.getExportData()) {
@@ -176,14 +172,14 @@ async function testExportImport(
176
172
  runMode,
177
173
  exportMode,
178
174
  importMode,
179
- failureMode,
180
175
  expectedArtifactNames,
176
+ failureMode = 'none',
181
177
  ) {
182
178
  const exportLog = makeExportLog();
183
179
  const [dbDir, cleanup] = await tmpDir('testdb');
184
180
  t.teardown(cleanup);
185
181
 
186
- const keepTranscripts = runMode !== 'current';
182
+ const keepTranscripts = runMode !== 'operational';
187
183
  const keepSnapshots = runMode === 'debug';
188
184
  const ssOut = initSwingStore(dbDir, {
189
185
  exportCallback: exportLog.callback,
@@ -219,14 +215,21 @@ async function testExportImport(
219
215
  actLikeAVatRunningACrank(vat, kernelStorage, crankNum);
220
216
  }
221
217
  if (block < 3) {
222
- // eslint-disable-next-line no-await-in-loop
223
218
  await fakeAVatSnapshot(vats[block % 2], kernelStorage);
224
219
  }
225
- // eslint-disable-next-line no-await-in-loop
226
220
  await ssOut.hostStorage.commit();
227
221
  }
228
222
 
229
- const exporter = makeSwingStoreExporter(dbDir, exportMode);
223
+ // the exporter may be broken (the swingstore may be incomplete), but that is
224
+ // signaled during `getArtifactNames()`, not during construction (which must
225
+ // finish quickly, without scanning the whole DB)
226
+ const exporter = makeSwingStoreExporter(dbDir, { artifactMode: exportMode });
227
+
228
+ const incomplete = 'incomplete archival transcript: 3 vs 12';
229
+ if (failureMode === 'export') {
230
+ await t.throws(() => exporter.getArtifactNames(), { message: incomplete });
231
+ return;
232
+ }
230
233
 
231
234
  const exportData = [];
232
235
  for await (const elem of exporter.getExportData()) {
@@ -300,38 +303,47 @@ async function testExportImport(
300
303
  ],
301
304
  ]);
302
305
 
303
- expectedArtifactNames = Array.from(expectedArtifactNames);
304
- expectedArtifactNames.push(`bundle.${bundleIDA}`);
305
- expectedArtifactNames.push(`bundle.${bundleIDB}`);
306
+ expectedArtifactNames = new Set(expectedArtifactNames);
307
+ expectedArtifactNames.add(`bundle.${bundleIDA}`);
308
+ expectedArtifactNames.add(`bundle.${bundleIDB}`);
306
309
 
307
- const artifactNames = [];
310
+ const artifactNames = new Set();
308
311
  for await (const name of exporter.getArtifactNames()) {
309
- artifactNames.push(name);
312
+ artifactNames.add(name);
310
313
  }
311
314
  t.deepEqual(artifactNames, expectedArtifactNames);
312
315
 
313
- const includeHistorical = importMode !== 'current';
314
-
315
316
  const beforeDump = debug.dump(keepSnapshots);
316
- let ssIn;
317
- try {
318
- ssIn = await importSwingStore(exporter, null, {
319
- includeHistorical,
320
- });
321
- } catch (e) {
322
- if (failureMode === 'transcript') {
323
- t.is(e.message, 'artifact "transcript.vatA.0.3" is not available');
324
- return;
325
- } else if (failureMode === 'snapshot') {
326
- t.is(e.message, 'artifact "snapshot.vatA.2" is not available');
327
- return;
328
- }
329
- throw e;
317
+ function doImport() {
318
+ return importSwingStore(exporter, null, { artifactMode: importMode });
319
+ }
320
+
321
+ if (failureMode === 'import') {
322
+ await t.throwsAsync(doImport, { message: incomplete });
323
+ return;
330
324
  }
331
325
  t.is(failureMode, 'none');
326
+ const ssIn = await doImport();
327
+ t.teardown(ssIn.hostStorage.close);
332
328
  await ssIn.hostStorage.commit();
333
- const dumpsShouldMatch =
334
- runMode !== 'debug' || (exportMode === 'debug' && importMode !== 'current');
329
+ let dumpsShouldMatch = true;
330
+ if (runMode === 'operational') {
331
+ dumpsShouldMatch = true; // there's no data to lose
332
+ } else if (runMode === 'archival') {
333
+ if (exportMode === 'current') {
334
+ dumpsShouldMatch = false; // export omits some data
335
+ }
336
+ if (importMode === 'current') {
337
+ dumpsShouldMatch = false; // import ignores some data
338
+ }
339
+ } else if (runMode === 'debug') {
340
+ if (exportMode !== 'debug') {
341
+ dumpsShouldMatch = false; // export omits some data
342
+ }
343
+ if (importMode !== 'debug') {
344
+ dumpsShouldMatch = false; // import ignores some data
345
+ }
346
+ }
335
347
  if (dumpsShouldMatch) {
336
348
  const afterDump = ssIn.debug.dump(keepSnapshots);
337
349
  t.deepEqual(beforeDump, afterDump);
@@ -366,100 +378,108 @@ const expectedDebugArtifacts = [
366
378
  'transcript.vatB.5.10',
367
379
  ];
368
380
 
369
- const C = 'current';
381
+ const C = 'operational'; // nee 'current'
382
+ // we don't try to test 'replay' here: see test-import.js and test-export.js
370
383
  const A = 'archival';
371
384
  const D = 'debug';
372
385
 
386
+ // importMode='archival' requires a non-pruned DB
387
+ // (runMode!=='current'), with exportMode as 'archival' or 'debug'
388
+
389
+ // the expected artifacts are a function of the runMode and exportMode, not importMode
390
+
373
391
  test('export and import data for state sync - current->current->current', async t => {
374
- await testExportImport(t, C, C, C, 'none', expectedCurrentArtifacts);
392
+ await testExportImport(t, C, C, C, expectedCurrentArtifacts);
375
393
  });
394
+ // so this one fails during import
376
395
  test('export and import data for state sync - current->current->archival', async t => {
377
- await testExportImport(t, C, C, A, 'none', expectedCurrentArtifacts);
396
+ await testExportImport(t, C, C, A, expectedCurrentArtifacts, 'import');
378
397
  });
379
398
  test('export and import data for state sync - current->current->debug', async t => {
380
- await testExportImport(t, C, C, D, 'none', expectedCurrentArtifacts);
399
+ await testExportImport(t, C, C, D, expectedCurrentArtifacts);
381
400
  });
382
401
 
402
+ // these all throw an error during export, because 'archival' requires a non-pruned DB
383
403
  test('export and import data for state sync - current->archival->current', async t => {
384
- await testExportImport(t, C, A, C, 'none', expectedArchivalArtifacts);
404
+ await testExportImport(t, C, A, C, [], 'export');
385
405
  });
386
406
  test('export and import data for state sync - current->archival->archival', async t => {
387
- await testExportImport(t, C, A, A, 'transcript', expectedArchivalArtifacts);
407
+ await testExportImport(t, C, A, A, [], 'export');
388
408
  });
389
409
  test('export and import data for state sync - current->archival->debug', async t => {
390
- await testExportImport(t, C, A, D, 'transcript', expectedArchivalArtifacts);
410
+ await testExportImport(t, C, A, D, [], 'export');
391
411
  });
392
412
 
393
413
  test('export and import data for state sync - current->debug->current', async t => {
394
- await testExportImport(t, C, D, C, 'none', expectedDebugArtifacts);
414
+ await testExportImport(t, C, D, C, expectedCurrentArtifacts);
395
415
  });
396
416
  test('export and import data for state sync - current->debug->archival', async t => {
397
- await testExportImport(t, C, D, A, 'snapshot', expectedDebugArtifacts);
417
+ await testExportImport(t, C, D, A, expectedCurrentArtifacts, 'import');
398
418
  });
399
419
  test('export and import data for state sync - current->debug->debug', async t => {
400
- await testExportImport(t, C, D, D, 'snapshot', expectedDebugArtifacts);
420
+ await testExportImport(t, C, D, D, expectedCurrentArtifacts);
401
421
  });
402
422
 
403
423
  // ------------------------------------------------------------
404
424
 
405
425
  test('export and import data for state sync - archival->current->current', async t => {
406
- await testExportImport(t, A, C, C, 'none', expectedCurrentArtifacts);
426
+ await testExportImport(t, A, C, C, expectedCurrentArtifacts);
407
427
  });
408
428
  test('export and import data for state sync - archival->current->archival', async t => {
409
- await testExportImport(t, A, C, A, 'none', expectedCurrentArtifacts);
429
+ await testExportImport(t, A, C, A, expectedCurrentArtifacts, 'import');
410
430
  });
411
431
  test('export and import data for state sync - archival->current->debug', async t => {
412
- await testExportImport(t, A, C, D, 'none', expectedCurrentArtifacts);
432
+ await testExportImport(t, A, C, D, expectedCurrentArtifacts);
413
433
  });
414
434
 
415
435
  test('export and import data for state sync - archival->archival->current', async t => {
416
- await testExportImport(t, A, A, C, 'none', expectedArchivalArtifacts);
436
+ await testExportImport(t, A, A, C, expectedArchivalArtifacts);
417
437
  });
418
438
  test('export and import data for state sync - archival->archival->archival', async t => {
419
- await testExportImport(t, A, A, A, 'none', expectedArchivalArtifacts);
439
+ await testExportImport(t, A, A, A, expectedArchivalArtifacts);
420
440
  });
421
441
  test('export and import data for state sync - archival->archival->debug', async t => {
422
- await testExportImport(t, A, A, D, 'none', expectedArchivalArtifacts);
442
+ await testExportImport(t, A, A, D, expectedArchivalArtifacts);
423
443
  });
424
444
 
425
445
  test('export and import data for state sync - archival->debug->current', async t => {
426
- await testExportImport(t, A, D, C, 'none', expectedDebugArtifacts);
446
+ await testExportImport(t, A, D, C, expectedArchivalArtifacts);
427
447
  });
428
448
  test('export and import data for state sync - archival->debug->archival', async t => {
429
- await testExportImport(t, A, D, A, 'snapshot', expectedDebugArtifacts);
449
+ await testExportImport(t, A, D, A, expectedArchivalArtifacts);
430
450
  });
431
451
  test('export and import data for state sync - archival->debug->debug', async t => {
432
- await testExportImport(t, A, D, D, 'snapshot', expectedDebugArtifacts);
452
+ await testExportImport(t, A, D, D, expectedArchivalArtifacts);
433
453
  });
434
454
 
435
455
  // ------------------------------------------------------------
436
456
 
437
457
  test('export and import data for state sync - debug->current->current', async t => {
438
- await testExportImport(t, D, C, C, 'none', expectedCurrentArtifacts);
458
+ await testExportImport(t, D, C, C, expectedCurrentArtifacts);
439
459
  });
440
460
  test('export and import data for state sync - debug->current->archival', async t => {
441
- await testExportImport(t, D, C, A, 'none', expectedCurrentArtifacts);
461
+ await testExportImport(t, D, C, A, expectedCurrentArtifacts, 'import');
442
462
  });
443
463
  test('export and import data for state sync - debug->current->debug', async t => {
444
- await testExportImport(t, D, C, D, 'none', expectedCurrentArtifacts);
464
+ await testExportImport(t, D, C, D, expectedCurrentArtifacts);
445
465
  });
446
466
 
447
467
  test('export and import data for state sync - debug->archival->current', async t => {
448
- await testExportImport(t, D, A, C, 'none', expectedArchivalArtifacts);
468
+ await testExportImport(t, D, A, C, expectedArchivalArtifacts);
449
469
  });
450
470
  test('export and import data for state sync - debug->archival->archival', async t => {
451
- await testExportImport(t, D, A, A, 'none', expectedArchivalArtifacts);
471
+ await testExportImport(t, D, A, A, expectedArchivalArtifacts);
452
472
  });
453
473
  test('export and import data for state sync - debug->archival->debug', async t => {
454
- await testExportImport(t, D, A, D, 'none', expectedArchivalArtifacts);
474
+ await testExportImport(t, D, A, D, expectedArchivalArtifacts);
455
475
  });
456
476
 
457
477
  test('export and import data for state sync - debug->debug->current', async t => {
458
- await testExportImport(t, D, D, C, 'none', expectedDebugArtifacts);
478
+ await testExportImport(t, D, D, C, expectedDebugArtifacts);
459
479
  });
460
480
  test('export and import data for state sync - debug->debug->archival', async t => {
461
- await testExportImport(t, D, D, A, 'none', expectedDebugArtifacts);
481
+ await testExportImport(t, D, D, A, expectedDebugArtifacts);
462
482
  });
463
483
  test('export and import data for state sync - debug->debug->debug', async t => {
464
- await testExportImport(t, D, D, D, 'none', expectedDebugArtifacts);
484
+ await testExportImport(t, D, D, D, expectedDebugArtifacts);
465
485
  });