diff options
author | Anita Zhang <the.anitazha@gmail.com> | 2020-08-14 01:20:43 -0700 |
---|---|---|
committer | Anita Zhang <the.anitazha@gmail.com> | 2020-10-22 17:04:22 -0700 |
commit | e4ff80404a71746864d29c0a3dc019a309277e53 (patch) | |
tree | 5bd08ce0d73d5689b75d52895ce8ce249d8ea126 | |
parent | 018b6f45483941e70df37661986bae39b0c90849 (diff) | |
download | systemd-e4ff80404a71746864d29c0a3dc019a309277e53.tar.gz |
test: add basic memory pressure extended test for oomd
Simple test to generate a lot of pressure in one unit and assert that
systemd-oomd kills the right one.
l--------- | test/TEST-56-OOMD/Makefile | 1 | ||||
-rwxr-xr-x | test/TEST-56-OOMD/test.sh | 48 | ||||
-rw-r--r-- | test/test-functions | 1 | ||||
-rwxr-xr-x | test/units/testsuite-56-slowgrowth.sh | 34 | ||||
-rw-r--r-- | test/units/testsuite-56.service | 7 | ||||
-rwxr-xr-x | test/units/testsuite-56.sh | 70 |
6 files changed, 161 insertions, 0 deletions
diff --git a/test/TEST-56-OOMD/Makefile b/test/TEST-56-OOMD/Makefile new file mode 120000 index 0000000000..e9f93b1104 --- /dev/null +++ b/test/TEST-56-OOMD/Makefile @@ -0,0 +1 @@ +../TEST-01-BASIC/Makefile
\ No newline at end of file diff --git a/test/TEST-56-OOMD/test.sh b/test/TEST-56-OOMD/test.sh new file mode 100755 index 0000000000..55b0d1dafd --- /dev/null +++ b/test/TEST-56-OOMD/test.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -e +TEST_DESCRIPTION="systemd-oomd Memory Pressure Test" + +. $TEST_BASE_DIR/test-functions + +check_result_nspawn() { + local ret=1 + local journald_report="" + local pids="" + [[ -e $1/testok ]] && ret=0 + if [[ -e $1/skipped ]]; then + echo "TEST-56-OOMD was skipped:" + cat $1/skipped + ret=0 + fi + [[ -f $1/failed ]] && cp -a $1/failed $TESTDIR + save_journal $1/var/log/journal + [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed + echo $JOURNAL_LIST + test -s $TESTDIR/failed && ret=$(($ret+1)) + [ -n "$TIMED_OUT" ] && ret=$(($ret+1)) + check_asan_reports "$1" || ret=$(($ret+1)) + _umount_dir $initdir + return $ret +} + +check_result_qemu() { + local ret=1 + mount_initdir + [[ -e $initdir/testok ]] && ret=0 + if [[ -e $initdir/skipped ]]; then + echo "TEST-56-OOMD was skipped:" + cat $initdir/skipped + ret=0 + fi + [[ -f $initdir/failed ]] && cp -a $initdir/failed $TESTDIR + save_journal $initdir/var/log/journal + check_asan_reports "$initdir" || ret=$(($ret+1)) + _umount_dir $initdir + [[ -f $TESTDIR/failed ]] && cat $TESTDIR/failed + echo $JOURNAL_LIST + test -s $TESTDIR/failed && ret=$(($ret+1)) + [ -n "$TIMED_OUT" ] && ret=$(($ret+1)) + return $ret +} + +do_test "$@" 56 diff --git a/test/test-functions b/test/test-functions index 9893864bcd..a2cb28c380 100644 --- a/test/test-functions +++ b/test/test-functions @@ -65,6 +65,7 @@ BASICTOOLS=( echo env false + getconf getent getfacl grep diff --git a/test/units/testsuite-56-slowgrowth.sh b/test/units/testsuite-56-slowgrowth.sh new file mode 100755 index 0000000000..ff5a747348 --- /dev/null +++ b/test/units/testsuite-56-slowgrowth.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -eu -o pipefail + +PAGE_SIZE=$(getconf PAGE_SIZE) +BLOAT_ITERATION_TARGET=$(( 100 << 20 )) # 100 MB +BLOAT_HOLDER=() +PID="$$" + +function bloat { + local set_size=$(cat "/proc/$PID/statm" | cut -d " " -f2) + local mem_usage=$(( "$set_size" * "$PAGE_SIZE" )) + local target_mem_size=$(( "$mem_usage" + "$1" )) + + BLOAT_HOLDER=() + while [[ "$mem_usage" -lt "$target_mem_size" ]]; do + echo "target $target_mem_size" + echo "mem usage $mem_usage" + BLOAT_HOLDER+=( $(printf "%0.sg" {1..1000000}) ) + set_size=$(cat "/proc/$PID/statm" | cut -d " " -f2) + mem_usage=$(( "$set_size" * "$PAGE_SIZE" )) + done +} + +function run { + local arr=() + + while [[ true ]]; do + bloat "$BLOAT_ITERATION_TARGET" + arr+=( "$BLOAT_HOLDER" ) + sleep 1 + done +} + +run diff --git a/test/units/testsuite-56.service b/test/units/testsuite-56.service new file mode 100644 index 0000000000..b53b0905db --- /dev/null +++ b/test/units/testsuite-56.service @@ -0,0 +1,7 @@ +[Unit] +Description=TESTSUITE-56-OOMD + +[Service] +ExecStartPre=rm -f /failed /skipped /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/units/testsuite-56.sh b/test/units/testsuite-56.sh new file mode 100755 index 0000000000..5be6658972 --- /dev/null +++ b/test/units/testsuite-56.sh @@ -0,0 +1,70 @@ +#!/usr/bin/env bash +set -ex +set -o pipefail + +systemd-analyze log-level debug +systemd-analyze log-target console + +# Loose checks to ensure the environment has the necessary features for systemd-oomd +[[ "$( awk '/SwapTotal/ { print $2 }' /proc/meminfo )" != "0" ]] || echo "no swap" >> /skipped +[[ -e /proc/pressure ]] || echo "no PSI" >> /skipped +cgroup_type=$(stat -fc %T /sys/fs/cgroup/) +if [[ "$cgroup_type" != *"cgroup2"* ]] && [[ "$cgroup_type" != *"0x63677270"* ]]; then + echo "no cgroup2" >> /skipped +fi +[[ -e /skipped ]] && exit 0 || true + +cat > /etc/systemd/system/testworkload.slice <<EOF +[Slice] +CPUAccounting=true +MemoryAccounting=true +IOAccounting=true +TasksAccounting=true +ManagedOOMMemoryPressure=kill +ManagedOOMMemoryPressureLimitPercent=50% +EOF + +# Create a lot of memory pressure by setting memory.high to a very small value +cat > /etc/systemd/system/testbloat.service <<EOF +[Service] +MemoryHigh=2M +Slice=testworkload.slice +ExecStart=/usr/lib/systemd/tests/testdata/units/testsuite-56-slowgrowth.sh +EOF + +# This generates no memory pressure +cat > /etc/systemd/system/testchill.service <<EOF +[Service] +MemoryHigh=2M +Slice=testworkload.slice +ExecStart=sleep infinity +EOF + +systemctl daemon-reload + +systemctl start testbloat.service +systemctl start testchill.service + +# Verify systemd-oomd is monitoring the expected units +oomctl | grep "/testworkload.slice" +oomctl | grep "50%" + +# systemd-oomd watches for elevated pressure for 30 seconds before acting. +# It can take time to build up pressure so either wait 5 minutes or for the service to fail. +timeout=$(date -ud "5 minutes" +%s) +while [[ $(date -u +%s) -le $timeout ]]; do + if ! systemctl status testbloat.service; then + break + fi + sleep 15 +done + +# testbloat should be killed and testchill should be fine +if systemctl status testbloat.service; then exit 42; fi +if ! systemctl status testchill.service; then exit 24; fi + +systemd-analyze log-level info + +echo OK > /testok + +exit 0 |