@agoric/swingset-liveslots 0.10.3-other-dev-8f8782b.0 → 0.10.3-other-dev-fbe72e7.0.fbe72e7

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.
Files changed (141) hide show
  1. package/README.md +2 -0
  2. package/package.json +34 -26
  3. package/src/boyd-gc.d.ts +12 -0
  4. package/src/boyd-gc.d.ts.map +1 -0
  5. package/src/boyd-gc.js +598 -0
  6. package/src/cache.d.ts +71 -0
  7. package/src/cache.d.ts.map +1 -0
  8. package/src/cache.js +3 -2
  9. package/src/capdata.d.ts +16 -0
  10. package/src/capdata.d.ts.map +1 -0
  11. package/src/capdata.js +17 -10
  12. package/src/collectionManager.d.ts +47 -0
  13. package/src/collectionManager.d.ts.map +1 -0
  14. package/src/collectionManager.js +220 -103
  15. package/src/facetiousness.d.ts +25 -0
  16. package/src/facetiousness.d.ts.map +1 -0
  17. package/src/facetiousness.js +1 -1
  18. package/src/index.d.ts +4 -0
  19. package/src/index.d.ts.map +1 -0
  20. package/src/index.js +4 -2
  21. package/src/kdebug.d.ts +7 -0
  22. package/src/kdebug.d.ts.map +1 -0
  23. package/src/liveslots.d.ts +42 -0
  24. package/src/liveslots.d.ts.map +1 -0
  25. package/src/liveslots.js +137 -305
  26. package/src/message.d.ts +49 -0
  27. package/src/message.d.ts.map +1 -0
  28. package/src/message.js +9 -5
  29. package/src/parseVatSlots.d.ts +125 -0
  30. package/src/parseVatSlots.d.ts.map +1 -0
  31. package/src/parseVatSlots.js +1 -1
  32. package/src/types-index.d.ts +4 -0
  33. package/src/types-index.js +2 -0
  34. package/src/types.d.ts +81 -0
  35. package/src/types.d.ts.map +1 -0
  36. package/src/types.js +14 -7
  37. package/src/vatDataTypes.d.ts +170 -0
  38. package/src/vatDataTypes.d.ts.map +1 -0
  39. package/src/vatDataTypes.ts +272 -0
  40. package/src/vatstore-iterators.d.ts +4 -0
  41. package/src/vatstore-iterators.d.ts.map +1 -0
  42. package/src/vatstore-iterators.js +2 -0
  43. package/src/vatstore-usage.md +198 -0
  44. package/src/virtualObjectManager.d.ts +44 -0
  45. package/src/virtualObjectManager.d.ts.map +1 -0
  46. package/src/virtualObjectManager.js +254 -84
  47. package/src/virtualReferences.d.ts +61 -0
  48. package/src/virtualReferences.d.ts.map +1 -0
  49. package/src/virtualReferences.js +135 -26
  50. package/src/vpid-tracking.md +92 -0
  51. package/src/watchedPromises.d.ts +31 -0
  52. package/src/watchedPromises.d.ts.map +1 -0
  53. package/src/watchedPromises.js +81 -24
  54. package/test/{test-baggage.js → baggage.test.js} +1 -2
  55. package/test/{test-cache.js → cache.test.js} +0 -1
  56. package/test/clear-collection.test.js +586 -0
  57. package/test/{test-collection-schema-refcount.js → collection-schema-refcount.test.js} +1 -2
  58. package/test/{test-collection-upgrade.js → collection-upgrade.test.js} +1 -3
  59. package/test/{test-collections.js → collections.test.js} +183 -18
  60. package/test/{test-dropped-collection-weakrefs.js → dropped-collection-weakrefs.test.js} +1 -2
  61. package/test/dropped-weakset-9939.test.js +80 -0
  62. package/test/dummyMeterControl.d.ts +2 -0
  63. package/test/dummyMeterControl.d.ts.map +1 -0
  64. package/test/dummyMeterControl.js +1 -1
  65. package/test/{test-durabilityChecks.js → durabilityChecks.test.js} +4 -4
  66. package/test/engine-gc.d.ts +3 -0
  67. package/test/engine-gc.d.ts.map +1 -0
  68. package/test/exo-utils.js +70 -0
  69. package/test/{test-facetiousness.js → facetiousness.test.js} +1 -2
  70. package/test/gc-and-finalize.d.ts +5 -0
  71. package/test/gc-and-finalize.d.ts.map +1 -0
  72. package/test/gc-and-finalize.js +30 -1
  73. package/test/gc-before-finalizer.test.js +230 -0
  74. package/test/gc-helpers.js +4 -5
  75. package/test/{test-gc-sensitivity.js → gc-sensitivity.test.js} +2 -2
  76. package/test/handled-promises.test.js +872 -0
  77. package/test/{test-initial-vrefs.js → initial-vrefs.test.js} +13 -20
  78. package/test/liveslots-helpers.d.ts +64 -0
  79. package/test/liveslots-helpers.d.ts.map +1 -0
  80. package/test/liveslots-helpers.js +13 -7
  81. package/test/{test-liveslots-mock-gc.js → liveslots-mock-gc.test.js} +101 -2
  82. package/test/{test-liveslots-real-gc.js → liveslots-real-gc.test.js} +73 -46
  83. package/test/{test-liveslots.js → liveslots.test.js} +17 -18
  84. package/test/mock-gc.js +1 -0
  85. package/test/storeGC/{test-lifecycle.js → lifecycle.test.js} +15 -14
  86. package/test/storeGC/{test-refcount-management.js → refcount-management.test.js} +1 -2
  87. package/test/storeGC/{test-scalar-store-kind.js → scalar-store-kind.test.js} +0 -1
  88. package/test/storeGC/{test-weak-key.js → weak-key.test.js} +1 -2
  89. package/test/strict-test-env-upgrade.test.js +94 -0
  90. package/test/util.d.ts +25 -0
  91. package/test/util.d.ts.map +1 -0
  92. package/test/util.js +4 -4
  93. package/test/vat-environment.test.js +65 -0
  94. package/test/vat-util.d.ts +9 -0
  95. package/test/vat-util.d.ts.map +1 -0
  96. package/test/vat-util.js +2 -2
  97. package/test/virtual-objects/{test-cease-recognition.js → cease-recognition.test.js} +2 -2
  98. package/test/virtual-objects/{test-cross-facet.js → cross-facet.test.js} +5 -4
  99. package/test/virtual-objects/{test-empty-data.js → empty-data.test.js} +1 -2
  100. package/test/virtual-objects/{test-facets.js → facets.test.js} +1 -2
  101. package/test/virtual-objects/{test-kind-changes.js → kind-changes.test.js} +2 -2
  102. package/test/virtual-objects/{test-reachable-vrefs.js → reachable-vrefs.test.js} +2 -2
  103. package/test/virtual-objects/{test-rep-tostring.js → rep-tostring.test.js} +3 -5
  104. package/test/virtual-objects/{test-retain-remotable.js → retain-remotable.test.js} +25 -24
  105. package/test/virtual-objects/set-debug-label-instances.js +1 -1
  106. package/test/virtual-objects/state-shape.test.js +389 -0
  107. package/test/virtual-objects/{test-virtualObjectGC.js → virtualObjectGC.test.js} +39 -38
  108. package/test/virtual-objects/{test-virtualObjectManager.js → virtualObjectManager.test.js} +104 -8
  109. package/test/virtual-objects/{test-vo-real-gc.js → vo-real-gc.test.js} +8 -8
  110. package/test/virtual-objects/{test-weakcollections-vref-handling.js → weakcollections-vref-handling.test.js} +1 -2
  111. package/test/{test-vo-test-harness.js → vo-test-harness.test.js} +13 -10
  112. package/test/{test-vpid-liveslots.js → vpid-liveslots.test.js} +105 -5
  113. package/test/waitUntilQuiescent.d.ts +3 -0
  114. package/test/waitUntilQuiescent.d.ts.map +1 -0
  115. package/test/waitUntilQuiescent.js +2 -1
  116. package/test/weakset-dropped-remotable.test.js +50 -0
  117. package/tools/fakeCollectionManager.d.ts +14 -0
  118. package/tools/fakeCollectionManager.d.ts.map +1 -0
  119. package/tools/fakeCollectionManager.js +44 -0
  120. package/tools/fakeVirtualObjectManager.d.ts +32 -0
  121. package/tools/fakeVirtualObjectManager.d.ts.map +1 -0
  122. package/tools/fakeVirtualObjectManager.js +62 -0
  123. package/tools/fakeVirtualSupport.d.ts +278 -0
  124. package/tools/fakeVirtualSupport.d.ts.map +1 -0
  125. package/tools/fakeVirtualSupport.js +389 -0
  126. package/tools/prepare-strict-test-env.d.ts +37 -0
  127. package/tools/prepare-strict-test-env.d.ts.map +1 -0
  128. package/tools/prepare-strict-test-env.js +124 -0
  129. package/tools/prepare-test-env.d.ts +2 -0
  130. package/tools/prepare-test-env.d.ts.map +1 -0
  131. package/tools/prepare-test-env.js +13 -0
  132. package/tools/setup-vat-data.d.ts +9 -0
  133. package/tools/setup-vat-data.d.ts.map +1 -0
  134. package/tools/setup-vat-data.js +95 -0
  135. package/tools/vo-test-harness.d.ts +33 -0
  136. package/tools/vo-test-harness.d.ts.map +1 -0
  137. package/tools/vo-test-harness.js +164 -0
  138. package/CHANGELOG.md +0 -61
  139. package/test/kmarshal.js +0 -79
  140. package/test/test-handled-promises.js +0 -360
  141. package/test/virtual-objects/test-state-shape.js +0 -298
@@ -0,0 +1,37 @@
1
+ export function annihilate(options?: Omit<ReincarnateOptions, "fakeVomKit" | "fakeStore">): {
2
+ relaxDurabilityRules?: boolean | undefined;
3
+ fakeStore: Map<string, string>;
4
+ weak?: boolean | undefined;
5
+ cacheSize?: number | undefined;
6
+ fakeVomKit: import("./setup-vat-data.js").FakeVomKit;
7
+ };
8
+ export function getBaggage(): Baggage;
9
+ export function nextLife(fromIncarnation?: ReincarnateOptions): {
10
+ relaxDurabilityRules?: boolean | undefined;
11
+ fakeStore: Map<string, string>;
12
+ weak?: boolean | undefined;
13
+ cacheSize?: number | undefined;
14
+ fakeVomKit: import("./setup-vat-data.js").FakeVomKit;
15
+ };
16
+ export function startLife<B extends (baggage: Baggage) => Promise<any> | any>(build: B, run?: (tools: Awaited<ReturnType<B>>) => Promise<void> | void, { fromIncarnation, cleanStart }?: {
17
+ fromIncarnation?: {
18
+ relaxDurabilityRules?: boolean | undefined;
19
+ fakeStore: Map<string, string>;
20
+ weak?: boolean | undefined;
21
+ cacheSize?: number | undefined;
22
+ fakeVomKit: import("./setup-vat-data.js").FakeVomKit;
23
+ } | undefined;
24
+ cleanStart?: boolean | undefined;
25
+ }): Promise<{
26
+ relaxDurabilityRules?: boolean | undefined;
27
+ fakeStore: Map<string, string>;
28
+ weak?: boolean | undefined;
29
+ cacheSize?: number | undefined;
30
+ fakeVomKit: import("./setup-vat-data.js").FakeVomKit;
31
+ }>;
32
+ import { flushIncarnation } from './setup-vat-data.js';
33
+ import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
34
+ import type { ReincarnateOptions } from './setup-vat-data.js';
35
+ import type { Baggage } from '@agoric/swingset-liveslots';
36
+ export { flushIncarnation, eventLoopIteration as nextCrank };
37
+ //# sourceMappingURL=prepare-strict-test-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepare-strict-test-env.d.ts","sourceRoot":"","sources":["prepare-strict-test-env.js"],"names":[],"mappings":"AAiCO,qCADK,IAAI,CAAC,kBAAkB,EAAE,YAAY,GAAG,WAAW,CAAC;;;;;;EAO/D;AAGM,8BADO,OAAO,CAGpB;AAKM,2CAFI,kBAAkB;;;;;;EAM5B;AAUM,0BAPiD,CAAC,SAA5C,CAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,GAAI,SAC5C,CAAC,QACD,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,oCAE/D;IAAqC,eAAe;;;;;;;IAC1B,UAAU;CAAC;;;;;;GA2DvC;iCA5G6C,qBAAqB;mCAIhC,uCAAuC;wCASnC,qBAAqB;6BADhC,4BAA4B"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Prepare Agoric SwingSet vat global strict environment for testing.
3
+ *
4
+ * Installs Hardened JS (and does lockdown), plus adds mocks for virtual objects
5
+ * and stores.
6
+ *
7
+ * Exports tools for simulating upgrades.
8
+ */
9
+
10
+ import '@agoric/internal/src/install-ses-debug.js';
11
+
12
+ // eslint-disable-next-line import/order
13
+ import { reincarnate, flushIncarnation } from './setup-vat-data.js';
14
+
15
+ import { makePromiseKit } from '@endo/promise-kit';
16
+ import { Fail } from '@endo/errors';
17
+ import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
18
+ import { makeUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js';
19
+
20
+ export { flushIncarnation };
21
+ export { eventLoopIteration as nextCrank };
22
+
23
+ /**
24
+ * @import { PromiseKit } from '@endo/promise-kit'
25
+ * @import { Baggage } from '@agoric/swingset-liveslots'
26
+ * @import { ReincarnateOptions } from './setup-vat-data.js'
27
+ */
28
+
29
+ /** @type {ReincarnateOptions} */
30
+ let incarnation;
31
+ let incarnationNumber = 0;
32
+
33
+ /** @param {Omit<ReincarnateOptions, 'fakeVomKit' | 'fakeStore'>} [options] */
34
+ export const annihilate = (options = {}) => {
35
+ // @ts-expect-error fakeStore and fakeVomKit don't exist on type, but drop them if they do at runtime
36
+ const { fakeStore: _fs, fakeVomKit: _fvk, ...opts } = options;
37
+ incarnation = reincarnate({ relaxDurabilityRules: false, ...opts });
38
+ incarnationNumber = 0;
39
+ return incarnation;
40
+ };
41
+
42
+ /** @returns {Baggage} */
43
+ export const getBaggage = () => {
44
+ return incarnation.fakeVomKit.cm.provideBaggage();
45
+ };
46
+
47
+ /**
48
+ * @param {ReincarnateOptions} [fromIncarnation]
49
+ */
50
+ export const nextLife = (fromIncarnation = incarnation) => {
51
+ incarnation = reincarnate(fromIncarnation);
52
+ incarnationNumber += 1;
53
+ return incarnation;
54
+ };
55
+
56
+ /**
57
+ * @template {(baggage: Baggage) => Promise<any> | any} B
58
+ * @param {B} build
59
+ * @param {(tools: Awaited<ReturnType<B>>) => Promise<void> | void} [run]
60
+ * @param {object} [options]
61
+ * @param {ReincarnateOptions} [options.fromIncarnation]
62
+ * @param {boolean} [options.cleanStart]
63
+ */
64
+ export const startLife = async (
65
+ build,
66
+ run,
67
+ { fromIncarnation, cleanStart } = {},
68
+ ) => {
69
+ await eventLoopIteration();
70
+ if (cleanStart) annihilate();
71
+ const oldIncarnationNumber = incarnationNumber;
72
+ const oldIncarnation = incarnation;
73
+ const disconnectionObject = makeUpgradeDisconnection(
74
+ 'vat upgraded',
75
+ oldIncarnationNumber,
76
+ );
77
+ const { fakeVomKit } = nextLife(fromIncarnation);
78
+ /** @type {Map<string, PromiseKit<any>>} */
79
+ const previouslyWatchedPromises = new Map();
80
+ let buildTools;
81
+ try {
82
+ buildTools = await build(getBaggage());
83
+ fakeVomKit.wpm.loadWatchedPromiseTable(vref => {
84
+ // See revivePromise in liveslots.js
85
+ const { getValForSlot, valToSlot, setValForSlot } = fakeVomKit.fakeStuff;
86
+ // Assume all promises were decided by the previous incarnation
87
+ !getValForSlot(vref) || Fail`Attempting to revive known promise ${vref}`;
88
+ const pk = makePromiseKit();
89
+ previouslyWatchedPromises.set(vref, pk);
90
+ const val = pk.promise;
91
+ valToSlot.set(val, vref);
92
+ setValForSlot(vref, val);
93
+ return val;
94
+ });
95
+
96
+ fakeVomKit.vom.insistAllDurableKindsReconnected();
97
+
98
+ await eventLoopIteration();
99
+ // End of start crank
100
+ } catch (err) {
101
+ // Rollback upgrade
102
+ incarnation = oldIncarnation;
103
+ incarnationNumber = oldIncarnationNumber;
104
+ throw err;
105
+ }
106
+
107
+ // Simulate a dispatch of previously decided promise rejections
108
+ // In real swingset this could happen after some deliveries
109
+ for (const { reject } of previouslyWatchedPromises.values()) {
110
+ reject(disconnectionObject);
111
+ }
112
+ await eventLoopIteration();
113
+ // End of resolution dispatch crank
114
+
115
+ if (run) {
116
+ await run(buildTools);
117
+ await eventLoopIteration();
118
+ }
119
+
120
+ return incarnation;
121
+ };
122
+
123
+ // Setup the initial incarnation
124
+ annihilate();
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=prepare-test-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prepare-test-env.d.ts","sourceRoot":"","sources":["prepare-test-env.js"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Prepare Agoric SwingSet vat global environment for testing.
3
+ *
4
+ * Installs Hardened JS (and does lockdown), plus adds mocks for virtual objects
5
+ * and stores.
6
+ */
7
+
8
+ import '@agoric/internal/src/install-ses-debug.js';
9
+
10
+ import { reincarnate } from './setup-vat-data.js';
11
+
12
+ // Install the VatData globals.
13
+ reincarnate();
@@ -0,0 +1,9 @@
1
+ export function flushIncarnation(options?: Partial<ReincarnateOptions>): Omit<ReincarnateOptions, "fakeVomKit">;
2
+ export function reincarnate(options?: Partial<ReincarnateOptions>): ReincarnateOptions;
3
+ export type FakeVomKit = ReturnType<typeof makeFakeVirtualStuff>;
4
+ export type ReincarnateOptions = import("@agoric/internal").Simplify<Omit<NonNullable<Parameters<typeof makeFakeVirtualStuff>[0]>, "WeakMap" | "WeakSet"> & {
5
+ fakeVomKit: FakeVomKit;
6
+ fakeStore: Map<string, string>;
7
+ }>;
8
+ import { makeFakeVirtualStuff } from './fakeVirtualSupport.js';
9
+ //# sourceMappingURL=setup-vat-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup-vat-data.d.ts","sourceRoot":"","sources":["setup-vat-data.js"],"names":[],"mappings":"AA2DO,2CAHI,OAAO,CAAC,kBAAkB,CAAC,GACzB,IAAI,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAelD;AAOM,sCAHI,OAAO,CAAC,kBAAkB,CAAC,GACzB,kBAAkB,CAiB9B;yBAjFa,UAAU,CAAC,OAAO,oBAAoB,CAAC;iCAmCxC,OAAO,kBAAkB,EAAE,QAAQ,CAC3C,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC,GACxF;IAAM,UAAU,EAAE,UAAU,CAAC;IAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAC3D;qCA1CiC,yBAAyB"}
@@ -0,0 +1,95 @@
1
+ /* global globalThis */
2
+
3
+ // This file produces the globalThis.VatData property outside of a
4
+ // running SwingSet so that it can be used by '@agoric/vat-data'
5
+ // (which only *consumes* `globalThis.VatData`) in code under test. It
6
+ // also populates the passStyleOf symbol-named property.
7
+
8
+ import { passStyleOf } from '@endo/pass-style';
9
+ import { PassStyleOfEndowmentSymbol } from '@endo/pass-style/endow.js';
10
+ import { makeFakeVirtualStuff } from './fakeVirtualSupport.js';
11
+
12
+ const { WeakMap, WeakSet } = globalThis;
13
+
14
+ /** @typedef {ReturnType<typeof makeFakeVirtualStuff>} FakeVomKit */
15
+
16
+ /** @type {FakeVomKit} */
17
+ let fakeVomKit;
18
+
19
+ globalThis.VatData = harden({
20
+ // @ts-expect-error spread argument for non-rest parameter
21
+ defineKind: (...args) => fakeVomKit.vom.defineKind(...args),
22
+ // @ts-expect-error spread argument for non-rest parameter
23
+ defineKindMulti: (...args) => fakeVomKit.vom.defineKindMulti(...args),
24
+ // @ts-expect-error spread argument for non-rest parameter
25
+ defineDurableKind: (...args) => fakeVomKit.vom.defineDurableKind(...args),
26
+ defineDurableKindMulti: (...args) =>
27
+ // @ts-expect-error spread argument for non-rest parameter
28
+ fakeVomKit.vom.defineDurableKindMulti(...args),
29
+ makeKindHandle: tag => fakeVomKit.vom.makeKindHandle(tag),
30
+ canBeDurable: (...args) => fakeVomKit.vom.canBeDurable(...args),
31
+ providePromiseWatcher: (...args) =>
32
+ // @ts-expect-error spread argument for non-rest parameter
33
+ fakeVomKit.wpm.providePromiseWatcher(...args),
34
+ watchPromise: (p, watcher, ...args) =>
35
+ fakeVomKit.wpm.watchPromise(p, watcher, ...args),
36
+ makeScalarBigMapStore: (...args) =>
37
+ fakeVomKit.cm.makeScalarBigMapStore(...args),
38
+ makeScalarBigWeakMapStore: (...args) =>
39
+ fakeVomKit.cm.makeScalarBigWeakMapStore(...args),
40
+ makeScalarBigSetStore: (...args) =>
41
+ fakeVomKit.cm.makeScalarBigSetStore(...args),
42
+ makeScalarBigWeakSetStore: (...args) =>
43
+ fakeVomKit.cm.makeScalarBigWeakSetStore(...args),
44
+ });
45
+
46
+ globalThis[PassStyleOfEndowmentSymbol] = passStyleOf;
47
+
48
+ /**
49
+ * @typedef {import("@agoric/internal").Simplify<
50
+ * Omit<NonNullable<Parameters<typeof makeFakeVirtualStuff>[0]>, 'WeakMap' | 'WeakSet'> &
51
+ * { fakeVomKit: FakeVomKit; fakeStore: Map<string, string> }
52
+ * >} ReincarnateOptions
53
+ */
54
+
55
+ /**
56
+ *
57
+ * @param {Partial<ReincarnateOptions>} options
58
+ * @returns {Omit<ReincarnateOptions, 'fakeVomKit'>}
59
+ */
60
+ export const flushIncarnation = (options = {}) => {
61
+ const { fakeVomKit: fvk = fakeVomKit, ...fakeStuffOptions } = options;
62
+
63
+ if (fvk) {
64
+ fvk.vom.flushStateCache();
65
+ fvk.cm.flushSchemaCache();
66
+ fvk.vrm.flushIDCounters();
67
+ }
68
+
69
+ // Clone previous fakeStore (if any) to avoid mutations from previous incarnation
70
+ const fakeStore = new Map(options.fakeStore);
71
+
72
+ return { ...fakeStuffOptions, fakeStore };
73
+ };
74
+
75
+ /**
76
+ *
77
+ * @param {Partial<ReincarnateOptions>} options
78
+ * @returns {ReincarnateOptions}
79
+ */
80
+ export const reincarnate = (options = {}) => {
81
+ const clonedIncarnation = flushIncarnation(options);
82
+
83
+ fakeVomKit = makeFakeVirtualStuff({
84
+ ...clonedIncarnation,
85
+ WeakMap,
86
+ WeakSet,
87
+ });
88
+
89
+ // @ts-expect-error toStringTag set imperatively so it doesn't show up in the type
90
+ globalThis.WeakMap = fakeVomKit.vom.VirtualObjectAwareWeakMap;
91
+ // @ts-expect-error ditto
92
+ globalThis.WeakSet = fakeVomKit.vom.VirtualObjectAwareWeakSet;
93
+
94
+ return { ...clonedIncarnation, fakeVomKit };
95
+ };
@@ -0,0 +1,33 @@
1
+ export function runVOTest(t: any, prepare: any, makeTestObject: any, testTestObject: any): Promise<void>;
2
+ export function makeSpy(t: import("ava").ExecutionContext): {
3
+ fail: (msg: any) => void;
4
+ falsy: (check: any, msg: any) => void;
5
+ failureMessage: string;
6
+ falsyMessage: string;
7
+ context: unknown;
8
+ title: string;
9
+ passed: boolean;
10
+ log: import("ava").LogFn;
11
+ plan: import("ava").PlanFn;
12
+ teardown: import("ava").TeardownFn;
13
+ timeout: import("ava").TimeoutFn;
14
+ try: import("ava").TryFn<unknown>;
15
+ assert: import("ava").AssertAssertion;
16
+ deepEqual: import("ava").DeepEqualAssertion;
17
+ like: import("ava").LikeAssertion;
18
+ false: import("ava").FalseAssertion;
19
+ is: import("ava").IsAssertion;
20
+ not: import("ava").NotAssertion;
21
+ notDeepEqual: import("ava").NotDeepEqualAssertion;
22
+ notRegex: import("ava").NotRegexAssertion;
23
+ notThrows: import("ava").NotThrowsAssertion;
24
+ notThrowsAsync: import("ava").NotThrowsAsyncAssertion;
25
+ pass: import("ava").PassAssertion;
26
+ regex: import("ava").RegexAssertion;
27
+ snapshot: import("ava").SnapshotAssertion;
28
+ throws: import("ava").ThrowsAssertion;
29
+ throwsAsync: import("ava").ThrowsAsyncAssertion;
30
+ true: import("ava").TrueAssertion;
31
+ truthy: import("ava").TruthyAssertion;
32
+ };
33
+ //# sourceMappingURL=vo-test-harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vo-test-harness.d.ts","sourceRoot":"","sources":["vo-test-harness.js"],"names":[],"mappings":"AA8FA,yGAqEC;AAxJM,2BAFI,OAAO,KAAK,EAAE,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBxC"}
@@ -0,0 +1,164 @@
1
+ import { Far } from '@endo/marshal';
2
+ import { setupTestLiveslots } from '../test/liveslots-helpers.js';
3
+
4
+ // This file contains a test harness for virtual objects. runVOTest()
5
+ // is to to help verify that a VO can be garbage collected and then
6
+ // reloaded from persistent storage while maintaining functionality.
7
+
8
+ /**
9
+ * A spy wrapping Ava's t for tests that are testing the harness itself.
10
+ * @param {import('ava').ExecutionContext} t
11
+ */
12
+ export const makeSpy = t => {
13
+ const tSpy = {
14
+ ...t,
15
+ fail: msg => {
16
+ tSpy.failureMessage = msg;
17
+ },
18
+ // In Ava 6, assertions throw?
19
+ falsy: (check, msg) => {
20
+ if (!check) return;
21
+ tSpy.falsyMessage = msg;
22
+ },
23
+ failureMessage: '',
24
+ falsyMessage: '',
25
+ };
26
+ return tSpy;
27
+ };
28
+
29
+ // Testing VO swapping with runVOTest:
30
+ //
31
+ // Step 1: import the necessary harness paraphernalia
32
+ //
33
+ // import { test, runVOTest } from '@agoric/swingset-vat/tools/vo-test-harness.js';
34
+ //
35
+ // `test` is the regular Ava test object that you'd normally import from
36
+ // `@agoric/swingset-vat/tools/prepare-test-env-ava.js`. The test harness will
37
+ // import it for you, since it needs to set up some test things itself.
38
+ //
39
+ // Step 2: write three functions that you will pass to the test harness
40
+ //
41
+ // `prepare(VatData)` should perform any necessary environmental setup that the
42
+ // virtual object kind under test will require. In particular, this includes
43
+ // executing any necessary `defineKind` or `defineDurableKind` calls to
44
+ // establish the VO itself. The `VatData` parameter is a regular `VatData`
45
+ // object that can be used to obtain functions like `defineKind`.
46
+ //
47
+ // `makeTestObject()` should create and return an instance of the VO to be tested.
48
+ //
49
+ // `testTestObject(obj, phase)` should execute whatever actual testing and test
50
+ // assertions you care to perform to verify your VO kind. `obj` will be a
51
+ // reference to an in-memory representative of the virtual object being tested
52
+ // and `phase` will be a string, either 'before' or 'after', indicating whether
53
+ // this instance of the object is before or after having been swapped out of
54
+ // memory and then reloaded. A correctly functioning VO should, among other
55
+ // things, behave exactly the same in both cases.
56
+ //
57
+ // Step 3: write an Ava test that invokes the test harness
58
+ //
59
+ // The outer portion of this should be a conventional Ava test written in the
60
+ // conventional way, e.g.:
61
+ //
62
+ // test('test name', async t => {
63
+ // ...your test here...
64
+ // });
65
+ //
66
+ // The body of your test most likely will enclose the three functions described
67
+ // above, since your `testTestObject` function (and possibly the others,
68
+ // depending on how you code things) will need access to the `t` object in order
69
+ // to execute test assertions. Then, from inside your test invoke:
70
+ //
71
+ // await runVOTest(t, prepare, makeTestObject, testTestObject);
72
+ //
73
+ // This will:
74
+ // 1 - execute the `prepare` function
75
+ // 2 - create a test object instance via `makeTestObject`
76
+ // 3 - run `testTestObject` on the test object (this is the 'before' phase)
77
+ // 4 - drop all in-memory references to the test object and force a GC pass
78
+ // 5 - run `testTestObject` on the test object *again* (this is the 'after' phase)
79
+ //
80
+ // The key thing that the test harness provides for you is step 4, which
81
+ // packages up some awkward boilerplate that's a bit of mysterious if you're not
82
+ // already pretty familiar with how the VO GC mechanism works (or perhaps even
83
+ // if you are).
84
+ //
85
+ // Note: It is critical that none of your own code retain any in-memory
86
+ // references to the test object beyond step 3. However, another key service
87
+ // that the test harness provides is to detect if you did this and if so fail
88
+ // the test. One use of the test harness is to verify that you aren't
89
+ // accidentally holding such references when you didn't mean to.
90
+ //
91
+ // The SwingSet test `vo-test-harness/test-vo-test-harness.js` is a test of the
92
+ // VO test harness itself, but can be used as a simple example of how to set
93
+ // things up.
94
+
95
+ export async function runVOTest(t, prepare, makeTestObject, testTestObject) {
96
+ function buildRootObject(vatPowers) {
97
+ const { VatData } = vatPowers;
98
+ const { defineKind } = VatData;
99
+
100
+ const freeChecker = new WeakSet();
101
+
102
+ const makeSlug = defineKind('slug', label => ({ label }), {
103
+ getLabel: ({ state }) => state.label,
104
+ });
105
+ const cacheDisplacer = makeSlug('cacheDisplacer');
106
+
107
+ const makeHolder = defineKind('holder', (held = null) => ({ held }), {
108
+ setValue: ({ state }, value) => {
109
+ state.held = value;
110
+ },
111
+ getValue: ({ state }) => state.held,
112
+ });
113
+ const holder = makeHolder();
114
+
115
+ let held = null;
116
+
117
+ prepare(VatData);
118
+
119
+ function displaceCache() {
120
+ return cacheDisplacer.getLabel();
121
+ }
122
+
123
+ return Far('root', {
124
+ makeAndHold() {
125
+ held = makeTestObject();
126
+ freeChecker.add(held);
127
+ displaceCache();
128
+ },
129
+ storeHeld() {
130
+ holder.setValue(held);
131
+ displaceCache();
132
+ },
133
+ dropHeld() {
134
+ held = null;
135
+ displaceCache();
136
+ },
137
+ fetchAndHold() {
138
+ held = holder.getValue();
139
+ t.falsy(
140
+ freeChecker.has(held),
141
+ 'somebody continues to hold test object',
142
+ );
143
+ displaceCache();
144
+ },
145
+ testHeld(phase) {
146
+ testTestObject(held, phase);
147
+ },
148
+ });
149
+ }
150
+
151
+ const { dispatchMessage } = await setupTestLiveslots(
152
+ t,
153
+ buildRootObject,
154
+ 'bob',
155
+ { forceGC: true, skipLogging: true },
156
+ );
157
+
158
+ await dispatchMessage('makeAndHold');
159
+ await dispatchMessage('testHeld', 'before');
160
+ await dispatchMessage('storeHeld');
161
+ await dispatchMessage('dropHeld');
162
+ await dispatchMessage('fetchAndHold');
163
+ await dispatchMessage('testHeld', 'after');
164
+ }
package/CHANGELOG.md DELETED
@@ -1,61 +0,0 @@
1
- # Change Log
2
-
3
- All notable changes to this project will be documented in this file.
4
- See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
-
6
- ### [0.10.3-u11.0](https://github.com/Agoric/agoric-sdk/compare/@agoric/swingset-liveslots@0.10.2...@agoric/swingset-liveslots@0.10.3-u11.0) (2023-08-24)
7
-
8
- **Note:** Version bump only for package @agoric/swingset-liveslots
9
-
10
-
11
-
12
-
13
-
14
- ### [0.10.2](https://github.com/Agoric/agoric-sdk/compare/@agoric/swingset-liveslots@0.10.1...@agoric/swingset-liveslots@0.10.2) (2023-06-02)
15
-
16
- **Note:** Version bump only for package @agoric/swingset-liveslots
17
-
18
-
19
-
20
-
21
-
22
- ### [0.10.1](https://github.com/Agoric/agoric-sdk/compare/@agoric/swingset-liveslots@0.10.0...@agoric/swingset-liveslots@0.10.1) (2023-05-24)
23
-
24
- **Note:** Version bump only for package @agoric/swingset-liveslots
25
-
26
-
27
-
28
-
29
-
30
- ## 0.10.0 (2023-05-19)
31
-
32
-
33
- ### Features
34
-
35
- * better diagnostic for failed reanimate ([c0c9c94](https://github.com/Agoric/agoric-sdk/commit/c0c9c9433648d520aa2bcdbadbbfe877831567c7)), closes [Error#1](https://github.com/Agoric/Error/issues/1)
36
- * **swingset-liveslots:** label virtual instances ([4191eb6](https://github.com/Agoric/agoric-sdk/commit/4191eb62d0e64048c3c715e5f71a53a747267350))
37
- * add APIs for tracking/debugging undesired object retention (aka "leaks") ([0a7221b](https://github.com/Agoric/agoric-sdk/commit/0a7221b3c04f3b2894c30346fa2ea6fb0130c046)), closes [#7318](https://github.com/Agoric/agoric-sdk/issues/7318)
38
- * move liveslots and specific tests to a new package ([0921a89](https://github.com/Agoric/agoric-sdk/commit/0921a8903b72cfefdf05a5906bcfb826cac1cc2f)), closes [#6596](https://github.com/Agoric/agoric-sdk/issues/6596)
39
-
40
-
41
- ### Bug Fixes
42
-
43
- * **liveslots:** allow new Kind upgrade to add new facets ([6bc6694](https://github.com/Agoric/agoric-sdk/commit/6bc6694968e6d2f529e7c91ec1efb11fdff2e2d3)), closes [#7437](https://github.com/Agoric/agoric-sdk/issues/7437)
44
- * **liveslots:** retain WeakRefs to voAware collections ([3935723](https://github.com/Agoric/agoric-sdk/commit/393572396781afd17691e1366abeba696228a24e)), closes [#7371](https://github.com/Agoric/agoric-sdk/issues/7371)
45
- * **swingset-liveslots:** prevent VOM infinite loop if `globalThis.WeakSet` etc are replaced ([d7b35e2](https://github.com/Agoric/agoric-sdk/commit/d7b35e28715a715ef510f2717e0040fa017caab4))
46
- * adding dup entries to virtual sets is OK ([c81d367](https://github.com/Agoric/agoric-sdk/commit/c81d3677d8085eb4debe5baa416816ff94d582cf)), closes [#7234](https://github.com/Agoric/agoric-sdk/issues/7234)
47
- * code updates for new marshal ([292f971](https://github.com/Agoric/agoric-sdk/commit/292f971769db69e61782f96638c2f687c3f95ac2))
48
- * **SwingSet:** Don't send stopVat during upgrade ([5cc47d2](https://github.com/Agoric/agoric-sdk/commit/5cc47d2d8892690f8c1653630b41dd64cc42d73b)), closes [#6650](https://github.com/Agoric/agoric-sdk/issues/6650)
49
- * **types:** return value of deleter ([457f576](https://github.com/Agoric/agoric-sdk/commit/457f5765b9fc0a693e6eb5e6644ddf4af3b791db))
50
- * move many type definitions from swingset to liveslots ([727143d](https://github.com/Agoric/agoric-sdk/commit/727143d5562498e2e3013c34304f229b4dd11da5))
51
- * move rejectAllPromises from stopVat to kernels-side upgradeVat ([d79623f](https://github.com/Agoric/agoric-sdk/commit/d79623f3fb3b87653dba1c71eb1153711c9d962c)), closes [#6694](https://github.com/Agoric/agoric-sdk/issues/6694)
52
- * Move upgrade-time abandonExports responsibility into the kernel ([66ac657](https://github.com/Agoric/agoric-sdk/commit/66ac657d51d3d1be61ee4a6e9a621a664086ee57)), closes [#6696](https://github.com/Agoric/agoric-sdk/issues/6696)
53
- * only the exo api change ([5cf3bf1](https://github.com/Agoric/agoric-sdk/commit/5cf3bf10a71dd02094365a66e87032e5d17d004f))
54
- * **liveslots:** use Map for vrefStatus, not object ([1456e2a](https://github.com/Agoric/agoric-sdk/commit/1456e2ae006bb1c702383cedda5e5c407968840e))
55
- * **swingset:** move a bunch of types from swingset to swingset-liveslots ([14f9bb0](https://github.com/Agoric/agoric-sdk/commit/14f9bb00c82c085dc647f23b6c90b26e6a0a6dfd))
56
- * **swingset-liveslots:** Move promise rejection responsibility into the kernel ([dd29ff3](https://github.com/Agoric/agoric-sdk/commit/dd29ff35c5dc72efbbf7087849182aa7f04b2bb1)), closes [#6694](https://github.com/Agoric/agoric-sdk/issues/6694)
57
- * add 'v'/'d' virtual/durable annotations to vrefs ([b859e92](https://github.com/Agoric/agoric-sdk/commit/b859e92fe041415d6e34250f672a10ad927aa33e)), closes [#6695](https://github.com/Agoric/agoric-sdk/issues/6695)
58
- * update description of "FINALIZED" state ([809f366](https://github.com/Agoric/agoric-sdk/commit/809f3660c083467e76deb1487015cb24205a801d))
59
- * without assertKeyPattern ([#7035](https://github.com/Agoric/agoric-sdk/issues/7035)) ([c9fcd7f](https://github.com/Agoric/agoric-sdk/commit/c9fcd7f82757732435cd96f3377e4fbfb6586ce7))
60
- * **swingset-liveslots:** copy helper files to new liveslots package ([be7229f](https://github.com/Agoric/agoric-sdk/commit/be7229f7217c1ecc523069a57945a372f4a1e00e))
61
- * **swingset-liveslots:** update imports of helper files ([0b4b38a](https://github.com/Agoric/agoric-sdk/commit/0b4b38a1f9efbb3e1e860172b0b802548d18ae2e))
package/test/kmarshal.js DELETED
@@ -1,79 +0,0 @@
1
- import { Far, makeMarshal, passStyleOf } from '@endo/marshal';
2
- import { assert } from '@agoric/assert';
3
-
4
- // Simple wrapper for serializing and unserializing marshalled values inside the
5
- // kernel, where we don't actually want to use clists nor actually allocate real
6
- // objects, but instead to stay entirely within the domain of krefs. This is
7
- // used to enable syntactic manipulation of serialized values while remaining
8
- // agnostic about the internal details of the serialization encoding.
9
-
10
- const refMap = new WeakMap();
11
-
12
- export const kslot = (kref, iface) => {
13
- assert.typeof(kref, 'string');
14
- if (iface && iface.startsWith('Alleged: ')) {
15
- // Encoder prepends "Alleged: " to iface string, but the decoder doesn't strip it
16
- // Unclear whether it's the decoder or me who is wrong
17
- iface = iface.slice(9);
18
- }
19
- if (
20
- kref.startsWith('p') ||
21
- kref.startsWith('kp') ||
22
- kref.startsWith('lp') ||
23
- kref.startsWith('rp')
24
- ) {
25
- // TODO: temporary hack because smallcaps encodes promise references
26
- // differently from remotable object references, and the current version of
27
- // the smallcaps decoder annoyingly insists that if the encoded body string
28
- // says a slot is a promise, then convertSlotToVal had better by damn return
29
- // an actual Promise, even if, as in the intended use case here, we neither
30
- // want nor need a promise, nor the overhead of a map to keep track of it
31
- // with. This behavior is in service of defense against a hypothesized
32
- // security issue whose exact nature has largely been forgotton in the
33
- // months since it was first encountered. MarkM is currently researching
34
- // what the problem was thought to have been, to see if it is real and to
35
- // understand it if so. This will eventually result in either changes to
36
- // the smallcaps encoding or to the marshal setup API to support the purely
37
- // manipulative use case. In the meantime, this ugliness...
38
- const p = new Promise(() => undefined);
39
- refMap.set(p, kref);
40
- return harden(p);
41
- } else {
42
- const o = Far(iface, {
43
- iface: () => iface,
44
- getKref: () => `${kref}`,
45
- });
46
- return o;
47
- }
48
- };
49
-
50
- export const krefOf = obj => {
51
- const fromMap = refMap.get(obj);
52
- if (fromMap) {
53
- return fromMap;
54
- }
55
- // When krefOf() is called as part of kmarshal.serialize, marshal
56
- // will only give it things that are 'remotable' (Promises and the
57
- // Far objects created by kslot()). When krefOf() is called by
58
- // kernel code (as part of extractSingleSlot() or the vat-comms
59
- // equivalent), it ought to throw if 'obj' is not one of the Far
60
- // objects created by our kslot().
61
- assert.equal(passStyleOf(obj), 'remotable', obj);
62
- const getKref = obj.getKref;
63
- assert.typeof(getKref, 'function');
64
- return getKref();
65
- };
66
-
67
- const kmarshal = makeMarshal(krefOf, kslot, {
68
- serializeBodyFormat: 'smallcaps',
69
- errorTagging: 'off',
70
- });
71
-
72
- export const kser = value => kmarshal.serialize(harden(value));
73
-
74
- export const kunser = serializedValue => kmarshal.unserialize(serializedValue);
75
-
76
- export function makeError(message) {
77
- assert.typeof(message, 'string');
78
- return kser(Error(message));
79
- }