1#!/bin/bash 2 3# usage: mkroot/testroot.sh [TARGET...] 4# 5# Test system image(s) (by booting qemu with -hda test.img providing /mnt/init) 6# and check that: 7# 8# A) it boots and runs our code (which means /dev/hda works) 9# B) the clock is set sanely ("make" is unhappy when source newer than output) 10# C) it can talk to the virtual network 11# 12# Each successful test prints a === line, and all 3 means it passed. 13# Writes result into root/build/test/$TARGET-test.txt 14# 15# With arguments, tests those targets (verbosely). With no arguments, tests 16# each target with a linux-kernel (in parallel) and prints pass/fail summary. 17 18die() { echo "$@"; exit 1; } 19 20[ -n "$(which toybox)" -a -n "$(which mksquashfs)" ] || 21 die "Need toybox and mksquashfs in $PATH" 22 23mkdir -p "${TEST:=$PWD/root/build/test}" && 24 25# Setup test filesystem and package it into a squashfs. 26cat > "$TEST"/init << 'EOF' && 27#!/bin/sh 28 29echo 30echo === init $HOST 31[ "$(date +%s)" -gt 1500000000 ] && echo === date ok $HOST 32wget http://10.0.2.2:65432 -O - 33# TODO: cd /mnt && scripts/test.sh 34EOF 35chmod +x "$TEST"/init && 36 37mksquashfs "$TEST"/init configure scripts/ tests/ "$TEST"/init.sqf -noappend -all-root >/dev/null && 38 39# Setup server on host's loopback for network smoke test 40echo === net ok > "$TEST"/index.html || die "smoketest setup" 41toybox netcat -p 65432 -s 127.0.0.1 -L toybox httpd "$TEST" & 42trap "kill $!" EXIT 43sleep .25 44 45[ -n "$(toybox wget http://127.0.0.1:65432/ -O - | grep ===)" ] || die "wget" 46 47do_test() 48{ 49 X=$(dirname "$1") Y=$(basename $X) 50 [ ! -e "$1" ] && { echo skip "$Y"; return 0; } 51 # Alas KARGS=quiet doesn't silence qemu's bios, so filter output ourselves. 52 # QEMU broke -hda because too many people know how to use it, this is 53 # the new edgier version they added to be -hda without gratuitous breakage. 54 { 55 cd $X || continue 56 echo === $X 57 # Can't point two QEMU instances at same sqf because gratuitous file locking 58 cp "$TEST"/init.{sqf,$BASHPID} && 59 # When stdin is a tty QEMU will SIGTTOU itself here, so </dev/null. 60 toybox timeout -i 10 bash -c "./run-qemu.sh -drive format=raw,file='$TEST'/init.$BASHPID < /dev/null 2>&1" 61 rm -f "$TEST/init.$BASHPID" 62 cd ../.. 63 } | tee root/build/log/$Y-test.txt | { [ -z "$V" ] && cat >/dev/null || { [ "$V" -gt 1 ] && cat || grep '^=== '; } } 64} 65 66# Just test targets on command line? 67if [ $# -gt 0 ]; then 68 ((V++)) 69 for I in "$@"; do do_test root/"$I"/linux-kernel; done 70 exit 71fi 72 73COUNT=0 CPUS=$(($(nproc)+0)) 74for I in root/*/linux-kernel 75do 76 do_test "$I" | { [ -z "$V" ] && cat >/dev/null || { [ "$V" -gt 1 ] && cat || grep '^=== '; } } & 77 [ $((++COUNT)) -ge $CPUS ] && 78 { wait -n; ((--COUNT)); [ -z "$V" ] && echo -n .; } 79done 80 81while [ $COUNT -gt 0 ]; do 82 wait -n; ((--COUNT)); [ -z "$V" ] && echo -n . 83done 84echo 85 86PASS= NOPASS= 87for I in root/*/linux-kernel 88do 89 [ ! -e "$I" ] && continue 90 X=$(dirname $I) Y=$(basename $X) 91 92 [ "$(grep '^=== ' root/build/log/$Y-test.txt | wc -l)" -eq 4 ] && 93 PASS+="$Y " || NOPASS+="$Y " 94done 95 96[ -n "$PASS" ] && echo PASS=$PASS 97[ -n "$NOPASS" ] && echo NOPASS=$NOPASS 98X="$(ls root | egrep -xv "$(ls root/*/linux-kernel | sed 's@root/\([^/]*\)/linux-kernel@\1@' | tr '\n' '|')build" | xargs)" 99[ -n "$X" ] && echo No kernel: $X 100