@agoric/swingset-liveslots 0.10.3-mainnet1B-dev-26244e8.0 → 0.10.3-orchestration-dev-096c4e8.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/README.md +2 -0
- package/package.json +25 -17
- package/src/cache.js +5 -3
- package/src/collectionManager.js +147 -69
- package/src/index.js +2 -1
- package/src/liveslots.js +52 -79
- package/src/message.js +4 -4
- package/src/types.js +8 -2
- package/src/vatDataTypes.d.ts +234 -0
- package/src/vatDataTypes.js +2 -0
- package/src/vatstore-iterators.js +2 -0
- package/src/virtualObjectManager.js +107 -63
- package/src/virtualReferences.js +51 -0
- package/src/watchedPromises.js +50 -15
- package/test/gc-and-finalize.js +30 -1
- package/test/gc-helpers.js +2 -1
- package/test/liveslots-helpers.js +6 -6
- package/test/mock-gc.js +1 -0
- package/test/storeGC/test-lifecycle.js +2 -2
- package/test/storeGC/test-refcount-management.js +1 -2
- package/test/storeGC/test-scalar-store-kind.js +0 -1
- package/test/storeGC/test-weak-key.js +1 -2
- package/test/test-baggage.js +1 -2
- package/test/test-cache.js +0 -1
- package/test/test-collection-schema-refcount.js +1 -2
- package/test/test-collection-upgrade.js +1 -3
- package/test/test-collections.js +117 -14
- package/test/test-dropped-collection-weakrefs.js +1 -2
- package/test/test-durabilityChecks.js +3 -3
- package/test/test-facetiousness.js +1 -2
- package/test/test-gc-sensitivity.js +2 -2
- package/test/test-handled-promises.js +5 -7
- package/test/test-initial-vrefs.js +2 -3
- package/test/test-liveslots-mock-gc.js +2 -2
- package/test/test-liveslots-real-gc.js +44 -35
- package/test/test-liveslots.js +13 -14
- package/test/test-vo-test-harness.js +0 -1
- package/test/test-vpid-liveslots.js +4 -5
- package/test/util.js +2 -2
- package/test/vat-util.js +1 -1
- package/test/virtual-objects/test-cease-recognition.js +2 -2
- package/test/virtual-objects/test-cross-facet.js +1 -2
- package/test/virtual-objects/test-empty-data.js +1 -2
- package/test/virtual-objects/test-facets.js +1 -2
- package/test/virtual-objects/test-kind-changes.js +2 -2
- package/test/virtual-objects/test-reachable-vrefs.js +2 -2
- package/test/virtual-objects/test-rep-tostring.js +2 -3
- package/test/virtual-objects/test-retain-remotable.js +25 -24
- package/test/virtual-objects/test-state-shape.js +2 -2
- package/test/virtual-objects/test-virtualObjectGC.js +2 -2
- package/test/virtual-objects/test-virtualObjectManager.js +126 -8
- package/test/virtual-objects/test-vo-real-gc.js +8 -8
- package/test/virtual-objects/test-weakcollections-vref-handling.js +1 -2
- package/tools/fakeVirtualSupport.js +48 -21
- package/tools/prepare-test-env.js +13 -0
- package/tools/setup-vat-data.js +62 -0
- package/CHANGELOG.md +0 -77
- package/test/kmarshal.js +0 -79
package/test/test-baggage.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
|
-
import '@endo/init/debug.js';
|
|
3
2
|
|
|
4
3
|
import { Far } from '@endo/marshal';
|
|
4
|
+
import { kunser } from '@agoric/kmarshal';
|
|
5
5
|
import { setupTestLiveslots } from './liveslots-helpers.js';
|
|
6
6
|
import { vstr } from './util.js';
|
|
7
|
-
import { kunser } from './kmarshal.js';
|
|
8
7
|
import { parseVatSlot } from '../src/parseVatSlots.js';
|
|
9
8
|
|
|
10
9
|
function buildRootObject(vatPowers, vatParameters, baggage) {
|
package/test/test-cache.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
|
-
import '@endo/init/debug.js';
|
|
3
2
|
|
|
4
3
|
import { Far } from '@endo/marshal';
|
|
4
|
+
import { kser } from '@agoric/kmarshal';
|
|
5
5
|
import { makeLiveSlots } from '../src/liveslots.js';
|
|
6
6
|
import { parseVatSlot } from '../src/parseVatSlots.js';
|
|
7
|
-
import { kser } from './kmarshal.js';
|
|
8
7
|
import { buildSyscall } from './liveslots-helpers.js';
|
|
9
8
|
import { makeStartVat, makeBringOutYourDead } from './util.js';
|
|
10
9
|
import { makeMockGC } from './mock-gc.js';
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
/* eslint-disable no-await-in-loop, @jessie.js/no-nested-await, no-shadow */
|
|
2
1
|
import test from 'ava';
|
|
3
|
-
import '@endo/init/debug.js';
|
|
4
2
|
|
|
5
3
|
import { Far } from '@endo/marshal';
|
|
4
|
+
import { kser } from '@agoric/kmarshal';
|
|
6
5
|
import { M } from '@agoric/store';
|
|
7
6
|
import { makeLiveSlots } from '../src/liveslots.js';
|
|
8
7
|
import { parseVatSlot } from '../src/parseVatSlots.js';
|
|
9
|
-
import { kser } from './kmarshal.js';
|
|
10
8
|
import { buildSyscall } from './liveslots-helpers.js';
|
|
11
9
|
import { makeStartVat } from './util.js';
|
|
12
10
|
import { makeMockGC } from './mock-gc.js';
|
package/test/test-collections.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
1
2
|
import test from 'ava';
|
|
2
|
-
import '@endo/init/debug.js';
|
|
3
3
|
|
|
4
4
|
import { Far } from '@endo/marshal';
|
|
5
5
|
import { M } from '@agoric/store';
|
|
6
|
+
import { makeCopyMap, makeCopySet } from '@endo/patterns';
|
|
6
7
|
import { makeFakeCollectionManager } from '../tools/fakeVirtualSupport.js';
|
|
7
8
|
|
|
8
9
|
const {
|
|
@@ -100,6 +101,12 @@ function exerciseMapOperations(t, collectionName, testStore) {
|
|
|
100
101
|
() => testStore.set(86, 'not work'),
|
|
101
102
|
m(`key 86 not found in collection "${collectionName}"`),
|
|
102
103
|
);
|
|
104
|
+
t.throws(
|
|
105
|
+
() => testStore.set(somethingMissing, 'not work'),
|
|
106
|
+
m(
|
|
107
|
+
`key "[Alleged: something missing]" not found in collection "${collectionName}"`,
|
|
108
|
+
),
|
|
109
|
+
);
|
|
103
110
|
t.throws(
|
|
104
111
|
() => testStore.init(47, 'already there'),
|
|
105
112
|
m(`key 47 already registered in collection "${collectionName}"`),
|
|
@@ -117,11 +124,17 @@ function exerciseMapOperations(t, collectionName, testStore) {
|
|
|
117
124
|
t.is(testStore.get(somethingElse), something);
|
|
118
125
|
|
|
119
126
|
testStore.delete(47);
|
|
127
|
+
testStore.delete(something);
|
|
120
128
|
t.falsy(testStore.has(47));
|
|
129
|
+
t.falsy(testStore.has(something));
|
|
121
130
|
t.throws(
|
|
122
131
|
() => testStore.get(47),
|
|
123
132
|
m(`key 47 not found in collection "${collectionName}"`),
|
|
124
133
|
);
|
|
134
|
+
t.throws(
|
|
135
|
+
() => testStore.get(something),
|
|
136
|
+
m(`key "[Alleged: something]" not found in collection "${collectionName}"`),
|
|
137
|
+
);
|
|
125
138
|
t.throws(
|
|
126
139
|
() => testStore.delete(22),
|
|
127
140
|
m(`key 22 not found in collection "${collectionName}"`),
|
|
@@ -146,7 +159,9 @@ function exerciseSetOperations(t, collectionName, testStore) {
|
|
|
146
159
|
t.notThrows(() => testStore.add(47));
|
|
147
160
|
|
|
148
161
|
testStore.delete(47);
|
|
162
|
+
testStore.delete(something);
|
|
149
163
|
t.falsy(testStore.has(47));
|
|
164
|
+
t.falsy(testStore.has(something));
|
|
150
165
|
t.throws(
|
|
151
166
|
() => testStore.delete(22),
|
|
152
167
|
m(`key 22 not found in collection "${collectionName}"`),
|
|
@@ -191,6 +206,89 @@ test('basic weak set operations', t => {
|
|
|
191
206
|
);
|
|
192
207
|
});
|
|
193
208
|
|
|
209
|
+
function exerciseSetAddAll(t, weak, testStore) {
|
|
210
|
+
const allThatStuff = stuff.map(entry => entry[0]);
|
|
211
|
+
|
|
212
|
+
testStore.addAll(allThatStuff);
|
|
213
|
+
for (const elem of allThatStuff) {
|
|
214
|
+
t.truthy(testStore.has(elem));
|
|
215
|
+
testStore.delete(elem);
|
|
216
|
+
}
|
|
217
|
+
if (!weak) {
|
|
218
|
+
t.is(testStore.getSize(), 0);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
testStore.addAll(makeCopySet(allThatStuff));
|
|
222
|
+
for (const elem of allThatStuff) {
|
|
223
|
+
t.truthy(testStore.has(elem));
|
|
224
|
+
testStore.delete(elem);
|
|
225
|
+
}
|
|
226
|
+
if (!weak) {
|
|
227
|
+
t.is(testStore.getSize(), 0);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
t.throws(
|
|
231
|
+
() => testStore.addAll({ bogus: 47 }),
|
|
232
|
+
m(/provided data source is not iterable/),
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
test('set addAll', t => {
|
|
237
|
+
exerciseSetAddAll(t, false, makeScalarBigSetStore('test set'));
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
test('weak set addAll', t => {
|
|
241
|
+
exerciseSetAddAll(t, true, makeScalarBigWeakSetStore('test weak set'));
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
test('set snapshot', t => {
|
|
245
|
+
const testStore = makeScalarBigSetStore('test set');
|
|
246
|
+
const allThatStuff = stuff.map(entry => entry[0]);
|
|
247
|
+
testStore.addAll(allThatStuff);
|
|
248
|
+
t.deepEqual(testStore.snapshot(), makeCopySet(allThatStuff));
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
function exerciseMapAddAll(t, weak, testStore) {
|
|
252
|
+
testStore.addAll(stuff);
|
|
253
|
+
for (const [k, v] of stuff) {
|
|
254
|
+
t.truthy(testStore.has(k));
|
|
255
|
+
t.is(testStore.get(k), v);
|
|
256
|
+
testStore.delete(k);
|
|
257
|
+
}
|
|
258
|
+
if (!weak) {
|
|
259
|
+
t.is(testStore.getSize(), 0);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
testStore.addAll(makeCopyMap(stuff));
|
|
263
|
+
for (const [k, v] of stuff) {
|
|
264
|
+
t.truthy(testStore.has(k));
|
|
265
|
+
t.is(testStore.get(k), v);
|
|
266
|
+
testStore.delete(k);
|
|
267
|
+
}
|
|
268
|
+
if (!weak) {
|
|
269
|
+
t.is(testStore.getSize(), 0);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
t.throws(
|
|
273
|
+
() => testStore.addAll({ bogus: 47 }),
|
|
274
|
+
m(/provided data source is not iterable/),
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
test('map addAll', t => {
|
|
279
|
+
exerciseMapAddAll(t, false, makeScalarBigMapStore('test map'));
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
test('weak map addAll', t => {
|
|
283
|
+
exerciseMapAddAll(t, true, makeScalarBigWeakMapStore('test weak map'));
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
test('map snapshot', t => {
|
|
287
|
+
const testStore = makeScalarBigMapStore('test map');
|
|
288
|
+
testStore.addAll(stuff);
|
|
289
|
+
t.deepEqual(testStore.snapshot(), makeCopyMap(stuff));
|
|
290
|
+
});
|
|
291
|
+
|
|
194
292
|
test('constrain map key shape', t => {
|
|
195
293
|
const stringsOnly = makeScalarBigMapStore('map key strings only', {
|
|
196
294
|
keyShape: M.string(),
|
|
@@ -405,7 +503,9 @@ test('map fail on concurrent modification', t => {
|
|
|
405
503
|
const primeMap = makeScalarBigMapStore('fmap', {
|
|
406
504
|
keyShape: M.number(),
|
|
407
505
|
});
|
|
408
|
-
|
|
506
|
+
for (const [i, v] of primes.entries()) {
|
|
507
|
+
primeMap.init(v, `${v} is prime #${i + 1}`);
|
|
508
|
+
}
|
|
409
509
|
|
|
410
510
|
let iter = primeMap.keys()[Symbol.iterator]();
|
|
411
511
|
t.deepEqual(iter.next(), { done: false, value: 2 });
|
|
@@ -433,7 +533,9 @@ test('set fail on concurrent modification', t => {
|
|
|
433
533
|
const primeSet = makeScalarBigSetStore('fset', {
|
|
434
534
|
keyShape: M.number(),
|
|
435
535
|
});
|
|
436
|
-
|
|
536
|
+
for (const v of primes) {
|
|
537
|
+
primeSet.add(v);
|
|
538
|
+
}
|
|
437
539
|
|
|
438
540
|
let iter = primeSet.keys()[Symbol.iterator]();
|
|
439
541
|
t.deepEqual(iter.next(), { done: false, value: 2 });
|
|
@@ -461,7 +563,9 @@ test('map ok with concurrent deletion', t => {
|
|
|
461
563
|
const primeMap = makeScalarBigMapStore('fmap', {
|
|
462
564
|
keyShape: M.number(),
|
|
463
565
|
});
|
|
464
|
-
|
|
566
|
+
for (const [i, v] of primes.entries()) {
|
|
567
|
+
primeMap.init(v, `${v} is prime #${i + 1}`);
|
|
568
|
+
}
|
|
465
569
|
const iter = primeMap.keys()[Symbol.iterator]();
|
|
466
570
|
t.deepEqual(iter.next(), { done: false, value: 2 });
|
|
467
571
|
primeMap.delete(3);
|
|
@@ -476,7 +580,9 @@ test('set ok with concurrent deletion', t => {
|
|
|
476
580
|
const primeSet = makeScalarBigSetStore('fset', {
|
|
477
581
|
keyShape: M.number(),
|
|
478
582
|
});
|
|
479
|
-
|
|
583
|
+
for (const v of primes) {
|
|
584
|
+
primeSet.add(v);
|
|
585
|
+
}
|
|
480
586
|
|
|
481
587
|
const iter = primeSet.keys()[Symbol.iterator]();
|
|
482
588
|
t.deepEqual(iter.next(), { done: false, value: 2 });
|
|
@@ -766,13 +872,6 @@ test('set queries', t => {
|
|
|
766
872
|
symbolKrusty,
|
|
767
873
|
undefined,
|
|
768
874
|
]);
|
|
769
|
-
|
|
770
|
-
// @ts-expect-error our BigSetStore has .entries, but not the SetStore type
|
|
771
|
-
t.deepEqual(Array.from(testStore.entries(M.number())), [
|
|
772
|
-
[-29, -29],
|
|
773
|
-
[3, 3],
|
|
774
|
-
[47, 47],
|
|
775
|
-
]);
|
|
776
875
|
});
|
|
777
876
|
|
|
778
877
|
test('remotable sort order', t => {
|
|
@@ -798,7 +897,9 @@ test('complex map queries', t => {
|
|
|
798
897
|
const primeStore = makeScalarBigMapStore('prime map', {
|
|
799
898
|
keyShape: M.number(),
|
|
800
899
|
});
|
|
801
|
-
|
|
900
|
+
for (const [i, v] of primes.entries()) {
|
|
901
|
+
primeStore.init(v, `${v} is prime #${i + 1}`);
|
|
902
|
+
}
|
|
802
903
|
|
|
803
904
|
t.deepEqual(Array.from(primeStore.values()), [
|
|
804
905
|
'2 is prime #1',
|
|
@@ -973,7 +1074,9 @@ test('complex set queries', t => {
|
|
|
973
1074
|
const primeStore = makeScalarBigSetStore('prime set', {
|
|
974
1075
|
keyShape: M.number(),
|
|
975
1076
|
});
|
|
976
|
-
|
|
1077
|
+
for (const v of primes) {
|
|
1078
|
+
primeStore.add(v);
|
|
1079
|
+
}
|
|
977
1080
|
|
|
978
1081
|
t.deepEqual(
|
|
979
1082
|
Array.from(primeStore.values()),
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
|
-
import '@endo/init/debug.js';
|
|
3
2
|
import { Far } from '@endo/marshal';
|
|
3
|
+
import { kser } from '@agoric/kmarshal';
|
|
4
4
|
import { makeLiveSlots } from '../src/liveslots.js';
|
|
5
|
-
import { kser } from './kmarshal.js';
|
|
6
5
|
import { buildSyscall } from './liveslots-helpers.js';
|
|
7
6
|
import { makeStartVat } from './util.js';
|
|
8
7
|
import { makeMockGC } from './mock-gc.js';
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
|
-
import '@endo/init/debug.js';
|
|
3
2
|
|
|
4
3
|
import { Far } from '@endo/marshal';
|
|
5
4
|
import { makeFakeVirtualStuff } from '../tools/fakeVirtualSupport.js';
|
|
@@ -16,6 +15,7 @@ async function runDurabilityCheckTest(t, relaxDurabilityRules) {
|
|
|
16
15
|
|
|
17
16
|
const durableHolderKind = makeKindHandle('holder');
|
|
18
17
|
|
|
18
|
+
/** @param {any} held */
|
|
19
19
|
const initHolder = (held = null) => ({ held });
|
|
20
20
|
const holderBehavior = {
|
|
21
21
|
hold: ({ state }, value) => {
|
|
@@ -269,5 +269,5 @@ async function runDurabilityCheckTest(t, relaxDurabilityRules) {
|
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
-
test('durability checks (strict)',
|
|
273
|
-
test('durability checks (relaxed)',
|
|
272
|
+
test('durability checks (strict)', runDurabilityCheckTest, false);
|
|
273
|
+
test('durability checks (relaxed)', runDurabilityCheckTest, true);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import '@endo/init/debug.js';
|
|
2
1
|
import test from 'ava';
|
|
3
2
|
import {
|
|
4
3
|
assessFacetiousness,
|
|
@@ -126,7 +125,7 @@ test('checkAndUpdateFacetiousness', t => {
|
|
|
126
125
|
t.deepEqual(cauf({}, barfoo), barfoo);
|
|
127
126
|
|
|
128
127
|
// a single Kind can only be redefined as another single
|
|
129
|
-
t.
|
|
128
|
+
t.is(cauf(desc(), undefined), undefined);
|
|
130
129
|
t.throws(() => cauf(desc(), foo), {
|
|
131
130
|
message: 'defineDurableKindMulti called for unfaceted KindHandle "tag"',
|
|
132
131
|
});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
1
2
|
import test from 'ava';
|
|
2
|
-
import '@endo/init/debug.js';
|
|
3
3
|
import { Far } from '@endo/marshal';
|
|
4
|
+
import { kser } from '@agoric/kmarshal';
|
|
4
5
|
import { buildSyscall } from './liveslots-helpers.js';
|
|
5
6
|
import { makeLiveSlots } from '../src/liveslots.js';
|
|
6
|
-
import { kser } from './kmarshal.js';
|
|
7
7
|
import { makeMockGC } from './mock-gc.js';
|
|
8
8
|
import { makeMessage, makeStartVat } from './util.js';
|
|
9
9
|
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
/* eslint-disable no-await-in-loop, @jessie.js/no-nested-await, no-shadow */
|
|
2
1
|
import test from 'ava';
|
|
3
|
-
import '@endo/init/debug.js';
|
|
4
2
|
|
|
5
3
|
import { Far } from '@endo/marshal';
|
|
6
4
|
import { Fail } from '@agoric/assert';
|
|
@@ -9,7 +7,7 @@ import { makePromiseKit } from '@endo/promise-kit';
|
|
|
9
7
|
// Disabled to avoid circular dependencies.
|
|
10
8
|
// import { makeStoreUtils } from '@agoric/vat-data/src/vat-data-bindings.js';
|
|
11
9
|
// import { makeExoUtils } from '@agoric/vat-data/src/exo-utils.js';
|
|
12
|
-
import { kslot, kser } from '
|
|
10
|
+
import { kslot, kser } from '@agoric/kmarshal';
|
|
13
11
|
import { setupTestLiveslots } from './liveslots-helpers.js';
|
|
14
12
|
import { makeResolve, makeReject } from './util.js';
|
|
15
13
|
|
|
@@ -233,12 +231,12 @@ test('past-incarnation watched promises', async t => {
|
|
|
233
231
|
t.deepEqual(getDispatchLogs(), [
|
|
234
232
|
fulfillmentMessage(`p-${nextPImport()}`, 'created local promise: rejected'),
|
|
235
233
|
]);
|
|
236
|
-
t.
|
|
234
|
+
t.is(
|
|
237
235
|
lastPImport - firstPImport + 1,
|
|
238
236
|
4,
|
|
239
237
|
'imported 4 promises (1 per dispatch)',
|
|
240
238
|
);
|
|
241
|
-
t.
|
|
239
|
+
t.is(lastPExport - firstPExport + 1, 1, 'exported 1 promise: first');
|
|
242
240
|
|
|
243
241
|
await dispatchMessage('watchLocalPromise', 'orphaned');
|
|
244
242
|
t.deepEqual(getDispatchLogs(), [
|
|
@@ -260,12 +258,12 @@ test('past-incarnation watched promises', async t => {
|
|
|
260
258
|
fulfillmentMessage(`p-${nextPImport()}`, 'watched local promise: rejected'),
|
|
261
259
|
rejectionMessage(`p+${lastPExport}`, S),
|
|
262
260
|
]);
|
|
263
|
-
t.
|
|
261
|
+
t.is(
|
|
264
262
|
lastPImport - firstPImport + 1,
|
|
265
263
|
7,
|
|
266
264
|
'imported 7 promises (1 per dispatch)',
|
|
267
265
|
);
|
|
268
|
-
t.
|
|
266
|
+
t.is(
|
|
269
267
|
lastPExport - firstPExport + 1,
|
|
270
268
|
4,
|
|
271
269
|
'exported 4 promises: first, orphaned, fulfilled, rejected',
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
|
-
import '@endo/init/debug.js';
|
|
3
2
|
|
|
4
3
|
import { Far } from '@endo/far';
|
|
4
|
+
import { kunser } from '@agoric/kmarshal';
|
|
5
5
|
import { M } from '@agoric/store';
|
|
6
6
|
import { setupTestLiveslots } from './liveslots-helpers.js';
|
|
7
|
-
import { kunser } from './kmarshal.js';
|
|
8
7
|
|
|
9
8
|
function buildRootObject(vatPowers, vatParameters, baggage) {
|
|
10
9
|
const vd = vatPowers.VatData;
|
|
@@ -148,5 +147,5 @@ test('vrefs', async t => {
|
|
|
148
147
|
const expectedStore1Vref = `o+v${initialKindIDs.scalarMapStore}/5`;
|
|
149
148
|
const store1Vref = (await run('getStore1')).slots[0];
|
|
150
149
|
t.is(store1Vref, expectedStore1Vref);
|
|
151
|
-
t.
|
|
150
|
+
t.is(kunser(JSON.parse(fakestore.get(`vc.5.s${'key'}`))), 'value');
|
|
152
151
|
});
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
1
2
|
import test from 'ava';
|
|
2
|
-
import '@endo/init/debug.js';
|
|
3
3
|
|
|
4
4
|
import { Far } from '@endo/marshal';
|
|
5
|
+
import { kslot, kser } from '@agoric/kmarshal';
|
|
5
6
|
import { makeLiveSlots } from '../src/liveslots.js';
|
|
6
7
|
import { parseVatSlot } from '../src/parseVatSlots.js';
|
|
7
|
-
import { kslot, kser } from './kmarshal.js';
|
|
8
8
|
import { buildSyscall } from './liveslots-helpers.js';
|
|
9
9
|
import {
|
|
10
10
|
makeMessage,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/* global process */
|
|
2
3
|
import test from 'ava';
|
|
3
|
-
import '@endo/init/debug.js';
|
|
4
4
|
|
|
5
5
|
import { Far } from '@endo/marshal';
|
|
6
6
|
import { makePromiseKit } from '@endo/promise-kit';
|
|
7
|
+
import { kslot, kser } from '@agoric/kmarshal';
|
|
7
8
|
import engineGC from './engine-gc.js';
|
|
8
|
-
import { makeGcAndFinalize } from './gc-and-finalize.js';
|
|
9
|
-
import { kslot, kser } from './kmarshal.js';
|
|
9
|
+
import { watchCollected, makeGcAndFinalize } from './gc-and-finalize.js';
|
|
10
10
|
import { buildSyscall, makeDispatch } from './liveslots-helpers.js';
|
|
11
11
|
import {
|
|
12
12
|
makeMessage,
|
|
@@ -28,13 +28,13 @@ const gcAndFinalize = makeGcAndFinalize(engineGC);
|
|
|
28
28
|
|
|
29
29
|
test.serial('liveslots retains pending exported promise', async t => {
|
|
30
30
|
const { log, syscall } = buildSyscall();
|
|
31
|
-
let
|
|
31
|
+
let collected;
|
|
32
32
|
const success = [];
|
|
33
33
|
function build(_vatPowers) {
|
|
34
34
|
const root = Far('root', {
|
|
35
35
|
make() {
|
|
36
36
|
const pk = makePromiseKit();
|
|
37
|
-
|
|
37
|
+
collected = watchCollected(pk.promise);
|
|
38
38
|
// we export the Promise, but do not retain resolve/reject
|
|
39
39
|
return [pk.promise];
|
|
40
40
|
},
|
|
@@ -55,7 +55,7 @@ test.serial('liveslots retains pending exported promise', async t => {
|
|
|
55
55
|
const resultP = 'p-1';
|
|
56
56
|
await dispatch(makeMessage(rootA, 'make', [], resultP));
|
|
57
57
|
await gcAndFinalize();
|
|
58
|
-
t.
|
|
58
|
+
t.false(collected.result, 'Promise retained');
|
|
59
59
|
t.is(log[0].type, 'resolve');
|
|
60
60
|
const res0 = log[0].resolutions[0];
|
|
61
61
|
t.is(res0[0], resultP);
|
|
@@ -66,13 +66,13 @@ test.serial('liveslots retains pending exported promise', async t => {
|
|
|
66
66
|
|
|
67
67
|
test.serial('liveslots retains device nodes', async t => {
|
|
68
68
|
const { syscall } = buildSyscall();
|
|
69
|
-
let
|
|
69
|
+
let collected;
|
|
70
70
|
const recognize = new WeakSet(); // real WeakSet
|
|
71
71
|
const success = [];
|
|
72
72
|
function build(_vatPowers) {
|
|
73
73
|
const root = Far('root', {
|
|
74
74
|
first(dn) {
|
|
75
|
-
|
|
75
|
+
collected = watchCollected(dn);
|
|
76
76
|
recognize.add(dn);
|
|
77
77
|
},
|
|
78
78
|
second(dn) {
|
|
@@ -87,25 +87,24 @@ test.serial('liveslots retains device nodes', async t => {
|
|
|
87
87
|
const device = 'd-1';
|
|
88
88
|
await dispatch(makeMessage(rootA, 'first', [kslot(device)]));
|
|
89
89
|
await gcAndFinalize();
|
|
90
|
-
t.
|
|
90
|
+
t.false(collected.result, 'Device node retained');
|
|
91
91
|
await dispatch(makeMessage(rootA, 'second', [kslot(device)]));
|
|
92
92
|
t.deepEqual(success, [true]);
|
|
93
93
|
});
|
|
94
94
|
|
|
95
95
|
test.serial('GC syscall.dropImports', async t => {
|
|
96
96
|
const { log, syscall } = buildSyscall();
|
|
97
|
-
let
|
|
97
|
+
let collected;
|
|
98
98
|
function build(_vatPowers) {
|
|
99
|
-
|
|
100
|
-
let presence1;
|
|
99
|
+
const holder = new Set();
|
|
101
100
|
const root = Far('root', {
|
|
102
101
|
one(arg) {
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
holder.add(arg);
|
|
103
|
+
collected = watchCollected(arg);
|
|
105
104
|
},
|
|
106
105
|
two() {},
|
|
107
106
|
three() {
|
|
108
|
-
|
|
107
|
+
holder.clear(); // drops the import
|
|
109
108
|
},
|
|
110
109
|
});
|
|
111
110
|
return root;
|
|
@@ -121,19 +120,29 @@ test.serial('GC syscall.dropImports', async t => {
|
|
|
121
120
|
// rp1 = root~.one(arg)
|
|
122
121
|
await dispatch(makeMessage(rootA, 'one', [kslot(arg)]));
|
|
123
122
|
await dispatch(makeBringOutYourDead());
|
|
124
|
-
t.
|
|
123
|
+
t.false(collected.result);
|
|
125
124
|
|
|
126
125
|
// an intermediate message will trigger GC, but the presence is still held
|
|
127
126
|
await dispatch(makeMessage(rootA, 'two', []));
|
|
128
127
|
await dispatch(makeBringOutYourDead());
|
|
129
|
-
t.
|
|
128
|
+
t.false(collected.result);
|
|
130
129
|
|
|
131
130
|
// now tell the vat to drop the 'arg' presence we gave them earlier
|
|
132
131
|
await dispatch(makeMessage(rootA, 'three', []));
|
|
133
132
|
await dispatch(makeBringOutYourDead());
|
|
134
133
|
|
|
134
|
+
const isV8 =
|
|
135
|
+
typeof process !== 'undefined' && 'v8' in (process.versions || {});
|
|
136
|
+
|
|
135
137
|
// the presence itself should be gone
|
|
136
|
-
|
|
138
|
+
if (!collected.result) {
|
|
139
|
+
if (isV8) {
|
|
140
|
+
// Flake in v8/node: https://github.com/Agoric/agoric-sdk/issues/8883
|
|
141
|
+
t.log('skipping flake in v8');
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
t.fail('import not collected');
|
|
145
|
+
}
|
|
137
146
|
|
|
138
147
|
// first it will check that there are no VO's holding onto it
|
|
139
148
|
const l2 = log.shift();
|
|
@@ -246,12 +255,12 @@ test.serial('GC dispatch.retireExports', async t => {
|
|
|
246
255
|
|
|
247
256
|
test.serial('GC dispatch.dropExports', async t => {
|
|
248
257
|
const { log, syscall } = buildSyscall();
|
|
249
|
-
let
|
|
258
|
+
let collected;
|
|
250
259
|
function build(_vatPowers) {
|
|
251
260
|
const root = Far('root', {
|
|
252
261
|
one() {
|
|
253
262
|
const ex1 = Far('export', {});
|
|
254
|
-
|
|
263
|
+
collected = watchCollected(ex1);
|
|
255
264
|
return ex1;
|
|
256
265
|
// ex1 goes out of scope, dropping last userspace strongref
|
|
257
266
|
},
|
|
@@ -285,19 +294,19 @@ test.serial('GC dispatch.dropExports', async t => {
|
|
|
285
294
|
|
|
286
295
|
// the exported Remotable should be held in place by exportedRemotables
|
|
287
296
|
// until we tell the vat we don't need it any more
|
|
288
|
-
t.
|
|
297
|
+
t.false(collected.result);
|
|
289
298
|
|
|
290
299
|
// an intermediate message will trigger GC, but the presence is still held
|
|
291
300
|
await dispatch(makeMessage(rootA, 'two', []));
|
|
292
301
|
await dispatch(makeBringOutYourDead());
|
|
293
|
-
t.
|
|
302
|
+
t.false(collected.result);
|
|
294
303
|
|
|
295
304
|
// now tell the vat we don't need a strong reference to that export.
|
|
296
305
|
await dispatch(makeDropExports(ex1));
|
|
297
306
|
await dispatch(makeBringOutYourDead());
|
|
298
307
|
|
|
299
308
|
// that should allow ex1 to be collected
|
|
300
|
-
t.
|
|
309
|
+
t.true(collected.result);
|
|
301
310
|
|
|
302
311
|
// and once it's collected, the vat should emit `syscall.retireExport`
|
|
303
312
|
// because nobody else will be able to recognize it again
|
|
@@ -313,19 +322,19 @@ test.serial(
|
|
|
313
322
|
'GC dispatch.retireExports inhibits syscall.retireExports',
|
|
314
323
|
async t => {
|
|
315
324
|
const { log, syscall } = buildSyscall();
|
|
316
|
-
let
|
|
325
|
+
let collected;
|
|
317
326
|
function build(_vatPowers) {
|
|
318
|
-
|
|
327
|
+
const holder = new Set();
|
|
319
328
|
const root = Far('root', {
|
|
320
329
|
hold() {
|
|
321
|
-
ex1 = Far('export', {});
|
|
322
|
-
|
|
330
|
+
const ex1 = Far('export', {});
|
|
331
|
+
holder.add(ex1);
|
|
332
|
+
collected = watchCollected(ex1);
|
|
323
333
|
return ex1;
|
|
324
334
|
},
|
|
325
335
|
two() {},
|
|
326
336
|
drop() {
|
|
327
|
-
//
|
|
328
|
-
ex1 = undefined; // drop the last userspace strongref
|
|
337
|
+
holder.clear(); // drop the last userspace strongref
|
|
329
338
|
},
|
|
330
339
|
});
|
|
331
340
|
return root;
|
|
@@ -356,19 +365,19 @@ test.serial(
|
|
|
356
365
|
|
|
357
366
|
// the exported Remotable should be held in place by exportedRemotables
|
|
358
367
|
// until we tell the vat we don't need it any more
|
|
359
|
-
t.
|
|
368
|
+
t.false(collected.result);
|
|
360
369
|
|
|
361
370
|
// an intermediate message will trigger GC, but the presence is still held
|
|
362
371
|
await dispatch(makeMessage(rootA, 'two', []));
|
|
363
372
|
await dispatch(makeBringOutYourDead());
|
|
364
|
-
t.
|
|
373
|
+
t.false(collected.result);
|
|
365
374
|
|
|
366
375
|
// now tell the vat we don't need a strong reference to that export.
|
|
367
376
|
await dispatch(makeDropExports(ex1));
|
|
368
377
|
await dispatch(makeBringOutYourDead());
|
|
369
378
|
|
|
370
379
|
// that removes the liveslots strongref, but the vat's remains in place
|
|
371
|
-
t.
|
|
380
|
+
t.false(collected.result);
|
|
372
381
|
|
|
373
382
|
// now the kernel tells the vat we can't even recognize the export
|
|
374
383
|
await dispatch(makeRetireExports(ex1));
|
|
@@ -376,14 +385,14 @@ test.serial(
|
|
|
376
385
|
|
|
377
386
|
// that ought to delete the table entry, but doesn't affect the vat
|
|
378
387
|
// strongref
|
|
379
|
-
t.
|
|
388
|
+
t.false(collected.result);
|
|
380
389
|
|
|
381
390
|
// now tell the vat to drop its strongref
|
|
382
391
|
await dispatch(makeMessage(rootA, 'drop', []));
|
|
383
392
|
await dispatch(makeBringOutYourDead());
|
|
384
393
|
|
|
385
394
|
// which should let the export be collected
|
|
386
|
-
t.
|
|
395
|
+
t.true(collected.result);
|
|
387
396
|
|
|
388
397
|
// the vat should *not* emit `syscall.retireExport`, because it already
|
|
389
398
|
// received a dispatch.retireExport
|