github.com/minio/madmin-go/v2@v2.2.1/cgroup/linux_test.go (about) 1 //go:build linux 2 // +build linux 3 4 // 5 // Copyright (c) 2015-2022 MinIO, Inc. 6 // 7 // This file is part of MinIO Object Storage stack 8 // 9 // This program is free software: you can redistribute it and/or modify 10 // it under the terms of the GNU Affero General Public License as 11 // published by the Free Software Foundation, either version 3 of the 12 // License, or (at your option) any later version. 13 // 14 // This program is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU Affero General Public License for more details. 18 // 19 // You should have received a copy of the GNU Affero General Public License 20 // along with this program. If not, see <http://www.gnu.org/licenses/>. 21 // 22 23 package cgroup 24 25 import ( 26 "io/ioutil" 27 "os" 28 "testing" 29 ) 30 31 // Testing parsing correctness for various process cgroup files. 32 func TestProcCGroup(t *testing.T) { 33 tmpPath, err := ioutil.TempFile("", "cgroup") 34 if err != nil { 35 t.Fatal(err) 36 } 37 defer os.Remove(tmpPath.Name()) 38 39 cgroup := ` 40 11:memory:/user.slice 41 10:blkio:/user.slice 42 9:hugetlb:/ 43 8:net_cls,net_prio:/ 44 7:perf_event:/ 45 6:pids:/user.slice/user-1000.slice 46 5:devices:/user.slice 47 4:cpuset:/ 48 3:cpu,cpuacct:/user.slice 49 2:freezer:/ 50 1:name=systemd:/user.slice/user-1000.slice/session-1.scope 51 ` 52 _, err = tmpPath.WriteString(cgroup) 53 if err != nil { 54 t.Fatal(err) 55 } 56 57 // Seek back to read from the beginning. 58 tmpPath.Seek(0, 0) 59 60 cg, err := parseProcCGroup(tmpPath) 61 if err != nil { 62 t.Fatal(err) 63 } 64 65 path := cg["memory"] 66 if len(path) == 0 { 67 t.Fatal("Path component cannot be empty") 68 } 69 70 if path != "/user.slice" { 71 t.Fatal("Path component cannot be empty") 72 } 73 74 path = cg["systemd"] 75 if path != "/user.slice/user-1000.slice/session-1.scope" { 76 t.Fatal("Path component cannot be empty") 77 } 78 79 // Mixed cgroups with different group names. 80 cgroup = ` 81 11:memory:/newtest/newtest 82 10:blkio:/user.slice 83 9:hugetlb:/ 84 8:net_cls,net_prio:/ 85 7:perf_event:/ 86 6:pids:/user.slice/user-1000.slice 87 5:devices:/user.slice 88 4:cpuset:/ 89 3:cpu,cpuacct:/newtest/newtest 90 2:freezer:/ 91 1:name=systemd:/user.slice/user-1000.slice/session-1.scope 92 ` 93 94 // Seek back to read from the beginning. 95 tmpPath.Seek(0, 0) 96 97 _, err = tmpPath.WriteString(cgroup) 98 if err != nil { 99 t.Fatal(err) 100 } 101 102 // Seek back to read from the beginning. 103 tmpPath.Seek(0, 0) 104 105 cg, err = parseProcCGroup(tmpPath) 106 if err != nil { 107 t.Fatal(err) 108 } 109 110 path = cg["memory"] 111 if path != "/newtest/newtest" { 112 t.Fatal("Path component cannot be empty") 113 } 114 115 path = cg["systemd"] 116 if path != "/user.slice/user-1000.slice/session-1.scope" { 117 t.Fatal("Path component cannot be empty") 118 } 119 } 120 121 // Tests cgroup memory limit path construction. 122 func TestMemoryLimitPath(t *testing.T) { 123 testCases := []struct { 124 cgroupPath string 125 expectedPath string 126 }{ 127 { 128 cgroupPath: "/user.slice", 129 expectedPath: "/sys/fs/cgroup/memory/user.slice/memory.limit_in_bytes", 130 }, 131 { 132 cgroupPath: "/docker/testing", 133 expectedPath: "/sys/fs/cgroup/memory/memory.limit_in_bytes", 134 }, 135 } 136 137 for i, testCase := range testCases { 138 actualPath := getMemoryLimitFilePath(testCase.cgroupPath) 139 if actualPath != testCase.expectedPath { 140 t.Fatalf("Test: %d: Expected: %s, got %s", i+1, testCase.expectedPath, actualPath) 141 } 142 } 143 }