use { super::*, std::time::{Duration, Instant}, }; fn kill(process_id: u32) { unsafe { libc::kill(process_id as i32, libc::SIGINT); } } fn interrupt_test(arguments: &[&str], justfile: &str) { let tmp = tempdir(); let mut justfile_path = tmp.path().to_path_buf(); justfile_path.push("justfile"); fs::write(justfile_path, unindent(justfile)).unwrap(); let start = Instant::now(); let mut child = Command::new(executable_path("just")) .current_dir(&tmp) .args(arguments) .spawn() .expect("just invocation failed"); while start.elapsed() < Duration::from_millis(500) {} kill(child.id()); let status = child.wait().unwrap(); let elapsed = start.elapsed(); if elapsed > Duration::from_secs(2) { panic!("process returned too late: {elapsed:?}"); } if elapsed < Duration::from_millis(100) { panic!("process returned too early : {elapsed:?}"); } assert_eq!(status.code(), Some(130)); } #[test] #[ignore] fn interrupt_shebang() { interrupt_test( &[], " default: #!/usr/bin/env sh sleep 1 ", ); } #[test] #[ignore] fn interrupt_line() { interrupt_test( &[], " default: @sleep 1 ", ); } #[test] #[ignore] fn interrupt_backtick() { interrupt_test( &[], " foo := `sleep 1` default: @echo {{foo}} ", ); } #[test] #[ignore] fn interrupt_command() { interrupt_test(&["--command", "sleep", "1"], ""); }