Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/wapython
Path: blob/main/core/posix-node/src/unistd.test.ts
1067 views
1
import posix from "./index";
2
import { userInfo } from "os";
3
4
const isRoot = userInfo().username == "root";
5
6
if (!isRoot) {
7
// chroot
8
test("chroot raises an error", () => {
9
// this can only work as root, which we can't test here easily
10
expect(() => {
11
posix.chroot?.("/");
12
}).toThrow();
13
});
14
}
15
16
// getegid
17
18
test("getegid returns a nonnegative number", () => {
19
expect(posix.getegid?.()).toBeGreaterThanOrEqual(0);
20
});
21
22
// geteuid
23
24
test("geteuid returns a nonnegative number", () => {
25
expect(posix.geteuid?.()).toBeGreaterThanOrEqual(0);
26
});
27
28
// gethostname
29
30
test("gethostname returns a string of length at least 1", () => {
31
const hostname = posix.gethostname?.();
32
if (hostname == null) throw Error("fail");
33
expect(typeof hostname).toBe("string");
34
expect(hostname.length).toBeGreaterThan(0);
35
});
36
37
// getpgid
38
39
test("getpgid returns an integer", () => {
40
expect(posix.getpgid?.(1)).toBeGreaterThanOrEqual(0);
41
});
42
43
test("getpgrp returns an integer", () => {
44
expect(posix.getpgrp?.()).toBeGreaterThanOrEqual(0);
45
});
46
47
test("a special case of setpgid that should work", () => {
48
// @ts-ignore
49
expect(posix.setpgid(0, 0)).toEqual(undefined);
50
});
51
52
test("a use of setpgid that should fail", () => {
53
expect(() => {
54
posix.setpgid?.(1, 2);
55
}).toThrow();
56
});
57
58
// getppid
59
test("getppid returns an integer", () => {
60
expect(posix.getppid?.()).toBeGreaterThanOrEqual(0);
61
});
62
63
test("that the security vulnerability CVE-2022-21211 does not impact posix-node", () => {
64
// @ts-ignore
65
expect(() => posix.setegid?.({ toString: 1 })).toThrow();
66
});
67
68
if (!isRoot) {
69
// setegid
70
test("setegid throws an error (not as root)", () => {
71
expect(() => posix.setegid?.(10)).toThrow();
72
});
73
74
// seteuid
75
test("seteuid throws an error (not as root)", () => {
76
expect(() => posix.seteuid?.(10)).toThrow();
77
});
78
79
// sethostname
80
test("sethostname fails since we're not root", () => {
81
expect(() => posix.sethostname?.("example.com")).toThrow();
82
});
83
84
// setregid
85
test("setregid throws an error (not as root)", () => {
86
expect(() => posix.setregid?.(10, 20)).toThrow();
87
});
88
// setsid
89
test("setsid throws an error (since process is already group leader)", () => {
90
expect(() => posix.setsid?.()).toThrow();
91
});
92
}
93
94
// ttyname
95
test("ttyname of stdin, stdout, stderr works and starts with /dev/ -- or on some platforms, throws an error since testing", () => {
96
try {
97
for (const fd of [0, 1, 2]) {
98
const ttyname = posix.ttyname?.(fd);
99
expect(ttyname?.startsWith("/dev")).toBe(true);
100
}
101
} catch (_err) {
102
// this is also fine under testing, e.g., happens on linux, since not a tty.
103
}
104
});
105
106
test("ttyname of an invalid fd throws an error", () => {
107
expect(() => {
108
posix.ttyname?.(999);
109
}).toThrow();
110
});
111
112
test("ttyname with no inputs throws an error", () => {
113
expect(() => {
114
// @ts-ignore
115
posix.ttyname?.();
116
}).toThrow();
117
});
118
119
test("ttyname with non-number input throws an error", () => {
120
expect(() => {
121
// @ts-ignore
122
posix.ttyname?.("xyz");
123
}).toThrow();
124
});
125
126
// I think this should work with 'jest --runInBand'
127
// but it is NOT working, so commented out for now.
128
/*
129
test("sending ourselves an alarm signal", (cb) => {
130
console.log("isMainThread", isMainThread);
131
process.on("SIGALRM", () => {
132
console.log("got SIGALRM");
133
cb();
134
return 0;
135
});
136
posix.alarm?.(1);
137
});
138
*/
139
140
// create a pipe
141
test("create a pipe", () => {
142
const x = posix.pipe?.();
143
if (x == null) throw Error("pipe must work");
144
const { readfd, writefd } = x;
145
expect(readfd).toBeGreaterThan(0);
146
expect(writefd).toBeGreaterThan(0);
147
});
148
149
test("pipe2 on linux", () => {
150
if (process.platform == "linux") {
151
const x = posix.pipe2?.(0);
152
if (x == null) throw Error("pipe2 must work on linux");
153
const { readfd, writefd } = x;
154
expect(readfd).toBeGreaterThan(0);
155
expect(writefd).toBeGreaterThan(0);
156
}
157
});
158
159
test("chdir and getcwd", () => {
160
// they start at the same
161
const orig = process.cwd();
162
expect(orig).toEqual(posix.getcwd?.());
163
// change at the library level:
164
posix.chdir?.("/");
165
expect(posix.getcwd?.()).toEqual("/");
166
// node version didn't change:
167
expect(process.cwd()).toEqual(orig);
168
});
169
170
const { readSync } = require("fs");
171
172
test("Use the full standard fork, dup, execv song and dance to do 'Hello world'", () => {
173
const { dup2, execv, fork, waitpid, pipe } = posix;
174
if (
175
// for typescript
176
dup2 == null ||
177
execv == null ||
178
fork == null ||
179
waitpid == null ||
180
pipe == null
181
) {
182
throw Error("bug");
183
}
184
185
const stdin = pipe();
186
const stdout = pipe();
187
const pid = fork();
188
189
const HELLO = "Hello there from Posix-node!";
190
if (pid == 0) {
191
// child
192
// connect up stdin and stdout
193
dup2(stdin.readfd, 0);
194
dup2(stdout.writefd, 1);
195
// replace with echo and output hello world to the pipe
196
execv("/bin/echo", ["/bin/echo", HELLO]);
197
} else {
198
let b = Buffer.alloc(10000);
199
// read output from the child
200
readSync(stdout.readfd, b);
201
const s = b.toString("utf8", 0, HELLO.length);
202
expect(s).toEqual(HELLO);
203
const { wstatus, ret } = waitpid(pid, 0);
204
expect(wstatus).toBe(0);
205
expect(ret).toBe(pid);
206
}
207
});
208
209
210
test("Use execvp", () => {
211
const { dup2, execvp, fork, waitpid, pipe } = posix;
212
if (
213
// for typescript
214
dup2 == null ||
215
execvp == null ||
216
fork == null ||
217
waitpid == null ||
218
pipe == null
219
) {
220
throw Error("bug");
221
}
222
223
const stdin = pipe();
224
const stdout = pipe();
225
const pid = fork();
226
227
const HELLO = "Hello there from Posix-node!";
228
if (pid == 0) {
229
dup2(stdin.readfd, 0);
230
dup2(stdout.writefd, 1);
231
execvp("echo", ["echo", HELLO]);
232
} else {
233
let b = Buffer.alloc(10000);
234
readSync(stdout.readfd, b);
235
const s = b.toString("utf8", 0, HELLO.length);
236
expect(s).toEqual(HELLO);
237
const { wstatus, ret } = waitpid(pid, 0);
238
expect(wstatus).toBe(0);
239
expect(ret).toBe(pid);
240
}
241
});
242
243