OILS / test / gold.sh View on Github | oils.pub

172 lines, 91 significant
1#!/usr/bin/env bash
2#
3# Run real shell code with osh and bash, and compare the results.
4#
5# Usage:
6# test/gold.sh <function name>
7
8set -o nounset
9set -o pipefail
10set -o errexit
11shopt -s strict:all 2>/dev/null || true # dogfood for OSH
12
13source test/common.sh # $OSH, run-test-funcs
14
15readonly GOLD_DIR='test/gold'
16
17# Runs an command (argv) the normal way (with its shebang) and then with
18# OSH, and compares the stdout and exit code.
19#
20# Also puts $PWD/bin on the front of $PATH, in order to read bin/readlink
21# and so forth.
22_compare() {
23 set +o errexit
24
25 "$@" >_tmp/shebang.txt
26 local expected_status=$?
27
28 export OILS_HIJACK_SHEBANG=$OSH
29 $OSH "$@" >_tmp/osh.txt
30 local osh_status=$?
31
32 set -o errexit
33
34 #md5sum _tmp/shebang.txt _tmp/osh.txt
35
36 if ! diff -u _tmp/shebang.txt _tmp/osh.txt; then
37 echo FAIL
38 exit 1
39 fi
40
41 if test $expected_status != $osh_status; then
42 echo "FAIL: Got status $osh_status but expected $expected_status"
43 echo "in test case: $@"
44 exit 1
45 fi
46
47 return 0
48}
49
50# Uses {core,osh}/*.py
51test-count() {
52 _compare metrics/source-code.sh for-translation
53 _compare metrics/source-code.sh overview
54}
55
56# Uses $(cd $(dirname $0) && pwd)
57test-spec-file() {
58 _compare test/spec.sh builtin-special
59}
60
61# Uses redirect of functions.
62test-html-summary() {
63 # BUG: in the devtools/release.sh process, there's nothing to summarize here
64 # because _tmp/spec is deleted.
65 _compare test/spec-runner.sh html-summary osh _tmp/spec/cpp
66}
67
68test-gen-module-init() {
69 local modules='time datetime'
70 _compare build/ref/ovm-actions.sh gen-module-init $modules
71}
72
73# NOTE: zsh behaves differently under sh and bin/osh! Looks like it is an
74# inherited file descriptor issue.
75#
76# A bin/osh app bundle also behaves differently. Maybe because of the internal
77# environment variables.
78# FAILS
79
80FAIL-test-startup-benchmark() {
81 _compare benchmarks/startup.sh compare-strace
82}
83
84test-configure() { _compare ./configure; }
85test-configure-bug() { _compare $GOLD_DIR/configure-bug.sh; }
86test-nix() { _compare $GOLD_DIR/nix.sh isElfSimpleWithStdin; }
87test-and-or() { _compare $GOLD_DIR/and-or.sh test-simple; }
88
89test-comments() { _compare $GOLD_DIR/comments.sh; }
90test-readonly_() { _compare $GOLD_DIR/readonly.sh; }
91test-export-case() { _compare $GOLD_DIR/export.sh; }
92test-glob() { _compare $GOLD_DIR/glob.sh; }
93test-no-op() { _compare metrics/source-code.sh; }
94test-complex-here-docs() { _compare $GOLD_DIR/complex-here-docs.sh; }
95
96# FAILS
97FAIL-test-big-here-doc() { _compare $GOLD_DIR/big-here-doc.sh; }
98
99test-case-in-subshell() { _compare $GOLD_DIR/case-in-subshell.sh; }
100test-command-sub() { _compare $GOLD_DIR/command-sub.sh; }
101test-command-sub-2() { _compare $GOLD_DIR/command-sub-2.sh; }
102
103char-class() { _compare $GOLD_DIR/char-class.sh demo; }
104strip-op-char-class() { _compare $GOLD_DIR/strip-op-char-class.sh; }
105
106# Similar tests for backslash escaping.
107FAIL-test-echo-e() { _compare $GOLD_DIR/echo-e.sh; }
108
109test-dollar-sq() { _compare $GOLD_DIR/dollar-sq.sh; }
110
111# 2025-06: This is a sort order issue that doesn't show up in CI (related to
112# LC_COLLATE)
113# I reproduced this issue in spec/glob case #39
114TODO-test-word-eval() { _compare $GOLD_DIR/word-eval.sh; }
115
116test-abuild() {
117 _compare $GOLD_DIR/abuild.sh is_function is_function
118}
119
120# Needs declare -p
121FAIL-test-declare() { _compare $GOLD_DIR/declare.sh demo; }
122
123# Needs declare -p
124FAIL-test-scope() { _compare $GOLD_DIR/scope.sh; }
125
126FAIL-test-readlink() { $GOLD_DIR/readlink.sh compare; }
127
128test-errexit() { _compare $GOLD_DIR/errexit.sh all; }
129
130# Hm this isn't tickling the bug?
131test-errexit-confusion() {
132 _compare $GOLD_DIR/errexit-confusion.sh run-for-release-OLD
133 _compare $GOLD_DIR/errexit-confusion.sh run-for-release-FIXED
134}
135
136test-parse-help() {
137 local dir=benchmarks/parse-help
138
139 # This is not hermetic since it calls 'ls'
140 _compare $dir/excerpt.sh _parse_help ls
141}
142
143test-autoconf-backtick() {
144 # https://github.com/oilshell/oil/issues/1449
145 _compare $GOLD_DIR/autoconf-backtick.sh
146}
147
148# Gah, bash gets this from compile-time configuration generated with autoconf,
149# not uname(). It looks like 'linux-gnu' on Ubuntu. In Alpine, it's
150# 'linux-musl'.
151_ostype() {
152 echo $OSTYPE
153}
154
155FAIL-test-ostype() {
156 _compare $0 _ostype
157}
158
159# TODO:
160# - Run the failing tests, and add an --allowed-failures mechanism
161# - and a timeout for big-here-doc
162
163# TODO: Turn it into a table?
164run-for-release() {
165 run-other-suite-for-release gold run-test-funcs
166}
167
168soil-run() {
169 run-test-funcs
170}
171
172"$@"