Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/cocalc
Path: blob/master/src/packages/next/pages/api/v2/exec.e2e.test.ts
5751 views
1
/** @jest-environment node */
2
3
const runE2E = process.env.COCALC_E2E === "true";
4
const describeE2E = runE2E ? describe : describe.skip;
5
6
describeE2E("/api/v2/exec e2e", () => {
7
const apiKey = process.env.COCALC_API_KEY ?? "";
8
const projectId = process.env.COCALC_PROJECT_ID ?? "";
9
const host = process.env.COCALC_HOST ?? "http://localhost:5000";
10
11
beforeAll(() => {
12
if (!apiKey || !projectId) {
13
throw new Error(
14
"COCALC_API_KEY and COCALC_PROJECT_ID must be set when COCALC_E2E=true",
15
);
16
}
17
});
18
19
test("exec date -Is", async () => {
20
const auth = Buffer.from(`${apiKey}:`).toString("base64");
21
const response = await fetch(`${host}/api/v2/exec`, {
22
method: "POST",
23
headers: {
24
"Content-Type": "application/json",
25
Authorization: `Basic ${auth}`,
26
},
27
body: JSON.stringify({
28
project_id: projectId,
29
command: "date",
30
args: ["-Is"],
31
}),
32
});
33
34
expect(response.status).toBe(200);
35
const data = await response.json();
36
if (data?.error) {
37
throw new Error(`API error: ${data.error}`);
38
}
39
40
const stdout = String(data.stdout ?? "").trim();
41
const stderr = String(data.stderr ?? "").trim();
42
43
expect(data.exit_code).toBe(0);
44
expect(stderr).toBe("");
45
expect(stdout).toMatch(
46
/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}[+-]\d{2}:\d{2}$/,
47
);
48
});
49
50
test("exec async_call with async_get", async () => {
51
const auth = Buffer.from(`${apiKey}:`).toString("base64");
52
const startResp = await fetch(`${host}/api/v2/exec`, {
53
method: "POST",
54
headers: {
55
"Content-Type": "application/json",
56
Authorization: `Basic ${auth}`,
57
},
58
body: JSON.stringify({
59
project_id: projectId,
60
bash: true,
61
command:
62
"echo $TEST_ENV; for i in $(seq 10); do echo i=$i; sleep 0.1; done",
63
timeout: 10,
64
async_call: true,
65
env: {
66
TEST_ENV: "123",
67
},
68
}),
69
});
70
71
expect(startResp.status).toBe(200);
72
const startData = await startResp.json();
73
if (startData?.error) {
74
throw new Error(`API error: ${startData.error}`);
75
}
76
77
expect(startData.type).toBe("async");
78
expect(startData.job_id).toBeTruthy();
79
expect(["running", "completed"]).toContain(startData.status);
80
81
const pollResp = await fetch(`${host}/api/v2/exec`, {
82
method: "POST",
83
headers: {
84
"Content-Type": "application/json",
85
Authorization: `Basic ${auth}`,
86
},
87
body: JSON.stringify({
88
project_id: projectId,
89
async_get: startData.job_id,
90
async_stats: true,
91
async_await: true,
92
}),
93
});
94
95
expect(pollResp.status).toBe(200);
96
const pollData = await pollResp.json();
97
if (pollData?.error) {
98
throw new Error(`API error: ${pollData.error}`);
99
}
100
101
const stdout = String(pollData.stdout ?? "").trim();
102
const stderr = String(pollData.stderr ?? "").trim();
103
104
expect(pollData.type).toBe("async");
105
expect(pollData.job_id).toBe(startData.job_id);
106
expect(pollData.status).toBe("completed");
107
expect(pollData.exit_code).toBe(0);
108
expect(stderr).toBe("");
109
const stdoutLines = stdout.split("\n");
110
expect(stdoutLines[0]).toBe("123");
111
expect(stdout).toContain("i=10");
112
});
113
});
114
115