oom_linux_test.go 3.2 KB

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