@agoric/async-flow 0.1.1-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.
Files changed (58) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/LICENSE +201 -0
  3. package/README.md +40 -0
  4. package/docs/async-flow-states.key +0 -0
  5. package/docs/async-flow-states.md +15 -0
  6. package/docs/async-flow-states.png +0 -0
  7. package/index.d.ts +3 -0
  8. package/index.d.ts.map +1 -0
  9. package/index.js +2 -0
  10. package/package.json +66 -0
  11. package/src/async-flow.d.ts +94 -0
  12. package/src/async-flow.d.ts.map +1 -0
  13. package/src/async-flow.js +520 -0
  14. package/src/bijection.d.ts +31 -0
  15. package/src/bijection.d.ts.map +1 -0
  16. package/src/bijection.js +207 -0
  17. package/src/convert.d.ts +6 -0
  18. package/src/convert.d.ts.map +1 -0
  19. package/src/convert.js +133 -0
  20. package/src/endowments.d.ts +16 -0
  21. package/src/endowments.d.ts.map +1 -0
  22. package/src/endowments.js +292 -0
  23. package/src/ephemera.d.ts +3 -0
  24. package/src/ephemera.d.ts.map +1 -0
  25. package/src/ephemera.js +39 -0
  26. package/src/equate.d.ts +2 -0
  27. package/src/equate.d.ts.map +1 -0
  28. package/src/equate.js +123 -0
  29. package/src/log-store.d.ts +27 -0
  30. package/src/log-store.d.ts.map +1 -0
  31. package/src/log-store.js +169 -0
  32. package/src/replay-membrane.d.ts +40 -0
  33. package/src/replay-membrane.d.ts.map +1 -0
  34. package/src/replay-membrane.js +752 -0
  35. package/src/type-guards.d.ts +4 -0
  36. package/src/type-guards.d.ts.map +1 -0
  37. package/src/type-guards.js +68 -0
  38. package/src/types.d.ts +67 -0
  39. package/src/types.d.ts.map +1 -0
  40. package/src/types.js +196 -0
  41. package/test/async-flow-crank.test.js +102 -0
  42. package/test/async-flow-early-completion.test.js +203 -0
  43. package/test/async-flow-no-this.js +65 -0
  44. package/test/async-flow.test.js +383 -0
  45. package/test/bad-host.test.js +210 -0
  46. package/test/bijection.test.js +124 -0
  47. package/test/convert.test.js +132 -0
  48. package/test/endowments.test.js +157 -0
  49. package/test/equate.test.js +120 -0
  50. package/test/log-store.test.js +120 -0
  51. package/test/prepare-test-env-ava.js +28 -0
  52. package/test/replay-membrane-eventual.test.js +217 -0
  53. package/test/replay-membrane-settlement.test.js +173 -0
  54. package/test/replay-membrane-zombie.test.js +187 -0
  55. package/test/replay-membrane.test.js +297 -0
  56. package/tsconfig.build.json +11 -0
  57. package/tsconfig.json +13 -0
  58. package/typedoc.json +8 -0
@@ -0,0 +1,217 @@
1
+ // eslint-disable-next-line import/order
2
+ import {
3
+ test,
4
+ getBaggage,
5
+ annihilate,
6
+ nextLife,
7
+ } from './prepare-test-env-ava.js';
8
+
9
+ import { Fail } from '@endo/errors';
10
+ import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
11
+ import { prepareVowTools } from '@agoric/vow';
12
+ import { E } from '@endo/eventual-send';
13
+ // import E from '@agoric/vow/src/E.js';
14
+ import { makeHeapZone } from '@agoric/zone/heap.js';
15
+ import { makeVirtualZone } from '@agoric/zone/virtual.js';
16
+ import { makeDurableZone } from '@agoric/zone/durable.js';
17
+
18
+ import { prepareLogStore } from '../src/log-store.js';
19
+ import { prepareBijection } from '../src/bijection.js';
20
+ import { makeReplayMembrane } from '../src/replay-membrane.js';
21
+
22
+ /**
23
+ * @import {PromiseKit} from '@endo/promise-kit'
24
+ * @import {Zone} from '@agoric/base-zone'
25
+ * @import {LogStore} from '../src/log-store.js';
26
+ * @import {Bijection} from '../src/bijection.js';
27
+ */
28
+
29
+ const watchWake = _vowish => {};
30
+ const panic = problem => Fail`panic over ${problem}`;
31
+
32
+ /**
33
+ * @param {Zone} zone
34
+ */
35
+ const preparePingee = zone =>
36
+ zone.exoClass('Pingee', undefined, () => ({}), {
37
+ ping(_str) {},
38
+ });
39
+
40
+ /**
41
+ * @typedef {ReturnType<ReturnType<preparePingee>>} Pingee
42
+ */
43
+
44
+ /**
45
+ * @param {any} t
46
+ * @param {Zone} zone
47
+ */
48
+ const testFirstPlay = async (t, zone) => {
49
+ const vowTools = prepareVowTools(zone);
50
+ const { makeVowKit } = vowTools;
51
+ const makeLogStore = prepareLogStore(zone);
52
+ const makeBijection = prepareBijection(zone);
53
+ const makePingee = preparePingee(zone);
54
+ const { vow: v1, resolver: r1 } = zone.makeOnce('v1', () => makeVowKit());
55
+ const { vow: _v2, resolver: _r2 } = zone.makeOnce('v2', () => makeVowKit());
56
+
57
+ const log = zone.makeOnce('log', () => makeLogStore());
58
+ const bijection = zone.makeOnce('bij', makeBijection);
59
+
60
+ const mem = makeReplayMembrane({
61
+ log,
62
+ bijection,
63
+ vowTools,
64
+ watchWake,
65
+ panic,
66
+ });
67
+
68
+ const p1 = mem.hostToGuest(v1);
69
+ t.deepEqual(log.dump(), []);
70
+
71
+ /** @type {Pingee} */
72
+ const pingee = zone.makeOnce('pingee', () => makePingee());
73
+ /** @type {Pingee} */
74
+ const guestPingee = mem.hostToGuest(pingee);
75
+ t.deepEqual(log.dump(), []);
76
+
77
+ const p = E(guestPingee).ping('send');
78
+ const pOnly = E.sendOnly(guestPingee).ping('sendOnly');
79
+ t.is(pOnly, undefined);
80
+
81
+ guestPingee.ping('call');
82
+
83
+ t.is(await p, undefined);
84
+ const dump = log.dump();
85
+ const v3 = dump[3][2];
86
+ t.deepEqual(dump, [
87
+ ['checkCall', pingee, 'ping', ['call'], 0],
88
+ ['doReturn', 0, undefined],
89
+ ['checkSend', pingee, 'ping', ['send'], 2],
90
+ ['doReturn', 2, v3],
91
+ ['checkSendOnly', pingee, 'ping', ['sendOnly'], 4],
92
+ ['doFulfill', v3, undefined],
93
+ ]);
94
+
95
+ r1.resolve('x');
96
+ t.is(await p1, 'x');
97
+
98
+ t.deepEqual(log.dump(), [
99
+ ['checkCall', pingee, 'ping', ['call'], 0],
100
+ ['doReturn', 0, undefined],
101
+ ['checkSend', pingee, 'ping', ['send'], 2],
102
+ ['doReturn', 2, v3],
103
+ ['checkSendOnly', pingee, 'ping', ['sendOnly'], 4],
104
+ ['doFulfill', v3, undefined],
105
+ ['doFulfill', v1, 'x'],
106
+ ]);
107
+ };
108
+
109
+ /**
110
+ * @param {any} t
111
+ * @param {Zone} zone
112
+ */
113
+ const testReplay = async (t, zone) => {
114
+ const vowTools = prepareVowTools(zone);
115
+ prepareLogStore(zone);
116
+ prepareBijection(zone);
117
+ preparePingee(zone);
118
+ const { vow: v1 } = zone.makeOnce('v1', () => Fail`need v1`);
119
+ const { vow: v2, resolver: r2 } = zone.makeOnce('v2', () => Fail`need v2`);
120
+
121
+ const log = /** @type {LogStore} */ (
122
+ zone.makeOnce('log', () => Fail`need log`)
123
+ );
124
+ const bijection = /** @type {Bijection} */ (
125
+ zone.makeOnce('bij', () => Fail`need bij`)
126
+ );
127
+
128
+ const pingee = zone.makeOnce('pingee', () => Fail`need pingee`);
129
+
130
+ const dump = log.dump();
131
+ const v3 = dump[3][2];
132
+ t.deepEqual(dump, [
133
+ ['checkCall', pingee, 'ping', ['call'], 0],
134
+ ['doReturn', 0, undefined],
135
+ ['checkSend', pingee, 'ping', ['send'], 2],
136
+ ['doReturn', 2, v3],
137
+ ['checkSendOnly', pingee, 'ping', ['sendOnly'], 4],
138
+ ['doFulfill', v3, undefined],
139
+ ['doFulfill', v1, 'x'],
140
+ ]);
141
+
142
+ const mem = makeReplayMembrane({
143
+ log,
144
+ bijection,
145
+ vowTools,
146
+ watchWake,
147
+ panic,
148
+ });
149
+ t.true(log.isReplaying());
150
+ t.is(log.getIndex(), 0);
151
+
152
+ const guestPingee = mem.hostToGuest(pingee);
153
+ const p2 = mem.hostToGuest(v2);
154
+ // @ts-expect-error TS doesn't know that r2 is a resolver
155
+ r2.resolve('y');
156
+ await eventLoopIteration();
157
+
158
+ const p1 = mem.hostToGuest(v1);
159
+ mem.wake();
160
+ t.true(log.isReplaying());
161
+ t.is(log.getIndex(), 0);
162
+ t.deepEqual(log.dump(), [
163
+ ['checkCall', pingee, 'ping', ['call'], 0],
164
+ ['doReturn', 0, undefined],
165
+ ['checkSend', pingee, 'ping', ['send'], 2],
166
+ ['doReturn', 2, v3],
167
+ ['checkSendOnly', pingee, 'ping', ['sendOnly'], 4],
168
+ ['doFulfill', v3, undefined],
169
+ ['doFulfill', v1, 'x'],
170
+ ]);
171
+
172
+ E(guestPingee).ping('send');
173
+ // TODO Once https://github.com/endojs/endo/issues/2336 is fixed,
174
+ // the following `void` should not be needed. But strangely, TS isn't
175
+ // telling me a `void` is needed above, which is also incorrect.
176
+ void E.sendOnly(guestPingee).ping('sendOnly');
177
+
178
+ guestPingee.ping('call');
179
+
180
+ t.is(await p1, 'x');
181
+ t.is(await p2, 'y');
182
+ t.false(log.isReplaying());
183
+
184
+ t.deepEqual(log.dump(), [
185
+ ['checkCall', pingee, 'ping', ['call'], 0],
186
+ ['doReturn', 0, undefined],
187
+ ['checkSend', pingee, 'ping', ['send'], 2],
188
+ ['doReturn', 2, v3],
189
+ ['checkSendOnly', pingee, 'ping', ['sendOnly'], 4],
190
+ ['doFulfill', v3, undefined],
191
+ ['doFulfill', v1, 'x'],
192
+ ['doFulfill', v2, 'y'],
193
+ ]);
194
+ };
195
+
196
+ test.serial('test heap replay-membrane settlement', async t => {
197
+ const zone = makeHeapZone('heapRoot');
198
+ return testFirstPlay(t, zone);
199
+ });
200
+
201
+ test.serial('test virtual replay-membrane settlement', async t => {
202
+ annihilate();
203
+ const zone = makeVirtualZone('virtualRoot');
204
+ return testFirstPlay(t, zone);
205
+ });
206
+
207
+ test.serial('test durable replay-membrane settlement', async t => {
208
+ annihilate();
209
+
210
+ nextLife();
211
+ const zone1 = makeDurableZone(getBaggage(), 'durableRoot');
212
+ await testFirstPlay(t, zone1);
213
+
214
+ nextLife();
215
+ const zone3 = makeDurableZone(getBaggage(), 'durableRoot');
216
+ return testReplay(t, zone3);
217
+ });
@@ -0,0 +1,173 @@
1
+ // eslint-disable-next-line import/order
2
+ import {
3
+ test,
4
+ getBaggage,
5
+ annihilate,
6
+ nextLife,
7
+ } from './prepare-test-env-ava.js';
8
+
9
+ import { Fail } from '@endo/errors';
10
+ import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
11
+ import { prepareVowTools } from '@agoric/vow';
12
+ import { makeHeapZone } from '@agoric/zone/heap.js';
13
+ import { makeVirtualZone } from '@agoric/zone/virtual.js';
14
+ import { makeDurableZone } from '@agoric/zone/durable.js';
15
+
16
+ import { prepareLogStore } from '../src/log-store.js';
17
+ import { prepareBijection } from '../src/bijection.js';
18
+ import { makeReplayMembrane } from '../src/replay-membrane.js';
19
+
20
+ /**
21
+ * @import {PromiseKit} from '@endo/promise-kit'
22
+ * @import {Zone} from '@agoric/base-zone'
23
+ * @import {LogStore} from '../src/log-store.js';
24
+ * @import {Bijection} from '../src/bijection.js';
25
+ */
26
+
27
+ const watchWake = _vowish => {};
28
+ const panic = problem => Fail`panic over ${problem}`;
29
+
30
+ /**
31
+ * @param {Zone} zone
32
+ */
33
+ const preparePingee = zone =>
34
+ zone.exoClass('Pingee', undefined, () => ({}), {
35
+ ping() {},
36
+ });
37
+
38
+ /**
39
+ * @param {any} t
40
+ * @param {Zone} zone
41
+ */
42
+ const testFirstPlay = async (t, zone) => {
43
+ const vowTools = prepareVowTools(zone);
44
+ const { makeVowKit } = vowTools;
45
+ const makeLogStore = prepareLogStore(zone);
46
+ const makeBijection = prepareBijection(zone);
47
+ const makePingee = preparePingee(zone);
48
+ const { vow: v1, resolver: r1 } = zone.makeOnce('v1', () => makeVowKit());
49
+ const { vow: _v2, resolver: _r2 } = zone.makeOnce('v2', () => makeVowKit());
50
+
51
+ const log = zone.makeOnce('log', () => makeLogStore());
52
+ const bijection = zone.makeOnce('bij', makeBijection);
53
+
54
+ const mem = makeReplayMembrane({
55
+ log,
56
+ bijection,
57
+ vowTools,
58
+ watchWake,
59
+ panic,
60
+ });
61
+
62
+ const p1 = mem.hostToGuest(v1);
63
+ t.deepEqual(log.dump(), []);
64
+
65
+ const pingee = zone.makeOnce('pingee', () => makePingee());
66
+ const guestPingee = mem.hostToGuest(pingee);
67
+ t.deepEqual(log.dump(), []);
68
+
69
+ guestPingee.ping();
70
+ t.deepEqual(log.dump(), [
71
+ // keep on separate lines
72
+ ['checkCall', pingee, 'ping', [], 0],
73
+ ['doReturn', 0, undefined],
74
+ ]);
75
+
76
+ r1.resolve('x');
77
+ t.is(await p1, 'x');
78
+
79
+ t.deepEqual(log.dump(), [
80
+ ['checkCall', pingee, 'ping', [], 0],
81
+ ['doReturn', 0, undefined],
82
+ ['doFulfill', v1, 'x'],
83
+ ]);
84
+ };
85
+
86
+ /**
87
+ * @param {any} t
88
+ * @param {Zone} zone
89
+ */
90
+ const testReplay = async (t, zone) => {
91
+ const vowTools = prepareVowTools(zone);
92
+ prepareLogStore(zone);
93
+ prepareBijection(zone);
94
+ preparePingee(zone);
95
+ const { vow: v1 } = zone.makeOnce('v1', () => Fail`need v1`);
96
+ const { vow: v2, resolver: r2 } = zone.makeOnce('v2', () => Fail`need v2`);
97
+
98
+ const log = /** @type {LogStore} */ (
99
+ zone.makeOnce('log', () => Fail`need log`)
100
+ );
101
+ const bijection = /** @type {Bijection} */ (
102
+ zone.makeOnce('bij', () => Fail`need bij`)
103
+ );
104
+
105
+ const pingee = zone.makeOnce('pingee', () => Fail`need pingee`);
106
+
107
+ t.deepEqual(log.dump(), [
108
+ ['checkCall', pingee, 'ping', [], 0],
109
+ ['doReturn', 0, undefined],
110
+ ['doFulfill', v1, 'x'],
111
+ ]);
112
+
113
+ const mem = makeReplayMembrane({
114
+ log,
115
+ bijection,
116
+ vowTools,
117
+ watchWake,
118
+ panic,
119
+ });
120
+ t.true(log.isReplaying());
121
+ t.is(log.getIndex(), 0);
122
+
123
+ const guestPingee = mem.hostToGuest(pingee);
124
+ const p2 = mem.hostToGuest(v2);
125
+ // @ts-expect-error TS doesn't know that r2 is a resolver
126
+ r2.resolve('y');
127
+ await eventLoopIteration();
128
+
129
+ const p1 = mem.hostToGuest(v1);
130
+ mem.wake();
131
+ t.true(log.isReplaying());
132
+ t.is(log.getIndex(), 0);
133
+ t.deepEqual(log.dump(), [
134
+ ['checkCall', pingee, 'ping', [], 0],
135
+ ['doReturn', 0, undefined],
136
+ ['doFulfill', v1, 'x'],
137
+ ]);
138
+
139
+ guestPingee.ping();
140
+ t.is(await p1, 'x');
141
+ t.is(await p2, 'y');
142
+ t.false(log.isReplaying());
143
+
144
+ t.deepEqual(log.dump(), [
145
+ ['checkCall', pingee, 'ping', [], 0],
146
+ ['doReturn', 0, undefined],
147
+ ['doFulfill', v1, 'x'],
148
+ ['doFulfill', v2, 'y'],
149
+ ]);
150
+ };
151
+
152
+ test.serial('test heap replay-membrane settlement', async t => {
153
+ const zone = makeHeapZone('heapRoot');
154
+ return testFirstPlay(t, zone);
155
+ });
156
+
157
+ test.serial('test virtual replay-membrane settlement', async t => {
158
+ annihilate();
159
+ const zone = makeVirtualZone('virtualRoot');
160
+ return testFirstPlay(t, zone);
161
+ });
162
+
163
+ test.serial('test durable replay-membrane settlement', async t => {
164
+ annihilate();
165
+
166
+ nextLife();
167
+ const zone1 = makeDurableZone(getBaggage(), 'durableRoot');
168
+ await testFirstPlay(t, zone1);
169
+
170
+ nextLife();
171
+ const zone3 = makeDurableZone(getBaggage(), 'durableRoot');
172
+ return testReplay(t, zone3);
173
+ });
@@ -0,0 +1,187 @@
1
+ // eslint-disable-next-line import/order
2
+ import {
3
+ test,
4
+ getBaggage,
5
+ annihilate,
6
+ nextLife,
7
+ } from './prepare-test-env-ava.js';
8
+
9
+ import { Fail } from '@endo/errors';
10
+ import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js';
11
+ import { prepareVowTools } from '@agoric/vow';
12
+ import { makeHeapZone } from '@agoric/zone/heap.js';
13
+ import { makeVirtualZone } from '@agoric/zone/virtual.js';
14
+ import { makeDurableZone } from '@agoric/zone/durable.js';
15
+
16
+ import { prepareLogStore } from '../src/log-store.js';
17
+ import { prepareBijection } from '../src/bijection.js';
18
+ import { makeReplayMembrane } from '../src/replay-membrane.js';
19
+
20
+ /**
21
+ * @import {PromiseKit} from '@endo/promise-kit'
22
+ * @import {Zone} from '@agoric/base-zone'
23
+ */
24
+
25
+ const watchWake = _vowish => {};
26
+ const panic = problem => Fail`panic over ${problem}`;
27
+
28
+ /**
29
+ * @param {any} t
30
+ * @param {Zone} zone
31
+ */
32
+ const testMissingStop = async (t, zone) => {
33
+ const vowTools = prepareVowTools(zone);
34
+ const { makeVowKit } = vowTools;
35
+ const makeLogStore = prepareLogStore(zone);
36
+ const makeBijection = prepareBijection(zone);
37
+
38
+ const log = makeLogStore();
39
+ const bijection = makeBijection();
40
+
41
+ const memA = makeReplayMembrane({
42
+ log,
43
+ bijection,
44
+ vowTools,
45
+ watchWake,
46
+ panic,
47
+ });
48
+
49
+ const { vow: v1, resolver: r1 } = makeVowKit();
50
+
51
+ const p1A = memA.hostToGuest(v1);
52
+ t.true(bijection.has(p1A, v1));
53
+
54
+ await eventLoopIteration();
55
+
56
+ t.deepEqual(log.dump(), []);
57
+
58
+ // do all the steps to drop an old membrane and set up a new membrane,
59
+ // except stopping the old membrane,
60
+ // to demonstate why `makeGuestForHostVow` also tests`stopped`.
61
+ log.reset();
62
+ bijection.reset();
63
+ const memB = makeReplayMembrane({
64
+ log,
65
+ bijection,
66
+ vowTools,
67
+ watchWake,
68
+ panic,
69
+ });
70
+
71
+ const p1B = memB.hostToGuest(v1);
72
+ t.true(bijection.has(p1B, v1));
73
+ t.false(bijection.hasGuest(p1A));
74
+
75
+ await eventLoopIteration();
76
+
77
+ t.deepEqual(log.dump(), []);
78
+
79
+ r1.resolve('x');
80
+
81
+ await eventLoopIteration();
82
+
83
+ t.deepEqual(log.dump(), [
84
+ // keep line break
85
+ ['doFulfill', v1, 'x'],
86
+ ['doFulfill', v1, 'x'], // this duplication is wrong, is the point
87
+ ]);
88
+ };
89
+
90
+ /**
91
+ * @param {any} t
92
+ * @param {Zone} zone
93
+ */
94
+ const testProperStop = async (t, zone) => {
95
+ const vowTools = prepareVowTools(zone);
96
+ const { makeVowKit } = vowTools;
97
+ const makeLogStore = prepareLogStore(zone);
98
+ const makeBijection = prepareBijection(zone);
99
+
100
+ const log = makeLogStore();
101
+ const bijection = makeBijection();
102
+
103
+ const memA = makeReplayMembrane({
104
+ log,
105
+ bijection,
106
+ vowTools,
107
+ watchWake,
108
+ panic,
109
+ });
110
+
111
+ const { vow: v1, resolver: r1 } = makeVowKit();
112
+
113
+ const p1A = memA.hostToGuest(v1);
114
+ t.true(bijection.has(p1A, v1));
115
+
116
+ await eventLoopIteration();
117
+
118
+ t.deepEqual(log.dump(), []);
119
+
120
+ // do all the steps to drop an old membrane and set up a new membrane,
121
+ // including stopping the old membrane,
122
+ // to demonstate why `makeGuestForHostVow` also tests`stopped`.
123
+ log.reset();
124
+ bijection.reset();
125
+ memA.stop(); // the point
126
+ const memB = makeReplayMembrane({
127
+ log,
128
+ bijection,
129
+ vowTools,
130
+ watchWake,
131
+ panic,
132
+ });
133
+
134
+ const p1B = memB.hostToGuest(v1);
135
+ t.true(bijection.has(p1B, v1));
136
+ t.false(bijection.hasGuest(p1A));
137
+
138
+ await eventLoopIteration();
139
+
140
+ t.deepEqual(log.dump(), []);
141
+
142
+ r1.resolve('x');
143
+
144
+ await eventLoopIteration();
145
+
146
+ t.deepEqual(log.dump(), [
147
+ // keep line break
148
+ ['doFulfill', v1, 'x'],
149
+ ]);
150
+ };
151
+
152
+ test.serial('test heap replay-membrane missing stop', async t => {
153
+ const zone = makeHeapZone('heapRoot');
154
+ return testMissingStop(t, zone);
155
+ });
156
+
157
+ test.serial('test heap replay-membrane proper stop', async t => {
158
+ annihilate();
159
+ const zone = makeHeapZone('heapRoot');
160
+ return testProperStop(t, zone);
161
+ });
162
+
163
+ test.serial('test virtual replay-membrane missing stop', async t => {
164
+ annihilate();
165
+ const zone = makeVirtualZone('virtualRoot');
166
+ return testMissingStop(t, zone);
167
+ });
168
+
169
+ test.serial('test virtual replay-membrane proper stop', async t => {
170
+ annihilate();
171
+ const zone = makeVirtualZone('virtualRoot');
172
+ return testProperStop(t, zone);
173
+ });
174
+
175
+ test.serial('test durable replay-membrane missing stop', async t => {
176
+ annihilate();
177
+ nextLife();
178
+ const zone = makeDurableZone(getBaggage(), 'durableRoot');
179
+ return testMissingStop(t, zone);
180
+ });
181
+
182
+ test.serial('test durable replay-membrane proper stop', async t => {
183
+ annihilate();
184
+ nextLife();
185
+ const zone = makeDurableZone(getBaggage(), 'durableRoot');
186
+ return testProperStop(t, zone);
187
+ });