TODO(vmarmol): Handle if CPU or memory is not isolated on this system. Check the ContainerSpec.
(t *testing.T)
| 178 | // TODO(vmarmol): Handle if CPU or memory is not isolated on this system. |
| 179 | // Check the ContainerSpec. |
| 180 | func TestDockerContainerSpec(t *testing.T) { |
| 181 | fm := framework.New(t) |
| 182 | defer fm.Cleanup() |
| 183 | |
| 184 | var ( |
| 185 | cpuShares = uint64(2048) |
| 186 | cpuMask = "0" |
| 187 | memoryLimit = uint64(1 << 30) // 1GB |
| 188 | image = "registry.k8s.io/pause" |
| 189 | env = map[string]string{"test_var": "FOO"} |
| 190 | labels = map[string]string{"bar": "baz"} |
| 191 | ) |
| 192 | |
| 193 | containerID := fm.Docker().Run(framework.DockerRunArgs{ |
| 194 | Image: image, |
| 195 | Args: []string{ |
| 196 | "--cpu-shares", strconv.FormatUint(cpuShares, 10), |
| 197 | "--cpuset-cpus", cpuMask, |
| 198 | "--memory", strconv.FormatUint(memoryLimit, 10), |
| 199 | "--env", "TEST_VAR=FOO", |
| 200 | "--label", "bar=baz", |
| 201 | }, |
| 202 | }) |
| 203 | |
| 204 | // Wait for the container to show up. |
| 205 | waitForContainer(containerID, fm) |
| 206 | |
| 207 | request := &info.ContainerInfoRequest{ |
| 208 | NumStats: 1, |
| 209 | } |
| 210 | containerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request) |
| 211 | require.NoError(t, err) |
| 212 | sanityCheck(containerID, containerInfo, t) |
| 213 | |
| 214 | assert := assert.New(t) |
| 215 | |
| 216 | assert.True(containerInfo.Spec.HasCpu, "CPU should be isolated") |
| 217 | if cgroups.IsCgroup2UnifiedMode() { |
| 218 | // cpu shares are converted on cgroupv2 due to conversion between cgroupv1 (cpu.shares) and cgroupv2 (cpu.weight) |
| 219 | // When container is created via docker, runc will convert cpu shares to cpu.weight using a log2-based quadratic formula https://github.com/opencontainers/cgroups/blob/v0.0.6/utils.go#L405-L427 |
| 220 | // And cAdvisor will convert cpu.weight back to cpu shares in https://github.com/google/cadvisor/blob/24e7a9883d12f944fd4403861707f4bafcaf4f3d/container/common/helpers.go#L249-L260 |
| 221 | // Worked example: |
| 222 | // cpuShares = 2048 (input to docker --cpu-shares) |
| 223 | // l = log2(2048) = 11; exponent = (l*l + 125*l)/612 - 7/34 = 2.2386; cpuWeight = ceil(10^exponent) = 174 (conversion done by runc) |
| 224 | // cpuWeight back to cpuShares = int(2 + ((cpuWeight-1)*262142)/9999)= 4537 |
| 225 | var cgroupV2Shares uint64 = 4537 |
| 226 | assert.Equal(cgroupV2Shares, containerInfo.Spec.Cpu.Limit, "Container should have %d shares, has %d", cgroupV2Shares, containerInfo.Spec.Cpu.Limit) |
| 227 | } else { |
| 228 | assert.Equal(cpuShares, containerInfo.Spec.Cpu.Limit, "Container should have %d shares, has %d", cpuShares, containerInfo.Spec.Cpu.Limit) |
| 229 | } |
| 230 | |
| 231 | assert.Equal(cpuMask, containerInfo.Spec.Cpu.Mask, "Cpu mask should be %q, but is %q", cpuMask, containerInfo.Spec.Cpu.Mask) |
| 232 | assert.True(containerInfo.Spec.HasMemory, "Memory should be isolated") |
| 233 | assert.Equal(memoryLimit, containerInfo.Spec.Memory.Limit, "Container should have memory limit of %d, has %d", memoryLimit, containerInfo.Spec.Memory.Limit) |
| 234 | assert.True(containerInfo.Spec.HasNetwork, "Network should be isolated") |
| 235 | assert.True(containerInfo.Spec.HasDiskIo, "Blkio should be isolated") |
| 236 | |
| 237 | assert.Equal(image, containerInfo.Spec.Image, "Spec should include container image") |
nothing calls this directly
no test coverage detected
searching dependent graphs…