//! `toolkit shell`, run as `brokerd` runs it, with the host's `/bin/sh`. Do not edit. mod support; use proto::tools::ShellArgs; use support::{TempDir, json, toolkit}; use toolkit::shell::MAX_OUTPUT; fn sh(command: &str, cwd: Option<&str>) -> support::Ran { let args = ShellArgs { command: command.to_string(), cwd: cwd.map(str::to_string), }; toolkit(&["shell"], &json(&args)) } #[test] fn output_and_errors_come_back_in_order_then_the_exit_status() { let ran = sh("echo one; echo two >&2; echo three", None); assert_eq!(ran.code, 0); assert_eq!(ran.stdout, "one\ntwo\nthree\n\n[exit 0]"); } #[test] fn a_failing_command_is_still_a_result_with_its_status() { let ran = sh("echo nope; exit 3", None); assert_eq!((ran.code, ran.stdout.as_str()), (0, "nope\n\n[exit 3]")); let ran = sh("true", None); assert_eq!(ran.stdout, "\n[exit 0]"); } #[test] fn a_command_killed_by_a_signal_says_so() { let ran = sh("kill -9 $$", None); assert_eq!( (ran.code, ran.stdout.as_str()), (0, "\n[killed by signal 9]") ); } #[test] fn the_command_runs_in_cwd_or_in_tmp() { let dir = TempDir::new("cwd"); let here = dir.path().to_str().unwrap(); let ran = sh("pwd", Some(here)); assert_eq!(ran.stdout, format!("{here}\n\n[exit 0]")); let ran = sh("pwd", None); assert_eq!(ran.stdout, "/tmp\n\n[exit 0]"); } #[test] fn a_missing_cwd_is_exit_1() { let ran = sh("pwd", Some("/no/such/dir")); assert_eq!( (ran.code, ran.stdout.as_str()), (1, "shell: /no/such/dir: no such directory") ); } #[test] fn standard_input_is_empty() { let ran = sh("cat; echo done", None); assert_eq!(ran.stdout, "done\n\n[exit 0]"); } #[test] fn output_past_the_limit_is_dropped_and_the_command_still_finishes() { let ran = sh( &format!( "head -c {} /dev/zero | tr '\\0' a; echo; echo end >&2; exit 4", MAX_OUTPUT + 5000 ), None, ); assert_eq!(ran.code, 0); let expected_tail = format!("\n[output after {MAX_OUTPUT} bytes dropped]\n[exit 4]"); assert!( ran.stdout.ends_with(&expected_tail), "{}", &ran.stdout[ran.stdout.len() - 80..] ); assert_eq!(ran.stdout.len(), MAX_OUTPUT + expected_tail.len()); } #[test] fn output_that_is_not_utf8_is_replaced_not_refused() { let ran = sh("printf 'a\\377b'", None); assert_eq!(ran.stdout, "a\u{fffd}b\n[exit 0]"); }