Compare commits
27 Commits
try-time
...
remote-tes
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
61315d377e | ||
|
|
7daa85cd32 | ||
|
|
90b2f93de6 | ||
|
|
fa432b5c09 | ||
|
|
236b8f86c2 | ||
|
|
74e9d95f77 | ||
|
|
0395ebb5b2 | ||
|
|
cebf0d3add | ||
|
|
123f04270b | ||
|
|
82c81822d3 | ||
|
|
9fe6058fbf | ||
|
|
e58ae17704 | ||
|
|
367ae3f2b1 | ||
|
|
5ffd065317 | ||
|
|
c0239915a2 | ||
|
|
b339c5f98e | ||
|
|
92d40c9ff1 | ||
|
|
24ecd302cd | ||
|
|
135c24fd72 | ||
|
|
c219f0a0e6 | ||
|
|
adf8dc3562 | ||
|
|
969340bfd6 | ||
|
|
a484300263 | ||
|
|
e8d946cc5c | ||
|
|
81c4cdeac0 | ||
|
|
b79045c6ee | ||
|
|
c6061b377b |
164
TODO
164
TODO
@@ -72,6 +72,114 @@ Setup for other environments includes the following.
|
|||||||
* `touch .zshrc`
|
* `touch .zshrc`
|
||||||
* Copy urchin and tests
|
* Copy urchin and tests
|
||||||
|
|
||||||
|
|
||||||
|
Fixtures
|
||||||
|
------------
|
||||||
|
I want to change the way that fixtures are done.
|
||||||
|
|
||||||
|
Instead of using setup, teardown, &c., use ordinary programs from within
|
||||||
|
your tests. For example.
|
||||||
|
|
||||||
|
# tests/.fixtures/tmp-dir
|
||||||
|
tmp=$(mktemp -d)
|
||||||
|
cd $tmp
|
||||||
|
@$
|
||||||
|
code=$?
|
||||||
|
cd /
|
||||||
|
rm -Rf $tmp
|
||||||
|
exit $code
|
||||||
|
|
||||||
|
# tests/blah
|
||||||
|
../.fixtures/tmp-dir 'blah blah blah'
|
||||||
|
|
||||||
|
It's best if I can wrap a bunch of commands in braces or paratheses
|
||||||
|
rather than just one command. Is there a nice way to do that?
|
||||||
|
|
||||||
|
Once I have this new way, I guess I might as well keep the old way.
|
||||||
|
I think the setup, teardown thing can be easier if you only have simple
|
||||||
|
fixtures. And since I'm going to keep it, I'm going to add another one.
|
||||||
|
|
||||||
|
* setup_dir runs once for the present directory.
|
||||||
|
* setup_children runs once for each child.
|
||||||
|
* setup_file runs once for each file descendent.
|
||||||
|
|
||||||
|
The present `setup` is renamed to `setup_children`, and the new
|
||||||
|
`setup_file` runs on each file (not directory) that is a child,
|
||||||
|
grandchild, great-grandchild, and so on.
|
||||||
|
|
||||||
|
Dependency checking
|
||||||
|
----------------------
|
||||||
|
You might want to skip tests based on dependencies. Currently you can
|
||||||
|
conditionally skip tests one at a time by exiting with code 3. I want to
|
||||||
|
be able to skip an entire directory.
|
||||||
|
|
||||||
|
So we add a new magic file called `dep`. If it exists, it is run before
|
||||||
|
everything else in the directory.
|
||||||
|
|
||||||
|
* If it exits with code 0, tests continue as if dep did not exist.
|
||||||
|
* If it exits with code 3, all tests in the directory are marked as
|
||||||
|
skipped.
|
||||||
|
* If it exits with code 1, all tests in the directory are marked as
|
||||||
|
failed. To make the implementation easier, I'll probably treat the
|
||||||
|
directory as a single test in this case.
|
||||||
|
|
||||||
|
A note on magic files
|
||||||
|
-------------------------
|
||||||
|
It is nice to have access to things like setup and dep (magic files)
|
||||||
|
once in a while, but you need to be doing rather substantial testing
|
||||||
|
before they make your test suite simpler; the documentation should
|
||||||
|
strongly recommend writing your tests without magic files and then
|
||||||
|
refactoring and only then considering moving things to magic files.
|
||||||
|
|
||||||
|
Remote testing
|
||||||
|
----------------
|
||||||
|
In order to test Urchin across multiple operating systems, I have
|
||||||
|
already added tests in Urchin's test suite that run Urchin tests in
|
||||||
|
remote servers. I would like to move this to Urchin itself so that
|
||||||
|
Urchin can test other things on remote servers.
|
||||||
|
|
||||||
|
Urchin's output presently looks like this.
|
||||||
|
|
||||||
|
Cycling with the following shells: sh bash dash mksh zsh
|
||||||
|
Running tests at 2016-04-07T12:33:49
|
||||||
|
|
||||||
|
Flags/
|
||||||
|
> --timeout output
|
||||||
|
. bash (0 seconds)
|
||||||
|
. dash (0 seconds)
|
||||||
|
. mksh (0 seconds)
|
||||||
|
. sh (0 seconds)
|
||||||
|
. zsh (0 seconds)
|
||||||
|
|
||||||
|
Done, took 1 second.
|
||||||
|
5 tests passed.
|
||||||
|
0 tests skipped.
|
||||||
|
0 tests failed.
|
||||||
|
|
||||||
|
After the change, the output should look like this.
|
||||||
|
|
||||||
|
Cycling with the following shells: sh dash mksh
|
||||||
|
Running tests at 2016-04-07T12:33:49
|
||||||
|
|
||||||
|
Flags/
|
||||||
|
> --timeout output
|
||||||
|
. dash on localhost (0 seconds)
|
||||||
|
. dash on localhost:8080 (0 seconds)
|
||||||
|
. dash on tlevine@hpux.polarhome.com (0 seconds)
|
||||||
|
. mksh on localhost (0 seconds)
|
||||||
|
. mksh on tlevine@hpux.polarhome.com (0 seconds)
|
||||||
|
. sh on localhost (0 seconds)
|
||||||
|
. sh on localhost:8080 (0 seconds)
|
||||||
|
. sh on tlevine@hpux.polarhome.com (0 seconds)
|
||||||
|
|
||||||
|
Done, took 1 second.
|
||||||
|
8 tests passed.
|
||||||
|
0 tests skipped.
|
||||||
|
0 tests failed.
|
||||||
|
|
||||||
|
This is just how the output should look; the tests run in whatever order
|
||||||
|
makes sense.
|
||||||
|
|
||||||
Bugs
|
Bugs
|
||||||
-------
|
-------
|
||||||
|
|
||||||
@@ -114,3 +222,59 @@ date
|
|||||||
tlevine@hpux64$ ./urchin tests/ -n -vv
|
tlevine@hpux64$ ./urchin tests/ -n -vv
|
||||||
date: bad format character - s
|
date: bad format character - s
|
||||||
|
|
||||||
|
So I need a portable seconds-from epoch
|
||||||
|
|
||||||
|
I also need to handle when no arguments are passed to urchin.
|
||||||
|
|
||||||
|
Exit code is wrong for which on HP-UX
|
||||||
|
|
||||||
|
## `$(...)`
|
||||||
|
Solaris doesn't support `$(...)`; you need `\`...\`` instead.
|
||||||
|
|
||||||
|
tlevine@solaris$ ./urchin --run-in-series tests/Errors/
|
||||||
|
./urchin: syntax error at line 84: `tmp=$' unexpected
|
||||||
|
|
||||||
|
I use this a lot.
|
||||||
|
|
||||||
|
$ grep -c '\$(' urchin
|
||||||
|
52
|
||||||
|
|
||||||
|
Darn
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Update tests to support
|
||||||
|
|
||||||
|
* md5
|
||||||
|
* rsync
|
||||||
|
* mktemp
|
||||||
|
* epoch
|
||||||
|
* Report cycling by default
|
||||||
|
* New format for reporting cycling
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Support systems without rsync
|
||||||
|
|
||||||
|
|
||||||
|
BSD mktemp
|
||||||
|
|
||||||
|
| NetBSD 6.1.3
|
||||||
|
| Welcome to NetBSD ...member of polarhome.com realm
|
||||||
|
|
|
||||||
|
| Usage: mktemp [-dqu] [-p <tmpdir>] {-t prefix | template ...}
|
||||||
|
| mkdir: : No such file or directory
|
||||||
|
| ./urchin: cannot create /log: permission denied
|
||||||
|
|
||||||
|
|
||||||
|
NetBSD
|
||||||
|
|
||||||
|
md5: unknown option -- q
|
||||||
|
usage: cksum [-n] [-a algorithm [-ptx] [-s string]] [-o 1|2]
|
||||||
|
[file ... | -c [-w] [sumfile]]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ fi
|
|||||||
urchin_dir=.urchin-cross-shell-test
|
urchin_dir=.urchin-cross-shell-test
|
||||||
|
|
||||||
rsync --archive -e "ssh ${flags}" $RSYNC_FLAGS \
|
rsync --archive -e "ssh ${flags}" $RSYNC_FLAGS \
|
||||||
../urchin ../tests "${hostname}":"${urchin_dir}"
|
../urchin ../tests "${hostname}":"${urchin_dir}" ||
|
||||||
|
scp -r ${flags} ../urchin ../tests "${hostname}":"${urchin_dir}"
|
||||||
ssh "${hostname}" ${flags} \
|
ssh "${hostname}" ${flags} \
|
||||||
"cd ${urchin_dir} && ./urchin --run-in-series tests"
|
"cd ${urchin_dir} && ./urchin --run-in-series tests"
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
$TEST_SHELL ../../urchin -v -s sh -t .testsuite/ |
|
$TEST_SHELL ../../urchin -v -s sh -t .testsuite/ |
|
||||||
sed -e 1d -e /second/d > $tmp
|
sed -e 1,2\ d -e /second/d > $tmp
|
||||||
diff $tmp .tap-output-expectation
|
diff $tmp .tap-output-expectation
|
||||||
|
|||||||
5
tests/Flags/Test Anything Protocol format 2
Executable file
5
tests/Flags/Test Anything Protocol format 2
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
lines=$(
|
||||||
|
$TEST_SHELL ../../urchin -v -s sh -t .testsuite/ |
|
||||||
|
tee $tmp | grep -v '^#' | wc -l)
|
||||||
|
cat $tmp
|
||||||
|
test $lines -eq 4
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
$TEST_SHELL ../../urchin -vv -s sh .testsuite/ |
|
$TEST_SHELL ../../urchin -vv -s sh .testsuite/ |
|
||||||
sed -e 1d -e 's/. seconds\?/1 second/' > $tmp
|
sed -e 1,2\ d -e 's/. seconds\?/1 second/' > $tmp
|
||||||
diff $tmp .urchin-output-expectation
|
diff $tmp .urchin-output-expectation
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
$TEST_SHELL ../../urchin --pretty -vv --shell sh .testsuite/ |
|
$TEST_SHELL ../../urchin --pretty -vv --shell sh .testsuite/ |
|
||||||
sed -e 1d -e 's/. seconds\?/1 second/' > $tmp
|
sed -e 1,2\ d -e 's/. seconds\?/1 second/' > $tmp
|
||||||
diff $tmp .urchin-output-expectation-color
|
diff $tmp .urchin-output-expectation-color
|
||||||
|
|||||||
185
urchin
185
urchin
@@ -68,6 +68,35 @@ if [ -n "${ZSH_VERSION}" ]; then
|
|||||||
emulate sh
|
emulate sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
epoch_date() {
|
||||||
|
date +%s
|
||||||
|
}
|
||||||
|
epoch_pax() {
|
||||||
|
# Based on http://stackoverflow.com/a/7262588/407226
|
||||||
|
tmp="$(mktemp_file)"
|
||||||
|
echo "ibase=8;$({ pax -wx cpio "${tmp}"; echo; } | cut -c 48-59)" | bc
|
||||||
|
rm "${tmp}"
|
||||||
|
}
|
||||||
|
|
||||||
|
mktemp_dir() {
|
||||||
|
# Support HP-UX mktemp that has wrong exit codes and
|
||||||
|
# can't make directories.
|
||||||
|
tmp=$(mktemp /tmp/urchin.XXXXXXXX)
|
||||||
|
if test -f "${tmp}"; then
|
||||||
|
rm "${tmp}"
|
||||||
|
fi
|
||||||
|
mkdir "${tmp}"
|
||||||
|
echo "${tmp}"
|
||||||
|
}
|
||||||
|
mktemp_file() {
|
||||||
|
tmp=$(mktemp /tmp/urchin.XXXXXXXX)
|
||||||
|
if ! test -f "${tmp}"; then
|
||||||
|
> "${tmp}"
|
||||||
|
fi
|
||||||
|
echo "${tmp}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
validate_test_arg() {
|
validate_test_arg() {
|
||||||
# Must be a file or directory
|
# Must be a file or directory
|
||||||
if [ ! -e "${1}" ]; then
|
if [ ! -e "${1}" ]; then
|
||||||
@@ -91,15 +120,7 @@ validate_test_arg() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# All temporary files go here
|
# All temporary files go here
|
||||||
urchin_tmp=$(mktemp)
|
urchin_tmp=$(mktemp_dir)
|
||||||
|
|
||||||
# Support HP-UX mktemp that has wrong exit codes and
|
|
||||||
# can't make directories.
|
|
||||||
if test -f "${urchin_tmp}"; then
|
|
||||||
rm "${urchin_tmp}"
|
|
||||||
fi
|
|
||||||
mkdir "${urchin_tmp}"
|
|
||||||
|
|
||||||
> "${urchin_tmp}/log"
|
> "${urchin_tmp}/log"
|
||||||
|
|
||||||
urchin_exit() {
|
urchin_exit() {
|
||||||
@@ -116,18 +137,35 @@ else
|
|||||||
urchin_exit 1
|
urchin_exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if epoch_date 2>&1 > /dev/null; then
|
||||||
|
epoch=epoch_date
|
||||||
|
elif epoch_pax 2>&1 > /dev/null; then
|
||||||
|
epoch=epoch_pax
|
||||||
|
else
|
||||||
|
echo I could not find a seconds counter. >&2
|
||||||
|
urchin_exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
stdout_file() {
|
stdout_file() {
|
||||||
the_test="${1}"
|
the_test="${1}"
|
||||||
the_shell="${2}"
|
the_shell="${2}"
|
||||||
|
host="${3}"
|
||||||
|
|
||||||
|
if test -n "${host}"; then
|
||||||
|
# This assumes the tests ran on a remote and have been copied.
|
||||||
|
x="${urchin_tmp}/remote/${host}/stdout${the_test}"
|
||||||
|
else
|
||||||
|
# This can be run during the tests.
|
||||||
|
x="${urchin_tmp}/stdout$(fullpath "$the_test")"
|
||||||
|
mkdir -p "${x}"
|
||||||
|
fi
|
||||||
|
|
||||||
x="${urchin_tmp}/stdout$(fullpath "$the_test")"
|
|
||||||
mkdir -p "${x}"
|
|
||||||
case "${urchin_md5}" in
|
case "${urchin_md5}" in
|
||||||
md5sum) y=$(echo "${the_shell}" | md5sum | cut -d\ -f1) ;;
|
md5sum) y=$(echo "${the_shell}" | md5sum | cut -d\ -f1) ;;
|
||||||
md5) y=$(echo "${the_shell}" | md5 -q) ;;
|
md5) y=$(echo "${the_shell}" | md5 | sed 's/.* //') ;;
|
||||||
*) echo md5 command is not configured >&2; urchin_exit 1;;
|
*) echo md5 command is not configured >&2; urchin_exit 1;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
echo "${x}/${y}"
|
echo "${x}/${y}"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -186,10 +224,6 @@ recurse() {
|
|||||||
cycle_shell="${3}"
|
cycle_shell="${3}"
|
||||||
TEST_SHELL="${4}"
|
TEST_SHELL="${4}"
|
||||||
|
|
||||||
if $print_debug; then
|
|
||||||
echo Entered directory "${PWD}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
for ignore in setup_dir teardown_dir setup teardown; do
|
for ignore in setup_dir teardown_dir setup teardown; do
|
||||||
if test "$(basename "${potential_test}")" = "${ignore}"; then
|
if test "$(basename "${potential_test}")" = "${ignore}"; then
|
||||||
return
|
return
|
||||||
@@ -220,9 +254,6 @@ recurse() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test -f setup_dir; then
|
if test -f setup_dir; then
|
||||||
if $print_debug; then
|
|
||||||
echo Sourcing "${PWD}/setup_dir"
|
|
||||||
fi
|
|
||||||
. ./setup_dir
|
. ./setup_dir
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -239,9 +270,6 @@ recurse() {
|
|||||||
if wait "${!}"; then exit_code=0; else exit_code="${?}"; fi
|
if wait "${!}"; then exit_code=0; else exit_code="${?}"; fi
|
||||||
if "${exit_on_not_ok}" && test "${exit_code}" -ne 0; then
|
if "${exit_on_not_ok}" && test "${exit_code}" -ne 0; then
|
||||||
if test -f teardown_dir; then
|
if test -f teardown_dir; then
|
||||||
if $print_debug; then
|
|
||||||
echo Sourcing "${PWD}/teardown_dir"
|
|
||||||
fi
|
|
||||||
. ./teardown_dir
|
. ./teardown_dir
|
||||||
fi
|
fi
|
||||||
return 1
|
return 1
|
||||||
@@ -250,32 +278,22 @@ recurse() {
|
|||||||
done
|
done
|
||||||
wait
|
wait
|
||||||
if test -f teardown_dir; then
|
if test -f teardown_dir; then
|
||||||
if $print_debug; then
|
|
||||||
echo Sourcing "${PWD}/teardown_dir"
|
|
||||||
fi
|
|
||||||
. ./teardown_dir
|
. ./teardown_dir
|
||||||
fi
|
fi
|
||||||
)
|
)
|
||||||
elif [ -f "${potential_test}" ]; then
|
elif [ -f "${potential_test}" ]; then
|
||||||
cd -- "$(dirname -- "${potential_test}")"
|
cd -- "$(dirname -- "${potential_test}")"
|
||||||
|
|
||||||
if $print_debug; then
|
|
||||||
echo Running "${potential_test}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Determine the environment variable to define for test scripts
|
# Determine the environment variable to define for test scripts
|
||||||
# that reflects the specified or implied shell to use for shell-code tests.
|
# that reflects the specified or implied shell to use for shell-code tests.
|
||||||
while read the_test_shell; do
|
while read the_test_shell; do
|
||||||
(
|
(
|
||||||
if test -f setup; then
|
if test -f setup; then
|
||||||
if $print_debug; then
|
|
||||||
echo Sourcing "${PWD}/setup"
|
|
||||||
fi
|
|
||||||
. ./setup
|
. ./setup
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Run the test
|
# Run the test
|
||||||
start=$(date +%s)
|
start=$("${epoch}")
|
||||||
set +e
|
set +e
|
||||||
{
|
{
|
||||||
if "${cycle_shell}"; then
|
if "${cycle_shell}"; then
|
||||||
@@ -297,12 +315,9 @@ recurse() {
|
|||||||
} > "$(stdout_file "${potential_test}" "${the_test_shell}")" 2>&1
|
} > "$(stdout_file "${potential_test}" "${the_test_shell}")" 2>&1
|
||||||
exit_code="${?}"
|
exit_code="${?}"
|
||||||
set -e
|
set -e
|
||||||
finish=$(date +%s)
|
finish=$("${epoch}")
|
||||||
|
|
||||||
if test -f teardown; then
|
if test -f teardown; then
|
||||||
if $print_debug; then
|
|
||||||
echo Sourcing "${PWD}/teardown"
|
|
||||||
fi
|
|
||||||
. ./teardown
|
. ./teardown
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -324,9 +339,6 @@ recurse() {
|
|||||||
if wait "${!}"; then exit_code=0; else exit_code="${?}"; fi
|
if wait "${!}"; then exit_code=0; else exit_code="${?}"; fi
|
||||||
if "${exit_on_not_ok}" && test "${exit_code}" -ne 0; then
|
if "${exit_on_not_ok}" && test "${exit_code}" -ne 0; then
|
||||||
if test -f teardown_dir; then
|
if test -f teardown_dir; then
|
||||||
if $print_debug; then
|
|
||||||
echo Sourcing "${PWD}/teardown_dir"
|
|
||||||
fi
|
|
||||||
. ./teardown_dir
|
. ./teardown_dir
|
||||||
fi
|
fi
|
||||||
return 1
|
return 1
|
||||||
@@ -350,23 +362,30 @@ report_outcome() {
|
|||||||
start="${4}"
|
start="${4}"
|
||||||
finish="${5}"
|
finish="${5}"
|
||||||
|
|
||||||
|
host="${6}"
|
||||||
|
if test -n "${host}"; then
|
||||||
|
onhost=" on ${host}"
|
||||||
|
fi
|
||||||
|
|
||||||
escaped_root="$(fullpath "${root}" | sed 's/\//\\\//g')"
|
escaped_root="$(fullpath "${root}" | sed 's/\//\\\//g')"
|
||||||
elapsed=$(($finish - $start))
|
elapsed=$(($finish - $start))
|
||||||
|
|
||||||
if "${tap_format}"; then
|
|
||||||
printf \#\
|
|
||||||
fi
|
|
||||||
if "${print_margins}" || "${tap_format}"; then
|
if "${print_margins}" || "${tap_format}"; then
|
||||||
echo Running tests at $(date +%Y-%m-%dT%H:%M:%S)
|
if $tap_format; then printf \#\ ; fi
|
||||||
|
echo Ran tests at $(date +%Y-%m-%dT%H:%M:%S) with the following shells:
|
||||||
|
if $tap_format; then printf \#\ ; fi
|
||||||
|
cat "${shell_list}" | tr '\n' \
|
||||||
|
echo
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
for number in n oks skips not_oks; do
|
for number in n oks skips not_oks; do
|
||||||
eval "${number}=0"
|
eval "${number}=0"
|
||||||
done
|
done
|
||||||
|
|
||||||
# Use a temporary file rather than a pipe because a pipe starts a sub-shell
|
# Use a temporary file rather than a pipe because a pipe starts a sub-shell
|
||||||
# and thus makes the above variables local.
|
# and thus makes the above variables local.
|
||||||
sorted_log_file=$(mktemp)
|
sorted_log_file=$(mktemp_file)
|
||||||
cat "${log_file}" | LC_COLLATE=C sort > "${sorted_log_file}"
|
cat "${log_file}" | LC_COLLATE=C sort > "${sorted_log_file}"
|
||||||
|
|
||||||
while read line; do
|
while read line; do
|
||||||
@@ -399,13 +418,13 @@ report_outcome() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test -z "${the_shell}"; then
|
if test -z "${the_shell}"; then
|
||||||
the_shell='File is not executable.'
|
the_shell='File is not executable'
|
||||||
fi
|
fi
|
||||||
echo "${not}ok $n - ${path} (${the_shell}) ${skip}"
|
echo "${not}ok $n - ${path} (${the_shell}${onhost}) ${skip}"
|
||||||
if { test "${result}" = not_ok && "${print_not_ok_stdout}"; } ||
|
if { test "${result}" = not_ok && "${print_not_ok_stdout}"; } ||
|
||||||
{ test "${result}" = ok && "${print_ok_stdout}"; }; then
|
{ test "${result}" = ok && "${print_ok_stdout}"; }; then
|
||||||
echo '# ------------ Begin output ------------'
|
echo '# ------------ Begin output ------------'
|
||||||
sed 's/^/# /' "$(stdout_file "${abspath}" "${the_shell}")"
|
sed 's/^/# /' "$(stdout_file "${abspath}" "${the_shell}" "${host}")"
|
||||||
echo '# ------------ End output ------------'
|
echo '# ------------ End output ------------'
|
||||||
fi
|
fi
|
||||||
echo "# Previous test took ${file_elapsed} seconds."
|
echo "# Previous test took ${file_elapsed} seconds."
|
||||||
@@ -428,7 +447,7 @@ report_outcome() {
|
|||||||
else
|
else
|
||||||
printf "${success_mark} "
|
printf "${success_mark} "
|
||||||
fi
|
fi
|
||||||
echo "${the_shell} ("${file_elapsed}" $(plural second $file_elapsed))"
|
echo "${the_shell}${onhost} (${file_elapsed} $(plural second $file_elapsed))"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
not_ok)
|
not_ok)
|
||||||
@@ -439,23 +458,23 @@ report_outcome() {
|
|||||||
else
|
else
|
||||||
printf "${fail_mark} "
|
printf "${fail_mark} "
|
||||||
fi
|
fi
|
||||||
echo "${the_shell} ("${file_elapsed}" $(plural second $file_elapsed))"
|
echo "${the_shell}${onhost} (${file_elapsed} $(plural second $file_elapsed))"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
skip)
|
skip)
|
||||||
if "${print_ok}"; then
|
if "${print_ok}"; then
|
||||||
header
|
header
|
||||||
if test -z "${the_shell}"; then
|
if test -z "${the_shell}"; then
|
||||||
echo ' (File is not executable.)'
|
echo " (File is not executable${onhost}.)"
|
||||||
else
|
else
|
||||||
echo " ${the_shell} ("${file_elapsed}" $(plural second $file_elapsed))"
|
echo " ${the_shell}${onhost} (${file_elapsed} $(plural second $file_elapsed))"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
if { test "${result}" = not_ok && "${print_not_ok_stdout}"; } ||
|
if { test "${result}" = not_ok && "${print_not_ok_stdout}"; } ||
|
||||||
{ test "${result}" = ok && "${print_ok_stdout}"; }; then
|
{ test "${result}" = ok && "${print_ok_stdout}"; }; then
|
||||||
sed 's/^/ | /' "$(stdout_file "${abspath}" "${the_shell}")"
|
sed 's/^/ | /' "$(stdout_file "${abspath}" "${the_shell}" "${host}")"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -545,13 +564,20 @@ And these options affect how much is printed.
|
|||||||
-v Print stdout from failing tests.
|
-v Print stdout from failing tests.
|
||||||
-vv Print names of passed tests.
|
-vv Print names of passed tests.
|
||||||
-vvv, --verbose Print stdout from all tests.
|
-vvv, --verbose Print stdout from all tests.
|
||||||
-vvvv, --debug Print debugging messages.
|
-vvvv, --debug Run with set -x.
|
||||||
|
|
||||||
The remaining flags provide information about urchin.
|
The remaining flags provide information about urchin.
|
||||||
|
|
||||||
-h, --help Display this help.
|
-h, --help Display this help.
|
||||||
--version Display the version number.
|
--version Display the version number.
|
||||||
|
|
||||||
|
Urchin recognizes certain environment variables.
|
||||||
|
|
||||||
|
TEST_SHELL This is sometimes over-ridden; see -s.
|
||||||
|
RUN_IN_SERIES Set this to true to have the same effect as
|
||||||
|
-b/--run-in-series. This is helpful if you are
|
||||||
|
calling urchin inside an urchin test suite.
|
||||||
|
|
||||||
Go to https://thomaslevine.com/!/urchin/ for documentation on writing tests.
|
Go to https://thomaslevine.com/!/urchin/ for documentation on writing tests.
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
@@ -578,9 +604,13 @@ validate_strings() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
|
argv="$@"
|
||||||
|
|
||||||
cycle_shell=true
|
cycle_shell=true
|
||||||
shell_list="${urchin_tmp}"/shell_list
|
shell_list="${urchin_tmp}"/shell_list
|
||||||
test_arg_list="${urchin_tmp}"/test_list
|
test_arg_list="${urchin_tmp}"/test_list
|
||||||
|
> "${test_arg_list}"
|
||||||
|
remotes_list="${urchin_tmp}"/remotes
|
||||||
run_in_series=false
|
run_in_series=false
|
||||||
force=false
|
force=false
|
||||||
exit_on_not_ok=false
|
exit_on_not_ok=false
|
||||||
@@ -592,7 +622,6 @@ main() {
|
|||||||
print_not_ok=true
|
print_not_ok=true
|
||||||
print_ok_stdout=false
|
print_ok_stdout=false
|
||||||
print_not_ok_stdout=false
|
print_not_ok_stdout=false
|
||||||
print_debug=false
|
|
||||||
while [ "${#}" -gt 0 ]
|
while [ "${#}" -gt 0 ]
|
||||||
do
|
do
|
||||||
case "${1}" in
|
case "${1}" in
|
||||||
@@ -642,7 +671,7 @@ main() {
|
|||||||
-vvvv|--debug) print_not_ok_stdout=true
|
-vvvv|--debug) print_not_ok_stdout=true
|
||||||
print_ok=true;
|
print_ok=true;
|
||||||
print_ok_stdout=true
|
print_ok_stdout=true
|
||||||
print_debug=true;;
|
set -x;;
|
||||||
|
|
||||||
-h|--help) urchin_help
|
-h|--help) urchin_help
|
||||||
urchin_exit 0;;
|
urchin_exit 0;;
|
||||||
@@ -656,6 +685,9 @@ main() {
|
|||||||
esac
|
esac
|
||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
if "${RUN_IN_SERIES}" 2> /dev/null; then
|
||||||
|
run_in_series=true
|
||||||
|
fi
|
||||||
|
|
||||||
if $print_in_color; then
|
if $print_in_color; then
|
||||||
success_mark=✓
|
success_mark=✓
|
||||||
@@ -684,11 +716,6 @@ main() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if $print_debug; then
|
|
||||||
echo Cycling with the following shells:
|
|
||||||
cat "${shell_list}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test -n "${urchin_timeout}"; then
|
if test -n "${urchin_timeout}"; then
|
||||||
# Choose the timeout command
|
# Choose the timeout command
|
||||||
if timeout -t 0 true 2> /dev/null; then
|
if timeout -t 0 true 2> /dev/null; then
|
||||||
@@ -707,7 +734,7 @@ main() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# -------------------- REALLY RUN -------------------- #
|
# -------------------- REALLY RUN -------------------- #
|
||||||
start=$(date +%s)
|
start=$("${epoch}")
|
||||||
|
|
||||||
# 1 test file or folder to run
|
# 1 test file or folder to run
|
||||||
# 2 urchin root
|
# 2 urchin root
|
||||||
@@ -717,16 +744,42 @@ main() {
|
|||||||
recurse "$(fullpath "${seed}")" "${root}" "${cycle_shell}" \
|
recurse "$(fullpath "${seed}")" "${root}" "${cycle_shell}" \
|
||||||
"${TEST_SHELL}" || break
|
"${TEST_SHELL}" || break
|
||||||
done < "${test_arg_list}"
|
done < "${test_arg_list}"
|
||||||
finish=$(date +%s)
|
finish=$("${epoch}")
|
||||||
|
|
||||||
if test $(cat "${urchin_tmp}"/log | wc -l) -eq 0; then
|
if test $(cat "${urchin_tmp}"/log | wc -l) -eq 0; then
|
||||||
echo 'No tests found' >&2
|
echo 'No tests found' >&2
|
||||||
urchin_exit 1
|
urchin_exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
report_outcome "${root}" "${tap_format}" "${urchin_tmp}"/log "${start}" \
|
if test -n "${RUNNING_ON_REMOTE}"; then
|
||||||
"${finish}"
|
echo "${urchin_tmp}"
|
||||||
urchin_exit "${?}"
|
elif test -f "${remotes_list}"; then
|
||||||
|
while read remote; do
|
||||||
|
remote_main $remote "${argv}"
|
||||||
|
done < "${remotes_list}"
|
||||||
|
else
|
||||||
|
report_outcome "${root}" "${tap_format}" "${urchin_tmp}"/log \
|
||||||
|
"${start}" "${finish}"
|
||||||
|
urchin_exit "${?}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
remote_main() {
|
||||||
|
hostname="${1}"; shift
|
||||||
|
flags="${1}"; shift
|
||||||
|
urchin_dir=.urchin-cross-shell-test
|
||||||
|
|
||||||
|
rsync --archive -e "ssh ${flags}"
|
||||||
|
../urchin ../tests "${hostname}":"${urchin_dir}" ||
|
||||||
|
scp -r ${flags} ../urchin ../tests "${hostname}":"${urchin_dir}"
|
||||||
|
|
||||||
|
remote_tmp="$(ssh "${hostname}" ${flags} "cd ${urchin_dir} && ./urchin $@")"
|
||||||
|
|
||||||
|
remotedir="${hostname}":"${remote_tmp}"
|
||||||
|
localdir="${urchin_tmp}/remote/${host}"
|
||||||
|
rsync --archive -e "ssh ${flags}" "${remotedir}" "${localdir}" ||
|
||||||
|
scp -r ${flags} "${remotedir}"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test -n "${TESTING_URCHIN_INTERNALS}" || main "$@"
|
test -n "${TESTING_URCHIN_INTERNALS}" || main "$@"
|
||||||
|
|||||||
Reference in New Issue
Block a user