summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnita Zhang <the.anitazha@gmail.com>2020-08-14 01:20:43 -0700
committerAnita Zhang <the.anitazha@gmail.com>2020-10-22 17:04:22 -0700
commite4ff80404a71746864d29c0a3dc019a309277e53 (patch)
tree5bd08ce0d73d5689b75d52895ce8ce249d8ea126
parent018b6f45483941e70df37661986bae39b0c90849 (diff)
downloadsystemd-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/Makefile1
-rwxr-xr-xtest/TEST-56-OOMD/test.sh48
-rw-r--r--test/test-functions1
-rwxr-xr-xtest/units/testsuite-56-slowgrowth.sh34
-rw-r--r--test/units/testsuite-56.service7
-rwxr-xr-xtest/units/testsuite-56.sh70
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