Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/file-server/zfs/test/nfs.test.ts
1450 views
1
/*
2
DEVELOPMENT:
3
4
pnpm exec jest --watch nfs.test.ts
5
*/
6
7
import { executeCode } from "@cocalc/backend/execute-code";
8
import {
9
createTestPools,
10
deleteTestPools,
11
restartNfsServer,
12
init,
13
describe,
14
} from "./util";
15
import {
16
createFilesystem,
17
createSnapshot,
18
get,
19
shareNFS,
20
unshareNFS,
21
} from "@cocalc/file-server/zfs";
22
import { filesystemMountpoint } from "@cocalc/file-server/zfs/names";
23
import { readFile, writeFile } from "fs/promises";
24
import { join } from "path";
25
26
describe("create a project, put in a files, snapshot, another file, then share via NFS, mount and verify it works", () => {
27
let x: any = null;
28
const project_id = "00000000-0000-0000-0000-000000000001";
29
let nsfMnt = "";
30
31
beforeAll(async () => {
32
x = await createTestPools({ count: 1, size: "1G" });
33
nsfMnt = join(x.tempDir, project_id);
34
await init();
35
});
36
37
afterAll(async () => {
38
if (x != null) {
39
await deleteTestPools(x);
40
}
41
});
42
43
const mnt = filesystemMountpoint({ project_id, namespace: "default" });
44
const FILE_CONTENT = "hello";
45
const FILENAME = "cocalc.txt";
46
it("creates a project and write a file", async () => {
47
const project = await createFilesystem({
48
project_id,
49
});
50
expect(project.owner_id).toBe(project_id);
51
const path = join(mnt, FILENAME);
52
await writeFile(path, FILE_CONTENT);
53
});
54
55
let snapshot1, snapshot2;
56
const FILE_CONTENT2 = "hello2";
57
const FILENAME2 = "cocalc2.txt";
58
59
it("create a snapshot and write another file, so there is a nontrivial snapshot to view through NFS", async () => {
60
snapshot1 = await createSnapshot({ project_id });
61
expect(!!snapshot1).toBe(true);
62
const path = join(mnt, FILENAME2);
63
await writeFile(path, FILE_CONTENT2);
64
snapshot2 = await createSnapshot({ project_id, force: true });
65
expect(snapshot2).not.toEqual(snapshot1);
66
});
67
68
let host = "";
69
const client = "127.0.0.1";
70
71
const mount = async () => {
72
await executeCode({
73
command: "sudo",
74
args: ["mkdir", "-p", nsfMnt],
75
});
76
await executeCode({
77
command: "sudo",
78
args: ["mount", host, nsfMnt],
79
});
80
};
81
82
it("shares the project via NFS, and mounts it", async () => {
83
host = await shareNFS({ project_id, client });
84
const project = get({ project_id });
85
expect(project.nfs).toEqual([client]);
86
await mount();
87
});
88
89
it("confirms our files and snapshots are there as expected", async () => {
90
const { stdout } = await executeCode({
91
command: "sudo",
92
args: ["ls", nsfMnt],
93
});
94
expect(stdout).toContain(FILENAME);
95
expect(stdout).toContain(FILENAME2);
96
expect((await readFile(join(nsfMnt, FILENAME))).toString()).toEqual(
97
FILE_CONTENT,
98
);
99
expect((await readFile(join(nsfMnt, FILENAME2))).toString()).toEqual(
100
FILE_CONTENT2,
101
);
102
});
103
104
it("stop NFS share and confirms it no longers works", async () => {
105
await executeCode({
106
command: "sudo",
107
args: ["umount", nsfMnt],
108
});
109
await restartNfsServer();
110
await unshareNFS({ project_id, client });
111
try {
112
await mount();
113
throw Error("bug -- mount should fail");
114
} catch (err) {
115
expect(`${err}`).toMatch(/not permitted|denied/);
116
}
117
});
118
});
119
120