-
Notifications
You must be signed in to change notification settings - Fork 280
/
Copy pathworker.js
110 lines (102 loc) · 3.25 KB
/
worker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
let chunks = [];
let last_post = 0;
function print(tty) {
if (tty.output && tty.output.length > 0) {
chunks.push(tty.output);
tty.output = [];
const now = performance.now();
if (now - last_post > 100) {
post();
last_post = now;
}
}
}
function post() {
self.postMessage(chunks);
chunks = [];
}
function make_tty_ops() {
return {
put_char(tty, val) {
if (val !== null) {
tty.output.push(val);
}
if (val === null || val === 10) {
print(tty);
}
},
fsync(tty) {
print(tty);
},
};
}
function setupStreams(FS, TTY) {
let mytty = FS.makedev(FS.createDevice.major++, 0);
let myttyerr = FS.makedev(FS.createDevice.major++, 0);
TTY.register(mytty, make_tty_ops());
TTY.register(myttyerr, make_tty_ops());
FS.mkdev('/dev/mytty', mytty);
FS.mkdev('/dev/myttyerr', myttyerr);
FS.unlink('/dev/stdin');
FS.unlink('/dev/stdout');
FS.unlink('/dev/stderr');
FS.symlink('/dev/mytty', '/dev/stdin');
FS.symlink('/dev/mytty', '/dev/stdout');
FS.symlink('/dev/myttyerr', '/dev/stderr');
FS.closeStream(0);
FS.closeStream(1);
FS.closeStream(2);
FS.open('/dev/stdin', 0);
FS.open('/dev/stdout', 1);
FS.open('/dev/stderr', 1);
}
async function get(url, mode) {
const r = await fetch(url);
if (r.ok) {
if (mode === 'text') {
return await r.text();
} else if (mode === 'json') {
return await r.json();
} else {
const blob = await r.blob();
let buffer = await blob.arrayBuffer();
return btoa(new Uint8Array(buffer).reduce((data, byte) => data + String.fromCharCode(byte), ''));
}
} else {
let text = await r.text();
console.error('unexpected response', r, text);
throw new Error(`${r.status}: ${text}`);
}
}
async function main() {
const query_args = new URLSearchParams(location.search);
let pydantic_core_version = query_args.get('pydantic_core_version');
if (!pydantic_core_version) {
const latest_release = await get('https://api.github.com/repos/pydantic/pydantic-core/releases/latest', 'json');
pydantic_core_version = latest_release.tag_name;
}
self.postMessage(`Running tests against latest pydantic-core release (${pydantic_core_version}).\n`);
self.postMessage(`Downloading repo archive to get tests...\n`);
const zip_url = `https://githubproxy.samuelcolvin.workers.dev/pydantic/pydantic-core/archive/refs/tags/${pydantic_core_version}.zip`;
try {
const [python_code, tests_zip] = await Promise.all([
get(`./run_tests.py?v=${Date.now()}`, 'text'),
// e4cf2e2 commit matches the pydantic-core wheel being used, so tests should pass
get(zip_url, 'blob'),
importScripts('https://cdn.jsdelivr.net/pyodide/v0.26.3/full/pyodide.js'),
]);
const pyodide = await loadPyodide();
const {FS} = pyodide;
setupStreams(FS, pyodide._module.TTY);
FS.mkdir('/test_dir');
FS.chdir('/test_dir');
await pyodide.loadPackage(['micropip', 'pytest', 'numpy', 'pygments']);
if (pydantic_core_version < '2.0.0') await pyodide.loadPackage(['typing-extensions']);
await pyodide.runPythonAsync(python_code, {globals: pyodide.toPy({pydantic_core_version, tests_zip})});
post();
} catch (err) {
console.error(err);
self.postMessage(`Error: ${err}\n`);
}
}
main();