@agoric/swing-store 0.9.2-dev-bf1e645.0 → 0.9.2-dev-07f6885.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.
@@ -1,12 +1,17 @@
1
1
  // @ts-check
2
+ import test from 'ava';
2
3
 
3
4
  import { Buffer } from 'node:buffer';
4
- import zlib from 'zlib';
5
+ import fs from 'node:fs';
6
+ import path from 'node:path';
7
+ import zlib from 'node:zlib';
5
8
  import sqlite3 from 'better-sqlite3';
9
+ import tmp from 'tmp';
6
10
 
7
- import test from 'ava';
8
11
  import { makeMeasureSeconds } from '@agoric/internal';
9
12
  import { makeSnapStore } from '../src/snapStore.js';
13
+ import { makeArchiveSnapshot } from '../src/archiver.js';
14
+ import { tmpDir } from './util.js';
10
15
 
11
16
  function makeExportLog() {
12
17
  const exportLog = [];
@@ -31,6 +36,10 @@ harden(getSnapshotStream);
31
36
  test('compress to cache file; closes snapshot stream', async t => {
32
37
  const db = sqlite3(':memory:');
33
38
  const exportLog = makeExportLog();
39
+ const [archiveDir, cleanupArchives] = await tmpDir('archives');
40
+ t.teardown(cleanupArchives);
41
+ const fsPowers = { fs, path, tmp };
42
+ const archiveSnapshot = makeArchiveSnapshot(archiveDir, fsPowers);
34
43
  const store = makeSnapStore(
35
44
  db,
36
45
  ensureTxn,
@@ -38,6 +47,7 @@ test('compress to cache file; closes snapshot stream', async t => {
38
47
  measureSeconds: makeMeasureSeconds(() => 0),
39
48
  },
40
49
  exportLog.noteExport,
50
+ { archiveSnapshot },
41
51
  );
42
52
 
43
53
  const snapshotStream = getSnapshotStream('abc');
@@ -50,6 +60,7 @@ test('compress to cache file; closes snapshot stream', async t => {
50
60
  uncompressedSize: 3,
51
61
  compressedSize: 23,
52
62
  dbSaveSeconds: 0,
63
+ archiveWriteSeconds: 0,
53
64
  compressSeconds: 0,
54
65
  });
55
66
  const snapshotInfo = store.getSnapshotInfo('fakeVatID');
@@ -89,6 +100,26 @@ test('compress to cache file; closes snapshot stream', async t => {
89
100
  ['snapshot.fakeVatID.47', JSON.stringify(logInfo)],
90
101
  ['snapshot.fakeVatID.current', `snapshot.fakeVatID.47`],
91
102
  ]);
103
+
104
+ // verify disk archive
105
+ t.deepEqual(
106
+ fs.readdirSync(archiveDir),
107
+ ['snapshot.fakeVatID.47.gz'],
108
+ 'archive must be written to disk',
109
+ );
110
+ const fileContents = fs.readFileSync(
111
+ path.join(archiveDir, 'snapshot.fakeVatID.47.gz'),
112
+ );
113
+ t.is(
114
+ fileContents.length,
115
+ dbInfo.compressedSize,
116
+ 'file size must match database compressedSize',
117
+ );
118
+ t.is(
119
+ zlib.gunzipSync(fileContents).toString(),
120
+ 'abc',
121
+ 'gunzip(fileContents) must match input data',
122
+ );
92
123
  });
93
124
 
94
125
  test('snapStore prepare / commit delete is robust', async t => {
@@ -96,11 +127,17 @@ test('snapStore prepare / commit delete is robust', async t => {
96
127
  measureSeconds: makeMeasureSeconds(() => 0),
97
128
  };
98
129
  const db = sqlite3(':memory:');
130
+ const [archiveDir, cleanupArchives] = await tmpDir('archives');
131
+ t.teardown(cleanupArchives);
132
+ const fsPowers = { fs, path, tmp };
133
+ const archiveSnapshot = makeArchiveSnapshot(archiveDir, fsPowers);
99
134
  const store = makeSnapStore(db, ensureTxn, io, () => {}, {
100
135
  keepSnapshots: true,
136
+ archiveSnapshot,
101
137
  });
102
138
 
103
139
  const hashes = [];
140
+ const expectedFiles = [];
104
141
  for (let i = 0; i < 5; i += 1) {
105
142
  const { hash } = await store.saveSnapshot(
106
143
  'fakeVatID2',
@@ -108,6 +145,7 @@ test('snapStore prepare / commit delete is robust', async t => {
108
145
  getSnapshotStream(`file ${i}`),
109
146
  );
110
147
  hashes.push(hash);
148
+ expectedFiles.push(`snapshot.fakeVatID2.${i}.gz`);
111
149
  }
112
150
  const sqlCountSnapshots = db.prepare(`
113
151
  SELECT COUNT(*)
@@ -116,19 +154,24 @@ test('snapStore prepare / commit delete is robust', async t => {
116
154
  sqlCountSnapshots.pluck(true);
117
155
 
118
156
  t.is(sqlCountSnapshots.get(), 5);
157
+ t.deepEqual(fs.readdirSync(archiveDir), expectedFiles);
119
158
 
120
159
  store.deleteSnapshotByHash('fakeVatID2', hashes[2]);
121
160
  t.is(sqlCountSnapshots.get(), 4);
161
+ t.deepEqual(fs.readdirSync(archiveDir), expectedFiles);
122
162
 
123
163
  // Restore (re-save) between prepare and commit.
124
164
  store.deleteSnapshotByHash('fakeVatID2', hashes[3]);
125
165
  await store.saveSnapshot('fakeVatID3', 29, getSnapshotStream(`file 3`));
166
+ expectedFiles.push(`snapshot.fakeVatID3.29.gz`);
126
167
  t.true(store.hasHash('fakeVatID3', hashes[3]));
168
+ t.deepEqual(fs.readdirSync(archiveDir), expectedFiles);
127
169
 
128
170
  store.deleteVatSnapshots('fakeVatID2');
129
171
  t.is(sqlCountSnapshots.get(), 1);
130
172
  store.deleteVatSnapshots('fakeVatID3');
131
173
  t.is(sqlCountSnapshots.get(), 0);
174
+ t.deepEqual(fs.readdirSync(archiveDir), expectedFiles);
132
175
 
133
176
  for (let i = 0; i < 5; i += 1) {
134
177
  const { hash } = await store.saveSnapshot(
@@ -137,8 +180,10 @@ test('snapStore prepare / commit delete is robust', async t => {
137
180
  getSnapshotStream(`file ${i}`),
138
181
  );
139
182
  hashes.push(hash);
183
+ expectedFiles.push(`snapshot.fakeVatID4.${i}.gz`);
140
184
  }
141
185
  t.is(sqlCountSnapshots.get(), 5);
142
186
  store.deleteAllUnusedSnapshots();
143
187
  t.is(sqlCountSnapshots.get(), 1);
188
+ t.deepEqual(fs.readdirSync(archiveDir), expectedFiles);
144
189
  });
@@ -181,10 +181,10 @@ const testTranscriptStore = test.macro({
181
181
  transcriptStore.initTranscript('st1');
182
182
  transcriptStore.initTranscript('st2');
183
183
  transcriptStore.addItem('st1', 'zeroth');
184
- transcriptStore.rolloverSpan('st1');
184
+ await transcriptStore.rolloverSpan('st1');
185
185
  transcriptStore.addItem('st1', 'first');
186
186
  transcriptStore.addItem('st1', 'second');
187
- transcriptStore.rolloverSpan('st1');
187
+ await transcriptStore.rolloverSpan('st1');
188
188
  transcriptStore.addItem('st1', 'third');
189
189
  transcriptStore.addItem('st2', 'oneth');
190
190
  transcriptStore.addItem('st1', 'fourth');