gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/control/proc_test.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package control 16 17 import ( 18 "testing" 19 20 "gvisor.dev/gvisor/pkg/log" 21 ktime "gvisor.dev/gvisor/pkg/sentry/kernel/time" 22 "gvisor.dev/gvisor/pkg/sentry/usage" 23 ) 24 25 func init() { 26 log.SetLevel(log.Debug) 27 } 28 29 // Tests that ProcessData.Table() prints with the correct format. 30 func TestProcessListTable(t *testing.T) { 31 testCases := []struct { 32 pl []*Process 33 expected string 34 }{ 35 { 36 pl: []*Process{}, 37 expected: "UID PID PPID C TTY STIME TIME CMD", 38 }, 39 { 40 pl: []*Process{ 41 { 42 UID: 0, 43 PID: 0, 44 PPID: 0, 45 C: 0, 46 TTY: "?", 47 STime: "0", 48 Time: "0", 49 Cmd: "zero", 50 }, 51 { 52 UID: 1, 53 PID: 1, 54 PPID: 1, 55 C: 1, 56 TTY: "pts/4", 57 STime: "1", 58 Time: "1", 59 Cmd: "one", 60 }, 61 }, 62 expected: `UID PID PPID C TTY STIME TIME CMD 63 0 0 0 0 ? 0 0 zero 64 1 1 1 1 pts/4 1 1 one`, 65 }, 66 } 67 68 for _, tc := range testCases { 69 output := ProcessListToTable(tc.pl) 70 71 if tc.expected != output { 72 t.Errorf("PrintTable(%v): got:\n%s\nwant:\n%s", tc.pl, output, tc.expected) 73 } 74 } 75 } 76 77 func TestProcessListJSON(t *testing.T) { 78 testCases := []struct { 79 pl []*Process 80 expected string 81 }{ 82 { 83 pl: []*Process{}, 84 expected: "[]", 85 }, 86 { 87 pl: []*Process{ 88 { 89 UID: 0, 90 PID: 0, 91 PPID: 0, 92 C: 0, 93 STime: "0", 94 Time: "0", 95 Cmd: "zero", 96 }, 97 { 98 UID: 1, 99 PID: 1, 100 PPID: 1, 101 C: 1, 102 STime: "1", 103 Time: "1", 104 Cmd: "one", 105 }, 106 }, 107 expected: "[0,1]", 108 }, 109 } 110 111 for _, tc := range testCases { 112 output, err := PrintPIDsJSON(tc.pl) 113 if err != nil { 114 t.Errorf("failed to generate JSON: %v", err) 115 } 116 117 if tc.expected != output { 118 t.Errorf("PrintJSON(%v): got:\n%s\nwant:\n%s", tc.pl, output, tc.expected) 119 } 120 } 121 } 122 123 func TestPercentCPU(t *testing.T) { 124 testCases := []struct { 125 stats usage.CPUStats 126 startTime ktime.Time 127 now ktime.Time 128 expected int32 129 }{ 130 { 131 // Verify that 100% use is capped at 99. 132 stats: usage.CPUStats{UserTime: 1e9, SysTime: 1e9}, 133 startTime: ktime.FromNanoseconds(7e9), 134 now: ktime.FromNanoseconds(9e9), 135 expected: 99, 136 }, 137 { 138 // Verify that if usage > lifetime, we get at most 99% 139 // usage. 140 stats: usage.CPUStats{UserTime: 2e9, SysTime: 2e9}, 141 startTime: ktime.FromNanoseconds(7e9), 142 now: ktime.FromNanoseconds(9e9), 143 expected: 99, 144 }, 145 { 146 // Verify that 50% usage is reported correctly. 147 stats: usage.CPUStats{UserTime: 1e9, SysTime: 1e9}, 148 startTime: ktime.FromNanoseconds(12e9), 149 now: ktime.FromNanoseconds(16e9), 150 expected: 50, 151 }, 152 { 153 // Verify that 0% usage is reported correctly. 154 stats: usage.CPUStats{UserTime: 0, SysTime: 0}, 155 startTime: ktime.FromNanoseconds(12e9), 156 now: ktime.FromNanoseconds(14e9), 157 expected: 0, 158 }, 159 } 160 161 for _, tc := range testCases { 162 if pcpu := percentCPU(tc.stats, tc.startTime, tc.now); pcpu != tc.expected { 163 t.Errorf("percentCPU(%v, %v, %v): got %d, want %d", tc.stats, tc.startTime, tc.now, pcpu, tc.expected) 164 } 165 } 166 }