X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/feae193b0c01181226522a5a2477e696876593d4..77a45bebc9168b396334630ef109c1d48ddaf930:/test/integration/framework diff --git a/test/integration/framework b/test/integration/framework index cad28af84..1db1946db 100644 --- a/test/integration/framework +++ b/test/integration/framework @@ -102,6 +102,9 @@ aptget() { runapt apt-get $*; } aptftparchive() { runapt apt-ftparchive $*; } aptkey() { runapt apt-key $*; } aptmark() { runapt apt-mark $*; } +aptwebserver() { + LD_LIBRARY_PATH=${APTWEBSERVERBINDIR} ${APTWEBSERVERBINDIR}/aptwebserver $*; +} dpkg() { $(which dpkg) --root=${TMPWORKINGDIRECTORY}/rootdir --force-not-root --force-bad-path --log=${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log $* } @@ -116,11 +119,18 @@ aptitude() { } gdb() { echo "gdb: run »$*«" - APT_CONFIG=aptconfig.conf LD_LIBRARY_PATH=${BUILDDIRECTORY} $(which gdb) ${BUILDDIRECTORY}/$1 + APT_CONFIG=aptconfig.conf LD_LIBRARY_PATH=${BUILDDIRECTORY} $(which gdb) ${BUILDDIRECTORY}/$1 --args $* } http() { LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/methods/http } +gpg() { + # see apt-key for the whole trickery. Setup is done in setupenvironment + command gpg --ignore-time-conflict --no-options --no-default-keyring \ + --homedir "${TMPWORKINGDIRECTORY}/gnupghome" \ + --no-auto-check-trustdb --trust-model always \ + "$@" +} exitwithstatus() { # error if we about to overflow, but ... @@ -154,8 +164,14 @@ setupenvironment() { TMPWORKINGDIRECTORY=$(mktemp -d) TESTDIRECTORY=$(readlink -f $(dirname $0)) msgninfo "Preparing environment for ${CCMD}$(basename $0)${CINFO} in ${TMPWORKINGDIRECTORY}… " - BUILDDIRECTORY="${TESTDIRECTORY}/../../build/bin" + + # allow overriding the default BUILDDIR location + BUILDDIRECTORY=${APT_INTEGRATION_TESTS_BUILD_DIR:-"${TESTDIRECTORY}/../../build/bin"} + METHODSDIR=${APT_INTEGRATION_TESTS_METHODS_DIR:-"${BUILDDIRECTORY}/methods"} + APTWEBSERVERBINDIR=${APT_INTEGRATION_TESTS_WEBSERVER_BIN_DIR:-"${BUILDDIRECTORY}"} test -x "${BUILDDIRECTORY}/apt-get" || msgdie "You need to build tree first" + # ----- + addtrap "cd /; rm -rf $TMPWORKINGDIRECTORY;" cd $TMPWORKINGDIRECTORY mkdir rootdir aptarchive keys @@ -181,7 +197,7 @@ setupenvironment() { echo "Dir::state::status \"${TMPWORKINGDIRECTORY}/rootdir/var/lib/dpkg/status\";" >> aptconfig.conf echo "Debug::NoLocking \"true\";" >> aptconfig.conf echo "APT::Get::Show-User-Simulation-Note \"false\";" >> aptconfig.conf - echo "Dir::Bin::Methods \"${BUILDDIRECTORY}/methods\";" >> aptconfig.conf + echo "Dir::Bin::Methods \"${METHODSDIR}\";" >> aptconfig.conf echo "Dir::Bin::dpkg \"fakeroot\";" >> aptconfig.conf echo "DPKG::options:: \"dpkg\";" >> aptconfig.conf echo "DPKG::options:: \"--root=${TMPWORKINGDIRECTORY}/rootdir\";" >> aptconfig.conf @@ -192,8 +208,24 @@ setupenvironment() { fi echo "DPKG::options:: \"--log=${TMPWORKINGDIRECTORY}/rootdir/var/log/dpkg.log\";" >> aptconfig.conf echo 'quiet::NoUpdate "true";' >> aptconfig.conf - export LC_ALL=C + echo "Acquire::https::CaInfo \"${TESTDIR}/apt.pem\";" > rootdir/etc/apt/apt.conf.d/99https + export LC_ALL=C.UTF-8 export PATH="${PATH}:/usr/local/sbin:/usr/sbin:/sbin" + configcompression '.' 'gz' #'bz2' 'lzma' 'xz' + + # gpg needs a trustdb to function, but it can't be invalid (not even empty) + # see also apt-key where this trickery comes from: + local TRUSTDBDIR="${TMPWORKINGDIRECTORY}/gnupghome" + mkdir "$TRUSTDBDIR" + chmod 700 "$TRUSTDBDIR" + # We also don't use a secret keyring, of course, but gpg panics and + # implodes if there isn't one available - and writeable for imports + local SECRETKEYRING="${TRUSTDBDIR}/secring.gpg" + touch $SECRETKEYRING + # now create the trustdb with an (empty) dummy keyring + # newer gpg versions are fine without it, but play it safe for now + gpg --quiet --check-trustdb --secret-keyring $SECRETKEYRING --keyring $SECRETKEYRING >/dev/null 2>&1 + msgdone "info" } @@ -215,14 +247,13 @@ getarchitectures() { } configarchitecture() { - local CONFFILE=rootdir/etc/apt/apt.conf.d/01multiarch.conf - rm -f $CONFFILE - echo "APT::Architecture \"$(getarchitecture $1)\";" > $CONFFILE - shift - while [ -n "$1" ]; do - echo "APT::Architectures:: \"$(getarchitecture $1)\";" >> $CONFFILE - shift - done + { + echo "APT::Architecture \"$(getarchitecture $1)\";" + while [ -n "$1" ]; do + echo "APT::Architectures:: \"$(getarchitecture $1)\";" + shift + done + } >rootdir/etc/apt/apt.conf.d/01multiarch.conf configdpkg } @@ -235,16 +266,17 @@ configdpkg() { echo -n > rootdir/var/lib/dpkg/status fi fi + rm -f rootdir/etc/apt/apt.conf.d/00foreigndpkg if $(which dpkg) --assert-multi-arch >/dev/null 2>&1; then local ARCHS="$(getarchitectures)" if echo "$ARCHS" | grep -E -q '[^ ]+ [^ ]+'; then DPKGARCH="$(dpkg --print-architecture)" for ARCH in ${ARCHS}; do if [ "${ARCH}" != "${DPKGARCH}" ]; then - if ! dpkg --add-architecture ${ARCH}; then + if ! dpkg --add-architecture ${ARCH} >/dev/null 2>&1; then # old-style used e.g. in Ubuntu-P – and as it seems travis - echo "DPKG::options:: \"--foreign-architecture\";" >> aptconfig.conf - echo "DPKG::options:: \"${ARCH}\";" >> aptconfig.conf + echo "DPKG::options:: \"--foreign-architecture\";" >> rootdir/etc/apt/apt.conf.d/00foreigndpkg + echo "DPKG::options:: \"${ARCH}\";" >> rootdir/etc/apt/apt.conf.d/00foreigndpkg fi fi done @@ -257,13 +289,31 @@ configdpkg() { fi } +configcompression() { + while [ -n "$1" ]; do + case "$1" in + '.') echo ".\t.\tcat";; + 'gz') echo "gzip\tgz\tgzip";; + 'bz2') echo "bzip2\tbz2\tbzip2";; + 'lzma') echo "lzma\tlzma\txz --format=lzma";; + 'xz') echo "xz\txz\txz";; + *) echo "$1\t$1\t$1";; + esac + shift + done > ${TMPWORKINGDIRECTORY}/rootdir/etc/testcase-compressor.conf +} + setupsimplenativepackage() { local NAME="$1" local ARCH="$2" local VERSION="$3" local RELEASE="${4:-unstable}" local DEPENDENCIES="$5" - local DESCRIPTION="$6" + local DESCRIPTION="${6:-"an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} + If you find such a package installed on your system, + something went horribly wrong! They are autogenerated + und used only by testcases and surf no other propose…"}" + local SECTION="${7:-others}" local DISTSECTION if [ "$SECTION" = "$(echo "$SECTION" | cut -d'/' -f 2)" ]; then @@ -295,14 +345,8 @@ Package: $NAME" > debian/control echo "Architecture: any" >> debian/control fi test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> debian/control - if [ -z "$DESCRIPTION" ]; then - echo "Description: an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} - If you find such a package installed on your system, - YOU did something horribly wrong! They are autogenerated - und used only by testcases for APT and surf no other propose…" >> debian/control - else - echo "Description: $DESCRIPTION" >> debian/control - fi + echo "Description: $DESCRIPTION" >> debian/control + test -e debian/compat || echo "7" > debian/compat test -e debian/source/format || echo "3.0 (native)" > debian/source/format test -e debian/rules || cp /usr/share/doc/debhelper/examples/rules.tiny debian/rules @@ -315,9 +359,14 @@ buildsimplenativepackage() { local VERSION="$3" local RELEASE="${4:-unstable}" local DEPENDENCIES="$5" - local DESCRIPTION="$6" + local DESCRIPTION="${6:-"an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} + If you find such a package installed on your system, + something went horribly wrong! They are autogenerated + und used only by testcases and surf no other propose…"}" + local SECTION="${7:-others}" local PRIORITY="${8:-optional}" + local FILE_TREE="$9" local DISTSECTION if [ "$SECTION" = "$(echo "$SECTION" | cut -d'/' -f 2)" ]; then DISTSECTION="main" @@ -355,21 +404,14 @@ Package: $NAME" >> ${BUILDDIR}/debian/control fi local DEPS="$(echo "$DEPENDENCIES" | grep -v '^Build-')" test -z "$DEPS" || echo "$DEPS" >> ${BUILDDIR}/debian/control - if [ -z "$DESCRIPTION" ]; then - echo "Description: an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} - If you find such a package installed on your system, - YOU did something horribly wrong! They are autogenerated - und used only by testcases for APT and surf no other propose…" >> ${BUILDDIR}/debian/control - else - echo "Description: $DESCRIPTION" >> ${BUILDDIR}/debian/control - fi + echo "Description: $DESCRIPTION" >> ${BUILDDIR}/debian/control echo '3.0 (native)' > ${BUILDDIR}/debian/source/format (cd ${BUILDDIR}/..; dpkg-source -b ${NAME}-${VERSION} 2>&1) | sed -n 's#^dpkg-source: info: building [^ ]\+ in ##p' \ | while read SRC; do echo "pool/${SRC}" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.srclist # if expr match "${SRC}" '.*\.dsc' >/dev/null 2>&1; then -# gpg --yes --no-default-keyring --secret-keyring ./keys/joesixpack.sec \ +# gpg --yes --secret-keyring ./keys/joesixpack.sec \ # --keyring ./keys/joesixpack.pub --default-key 'Joe Sixpack' \ # --clearsign -o "${BUILDDIR}/../${SRC}.sign" "${BUILDDIR}/../$SRC" # mv "${BUILDDIR}/../${SRC}.sign" "${BUILDDIR}/../$SRC" @@ -381,9 +423,12 @@ Package: $NAME" >> ${BUILDDIR}/debian/control mkdir -p ${BUILDDIR}/debian/tmp/DEBIAN ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME} ${BUILDDIR}/debian/tmp/usr/bin cp ${BUILDDIR}/debian/copyright ${BUILDDIR}/debian/changelog ${BUILDDIR}/FEATURES ${BUILDDIR}/debian/tmp/usr/share/doc/${NAME} cp ${BUILDDIR}/${NAME} ${BUILDDIR}/debian/tmp/usr/bin/${NAME}-${arch} + if [ -n "$FILE_TREE" ]; then + cp -ar "$FILE_TREE" ${BUILDDIR}/debian/tmp + fi + (cd ${BUILDDIR}; dpkg-gencontrol -DArchitecture=$arch) (cd ${BUILDDIR}/debian/tmp; md5sum $(find usr/ -type f) > DEBIAN/md5sums) - dpkg-deb --build ${BUILDDIR}/debian/tmp ${BUILDDIR}/.. 2> /dev/null > /dev/null echo "pool/${NAME}_${VERSION}_${arch}.deb" >> ${BUILDDIR}/../${RELEASE}.${DISTSECTION}.pkglist done @@ -427,6 +472,8 @@ buildaptarchive() { } createaptftparchiveconfig() { + local COMPRESSORS="$(cut -d' ' -f 1 ${TMPWORKINGDIRECTORY}/rootdir/etc/testcase-compressor.conf | tr '\n' ' ')" + COMPRESSORS="${COMPRESSORS%* }" local ARCHS="$(find pool/ -name '*.deb' | grep -oE '_[a-z0-9-]+\.deb$' | sort | uniq | sed -e '/^_all.deb$/ d' -e 's#^_\([a-z0-9-]*\)\.deb$#\1#' | tr '\n' ' ')" if [ -z "$ARCHS" ]; then # the pool is empty, so we will operate on faked packages - let us use the configured archs @@ -444,10 +491,10 @@ createaptftparchiveconfig() { echo -n '"; }; Default { - Packages::Compress ". gzip bzip2 lzma xz"; - Sources::Compress ". gzip bzip2 lzma xz"; - Contents::Compress ". gzip bzip2 lzma xz"; - Translation::Compress ". gzip bzip2 lzma xz"; + Packages::Compress "'"$COMPRESSORS"'"; + Sources::Compress "'"$COMPRESSORS"'"; + Contents::Compress "'"$COMPRESSORS"'"; + Translation::Compress "'"$COMPRESSORS"'"; LongDescription "false"; }; TreeDefault { @@ -509,7 +556,10 @@ insertpackage() { local VERSION="$4" local DEPENDENCIES="$5" local PRIORITY="${6:-optional}" - local DESCRIPTION="${7}" + local DESCRIPTION="${7:-"an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} + If you find such a package installed on your system, + something went horribly wrong! They are autogenerated + und used only by testcases and surf no other propose…"}" local ARCHS="" for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do if [ "$arch" = 'all' -o "$arch" = 'none' ]; then @@ -531,15 +581,7 @@ Maintainer: Joe Sixpack " >> $FILE echo "Version: $VERSION Filename: pool/main/${NAME}/${NAME}_${VERSION}_${arch}.deb" >> $FILE test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE - echo -n 'Description: ' >> $FILE - if [ -z "$DESCRIPTION" ]; then - echo "an autogenerated dummy ${NAME}=${VERSION}/${RELEASE} - If you find such a package installed on your system, - YOU did something horribly wrong! They are autogenerated - und used only by testcases for APT and surf no other propose…" >> $FILE - else - echo "$DESCRIPTION" >> $FILE - fi + echo "Description: $DESCRIPTION" >> $FILE echo >> $FILE done done @@ -574,6 +616,11 @@ insertinstalledpackage() { local DEPENDENCIES="$4" local PRIORITY="${5:-optional}" local STATUS="${6:-install ok installed}" + local DESCRIPTION="${7:-"an autogenerated dummy ${NAME}=${VERSION}/installed + If you find such a package installed on your system, + something went horribly wrong! They are autogenerated + und used only by testcases and surf no other propose…"}" + local FILE='rootdir/var/lib/dpkg/status' local INFO='rootdir/var/lib/dpkg/info' for arch in $(echo "$ARCH" | sed -e 's#,#\n#g' | sed -e "s#^native\$#$(getarchitecture 'native')#"); do @@ -586,11 +633,8 @@ Maintainer: Joe Sixpack Version: $VERSION" >> $FILE test "$arch" = 'none' || echo "Architecture: $arch" >> $FILE test -z "$DEPENDENCIES" || echo "$DEPENDENCIES" >> $FILE - echo "Description: an autogenerated dummy ${NAME}=${VERSION}/installed - If you find such a package installed on your system, - YOU did something horribly wrong! They are autogenerated - und used only by testcases for APT and surf no other propose… -" >> $FILE + echo "Description: $DESCRIPTION" >> $FILE + echo >> $FILE if [ "$(dpkg-query -W --showformat='${Multi-Arch}')" = 'same' ]; then echo -n > ${INFO}/${NAME}:${arch}.list else @@ -617,20 +661,34 @@ buildaptarchivefromfiles() { msginfo "Build APT archive for ${CCMD}$(basename $0)${CINFO} based on prebuild files…" find aptarchive -name 'Packages' -o -name 'Sources' | while read line; do msgninfo "\t${line} file… " - cat ${line} | gzip > ${line}.gz - cat ${line} | bzip2 > ${line}.bz2 - cat ${line} | xz --format=lzma > ${line}.lzma - cat ${line} | xz > ${line}.xz - if [ -n "$1" ]; then - touch -d "$1" ${line}.gz ${line}.bz2 ${line}.lzma ${line}.xz - fi + compressfile "$line" "$1" msgdone "info" done generatereleasefiles "$@" } +compressfile() { + cat ${TMPWORKINGDIRECTORY}/rootdir/etc/testcase-compressor.conf | while read compressor extension command; do + if [ "$compressor" = '.' ]; then + if [ -n "$2" ]; then + touch -d "$2" "$1" + fi + continue + fi + cat "$1" | $command > "${1}.${extension}" + if [ -n "$2" ]; then + touch -d "$2" "${1}.${extension}" + fi + done +} + # can be overridden by testcases for their pleasure -getcodenamefromsuite() { echo -n "$1"; } +getcodenamefromsuite() { + case "$1" in + unstable) echo 'sid';; + *) echo -n "$1";; + esac +} getreleaseversionfromsuite() { true; } getlabelfromsuite() { true; } @@ -727,7 +785,7 @@ setupaptarchive() { signreleasefiles() { local SIGNER="${1:-Joe Sixpack}" - local GPG="gpg --batch --yes --no-default-keyring --trustdb-name rootdir/etc/apt/trustdb.gpg" + local GPG="gpg --batch --yes" msgninfo "\tSign archive with $SIGNER key… " local REXKEY='keys/rexexpired' local SECEXPIREBAK="${REXKEY}.sec.bak" @@ -769,42 +827,73 @@ signreleasefiles() { msgdone "info" } +webserverconfig() { + msgtest "Set webserver config option '${1}' to" "$2" + downloadfile "http://localhost:8080/_config/set/${1}/${2}" '/dev/null' >/dev/null + local DOWNLOG='download-testfile.log' + rm -f "$DOWNLOG" + local STATUS="$(mktemp)" + addtrap "rm $STATUS;" + downloadfile "http://localhost:8080/_config/find/aptwebserver::last-status-code" "$STATUS" > "$DOWNLOG" + if [ "$(cat "$STATUS")" = '200' ]; then + msgpass + else + cat >&2 "$DOWNLOG" + msgfail "Statuscode was $(cat "$STATUS")" + fi +} + +rewritesourceslist() { + local APTARCHIVE="file://$(readlink -f "${TMPWORKINGDIRECTORY}/aptarchive")" + for LIST in $(find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list'); do + sed -i $LIST -e "s#$APTARCHIVE#${1}#" -e "s#http://localhost:8080/#${1}#" -e "s#http://localhost:4433/#${1}#" + done +} + changetowebserver() { - local LOG='/dev/null' - if test -x ${BUILDDIRECTORY}/aptwebserver; then + if [ "$1" != '--no-rewrite' ]; then + rewritesourceslist 'http://localhost:8080/' + else + shift + fi + if test -x ${APTWEBSERVERBINDIR}/aptwebserver; then cd aptarchive - LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/aptwebserver -o aptwebserver::fork=1 "$@" >$LOG 2>&1 + local LOG="$(mktemp)" + addtrap "rm $LOG;" + if ! aptwebserver -o aptwebserver::fork=1 "$@" >$LOG 2>&1 ; then + cat $LOG + false + fi local PID="$(cat aptwebserver.pid)" if [ -z "$PID" ]; then msgdie 'Could not fork aptwebserver successfully' fi addtrap "kill $PID;" cd - > /dev/null - elif [ $# -gt 0 ]; then - msgdie 'Need the aptwebserver when passing arguments for the webserver' - elif which weborf > /dev/null; then - weborf -xb aptarchive/ >$LOG 2>&1 & - addtrap "kill $!;" - elif which gatling > /dev/null; then - cd aptarchive - gatling -p 8080 -F -S >$LOG 2>&1 & - addtrap "kill $!;" - cd - > /dev/null - elif which lighttpd > /dev/null; then - echo "server.document-root = \"$(readlink -f ./aptarchive)\" -server.port = 8080 -server.stat-cache-engine = \"disable\"" > lighttpd.conf - lighttpd -t -f lighttpd.conf >/dev/null || msgdie 'Can not change to webserver: our lighttpd config is invalid' - lighttpd -D -f lighttpd.conf >$LOG 2>&1 & - addtrap "kill $!;" else msgdie 'You have to build aptwerbserver or install a webserver' fi - local APTARCHIVE="file://$(readlink -f ./aptarchive)" - for LIST in $(find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list'); do - sed -i $LIST -e "s#$APTARCHIVE#http://localhost:8080/#" - done - return 0 +} + +changetohttpswebserver() { + if ! which stunnel4 >/dev/null; then + msgdie 'You need to install stunnel4 for https testcases' + fi + if [ ! -e "${TMPWORKINGDIRECTORY}/aptarchive/aptwebserver.pid" ]; then + changetowebserver --no-rewrite + fi + echo "pid = ${TMPWORKINGDIRECTORY}/aptarchive/stunnel.pid +cert = ${TESTDIRECTORY}/apt.pem +output = /dev/null + +[https] +accept = 4433 +connect = 8080 +" > ${TMPWORKINGDIRECTORY}/stunnel.conf + stunnel4 "${TMPWORKINGDIRECTORY}/stunnel.conf" + local PID="$(cat ${TMPWORKINGDIRECTORY}/aptarchive/stunnel.pid)" + addtrap 'prefix' "kill ${PID};" + rewritesourceslist 'https://localhost:4433/' } changetocdrom() { @@ -822,6 +911,46 @@ changetocdrom() { find rootdir/etc/apt/sources.list.d/ -name 'apt-test-*.list' -delete } +downloadfile() { + PROTO="$(echo "$1" | cut -d':' -f 1)" + local DOWNLOG="${TMPWORKINGDIRECTORY}/download.log" + rm -f "$DOWNLOG" + touch "$DOWNLOG" + { + echo "601 Configuration +Config-Item: Acquire::https::CaInfo=${TESTDIR}/apt.pem +Config-Item: Debug::Acquire::${PROTO}=1 + +600 Acquire URI +URI: $1 +Filename: ${2} +" + # simple worker keeping stdin open until we are done (201) or error (400) + # and requesting new URIs on try-agains/redirects inbetween + { tail -n 999 -f "$DOWNLOG" & echo "TAILPID: $!"; } | while read f1 f2; do + if [ "$f1" = 'TAILPID:' ]; then + TAILPID="$f2" + elif [ "$f1" = 'New-URI:' ]; then + echo "600 Acquire URI +URI: $f2 +Filename: ${2} +" + elif [ "$f1" = '201' ] || [ "$f1" = '400' ]; then + # tail would only die on next read – which never happens + test -z "$TAILPID" || kill -s HUP "$TAILPID" + break + fi + done + } | LD_LIBRARY_PATH=${BUILDDIRECTORY} ${BUILDDIRECTORY}/methods/${PROTO} 2>&1 | tee "$DOWNLOG" + rm "$DOWNLOG" + # only if the file exists the download was successful + if [ -e "$2" ]; then + return 0 + else + return 1 + fi +} + checkdiff() { local DIFFTEXT="$($(which diff) -u $* | sed -e '/^---/ d' -e '/^+++/ d' -e '/^@@/ d')" if [ -n "$DIFFTEXT" ]; then @@ -867,7 +996,7 @@ testequalor2() { echo "$2" > $COMPAREFILE2 shift 2 msgtest "Test for equality OR of" "$*" - $* >$COMPAREAGAINST 2>&1 + $* >$COMPAREAGAINST 2>&1 || true (checkdiff $COMPAREFILE1 $COMPAREAGAINST 1> /dev/null || checkdiff $COMPAREFILE2 $COMPAREAGAINST 1> /dev/null) && msgpass || ( echo "\n${CINFO}Diff against OR 1${CNORMAL}" "$(checkdiff $COMPAREFILE1 $COMPAREAGAINST)" \