github.com/minio/madmin-go/v3@v3.0.51/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 "os" 27 "testing" 28 ) 29 30 // Testing parsing correctness for various process cgroup files. 31 func TestProcCGroup(t *testing.T) { 32 tmpPath, err := os.CreateTemp("", "cgroup") 33 if err != nil { 34 t.Fatal(err) 35 } 36 defer os.Remove(tmpPath.Name()) 37 38 cgroup := ` 39 11:memory:/user.slice 40 10:blkio:/user.slice 41 9:hugetlb:/ 42 8:net_cls,net_prio:/ 43 7:perf_event:/ 44 6:pids:/user.slice/user-1000.slice 45 5:devices:/user.slice 46 4:cpuset:/ 47 3:cpu,cpuacct:/user.slice 48 2:freezer:/ 49 1:name=systemd:/user.slice/user-1000.slice/session-1.scope 50 ` 51 _, err = tmpPath.WriteString(cgroup) 52 if err != nil { 53 t.Fatal(err) 54 } 55 56 // Seek back to read from the beginning. 57 tmpPath.Seek(0, 0) 58 59 cg, err := parseProcCGroup(tmpPath) 60 if err != nil { 61 t.Fatal(err) 62 } 63 64 path := cg["memory"] 65 if len(path) == 0 { 66 t.Fatal("Path component cannot be empty") 67 } 68 69 if path != "/user.slice" { 70 t.Fatal("Path component cannot be empty") 71 } 72 73 path = cg["systemd"] 74 if path != "/user.slice/user-1000.slice/session-1.scope" { 75 t.Fatal("Path component cannot be empty") 76 } 77 78 // Mixed cgroups with different group names. 79 cgroup = ` 80 11:memory:/newtest/newtest 81 10:blkio:/user.slice 82 9:hugetlb:/ 83 8:net_cls,net_prio:/ 84 7:perf_event:/ 85 6:pids:/user.slice/user-1000.slice 86 5:devices:/user.slice 87 4:cpuset:/ 88 3:cpu,cpuacct:/newtest/newtest 89 2:freezer:/ 90 1:name=systemd:/user.slice/user-1000.slice/session-1.scope 91 ` 92 93 // Seek back to read from the beginning. 94 tmpPath.Seek(0, 0) 95 96 _, err = tmpPath.WriteString(cgroup) 97 if err != nil { 98 t.Fatal(err) 99 } 100 101 // Seek back to read from the beginning. 102 tmpPath.Seek(0, 0) 103 104 cg, err = parseProcCGroup(tmpPath) 105 if err != nil { 106 t.Fatal(err) 107 } 108 109 path = cg["memory"] 110 if path != "/newtest/newtest" { 111 t.Fatal("Path component cannot be empty") 112 } 113 114 path = cg["systemd"] 115 if path != "/user.slice/user-1000.slice/session-1.scope" { 116 t.Fatal("Path component cannot be empty") 117 } 118 } 119 120 // Tests cgroup memory limit path construction. 121 func TestMemoryLimitPath(t *testing.T) { 122 testCases := []struct { 123 cgroupPath string 124 expectedPath string 125 }{ 126 { 127 cgroupPath: "/user.slice", 128 expectedPath: "/sys/fs/cgroup/memory/user.slice/memory.limit_in_bytes", 129 }, 130 { 131 cgroupPath: "/docker/testing", 132 expectedPath: "/sys/fs/cgroup/memory/memory.limit_in_bytes", 133 }, 134 } 135 136 for i, testCase := range testCases { 137 actualPath := getMemoryLimitFilePath(testCase.cgroupPath) 138 if actualPath != testCase.expectedPath { 139 t.Fatalf("Test: %d: Expected: %s, got %s", i+1, testCase.expectedPath, actualPath) 140 } 141 } 142 }