70 lines
2.9 KiB
Python
70 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Live edits wait for present even across a compile-quiet startup interval.
|
|
|
|
Run with an absolute release Relax binary; MAKEPAD_RUN_STD names this checkout's std.
|
|
The fixture uses the platform crate name to exercise the GUI admission policy,
|
|
without creating a window or requiring a GPU.
|
|
"""
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import sys
|
|
import tempfile
|
|
import time
|
|
|
|
binary = str(Path(sys.argv[1]).resolve())
|
|
with tempfile.TemporaryDirectory(prefix="relax-startup-") as tmp:
|
|
root = Path(tmp)
|
|
(root / "src").mkdir()
|
|
(root / "Cargo.toml").write_text('[package]\nname="makepad-platform"\nversion="0.0.0"\nedition="2021"\n[workspace]\n')
|
|
(root / "src/main.rs").write_text('''
|
|
mod helper;
|
|
extern "C" { fn relax_first_present(); }
|
|
fn main() {
|
|
println!("waiting for present");
|
|
while !std::path::Path::new("present").exists() {
|
|
println!("value {}", std::hint::black_box(helper::value as fn() -> u32)());
|
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
|
}
|
|
unsafe { relax_first_present(); }
|
|
loop {
|
|
let v = std::hint::black_box(helper::value as fn() -> u32)();
|
|
println!("value {}", v);
|
|
if v == 2 { break; }
|
|
std::thread::sleep(std::time::Duration::from_millis(100));
|
|
}
|
|
}
|
|
''')
|
|
helper = root / "src/helper.rs"
|
|
helper.write_text('#[inline(never)] pub fn value() -> u32 { 1 }\n')
|
|
log_path = root / "run.log"
|
|
with log_path.open("w") as log:
|
|
p = subprocess.Popen([binary, "run", "makepad-platform"], cwd=root,
|
|
env=dict(os.environ, MAKEPAD_RUN_LIVE_READY=str(root / "live-ready"), MAKEPAD_RUN_CACHE="off", MAKEPAD_RUN_STARTUP_PHASE="0"),
|
|
stdout=log, stderr=subprocess.STDOUT)
|
|
def text():
|
|
return log_path.read_text(errors="replace")
|
|
def wait_for(predicate):
|
|
deadline = time.monotonic() + 120
|
|
while not predicate():
|
|
assert p.poll() is None, text()
|
|
assert time.monotonic() < deadline, text()
|
|
time.sleep(.05)
|
|
try:
|
|
wait_for(lambda: "value 1" in text() and (root / "live-ready").exists())
|
|
helper.write_text('#[inline(never)] pub fn value() -> u32 { 2 }\n')
|
|
time.sleep(3)
|
|
assert "patched" not in text() and "value 2" not in text(), text()
|
|
(root / "present").touch()
|
|
p.wait(timeout=120)
|
|
assert p.returncode == 0 and "value 2" in text(), text()
|
|
assert text().count("helper.rs: patched") == 1, text()
|
|
print("PASS startup edit queued once until present; scheduling opt-out cannot bypass gate")
|
|
finally:
|
|
if p.poll() is None:
|
|
p.terminate()
|
|
try:
|
|
p.wait(timeout=10)
|
|
except subprocess.TimeoutExpired:
|
|
p.kill()
|
|
p.wait()
|