1// +build functional 2 3package cri_containerd 4 5import ( 6 "context" 7 "testing" 8 9 runtime "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2" 10) 11 12func runContainerAndQueryStats(t *testing.T, client runtime.RuntimeServiceClient, ctx context.Context, request *runtime.CreateContainerRequest) { 13 containerID := createContainer(t, client, ctx, request) 14 defer removeContainer(t, client, ctx, containerID) 15 startContainer(t, client, ctx, containerID) 16 defer stopContainer(t, client, ctx, containerID) 17 18 statsRequest := &runtime.ContainerStatsRequest{ 19 ContainerId: containerID, 20 } 21 22 stats, err := client.ContainerStats(ctx, statsRequest) 23 if err != nil { 24 t.Fatal(err) 25 } 26 27 stat := stats.Stats 28 verifyStatsContent(t, stat) 29} 30 31func runContainerAndQueryListStats(t *testing.T, client runtime.RuntimeServiceClient, ctx context.Context, request *runtime.CreateContainerRequest) { 32 containerID := createContainer(t, client, ctx, request) 33 defer removeContainer(t, client, ctx, containerID) 34 startContainer(t, client, ctx, containerID) 35 defer stopContainer(t, client, ctx, containerID) 36 37 statsRequest := &runtime.ListContainerStatsRequest{ 38 Filter: &runtime.ContainerStatsFilter{ 39 Id: containerID, 40 }, 41 } 42 43 stats, err := client.ListContainerStats(ctx, statsRequest) 44 if err != nil { 45 t.Fatal(err) 46 } 47 48 if len(stats.Stats) != 1 { 49 t.Fatalf("expected 1 stats result but got %d", len(stats.Stats)) 50 } 51 stat := stats.Stats[0] 52 verifyStatsContent(t, stat) 53} 54 55func verifyStatsContent(t *testing.T, stat *runtime.ContainerStats) { 56 if stat == nil { 57 t.Fatal("expected stat to be non nil") 58 } 59 if stat.Cpu.Timestamp == 0 { 60 t.Fatalf("expected cpu stat timestamp != 0 but got %d", stat.Cpu.Timestamp) 61 } 62 if stat.Cpu.UsageCoreNanoSeconds.Value == 0 { 63 t.Fatalf("expected cpu usage != 0 but got %d", stat.Cpu.UsageCoreNanoSeconds.Value) 64 } 65 if stat.Memory.Timestamp == 0 { 66 t.Fatalf("expected memory stat timestamp != 0 but got %d", stat.Memory.Timestamp) 67 } 68 if stat.Memory.WorkingSetBytes.Value == 0 { 69 t.Fatalf("expected memory usage != 0 but got %d", stat.Memory.WorkingSetBytes.Value) 70 } 71} 72 73func Test_SandboxStats_Single_LCOW(t *testing.T) { 74 pullRequiredLcowImages(t, []string{imageLcowK8sPause}) 75 76 request := &runtime.RunPodSandboxRequest{ 77 Config: &runtime.PodSandboxConfig{ 78 Metadata: &runtime.PodSandboxMetadata{ 79 Name: t.Name(), 80 Namespace: testNamespace, 81 }, 82 }, 83 RuntimeHandler: lcowRuntimeHandler, 84 } 85 86 client := newTestRuntimeClient(t) 87 ctx, cancel := context.WithCancel(context.Background()) 88 defer cancel() 89 90 podID := runPodSandbox(t, client, ctx, request) 91 defer removePodSandbox(t, client, ctx, podID) 92 defer stopPodSandbox(t, client, ctx, podID) 93 94 statsRequest := &runtime.ContainerStatsRequest{ 95 ContainerId: podID, 96 } 97 98 stats, err := client.ContainerStats(ctx, statsRequest) 99 if err != nil { 100 t.Fatal(err) 101 } 102 103 stat := stats.Stats 104 verifyStatsContent(t, stat) 105} 106 107func Test_SandboxStats_List_ContainerID_LCOW(t *testing.T) { 108 pullRequiredLcowImages(t, []string{imageLcowK8sPause}) 109 110 request := &runtime.RunPodSandboxRequest{ 111 Config: &runtime.PodSandboxConfig{ 112 Metadata: &runtime.PodSandboxMetadata{ 113 Name: t.Name(), 114 Namespace: testNamespace, 115 }, 116 }, 117 RuntimeHandler: lcowRuntimeHandler, 118 } 119 120 client := newTestRuntimeClient(t) 121 ctx, cancel := context.WithCancel(context.Background()) 122 defer cancel() 123 124 podID := runPodSandbox(t, client, ctx, request) 125 defer removePodSandbox(t, client, ctx, podID) 126 defer stopPodSandbox(t, client, ctx, podID) 127 128 statsRequest := &runtime.ListContainerStatsRequest{ 129 Filter: &runtime.ContainerStatsFilter{ 130 Id: podID, 131 }, 132 } 133 134 stats, err := client.ListContainerStats(ctx, statsRequest) 135 if err != nil { 136 t.Fatal(err) 137 } 138 139 if len(stats.Stats) != 1 { 140 t.Fatalf("expected 1 stats result but got %d", len(stats.Stats)) 141 } 142 stat := stats.Stats[0] 143 verifyStatsContent(t, stat) 144} 145 146func Test_SandboxStats_List_PodID_LCOW(t *testing.T) { 147 pullRequiredLcowImages(t, []string{imageLcowK8sPause}) 148 149 request := &runtime.RunPodSandboxRequest{ 150 Config: &runtime.PodSandboxConfig{ 151 Metadata: &runtime.PodSandboxMetadata{ 152 Name: t.Name(), 153 Namespace: testNamespace, 154 }, 155 }, 156 RuntimeHandler: lcowRuntimeHandler, 157 } 158 159 client := newTestRuntimeClient(t) 160 ctx, cancel := context.WithCancel(context.Background()) 161 defer cancel() 162 163 podID := runPodSandbox(t, client, ctx, request) 164 defer removePodSandbox(t, client, ctx, podID) 165 defer stopPodSandbox(t, client, ctx, podID) 166 167 statsRequest := &runtime.ListContainerStatsRequest{ 168 Filter: &runtime.ContainerStatsFilter{ 169 PodSandboxId: podID, 170 }, 171 } 172 173 stats, err := client.ListContainerStats(ctx, statsRequest) 174 if err != nil { 175 t.Fatal(err) 176 } 177 178 if len(stats.Stats) != 1 { 179 t.Fatalf("expected 1 stats result but got %d", len(stats.Stats)) 180 } 181 stat := stats.Stats[0] 182 verifyStatsContent(t, stat) 183} 184 185func Test_ContainerStats_ContainerID(t *testing.T) { 186 type config struct { 187 name string 188 189 runtimeHandler string 190 sandboxImage string 191 containerImage string 192 cmd []string 193 } 194 tests := []config{ 195 { 196 name: "WCOW_Process", 197 runtimeHandler: wcowProcessRuntimeHandler, 198 sandboxImage: imageWindowsNanoserver, 199 containerImage: imageWindowsNanoserver, 200 cmd: []string{"cmd", "/c", "ping", "-t", "127.0.0.1"}, 201 }, 202 { 203 name: "WCOW_Hypervisor", 204 runtimeHandler: wcowHypervisorRuntimeHandler, 205 sandboxImage: imageWindowsNanoserver, 206 containerImage: imageWindowsNanoserver, 207 cmd: []string{"cmd", "/c", "ping", "-t", "127.0.0.1"}, 208 }, 209 { 210 name: "LCOW", 211 runtimeHandler: lcowRuntimeHandler, 212 sandboxImage: imageLcowK8sPause, 213 containerImage: imageLcowAlpine, 214 cmd: []string{"top"}, 215 }, 216 } 217 218 for _, test := range tests { 219 t.Run(test.name, func(t *testing.T) { 220 if test.runtimeHandler == lcowRuntimeHandler { 221 pullRequiredLcowImages(t, []string{test.sandboxImage, test.containerImage}) 222 } else { 223 pullRequiredImages(t, []string{test.sandboxImage, test.containerImage}) 224 } 225 226 podRequest := &runtime.RunPodSandboxRequest{ 227 Config: &runtime.PodSandboxConfig{ 228 Metadata: &runtime.PodSandboxMetadata{ 229 Name: t.Name(), 230 Uid: "0", 231 Namespace: testNamespace, 232 }, 233 }, 234 RuntimeHandler: test.runtimeHandler, 235 } 236 237 client := newTestRuntimeClient(t) 238 ctx, cancel := context.WithCancel(context.Background()) 239 defer cancel() 240 241 podID := runPodSandbox(t, client, ctx, podRequest) 242 defer removePodSandbox(t, client, ctx, podID) 243 defer stopPodSandbox(t, client, ctx, podID) 244 245 request := &runtime.CreateContainerRequest{ 246 Config: &runtime.ContainerConfig{ 247 Metadata: &runtime.ContainerMetadata{ 248 Name: t.Name() + "-Container", 249 }, 250 Image: &runtime.ImageSpec{ 251 Image: test.containerImage, 252 }, 253 Command: test.cmd, 254 }, 255 PodSandboxId: podID, 256 SandboxConfig: podRequest.Config, 257 } 258 runContainerAndQueryStats(t, client, ctx, request) 259 }) 260 } 261 262} 263 264func Test_ContainerStats_List_ContainerID(t *testing.T) { 265 type config struct { 266 name string 267 268 runtimeHandler string 269 sandboxImage string 270 containerImage string 271 cmd []string 272 } 273 tests := []config{ 274 { 275 name: "WCOW_Process", 276 runtimeHandler: wcowProcessRuntimeHandler, 277 sandboxImage: imageWindowsNanoserver, 278 containerImage: imageWindowsNanoserver, 279 cmd: []string{"cmd", "/c", "ping", "-t", "127.0.0.1"}, 280 }, 281 { 282 name: "WCOW_Hypervisor", 283 runtimeHandler: wcowHypervisorRuntimeHandler, 284 sandboxImage: imageWindowsNanoserver, 285 containerImage: imageWindowsNanoserver, 286 cmd: []string{"cmd", "/c", "ping", "-t", "127.0.0.1"}, 287 }, 288 { 289 name: "LCOW", 290 runtimeHandler: lcowRuntimeHandler, 291 sandboxImage: imageLcowK8sPause, 292 containerImage: imageLcowAlpine, 293 cmd: []string{"top"}, 294 }, 295 } 296 297 for _, test := range tests { 298 t.Run(test.name, func(t *testing.T) { 299 if test.runtimeHandler == lcowRuntimeHandler { 300 pullRequiredLcowImages(t, []string{test.sandboxImage, test.containerImage}) 301 } else { 302 pullRequiredImages(t, []string{test.sandboxImage, test.containerImage}) 303 } 304 305 podRequest := &runtime.RunPodSandboxRequest{ 306 Config: &runtime.PodSandboxConfig{ 307 Metadata: &runtime.PodSandboxMetadata{ 308 Name: t.Name(), 309 Uid: "0", 310 Namespace: testNamespace, 311 }, 312 }, 313 RuntimeHandler: test.runtimeHandler, 314 } 315 316 client := newTestRuntimeClient(t) 317 ctx, cancel := context.WithCancel(context.Background()) 318 defer cancel() 319 320 podID := runPodSandbox(t, client, ctx, podRequest) 321 defer removePodSandbox(t, client, ctx, podID) 322 defer stopPodSandbox(t, client, ctx, podID) 323 324 request := &runtime.CreateContainerRequest{ 325 Config: &runtime.ContainerConfig{ 326 Metadata: &runtime.ContainerMetadata{ 327 Name: t.Name() + "-Container", 328 }, 329 Image: &runtime.ImageSpec{ 330 Image: test.containerImage, 331 }, 332 Command: test.cmd, 333 }, 334 PodSandboxId: podID, 335 SandboxConfig: podRequest.Config, 336 } 337 runContainerAndQueryListStats(t, client, ctx, request) 338 }) 339 } 340} 341