|
|
@@ -343,3 +343,42 @@ fn logs_follow_cmd_format() {
|
|
|
// Follow should not include --tail (we want a live stream from now).
|
|
|
assert!(!cmd.contains("--tail"));
|
|
|
}
|
|
|
+
|
|
|
+// ── Shell quoting ─────────────────────────────────────────────
|
|
|
+
|
|
|
+#[test]
|
|
|
+fn shq_wraps_simple_strings() {
|
|
|
+ assert_eq!(shq("foo"), "'foo'");
|
|
|
+ assert_eq!(shq(""), "''");
|
|
|
+ assert_eq!(shq("foo bar"), "'foo bar'");
|
|
|
+}
|
|
|
+
|
|
|
+#[test]
|
|
|
+fn shq_escapes_inner_single_quotes() {
|
|
|
+ // "don't" → 'don'\''t'
|
|
|
+ assert_eq!(shq("don't"), "'don'\\''t'");
|
|
|
+}
|
|
|
+
|
|
|
+#[test]
|
|
|
+fn entrypoint_script_is_shell_quoted() {
|
|
|
+ // sh -c SCRIPT should wrap the script in single quotes so it survives
|
|
|
+ // bash word-splitting on the SSH server.
|
|
|
+ let mut r = trec();
|
|
|
+ r.entrypoint = vec!["sh".into(), "-c".into(), "echo $i; sleep 1".into()];
|
|
|
+ let cmd = run(&r, &tcls().nodes[0], true);
|
|
|
+ // The script element should appear wrapped in single quotes
|
|
|
+ assert!(
|
|
|
+ cmd.contains("'echo $i; sleep 1'"),
|
|
|
+ "script should be shell-quoted, got: {cmd}"
|
|
|
+ );
|
|
|
+}
|
|
|
+
|
|
|
+#[test]
|
|
|
+fn entrypoint_script_non_sh_passes_through() {
|
|
|
+ // For non `sh -c` entrypoints (e.g. ["sh", "-c", "...", "extra"]) or
|
|
|
+ // direct binaries, we leave the args alone — no false positive shq.
|
|
|
+ let mut r = trec();
|
|
|
+ r.entrypoint = vec!["sh".into(), "-c".into()];
|
|
|
+ let cmd = run(&r, &tcls().nodes[0], true);
|
|
|
+ assert!(cmd.contains("docker run"));
|
|
|
+}
|