176421c
#!/usr/bin/bash
176421c
set -uexo pipefail
176421c
176421c
# The custom %check script to run the OpenSSH upstream testsuite in parallel.
176421c
#
176421c
# The upstream testsuite is serial,
176421c
# so the idea here is to split the testsuite into several $PARTS:
176421c
# * file-tests
176421c
# * interop-tests
176421c
# * unit
176421c
# * ltests-00
176421c
# * ltests-01
176421c
# * ...
176421c
# * ltests-23
176421c
# and run them in parallel, using make, each in its own build subtree.
176421c
176421c
PARALLEL_MAKEFILE=$1
176421c
176421c
SPLIT=24
176421c
PARTS='file-tests interop-tests unit '
176421c
for ((i = 1; i < SPLIT; i++)); do ii=$(printf %02d $i);
176421c
    PARTS+="t-exec-$ii "
176421c
done
176421c
176421c
# work around a selinux restriction:
665f4ad
chcon -t unconfined_exec_t ssh-sk-helper || :
176421c
176421c
# work around something else that only crops up in brew
176421c
export TEST_SSH_UNSAFE_PERMISSIONS=1
176421c
176421c
# create a .test directory to store all our files in:
176421c
mkdir -p .test/tree .test/ltests/{in,not-in}
176421c
176421c
# patch testsuite: use different ports to avoid port collisions
176421c
grep -REi 'port=[2-9][0-9]*' regress
176421c
sed -i 's|PORT=4242|PORT=$(expr $TEST_SSH_PORT + 1)|' \
176421c
    regress/test-exec.sh*
176421c
sed -i 's|^P=3301  # test port|P=$(expr $TEST_SSH_PORT + 1)|' \
176421c
    regress/multiplex.sh*
176421c
sed -i 's|^fwdport=3301|fwdport=$(expr $TEST_SSH_PORT + 1)|' \
176421c
    regress/cfgmatch.sh* regress/cfgmatchlisten.sh*
176421c
sed -i 's|^LFWD_PORT=.*|LFWD_PORT=$(expr $TEST_SSH_PORT + 1)|' \
176421c
    regress/forward-control.sh*
176421c
sed -i 's|^RFWD_PORT=.*|RFWD_PORT=$(expr $TEST_SSH_PORT + 2)|' \
176421c
    regress/forward-control.sh*
176421c
( ! grep -REi 'port=[2-9][0-9]*' regress)  # try to find more of those
176421c
176421c
# patch testsuite: speed up
176421c
sed -i 's|sleep 1$|sleep .25|' regress/forward-control.sh
176421c
176421c
# extract LTESTS list to .tests/ltests/all:
176421c
grep -Ex 'tests:[[:space:]]*file-tests t-exec interop-tests extra-tests unit' Makefile
176421c
echo -ne '\necho-ltests:\n\techo ${LTESTS}' >> regress/Makefile
176421c
make -s -C regress echo-ltests | tr ' ' '\n' > .test/ltests/all
176421c
176421c
# separate ltests into $SPLIT roughly equal .tests/ltests/in/$ii parts:
176421c
grep -qFx connect .test/ltests/all
176421c
( ! grep -qFx nonex .test/ltests/all )
176421c
split -d -a2 --number=l/$SPLIT .test/ltests/all .test/ltests/in/
176421c
wc -l .test/ltests/in/*
176421c
grep -qFx connect .test/ltests/in/*
176421c
176421c
# generate the inverses of them --- .test/ltests/not-in/$ii:
176421c
( ! grep -qFx nonex .test/ltests/in/* )
176421c
for ((i = 0; i < SPLIT; i++)); do ii=$(printf %02d $i);
176421c
    while read -r tname; do
176421c
        if ! grep -qFx "$tname" ".test/ltests/in/$ii"; then
176421c
            echo -n "$tname " >> ".test/ltests/not-in/$ii"
176421c
        fi
176421c
    done < .test/ltests/all
176421c
done
176421c
grep . .test/ltests/not-in/*
176421c
( ! grep -q ^connect .test/ltests/not-in/0 )
176421c
for ((i = 1; i < SPLIT; i++)); do ii=$(printf %02d $i);
176421c
    grep -q ^connect .test/ltests/not-in/$ii
176421c
done
176421c
176421c
# prepare several test directories:
176421c
for PART in $PARTS; do
176421c
    mkdir .test/tree/${PART}
176421c
    cp -ra * .test/tree/${PART}/
176421c
    sed -i "s|abs_top_srcdir=.*|abs_top_srcdir=$(pwd)/.test/tree/${PART}|" \
176421c
        .test/tree/${PART}/Makefile
176421c
    sed -i "s|abs_top_builddir=.*|abs_top_builddir=$(pwd)/.test/tree/${PART}|" \
176421c
        .test/tree/${PART}/Makefile
176421c
    sed -i "s|^BUILDDIR=.*|BUILDDIR=$(pwd)/.test/tree/${PART}|" \
176421c
        .test/tree/${PART}/Makefile
176421c
done
176421c
176421c
# finally, run tests $PARTS in parallel in their own subtrees:
176421c
time make -f "$PARALLEL_MAKEFILE" -j$(nproc) $PARTS