char/avril

(wip) why'd you have to go and make things so complicaaaaated?

git clone https://git.t4t.associates/char/avril

Charlotte Somsnapshot: embed shared main and worker startup in the CLI688e96e

main
3.8 KiB118 linesraw
1use std::process::{Command, Output};
2
3fn run(source: &str, args: &[&str]) -> (tempfile::TempDir, Output) {
4    let dir = tempfile::tempdir().unwrap();
5    std::fs::write(dir.path().join("main.ts"), source).unwrap();
6    let output = Command::new(env!("CARGO_BIN_EXE_avril"))
7        .current_dir(dir.path())
8        .arg("run")
9        .args(args)
10        .arg("main.ts")
11        .output()
12        .unwrap();
13    (dir, output)
14}
15
16fn success(output: &Output) -> String {
17    assert!(
18        output.status.success(),
19        "{}",
20        String::from_utf8_lossy(&output.stderr)
21    );
22    String::from_utf8(output.stdout.clone()).unwrap()
23}
24
25#[test]
26fn process_and_runtime_report_this_host() {
27    let (dir, output) = run(
28        r#"
29        import { process, runtime } from 'avril:std';
30        console.log(process.pid > 0, process.cwd(), process.hostname().length > 0,
31            process.osRelease().length > 0, process.uptime() >= 0,
32            process.loadavg().length === 3, process.loadavg().every((value) => value >= 0));
33        console.log(runtime.os, runtime.arch, runtime.version, runtime.v8.length > 0);
34        console.log(Object.isFrozen(process), Object.isFrozen(runtime));
35        "#,
36        &[],
37    );
38    let text = success(&output);
39    let lines: Vec<&str> = text.lines().collect();
40    assert_eq!(lines.len(), 3);
41    assert_eq!(
42        lines[0],
43        format!(
44            "true {} true true true true true",
45            dir.path().canonicalize().unwrap().display()
46        )
47    );
48    assert_eq!(
49        lines[1],
50        format!(
51            "{} {} {} true",
52            std::env::consts::OS,
53            std::env::consts::ARCH,
54            env!("CARGO_PKG_VERSION")
55        )
56    );
57    assert_eq!(lines[2], "true true");
58}
59
60#[test]
61fn sys_and_cwd_are_gated_independently() {
62    let (_dir, output) = run(
63        r#"
64        import { errors, process, runtime } from 'avril:std';
65        function denied(call) {
66            try { call(); return false; }
67            catch (error) { return error instanceof errors.PermissionDenied; }
68        }
69        console.log(process.pid > 0, runtime.os.length > 0);
70        console.log(denied(() => process.cwd()), denied(() => process.hostname()),
71            process.uptime() >= 0, denied(() => process.loadavg()));
72        "#,
73        &["-0", "--allow-sys=uptime"],
74    );
75    assert_eq!(success(&output), "true true\ntrue true true true\n");
76}
77
78#[test]
79fn grants_and_pledges_narrow_sys_and_cwd() {
80    let (_dir, output) = run(
81        r#"
82        import { pledge, process } from 'avril:std';
83        function denied(call) {
84            try { call(); return false; }
85            catch (error) { return error.name === 'PermissionDenied'; }
86        }
87        console.log(process.cwd().length > 0, process.hostname().length > 0);
88        pledge({ sys: { allow: ['hostname'] } });
89        console.log(process.hostname().length > 0, denied(() => process.osRelease()),
90            denied(() => process.uptime()));
91        pledge({ read: false });
92        console.log(denied(() => process.cwd()), process.hostname().length > 0);
93        pledge({ sys: false });
94        console.log(denied(() => process.hostname()));
95        try { pledge({ sys: { allow: ['bogus'] } }); console.log('accepted'); }
96        catch (error) { console.log(error instanceof TypeError); }
97        "#,
98        &[],
99    );
100    assert_eq!(
101        success(&output),
102        "true true\ntrue true true\ntrue true\ntrue\ntrue\n"
103    );
104}
105
106#[test]
107fn unknown_sys_names_are_rejected_at_startup() {
108    let (_dir, output) = run(
109        "import { process } from 'avril:std'; console.log(process.hostname());",
110        &["-0", "--allow-sys=bogus"],
111    );
112    assert!(!output.status.success());
113    assert!(
114        String::from_utf8_lossy(&output.stderr).contains("Unknown system information name: bogus"),
115        "{}",
116        String::from_utf8_lossy(&output.stderr)
117    );
118}