Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,9 @@ jobs:
run: cargo clippy --locked --all-targets -- -D warnings

- name: Validate Python tooling
run: python3 -m py_compile x.py tools/run_tests.py
run: |
python3 -m py_compile x.py tools/run_tests.py tools/test_contracts.py tools/test_test_contracts.py
python3 -m unittest tools.test_test_contracts

- name: Run Rust tests
run: cargo test --locked --all-targets --verbose
Expand Down
24 changes: 18 additions & 6 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ jobs:
run: cargo clippy --locked --all-targets -- -D warnings

- name: Validate Python tooling
run: python3 -m py_compile x.py tools/run_tests.py
run: |
python3 -m py_compile x.py tools/run_tests.py tools/test_contracts.py tools/test_test_contracts.py
python3 -m unittest tools.test_test_contracts

- name: Build release compiler
run: cargo build --locked --release --verbose
Expand Down Expand Up @@ -119,7 +121,9 @@ jobs:
run: cargo clippy --locked --all-targets -- -D warnings

- name: Validate Python tooling
run: python3 -m py_compile x.py tools/run_tests.py
run: |
python3 -m py_compile x.py tools/run_tests.py tools/test_contracts.py tools/test_test_contracts.py
python3 -m unittest tools.test_test_contracts

- name: Build release compiler
run: cargo build --locked --release --verbose
Expand Down Expand Up @@ -199,7 +203,9 @@ jobs:
run: cargo clippy --locked --all-targets -- -D warnings

- name: Validate Python tooling
run: python3 -m py_compile x.py tools/run_tests.py
run: |
python3 -m py_compile x.py tools/run_tests.py tools/test_contracts.py tools/test_test_contracts.py
python3 -m unittest tools.test_test_contracts

- name: Build release compiler
run: cargo build --locked --release --verbose
Expand Down Expand Up @@ -325,7 +331,9 @@ jobs:
run: cargo clippy --locked --all-targets -- -D warnings

- name: Validate Python tooling
run: python3 -m py_compile x.py tools/run_tests.py
run: |
python3 -m py_compile x.py tools/run_tests.py tools/test_contracts.py tools/test_test_contracts.py
python3 -m unittest tools.test_test_contracts

- name: Build release compiler
run: cargo build --locked --release --verbose
Expand Down Expand Up @@ -387,7 +395,9 @@ jobs:
run: cargo clippy --locked --all-targets -- -D warnings

- name: Validate Python tooling
run: python3 -m py_compile x.py tools/run_tests.py
run: |
python3 -m py_compile x.py tools/run_tests.py tools/test_contracts.py tools/test_test_contracts.py
python3 -m unittest tools.test_test_contracts

- name: Build release compiler
run: cargo build --locked --release --verbose
Expand Down Expand Up @@ -508,7 +518,9 @@ jobs:
env:
PYTHONUTF8: "1"
PYTHONIOENCODING: "utf-8"
run: python -m py_compile x.py tools/run_tests.py
run: |
python -m py_compile x.py tools/run_tests.py tools/test_contracts.py tools/test_test_contracts.py
python -m unittest tools.test_test_contracts

- name: Build release compiler
shell: msys2 {0}
Expand Down
2 changes: 1 addition & 1 deletion tests/cases/test101.wave
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// wave-test: host-os=linux, host-arch=riscv64
// wave-test: mode=build, runner=compile, target=riscv64-unknown-linux-gnu, emit=asm, asm-contains=ecall|a7
fun do_recv(sockfd: i64, buf: ptr<array<i8, 128>>, src: ptr<array<i8, 16>>, srclen: ptr<i64>) -> i64 {
var n: i64;
asm {
Expand Down
2 changes: 1 addition & 1 deletion tests/cases/test107.wave
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// wave-test: mode=build, emit=obj
// wave-test: mode=build, runner=compile, emit=obj

export(c, "wave_add_i32") fun add_i32(a: i32, b: i32) -> i32 {
return a + b;
Expand Down
2 changes: 1 addition & 1 deletion tests/cases/test108.wave
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// wave-test: mode=build, target=x86_64-pc-windows-gnu, emit=obj, freestanding=true
// wave-test: mode=build, runner=compile, target=x86_64-pc-windows-gnu, emit=obj, freestanding=true

const KERNEL_ENTRY_POINT: u64 = 0x200000;
const KERNEL_IMAGE_SIZE: u64 = 4;
Expand Down
2 changes: 1 addition & 1 deletion tests/cases/test54.wave
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// wave-test: host-arch=x86_64, mode=build, target=x86_64-unknown-none-elf, emit=obj, freestanding=true
// wave-test: mode=build, runner=compile, target=x86_64-unknown-none-elf, emit=obj, freestanding=true, object-arch=x86_64, object-bits=64
fun main() {
asm {
"mov ah, 0x0e"
Expand Down
2 changes: 1 addition & 1 deletion tests/cases/test94.wave
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// wave-test: host-os=linux, host-arch=riscv64
// wave-test: mode=build, runner=compile, target=riscv64-unknown-linux-gnu, emit=obj, object-arch=riscv64, object-bits=64, riscv-float-abi=lp64d
fun main() {
var dummy_ptr: ptr<i8> = "dummy";
var ret_val: i64;
Expand Down
2 changes: 1 addition & 1 deletion tests/cases/test96.wave
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// wave-test: host-os=linux, host-arch=riscv64
// wave-test: mode=build, runner=compile, target=riscv64-unknown-linux-gnu, emit=asm, asm-contains=ecall|a7
fun factorial_simple(n: i32) -> i32 {
var result: i32 = 1;
var i: i32 = 1;
Expand Down
2 changes: 1 addition & 1 deletion tests/cases/test99.wave
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// wave-test: host-os=linux, host-arch=riscv64
// wave-test: mode=build, runner=compile, target=riscv64-unknown-linux-gnu, emit=obj, object-arch=riscv64, object-bits=64, riscv-float-abi=lp64d
fun syscall_mmap(addr: ptr<u8>, length: i64, prot: i64, flags: i64, fd: i64, offset: i64) -> ptr<u8> {
let r: ptr<u8>;
asm {
Expand Down
112 changes: 39 additions & 73 deletions tools/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@
import tempfile
import errno

try:
from tools.test_contracts import (
normalize_arch,
parse_test_metadata as parse_test_metadata_file,
validate_compiled_artifact,
)
except ModuleNotFoundError:
from test_contracts import (
normalize_arch,
parse_test_metadata as parse_test_metadata_file,
validate_compiled_artifact,
)

ROOT = Path(__file__).resolve().parent.parent
TEST_DIR = ROOT / "tests" / "cases"

Expand Down Expand Up @@ -79,18 +92,7 @@ def resolve_wavec() -> Path:
results = []

HOST_OS = platform.system().lower()
HOST_ARCH = platform.machine().lower()


def normalize_arch(arch: str) -> str:
aliases = {
"amd64": "x86_64",
"arm64": "aarch64",
}
return aliases.get(arch.lower(), arch.lower())


HOST_ARCH = normalize_arch(HOST_ARCH)
HOST_ARCH = normalize_arch(platform.machine())
TEST_OUTPUT_DIR = Path(tempfile.mkdtemp(prefix="wave-test-output-"))


Expand Down Expand Up @@ -128,64 +130,13 @@ def iter_test_entries():


def parse_test_metadata(rel_path: str):
path = ROOT / rel_path
meta = {
"host_os": None,
"host_arch": None,
"mode": "run",
"target": None,
"emit": "obj",
"freestanding": False,
"expected_exit": 0,
"udp_input": False,
}

try:
for line in path.read_text().splitlines():
stripped = line.strip()
if not stripped.startswith("//"):
if stripped:
break
continue

marker = "// wave-test:"
if not stripped.startswith(marker):
continue

body = stripped[len(marker):].strip()
for item in body.split(","):
item = item.strip()
if not item or "=" not in item:
continue
key, value = item.split("=", 1)
key = key.strip()
value = value.strip()
if key == "host-os":
meta["host_os"] = value.lower()
elif key == "host-arch":
meta["host_arch"] = normalize_arch(value)
elif key == "mode":
meta["mode"] = value.lower()
elif key == "target":
meta["target"] = value
elif key == "emit":
meta["emit"] = value.lower()
elif key == "freestanding":
meta["freestanding"] = value.lower() in {"1", "true", "yes"}
elif key == "expected-exit":
meta["expected_exit"] = int(value)
elif key == "udp-input":
meta["udp_input"] = value.lower() in {"1", "true", "yes"}
except OSError:
pass

return meta
return parse_test_metadata_file(ROOT / rel_path, rel_path)


def skip_reason_for_metadata(name: str, rel_path: str):
meta = parse_test_metadata(rel_path)
host_os = meta["host_os"]
host_arch = meta["host_arch"]
host_os = meta.host_os
host_arch = meta.host_arch

if host_os and host_os != HOST_OS:
return f"{name} requires host OS {host_os}, current host is {HOST_OS}"
Expand All @@ -198,7 +149,7 @@ def skip_reason_for_metadata(name: str, rel_path: str):

def command_for_test(name: str, rel_path: str):
meta = parse_test_metadata(rel_path)
mode = meta["mode"]
mode = meta.mode

if mode == "run":
return [str(WAVEC), "run", rel_path]
Expand All @@ -214,13 +165,13 @@ def command_for_test(name: str, rel_path: str):
str(WAVEC),
"build",
rel_path,
f"--emit={meta['emit']}",
f"--emit={meta.emit}",
"--out-dir",
str(output_dir),
]
if meta["target"]:
cmd.extend(["--target", meta["target"]])
if meta["freestanding"]:
if meta.target:
cmd.extend(["--target", meta.target])
if meta.freestanding:
cmd.append("--freestanding")
return cmd

Expand Down Expand Up @@ -318,7 +269,8 @@ def run_and_classify(name, rel_path, cmd):
print(f"{CYAN}→ SKIP ({skip_reason}){RESET}\n")
return 2

expected_exit = parse_test_metadata(rel_path)["expected_exit"]
metadata = parse_test_metadata(rel_path)
expected_exit = metadata.expected_exit

stdin_data = None
if name == "test22.wave":
Expand All @@ -331,7 +283,7 @@ def run_and_classify(name, rel_path, cmd):
return run_test56_server(cmd)

try:
if parse_test_metadata(rel_path)["udp_input"]:
if metadata.udp_input:
threading.Thread(
target=send_udp_test_input,
daemon=True
Expand Down Expand Up @@ -362,6 +314,17 @@ def run_and_classify(name, rel_path, cmd):
if expected_exit != 0:
print(f"{MAGENTA}→ PASS (expected exit={expected_exit}){RESET}\n")
return 3
artifact_error = validate_compiled_artifact(
name,
ROOT / rel_path,
TEST_OUTPUT_DIR,
metadata,
)
if artifact_error:
print(f"{RED}→ FAIL (artifact contract){RESET}")
print(artifact_error)
print()
return 0
print(f"{GREEN}→ PASS{RESET}\n")
return 1

Expand Down Expand Up @@ -412,6 +375,9 @@ def run_and_classify(name, rel_path, cmd):
except KeyboardInterrupt:
print(f"\n{YELLOW}Interrupted by user.{RESET}")
sys.exit(130)
except ValueError as error:
print(f"{RED}invalid wave-test metadata: {error}{RESET}", file=sys.stderr)
sys.exit(2)
finally:
shutil.rmtree(TEST_OUTPUT_DIR, ignore_errors=True)

Expand Down
Loading
Loading