github.com/google/cadvisor@v0.49.1/utils/oomparser/oomparser_test.go (about) 1 // Copyright 2015 Google Inc. All Rights Reserved. 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 oomparser 16 17 import ( 18 "fmt" 19 "testing" 20 "time" 21 22 "github.com/euank/go-kmsg-parser/kmsgparser" 23 "github.com/stretchr/testify/assert" 24 ) 25 26 const ( 27 startLine = "ruby invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0" 28 endLine = "Killed process 19667 (evil-program2) total-vm:1460016kB, anon-rss:1414008kB, file-rss:4kB" 29 legacyContainerLine = "Task in /mem2 killed as a result of limit of /mem3" 30 containerLine = "oom-kill:constraint=CONSTRAINT_MEMCG,nodemask=(null),cpuset=ef807430361e6e82b45db92e2e9b6fbec98f419b12c591e655c1a725565e73a8,mems_allowed=0,oom_memcg=/kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012,task_memcg=/kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012/ef807430361e6e82b45db92e2e9b6fbec98f419b12c591e655c1a725565e73a8,task=manager,pid=966,uid=0" 31 ) 32 33 func TestGetLegacyContainerName(t *testing.T) { 34 currentOomInstance := new(OomInstance) 35 finished, err := getContainerName(startLine, currentOomInstance) 36 if err != nil { 37 t.Errorf("bad line fed to getContainerName should yield no error, but had error %v", err) 38 } 39 if finished { 40 t.Errorf("bad line fed to getContainerName should not result in a finished oom log, but it did") 41 } 42 if currentOomInstance.ContainerName != "" { 43 t.Errorf("bad line fed to getContainerName yielded no container name but set it to %s", currentOomInstance.ContainerName) 44 } 45 finished, err = getContainerName(legacyContainerLine, currentOomInstance) 46 if err != nil { 47 t.Errorf("container line fed to getContainerName should yield no error, but had error %v", err) 48 } 49 if finished { 50 t.Errorf("getContainerName with the legacy log line should not result in a finished oom log, but it did") 51 52 } 53 if currentOomInstance.ContainerName != "/mem2" { 54 t.Errorf("getContainerName should have set containerName to /mem2, not %s", currentOomInstance.ContainerName) 55 } 56 if currentOomInstance.VictimContainerName != "/mem3" { 57 t.Errorf("getContainerName should have set victimContainerName to /mem3, not %s", currentOomInstance.VictimContainerName) 58 } 59 } 60 61 func TestGetContainerName(t *testing.T) { 62 currentOomInstance := new(OomInstance) 63 finished, err := getContainerName(startLine, currentOomInstance) 64 if err != nil { 65 t.Errorf("bad line fed to getContainerName should yield no error, but had error %v", err) 66 } 67 if finished { 68 t.Errorf("bad line fed to getContainerName should not result in a finished oom log, but it did") 69 } 70 if currentOomInstance.ContainerName != "" { 71 t.Errorf("bad line fed to getContainerName yielded no container name but set it to %s", currentOomInstance.ContainerName) 72 } 73 finished, err = getContainerName(containerLine, currentOomInstance) 74 if err != nil { 75 t.Errorf("container line fed to getContainerName should yield no error, but had error %v", err) 76 } 77 if !finished { 78 t.Errorf("getContainerName with the complete log line should result in a finished oom log, but it did not") 79 80 } 81 if currentOomInstance.ContainerName != "/kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012/ef807430361e6e82b45db92e2e9b6fbec98f419b12c591e655c1a725565e73a8" { 82 t.Errorf("getContainerName should have set containerName to /kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012/ef807430361e6e82b45db92e2e9b6fbec98f419b12c591e655c1a725565e73a8, not %s", currentOomInstance.ContainerName) 83 } 84 if currentOomInstance.VictimContainerName != "/kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012" { 85 t.Errorf("getContainerName should have set victimContainerName to /kubepods/burstable/podfbdfe8e3-1c87-4ff2-907c-b2ec8e25d012, not %s", currentOomInstance.VictimContainerName) 86 } 87 if currentOomInstance.Pid != 966 { 88 t.Errorf("getContainerName should have set Pid to 966, not %d", currentOomInstance.Pid) 89 } 90 if currentOomInstance.ProcessName != "manager" { 91 t.Errorf("getContainerName should have set ProcessName to manager, not %s", currentOomInstance.ProcessName) 92 } 93 if currentOomInstance.Constraint != "CONSTRAINT_MEMCG" { 94 t.Errorf("getContainerName should have set ProcessName to CONSTRAINT_MEMCG, not %s", currentOomInstance.Constraint) 95 } 96 } 97 98 func TestGetProcessNamePid(t *testing.T) { 99 currentOomInstance := new(OomInstance) 100 couldParseLine, err := getProcessNamePid(startLine, currentOomInstance) 101 if err != nil { 102 t.Errorf("bad line fed to getProcessNamePid should yield no error, but had error %v", err) 103 } 104 if couldParseLine { 105 t.Errorf("bad line fed to getProcessNamePid should return false but returned %v", couldParseLine) 106 } 107 108 couldParseLine, err = getProcessNamePid(endLine, currentOomInstance) 109 if err != nil { 110 t.Errorf("good line fed to getProcessNamePid should yield no error, but had error %v", err) 111 } 112 if !couldParseLine { 113 t.Errorf("good line fed to getProcessNamePid should return true but returned %v", couldParseLine) 114 } 115 if currentOomInstance.ProcessName != "evil-program2" { 116 t.Errorf("getProcessNamePid should have set processName to evil-program2, not %s", currentOomInstance.ProcessName) 117 } 118 if currentOomInstance.Pid != 19667 { 119 t.Errorf("getProcessNamePid should have set PID to 19667, not %d", currentOomInstance.Pid) 120 } 121 } 122 123 func TestCheckIfStartOfMessages(t *testing.T) { 124 couldParseLine := checkIfStartOfOomMessages(endLine) 125 if couldParseLine { 126 t.Errorf("bad line fed to checkIfStartOfMessages should return false but returned %v", couldParseLine) 127 } 128 couldParseLine = checkIfStartOfOomMessages(startLine) 129 if !couldParseLine { 130 t.Errorf("start line fed to checkIfStartOfMessages should return true but returned %v", couldParseLine) 131 } 132 } 133 134 func TestLastLineRegex(t *testing.T) { 135 processNames := []string{"foo", "python3.4", "foo-bar", "Plex Media Server", "x86_64-pc-linux-gnu-c++-5.4.0", "[", "()", `"with quotes"`} 136 for _, name := range processNames { 137 line := fmt.Sprintf("Jan 21 22:01:49 localhost kernel: [62279.421192] Killed process 1234 (%s) total-vm:1460016kB, anon-rss:1414008kB, file-rss:4kB", name) 138 oomInfo := &OomInstance{} 139 isPid, err := getProcessNamePid(line, oomInfo) 140 assert.True(t, isPid) 141 assert.NoError(t, err) 142 assert.Equal(t, 1234, oomInfo.Pid) 143 assert.Equal(t, name, oomInfo.ProcessName) 144 } 145 } 146 147 func TestStreamOOMs(t *testing.T) { 148 mockMsgs := make(chan kmsgparser.Message) 149 p := &OomParser{ 150 parser: &mockKmsgParser{ 151 messages: mockMsgs, 152 }, 153 } 154 155 oomsOut := make(chan *OomInstance) 156 157 go func() { 158 p.StreamOoms(oomsOut) 159 }() 160 161 writeAll := func(m []string, t time.Time) { 162 for _, msg := range m { 163 mockMsgs <- kmsgparser.Message{ 164 Message: msg, 165 Timestamp: t, 166 } 167 } 168 } 169 170 type in struct { 171 msgs []string 172 time time.Time 173 } 174 175 testTime := time.Unix(0xf331f4ee, 0) 176 testTime2 := time.Unix(0xfa51f001, 0) 177 testPairs := []struct { 178 in []in 179 out []*OomInstance 180 }{ 181 { 182 in: []in{{ 183 time: testTime, 184 msgs: []string{ 185 "memorymonster invoked oom-killer: gfp_mask=0xd0, order=0, oom_score_adj=0", 186 "memorymonster cpuset=/ mems_allowed=0", 187 "CPU: 5 PID: 13536 Comm: memorymonster Tainted: P OX 3.13.0-43-generic #72-Ubuntu", 188 "Hardware name: Hewlett-Packard HP Z420 Workstation/1589, BIOS J61 v03.65 12/19/2013", 189 " ffff88072ae10800 ffff8807a4835c48 ffffffff81720bf6 ffff8807a8e86000", 190 " ffff8807a4835cd0 ffffffff8171b4b1 0000000000000246 ffff88072ae10800", 191 " ffff8807a4835c90 ffff8807a4835ca0 ffffffff811522a7 0000000000000001", 192 "Call Trace:", 193 " [<ffffffff81720bf6>] dump_stack+0x45/0x56", 194 " [<ffffffff8171b4b1>] dump_header+0x7f/0x1f1", 195 " [<ffffffff811522a7>] ? find_lock_task_mm+0x27/0x70", 196 " [<ffffffff811526de>] oom_kill_process+0x1ce/0x330", 197 " [<ffffffff812d6ce5>] ? security_capable_noaudit+0x15/0x20", 198 " [<ffffffff811b491c>] mem_cgroup_oom_synchronize+0x51c/0x560", 199 " [<ffffffff811b3e50>] ? mem_cgroup_charge_common+0xa0/0xa0", 200 " [<ffffffff81152e64>] pagefault_out_of_memory+0x14/0x80", 201 " [<ffffffff81719aa1>] mm_fault_error+0x8e/0x180", 202 " [<ffffffff8172cf31>] __do_page_fault+0x4a1/0x560", 203 " [<ffffffff810a0255>] ? set_next_entity+0x95/0xb0", 204 " [<ffffffff81012609>] ? __switch_to+0x169/0x4c0", 205 " [<ffffffff8172d00a>] do_page_fault+0x1a/0x70", 206 " [<ffffffff81729468>] page_fault+0x28/0x30", 207 "Task in /mem2 killed as a result of limit of /mem2", 208 "memory: usage 980kB, limit 980kB, failcnt 4152239", 209 "memory+swap: usage 0kB, limit 18014398509481983kB, failcnt 0", 210 "kmem: usage 0kB, limit 18014398509481983kB, failcnt 0", 211 "Memory cgroup stats for /mem2: cache:0KB rss:980KB rss_huge:0KB mapped_file:0KB writeback:20KB inactive_anon:560KB active_anon:420KB inactive_file:0KB active_file:0KB unevictable:0KB", 212 "[ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name", 213 "[13536] 275858 13536 8389663 343 16267 8324326 0 memorymonster", 214 "Memory cgroup out of memory: Kill process 13536 (memorymonster) score 996 or sacrifice child", 215 "Killed process 13536 (memorymonster) total-vm:33558652kB, anon-rss:920kB, file-rss:452kB", 216 }, 217 }}, 218 out: []*OomInstance{{ 219 TimeOfDeath: testTime, 220 ContainerName: "/mem2", 221 ProcessName: "memorymonster", 222 Pid: 13536, 223 VictimContainerName: "/mem2", 224 }}, 225 }, 226 { 227 in: []in{{ 228 time: testTime, 229 msgs: []string{ 230 "badsysprogram invoked oom-killer: gfp_mask=0x280da, order=0, oom_score_adj=0", 231 "badsysprogram cpuset=/ mems_allowed=0", 232 "CPU: 0 PID: 1532 Comm: badsysprogram Not tainted 3.13.0-27-generic #50-Ubuntu", 233 "Hardware name: Google Google, BIOS Google 01/01/2011", 234 " 0000000000000000 ffff880069715a90 ffffffff817199c4 ffff8800680d8000", 235 " ffff880069715b18 ffffffff817142ff 0000000000000000 0000000000000000", 236 " 0000000000000000 0000000000000000 0000000000000000 0000000000000000", 237 "Call Trace:", 238 " [<ffffffff817199c4>] dump_stack+0x45/0x56", 239 " [<ffffffff817142ff>] dump_header+0x7f/0x1f1", 240 " [<ffffffff8115196e>] oom_kill_process+0x1ce/0x330", 241 " [<ffffffff812d3395>] ? security_capable_noaudit+0x15/0x20", 242 " [<ffffffff811520a4>] out_of_memory+0x414/0x450", 243 " [<ffffffff81158377>] __alloc_pages_nodemask+0xa87/0xb20", 244 " [<ffffffff811985da>] alloc_pages_vma+0x9a/0x140", 245 " [<ffffffff8117909b>] handle_mm_fault+0xb2b/0xf10", 246 " [<ffffffff81725924>] __do_page_fault+0x184/0x560", 247 " [<ffffffff8101b7d9>] ? sched_clock+0x9/0x10", 248 " [<ffffffff8109d13d>] ? sched_clock_local+0x1d/0x80", 249 " [<ffffffff811112ec>] ? acct_account_cputime+0x1c/0x20", 250 " [<ffffffff8109d76b>] ? account_user_time+0x8b/0xa0", 251 " [<ffffffff8109dd84>] ? vtime_account_user+0x54/0x60", 252 " [<ffffffff81725d1a>] do_page_fault+0x1a/0x70", 253 " [<ffffffff81722188>] page_fault+0x28/0x30", 254 "Mem-Info:", 255 "Node 0 DMA per-cpu:", 256 "CPU 0: hi: 0, btch: 1 usd: 0", 257 "Node 0 DMA32 per-cpu:", 258 "CPU 0: hi: 186, btch: 31 usd: 86", 259 "active_anon:405991 inactive_anon:57 isolated_anon:0", 260 " active_file:35 inactive_file:69 isolated_file:0", 261 " unevictable:0 dirty:0 writeback:0 unstable:0", 262 " free:12929 slab_reclaimable:1635 slab_unreclaimable:1919", 263 " mapped:34 shmem:70 pagetables:1423 bounce:0", 264 " free_cma:0", 265 "Node 0 DMA free:7124kB min:412kB low:512kB high:616kB active_anon:8508kB inactive_anon:4kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:4kB slab_reclaimable:16kB slab_unreclaimable:16kB kernel_stack:0kB pagetables:12kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes", 266 "lowmem_reserve[]: 0 1679 1679 1679", 267 "Node 0 DMA32 free:44592kB min:44640kB low:55800kB high:66960kB active_anon:1615456kB inactive_anon:224kB active_file:140kB inactive_file:276kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:1765368kB managed:1722912kB mlocked:0kB dirty:0kB writeback:0kB mapped:136kB shmem:276kB slab_reclaimable:6524kB slab_unreclaimable:7660kB kernel_stack:592kB pagetables:5680kB unstable:0kB bounce:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:819 all_unreclaimable? yes", 268 "lowmem_reserve[]: 0 0 0 0", 269 "Node 0 DMA: 5*4kB (UM) 6*8kB (UEM) 7*16kB (UEM) 1*32kB (M) 2*64kB (UE) 3*128kB (UEM) 1*256kB (E) 2*512kB (EM) 3*1024kB (UEM) 1*2048kB (R) 0*4096kB = 7124kB", 270 "Node 0 DMA32: 74*4kB (UEM) 125*8kB (UEM) 78*16kB (UEM) 26*32kB (UE) 12*64kB (UEM) 4*128kB (UE) 4*256kB (UE) 2*512kB (E) 11*1024kB (UE) 7*2048kB (UE) 3*4096kB (UR) = 44592kB", 271 "Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB", 272 "204 total pagecache pages", 273 "0 pages in swap cache", 274 "Swap cache stats: add 0, delete 0, find 0/0", 275 "Free swap = 0kB", 276 "Total swap = 0kB", 277 "445340 pages RAM", 278 "0 pages HighMem/MovableOnly", 279 "10614 pages reserved", 280 "[ pid ] uid tgid total_vm rss nr_ptes swapents oom_score_adj name", 281 "[ 273] 0 273 4869 50 13 0 0 upstart-udev-br", 282 "[ 293] 0 293 12802 154 28 0 -1000 systemd-udevd", 283 "[ 321] 0 321 3819 54 12 0 0 upstart-file-br", 284 "[ 326] 102 326 9805 109 24 0 0 dbus-daemon", 285 "[ 334] 101 334 63960 94 26 0 0 rsyslogd", 286 "[ 343] 0 343 10863 102 26 0 0 systemd-logind", 287 "[ 546] 0 546 3815 60 13 0 0 upstart-socket-", 288 "[ 710] 0 710 2556 587 8 0 0 dhclient", 289 "[ 863] 0 863 3955 48 13 0 0 getty", 290 "[ 865] 0 865 3955 50 13 0 0 getty", 291 "[ 867] 0 867 3955 51 13 0 0 getty", 292 "[ 868] 0 868 3955 51 12 0 0 getty", 293 "[ 870] 0 870 3955 49 13 0 0 getty", 294 "[ 915] 0 915 5914 61 16 0 0 cron", 295 "[ 1015] 0 1015 10885 1524 25 0 0 manage_addresse", 296 "[ 1028] 0 1028 3955 49 13 0 0 getty", 297 "[ 1033] 0 1033 3197 48 12 0 0 getty", 298 "[ 1264] 0 1264 11031 1635 26 0 0 manage_accounts", 299 "[ 1268] 0 1268 15341 180 33 0 -1000 sshd", 300 "[ 1313] 104 1313 6804 154 17 0 0 ntpd", 301 "[ 1389] 0 1389 25889 255 55 0 0 sshd", 302 "[ 1407] 1020 1407 25889 255 52 0 0 sshd", 303 "[ 1408] 1020 1408 5711 581 17 0 0 bash", 304 "[ 1425] 0 1425 25889 256 53 0 0 sshd", 305 "[ 1443] 1020 1443 25889 257 52 0 0 sshd", 306 "[ 1444] 1020 1444 5711 581 16 0 0 bash", 307 "[ 1476] 1020 1476 1809 25 9 0 0 tail", 308 "[ 1532] 1020 1532 410347 398810 788 0 0 badsysprogram", 309 "Out of memory: Kill process 1532 (badsysprogram) score 919 or sacrifice child", 310 "Killed process 1532 (badsysprogram) total-vm:1641388kB, anon-rss:1595164kB, file-rss:76kB", 311 }, 312 }}, 313 out: []*OomInstance{{ 314 Pid: 1532, 315 ProcessName: "badsysprogram", 316 TimeOfDeath: testTime, 317 ContainerName: "/", 318 VictimContainerName: "/", 319 }}, 320 }, 321 { // Multiple OOMs 322 // These were generated via `docker run -m 20M euank/gunpowder-memhog 2G; docker run -m 300M euank/gunpowder-memhog 800M` 323 // followed by nabbing output from `/dev/kmsg` and stripping the syslog-ish prefixes `kmsgparser` will handle anyways. 324 in: []in{ 325 { 326 time: testTime, 327 msgs: []string{ 328 "docker0: port 2(veth380a1cd) entered disabled state", 329 "device veth380a1cd left promiscuous mode", 330 "docker0: port 2(veth380a1cd) entered disabled state", 331 "docker0: port 2(vethcd0dbfb) entered blocking state", 332 "docker0: port 2(vethcd0dbfb) entered disabled state", 333 "device vethcd0dbfb entered promiscuous mode", 334 "IPv6: ADDRCONF(NETDEV_UP): vethcd0dbfb: link is not ready", 335 "IPv6: ADDRCONF(NETDEV_CHANGE): vethcd0dbfb: link becomes ready", 336 "docker0: port 2(vethcd0dbfb) entered blocking state", 337 "docker0: port 2(vethcd0dbfb) entered forwarding state", 338 "docker0: port 2(vethcd0dbfb) entered disabled state", 339 "eth0: renamed from vethbcd01c4", 340 "docker0: port 2(vethcd0dbfb) entered blocking state", 341 "docker0: port 2(vethcd0dbfb) entered forwarding state", 342 "gunpowder-memho invoked oom-killer: gfp_mask=0x24000c0(GFP_KERNEL), order=0, oom_score_adj=0", 343 "gunpowder-memho cpuset=2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50 mems_allowed=0", 344 "CPU: 0 PID: 1381 Comm: gunpowder-memho Tainted: G O 4.8.0-gentoo #2", 345 "Hardware name: LENOVO 20BSCTO1WW/20BSCTO1WW, BIOS N14ET32W (1.10 ) 08/13/2015", 346 " 0000000000000000 ffff8800968e3ca0 ffffffff8137ad47 ffff8800968e3d68", 347 " ffff8800b74ee540 ffff8800968e3d00 ffffffff811261dd 0000000000000003", 348 " 0000000000000000 0000000000000001 0000000000000246 0000000000000202", 349 "Call Trace:", 350 " [<ffffffff8137ad47>] dump_stack+0x4d/0x63", 351 " [<ffffffff811261dd>] dump_header+0x58/0x1c8", 352 " [<ffffffff810e85fe>] oom_kill_process+0x7e/0x362", 353 " [<ffffffff811221a8>] ? mem_cgroup_iter+0x109/0x23e", 354 " [<ffffffff811239dc>] mem_cgroup_out_of_memory+0x241/0x299", 355 " [<ffffffff81124447>] mem_cgroup_oom_synchronize+0x273/0x28c", 356 " [<ffffffff81120839>] ? __mem_cgroup_insert_exceeded+0x76/0x76", 357 " [<ffffffff810e8b46>] pagefault_out_of_memory+0x1f/0x76", 358 " [<ffffffff81038f38>] mm_fault_error+0x56/0x108", 359 " [<ffffffff81039355>] __do_page_fault+0x36b/0x3ee", 360 " [<ffffffff81039405>] do_page_fault+0xc/0xe", 361 " [<ffffffff81560082>] page_fault+0x22/0x30", 362 "Task in /docker/2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50 killed as a result of limit of /docker/2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50", 363 "memory: usage 20480kB, limit 20480kB, failcnt 1204", 364 "memory+swap: usage 40940kB, limit 40960kB, failcnt 6", 365 "kmem: usage 220kB, limit 9007199254740988kB, failcnt 0", 366 "Memory cgroup stats for /docker/2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50: cache:0KB rss:20260KB rss_huge:0KB mapped_file:0KB dirty:0KB writeback:1016KB swap:20460KB inactive_anon:10232KB active_anon:10028KB inactive_file:0KB active_file:0KB unevictable:0KB", 367 "[ pid ] uid tgid total_vm rss nr_ptes nr_pmds swapents oom_score_adj name", 368 "[ 1381] 0 1381 530382 5191 34 4 5489 0 gunpowder-memho", 369 "Memory cgroup out of memory: Kill process 1381 (gunpowder-memho) score 1046 or sacrifice child", 370 "Killed process 1381 (gunpowder-memho) total-vm:2121528kB, anon-rss:18624kB, file-rss:2140kB, shmem-rss:0kB", 371 "oom_reaper: reaped process 1381 (gunpowder-memho), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB", 372 "docker0: port 2(vethcd0dbfb) entered disabled state", 373 "vethbcd01c4: renamed from eth0", 374 "docker0: port 2(vethcd0dbfb) entered disabled state", 375 "device vethcd0dbfb left promiscuous mode", 376 "docker0: port 2(vethcd0dbfb) entered disabled state", 377 "docker0: port 2(veth4cb51e1) entered blocking state", 378 "docker0: port 2(veth4cb51e1) entered disabled state", 379 "device veth4cb51e1 entered promiscuous mode", 380 }, 381 }, 382 { 383 time: testTime2, 384 msgs: []string{ 385 "IPv6: ADDRCONF(NETDEV_UP): veth4cb51e1: link is not ready", 386 "docker0: port 2(veth4cb51e1) entered blocking state", 387 "docker0: port 2(veth4cb51e1) entered forwarding state", 388 "IPv6: ADDRCONF(NETDEV_CHANGE): veth4cb51e1: link becomes ready", 389 "docker0: port 2(veth4cb51e1) entered disabled state", 390 "eth0: renamed from veth4b89c12", 391 "docker0: port 2(veth4cb51e1) entered blocking state", 392 "docker0: port 2(veth4cb51e1) entered forwarding state", 393 "gunpowder-memho invoked oom-killer: gfp_mask=0x24000c0(GFP_KERNEL), order=0, oom_score_adj=0", 394 "gunpowder-memho cpuset=6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70 mems_allowed=0", 395 "CPU: 0 PID: 1667 Comm: gunpowder-memho Tainted: G O 4.8.0-gentoo #2", 396 "Hardware name: LENOVO 20BSCTO1WW/20BSCTO1WW, BIOS N14ET32W (1.10 ) 08/13/2015", 397 " 0000000000000000 ffff88008137fca0 ffffffff8137ad47 ffff88008137fd68", 398 " ffff8801c75b0c40 ffff88008137fd00 ffffffff811261dd 0000000000000003", 399 " 0000000000000000 0000000000000001 0000000000000246 0000000000000202", 400 "Call Trace:", 401 " [<ffffffff8137ad47>] dump_stack+0x4d/0x63", 402 " [<ffffffff811261dd>] dump_header+0x58/0x1c8", 403 " [<ffffffff810e85fe>] oom_kill_process+0x7e/0x362", 404 " [<ffffffff811221a8>] ? mem_cgroup_iter+0x109/0x23e", 405 " [<ffffffff811239dc>] mem_cgroup_out_of_memory+0x241/0x299", 406 " [<ffffffff81124447>] mem_cgroup_oom_synchronize+0x273/0x28c", 407 " [<ffffffff81120839>] ? __mem_cgroup_insert_exceeded+0x76/0x76", 408 " [<ffffffff810e8b46>] pagefault_out_of_memory+0x1f/0x76", 409 " [<ffffffff81038f38>] mm_fault_error+0x56/0x108", 410 " [<ffffffff81039355>] __do_page_fault+0x36b/0x3ee", 411 " [<ffffffff81039405>] do_page_fault+0xc/0xe", 412 " [<ffffffff81560082>] page_fault+0x22/0x30", 413 "Task in /docker/6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70 killed as a result of limit of /docker/6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70", 414 "memory: usage 307112kB, limit 307200kB, failcnt 35982", 415 "memory+swap: usage 614400kB, limit 614400kB, failcnt 11", 416 "kmem: usage 1308kB, limit 9007199254740988kB, failcnt 0", 417 "Memory cgroup stats for /docker/6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70: cache:0KB rss:305804KB rss_huge:0KB mapped_file:0KB dirty:0KB writeback:55884KB swap:307288KB inactive_anon:152940KB active_anon:152832KB inactive_file:0KB active_file:0KB unevictable:0KB", 418 "[ pid ] uid tgid total_vm rss nr_ptes nr_pmds swapents oom_score_adj name", 419 "[ 1667] 0 1667 210894 62557 315 4 91187 0 gunpowder-memho", 420 "Memory cgroup out of memory: Kill process 1667 (gunpowder-memho) score 1003 or sacrifice child", 421 "Killed process 1667 (gunpowder-memho) total-vm:843576kB, anon-rss:248180kB, file-rss:2048kB, shmem-rss:0kB", 422 "oom_reaper: reaped process 1667 (gunpowder-memho), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB", 423 "docker0: port 2(veth4cb51e1) entered disabled state", 424 "veth4b89c12: renamed from eth0", 425 "docker0: port 2(veth4cb51e1) entered blocking state", 426 "docker0: port 2(veth4cb51e1) entered forwarding state", 427 "docker0: port 2(veth4cb51e1) entered disabled state", 428 "device veth4cb51e1 left promiscuous mode", 429 "docker0: port 2(veth4cb51e1) entered disabled state", 430 }, 431 }, 432 }, 433 out: []*OomInstance{ 434 { 435 Pid: 1381, 436 ProcessName: "gunpowder-memho", 437 TimeOfDeath: testTime, 438 ContainerName: "/docker/2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50", 439 VictimContainerName: "/docker/2e088fe462e25e60be1dafafe2c05c47bda1a97978648d10ad2b7484fc0b8f50", 440 }, 441 { 442 Pid: 1667, 443 ProcessName: "gunpowder-memho", 444 TimeOfDeath: testTime2, 445 ContainerName: "/docker/6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70", 446 VictimContainerName: "/docker/6c6fcab8562fd3150854986b78552c732f234fd405b624207b8843528a145e70", 447 }, 448 }, 449 }, 450 } 451 452 for _, pair := range testPairs { 453 pair := pair 454 go func() { 455 for _, x := range pair.in { 456 writeAll(x.msgs, x.time) 457 } 458 }() 459 for _, expected := range pair.out { 460 oom := <-oomsOut 461 assert.Equal(t, expected, oom) 462 } 463 464 select { 465 case oom := <-oomsOut: 466 t.Errorf("did not expect any remaining OOMs, got %+v", oom) 467 default: 468 } 469 470 } 471 } 472 473 type mockKmsgParser struct { 474 messages chan kmsgparser.Message 475 } 476 477 func (m *mockKmsgParser) SeekEnd() error { 478 return nil 479 } 480 481 func (m *mockKmsgParser) Parse() <-chan kmsgparser.Message { 482 return m.messages 483 } 484 485 func (m *mockKmsgParser) SetLogger(kmsgparser.Logger) {} 486 func (m *mockKmsgParser) Close() error { 487 close(m.messages) 488 return nil 489 }