mirror of
https://github.com/troglobit/finit.git
synced 2026-10-26 12:14:37 +00:00
Merge pull request #158 from troglobit/wip-tests
Test framework and a small set of basic tests Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
23 files changed
+669
-2
No files matched your search
@@ -33,6 +33,9 @@ GTAGS
|
|||||||
/Makefile.in
|
/Makefile.in
|
||||||
/stamp-h1
|
/stamp-h1
|
||||||
|
|
||||||
|
/test-driver
|
||||||
|
/test-suite.log
|
||||||
|
|
||||||
# TroglOS build system
|
# TroglOS build system
|
||||||
/.config
|
/.config
|
||||||
/.stamp
|
/.stamp
|
||||||
|
|||||||
@@ -59,3 +59,7 @@ script:
|
|||||||
- size /tmp/sbin/initctl
|
- size /tmp/sbin/initctl
|
||||||
- size /tmp/sbin/reboot
|
- size /tmp/sbin/reboot
|
||||||
- LD_LIBRARY_PATH=/tmp/lib /tmp/sbin/initctl -h
|
- LD_LIBRARY_PATH=/tmp/lib /tmp/sbin/initctl -h
|
||||||
|
- unshare -V
|
||||||
|
- nsenter -V
|
||||||
|
- chroot --version
|
||||||
|
- 'LD_LIBRARY_PATH=/tmp/lib make distcheck || (cat finit-4.0-beta1/_build/sub/test/test-suite.log; exit 1)'
|
||||||
@@ -5,6 +5,7 @@ Major Contributors:
|
|||||||
* Tobias Waldekranz <tobias@waldekranz.com>
|
* Tobias Waldekranz <tobias@waldekranz.com>
|
||||||
* Mattias Walström <mattias.walstrom@westermo.se>
|
* Mattias Walström <mattias.walstrom@westermo.se>
|
||||||
* Jonas Johansson <jonas.johansson@westermo.se>
|
* Jonas Johansson <jonas.johansson@westermo.se>
|
||||||
|
* Jacques de Laval <jacques@de-laval.se>
|
||||||
|
|
||||||
Original Author(s):
|
Original Author(s):
|
||||||
* Claudio Matsuoka <cmatsuoka@gmail.com>
|
* Claudio Matsuoka <cmatsuoka@gmail.com>
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
SUBDIRS = plugins src
|
SUBDIRS = plugins src test
|
||||||
doc_DATA = README.md LICENSE contrib/finit.conf
|
doc_DATA = README.md LICENSE contrib/finit.conf
|
||||||
EXTRA_DIST = README.md LICENSE ChangeLog.md contrib/finit.conf
|
EXTRA_DIST = README.md LICENSE ChangeLog.md contrib/finit.conf
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -12,7 +12,9 @@ AC_CONFIG_FILES([Makefile
|
|||||||
contrib/void/Makefile contrib/void/finit.d/Makefile contrib/void/finit.d/available/Makefile
|
contrib/void/Makefile contrib/void/finit.d/Makefile contrib/void/finit.d/available/Makefile
|
||||||
doc/Makefile
|
doc/Makefile
|
||||||
plugins/Makefile
|
plugins/Makefile
|
||||||
src/Makefile])
|
src/Makefile
|
||||||
|
test/test.env
|
||||||
|
test/Makefile])
|
||||||
|
|
||||||
# Older versions of autoconf (<2.58) do not have AC_CONFIG_MACRO_DIR()
|
# Older versions of autoconf (<2.58) do not have AC_CONFIG_MACRO_DIR()
|
||||||
#m4_include([m4/plugin.m4])
|
#m4_include([m4/plugin.m4])
|
||||||
@@ -157,12 +159,14 @@ AS_IF([test "x$with_config" != "xno"], [
|
|||||||
conf=$sysconfdir/finit.conf])])
|
conf=$sysconfdir/finit.conf])])
|
||||||
AC_EXPAND_DIR(conf_path, "$conf")
|
AC_EXPAND_DIR(conf_path, "$conf")
|
||||||
AC_DEFINE_UNQUOTED(FINIT_CONF, "$conf_path", [Main Finit configuration file, default /etc/finit.conf])
|
AC_DEFINE_UNQUOTED(FINIT_CONF, "$conf_path", [Main Finit configuration file, default /etc/finit.conf])
|
||||||
|
AC_SUBST(FINIT_CONF, "$conf_path")
|
||||||
|
|
||||||
AS_IF([test "x$with_rcsd" != "xno"], [
|
AS_IF([test "x$with_rcsd" != "xno"], [
|
||||||
AS_IF([test "x$rcsd" = "xyes"], [
|
AS_IF([test "x$rcsd" = "xyes"], [
|
||||||
rcsd=$sysconfdir/finit.d])])
|
rcsd=$sysconfdir/finit.d])])
|
||||||
AC_EXPAND_DIR(rcsd_path, "$rcsd")
|
AC_EXPAND_DIR(rcsd_path, "$rcsd")
|
||||||
AC_DEFINE_UNQUOTED(FINIT_RCSD, "$rcsd_path", [Finit rcS.d/, default /etc/finit.d])
|
AC_DEFINE_UNQUOTED(FINIT_RCSD, "$rcsd_path", [Finit rcS.d/, default /etc/finit.d])
|
||||||
|
AC_SUBST(FINIT_RCSD, "$rcsd_path")
|
||||||
|
|
||||||
AS_IF([test "x$with_rc_local" != "xno"], [
|
AS_IF([test "x$with_rc_local" != "xno"], [
|
||||||
AS_IF([test "x$rclocal" = "xyes"], [
|
AS_IF([test "x$rclocal" = "xyes"], [
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
# GNU configure and build system
|
||||||
|
*.log
|
||||||
|
*.trs
|
||||||
|
/Makefile
|
||||||
|
/Makefile.in
|
||||||
|
|
||||||
|
/test.env
|
||||||
|
/checkself.sh
|
||||||
|
/tenv-root
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
EXTRA_DIST = tenv/lib.sh tenv/exec.sh tenv/start.sh
|
||||||
|
EXTRA_DIST += tenv/root.mk tenv/busybox-x86_64.md5
|
||||||
|
EXTRA_DIST += tenv/chrootsetup.sh
|
||||||
|
EXTRA_DIST += setup-root.sh
|
||||||
|
EXTRA_DIST += common/service.conf common/service.sh
|
||||||
|
EXTRA_DIST += checkself.sh
|
||||||
|
EXTRA_DIST += add-remove-dynamic-service.sh
|
||||||
|
EXTRA_DIST += add-remove-dynamic-service-sub-config.sh
|
||||||
|
EXTRA_DIST += start-stop-service.sh
|
||||||
|
EXTRA_DIST += start-stop-service-sub-config.sh
|
||||||
|
|
||||||
|
AM_TESTS_ENVIRONMENT = TENV_ROOT='$(abs_builddir)/tenv-root/';
|
||||||
|
AM_TESTS_ENVIRONMENT += export TENV_ROOT;
|
||||||
|
AM_TESTS_ENVIRONMENT += export LD_LIBRARY_PATH;
|
||||||
|
AM_TESTS_ENVIRONMENT += top_builddir=$(top_builddir);
|
||||||
|
AM_TESTS_ENVIRONMENT += export top_builddir;
|
||||||
|
|
||||||
|
checkself.sh:
|
||||||
|
echo '#!/bin/sh' > $@
|
||||||
|
echo shellcheck $(addprefix '"$$srcdir"'/,$(filter %.sh,$(filter-out $@, $(EXTRA_DIST)))) >> $@
|
||||||
|
chmod +x $@
|
||||||
|
|
||||||
|
TEST_EXTENSIONS = .sh
|
||||||
|
TESTS = checkself.sh
|
||||||
|
TESTS += setup-root.sh
|
||||||
|
TESTS += add-remove-dynamic-service.sh
|
||||||
|
TESTS += add-remove-dynamic-service-sub-config.sh
|
||||||
|
TESTS += start-stop-service.sh
|
||||||
|
TESTS += start-stop-service-sub-config.sh
|
||||||
|
|
||||||
|
clean-local:
|
||||||
|
-rm -rf $(builddir)/tenv-root/
|
||||||
|
-rm -f checkself.sh
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
Tests
|
||||||
|
=====
|
||||||
|
|
||||||
|
Finit comes with a set of tests and a small framework for running them.
|
||||||
|
Contributors are encouraged to write new tests when implementing features, or
|
||||||
|
fixing bugs.
|
||||||
|
|
||||||
|
Each test is run in isolation, in it's own namespace. Finit will therefore
|
||||||
|
be able to be launched as PID 1. Since it's also running with it's own root
|
||||||
|
directory it will be able to function properly without having any super user
|
||||||
|
privileges in the host environment.
|
||||||
|
|
||||||
|
Running tests
|
||||||
|
-------------
|
||||||
|
|
||||||
|
To run the test suite, first [build](../doc/build.md) Finit - then simply run:
|
||||||
|
|
||||||
|
make check
|
||||||
|
|
||||||
|
`make check` will set up the required assets for the test environment, and then
|
||||||
|
run the full set of tests. The environment is not removed afterwards so at
|
||||||
|
this point individual tests can be executed without having to run the entire
|
||||||
|
test suite, which is handy when developing new tests or debugging existing
|
||||||
|
test. To execute an individual test, simply invoke the script containing it:
|
||||||
|
|
||||||
|
./test/name-of-the-test.sh
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
TEST_DIR=$(dirname "$0")
|
||||||
|
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
. "$TEST_DIR/tenv/lib.sh"
|
||||||
|
|
||||||
|
test_teardown() {
|
||||||
|
say "Test done $(date)"
|
||||||
|
say "Running test teardown."
|
||||||
|
|
||||||
|
texec rm -f "$FINIT_RCSD/service.conf"
|
||||||
|
texec rm -f /test_assets/service.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
say "Test start $(date)"
|
||||||
|
|
||||||
|
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
|
||||||
|
|
||||||
|
say "Add a dynamic service in $FINIT_RCSD/service.conf"
|
||||||
|
texec sh -c "echo 'service [2345] kill:20 log /test_assets/service.sh' > $FINIT_RCSD/service.conf"
|
||||||
|
|
||||||
|
say 'Reload Finit'
|
||||||
|
texec sh -c "initctl reload"
|
||||||
|
|
||||||
|
retry 'assert_num_children 1 service.sh'
|
||||||
|
|
||||||
|
say 'Remove the dynamic service from /etc/finit.d/service.conf'
|
||||||
|
texec sh -c "echo > $FINIT_RCSD/service.conf"
|
||||||
|
|
||||||
|
say 'Reload Finit'
|
||||||
|
texec sh -c "initctl reload"
|
||||||
|
|
||||||
|
retry 'assert_num_children 0 service.sh'
|
||||||
Executable
+36
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
TEST_DIR=$(dirname "$0")
|
||||||
|
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
. "$TEST_DIR/tenv/lib.sh"
|
||||||
|
|
||||||
|
test_teardown() {
|
||||||
|
say "Test done $(date)"
|
||||||
|
say "Running test teardown."
|
||||||
|
|
||||||
|
texec rm -f "$FINIT_CONF"
|
||||||
|
texec rm -f /test_assets/service.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
say "Test start $(date)"
|
||||||
|
|
||||||
|
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
|
||||||
|
|
||||||
|
say "Add a dynamic service in $FINIT_CONF"
|
||||||
|
texec sh -c "echo 'service [2345] kill:20 log /test_assets/service.sh' > $FINIT_CONF"
|
||||||
|
|
||||||
|
say 'Reload Finit'
|
||||||
|
texec sh -c "initctl reload"
|
||||||
|
|
||||||
|
retry 'assert_num_children 1 service.sh'
|
||||||
|
|
||||||
|
say 'Remove the dynamic service from /etc/finit.conf'
|
||||||
|
texec sh -c "echo > $FINIT_CONF"
|
||||||
|
|
||||||
|
say 'Reload Finit'
|
||||||
|
texec sh -c "initctl reload"
|
||||||
|
|
||||||
|
retry 'assert_num_children 0 service.sh'
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
service [2345] kill:20 log /test_assets/service.sh
|
||||||
Executable
+7
@@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
Executable
+8
@@ -0,0 +1,8 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
make -C "$top_builddir" DESTDIR="$TENV_ROOT" install
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
FINITBIN="$(pwd)/$top_builddir/src/finit" DEST="$TENV_ROOT" make -f "$srcdir/tenv/root.mk"
|
||||||
Executable
+38
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
TEST_DIR=$(dirname "$0")
|
||||||
|
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
. "$TEST_DIR/tenv/lib.sh"
|
||||||
|
|
||||||
|
test_teardown() {
|
||||||
|
say "Test done $(date)"
|
||||||
|
say "Running test teardown."
|
||||||
|
|
||||||
|
texec rm -f "$FINIT_RCSD/service.conf"
|
||||||
|
texec rm -f /test_assets/service.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
say "Test start $(date)"
|
||||||
|
|
||||||
|
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
|
||||||
|
|
||||||
|
say "Add service stanza in $FINIT_RCSD/service.conf"
|
||||||
|
texec sh -c "echo 'service [2345] kill:20 log /test_assets/service.sh' > $FINIT_RCSD/service.conf"
|
||||||
|
|
||||||
|
say 'Reload Finit'
|
||||||
|
texec sh -c "initctl reload"
|
||||||
|
|
||||||
|
retry 'assert_num_children 1 service.sh'
|
||||||
|
|
||||||
|
say 'Stop the service'
|
||||||
|
texec sh -c "initctl stop service.sh"
|
||||||
|
|
||||||
|
retry 'assert_num_children 0 service.sh'
|
||||||
|
|
||||||
|
say 'Start the service again'
|
||||||
|
texec sh -c "initctl start service.sh"
|
||||||
|
|
||||||
|
retry 'assert_num_children 1 service.sh'
|
||||||
Executable
+38
@@ -0,0 +1,38 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
TEST_DIR=$(dirname "$0")
|
||||||
|
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
. "$TEST_DIR/tenv/lib.sh"
|
||||||
|
|
||||||
|
test_teardown() {
|
||||||
|
say "Test done $(date)"
|
||||||
|
say "Running test teardown."
|
||||||
|
|
||||||
|
texec rm -f "$FINIT_CONF"
|
||||||
|
texec rm -f /test_assets/service.sh
|
||||||
|
}
|
||||||
|
|
||||||
|
say "Test start $(date)"
|
||||||
|
|
||||||
|
cp "$TEST_DIR"/common/service.sh "$TENV_ROOT"/test_assets/
|
||||||
|
|
||||||
|
say "Add service stanza in $FINIT_CONF"
|
||||||
|
texec sh -c "echo 'service [2345] kill:20 log /test_assets/service.sh' > $FINIT_CONF"
|
||||||
|
|
||||||
|
say 'Reload Finit'
|
||||||
|
texec sh -c "initctl reload"
|
||||||
|
|
||||||
|
retry 'assert_num_children 1 service.sh'
|
||||||
|
|
||||||
|
say 'Stop the service'
|
||||||
|
texec sh -c "initctl stop service.sh"
|
||||||
|
|
||||||
|
retry 'assert_num_children 0 service.sh'
|
||||||
|
|
||||||
|
say 'Start the service again'
|
||||||
|
texec sh -c "initctl start service.sh"
|
||||||
|
|
||||||
|
retry 'assert_num_children 1 service.sh'
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
ea7e2353af0067a926d3e021e504290e busybox-x86_64
|
||||||
Executable
+49
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Setup the things (mount /proc, /tmp, etc.) that needs to be set up from
|
||||||
|
# within the namespace/chroot and then start PID 1.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Jacques de Laval <jacques@de-laval.se>
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
# It would have been nice to mount /dev as devtmpfs, but unfortunately
|
||||||
|
# that's not possible if you're not privileged. For now tmpfs will
|
||||||
|
# have to do.
|
||||||
|
mount -n -t tmpfs none /dev
|
||||||
|
|
||||||
|
mount -t proc none /proc
|
||||||
|
mount -t sysfs none /sys
|
||||||
|
|
||||||
|
if [ "$(ls -A /tmp)" ]; then
|
||||||
|
mkdir -p /tmp.shadow
|
||||||
|
mount --bind /tmp /tmp.shadow
|
||||||
|
mount -t tmpfs none /tmp
|
||||||
|
cp -a /tmp.shadow/* /tmp/
|
||||||
|
else
|
||||||
|
mount -t tmpfs none /tmp
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$FINIT_RCSD"
|
||||||
|
|
||||||
|
tty=/dev/$(cat /sys/class/tty/console/active)
|
||||||
|
mkfifo "$tty"
|
||||||
|
|
||||||
|
exec "$@"
|
||||||
Executable
+27
@@ -0,0 +1,27 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
cmd=""
|
||||||
|
if [ "$#" -lt 1 ]; then
|
||||||
|
cmd="/bin/sh"
|
||||||
|
else
|
||||||
|
cmd=$1
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
TEST_DIR=$(dirname "$0")/..
|
||||||
|
TENV_ROOT="${TENV_ROOT:-$(pwd)/${TEST_DIR}/tenv-root}"
|
||||||
|
PID_FILE="$TENV_ROOT/running_test.pid"
|
||||||
|
|
||||||
|
if [ -f "$PID_FILE" ] ; then
|
||||||
|
target=$(cat "$PID_FILE")
|
||||||
|
target=$(pgrep -P "$target")
|
||||||
|
else
|
||||||
|
echo "No test running!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
source "$TEST_DIR/test.env"
|
||||||
|
|
||||||
|
"$(dirname "$0")"/exec.sh "$target" "$cmd" "$@"
|
||||||
Executable
+57
@@ -0,0 +1,57 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Execute a given command from withing the test environment.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Jacques de Laval <jacques@de-laval.se>
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
if [ "$#" -lt 2 ]; then
|
||||||
|
echo "Usage:"
|
||||||
|
echo " $0 [target-pid] [command [arguments]]"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
target="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
TEST_DIR=$(dirname "$0"../)
|
||||||
|
TENV_ROOT="${TENV_ROOT:-$(pwd)/${TEST_DIR}/tenv-root}"
|
||||||
|
|
||||||
|
nsenter=$(command -v nsenter)
|
||||||
|
chroot=$(command -v chroot)
|
||||||
|
|
||||||
|
export PS1='\w \$ '
|
||||||
|
export PS2='> '
|
||||||
|
export PS3='#? '
|
||||||
|
export PS4='+ '
|
||||||
|
|
||||||
|
PATH="$TESTENV_PATH"
|
||||||
|
export PATH
|
||||||
|
|
||||||
|
"$nsenter" \
|
||||||
|
--preserve-credentials \
|
||||||
|
--user \
|
||||||
|
--mount \
|
||||||
|
--uts \
|
||||||
|
--ipc \
|
||||||
|
--net \
|
||||||
|
--pid \
|
||||||
|
-w -t "$target" \
|
||||||
|
"$chroot" "$TENV_ROOT" "$@"
|
||||||
Executable
+144
@@ -0,0 +1,144 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Small framework for executing tests in a test environment.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Jacques de Laval <jacques@de-laval.se>
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
assert_num_children() {
|
||||||
|
assert "$1 services are running" "$(texec pgrep -P 1 "$2" | wc -l)" -eq "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
texec() {
|
||||||
|
# shellcheck disable=SC2154
|
||||||
|
"$TEST_DIR/tenv/exec.sh" "$finit_pid" "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
pause() {
|
||||||
|
echo "Press any key to continue... "
|
||||||
|
read -r REPLY
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle_finit_debug() {
|
||||||
|
say 'Toggle finit debug'
|
||||||
|
texec initctl debug
|
||||||
|
sleep 0.5
|
||||||
|
}
|
||||||
|
|
||||||
|
color_reset='\e[0m'
|
||||||
|
fg_red='\e[1;31m'
|
||||||
|
fg_green='\e[1;32m'
|
||||||
|
fg_yellow='\e[1;33m'
|
||||||
|
log() {
|
||||||
|
printf "< %s > %b%b%b %s\n" "$0" "$1" "$2" "$color_reset" "$3"
|
||||||
|
}
|
||||||
|
|
||||||
|
assert() {
|
||||||
|
__assert_msg=$1
|
||||||
|
shift
|
||||||
|
if [ ! "$@" ]; then
|
||||||
|
log "$fg_red" ✘ "$__assert_msg ($*)"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
log "$fg_green" ✔ "$__assert_msg"
|
||||||
|
}
|
||||||
|
|
||||||
|
retry() {
|
||||||
|
__retry_cmd=$1
|
||||||
|
shift
|
||||||
|
case "$#" in
|
||||||
|
2)
|
||||||
|
__retry_n=$1
|
||||||
|
__retry_sleep=$2
|
||||||
|
;;
|
||||||
|
1)
|
||||||
|
__retry_n=$1
|
||||||
|
__retry_sleep=0.1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
__retry_n=50
|
||||||
|
__retry_sleep=0.1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
for _ in $(seq 1 "$__retry_n"); do
|
||||||
|
sleep "$__retry_sleep"
|
||||||
|
__retry_cmd_out=$(eval "$__retry_cmd") && \
|
||||||
|
echo "$__retry_cmd_out" && \
|
||||||
|
return 0
|
||||||
|
done
|
||||||
|
__retry_cmd_exit="$?"
|
||||||
|
echo "$__retry_cmd_out"
|
||||||
|
return "$__retry_cmd_exit"
|
||||||
|
}
|
||||||
|
|
||||||
|
say() {
|
||||||
|
log "$fg_yellow" • "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
teardown() {
|
||||||
|
test_status="$?"
|
||||||
|
|
||||||
|
if type test_teardown > /dev/null 2>&1 ; then
|
||||||
|
test_teardown
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "$color_reset" '--' ''
|
||||||
|
if [ "$test_status" -eq 0 ]; then
|
||||||
|
log "$fg_green" 'TEST PASS' ''
|
||||||
|
else
|
||||||
|
log "$fg_red" 'TEST FAIL' ''
|
||||||
|
fi
|
||||||
|
if [ -n "${finit_pid+x}" ]; then
|
||||||
|
texec kill -SIGUSR2 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
wait
|
||||||
|
|
||||||
|
if [ -d "$TENV_ROOT/var/lock" ]; then
|
||||||
|
chmod +r "$TENV_ROOT/var/lock"
|
||||||
|
fi
|
||||||
|
rm -f "$TENV_ROOT"/running_test.pid
|
||||||
|
}
|
||||||
|
|
||||||
|
trap teardown EXIT
|
||||||
|
|
||||||
|
TENV_ROOT="${TENV_ROOT:-$(pwd)/${TEST_DIR}/tenv-root}"
|
||||||
|
export TENV_ROOT
|
||||||
|
|
||||||
|
# shellcheck source=/dev/null
|
||||||
|
. "$TENV_ROOT/../test.env"
|
||||||
|
|
||||||
|
# Setup test environment
|
||||||
|
if [ -n "${DEBUG:-}" ]; then
|
||||||
|
FINIT_ARGS="${FINIT_ARGS:-} finit.debug=on"
|
||||||
|
fi
|
||||||
|
# shellcheck disable=2086
|
||||||
|
"$TEST_DIR/tenv/start.sh" finit ${FINIT_ARGS:-} &
|
||||||
|
finit_ppid=$!
|
||||||
|
echo "$finit_ppid" > "$TENV_ROOT"/running_test.pid
|
||||||
|
|
||||||
|
>&2 echo "Hint: Execute 'TENV_ROOT=$TENV_ROOT $TEST_DIR/tenv/enter.sh' to enter the test namespace"
|
||||||
|
log "$color_reset" 'Setup of test environment done' ''
|
||||||
|
|
||||||
|
finit_pid=$(retry "pgrep -P $finit_ppid")
|
||||||
|
|
||||||
|
tty=/dev/$(texec cat /sys/class/tty/console/active)
|
||||||
|
texec cat "$tty" &
|
||||||
|
sleep 1
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
# Root file system for test environment.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Jacques de Laval <jacques@de-laval.se>
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
DEST ?= ../tenv-root
|
||||||
|
srcdir ?= ../
|
||||||
|
|
||||||
|
ARCH ?= x86_64
|
||||||
|
|
||||||
|
FINITBIN ?= ./sbin/finit
|
||||||
|
|
||||||
|
BBVER ?= 1.31.0
|
||||||
|
BBBIN = busybox-$(ARCH)
|
||||||
|
BBURL ?= https://www.busybox.net/downloads/binaries/$(BBVER)-defconfig-multiarch-musl/$(BBBIN)
|
||||||
|
|
||||||
|
binaries = $(DEST)/bin/cat \
|
||||||
|
$(DEST)/bin/cp \
|
||||||
|
$(DEST)/bin/date \
|
||||||
|
$(DEST)/bin/echo \
|
||||||
|
$(DEST)/bin/env \
|
||||||
|
$(DEST)/bin/find \
|
||||||
|
$(DEST)/bin/kill \
|
||||||
|
$(DEST)/bin/ls \
|
||||||
|
$(DEST)/bin/mkdir \
|
||||||
|
$(DEST)/bin/mkfifo \
|
||||||
|
$(DEST)/bin/mknod \
|
||||||
|
$(DEST)/bin/mount \
|
||||||
|
$(DEST)/bin/printf \
|
||||||
|
$(DEST)/bin/pgrep \
|
||||||
|
$(DEST)/bin/ps \
|
||||||
|
$(DEST)/bin/rm \
|
||||||
|
$(DEST)/bin/sh \
|
||||||
|
$(DEST)/bin/sleep \
|
||||||
|
$(DEST)/bin/top \
|
||||||
|
$(DEST)/bin/touch
|
||||||
|
|
||||||
|
dirs = $(DEST)/bin \
|
||||||
|
$(DEST)/dev \
|
||||||
|
$(DEST)/etc \
|
||||||
|
$(DEST)/proc \
|
||||||
|
$(DEST)/sbin \
|
||||||
|
$(DEST)/sys \
|
||||||
|
$(DEST)/test_assets \
|
||||||
|
$(DEST)/tmp
|
||||||
|
|
||||||
|
_libs_src = $(shell ldd $(FINITBIN) | grep -Eo '/[^ ]+')
|
||||||
|
libs = $(foreach path,$(_libs_src),$(abspath $(DEST))$(path))
|
||||||
|
|
||||||
|
all: $(dirs) $(binaries) $(libs) $(DEST)/bin/chrootsetup.sh
|
||||||
|
|
||||||
|
$(dirs):
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
$(DEST)/bin/$(BBBIN).md5:
|
||||||
|
cp $(srcdir)/tenv/$(notdir $@) $@
|
||||||
|
|
||||||
|
$(DEST)/bin/$(BBBIN): $(DEST)/bin/$(BBBIN).md5
|
||||||
|
wget -O $@ $(BBURL)
|
||||||
|
chmod +x $@
|
||||||
|
cd $(dir $@); \
|
||||||
|
md5sum -c $(BBBIN).md5
|
||||||
|
|
||||||
|
$(DEST)/bin/chrootsetup.sh:
|
||||||
|
cp $(srcdir)/tenv/$(notdir $@) $@
|
||||||
|
|
||||||
|
$(binaries): $(DEST)/bin/$(BBBIN)
|
||||||
|
cd $(DEST)/bin; \
|
||||||
|
rm -f $(notdir $@); \
|
||||||
|
ln -s $(BBBIN) $(notdir $@)
|
||||||
|
|
||||||
|
$(libs):
|
||||||
|
mkdir -p $(dir $@)
|
||||||
|
cp $(patsubst $(abspath $(DEST))%,%,$@) $@
|
||||||
Executable
+48
@@ -0,0 +1,48 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# Start a new test environment.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 Jacques de Laval <jacques@de-laval.se>
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
TEST_DIR=$(dirname "$0"../)
|
||||||
|
TENV_ROOT="${TENV_ROOT:-$(pwd)/${TEST_DIR}/tenv-root}"
|
||||||
|
|
||||||
|
unshare=$(command -v unshare)
|
||||||
|
chroot=$(command -v chroot)
|
||||||
|
|
||||||
|
export PS1='\w \$ '
|
||||||
|
export PS2='> '
|
||||||
|
export PS3='#? '
|
||||||
|
export PS4='+ '
|
||||||
|
|
||||||
|
PATH="$TESTENV_PATH"
|
||||||
|
export PATH
|
||||||
|
|
||||||
|
# Not supported by Busybox unshare:
|
||||||
|
# --cgroup --time
|
||||||
|
exec "$unshare" \
|
||||||
|
--user --map-root-user \
|
||||||
|
--fork --pid --mount-proc \
|
||||||
|
--mount \
|
||||||
|
--mount-proc \
|
||||||
|
--uts --ipc --net \
|
||||||
|
"$chroot" "$TENV_ROOT" /bin/chrootsetup.sh "$@"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
|
||||||
|
export TESTENV_PATH=/bin:/sbin:"@bindir@":"@sbindir@"
|
||||||
|
export FINIT_CONF="@FINIT_CONF@"
|
||||||
|
export FINIT_RCSD="@FINIT_RCSD@"
|
||||||
Reference in new issue
Block a user