@@ -64,6 +64,9 @@ $(LIBFDT_archive): $(addprefix $(LIBFDT_objdir)/,$(LIBFDT_OBJS))
-include */.*.d */*/.*.d
+standalone: all
+ @scripts/mkallstandalone.sh
+
install:
mkdir -p $(DESTDIR)
install $(tests_and_config) $(DESTDIR)
@@ -78,6 +81,7 @@ libfdt_clean:
distclean: clean libfdt_clean
$(RM) lib/asm config.mak $(TEST_DIR)-run test.log msr.out cscope.*
+ $(RM) -r tests
cscope: common_dirs = lib lib/libfdt lib/asm lib/asm-generic
cscope:
new file mode 100755
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+kernel=
+testname=
+
+if [ ! -f config.mak ]; then
+ echo "run ./configure && make first. See ./configure -h"
+ exit
+fi
+source config.mak
+
+exec {fd}<$TEST_DIR/unittests.cfg
+
+while read -u $fd line; do
+ if [[ "$line" =~ ^\[(.*)\]$ ]]; then
+ if [ "$testname" ]; then
+ printf "%-40s(%s)\n" $testname $kernel
+ scripts/mkstandalone.sh $kernel $testname
+ fi
+ testname=${BASH_REMATCH[1]}
+ kernel=""
+ arch=""
+ elif [[ $line =~ ^file\ *=\ *(.*)$ ]]; then
+ kernel=$TEST_DIR/${BASH_REMATCH[1]}
+ elif [[ $line =~ ^arch\ *=\ *(.*)$ ]]; then
+ arch=${BASH_REMATCH[1]}
+ if [ -n "$arch" ] && [ "$arch" != "$ARCH" ]; then
+ testname=""
+ kernel=""
+ arch=""
+ fi
+ fi
+done
+printf "%-40s(%s)\n" $testname $kernel
+scripts/mkstandalone.sh $kernel $testname
+exec {fd}<&-
new file mode 100755
@@ -0,0 +1,110 @@
+#!/usr/bin/bash
+
+if [ -z "$1" ]; then
+ echo "usage: mkstandalone.sh <kernel> [testname]"
+ exit 1
+fi
+
+if [ ! -f config.mak ]; then
+ echo "run ./configure && make first. See ./configure -h"
+ exit
+fi
+source config.mak
+
+kernel=$1
+kernel_base=$(basename $kernel)
+testname=$2
+if [ -z "$testname" ]; then
+ testname=${kernel_base%.*}
+fi
+standalone="tests/${testname}"
+bin=$(mktemp)
+cfg=$(mktemp)
+cfg2=$(mktemp)
+arch=
+check=
+opts=
+
+mkdir -p tests
+trap "{ rm -f $bin $cfg $cfg2; exit 1; }" INT TERM
+trap "{ rm -f $bin $cfg $cfg2; }" EXIT
+
+gzip - < $kernel | base64 > $bin
+
+if grep -q "\[$testname\]" $TEST_DIR/unittests.cfg; then
+ sed -n "/\\[$testname\\]/,/^\\[/p" $TEST_DIR/unittests.cfg \
+ | awk '!/^\[/ || NR == 1' > $cfg
+ arch="$(grep ^arch $cfg | cut -d= -f2- | sed 's/^ *//')"
+ check="$(grep ^check $cfg | cut -d= -f2- | sed 's/^ *//')"
+ opts="$(grep ^extra_params $cfg | cut -d= -f2- | sed 's/^ *//')"
+ grep -ve ^arch -e ^check -e ^extra_params $cfg > $cfg2
+ cp -f $cfg2 $cfg
+else
+ echo "[$testname]" > $cfg
+ echo "file = $kernel_base" >> $cfg
+fi
+./run_tests.sh -d -u $cfg >& /dev/null
+qemu=$(cut -d' ' -f1 < test.log)
+cmdline=$(cut -d' ' -f2- < test.log)
+
+cat <<EOF > $standalone
+#!/bin/bash
+scr=\$(mktemp)
+bin1=\$(mktemp)
+bin2=\$(mktemp)
+trap '{ rm -f \$scr \$bin1 \$bin2; exit 1; }' INT TERM
+trap '{ rm -f \$scr \$bin1 \$bin2; }' EXIT
+# ============= SCR ==============
+cat - > \$scr << 'SHAR_EOF' &&
+#!/bin/bash
+
+standalone=\$1
+kernel=\$2
+
+ARCH=\`uname -m | sed -e s/i.86/i386/ | sed -e 's/arm.*/arm/'\`
+[ "\$ARCH" = "aarch64" ] && ARCH="arm64"
+
+qemu="\${QEMU:-$qemu}"
+cmdline_orig='$cmdline $opts'
+cmdline="\$(echo '$cmdline $opts' | sed s%$kernel%\$kernel%)"
+arch="$arch"
+check="$check"
+
+if [ -n "\$arch" ] && [ "\$arch" != "\$ARCH" ]; then
+ echo "skip $testname (\$arch only)" 1>&2
+ exit 1
+fi
+
+for p in \$check; do
+ path=\${p%%=*}
+ value=\${p#*=}
+ if [ "\$path" ] && [ "\$(cat \$path)" != "\$value" ]; then
+ echo "skip $testname (\$path not equal to \$value)" 1>&2
+ exit 1
+ fi
+done
+
+eval echo \$qemu \$cmdline_orig
+eval \$qemu \$cmdline
+ret=\$?
+echo Return value from qemu: \$ret
+if [ \$? -le 1 ]; then
+ echo -e "\e[32mPASS\e[0m \$standalone" 1>&2
+else
+ echo -e "\e[31mFAIL\e[0m \$standalone" 1>&2
+fi
+exit 0
+SHAR_EOF
+chmod +x \$scr
+# ============= BIN ==============
+cat - > \$bin1 << 'SHAR_EOF' &&
+EOF
+cat $bin >> $standalone
+cat <<EOF >> $standalone
+SHAR_EOF
+base64 -d \$bin1 | zcat > \$bin2
+\$scr \$(basename \$0) \$bin2
+ret=\$?
+exit \$ret
+EOF
+chmod +x $standalone
This is a super ugly bash script, wrapped around a couple ugly bash scripts, and it generates an ugly bash script. But, it gets the job done. What's the job? Take a unit test and generate a standalone script that can be run on any appropriate system with an appropriate qemu. This makes distributing single, pre-compiled, unit tests easy, even through email, which can be useful for getting test results from a variety of users, or even for deploying the unit test as utility (if it works that way) in a distribution. Works like shar, but doesn't use shar, as it's better to avoid the dependency. mkstandalone.sh just creates one unit test. mkallstandalone.sh does all (run with 'make standalone'). The standalone test(s) are placed in ./tests Signed-off-by: Andrew Jones <drjones@redhat.com> --- Makefile | 4 ++ scripts/mkallstandalone.sh | 36 +++++++++++++++ scripts/mkstandalone.sh | 110 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100755 scripts/mkallstandalone.sh create mode 100755 scripts/mkstandalone.sh