Skip to content

Commit 4344f86

Browse files
committed
integration: add more Docker container handler tests
Add new integration tests to improve coverage of the Docker container handler: - TestDockerContainerRestartCount: Tests restart count label capture (may skip if container exits before query) - TestDockerContainerDiskIoStats: Tests DiskIo stats collection - TestDockerContainerNetworkNone: Tests containers with --network none - TestDockerContainerNetworkHost: Tests containers with --network host - TestDockerContainerSharedNetwork: Tests containers with shared network namespace (--network container:X), exercising code path near the GraphDriver nil pointer fix - TestDockerContainerImageInfo: Tests image metadata capture - TestDockerContainerCreationTime: Tests creation timestamp accuracy Signed-off-by: Davanum Srinivas <davanum@gmail.com>
1 parent 7cbdee9 commit 4344f86

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed

integration/tests/api/docker_test.go

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,213 @@ func TestDockerHealthState(t *testing.T) {
431431
return getHealth() == "healthy"
432432
}, 10*time.Second, 100*time.Millisecond)
433433
}
434+
435+
// Check that restart count is captured in labels.
436+
func TestDockerContainerRestartCount(t *testing.T) {
437+
fm := framework.New(t)
438+
defer fm.Cleanup()
439+
440+
containerName := fmt.Sprintf("test-restart-count-%d", os.Getpid())
441+
// Run a container that runs briefly then exits with failure, with restart policy
442+
// The sleep gives cAdvisor time to detect the container between restarts
443+
fm.Docker().Run(framework.DockerRunArgs{
444+
Image: "registry.k8s.io/busybox:1.27",
445+
Args: []string{
446+
"--name", containerName,
447+
"--restart", "on-failure:5",
448+
},
449+
}, "sh", "-c", "sleep 3 && exit 1")
450+
451+
// Wait for container to show up initially
452+
waitForContainer(containerName, fm)
453+
454+
// Wait for at least one restart to occur
455+
time.Sleep(5 * time.Second)
456+
457+
request := &info.ContainerInfoRequest{
458+
NumStats: 1,
459+
}
460+
461+
// Query the container - it should still be running or restarting
462+
containerInfo, err := fm.Cadvisor().Client().DockerContainer(containerName, request)
463+
require.NoError(t, err, "Container should still be available during restart cycle")
464+
sanityCheck(containerName, containerInfo, t)
465+
466+
// Check that restart count label is present and greater than 0
467+
restartCount, ok := containerInfo.Spec.Labels["restartcount"]
468+
require.True(t, ok, "restartcount label should be present")
469+
count, err := strconv.Atoi(restartCount)
470+
require.NoError(t, err)
471+
assert.GreaterOrEqual(t, count, 1, "Restart count should be at least 1")
472+
}
473+
474+
// Check the DiskIo ContainerStats.
475+
func TestDockerContainerDiskIoStats(t *testing.T) {
476+
fm := framework.New(t)
477+
defer fm.Cleanup()
478+
479+
// Run a container that does disk I/O and stays running
480+
containerID := fm.Docker().RunBusybox("sh", "-c", "dd if=/dev/zero of=/tmp/testfile bs=1024 count=1000 && sync && sleep 30")
481+
482+
// Wait for the container to show up and do some I/O
483+
waitForContainer(containerID, fm)
484+
time.Sleep(3 * time.Second)
485+
486+
request := &info.ContainerInfoRequest{
487+
NumStats: 1,
488+
}
489+
containerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)
490+
require.NoError(t, err)
491+
sanityCheck(containerID, containerInfo, t)
492+
493+
// Check that DiskIo stats are present
494+
assert.True(t, containerInfo.Spec.HasDiskIo, "Container should have DiskIo isolation")
495+
}
496+
497+
// Check container with --network none.
498+
func TestDockerContainerNetworkNone(t *testing.T) {
499+
fm := framework.New(t)
500+
defer fm.Cleanup()
501+
502+
containerName := fmt.Sprintf("test-network-none-%d", os.Getpid())
503+
containerID := fm.Docker().Run(framework.DockerRunArgs{
504+
Image: "registry.k8s.io/pause",
505+
Args: []string{
506+
"--name", containerName,
507+
"--network", "none",
508+
},
509+
})
510+
511+
// Wait for the container to show up
512+
waitForContainer(containerID, fm)
513+
514+
request := &info.ContainerInfoRequest{
515+
NumStats: 1,
516+
}
517+
containerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)
518+
require.NoError(t, err)
519+
sanityCheck(containerID, containerInfo, t)
520+
521+
// Container with network none should still be monitored
522+
assert.NotEmpty(t, containerInfo.Stats, "Container should have stats even with --network none")
523+
}
524+
525+
// Check container with --network host.
526+
func TestDockerContainerNetworkHost(t *testing.T) {
527+
fm := framework.New(t)
528+
defer fm.Cleanup()
529+
530+
containerName := fmt.Sprintf("test-network-host-%d", os.Getpid())
531+
containerID := fm.Docker().Run(framework.DockerRunArgs{
532+
Image: "registry.k8s.io/pause",
533+
Args: []string{
534+
"--name", containerName,
535+
"--network", "host",
536+
},
537+
})
538+
539+
// Wait for the container to show up
540+
waitForContainer(containerID, fm)
541+
542+
request := &info.ContainerInfoRequest{
543+
NumStats: 1,
544+
}
545+
containerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)
546+
require.NoError(t, err)
547+
sanityCheck(containerID, containerInfo, t)
548+
549+
// Container with host network should be monitored
550+
assert.NotEmpty(t, containerInfo.Stats, "Container should have stats with --network host")
551+
}
552+
553+
// Check container with shared network namespace (--network container:X).
554+
// This exercises the code path where we need to inspect another container for IP address.
555+
func TestDockerContainerSharedNetwork(t *testing.T) {
556+
fm := framework.New(t)
557+
defer fm.Cleanup()
558+
559+
// First, create a container that will share its network namespace
560+
networkContainerName := fmt.Sprintf("test-network-provider-%d", os.Getpid())
561+
networkContainerID := fm.Docker().Run(framework.DockerRunArgs{
562+
Image: "registry.k8s.io/pause",
563+
Args: []string{
564+
"--name", networkContainerName,
565+
},
566+
})
567+
waitForContainer(networkContainerID, fm)
568+
569+
// Now create a container that shares the network namespace of the first container
570+
sharedNetworkContainerName := fmt.Sprintf("test-network-consumer-%d", os.Getpid())
571+
sharedNetworkContainerID := fm.Docker().Run(framework.DockerRunArgs{
572+
Image: "registry.k8s.io/pause",
573+
Args: []string{
574+
"--name", sharedNetworkContainerName,
575+
"--network", fmt.Sprintf("container:%s", networkContainerName),
576+
},
577+
})
578+
waitForContainer(sharedNetworkContainerID, fm)
579+
580+
request := &info.ContainerInfoRequest{
581+
NumStats: 1,
582+
}
583+
584+
// Both containers should be accessible
585+
containerInfo1, err := fm.Cadvisor().Client().DockerContainer(networkContainerID, request)
586+
require.NoError(t, err)
587+
sanityCheck(networkContainerID, containerInfo1, t)
588+
589+
containerInfo2, err := fm.Cadvisor().Client().DockerContainer(sharedNetworkContainerID, request)
590+
require.NoError(t, err)
591+
sanityCheck(sharedNetworkContainerID, containerInfo2, t)
592+
593+
// The container with shared network should have stats
594+
assert.NotEmpty(t, containerInfo2.Stats, "Container with shared network should have stats")
595+
}
596+
597+
// Check that container image information is captured.
598+
func TestDockerContainerImageInfo(t *testing.T) {
599+
fm := framework.New(t)
600+
defer fm.Cleanup()
601+
602+
expectedImage := "registry.k8s.io/pause"
603+
containerID := fm.Docker().Run(framework.DockerRunArgs{
604+
Image: expectedImage,
605+
})
606+
607+
waitForContainer(containerID, fm)
608+
609+
request := &info.ContainerInfoRequest{
610+
NumStats: 1,
611+
}
612+
containerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)
613+
require.NoError(t, err)
614+
sanityCheck(containerID, containerInfo, t)
615+
616+
// Check image name is captured
617+
assert.Contains(t, containerInfo.Spec.Image, "pause", "Container image should contain 'pause'")
618+
}
619+
620+
// Check that container creation time is valid.
621+
func TestDockerContainerCreationTime(t *testing.T) {
622+
fm := framework.New(t)
623+
defer fm.Cleanup()
624+
625+
beforeCreation := time.Now().Add(-1 * time.Second)
626+
627+
containerID := fm.Docker().RunPause()
628+
waitForContainer(containerID, fm)
629+
630+
afterCreation := time.Now().Add(1 * time.Second)
631+
632+
request := &info.ContainerInfoRequest{
633+
NumStats: 1,
634+
}
635+
containerInfo, err := fm.Cadvisor().Client().DockerContainer(containerID, request)
636+
require.NoError(t, err)
637+
sanityCheck(containerID, containerInfo, t)
638+
639+
// Check creation time is within expected range
640+
creationTime := containerInfo.Spec.CreationTime
641+
assert.True(t, creationTime.After(beforeCreation), "Creation time %v should be after %v", creationTime, beforeCreation)
642+
assert.True(t, creationTime.Before(afterCreation), "Creation time %v should be before %v", creationTime, afterCreation)
643+
}

0 commit comments

Comments
 (0)