1#!/bin/sh 2 3# Common unit test commands 4set -e 5 6export LC_ALL=C 7 8# Linux command line tools that may be different on other OSes 9READLINK=readlink 10BASE64_DECODE=-d 11TIMEOUT=timeout 12 13if [ -d "/mnt/c/Users" ]; then 14 # Windows 10 bash mode 15 HOST_OS=Windows 16 HOST_ARCH=amd64 17else 18 HOST_OS=$(uname -s) 19 HOST_ARCH=$(uname -m) 20fi 21 22case "$HOST_OS" in 23 Darwin) 24 # BSD stat 25 STAT_FILESIZE_FLAGS="-f %z" 26 27 # Not -d? 28 BASE64_DECODE=-D 29 30 BREW_PREFIX=$(brew --prefix) 31 READLINK="$BREW_PREFIX"/bin/greadlink 32 [ -e "$READLINK" ] || ( echo "Please run 'brew install coreutils' to install greadlink"; exit 1 ) 33 [ -e "$BREW_PREFIX/bin/mdir" ] || ( echo "Please run 'brew install mtools' to install mdir"; exit 1 ) 34 35 FSCK_FAT="$(brew --prefix dosfstools)/sbin/fsck.fat" 36 if [ -f "$FSCK_FAT" ]; then 37 FSCK_FAT="$FSCK_FAT -n" 38 else 39 # Fall back to the OSX fsck_msdos which isn't as picky, but still catches issues. 40 FSCK_FAT=fsck_msdos 41 fi 42 43 TIMEOUT=gtimeout 44 ;; 45 FreeBSD|NetBSD|OpenBSD|DragonFly) 46 # BSD stat 47 STAT_FILESIZE_FLAGS="-f %z" 48 49 # fsck_msdosfs fails on BSD, but the failure doesn't look like a 50 # problem, so ignore. 51 #FSCK_FAT=fsck_msdosfs 52 FSCK_FAT=true 53 54 # The BSDs don't have the timeout command 55 TIMEOUT= 56 ;; 57 *) 58 # GNU stat 59 STAT_FILESIZE_FLAGS=-c%s 60 61 # dosfstools 62 FSCK_FAT="fsck.fat -n" 63 64 # Check for Busybox timeout which is a symlink 65 if [ -L $(which $TIMEOUT) ]; then 66 TIMEOUT= 67 fi 68 ;; 69esac 70 71base64_decode() { 72 base64 $BASE64_DECODE 73} 74 75base64_decodez() { 76 base64 $BASE64_DECODE | zcat 77} 78 79filesize() { 80 stat $STAT_FILESIZE_FLAGS $1 81} 82 83TESTS_SRC_DIR=$(dirname $($READLINK -f $0)) 84TESTS_DIR=$(pwd) 85 86# Default to testing the fwup built in the src directory, 87# but it is possible to define the version of fwup used for 88# the create and apply steps separately. 89FWUP_DEFAULT=$TESTS_DIR/../src/fwup 90FWUP_BINARY=$TESTS_DIR/../src/fwup 91FRAMING_HELPER=$TESTS_DIR/fixture/framing-helper 92if [ ! -e $FWUP_DEFAULT ]; then 93 if [ -e $FWUP_DEFAULT.exe ]; then 94 EXEEXT=.exe 95 FWUP_BINARY="$FWUP_DEFAULT.exe" 96 FWUP_DEFAULT="wine $FWUP_BINARY" 97 FRAMING_HELPER="wine $TESTS_DIR/fixture/framing-helper.exe" 98 fi 99fi 100 101if [ -z $FWUP_CREATE ]; then FWUP_CREATE="$FWUP_DEFAULT"; fi 102if [ -z $FWUP_APPLY ]; then FWUP_APPLY="$FWUP_DEFAULT"; fi 103if [ -z $FWUP_APPLY_NO_CHECK ]; then FWUP_APPLY_NO_CHECK="$FWUP_APPLY"; fi 104if [ -z $FWUP_VERIFY ]; then FWUP_VERIFY="$FWUP_DEFAULT"; fi 105 106if [ -z $EXEEXT ]; then 107 # No sanity check for windows builds. 108 [ -e $FWUP_CREATE ] || ( echo "Can't find $FWUP_CREATE"; exit 1 ) 109 [ -e $FWUP_APPLY ] || ( echo "Can't find $FWUP_APPLY"; exit 1 ) 110 [ -e $FWUP_VERIFY ] || ( echo "Can't find $FWUP_VERIFY"; exit 1 ) 111 [ -e $FRAMING_HELPER ] || ( echo "Can't find $FRAMING_HELPER"; exit 1 ) 112fi 113 114if [ -n "$VALGRIND" ]; then 115 # Example: 116 # VALGRIND="valgrind -s --leak-check=full --error-exitcode=1 --track-origins=yes 117 FWUP_CREATE="$VALGRIND $FWUP_CREATE" 118 FWUP_APPLY="$VALGRIND $FWUP_APPLY" 119 FWUP_VERIFY="$VALGRIND $FWUP_VERIFY" 120else 121# The syscall verification code only runs on a subset of 122# platforms. Let autoconf figure out which ones and run it 123# if the verify-syscalls program built. 124if [ -e $TESTS_DIR/fixture/verify-syscalls ]; then 125 export VERIFY_SYSCALLS_CMD=$FWUP_APPLY 126 FWUP_APPLY=$TESTS_DIR/fixture/verify-syscalls 127fi 128fi 129 130# The write fault simulator only runs only runs on a subset of 131# platforms. Let autoconf figure out which ones. 132WRITE_SHIM="$TESTS_DIR/fixture/.libs/libwrite_shim.so" 133if [ -e "$WRITE_SHIM" ]; then 134 export HAS_WRITE_SHIM=true 135 export LD_PRELOAD="$WRITE_SHIM" 136 export DYLD_INSERT_LIBRARIES="$WRITE_SHIM" 137else 138 export HAS_WRITE_SHIM=false 139fi 140 141WORK=$TESTS_DIR/work-$(basename "$0") 142RESULTS=$WORK/results 143 144CONFIG=$WORK/fwup.conf 145FWFILE=$WORK/fwup.fw 146IMGFILE=$WORK/fwup.img 147UNZIPDIR=$WORK/unzip 148EXPECTED_META_CONF=$WORK/meta.conf.expected 149TRIMMED_META_CONF=$WORK/meta.conf.trimmed 150 151# Setup the directories 152rm -fr $WORK 153mkdir -p $WORK 154 155unzip_fw() { 156 mkdir -p $UNZIPDIR 157 unzip -q $FWFILE -d $UNZIPDIR 158} 159 160check_meta_conf() { 161 # Need to unzip the fw file to check the meta.conf 162 if ! [ -e $UNZIPDIR/meta.conf ]; then 163 unzip_fw 164 fi 165 166 # Trim the results of known lines that vary between runs 167 cat $UNZIPDIR/meta.conf \ 168 > $TRIMMED_META_CONF 169 diff -w $EXPECTED_META_CONF $TRIMMED_META_CONF 170} 171 172cleanup() { 173 rc=$? 174 if [ $rc = "0" ]; then 175 echo "Test succeeded" 176 rm -fr $WORK 177 elif [ $rc = "77" ]; then 178 echo "Test skipped" 179 rm -fr $WORK 180 else 181 echo 182 echo "Test failed!" 183 echo 184 echo "Leaving test work files in '$WORK'" 185 fi 186} 187 188trap cleanup EXIT 189 190# Test input files 191 192# These files contain random data so that it is possible to 193# verify that fwup copied things correctly. Previously fwup 194# unit tests used files filled with 1s, and it possible for 195# a test to pass even though the data had been reordered. 196# (This never actually happened to my knowledge.) 197 198TESTFILE_1K="$TESTS_SRC_DIR/1K.bin" 199TESTFILE_1K_CORRUPT="$TESTS_SRC_DIR/1K-corrupt.bin" 200TESTFILE_150K="$TESTS_SRC_DIR/150K.bin" 201 202# Generated test data 203create_15M_file() { 204 if [ ! -e $TESTFILE_15M ]; then 205 i=0 206 while [ $i -lt 100 ]; do 207 cat $TESTFILE_150K >> $TESTFILE_15M 208 i=$(expr $i + 1) 209 done 210 fi 211} 212TESTFILE_15M=$WORK/15M.bin 213 214# GNU and BSD friendly cmp --bytes 215# Invoke as: cmp_bytes <byte count> <file1> <file2> [offset1] [offset2] 216# 217# NOTE: This implementation has the unfortunate constraint that bytes and 218# offsets need to be multiples of the block size. The block size 219# could be set to 1, but that makes some large comparisons VERY slow. 220cmp_bytes() { 221 BYTE_COUNT=$1 222 FILE1=$2 223 FILE2=$3 224 BEGIN1=$4 225 BEGIN2=$5 226 227 if [ -z $BEGIN1 ]; then BEGIN1=0; fi 228 if [ -z $BEGIN2 ]; then BEGIN2=0; fi 229 230 BEGIN1=$(expr $BEGIN1 / 512) || true 231 BEGIN2=$(expr $BEGIN2 / 512) || true 232 BLOCK_COUNT=$(expr $BYTE_COUNT / 512) 233 234 dd if=$FILE1 of=$WORK/cmp_bytes1 count=$BLOCK_COUNT skip=$BEGIN1 2> /dev/null 235 dd if=$FILE2 of=$WORK/cmp_bytes2 count=$BLOCK_COUNT skip=$BEGIN2 2> /dev/null 236 237 cmp $WORK/cmp_bytes1 $WORK/cmp_bytes2 238} 239