Files
cadcraft/apps/cadcraft-cli/tests/dwg_worker.rs
T
Tanish Manku f6d84e28f3 DWG reader and writer run in a child process (E7) (#2673)
* DWG reader and writer run in a child process (E7)

An allocation failure or stack overflow in the third-party code ends its
process, which catch_unwind can't stop, so one bad file took every open drawing
with it. The app and CLI now run them in a copy of themselves over pipes. A
worker that dies or runs past 30 minutes costs that one open or save. If no
worker can be started, the work stays in the process, as before.

* DWG worker: keep the reply's bytes instead of copying them; skip the test without a bridge
2026-11-02 18:47:29 -07:00

34 lines
1.6 KiB
Rust

//! The DWG reader and writer run in a child process, so a decoder that dies ends one open or save,
//! not the app. The worker setting is process-wide, so everything runs in one test.
#![cfg(not(any(target_arch = "wasm32", all(target_os = "freebsd", target_arch = "aarch64"))))]
use cadcraft_io::dwg_worker;
#[test]
fn a_real_worker_reads_and_writes_and_its_death_is_an_error_here() {
let drawing = cadcraft_engine::sample::bracket();
let in_process = cadcraft_io::write(&drawing, "a.dwg").unwrap();
dwg_worker::use_worker(env!("CARGO_BIN_EXE_cadcraft-cli").into(), vec![dwg_worker::WORKER_ARG.into()]);
let written = cadcraft_io::write(&drawing, "a.dwg").unwrap();
assert_eq!(written.get(..6), in_process.get(..6), "the same version of file");
let read = cadcraft_io::read(&written, "a.dwg").unwrap();
assert_eq!(read.model.len(), drawing.model.len());
// A decode error comes back as that error, not as the worker stopping.
let mut bad = in_process.clone();
bad.truncate(64);
let e = cadcraft_io::read(&bad, "a.dwg").unwrap_err().to_string();
assert!(!e.contains("worker"), "{e}");
// The worker aborts as the third-party code can. This process goes on.
let e = dwg_worker::crash_worker_for_test().unwrap_err();
assert!(e.contains("worker stopped"), "{e}");
assert!(cadcraft_io::read(&written, "a.dwg").is_ok(), "the next file gets a new worker");
// No worker to start: the work happens here, as without one.
dwg_worker::use_worker("no-such-program-here".into(), Vec::new());
assert!(cadcraft_io::read(&written, "a.dwg").is_ok());
}