k8s.io/kubernetes@v1.29.3/pkg/util/oom/oom_linux_test.go (about) 1 //go:build linux 2 // +build linux 3 4 /* 5 Copyright 2015 The Kubernetes Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 */ 19 20 package oom 21 22 import ( 23 "os" 24 25 "github.com/opencontainers/runc/libcontainer/cgroups" 26 "testing" 27 28 "github.com/stretchr/testify/assert" 29 ) 30 31 // Converts a sequence of PID lists into a PID lister. 32 // The PID lister returns pidListSequence[i] on the ith call. If i >= length of pidListSequence 33 // then return the last element of pidListSequence (the sequence is considered to have) stabilized. 34 func sequenceToPidLister(pidListSequence [][]int) func(string) ([]int, error) { 35 var numCalls int 36 return func(cgroupName string) ([]int, error) { 37 numCalls++ 38 if len(pidListSequence) == 0 { 39 return []int{}, nil 40 } else if numCalls > len(pidListSequence) { 41 return pidListSequence[len(pidListSequence)-1], nil 42 } 43 return pidListSequence[numCalls-1], nil 44 } 45 } 46 47 // Tests that applyOOMScoreAdjContainer correctly applies OOM scores to relevant processes, or 48 // returns the right error. 49 func applyOOMScoreAdjContainerTester(pidListSequence [][]int, maxTries int, appliedPids []int, expectedError bool, t *testing.T) { 50 pidOOMs := make(map[int]bool) 51 52 // Mock ApplyOOMScoreAdj and pidLister. 53 oomAdjuster := NewOOMAdjuster() 54 oomAdjuster.ApplyOOMScoreAdj = func(pid int, oomScoreAdj int) error { 55 pidOOMs[pid] = true 56 return nil 57 } 58 oomAdjuster.pidLister = sequenceToPidLister(pidListSequence) 59 err := oomAdjuster.ApplyOOMScoreAdjContainer("", 100, maxTries) 60 61 // Check error value. 62 if expectedError && err == nil { 63 t.Errorf("Expected error %+v when running ApplyOOMScoreAdjContainer but got no error", expectedError) 64 return 65 } else if !expectedError && err != nil { 66 t.Errorf("Expected no error but got error %+v when running ApplyOOMScoreAdjContainer", err) 67 return 68 } else if err != nil { 69 return 70 } 71 // Check that OOM scores were applied to the right processes. 72 if len(appliedPids) != len(pidOOMs) { 73 t.Errorf("Applied OOM scores to incorrect number of processes - %+v vs %v", appliedPids, pidOOMs) 74 return 75 } 76 for _, pid := range appliedPids { 77 if !pidOOMs[pid] { 78 t.Errorf("Failed to apply OOM scores to process %d", pid) 79 } 80 } 81 } 82 83 func TestOOMScoreAdjContainer(t *testing.T) { 84 pidListSequenceEmpty := [][]int{} 85 applyOOMScoreAdjContainerTester(pidListSequenceEmpty, 3, nil, true, t) 86 87 pidListSequence1 := [][]int{ 88 {1, 2}, 89 } 90 applyOOMScoreAdjContainerTester(pidListSequence1, 1, []int{1, 2}, false, t) 91 92 pidListSequenceLag := [][]int{ 93 {}, 94 {}, 95 {}, 96 {1, 2, 4}, 97 } 98 for i := 1; i < 4; i++ { 99 applyOOMScoreAdjContainerTester(pidListSequenceLag, i, nil, true, t) 100 } 101 applyOOMScoreAdjContainerTester(pidListSequenceLag, 4, []int{1, 2, 4}, false, t) 102 } 103 104 func TestPidListerFailure(t *testing.T) { 105 _, err := getPids("/does/not/exist") 106 assert.True(t, cgroups.IsNotFound(err) || os.IsNotExist(err), "expected getPids to return not exists error. Got %v", err) 107 }