Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fae4c7025e |
8
HISTORY
8
HISTORY
@@ -1,8 +1,10 @@
|
|||||||
HISTORY
|
HISTORY
|
||||||
=======
|
=======
|
||||||
|
|
||||||
Version 0.2.0 (unstable)
|
Version 0.1.0
|
||||||
---------------------
|
---------------------
|
||||||
|
This release includes breaking changes.
|
||||||
|
|
||||||
### Cross-OS testing
|
### Cross-OS testing
|
||||||
I have started testing Urchin across multiple operating systems.
|
I have started testing Urchin across multiple operating systems.
|
||||||
This gives access to more shells, as some shels are easier to install on
|
This gives access to more shells, as some shels are easier to install on
|
||||||
@@ -11,10 +13,6 @@ certain operating systems.
|
|||||||
With this cross-OS test suite, I have extended support to more shells.
|
With this cross-OS test suite, I have extended support to more shells.
|
||||||
A later version of Urchin could include a remote testing feature.
|
A later version of Urchin could include a remote testing feature.
|
||||||
|
|
||||||
Version 0.1.0 (stable)
|
|
||||||
---------------------
|
|
||||||
This release includes breaking changes.
|
|
||||||
|
|
||||||
### Test root directory
|
### Test root directory
|
||||||
We introduce a concept of the root directory of a test suite.
|
We introduce a concept of the root directory of a test suite.
|
||||||
Such a concept is important in case you want to run subsets of your
|
Such a concept is important in case you want to run subsets of your
|
||||||
|
|||||||
178
TODO
178
TODO
@@ -72,114 +72,6 @@ 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
|
||||||
-------
|
-------
|
||||||
|
|
||||||
@@ -222,73 +114,3 @@ 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]]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Things I can use to make things better
|
|
||||||
------------------------
|
|
||||||
${x##*blah}
|
|
||||||
$IFS and set --
|
|
||||||
Redirection, especiall <<-
|
|
||||||
Maybe fifo
|
|
||||||
for x in "$@"
|
|
||||||
until
|
|
||||||
readonly
|
|
||||||
getopts
|
|
||||||
|
|
||||||
Variable assignments specified with special built-in utilities remain in
|
|
||||||
effect after the built-in completes; this shall not be the case with a
|
|
||||||
regular built-in or other utility.
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ 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,109 +0,0 @@
|
|||||||
Here I discuss Urchin's general execution flow and how it is handled
|
|
||||||
specifically when tests are run on remote environments.
|
|
||||||
|
|
||||||
|
|
||||||
Steps of an Urchin run
|
|
||||||
----------------------
|
|
||||||
When Urchin runs a directory of files, it goes through the following
|
|
||||||
steps.
|
|
||||||
|
|
||||||
1. Head
|
|
||||||
2. Test
|
|
||||||
3. Foot
|
|
||||||
4. Reporting
|
|
||||||
|
|
||||||
Urchin stores files in a temporary directory, creating a new directory
|
|
||||||
on each invocation. The directory contains these things.
|
|
||||||
|
|
||||||
* head (file)
|
|
||||||
* test (file)
|
|
||||||
* foot (file)
|
|
||||||
* stdout (directory)
|
|
||||||
|
|
||||||
When run on remotes, the temporary directory corresponding to the local
|
|
||||||
master process additionally has these files.
|
|
||||||
|
|
||||||
* remote-test
|
|
||||||
|
|
||||||
Messages from the head, test, and foot steps go in the corresponding
|
|
||||||
files. In the head and foot phases, messages are just simple prints.
|
|
||||||
Messages from the test phase always correspond to a particular test
|
|
||||||
file, and they are written to the test file in a delimiter-separated
|
|
||||||
format.
|
|
||||||
|
|
||||||
Stdout and stderr from test runs are written to files in the stdout
|
|
||||||
directory, one file per test file per shell that the file is run in.
|
|
||||||
|
|
||||||
The reporting phase
|
|
||||||
----------------------
|
|
||||||
In most cases Urchin begins printing to the screen only during the
|
|
||||||
reporting phase. The only case where anything is printed beforehand is
|
|
||||||
when Urchin is run with -vvvv; that sets "+x", so the commands are
|
|
||||||
printed as they run, though all other output is still suppressed.
|
|
||||||
|
|
||||||
Test results are reported in the reporting phase. Four output formats
|
|
||||||
are available.
|
|
||||||
|
|
||||||
1. Urchin's human-readable format (default)
|
|
||||||
2. Test Anything Protocol
|
|
||||||
3. Delimiter-separated values (used internally)
|
|
||||||
4. Remote Urchin worker output
|
|
||||||
|
|
||||||
Most of the output is generated based on the delimiter-separated values
|
|
||||||
in the test log file. The first two formats also include stdout and
|
|
||||||
stderr from the tests, depending on verbosity level flags; when it needs
|
|
||||||
these, Urchin reads them from appropriate files in the temporary
|
|
||||||
directory.
|
|
||||||
|
|
||||||
I could discuss the further details of each format elsewhere.
|
|
||||||
|
|
||||||
Remotes
|
|
||||||
----------------------
|
|
||||||
When Urchin runs tests on a remote, it copies tests to the remote and
|
|
||||||
then calls Urchin on the remote with "--format=remote". This specifies
|
|
||||||
the following.
|
|
||||||
|
|
||||||
* The temporary directory should be kept, rather than deleted, after
|
|
||||||
Urchin runs.
|
|
||||||
* The path of the temporary directory should be printed as output.
|
|
||||||
* No other output should be printed to stdout.
|
|
||||||
|
|
||||||
After the remote Urchin finishes running, the local urchin downloads
|
|
||||||
the remote Urchin's test log file from the temporary directory.
|
|
||||||
It modifies the file to include the remote's name and then concatenates
|
|
||||||
the result to the "remote-test" file in the local temporary directory.
|
|
||||||
For example, the file from the remote might look like this,
|
|
||||||
|
|
||||||
:sh:Counting tests/.test/faila:0:not_ok
|
|
||||||
|
|
||||||
and the result might look like this.
|
|
||||||
|
|
||||||
nsa:sh:Counting tests/.test/faila:0:not_ok
|
|
||||||
|
|
||||||
This gets processed in the reporting step like usual, according to
|
|
||||||
whatever format is specified. Instead of printing just "sh" as the
|
|
||||||
environment in which the particular test was run, the report will print
|
|
||||||
"sh on nsa".
|
|
||||||
|
|
||||||
When it needs the stdout files, it prints them over ssh.
|
|
||||||
|
|
||||||
New flags
|
|
||||||
----------
|
|
||||||
In making this remotes feature, I wound up adding some others.
|
|
||||||
|
|
||||||
-r, --remote SSH host to use as a remote
|
|
||||||
-F, --format Output format, one of "urchin", "tap", "dsv", "remote"
|
|
||||||
|
|
||||||
Urchin runs only locally by default. If you pass at least one --remote
|
|
||||||
flag, Urchin runs tests only on the specified remotes; it can't run both
|
|
||||||
locally and remotely in the same run. If you want to do that, you could
|
|
||||||
wait until I add that feature, or you can add "localhost" as a remote.
|
|
||||||
|
|
||||||
Settings that I'm thinking about
|
|
||||||
|
|
||||||
* Port for rsync/ssh
|
|
||||||
* SSH protocol version
|
|
||||||
* --rsync-path
|
|
||||||
|
|
||||||
Can those all be set in ssh_config? Probably not --rsync-path, but
|
|
||||||
I guess I could just fix it on the remote.
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
# A NixOS container to protect against accidental fork bombs
|
|
||||||
#
|
|
||||||
# Put this in /var/lib/containers/test/etc/nixos/configuration.nix
|
|
||||||
# See https://nixos.org/wiki/NixOS:Containers
|
|
||||||
{ config, lib, pkgs, ... }:
|
|
||||||
|
|
||||||
with lib;
|
|
||||||
|
|
||||||
{ boot.isContainer = true;
|
|
||||||
networking.hostName = mkDefault "urchin";
|
|
||||||
networking.useDHCP = false;
|
|
||||||
|
|
||||||
environment.systemPackages = with pkgs; [
|
|
||||||
# Urchin
|
|
||||||
bash dash mksh zsh
|
|
||||||
busybox
|
|
||||||
|
|
||||||
# Other
|
|
||||||
vim git rsync tmux
|
|
||||||
];
|
|
||||||
security.pam.loginLimits = [
|
|
||||||
# Prevent accidental fork bombs.
|
|
||||||
{ domain = "*"; item = "nproc"; type = "hard"; value = "200"; }
|
|
||||||
];
|
|
||||||
services.openssh = {
|
|
||||||
enable = true;
|
|
||||||
passwordAuthentication = false;
|
|
||||||
};
|
|
||||||
users.extraUsers.user = {
|
|
||||||
name = "tlevine";
|
|
||||||
uid = 1000;
|
|
||||||
isNormalUser = true;
|
|
||||||
home = "/home/tlevine";
|
|
||||||
extraGroups = [ "users" "wheel" ];
|
|
||||||
openssh.authorizedKeys.keys = [
|
|
||||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDGvQyzr42/96acUTUedaeM2ee+DMt9bkxeurdeXji9sNE10MjjAUFtxPmSI8/BUZW2/a9ByblfaJEI+H+kFVPjVr+QGKXZluxcFMj2BLbH53fi9xLgoQRjb2aAXutb2Bp74/E8R1K+CuFfRRGQ5Spdnv44SLt04D6JbBLcLIcWTpQ4v5RaYr2U27jfiF9z0m+/opxvowEy2gnqlEXFxFk8jZHT4K0uLWm2ENjT6OpyOx8hWcKeAN2vRVRex3pJfSzswn0LpuCrM1rUZ4DRE+FABi8N21Q3MBaMRkwnZPwaZwKzv06q8bu23jYTqK5BrUPtOXeeVuroQXMc12H/6/Nh laptop"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
# Create the container.
|
|
||||||
if ! nixos-container list | grep ^urchin$ > /dev/null; then
|
|
||||||
sudo nixos-container create urchin
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Configure the container.
|
|
||||||
sudo cp configuration.nix \
|
|
||||||
/var/lib/containers/urchin/etc/nixos/configuration.nix
|
|
||||||
sudo nixos-container update urchin
|
|
||||||
sudo nixos-container start urchin
|
|
||||||
|
|
||||||
# Create the git repository.
|
|
||||||
host="tlevine@$(nixos-container show-ip urchin)"
|
|
||||||
ssh "${host}" 'if mkdir urchin 2> /dev/null; then
|
|
||||||
cd urchin
|
|
||||||
git init
|
|
||||||
git config --add receive.denyCurrentBranch ignore
|
|
||||||
fi
|
|
||||||
'
|
|
||||||
|
|
||||||
# Push to the git repository
|
|
||||||
git push "${host}":urchin
|
|
||||||
|
|
||||||
# Print information
|
|
||||||
echo "Log in:
|
|
||||||
|
|
||||||
ssh ${host}
|
|
||||||
|
|
||||||
Add git remote
|
|
||||||
|
|
||||||
git remote add ${host} container
|
|
||||||
|
|
||||||
"
|
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
"bin": "./urchin",
|
"bin": "./urchin",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://git.sdf.org/tlevine/urchin"
|
"url": "git://github.com/tlevine/urchin.git"
|
||||||
},
|
},
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"shell",
|
"shell",
|
||||||
@@ -1,5 +1,3 @@
|
|||||||
**The repository at https://github.com/tlevine/urchin will go away. New location is https://git.sdf.org/tlevine/urchin.**
|
|
||||||
|
|
||||||
__ _
|
__ _
|
||||||
__ ____________/ /_ (_)___
|
__ ____________/ /_ (_)___
|
||||||
/ / / / ___/ ___/ __ \/ / __ \
|
/ / / / ___/ ___/ __ \/ / __ \
|
||||||
@@ -19,7 +17,7 @@ have shells called "tests".
|
|||||||
Urchin's tests are written in Urchin, so you can run them to see what Urchin
|
Urchin's tests are written in Urchin, so you can run them to see what Urchin
|
||||||
is like. Clone the repository
|
is like. Clone the repository
|
||||||
|
|
||||||
git clone https://git.sdf.org/tlevine/urchin
|
git clone git://github.com/tlevine/urchin.git
|
||||||
|
|
||||||
Run the tests
|
Run the tests
|
||||||
|
|
||||||
@@ -53,7 +51,7 @@ Urchin is contained in a single file, so you can install it by copying it to a
|
|||||||
directory in your `PATH`. For example, you can run the following as root.
|
directory in your `PATH`. For example, you can run the following as root.
|
||||||
|
|
||||||
cd /usr/local/bin
|
cd /usr/local/bin
|
||||||
wget https://git.sdf.org/tlevine/urchin/raw/branch/master/urchin
|
wget https://raw.githubusercontent.com/tlevine/urchin/v0.1.0-rc3/urchin
|
||||||
chmod +x urchin
|
chmod +x urchin
|
||||||
|
|
||||||
Urchin can be installed with npm too.
|
Urchin can be installed with npm too.
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
$TEST_SHELL ../../urchin -v -s sh -t .testsuite/ |
|
$TEST_SHELL ../../urchin -v -s sh -t .testsuite/ |
|
||||||
sed -e 1,2\ d -e /second/d > $tmp
|
sed -e 1d -e /second/d > $tmp
|
||||||
diff $tmp .tap-output-expectation
|
diff $tmp .tap-output-expectation
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
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 1,2\ d -e 's/. seconds\?/1 second/' > $tmp
|
sed -e 1d -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 1,2\ d -e 's/. seconds\?/1 second/' > $tmp
|
sed -e 1d -e 's/. seconds\?/1 second/' > $tmp
|
||||||
diff $tmp .urchin-output-expectation-color
|
diff $tmp .urchin-output-expectation-color
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
echo "$1" > $tmp
|
echo "$1" > $tmp
|
||||||
NO_MAIN= . ../../../urchin
|
TESTING_URCHIN_INTERNALS=true . ../../../urchin
|
||||||
has_shebang_line $tmp
|
has_shebang_line $tmp
|
||||||
|
|||||||
Reference in New Issue
Block a user