File: worker.js

package info (click to toggle)
pydantic-core 2.41.4-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 3,828 kB
  • sloc: python: 35,564; javascript: 211; makefile: 128
file content (109 lines) | stat: -rw-r--r-- 3,242 bytes parent folder | download | duplicates (2)
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();