Skip to content

Commit

Permalink
Regression test mode improvements
Browse files Browse the repository at this point in the history
This enters regression test mode automatically when not pid 1. It also
clears the environment in a more robust way. The previous method got
fooled when environment variables contained '\n' characters.
  • Loading branch information
fhunleth committed Jan 29, 2015
1 parent dfa936f commit f2e05f8
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 169 deletions.
27 changes: 14 additions & 13 deletions erlinit.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ static char *merged_argv[MAX_ARGC];

static int verbose = 0;
static int print_timing = 0;
static int debug_mode = 0;
static int regression_test_mode = 0;
static int desired_reboot_cmd = -1;

static char erts_dir[PATH_MAX];
Expand Down Expand Up @@ -121,7 +121,7 @@ static void fatal(const char *fmt, ...)

fprintf(stderr, "\n\nCANNOT CONTINUE.\n");

if (!debug_mode)
if (!regression_test_mode)
sleep(9999);

exit(1);
Expand Down Expand Up @@ -149,7 +149,7 @@ static int readsysfs(const char *path, char *buffer, int maxlen)
static void set_ctty()
{
debug("set_ctty");
if (debug_mode)
if (regression_test_mode)
return;

// Set up a controlling terminal for Erlang so that
Expand Down Expand Up @@ -454,7 +454,7 @@ static void enable_loopback()
static void setup_networking()
{
debug("setup_networking");
if (debug_mode)
if (regression_test_mode)
return;

// Bring up the loopback interface (needed if the erlang distribute protocol code gets run)
Expand Down Expand Up @@ -503,9 +503,8 @@ static unsigned long str_to_mountflags(char *s)

static void setup_filesystems()
{
// Debug mode is currently used for regression tests on a host. Since
// we can't mount anything in this environment, just return.
if (debug_mode)
// Since we can't mount anything in this environment, just return.
if (regression_test_mode)
return;

// Mount and init the virtual file systems.
Expand Down Expand Up @@ -632,7 +631,7 @@ static void child()
static void unmount_all()
{
debug("unmount_all");
if (debug_mode)
if (regression_test_mode)
return;

FILE *fp = fopen("/proc/mounts", "r");
Expand Down Expand Up @@ -726,7 +725,7 @@ void signal_handler(int signum)
static void kill_all()
{
debug("kill_all");
if (debug_mode)
if (regression_test_mode)
return;

// Kill processes the nice way
Expand Down Expand Up @@ -849,20 +848,22 @@ void merge_config(int argc, char *argv[])

int main(int argc, char *argv[])
{
// erlinit should be pid 1. Anything else is not expected, so run in
// regression test mode.
if (getpid() != 1)
regression_test_mode = 1;

// Merge the config file and the command line arguments
merge_config(argc, argv);

int hang_on_exit = 0;
int opt;

while ((opt = getopt(merged_argc, merged_argv, "c:de:hm:r:s:tv")) != -1) {
while ((opt = getopt(merged_argc, merged_argv, "c:e:hm:r:s:tv")) != -1) {
switch (opt) {
case 'c':
controlling_terminal = strdup(optarg);
break;
case 'd':
debug_mode = 1;
break;
case 'e':
additional_env = strdup(optarg);
break;
Expand Down
100 changes: 1 addition & 99 deletions tests/run_tests.sh
Original file line number Diff line number Diff line change
@@ -1,101 +1,3 @@
#!/bin/bash

# Set absolute paths to utilities since we'll clear the environment for testing
# NOTE: It should be possible to delay clearing the environment to make this less
# painful.
CAT=/bin/cat
ECHO=/bin/echo
GREP=/bin/grep
LN=/bin/ln
LS=/bin/ls
MKDIR=/bin/mkdir
RM=/bin/rm
SH=/bin/sh
DIFF=/usr/bin/diff
FAKECHROOT=/usr/bin/fakechroot
SORT=/usr/bin/sort
TOUCH=/usr/bin/touch
CHROOT=/usr/sbin/chroot

TESTS_DIR=$(dirname $(readlink -f $0))

WORK=$TESTS_DIR/work
ERLINIT=$TESTS_DIR/../erlinit
FAKE_ERLEXEC=$TESTS_DIR/fake_erlexec
RESULTS=$WORK/results

FAKE_ERTS_DIR=$WORK/usr/lib/erlang/erts-6.0

# Just in case there are some leftover from a previous test, clear it out
$RM -fr $WORK

[ -e $ERLINIT ] || ( $ECHO "Build $ERLINIT first"; exit 1 )
[ -e $FAKECHROOT ] || ( $ECHO "Can't find $FAKECHROOT"; exit 1 )
[ -e $CHROOT ] || ( $ECHO "Can't find $CHROOT"; exit 1 )

# Forget the environment, since that's how erlinit runs
unset -v `env | sed -e 's/=.*//'`

run() {
TEST=$1
CONFIG=$WORK/$TEST.config
CMDLINE_FILE=$WORK/$TEST.cmdline
EXPECTED=$WORK/$TEST.expected

$ECHO Running $TEST...

# Setup a fake chroot to simulate erlinit boot
$RM -fr $WORK
$MKDIR -p $WORK/sbin
$MKDIR -p $WORK/bin
$MKDIR -p $WORK/etc
$MKDIR -p $WORK/usr/bin
$LN -s $ECHO $WORK/bin/echo
$LN -s $SH $WORK/bin/sh
$LN -s $ERLINIT $WORK/sbin/erlinit
$MKDIR -p $FAKE_ERTS_DIR/bin
$LN -s $FAKE_ERLEXEC $FAKE_ERTS_DIR/bin/erlexec

# Run the test script to setup files for the test
source $TESTS_DIR/$TEST

if [ -e $CONFIG ]; then
$LN -s $CONFIG $WORK/etc/erlinit.config
fi

if [ -e $CMDLINE_FILE ]; then
CMDLINE=$($CAT $CMDLINE_FILE)
else
CMDLINE=
fi

# run
$FAKECHROOT $CHROOT $WORK /sbin/erlinit $CMDLINE 2> $RESULTS.raw

# Trim the results of known lines that vary between runs
$CAT $RESULTS.raw | \
$GREP -vi "erlinit: Env:.*FAKECHROOT" | \
$GREP -v "erlinit: Env: 'LD_" | \
$GREP -v "erlinit: Env: 'SHLVL=" | \
$GREP -v "erlinit: Env: '_=" | \
$GREP -v "erlinit: Env: 'PWD=" \
> $RESULTS

# check results
$DIFF $RESULTS $EXPECTED
if [ $? != 0 ]; then
$ECHO Test $TEST failed!
exit 1
fi
}

# Test command line arguments
TESTS=$($LS $TESTS_DIR/test_* | $SORT)
for TEST_CONFIG in $TESTS; do
TEST=$(/usr/bin/basename $TEST_CONFIG .expected)
run $TEST
done

$RM -fr $WORK
$ECHO Pass!
exit 0
env -i /bin/bash $(dirname $(readlink -f $0))/run_tests_impl.sh
97 changes: 97 additions & 0 deletions tests/run_tests_impl.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/bin/bash

# Set absolute paths to utilities since this should be started in an empty
# environment so simulate how erlinit runs.
CAT=/bin/cat
ECHO=/bin/echo
GREP=/bin/grep
LN=/bin/ln
LS=/bin/ls
MKDIR=/bin/mkdir
RM=/bin/rm
SH=/bin/sh
DIFF=/usr/bin/diff
FAKECHROOT=/usr/bin/fakechroot
SORT=/usr/bin/sort
TOUCH=/usr/bin/touch
CHROOT=/usr/sbin/chroot

TESTS_DIR=$(dirname $(readlink -f $0))

WORK=$TESTS_DIR/work
ERLINIT=$TESTS_DIR/../erlinit
FAKE_ERLEXEC=$TESTS_DIR/fake_erlexec
RESULTS=$WORK/results

FAKE_ERTS_DIR=$WORK/usr/lib/erlang/erts-6.0

# Just in case there are some leftover from a previous test, clear it out
$RM -fr $WORK

[ -e $ERLINIT ] || ( $ECHO "Build $ERLINIT first"; exit 1 )
[ -e $FAKECHROOT ] || ( $ECHO "Can't find $FAKECHROOT"; exit 1 )
[ -e $CHROOT ] || ( $ECHO "Can't find $CHROOT"; exit 1 )

run() {
TEST=$1
CONFIG=$WORK/$TEST.config
CMDLINE_FILE=$WORK/$TEST.cmdline
EXPECTED=$WORK/$TEST.expected

$ECHO Running $TEST...

# Setup a fake chroot to simulate erlinit boot
$RM -fr $WORK
$MKDIR -p $WORK/sbin
$MKDIR -p $WORK/bin
$MKDIR -p $WORK/etc
$MKDIR -p $WORK/usr/bin
$LN -s $ECHO $WORK/bin/echo
$LN -s $SH $WORK/bin/sh
$LN -s $ERLINIT $WORK/sbin/erlinit
$MKDIR -p $FAKE_ERTS_DIR/bin
$LN -s $FAKE_ERLEXEC $FAKE_ERTS_DIR/bin/erlexec

# Run the test script to setup files for the test
source $TESTS_DIR/$TEST

if [ -e $CONFIG ]; then
$LN -s $CONFIG $WORK/etc/erlinit.config
fi

if [ -e $CMDLINE_FILE ]; then
CMDLINE=$($CAT $CMDLINE_FILE)
else
CMDLINE=
fi

# run
$FAKECHROOT $CHROOT $WORK /sbin/erlinit $CMDLINE 2> $RESULTS.raw

# Trim the results of known lines that vary between runs
$CAT $RESULTS.raw | \
$GREP -vi "erlinit: Env:.*FAKECHROOT" | \
$GREP -v "erlinit: Env: 'LD_" | \
$GREP -v "erlinit: Env: 'SHLVL=" | \
$GREP -v "erlinit: Env: '_=" | \
$GREP -v "erlinit: Env: 'PWD=" \
> $RESULTS

# check results
$DIFF $RESULTS $EXPECTED
if [ $? != 0 ]; then
$ECHO Test $TEST failed!
exit 1
fi
}

# Test command line arguments
TESTS=$($LS $TESTS_DIR/test_* | $SORT)
for TEST_CONFIG in $TESTS; do
TEST=$(/usr/bin/basename $TEST_CONFIG .expected)
run $TEST
done

$RM -fr $WORK
$ECHO Pass!
exit 0
20 changes: 18 additions & 2 deletions tests/test_001_cmdline_verbose
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ erlinit: Starting erlinit...
erlinit: cmdline argc=2, merged argc=2
erlinit: merged argv[0]=/sbin/erlinit
erlinit: merged argv[1]=-v
erlinit: Could not mount tmpfs in /tmp: Operation not permitted
Check that tmpfs support is enabled in the kernel config.
erlinit: set_ctty
erlinit: find_erts_directory
erlinit: find_release
erlinit: No release found in /srv/erlang/releases.
erlinit: setup_environment
erlinit: setup_networking
erlinit: Env: 'HOME=/'
erlinit: Env: 'PATH=/usr/sbin:/usr/bin:/sbin:/bin'
erlinit: Env: 'TERM=vt100'
erlinit: Env: 'ROOTDIR=/usr/lib/erlang'
erlinit: Env: 'BINDIR=/usr/lib/erlang/erts-6.0/bin'
erlinit: Env: 'EMU=beam'
erlinit: Env: 'PROGNAME=erl'
erlinit: Arg: 'erlexec'
erlinit: Launching erl...
Hello from erlexec
erlinit: kill_all
erlinit: unmount_all
EOF
20 changes: 18 additions & 2 deletions tests/test_002_config_verbose
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ erlinit: Starting erlinit...
erlinit: cmdline argc=1, merged argc=2
erlinit: merged argv[0]=/sbin/erlinit
erlinit: merged argv[1]=-v
erlinit: Could not mount tmpfs in /tmp: Operation not permitted
Check that tmpfs support is enabled in the kernel config.
erlinit: set_ctty
erlinit: find_erts_directory
erlinit: find_release
erlinit: No release found in /srv/erlang/releases.
erlinit: setup_environment
erlinit: setup_networking
erlinit: Env: 'HOME=/'
erlinit: Env: 'PATH=/usr/sbin:/usr/bin:/sbin:/bin'
erlinit: Env: 'TERM=vt100'
erlinit: Env: 'ROOTDIR=/usr/lib/erlang'
erlinit: Env: 'BINDIR=/usr/lib/erlang/erts-6.0/bin'
erlinit: Env: 'EMU=beam'
erlinit: Env: 'PROGNAME=erl'
erlinit: Arg: 'erlexec'
erlinit: Launching erl...
Hello from erlexec
erlinit: kill_all
erlinit: unmount_all
EOF
35 changes: 0 additions & 35 deletions tests/test_003_run_erl

This file was deleted.

Loading

0 comments on commit f2e05f8

Please sign in to comment.