github.com/cilium/cilium@v1.16.2/pkg/cgroups/manager/provider_test.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package manager 5 6 import ( 7 "errors" 8 "fmt" 9 "os" 10 "testing" 11 12 "github.com/stretchr/testify/require" 13 14 "github.com/cilium/cilium/pkg/cgroups" 15 v1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/api/core/v1" 16 ) 17 18 var ( 19 fsMockDefault = fsMock{ 20 getFullPath(defaultCgroupBasePath): struct{}{}, 21 } 22 fsMockSystemd = fsMock{ 23 getFullPath(systemdCgroupBasePath): struct{}{}, 24 } 25 fsMockNested = fsMock{ 26 getFullPath(nestedCgroupBasePath): struct{}{}, 27 } 28 fsMockSystemdNested = fsMock{ 29 getFullPath(nestedSystemdCgroupBasePath): struct{}{}, 30 } 31 cgroupRoot = cgroups.GetCgroupRoot() 32 cDefaultPath = cgroupRoot + "/kubepods/burstable/pod1858680e-b044-4fd5-9dd4-f137e30e2180/" + c1Id 33 cDefaultGuaranteedPath = cgroupRoot + "/kubepods/pod1858680e-b044-4fd5-9dd4-f137e30e2180/" + c1Id 34 cSystemdPath = cgroupRoot + "/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod1858680e_b044_4fd5_9dd4_f137e30e2180.slice/" + "cri-containerd-" + c1Id + ".scope" 35 cSystemdGuaranteedPath = cgroupRoot + "/kubepods.slice/kubepods-pod1858680e_b044_4fd5_9dd4_f137e30e2180.slice/" + "crio-" + c1Id + ".scope" 36 cNestedPath = cgroupRoot + "/kubelet/kubepods/burstable/pod1858680e-b044-4fd5-9dd4-f137e30e2180/" + c1Id 37 cSystemdNestedPath = cgroupRoot + "/kubelet.slice/kubelet-kubepods.slice/kubelet-kubepods-burstable.slice/kubelet-kubepods-burstable-pod1858680e_b044_4fd5_9dd4_f137e30e2180.slice/" + "cri-containerd-" + c1Id + ".scope" 38 ) 39 40 type fsMock map[string]struct{} 41 42 func (fs fsMock) Stat(file string) (info os.FileInfo, err error) { 43 if _, ok := fs[file]; ok { 44 return nil, nil 45 } 46 47 return nil, errors.New("") 48 } 49 50 func TestGetBasePath(t *testing.T) { 51 type test struct { 52 input fs 53 want string 54 } 55 tests := []test{ 56 {input: fsMockDefault, want: getFullPath(defaultCgroupBasePath)}, 57 {input: fsMockSystemd, want: getFullPath(systemdCgroupBasePath)}, 58 {input: fsMockNested, want: getFullPath(nestedCgroupBasePath)}, 59 {input: fsMockSystemdNested, want: getFullPath(nestedSystemdCgroupBasePath)}, 60 } 61 62 for i, tt := range tests { 63 t.Run(fmt.Sprintf("Test index %d", i), func(t *testing.T) { 64 initProviderTest(tt.input) 65 got, err := getCgroupPathProvider() 66 require.NoError(t, err) 67 require.NotNil(t, got) 68 path, err := got.getBasePath() 69 require.NoError(t, err) 70 require.Equal(t, tt.want, path) 71 }) 72 73 } 74 } 75 76 type inputParams struct { 77 provider cgroupPathProvider 78 podId string 79 containerId string 80 qos v1.PodQOSClass 81 fsMock fs 82 } 83 84 func getTestInput() *inputParams { 85 return &inputParams{ 86 provider: newDefaultProvider(), 87 podId: string(pod1.ObjectMeta.UID), 88 containerId: c1Id, 89 qos: pod1.Status.QOSClass, 90 fsMock: fsMock{ 91 cgroupRoot + defaultCgroupBasePath: struct{}{}, 92 cDefaultPath: struct{}{}, 93 }, 94 } 95 } 96 97 func TestGetContainerPath(t *testing.T) { 98 tests := []struct { 99 name string 100 input func(input *inputParams) 101 want string 102 wantErr bool 103 }{ 104 { 105 name: "default provider", 106 want: cDefaultPath, 107 }, 108 { 109 name: "default provider + guaranteed qos pod", 110 input: func(input *inputParams) { 111 input.qos = v1.PodQOSGuaranteed 112 input.fsMock = fsMock{ 113 cgroupRoot + defaultCgroupBasePath: struct{}{}, 114 cDefaultGuaranteedPath: struct{}{}, 115 } 116 }, 117 want: cDefaultGuaranteedPath, 118 }, 119 { 120 name: "systemd provider", 121 input: func(input *inputParams) { 122 input.provider = newSystemdProvider() 123 input.fsMock = fsMock{ 124 cgroupRoot + systemdCgroupBasePath: struct{}{}, 125 cSystemdPath: struct{}{}, 126 } 127 }, 128 want: cSystemdPath, 129 }, 130 { 131 name: "systemd provider + guaranteed qos pod + crio", 132 input: func(input *inputParams) { 133 input.provider = newSystemdProvider() 134 input.qos = v1.PodQOSGuaranteed 135 input.fsMock = fsMock{ 136 cgroupRoot + systemdCgroupBasePath: struct{}{}, 137 cSystemdGuaranteedPath: struct{}{}, 138 } 139 }, 140 want: cSystemdGuaranteedPath, 141 }, 142 { 143 name: "nested provider", 144 input: func(input *inputParams) { 145 input.provider = newNestedProvider() 146 input.fsMock = fsMock{ 147 cgroupRoot + nestedCgroupBasePath: struct{}{}, 148 cNestedPath: struct{}{}, 149 } 150 }, 151 want: cNestedPath, 152 }, 153 { 154 name: "nested systemd provider", 155 input: func(input *inputParams) { 156 input.provider = newNestedSystemdProvider() 157 input.fsMock = fsMock{ 158 cgroupRoot + nestedSystemdCgroupBasePath: struct{}{}, 159 cSystemdNestedPath: struct{}{}, 160 } 161 }, 162 want: cSystemdNestedPath, 163 }, 164 { 165 name: "default provider + no valid path", 166 input: func(input *inputParams) { 167 input.fsMock = fsMock{ 168 cgroupRoot + defaultCgroupBasePath: struct{}{}, 169 cgroupRoot + "/foo": struct{}{}, 170 } 171 }, 172 want: "", 173 wantErr: true, 174 }, 175 { 176 name: "systemd provider + no valid path", 177 input: func(input *inputParams) { 178 input.provider = newSystemdProvider() 179 input.fsMock = fsMock{ 180 cgroupRoot + systemdCgroupBasePath: struct{}{}, 181 cgroupRoot + "/foo": struct{}{}, 182 } 183 }, 184 want: "", 185 wantErr: true, 186 }, 187 { 188 name: "nested systemd provider + no valid path", 189 input: func(input *inputParams) { 190 input.provider = newNestedSystemdProvider() 191 input.fsMock = fsMock{ 192 cgroupRoot + nestedSystemdCgroupBasePath: struct{}{}, 193 cgroupRoot + "/foo": struct{}{}, 194 } 195 }, 196 want: "", 197 wantErr: true, 198 }, 199 } 200 201 for _, tt := range tests { 202 t.Run(tt.name, func(t *testing.T) { 203 ti := getTestInput() 204 if tt.input != nil { 205 tt.input(ti) 206 } 207 initProviderTest(ti.fsMock) 208 209 got, err := ti.provider.getContainerPath(ti.podId, ti.containerId, ti.qos) 210 211 if !tt.wantErr { 212 require.NoError(t, err) 213 require.Equal(t, tt.want, got) 214 } else { 215 require.Error(t, err) 216 } 217 }) 218 } 219 }