From 04e784a04fbee4cd9950b42e59643e1cf53c0721 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sat, 17 Oct 2026 03:57:16 -0700 Subject: [PATCH] Tests: five tests that wait on another thread pass on a loaded machine On a machine busy with other builds, five tests on main failed now and then and passed when run alone. The canvas test for dragging an object with raster effects gave the render worker 10 s for its frame, which took 0.10 s alone and 5.8 to 9.4 s with four ui-egui test runs at once. The three tests_sysclip_probe tests gave the clipboard probe's thread 2 or 3 s. The control server's persistent-requests test sent each request with writeln!, which sends the JSON to the socket in many small writes, and a pause of more than the test's 120 ms line deadline between two of them closed the connection. The canvas test now waits up to 60 s for the worker, as another test in canvas.rs does. The probe tests wait up to 60 s too. The control server test sends each request line in one write and keeps its 120 ms line deadline. Only test code changes. --- apps/vectorcraft/src/control_server.rs | 5 ++++- crates/ui-egui/src/canvas.rs | 2 +- crates/ui-egui/src/tests_sysclip_probe.rs | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/apps/vectorcraft/src/control_server.rs b/apps/vectorcraft/src/control_server.rs index 21eacd61a..529100513 100644 --- a/apps/vectorcraft/src/control_server.rs +++ b/apps/vectorcraft/src/control_server.rs @@ -383,7 +383,10 @@ mod tests { }); let mut reader = BufReader::new(client.try_clone().unwrap()); for id in [1, 2] { - writeln!(client, "{}", json!({"id": id, "method": "inspect"})).unwrap(); + // The client sends each line in one write. `writeln!` on the socket sends the JSON in many + // small writes, and when the machine is busy, a pause of more than the 120 ms line deadline + // between two of them closes the connection. + client.write_all(format!("{}\n", json!({"id": id, "method": "inspect"})).as_bytes()).unwrap(); let mut line = String::new(); reader.read_line(&mut line).unwrap(); assert_eq!(serde_json::from_str::(&line).unwrap(), json!({"id": id, "ok": true})); diff --git a/crates/ui-egui/src/canvas.rs b/crates/ui-egui/src/canvas.rs index fe1f71e68..202bfc10f 100644 --- a/crates/ui-egui/src/canvas.rs +++ b/crates/ui-egui/src/canvas.rs @@ -4411,7 +4411,7 @@ mod tests { app.session.pointer(&PointerEvent::new(PointerKind::Up, 181.9, 131.3), view).unwrap(); assert!(upload(&mut app).is_none(), "not rendered on this thread"); assert!(app.canvas.worker.as_ref().and_then(|w| w.pending.as_ref()).is_some_and(|k| !k.interacting), "sent to the worker"); - let until = std::time::Instant::now() + std::time::Duration::from_secs(10); + let until = std::time::Instant::now() + std::time::Duration::from_secs(60); let mut after = None; while after.is_none() && std::time::Instant::now() < until { std::thread::sleep(std::time::Duration::from_millis(5)); diff --git a/crates/ui-egui/src/tests_sysclip_probe.rs b/crates/ui-egui/src/tests_sysclip_probe.rs index e09ba3a09..48e4f2e34 100644 --- a/crates/ui-egui/src/tests_sysclip_probe.rs +++ b/crates/ui-egui/src/tests_sysclip_probe.rs @@ -117,7 +117,7 @@ fn a_slow_clipboard_is_read_off_the_ui_thread() { frame(&mut app); assert!(t0.elapsed() < Duration::from_millis(300), "the frame waited on the clipboard: {:?}", t0.elapsed()); // The probe's verdict (the UI's own handle would say no) enables Paste once it arrives. - assert!(frames_until(&mut app, Duration::from_secs(3), |app| app.system_paste), "the probe's verdict never arrived"); + assert!(frames_until(&mut app, Duration::from_secs(60), |app| app.system_paste), "the probe's verdict never arrived"); assert!(menus::enabled(&app, "edit.paste")); let threads = rec.threads.lock().unwrap().clone(); assert!(threads.iter().all(|n| n.as_deref() == Some("vectorcraft-clip")), "checked on: {threads:?}"); @@ -128,7 +128,7 @@ fn the_probe_rests_after_a_copy_and_stops_with_the_app() { let rec = Arc::new(Recorder::default()); let mut app = app(&rec, Duration::ZERO, false, Some(true)); run(&mut app, "file.new", json!({"width": 100, "height": 100})); - assert!(frames_until(&mut app, Duration::from_secs(2), |app| app.system_paste)); + assert!(frames_until(&mut app, Duration::from_secs(60), |app| app.system_paste)); // Something copied in the app enables Paste alone: the clipboard isn't read any more. copy_rect(&mut app); frames_until(&mut app, Duration::from_millis(50), |_| false); @@ -149,7 +149,7 @@ fn without_its_thread_the_check_runs_in_line_again() { // The probe's clipboard panics: its thread ends. let mut app = app(&rec, Duration::ZERO, true, None); run(&mut app, "file.new", json!({"width": 100, "height": 100})); - assert!(frames_until(&mut app, Duration::from_secs(2), |app| app.system_paste), "no fallback"); + assert!(frames_until(&mut app, Duration::from_secs(60), |app| app.system_paste), "no fallback"); assert!(app.clipboard_probe.is_none()); let threads = rec.threads.lock().unwrap().clone(); assert_eq!(threads.first().cloned().flatten().as_deref(), Some("vectorcraft-clip"), "{threads:?}");