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
|
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.27.7/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']);
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();
|