| 1 | #!/usr/bin/env bash
|
| 2 | #
|
| 3 | # Compare Python implementation with other shells.
|
| 4 | #
|
| 5 | # Contrast with test/spec-cpp.sh, which compares the Python and C++ version.
|
| 6 | #
|
| 7 | # Usage:
|
| 8 | # test/spec-py.sh <function name>
|
| 9 |
|
| 10 | : ${LIB_OSH=stdlib/osh}
|
| 11 | source $LIB_OSH/bash-strict.sh
|
| 12 | source $LIB_OSH/task-five.sh
|
| 13 |
|
| 14 | REPO_ROOT=$(cd "$(dirname $0)/.."; pwd)
|
| 15 | source test/spec-common.sh
|
| 16 |
|
| 17 | check-survey-shells() {
|
| 18 | ### Make sure bash, zsh, OSH, etc. exist
|
| 19 |
|
| 20 | # Note: yash isn't here, but it is used in a couple tests
|
| 21 |
|
| 22 | test/spec-runner.sh shell-sanity-check dash bash mksh zsh ash $OSH_LIST
|
| 23 | }
|
| 24 |
|
| 25 | run-file() {
|
| 26 | local spec_name=$1
|
| 27 | shift
|
| 28 |
|
| 29 | sh-spec spec/$spec_name.test.sh \
|
| 30 | --compare-shells \
|
| 31 | --oils-bin-dir $PWD/bin "$@"
|
| 32 | }
|
| 33 |
|
| 34 | osh-all() {
|
| 35 | check-survey-shells
|
| 36 |
|
| 37 | # $suite $compare_mode $spec_subdir
|
| 38 | test/spec-runner.sh all-parallel osh compare-py osh-py "$@"
|
| 39 |
|
| 40 | # By default, it runs sh_spec.py with --compare-shells
|
| 41 | # Can also add:
|
| 42 | # --ovm-bin-dir
|
| 43 | # --oils-cpp-bin-dir
|
| 44 | # to compare with more
|
| 45 | }
|
| 46 |
|
| 47 | ysh-all() {
|
| 48 | # $suite $compare_mode $spec_subdir
|
| 49 | test/spec-runner.sh all-parallel ysh compare-py ysh-py "$@"
|
| 50 | }
|
| 51 |
|
| 52 | ysh-ovm-tarball() {
|
| 53 | ### Regression test run by CI
|
| 54 |
|
| 55 | local version
|
| 56 | version=$(head -n 1 oils-version.txt)
|
| 57 |
|
| 58 | local tar_root=$REPO_ROOT/_tmp/oils-ref-tar-test/oils-ref-$version
|
| 59 |
|
| 60 | pushd $tar_root
|
| 61 | $REPO_ROOT/devtools/bin.sh make-ovm-links
|
| 62 | popd
|
| 63 |
|
| 64 | # Run the file that depends on stdlib/
|
| 65 |
|
| 66 | #test/spec.sh ysh-stdlib --ovm-bin-dir $tar_root/_bin
|
| 67 |
|
| 68 | set +o errexit
|
| 69 | ysh-all-serial --ovm-bin-dir $tar_root/_bin
|
| 70 | local status=$?
|
| 71 | set +o errexit
|
| 72 |
|
| 73 | echo
|
| 74 | echo status=$status
|
| 75 | }
|
| 76 |
|
| 77 | ysh-stdlib-regress() {
|
| 78 | test/spec.sh ysh-stdlib --ovm-bin-dir $REPO_ROOT/_bin "$@"
|
| 79 | }
|
| 80 |
|
| 81 | osh-minimal() {
|
| 82 | ### Some tests that work on the minimal build. Run by Soil.
|
| 83 |
|
| 84 | # depends on link-busybox-ash, then source dev-shell.sh at the top of this
|
| 85 | # file
|
| 86 | check-survey-shells
|
| 87 |
|
| 88 | # suite compare_mode spec_subdir
|
| 89 | test/spec-runner.sh all-parallel osh-minimal compare-py osh-minimal "$@"
|
| 90 | }
|
| 91 |
|
| 92 |
|
| 93 | osh-all-serial() { MAX_PROCS=1 $0 osh-all "$@"; }
|
| 94 | ysh-all-serial() { MAX_PROCS=1 $0 ysh-all "$@"; }
|
| 95 | osh-minimal-serial() { MAX_PROCS=1 $0 osh-minimal "$@"; }
|
| 96 |
|
| 97 | interactive-osh() {
|
| 98 | ### Run spec files tagged 'interactive' in soil/interactive, which uses a terminal
|
| 99 | # This repeats what 'compare-py' does.
|
| 100 |
|
| 101 | # Doesn't seem to trigger "Stopped" bug, but it hangs in the CI unless serial
|
| 102 |
|
| 103 | # pass '1' to make it serial. default is N-1 CPUS in test/spec-common.sh
|
| 104 | local max_procs=${1:-1}
|
| 105 |
|
| 106 | # Note: without MAX_PROCS=1, I observed at least 2 instances of hanging (for
|
| 107 | # 30 minutes)
|
| 108 | #
|
| 109 | # TODO:
|
| 110 | # - better diagnostics from those hanging instances
|
| 111 | # - note: worked OK (failed to hang) one time in soil/host-shim.sh local-test-uke
|
| 112 | # - I suspect job control, we need to test it more throoughly, by simulating
|
| 113 | # the kernel in Python unit tests
|
| 114 |
|
| 115 | # $suite $compare_mode $spec_subdir
|
| 116 | MAX_PROCS=$max_procs test/spec-runner.sh all-parallel \
|
| 117 | interactive osh-only interactive-osh "$@"
|
| 118 | }
|
| 119 |
|
| 120 | debug-2023-06() {
|
| 121 | # 2023-06-30:
|
| 122 | # HANGING BUG after removing test/spec_param.py, and using run-file
|
| 123 | # All of the sudden test/spec-py.sh interactive-osh hangs in Docker, and then
|
| 124 | # this does too
|
| 125 | # It reproduces LOCALLY as well
|
| 126 | # But doesn't reproduce outside the container on my machine
|
| 127 | #
|
| 128 | # I get an ORPHANED bash -i command running at 100%, outside the container
|
| 129 | # Remember that runs with docker -t
|
| 130 |
|
| 131 | # NARROWED DOWN: the bug was that bash ALWAYS fails inside the container
|
| 132 | #
|
| 133 | # We don't run with bash and a terminal in the CI
|
| 134 |
|
| 135 | test/spec.sh run-file-with-osh builtin-history
|
| 136 | }
|
| 137 |
|
| 138 | interactive-bash() {
|
| 139 | # Triggers the "Stopped" bug with bash alone, unless max_procs=1
|
| 140 |
|
| 141 | # pass '1' to make it serial. default is N-1 CPUS in test/spec-common.sh
|
| 142 | local max_procs=${1:-}
|
| 143 |
|
| 144 | # $suite $compare_mode $spec_subdir
|
| 145 | MAX_PROCS=$max_procs test/spec-runner.sh all-parallel \
|
| 146 | interactive bash-only interactive-bash "$@"
|
| 147 | }
|
| 148 |
|
| 149 | interactive-osh-bash() {
|
| 150 | # Triggers the "Stopped" bug with osh and bash!
|
| 151 |
|
| 152 | # Note: there's no longer a way to run with 2 shells? We could do
|
| 153 | # test/sh_spec.py --shells-from-argv foo.test.sh osh bash
|
| 154 | echo TODO
|
| 155 | }
|
| 156 |
|
| 157 | all-and-smoosh() {
|
| 158 | ### Published with each release
|
| 159 |
|
| 160 | # Args are flags to sh_spec.py
|
| 161 | # --oils-bin-dir
|
| 162 | # --ovm-bin-dir
|
| 163 | local -a more_flags=( "$@" )
|
| 164 |
|
| 165 | # Note: MAX_PROCS=1 prevents [#oil-dev > Random Spec Test Stoppages]
|
| 166 | # Still need to fix that bug
|
| 167 | MAX_PROCS=1 osh-all "${more_flags[@]}"
|
| 168 | ysh-all "${more_flags[@]}"
|
| 169 |
|
| 170 | # These aren't all green/yellow yet, and are slow.
|
| 171 | smoosh-html "${more_flags[@]}"
|
| 172 | smoosh-hang-html "${more_flags[@]}"
|
| 173 | }
|
| 174 |
|
| 175 | #
|
| 176 | # Smoosh
|
| 177 | #
|
| 178 |
|
| 179 | readonly SMOOSH_REPO=~/git/languages/smoosh
|
| 180 |
|
| 181 | sh-spec-smoosh-env() {
|
| 182 | local test_file=$1
|
| 183 | shift
|
| 184 |
|
| 185 | # - smoosh tests use $TEST_SHELL instead of $SH
|
| 186 | # - cd $TMP to avoid littering repo
|
| 187 | # - pass -o posix
|
| 188 | # - timeout of 1 second
|
| 189 | # - Some tests in smoosh use $HOME and $LOGNAME
|
| 190 |
|
| 191 | sh-spec $test_file \
|
| 192 | --sh-env-var-name TEST_SHELL \
|
| 193 | --posix \
|
| 194 | --env-pair "TEST_UTIL=$SMOOSH_REPO/tests/util" \
|
| 195 | --env-pair "LOGNAME=$LOGNAME" \
|
| 196 | --env-pair "HOME=$HOME" \
|
| 197 | --timeout 1 \
|
| 198 | --oils-bin-dir $REPO_ROOT/bin \
|
| 199 | --compare-shells \
|
| 200 | "$@"
|
| 201 | }
|
| 202 |
|
| 203 | # For speed, only run with one copy of OSH.
|
| 204 | readonly smoosh_osh_list=$OSH_CPYTHON
|
| 205 |
|
| 206 | smoosh() {
|
| 207 | ### Run case smoosh from the console
|
| 208 |
|
| 209 | # TODO: Use --oils-bin-dir
|
| 210 | # our_shells, etc.
|
| 211 |
|
| 212 | sh-spec-smoosh-env _tmp/smoosh.test.sh \
|
| 213 | dash bash mksh $smoosh_osh_list \
|
| 214 | "$@"
|
| 215 | }
|
| 216 |
|
| 217 | smoosh-hang() {
|
| 218 | ### Run case smoosh-hang from the console
|
| 219 |
|
| 220 | # Need the smoosh timeout tool to run correctly.
|
| 221 | sh-spec-smoosh-env _tmp/smoosh-hang.test.sh \
|
| 222 | --timeout-bin "$SMOOSH_REPO/tests/util/timeout" \
|
| 223 | --timeout 1 \
|
| 224 | "$@"
|
| 225 | }
|
| 226 |
|
| 227 | _one-html() {
|
| 228 | local spec_name=$1
|
| 229 | shift
|
| 230 |
|
| 231 | local out_dir=_tmp/spec/smoosh
|
| 232 | local tmp_dir=_tmp/src-smoosh
|
| 233 | mkdir -p $out_dir $out_dir
|
| 234 |
|
| 235 | PYTHONPATH='.:vendor' doctools/src_tree.py smoosh-file \
|
| 236 | _tmp/$spec_name.test.sh \
|
| 237 | $out_dir/$spec_name.test.html
|
| 238 |
|
| 239 | local out=$out_dir/${spec_name}.html
|
| 240 | set +o errexit
|
| 241 | # Shell function is smoosh or smoosh-hang
|
| 242 | time $spec_name --format html "$@" > $out
|
| 243 | set -o errexit
|
| 244 |
|
| 245 | echo
|
| 246 | echo "Wrote $out"
|
| 247 |
|
| 248 | # NOTE: This IGNORES the exit status.
|
| 249 | }
|
| 250 |
|
| 251 | # TODO:
|
| 252 | # - Put these tests in the CI
|
| 253 | # - Import smoosh spec tests into the repo, with 'test/smoosh.sh'
|
| 254 |
|
| 255 | smoosh-html() {
|
| 256 | ### Run by devtools/release.sh
|
| 257 | _one-html smoosh "$@"
|
| 258 | }
|
| 259 |
|
| 260 | smoosh-hang-html() {
|
| 261 | ### Run by devtools/release.sh
|
| 262 | _one-html smoosh-hang "$@"
|
| 263 | }
|
| 264 |
|
| 265 | html-demo() {
|
| 266 | ### Test for --format html
|
| 267 |
|
| 268 | local out=_tmp/spec/demo.html
|
| 269 | builtin-special --format html "$@" > $out
|
| 270 |
|
| 271 | echo
|
| 272 | echo "Wrote $out"
|
| 273 | }
|
| 274 |
|
| 275 |
|
| 276 | #
|
| 277 | # Misc
|
| 278 | #
|
| 279 |
|
| 280 | # Really what I want is enter(func) and exit(func), and filter by regex?
|
| 281 | trace-var-sub() {
|
| 282 | local out=_tmp/coverage
|
| 283 | mkdir -p $out
|
| 284 |
|
| 285 | # This creates *.cover files, with line counts.
|
| 286 | #python -m trace --count -C $out \
|
| 287 |
|
| 288 | # This prints trace with line numbers to stdout.
|
| 289 | #python -m trace --trace -C $out \
|
| 290 | PYTHONPATH=. python -m trace --trackcalls -C $out \
|
| 291 | test/sh_spec.py spec/var-sub.test.sh dash bash "$@"
|
| 292 |
|
| 293 | ls -l $out
|
| 294 | head $out/*.cover
|
| 295 | }
|
| 296 |
|
| 297 | task-five "$@"
|