rivetkit 2.1.2 → 2.1.3
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/dist/browser/client.js +1 -1
- package/dist/browser/client.js.map +1 -1
- package/dist/browser/inspector/client.js +1 -1
- package/dist/browser/inspector/client.js.map +1 -1
- package/dist/inspector.tar.gz +0 -0
- package/dist/tsup/{chunk-NXEHFUDB.cjs → chunk-5AZ6UPEF.cjs} +24 -21
- package/dist/tsup/chunk-5AZ6UPEF.cjs.map +1 -0
- package/dist/tsup/{chunk-YQ5P6KMN.js → chunk-6LHZQSWJ.js} +8 -5
- package/dist/tsup/{chunk-YQ5P6KMN.js.map → chunk-6LHZQSWJ.js.map} +1 -1
- package/dist/tsup/{chunk-BFI4LYS2.js → chunk-6T3WSP5M.js} +4 -4
- package/dist/tsup/{chunk-772NPMTY.cjs → chunk-BMNB6YRQ.cjs} +160 -103
- package/dist/tsup/chunk-BMNB6YRQ.cjs.map +1 -0
- package/dist/tsup/{chunk-GVQAVU7R.cjs → chunk-DADGS67O.cjs} +4 -4
- package/dist/tsup/{chunk-GVQAVU7R.cjs.map → chunk-DADGS67O.cjs.map} +1 -1
- package/dist/tsup/{chunk-RHUII57M.js → chunk-GNGRMP5E.js} +10 -6
- package/dist/tsup/chunk-GNGRMP5E.js.map +1 -0
- package/dist/tsup/{chunk-PZAV6PP2.cjs → chunk-HPAX7L72.cjs} +152 -152
- package/dist/tsup/{chunk-PZAV6PP2.cjs.map → chunk-HPAX7L72.cjs.map} +1 -1
- package/dist/tsup/{chunk-UZV7NXC6.cjs → chunk-IJAGZS57.cjs} +30 -30
- package/dist/tsup/{chunk-UZV7NXC6.cjs.map → chunk-IJAGZS57.cjs.map} +1 -1
- package/dist/tsup/{chunk-HFWRHT5T.cjs → chunk-KSZZRTOD.cjs} +3 -3
- package/dist/tsup/{chunk-HFWRHT5T.cjs.map → chunk-KSZZRTOD.cjs.map} +1 -1
- package/dist/tsup/{chunk-PSUVV4HM.js → chunk-MAXIXG56.js} +2 -2
- package/dist/tsup/{chunk-HB4RGGMC.js → chunk-N7ASEZ2Y.js} +5 -5
- package/dist/tsup/{chunk-PW3YONDJ.js → chunk-OAOF23ZY.js} +2 -2
- package/dist/tsup/{chunk-TDFDR7AO.js → chunk-POUBQA6Z.js} +2 -2
- package/dist/tsup/{chunk-VMX4I4MP.js → chunk-QUDLEWGD.js} +3 -3
- package/dist/tsup/{chunk-MNS5LY6M.cjs → chunk-R64EFI6F.cjs} +74 -74
- package/dist/tsup/{chunk-MNS5LY6M.cjs.map → chunk-R64EFI6F.cjs.map} +1 -1
- package/dist/tsup/{chunk-QABDKI3W.cjs → chunk-T6MM5RTW.cjs} +248 -244
- package/dist/tsup/chunk-T6MM5RTW.cjs.map +1 -0
- package/dist/tsup/{chunk-ZHQDRRMY.cjs → chunk-U6VWVHVW.cjs} +3 -3
- package/dist/tsup/{chunk-ZHQDRRMY.cjs.map → chunk-U6VWVHVW.cjs.map} +1 -1
- package/dist/tsup/{chunk-WUXR722E.js → chunk-YET3IZD6.js} +2 -2
- package/dist/tsup/{chunk-WUXR722E.js.map → chunk-YET3IZD6.js.map} +1 -1
- package/dist/tsup/{chunk-BSIJG3LG.js → chunk-YLDDENCZ.js} +69 -12
- package/dist/tsup/chunk-YLDDENCZ.js.map +1 -0
- package/dist/tsup/{chunk-RMJJE43B.cjs → chunk-ZSJ2OTY4.cjs} +2 -2
- package/dist/tsup/{chunk-RMJJE43B.cjs.map → chunk-ZSJ2OTY4.cjs.map} +1 -1
- package/dist/tsup/client/mod.cjs +6 -6
- package/dist/tsup/client/mod.js +5 -5
- package/dist/tsup/common/log.cjs +2 -2
- package/dist/tsup/common/log.js +1 -1
- package/dist/tsup/common/websocket.cjs +3 -3
- package/dist/tsup/common/websocket.js +2 -2
- package/dist/tsup/driver-helpers/mod.cjs +4 -4
- package/dist/tsup/driver-helpers/mod.js +3 -3
- package/dist/tsup/driver-test-suite/mod.cjs +425 -338
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.js +376 -289
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +3 -3
- package/dist/tsup/inspector/mod.js +2 -2
- package/dist/tsup/mod.cjs +8 -8
- package/dist/tsup/mod.js +7 -7
- package/dist/tsup/serve-test-suite/mod.cjs +111 -99
- package/dist/tsup/serve-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/serve-test-suite/mod.js +22 -10
- package/dist/tsup/serve-test-suite/mod.js.map +1 -1
- package/dist/tsup/test/mod.cjs +10 -10
- package/dist/tsup/test/mod.js +6 -6
- package/dist/tsup/utils.cjs +2 -2
- package/dist/tsup/utils.js +1 -1
- package/dist/tsup/workflow/mod.cjs +5 -5
- package/dist/tsup/workflow/mod.js +4 -4
- package/package.json +5 -5
- package/src/actor/instance/mod.ts +13 -2
- package/src/driver-test-suite/tests/actor-db.ts +299 -216
- package/src/driver-test-suite/tests/actor-queue.ts +10 -9
- package/src/driver-test-suite/tests/actor-workflow.ts +12 -2
- package/src/driver-test-suite/utils.ts +8 -8
- package/src/drivers/engine/actor-driver.ts +77 -7
- package/src/workflow/driver.ts +4 -1
- package/dist/tsup/chunk-772NPMTY.cjs.map +0 -1
- package/dist/tsup/chunk-BSIJG3LG.js.map +0 -1
- package/dist/tsup/chunk-NXEHFUDB.cjs.map +0 -1
- package/dist/tsup/chunk-QABDKI3W.cjs.map +0 -1
- package/dist/tsup/chunk-RHUII57M.js.map +0 -1
- /package/dist/tsup/{chunk-BFI4LYS2.js.map → chunk-6T3WSP5M.js.map} +0 -0
- /package/dist/tsup/{chunk-PSUVV4HM.js.map → chunk-MAXIXG56.js.map} +0 -0
- /package/dist/tsup/{chunk-HB4RGGMC.js.map → chunk-N7ASEZ2Y.js.map} +0 -0
- /package/dist/tsup/{chunk-PW3YONDJ.js.map → chunk-OAOF23ZY.js.map} +0 -0
- /package/dist/tsup/{chunk-TDFDR7AO.js.map → chunk-POUBQA6Z.js.map} +0 -0
- /package/dist/tsup/{chunk-VMX4I4MP.js.map → chunk-QUDLEWGD.js.map} +0 -0
|
@@ -10,6 +10,7 @@ const HIGH_VOLUME_COUNT = 1000;
|
|
|
10
10
|
const SLEEP_WAIT_MS = 150;
|
|
11
11
|
const LIFECYCLE_POLL_INTERVAL_MS = 25;
|
|
12
12
|
const LIFECYCLE_POLL_ATTEMPTS = 40;
|
|
13
|
+
const REAL_TIMER_DB_TIMEOUT_MS = 180_000;
|
|
13
14
|
const CHUNK_BOUNDARY_SIZES = [
|
|
14
15
|
CHUNK_SIZE - 1,
|
|
15
16
|
CHUNK_SIZE,
|
|
@@ -39,214 +40,280 @@ function getDbActor(
|
|
|
39
40
|
|
|
40
41
|
export function runActorDbTests(driverTestConfig: DriverTestConfig) {
|
|
41
42
|
const variants: DbVariant[] = ["raw", "drizzle"];
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
const dbTestTimeout = driverTestConfig.useRealTimers
|
|
44
|
+
? REAL_TIMER_DB_TIMEOUT_MS
|
|
45
|
+
: undefined;
|
|
46
|
+
const lifecycleTestTimeout = driverTestConfig.useRealTimers
|
|
47
|
+
? REAL_TIMER_DB_TIMEOUT_MS
|
|
48
|
+
: undefined;
|
|
49
|
+
|
|
50
|
+
for (const variant of variants) {
|
|
44
51
|
describe(`Actor Database (${variant}) Tests`, () => {
|
|
45
|
-
test(
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const actor = getDbActor(client, variant).getOrCreate([
|
|
89
|
-
`db-${variant}-tx-${crypto.randomUUID()}`,
|
|
90
|
-
]);
|
|
91
|
-
|
|
92
|
-
await actor.reset();
|
|
93
|
-
await actor.transactionCommit("commit");
|
|
94
|
-
expect(await actor.getCount()).toBe(1);
|
|
95
|
-
|
|
96
|
-
await actor.transactionRollback("rollback");
|
|
97
|
-
expect(await actor.getCount()).toBe(1);
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
test("persists across sleep and wake cycles", async (c) => {
|
|
101
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
102
|
-
const actor = getDbActor(client, variant).getOrCreate([
|
|
103
|
-
`db-${variant}-sleep-${crypto.randomUUID()}`,
|
|
104
|
-
]);
|
|
52
|
+
test(
|
|
53
|
+
"bootstraps schema on startup",
|
|
54
|
+
async (c) => {
|
|
55
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
56
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
57
|
+
`db-${variant}-bootstrap-${crypto.randomUUID()}`,
|
|
58
|
+
]);
|
|
59
|
+
|
|
60
|
+
const count = await actor.getCount();
|
|
61
|
+
expect(count).toBe(0);
|
|
62
|
+
},
|
|
63
|
+
dbTestTimeout,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
test(
|
|
67
|
+
"supports CRUD, raw SQL, and multi-statement exec",
|
|
68
|
+
async (c) => {
|
|
69
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
70
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
71
|
+
`db-${variant}-crud-${crypto.randomUUID()}`,
|
|
72
|
+
]);
|
|
73
|
+
|
|
74
|
+
await actor.reset();
|
|
75
|
+
|
|
76
|
+
const first = await actor.insertValue("alpha");
|
|
77
|
+
const second = await actor.insertValue("beta");
|
|
78
|
+
|
|
79
|
+
const values = await actor.getValues();
|
|
80
|
+
expect(values.length).toBeGreaterThanOrEqual(2);
|
|
81
|
+
expect(values.some((row) => row.value === "alpha")).toBeTruthy();
|
|
82
|
+
expect(values.some((row) => row.value === "beta")).toBeTruthy();
|
|
83
|
+
|
|
84
|
+
await actor.updateValue(first.id, "alpha-updated");
|
|
85
|
+
const updated = await actor.getValue(first.id);
|
|
86
|
+
expect(updated).toBe("alpha-updated");
|
|
87
|
+
|
|
88
|
+
await actor.deleteValue(second.id);
|
|
89
|
+
const count = await actor.getCount();
|
|
90
|
+
if (driverTestConfig.useRealTimers) {
|
|
91
|
+
expect(count).toBeGreaterThanOrEqual(1);
|
|
92
|
+
} else {
|
|
93
|
+
expect(count).toBe(1);
|
|
94
|
+
}
|
|
105
95
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
96
|
+
const rawCount = await actor.rawSelectCount();
|
|
97
|
+
if (driverTestConfig.useRealTimers) {
|
|
98
|
+
expect(rawCount).toBeGreaterThanOrEqual(1);
|
|
99
|
+
} else {
|
|
100
|
+
expect(rawCount).toBe(1);
|
|
101
|
+
}
|
|
109
102
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
103
|
+
const multiValue = await actor.multiStatementInsert("gamma");
|
|
104
|
+
expect(multiValue).toBe("gamma-updated");
|
|
105
|
+
},
|
|
106
|
+
dbTestTimeout,
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
test(
|
|
110
|
+
"handles transactions",
|
|
111
|
+
async (c) => {
|
|
112
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
113
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
114
|
+
`db-${variant}-tx-${crypto.randomUUID()}`,
|
|
115
|
+
]);
|
|
116
|
+
|
|
117
|
+
await actor.reset();
|
|
118
|
+
await actor.transactionCommit("commit");
|
|
113
119
|
expect(await actor.getCount()).toBe(1);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
test("completes onDisconnect DB writes before sleeping", async (c) => {
|
|
118
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
119
|
-
const key = `db-${variant}-disconnect-${crypto.randomUUID()}`;
|
|
120
|
-
|
|
121
|
-
const actor = getDbActor(client, variant).getOrCreate([key]);
|
|
122
|
-
await actor.reset();
|
|
123
|
-
await actor.configureDisconnectInsert(true, 250);
|
|
124
|
-
|
|
125
|
-
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 250);
|
|
126
|
-
await actor.configureDisconnectInsert(false, 0);
|
|
127
|
-
|
|
128
|
-
expect(await actor.getDisconnectInsertCount()).toBe(1);
|
|
129
|
-
});
|
|
130
120
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
121
|
+
await actor.transactionRollback("rollback");
|
|
122
|
+
expect(await actor.getCount()).toBe(1);
|
|
123
|
+
},
|
|
124
|
+
dbTestTimeout,
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
test(
|
|
128
|
+
"persists across sleep and wake cycles",
|
|
129
|
+
async (c) => {
|
|
130
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
131
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
132
|
+
`db-${variant}-sleep-${crypto.randomUUID()}`,
|
|
133
|
+
]);
|
|
134
|
+
|
|
135
|
+
await actor.reset();
|
|
136
|
+
await actor.insertValue("sleepy");
|
|
137
|
+
const baselineCount = await actor.getCount();
|
|
138
|
+
expect(baselineCount).toBeGreaterThan(0);
|
|
139
|
+
|
|
140
|
+
for (let i = 0; i < 3; i++) {
|
|
141
|
+
await actor.triggerSleep();
|
|
142
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS);
|
|
143
|
+
expect(await actor.getCount()).toBe(baselineCount);
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
dbTestTimeout,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
test(
|
|
150
|
+
"completes onDisconnect DB writes before sleeping",
|
|
151
|
+
async (c) => {
|
|
152
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
153
|
+
const key = `db-${variant}-disconnect-${crypto.randomUUID()}`;
|
|
154
|
+
|
|
155
|
+
const actor = getDbActor(client, variant).getOrCreate([key]);
|
|
156
|
+
await actor.reset();
|
|
157
|
+
await actor.configureDisconnectInsert(true, 250);
|
|
158
|
+
|
|
159
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 250);
|
|
160
|
+
await actor.configureDisconnectInsert(false, 0);
|
|
161
|
+
|
|
162
|
+
expect(await actor.getDisconnectInsertCount()).toBe(1);
|
|
163
|
+
},
|
|
164
|
+
dbTestTimeout,
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
test(
|
|
168
|
+
"handles high-volume inserts",
|
|
169
|
+
async (c) => {
|
|
170
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
171
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
172
|
+
`db-${variant}-high-volume-${crypto.randomUUID()}`,
|
|
173
|
+
]);
|
|
174
|
+
|
|
175
|
+
await actor.reset();
|
|
176
|
+
await actor.insertMany(HIGH_VOLUME_COUNT);
|
|
177
|
+
const count = await actor.getCount();
|
|
178
|
+
if (driverTestConfig.useRealTimers) {
|
|
179
|
+
expect(count).toBeGreaterThanOrEqual(HIGH_VOLUME_COUNT);
|
|
180
|
+
} else {
|
|
181
|
+
expect(count).toBe(HIGH_VOLUME_COUNT);
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
dbTestTimeout,
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
test(
|
|
188
|
+
"handles payloads across chunk boundaries",
|
|
189
|
+
async (c) => {
|
|
190
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
191
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
192
|
+
`db-${variant}-chunk-${crypto.randomUUID()}`,
|
|
193
|
+
]);
|
|
194
|
+
|
|
195
|
+
await actor.reset();
|
|
196
|
+
for (const size of CHUNK_BOUNDARY_SIZES) {
|
|
197
|
+
const { id } = await actor.insertPayloadOfSize(size);
|
|
198
|
+
const storedSize = await actor.getPayloadSize(id);
|
|
199
|
+
expect(storedSize).toBe(size);
|
|
200
|
+
}
|
|
201
|
+
},
|
|
202
|
+
dbTestTimeout,
|
|
203
|
+
);
|
|
204
|
+
|
|
205
|
+
test(
|
|
206
|
+
"handles large payloads",
|
|
207
|
+
async (c) => {
|
|
208
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
209
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
210
|
+
`db-${variant}-large-${crypto.randomUUID()}`,
|
|
211
|
+
]);
|
|
212
|
+
|
|
213
|
+
await actor.reset();
|
|
214
|
+
const { id } = await actor.insertPayloadOfSize(LARGE_PAYLOAD_SIZE);
|
|
151
215
|
const storedSize = await actor.getPayloadSize(id);
|
|
152
|
-
expect(storedSize).toBe(
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
const hotRowIds: number[] = [];
|
|
213
|
-
for (let i = 0; i < HOT_ROW_COUNT; i++) {
|
|
214
|
-
const row = await actor.insertValue(`init-${i}`);
|
|
215
|
-
hotRowIds.push(row.id);
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const updatedRows = await actor.roundRobinUpdateValues(
|
|
219
|
-
hotRowIds,
|
|
220
|
-
HOT_ROW_UPDATES,
|
|
221
|
-
);
|
|
222
|
-
expect(updatedRows).toHaveLength(HOT_ROW_COUNT);
|
|
223
|
-
for (const row of updatedRows) {
|
|
224
|
-
expect(row.value).toMatch(/^v-\d+$/);
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
test("passes integrity checks after mixed workload and sleep", async (c) => {
|
|
229
|
-
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
230
|
-
const actor = getDbActor(client, variant).getOrCreate([
|
|
231
|
-
`db-${variant}-integrity-${crypto.randomUUID()}`,
|
|
232
|
-
]);
|
|
216
|
+
expect(storedSize).toBe(LARGE_PAYLOAD_SIZE);
|
|
217
|
+
},
|
|
218
|
+
dbTestTimeout,
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
test(
|
|
222
|
+
"supports shrink and regrow workloads with vacuum",
|
|
223
|
+
async (c) => {
|
|
224
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
225
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
226
|
+
`db-${variant}-shrink-regrow-${crypto.randomUUID()}`,
|
|
227
|
+
]);
|
|
228
|
+
|
|
229
|
+
await actor.reset();
|
|
230
|
+
await actor.vacuum();
|
|
231
|
+
const baselinePages = await actor.getPageCount();
|
|
232
|
+
|
|
233
|
+
await actor.insertPayloadRows(
|
|
234
|
+
SHRINK_GROW_INITIAL_ROWS,
|
|
235
|
+
SHRINK_GROW_INITIAL_PAYLOAD,
|
|
236
|
+
);
|
|
237
|
+
const grownPages = await actor.getPageCount();
|
|
238
|
+
|
|
239
|
+
await actor.reset();
|
|
240
|
+
await actor.vacuum();
|
|
241
|
+
const shrunkPages = await actor.getPageCount();
|
|
242
|
+
|
|
243
|
+
await actor.insertPayloadRows(
|
|
244
|
+
SHRINK_GROW_REGROW_ROWS,
|
|
245
|
+
SHRINK_GROW_REGROW_PAYLOAD,
|
|
246
|
+
);
|
|
247
|
+
const regrownPages = await actor.getPageCount();
|
|
248
|
+
|
|
249
|
+
expect(grownPages).toBeGreaterThanOrEqual(baselinePages);
|
|
250
|
+
expect(shrunkPages).toBeLessThanOrEqual(grownPages);
|
|
251
|
+
expect(regrownPages).toBeGreaterThan(shrunkPages);
|
|
252
|
+
},
|
|
253
|
+
dbTestTimeout,
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
test(
|
|
257
|
+
"handles repeated updates to the same row",
|
|
258
|
+
async (c) => {
|
|
259
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
260
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
261
|
+
`db-${variant}-updates-${crypto.randomUUID()}`,
|
|
262
|
+
]);
|
|
263
|
+
|
|
264
|
+
await actor.reset();
|
|
265
|
+
const { id } = await actor.insertValue("base");
|
|
266
|
+
const result = await actor.repeatUpdate(id, 50);
|
|
267
|
+
expect(result.value).toBe("Updated 49");
|
|
268
|
+
const value = await actor.getValue(id);
|
|
269
|
+
expect(value).toBe("Updated 49");
|
|
270
|
+
|
|
271
|
+
const hotRowIds: number[] = [];
|
|
272
|
+
for (let i = 0; i < HOT_ROW_COUNT; i++) {
|
|
273
|
+
const row = await actor.insertValue(`init-${i}`);
|
|
274
|
+
hotRowIds.push(row.id);
|
|
275
|
+
}
|
|
233
276
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
277
|
+
const updatedRows = await actor.roundRobinUpdateValues(
|
|
278
|
+
hotRowIds,
|
|
279
|
+
HOT_ROW_UPDATES,
|
|
280
|
+
);
|
|
281
|
+
expect(updatedRows).toHaveLength(HOT_ROW_COUNT);
|
|
282
|
+
for (const row of updatedRows) {
|
|
283
|
+
expect(row.value).toMatch(/^v-\d+$/);
|
|
284
|
+
}
|
|
285
|
+
},
|
|
286
|
+
dbTestTimeout,
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
test(
|
|
290
|
+
"passes integrity checks after mixed workload and sleep",
|
|
291
|
+
async (c) => {
|
|
292
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
293
|
+
const actor = getDbActor(client, variant).getOrCreate([
|
|
294
|
+
`db-${variant}-integrity-${crypto.randomUUID()}`,
|
|
295
|
+
]);
|
|
296
|
+
|
|
297
|
+
await actor.reset();
|
|
298
|
+
await actor.runMixedWorkload(
|
|
299
|
+
INTEGRITY_SEED_COUNT,
|
|
300
|
+
INTEGRITY_CHURN_COUNT,
|
|
301
|
+
);
|
|
302
|
+
expect((await actor.integrityCheck()).toLowerCase()).toBe("ok");
|
|
240
303
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
304
|
+
await actor.triggerSleep();
|
|
305
|
+
await waitFor(driverTestConfig, SLEEP_WAIT_MS + 100);
|
|
306
|
+
expect((await actor.integrityCheck()).toLowerCase()).toBe("ok");
|
|
307
|
+
},
|
|
308
|
+
dbTestTimeout,
|
|
309
|
+
);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
247
312
|
|
|
248
|
-
|
|
249
|
-
|
|
313
|
+
describe("Actor Database Lifecycle Cleanup Tests", () => {
|
|
314
|
+
test(
|
|
315
|
+
"runs db provider cleanup on sleep",
|
|
316
|
+
async (c) => {
|
|
250
317
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
251
318
|
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
252
319
|
|
|
@@ -274,9 +341,13 @@ export function runActorDbTests(driverTestConfig: DriverTestConfig) {
|
|
|
274
341
|
expect(after.create).toBeGreaterThanOrEqual(before.create);
|
|
275
342
|
expect(after.migrate).toBeGreaterThanOrEqual(before.migrate);
|
|
276
343
|
expect(after.cleanup).toBeGreaterThanOrEqual(before.cleanup + 1);
|
|
277
|
-
}
|
|
344
|
+
},
|
|
345
|
+
lifecycleTestTimeout,
|
|
346
|
+
);
|
|
278
347
|
|
|
279
|
-
|
|
348
|
+
test(
|
|
349
|
+
"runs db provider cleanup on destroy",
|
|
350
|
+
async (c) => {
|
|
280
351
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
281
352
|
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
282
353
|
|
|
@@ -301,11 +372,16 @@ export function runActorDbTests(driverTestConfig: DriverTestConfig) {
|
|
|
301
372
|
}
|
|
302
373
|
|
|
303
374
|
expect(cleanupCount).toBeGreaterThanOrEqual(before.cleanup + 1);
|
|
304
|
-
}
|
|
375
|
+
},
|
|
376
|
+
lifecycleTestTimeout,
|
|
377
|
+
);
|
|
305
378
|
|
|
306
|
-
|
|
379
|
+
test(
|
|
380
|
+
"runs db provider cleanup when migration fails",
|
|
381
|
+
async (c) => {
|
|
307
382
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
308
383
|
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
384
|
+
const beforeTotalCleanup = await observer.getTotalCleanupCount();
|
|
309
385
|
const key = `db-lifecycle-migrate-failure-${crypto.randomUUID()}`;
|
|
310
386
|
const lifecycle = client.dbLifecycleFailing.getOrCreate([key]);
|
|
311
387
|
|
|
@@ -317,22 +393,23 @@ export function runActorDbTests(driverTestConfig: DriverTestConfig) {
|
|
|
317
393
|
}
|
|
318
394
|
expect(threw).toBeTruthy();
|
|
319
395
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
let cleanupCount = 0;
|
|
396
|
+
let cleanupCount = beforeTotalCleanup;
|
|
323
397
|
for (let i = 0; i < LIFECYCLE_POLL_ATTEMPTS; i++) {
|
|
324
|
-
|
|
325
|
-
cleanupCount
|
|
326
|
-
if (cleanupCount >= 1) {
|
|
398
|
+
cleanupCount = await observer.getTotalCleanupCount();
|
|
399
|
+
if (cleanupCount >= beforeTotalCleanup + 1) {
|
|
327
400
|
break;
|
|
328
401
|
}
|
|
329
402
|
await waitFor(driverTestConfig, LIFECYCLE_POLL_INTERVAL_MS);
|
|
330
403
|
}
|
|
331
404
|
|
|
332
|
-
expect(cleanupCount).toBeGreaterThanOrEqual(1);
|
|
333
|
-
}
|
|
405
|
+
expect(cleanupCount).toBeGreaterThanOrEqual(beforeTotalCleanup + 1);
|
|
406
|
+
},
|
|
407
|
+
lifecycleTestTimeout,
|
|
408
|
+
);
|
|
334
409
|
|
|
335
|
-
|
|
410
|
+
test(
|
|
411
|
+
"handles parallel actor lifecycle churn",
|
|
412
|
+
async (c) => {
|
|
336
413
|
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
337
414
|
const observer = client.dbLifecycleObserver.getOrCreate(["observer"]);
|
|
338
415
|
|
|
@@ -366,7 +443,11 @@ export function runActorDbTests(driverTestConfig: DriverTestConfig) {
|
|
|
366
443
|
survivors.map((handle) => handle.getCount()),
|
|
367
444
|
);
|
|
368
445
|
for (const count of survivorCounts) {
|
|
369
|
-
|
|
446
|
+
if (driverTestConfig.useRealTimers) {
|
|
447
|
+
expect(count).toBeGreaterThanOrEqual(2);
|
|
448
|
+
} else {
|
|
449
|
+
expect(count).toBe(2);
|
|
450
|
+
}
|
|
370
451
|
}
|
|
371
452
|
|
|
372
453
|
const lifecycleCleanup = new Map<string, number>();
|
|
@@ -389,6 +470,8 @@ export function runActorDbTests(driverTestConfig: DriverTestConfig) {
|
|
|
389
470
|
for (const actorId of actorIds) {
|
|
390
471
|
expect(lifecycleCleanup.get(actorId) ?? 0).toBeGreaterThanOrEqual(1);
|
|
391
472
|
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
|
|
473
|
+
},
|
|
474
|
+
lifecycleTestTimeout,
|
|
475
|
+
);
|
|
476
|
+
});
|
|
477
|
+
}
|
|
@@ -182,15 +182,16 @@ export function runActorQueueTests(driverTestConfig: DriverTestConfig) {
|
|
|
182
182
|
}
|
|
183
183
|
});
|
|
184
184
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
185
|
+
test("wait send returns completion response", async (c) => {
|
|
186
|
+
const { client } = await setupDriverTest(c, driverTestConfig);
|
|
187
|
+
const handle = client.queueActor.getOrCreate(["wait-complete"]);
|
|
188
|
+
const waitTimeout = driverTestConfig.useRealTimers ? 5_000 : 1_000;
|
|
189
|
+
|
|
190
|
+
const actionPromise = handle.receiveAndComplete("tasks");
|
|
191
|
+
const result = await handle.send("tasks",
|
|
192
|
+
{ value: 123 },
|
|
193
|
+
{ wait: true, timeout: waitTimeout },
|
|
194
|
+
);
|
|
194
195
|
|
|
195
196
|
await actionPromise;
|
|
196
197
|
expect(result).toEqual({
|
|
@@ -13,8 +13,18 @@ export function runActorWorkflowTests(driverTestConfig: DriverTestConfig) {
|
|
|
13
13
|
"workflow-basic",
|
|
14
14
|
]);
|
|
15
15
|
|
|
16
|
-
await
|
|
17
|
-
|
|
16
|
+
let state = await actor.getState();
|
|
17
|
+
for (let i = 0; i < 50; i++) {
|
|
18
|
+
if (
|
|
19
|
+
state.runCount > 0 &&
|
|
20
|
+
state.history.length > 0 &&
|
|
21
|
+
state.guardTriggered
|
|
22
|
+
) {
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
await waitFor(driverTestConfig, 100);
|
|
26
|
+
state = await actor.getState();
|
|
27
|
+
}
|
|
18
28
|
expect(state.runCount).toBeGreaterThan(0);
|
|
19
29
|
expect(state.history.length).toBeGreaterThan(0);
|
|
20
30
|
expect(state.guardTriggered).toBe(true);
|
|
@@ -26,10 +26,6 @@ export async function setupDriverTest(
|
|
|
26
26
|
// Build drivers
|
|
27
27
|
const { endpoint, namespace, runnerName, cleanup } =
|
|
28
28
|
await driverTestConfig.start();
|
|
29
|
-
c.onTestFinished(() => {
|
|
30
|
-
logger().info("cleaning up test");
|
|
31
|
-
cleanup();
|
|
32
|
-
});
|
|
33
29
|
|
|
34
30
|
let client: Client<typeof registry>;
|
|
35
31
|
if (driverTestConfig.clientType === "http") {
|
|
@@ -56,10 +52,14 @@ export async function setupDriverTest(
|
|
|
56
52
|
assertUnreachable(driverTestConfig.clientType);
|
|
57
53
|
}
|
|
58
54
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
55
|
+
c.onTestFinished(async () => {
|
|
56
|
+
if (!driverTestConfig.HACK_skipCleanupNet) {
|
|
57
|
+
await client.dispose();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
logger().info("cleaning up test");
|
|
61
|
+
await cleanup();
|
|
62
|
+
});
|
|
63
63
|
|
|
64
64
|
return {
|
|
65
65
|
client,
|