summaryrefslogtreecommitdiff
path: root/std/wasi/snapshot_preview1_test.ts
blob: 37502e606c89c2078a63d89cf1ca4a5e00d3cef8 (plain)
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/* eslint-disable */

import { assert, assertEquals } from "../testing/asserts.ts";
import * as path from "../path/mod.ts";
import WASI from "./snapshot_preview1.ts";

if (import.meta.main) {
  const options = JSON.parse(Deno.args[0]);
  const binary = await Deno.readFile(Deno.args[1]);
  const module = await WebAssembly.compile(binary);

  const wasi = new WASI({
    env: options.env,
    args: options.args,
    preopens: options.preopens,
  });

  const instance = new WebAssembly.Instance(module, {
    wasi_snapshot_preview1: wasi.exports,
  });

  wasi.memory = instance.exports.memory;

  instance.exports._start();
} else {
  const rootdir = path.dirname(path.fromFileUrl(import.meta.url));
  const testdir = path.join(rootdir, "testdata");
  const outdir = path.join(testdir, "snapshot_preview1");

  for await (const entry of Deno.readDir(testdir)) {
    if (!entry.name.endsWith(".rs")) {
      continue;
    }

    const process = Deno.run({
      cmd: [
        "rustc",
        "--target",
        "wasm32-wasi",
        "--out-dir",
        outdir,
        path.join(testdir, entry.name),
      ],
      stdout: "inherit",
      stderr: "inherit",
    });

    const status = await process.status();
    assert(status.success);

    process.close();

    // TODO(caspervonb) allow the prelude to span multiple lines
    const source = await Deno.readTextFile(path.join(testdir, entry.name));
    const prelude = source.match(/^\/\/\s*\{.*/);
    if (prelude) {
      const basename = entry.name.replace(/.rs$/, ".json");
      await Deno.writeTextFile(
        path.join(outdir, basename),
        prelude[0].slice(2)
      );
    }
  }

  for await (const entry of Deno.readDir(outdir)) {
    if (!entry.name.endsWith(".wasm")) {
      continue;
    }

    Deno.test(entry.name, async function () {
      const basename = entry.name.replace(/\.wasm$/, ".json");
      const prelude = await Deno.readTextFile(path.resolve(outdir, basename));
      const options = JSON.parse(prelude);

      const process = await Deno.run({
        cwd: testdir,
        cmd: [
          `${Deno.execPath()}`,
          "run",
          "--quiet",
          "--unstable",
          "--allow-all",
          import.meta.url,
          prelude,
          path.resolve(outdir, entry.name),
        ],
        stdin: "piped",
        stdout: "piped",
        stderr: "piped",
      });

      if (options.stdin) {
        const stdin = new TextEncoder().encode(options.stdin);
        await Deno.writeAll(process.stdin, stdin);
      }

      process.stdin.close();

      const stdout = await Deno.readAll(process.stdout);

      if (options.stdout) {
        assertEquals(new TextDecoder().decode(stdout), options.stdout);
      } else {
        await Deno.writeAll(Deno.stdout, stdout);
      }

      process.stdout.close();

      const stderr = await Deno.readAll(process.stderr);

      if (options.stderr) {
        assertEquals(new TextDecoder().decode(stderr), options.stderr);
      } else {
        await Deno.writeAll(Deno.stderr, stderr);
      }

      process.stderr.close();

      const status = await process.status();
      assertEquals(status.code, options.exitCode ? +options.exitCode : 0);

      process.close();
    });
  }
}