From 2f2a0454efd07644a4e0ccb3f00f1db2d7043391 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Tue, 5 Mar 2019 13:50:28 +0100 Subject: [PATCH 1/2] test: parallelize tasks in TEST-24-UNIT-TESTS --- test/TEST-24-UNIT-TESTS/test.sh | 2 + test/TEST-24-UNIT-TESTS/testsuite.sh | 99 +++++++++++++++++++++------- 2 files changed, 78 insertions(+), 23 deletions(-) diff --git a/test/TEST-24-UNIT-TESTS/test.sh b/test/TEST-24-UNIT-TESTS/test.sh index 014ee52277..fc8c89fe0a 100755 --- a/test/TEST-24-UNIT-TESTS/test.sh +++ b/test/TEST-24-UNIT-TESTS/test.sh @@ -78,6 +78,8 @@ test_setup() { setup_basic_environment install_keymaps yes install_zoneinfo + # Install nproc to determine # of CPUs for correct parallelization + inst_binary nproc # setup the testsuite service cat >$initdir/etc/systemd/system/testsuite.service < /$NAME.log 2>&1 - ret=$? - if (( $ret && $ret != 77 )); then - echo "$NAME failed with $ret" - echo $NAME >> /failed-tests - echo "--- $NAME begin ---" >> /failed - cat /$NAME.log >> /failed - echo "--- $NAME end ---" >> /failed - elif (( $ret == 77 )); then - echo "$NAME skipped" - echo $NAME >> /skipped-tests - echo "--- $NAME begin ---" >> /skipped - cat /$NAME.log >> /skipped - echo "--- $NAME end ---" >> /skipped - else - echo "$NAME OK" - echo $NAME >> /testok +NPROC=$(nproc) +MAX_QUEUE_SIZE=${NPROC:-2} +IFS=$'\n' TEST_LIST=($(ls /usr/lib/systemd/tests/test-*)) + +# Check & report test results +# Arguments: +# $1: test path +# $2: test exit code +function report_result() { + if [[ $# -ne 2 ]]; then + echo >&2 "check_result: missing arguments" + exit 1 fi - systemd-cat echo "--- $NAME ---" - systemd-cat cat /$NAME.log + local name="${1##*/}" + local ret=$2 + + if [[ $ret -ne 0 && $ret != 77 ]]; then + echo "$name failed with $ret" + echo "$name" >> /failed-tests + { + echo "--- $name begin ---" + cat "/$name.log" + echo "--- $name end ---" + } >> /failed + elif [[ $ret == 77 ]]; then + echo "$name skipped" + echo "$name" >> /skipped-tests + { + echo "--- $name begin ---" + cat "/$name.log" + echo "--- $name end ---" + } >> /skipped + else + echo "$name OK" + echo "$name" >> /testok + fi + + systemd-cat echo "--- $name ---" + systemd-cat cat "/$name.log" +} + +# Associative array for running tasks, where running[test-path]=PID +declare -A running=() +for task in "${TEST_LIST[@]}"; do + # If there's MAX_QUEUE_SIZE running tasks, keep checking the running queue + # until one of the tasks finishes, so we can replace it. + while [[ ${#running[@]} -ge $MAX_QUEUE_SIZE ]]; do + for key in "${!running[@]}"; do + if ! kill -0 ${running[$key]} &>/dev/null; then + # Task has finished, report its result and drop it from the queue + wait ${running[$key]} + ec=$? + report_result "$key" $ec + unset running["$key"] + # Break from inner for loop and outer while loop to skip + # the sleep below when we find a free slot in the queue + break 2 + fi + done + + # Precisely* calculated constant to keep the spinlock from burning the CPU(s) + sleep 0.01 + done + + if [[ -x $task ]]; then + log_file="/${task##*/}.log" + $task &> "$log_file" & + running[$task]=$! + fi +done + +# Wait for remaining running tasks +for key in "${!running[@]}"; do + wait ${running[$key]} + ec=$? + report_result "$key" $ec + unset running["$key"] done exit 0 From 5bfb2a93a4a36bba0d24199553dcda6e560cbb75 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Tue, 5 Mar 2019 16:08:00 +0100 Subject: [PATCH 2/2] test: try to determine QEMU_SMP dynamically If the QEMU_SMP value has not been explicitly set, try to determine it from the number of online CPUs using the nproc utility. If this approach fails, fall back to the default value QEMU_SMP=1. This change should significantly help when running integration tests under QEMU on multicore systems. --- test/test-functions | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/test-functions b/test/test-functions index a936202e4a..d8a3502a4a 100644 --- a/test/test-functions +++ b/test/test-functions @@ -134,7 +134,16 @@ run_qemu() { fi fi - [ "$QEMU_SMP" ] || QEMU_SMP=1 + # If QEMU_SMP was not explicitly set, try to determine the value 'dynamically' + # i.e. use the number of online CPUs on the host machine. If the nproc utility + # is not installed or there's some other error when calling it, fall back + # to the original value (QEMU_SMP=1). + if ! [ "$QEMU_SMP" ]; then + if ! QEMU_SMP=$(nproc); then + dwarn "nproc utility is not installed, falling back to QEMU_SMP=1" + QEMU_SMP=1 + fi + fi find_qemu_bin || return 1