Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemathinc
GitHub Repository: sagemathinc/wapython
Path: blob/main/python/python-wasm/src/test/posix/socket.test.ts
1067 views
1
// This breaks randomly, due to probably threading issues, since this is the error:
2
// "ENOENT: no such file or directory, uv_cwd"
3
// Hence we have to skip it for now.
4
5
import { asyncPython } from "../../node";
6
7
const CREATE_SERVER =
8
"import socket; s = socket.create_server(('localhost', 0)); s.listen(1)";
9
10
// See also packages/python-wasm/data/socket for some python scripts
11
// you can run directly.
12
13
test.skip("create a client and a server and have them send/recv strings", async () => {
14
// It is really cool how easily we can do this test due to the
15
// architecture of python-wasm!
16
// We just run two completely separate copies of Python
17
// at the same time in memory, one as the client and one as the server. Each
18
// gets their own independent thread and separate WebAssembly memory, but this
19
// is actually all happening inside one single operating system process.
20
const client = await asyncPython();
21
const server = await asyncPython();
22
23
// We let Python assign an available port.
24
await server.exec(CREATE_SERVER);
25
// Get the port that Python assigned:
26
const port = eval(await server.repr("s.getsockname()[1]"));
27
expect(port).toBeGreaterThan(0);
28
// Create a server that accepts one connection, sends "Hello",
29
// then receives 6 bytes and saves them. We do not await
30
// this call since this blocks until after server one client.
31
server.exec(`
32
conn, addr = s.accept()
33
conn.send(b"Hello")
34
received = conn.recv(6)
35
conn.close()
36
`);
37
// Make the client connect to the server.
38
await client.exec(
39
`import socket; conn = socket.create_connection(("localhost", ${port}))`
40
);
41
// Get Hello and confirm it worked.
42
expect(await client.repr("conn.recv(5)")).toBe("b'Hello'");
43
// Now send back "CoWasm" to the server
44
await client.exec("conn.send(b'CoWasm')");
45
// Confirm that the server received CoWasm
46
expect(await server.repr("received")).toBe("b'CoWasm'");
47
48
client.kernel.terminate();
49
server.kernel.terminate();
50
});
51
52
// socket.settimeout is very commonly used on sockets and uses fd_fdstat_set_flags in WASI
53
// so we better test that it doesn't crash.
54
55
test.skip("settimeout on a socket", async () => {
56
const client = await asyncPython();
57
const server = await asyncPython();
58
await server.exec(CREATE_SERVER);
59
const port = eval(await server.repr("s.getsockname()[1]"));
60
expect(port).toBeGreaterThan(0);
61
62
(async () => {
63
try {
64
// We wrap this since it is supposed to throw when we terminate the server.
65
await server.exec(`
66
conn, addr = s.accept()
67
import time; time.sleep(0.25)
68
conn.send(b"Hello")
69
# never close conn and never send anything.
70
time.sleep(1)
71
`);
72
} catch (err) {}
73
})();
74
await client.exec(
75
`import socket; conn = socket.create_connection(("localhost", ${port}))`
76
);
77
// Set a timeout and see that reading still happens quickly.
78
await client.exec("conn.settimeout(1000)");
79
// Get Hello and confirm it worked.
80
expect(await client.repr("conn.recv(5)")).toBe("b'Hello'");
81
82
// Make timeout short:
83
await client.exec("conn.settimeout(0.5)");
84
// Try to get more and confirm it stopped trying
85
// quickly a bit after the timeout, showing the timeout
86
// actually works.
87
const start = new Date().valueOf();
88
try {
89
await client.repr("conn.recv(6)");
90
} catch (err) {}
91
expect(new Date().valueOf() - start).toBeLessThan(1000); // less than 1 second.
92
expect(new Date().valueOf() - start).toBeGreaterThan(400);
93
94
client.kernel.terminate();
95
server.kernel.terminate();
96
});
97
98