-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinitial-upload.test.ts
More file actions
121 lines (118 loc) · 3.99 KB
/
Copy pathinitial-upload.test.ts
File metadata and controls
121 lines (118 loc) · 3.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import { test, expect } from "vitest";
import { mkdtemp, mkdir, readFile, writeFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { randomUUID } from "node:crypto";
import { FileStore, type ObjectStore } from "./src/storage.js";
import {
capture,
openNative,
prepareInitialUpload,
restore,
type NativeRuntime,
} from "./src/native-state.js";
test("new workspaces use bundled files without accessing remote storage", async () => {
const inaccessible: ObjectStore = {
get: async () => {
throw new Error("Remote storage accessed during startup");
},
put: async () => {
throw new Error("Remote storage accessed during startup");
},
};
const runtime = await openNative(randomUUID(), inaccessible);
try {
expect(
await readFile(join(runtime.workspace, "README.md"), "utf8"),
).toContain("Release Notes Demo");
} finally {
await rm(runtime.root, { recursive: true, force: true });
}
});
test("a blocked initial upload preserves frozen bytes while edits and rollback proceed locally", async () => {
const root = await mkdtemp(join(tmpdir(), "initial-upload-test-"));
const runtime: NativeRuntime = {
root: join(root, "runtime"),
workspace: join(root, "runtime/workspace"),
handles: {},
};
const remote = new FileStore(join(root, "remote"));
let release!: () => void;
const gate = {
promise: new Promise<void>((resolve) => {
release = resolve;
}),
resolve: () => release(),
};
let finished = false;
let prepared: Awaited<ReturnType<typeof prepareInitialUpload>> | undefined;
try {
await mkdir(runtime.workspace, { recursive: true });
await writeFile(join(runtime.workspace, "proof.txt"), "original");
prepared = await prepareInitialUpload(runtime, {
get: (key) => remote.get(key),
put: async (key, body) => {
await gate.promise;
await remote.put(key, body);
},
});
const pending = prepared.upload().then(() => {
finished = true;
});
await writeFile(join(runtime.workspace, "proof.txt"), "modified");
runtime.handles.pi = { id: "partial-session", through: 1 };
const changed = await capture(runtime, remote, prepared.snapshot);
expect(finished).toBe(false);
expect(
await remote.get(prepared.snapshot.files["workspace/proof.txt"].key),
).toBeUndefined();
await prepared.rollback();
expect(await readFile(join(runtime.workspace, "proof.txt"), "utf8")).toBe(
"original",
);
expect(runtime.handles).toEqual({});
expect(finished).toBe(false);
gate.resolve();
await pending;
await restore(runtime, changed, remote);
expect(await readFile(join(runtime.workspace, "proof.txt"), "utf8")).toBe(
"modified",
);
await restore(runtime, prepared.snapshot, remote);
expect(await readFile(join(runtime.workspace, "proof.txt"), "utf8")).toBe(
"original",
);
} finally {
gate.resolve();
await prepared?.dispose();
await rm(root, { recursive: true, force: true });
}
});
test("background upload failure remains a commit barrier but does not prevent local rollback", async () => {
const root = await mkdtemp(join(tmpdir(), "initial-failure-test-"));
const runtime: NativeRuntime = {
root,
workspace: join(root, "workspace"),
handles: {},
};
await mkdir(runtime.workspace);
await writeFile(join(runtime.workspace, "proof.txt"), "original");
const prepared = await prepareInitialUpload(runtime, {
get: async () => undefined,
put: async () => {
throw new Error("Upload unavailable");
},
});
try {
void prepared.upload();
await writeFile(join(runtime.workspace, "proof.txt"), "modified");
await prepared.rollback();
expect(await readFile(join(runtime.workspace, "proof.txt"), "utf8")).toBe(
"original",
);
await expect(prepared.upload()).rejects.toThrow("Upload unavailable");
} finally {
await prepared.dispose();
await rm(root, { recursive: true, force: true });
}
});