@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.
- package/docs/transcriptstore.md +3 -3
- package/package.json +3 -3
- package/src/archiver.js +80 -0
- package/src/index.js +2 -0
- package/src/snapStore.js +55 -67
- package/src/swingStore.js +9 -1
- package/src/transcriptStore.js +167 -145
- package/test/deletion.test.js +182 -131
- package/test/export.test.js +4 -4
- package/test/exportImport.test.js +1 -1
- package/test/snapstore.test.js +47 -2
- package/test/state.test.js +2 -2
package/test/snapstore.test.js
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
+
import test from 'ava';
|
|
2
3
|
|
|
3
4
|
import { Buffer } from 'node:buffer';
|
|
4
|
-
import
|
|
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
|
});
|
package/test/state.test.js
CHANGED
|
@@ -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');
|