Bash · 4278 bytes Raw Blame History
1 #!/bin/sh
2 TEST_PREFIX="[int-pipeline]"
3 SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
4 SHELL_BIN="${SHELL_BIN:?ERROR: SHELL_BIN must be set}"
5 export SHELL_BIN
6 . "$SCRIPT_DIR/../test_harness.sh"
7
8 # Integration tests: builtins interacting with pipelines
9
10 section "1. builtins as pipeline source"
11 compare_output "echo into pipeline" 'echo hello world | tr a-z A-Z'
12 compare_output "printf into pipeline" 'printf "%s\n" a b c | sort -r'
13 compare_output "echo pipe to wc" 'echo "one two three" | wc -w | tr -d " "'
14 compare_output "pwd in pipeline" 'pwd | grep -q / && echo yes'
15 compare_output "type in pipeline" 'type echo | head -1'
16 compare_output "printf format in pipeline" 'printf "%d\n" 3 1 2 | sort -n'
17 compare_output "set outputs to pipeline" 'X=hello; set | grep "^X=" | head -1'
18 compare_output "declare -p in pipeline" 'X=42; declare -p X 2>/dev/null | head -1'
19 compare_output "export -p in pipeline" 'export EX=val; export -p | grep "^declare -x EX=" | head -1'
20 compare_output "alias in pipeline" 'alias myalias="echo test" 2>/dev/null; alias | grep myalias | head -1; unalias myalias 2>/dev/null'
21
22 section "2. builtins as pipeline sink"
23 compare_output "read from pipeline" 'echo hello | read VAR; echo $VAR'
24 compare_output "read line from pipeline" 'printf "a\nb\nc\n" | while read line; do echo "got:$line"; done'
25 compare_output "read multiple vars from pipeline" 'echo "one two three" | { read A B C; echo "$A $B $C"; }'
26 compare_output "read in while from seq" 'seq 3 | while read n; do echo "num:$n"; done'
27 compare_output "multi-stage to read" 'printf "c\na\nb\n" | sort | while read x; do echo "sorted:$x"; done'
28 compare_output "read with IFS from pipeline" 'echo "a:b:c" | { IFS=: read A B C; echo "$A $B $C"; }'
29
30 section "3. builtins mid-pipeline"
31 compare_output "builtin mid-pipeline sort head" 'echo -e "b\na\nc" | sort | head -1'
32 compare_output "echo tr wc chain" 'echo "hello world" | tr a-z A-Z | wc -c | tr -d " "'
33 compare_output "printf sort tail chain" 'printf "%d\n" 5 1 3 2 4 | sort -n | tail -1'
34 compare_output "command substitution in pipeline" 'echo $(echo hello) | tr a-z A-Z'
35
36 section "4. pipeline exit status"
37 compare_output "last cmd status true" 'false | true; echo $?'
38 compare_output "last cmd status false" 'true | false; echo $?'
39 compare_output "pipefail first fails" 'set -o pipefail; false | true; echo $?'
40 compare_output "pipefail middle fails" 'set -o pipefail; true | false | true; echo $?'
41 compare_output "pipefail all succeed" 'set -o pipefail; true | true; echo $?'
42 compare_output "negated pipeline" '! true; echo $?'
43 compare_output "negated pipeline false" '! false; echo $?'
44 compare_output "PIPESTATUS basic" 'true | false | true; echo ${PIPESTATUS[0]} ${PIPESTATUS[1]} ${PIPESTATUS[2]}'
45 compare_output "PIPESTATUS all zero" 'true | true | true; echo ${PIPESTATUS[@]}'
46
47 section "5. pipeline subshell semantics"
48 compare_output "var set in pipeline doesnt leak" 'X=before; echo y | read X; echo $X'
49 compare_output "cd in pipeline doesnt affect parent" 'cd /tmp | cat; pwd'
50 # Filter out non-deterministic "Broken pipe" errors from comparison
51 TEST_NUM=$((TEST_NUM + 1))
52 _pp_expected=$(run_with_timeout "$TEST_TIMEOUT" "$BASH_REF" -c 'echo test | { export PVAR=pipe; echo $PVAR; }; echo ${PVAR:-unset}' 2>&1 | grep -v 'Broken pipe')
53 _pp_actual=$(run_with_timeout "$TEST_TIMEOUT" "$SHELL_BIN" -c 'echo test | { export PVAR=pipe; echo $PVAR; }; echo ${PVAR:-unset}' 2>&1 | grep -v 'Broken pipe')
54 if [ "$_pp_expected" = "$_pp_actual" ]; then pass "export in pipeline segment"
55 else fail "export in pipeline segment" "$_pp_expected" "$_pp_actual"; fi
56 compare_output "cmd sub in pipeline" 'echo "$(echo hello)" | tr h H'
57 compare_output "subshell in pipeline" '(echo from_sub) | tr a-z A-Z'
58
59 section "6. pipeline edge cases"
60 compare_output "empty pipeline source" 'echo -n "" | wc -c | tr -d " "'
61 compare_output "large data through pipeline" 'printf "%0100s\n" | wc -c | tr -d " "'
62 compare_output "multiple echo into pipeline" '{ echo a; echo b; echo c; } | sort -r'
63 compare_output "pipeline with command group" '{ echo 1; echo 2; } | { while read n; do echo "got:$n"; done; }'
64 compare_output "pipeline preserves whitespace" 'echo " hello " | cat'
65 compare_output "pipeline with exit in subshell" '(echo before; exit 0; echo after) | cat'
66
67 print_summary