redict/tests/unit/oom-score-adj.tcl
yoav-steinberg 1736fa4d22
Don't write oom score adj to proc unless we're managing it. (#9904)
When disabling redis oom-score-adj managment we restore the
base value read before enabling oom-score-adj management.

This fixes an issue introduced in #9748 where updating
`oom-score-adj-values` while `oom-score-adj` was set to `no`
would write the base oom score adj value read on startup to `/proc`.
This is a bug since while `oom-score-adj` is disabled we should
never write to proc and let external processes manage it.

Added appropriate tests.
2021-12-07 16:05:51 +02:00

127 lines
4.3 KiB
Tcl

set system_name [string tolower [exec uname -s]]
set user_id [exec id -u]
if {$system_name eq {linux}} {
start_server {tags {"oom-score-adj external:skip"}} {
proc get_oom_score_adj {{pid ""}} {
if {$pid == ""} {
set pid [srv 0 pid]
}
set fd [open "/proc/$pid/oom_score_adj" "r"]
set val [gets $fd]
close $fd
return $val
}
proc set_oom_score_adj {score {pid ""}} {
if {$pid == ""} {
set pid [srv 0 pid]
}
set fd [open "/proc/$pid/oom_score_adj" "w"]
puts $fd $score
close $fd
}
test {CONFIG SET oom-score-adj works as expected} {
set base [get_oom_score_adj]
# Enable oom-score-adj, check defaults
r config set oom-score-adj-values "10 20 30"
r config set oom-score-adj yes
assert {[get_oom_score_adj] == [expr $base + 10]}
# Modify current class
r config set oom-score-adj-values "15 20 30"
assert {[get_oom_score_adj] == [expr $base + 15]}
# Check replica class
r replicaof localhost 1
assert {[get_oom_score_adj] == [expr $base + 20]}
r replicaof no one
assert {[get_oom_score_adj] == [expr $base + 15]}
# Check child process
r set key-a value-a
r config set rdb-key-save-delay 1000000
r bgsave
set child_pid [get_child_pid 0]
# Wait until background child process to setOOMScoreAdj success.
wait_for_condition 100 10 {
[get_oom_score_adj $child_pid] == [expr $base + 30]
} else {
fail "Set oom-score-adj of background child process is not ok"
}
}
# Failed oom-score-adj tests can only run unprivileged
if {$user_id != 0} {
test {CONFIG SET oom-score-adj handles configuration failures} {
# Bad config
r config set oom-score-adj no
r config set oom-score-adj-values "-1000 -1000 -1000"
# Make sure it fails
catch {r config set oom-score-adj yes} e
assert_match {*Failed to set*} $e
# Make sure it remains off
assert {[r config get oom-score-adj] == "oom-score-adj no"}
# Fix config
r config set oom-score-adj-values "0 100 100"
r config set oom-score-adj yes
# Make sure it fails
catch {r config set oom-score-adj-values "-1000 -1000 -1000"} e
assert_match {*Failed*} $e
# Make sure previous values remain
assert {[r config get oom-score-adj-values] == {oom-score-adj-values {0 100 100}}}
}
}
test {CONFIG SET oom-score-adj-values doesn't touch proc when disabled} {
set orig_osa [get_oom_score_adj]
set other_val1 [expr $orig_osa + 1]
set other_val2 [expr $orig_osa + 2]
r config set oom-score-adj no
set_oom_score_adj $other_val2
assert_equal [get_oom_score_adj] $other_val2
r config set oom-score-adj-values "$other_val1 $other_val1 $other_val1"
assert_equal [get_oom_score_adj] $other_val2
}
test {CONFIG SET oom score restored on disable} {
r config set oom-score-adj no
set_oom_score_adj 22
assert_equal [get_oom_score_adj] 22
r config set oom-score-adj-values "9 9 9" oom-score-adj yes
assert_equal [get_oom_score_adj] [expr 9+22]
r config set oom-score-adj no
assert_equal [get_oom_score_adj] 22
}
test {CONFIG SET oom score relative and absolute} {
set custom_oom 9
r config set oom-score-adj no
set base_oom [get_oom_score_adj]
r config set oom-score-adj-values "$custom_oom $custom_oom $custom_oom" oom-score-adj relative
assert_equal [get_oom_score_adj] [expr $base_oom+$custom_oom]
r config set oom-score-adj absolute
assert_equal [get_oom_score_adj] $custom_oom
}
}
}