Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/file-server/zfs/test/archive.test.ts
1450 views
1
/*
2
DEVELOPMENT:
3
4
pnpm exec jest --watch archive.test.ts
5
*/
6
7
import { executeCode } from "@cocalc/backend/execute-code";
8
import { createTestPools, deleteTestPools, init, describe } from "./util";
9
import {
10
archiveFilesystem,
11
dearchiveFilesystem,
12
createFilesystem,
13
createSnapshot,
14
getSnapshots,
15
get,
16
} from "@cocalc/file-server/zfs";
17
import { filesystemMountpoint } from "@cocalc/file-server/zfs/names";
18
import { readFile, writeFile } from "fs/promises";
19
import { join } from "path";
20
21
describe("create a project, put in some files/snapshot, archive the project, confirm gone, de-archive it, and confirm files are back as expected", () => {
22
jest.setTimeout(10000);
23
let x: any = null;
24
25
beforeAll(async () => {
26
x = await createTestPools({ count: 1, size: "1G" });
27
await init();
28
});
29
30
afterAll(async () => {
31
if (x != null) {
32
await deleteTestPools(x);
33
}
34
});
35
36
const project_id = "00000000-0000-0000-0000-000000000001";
37
const mnt = filesystemMountpoint({ project_id, namespace: "default" });
38
const FILE_CONTENT = "hello";
39
const FILENAME = "cocalc.txt";
40
it("creates a project and write a file", async () => {
41
const filesystem = await createFilesystem({
42
project_id,
43
});
44
expect(filesystem.owner_type).toBe("project");
45
expect(filesystem.owner_id).toBe(project_id);
46
const path = join(mnt, FILENAME);
47
await writeFile(path, FILE_CONTENT);
48
});
49
50
let snapshot1, snapshot2;
51
const FILE_CONTENT2 = "hello2";
52
const FILENAME2 = "cocalc2.txt";
53
54
it("create a snapshot and write another file, so there is a nontrivial snapshot to be archived", async () => {
55
snapshot1 = await createSnapshot({ project_id });
56
expect(!!snapshot1).toBe(true);
57
const path = join(mnt, FILENAME2);
58
await writeFile(path, FILE_CONTENT2);
59
snapshot2 = await createSnapshot({ project_id, force: true });
60
expect(snapshot2).not.toEqual(snapshot1);
61
});
62
63
it("archive the project and checks project is no longer in zfs", async () => {
64
expect(get({ project_id }).archived).toBe(false);
65
await archiveFilesystem({ project_id });
66
const { stdout } = await executeCode({
67
command: "zfs",
68
args: ["list", x.pools[0]],
69
});
70
expect(stdout).not.toContain(project_id);
71
expect(get({ project_id }).archived).toBe(true);
72
});
73
74
it("archiving an already archived project is an error", async () => {
75
await expect(
76
async () => await archiveFilesystem({ project_id }),
77
).rejects.toThrow();
78
});
79
80
it("dearchive project and verify zfs filesystem is back, along with files and snapshots", async () => {
81
let called = false;
82
await dearchiveFilesystem({
83
project_id,
84
progress: () => {
85
called = true;
86
},
87
});
88
expect(called).toBe(true);
89
expect(get({ project_id }).archived).toBe(false);
90
91
expect((await readFile(join(mnt, FILENAME))).toString()).toEqual(
92
FILE_CONTENT,
93
);
94
expect((await readFile(join(mnt, FILENAME2))).toString()).toEqual(
95
FILE_CONTENT2,
96
);
97
expect(await getSnapshots({ project_id })).toEqual([snapshot1, snapshot2]);
98
});
99
100
it("dearchiving an already de-archived project is an error", async () => {
101
await expect(
102
async () => await dearchiveFilesystem({ project_id }),
103
).rejects.toThrow();
104
});
105
});
106
107