mirror of
https://github.com/moby/moby.git
synced 2026-01-11 18:51:37 +00:00
208 lines
6.4 KiB
Go
208 lines
6.4 KiB
Go
package container
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
containertypes "github.com/moby/moby/api/types/container"
|
|
"github.com/moby/moby/client"
|
|
"github.com/moby/moby/client/pkg/versions"
|
|
"github.com/moby/moby/v2/integration/internal/container"
|
|
"github.com/moby/moby/v2/internal/testutil"
|
|
"github.com/moby/moby/v2/internal/testutil/request"
|
|
"gotest.tools/v3/assert"
|
|
is "gotest.tools/v3/assert/cmp"
|
|
"gotest.tools/v3/poll"
|
|
"gotest.tools/v3/skip"
|
|
)
|
|
|
|
func TestContainerList(t *testing.T) {
|
|
ctx := setupTest(t)
|
|
apiClient := request.NewAPIClient(t)
|
|
|
|
// remove all existing containers
|
|
container.RemoveAll(ctx, t, apiClient)
|
|
|
|
// create the containers
|
|
num := 64
|
|
containers := make([]string, num)
|
|
for i := range num {
|
|
id := container.Create(ctx, t, apiClient)
|
|
defer container.Remove(ctx, t, apiClient, id, client.ContainerRemoveOptions{Force: true})
|
|
containers[i] = id
|
|
}
|
|
|
|
// list them and verify correctness
|
|
list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{All: true})
|
|
assert.NilError(t, err)
|
|
assert.Assert(t, is.Len(list.Items, num))
|
|
for i := range num {
|
|
// container list should be ordered in descending creation order
|
|
assert.Assert(t, is.Equal(list.Items[i].ID, containers[num-1-i]))
|
|
}
|
|
}
|
|
|
|
func TestContainerList_Annotations(t *testing.T) {
|
|
ctx := setupTest(t)
|
|
|
|
testcases := []struct {
|
|
apiVersion string
|
|
expectedAnnotations map[string]string
|
|
}{
|
|
{
|
|
apiVersion: "1.44",
|
|
expectedAnnotations: nil,
|
|
},
|
|
{
|
|
apiVersion: "1.46",
|
|
expectedAnnotations: map[string]string{
|
|
"foo": "bar",
|
|
"io.kubernetes.docker.type": "container",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(fmt.Sprintf("run with version v%s", tc.apiVersion), func(t *testing.T) {
|
|
apiClient := request.NewAPIClient(t, client.WithAPIVersion(tc.apiVersion))
|
|
id := container.Create(ctx, t, apiClient, container.WithAnnotations(tc.expectedAnnotations))
|
|
defer container.Remove(ctx, t, apiClient, id, client.ContainerRemoveOptions{Force: true})
|
|
|
|
list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
|
|
All: true,
|
|
Filters: make(client.Filters).Add("id", id),
|
|
})
|
|
assert.NilError(t, err)
|
|
assert.Assert(t, is.Len(list.Items, 1))
|
|
assert.Equal(t, list.Items[0].ID, id)
|
|
assert.Check(t, is.DeepEqual(list.Items[0].HostConfig.Annotations, tc.expectedAnnotations))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestContainerList_Filter(t *testing.T) {
|
|
ctx := setupTest(t)
|
|
apiClient := testEnv.APIClient()
|
|
|
|
prev := container.Create(ctx, t, apiClient)
|
|
top := container.Create(ctx, t, apiClient)
|
|
next := container.Create(ctx, t, apiClient)
|
|
|
|
defer func() {
|
|
container.Remove(ctx, t, apiClient, prev, client.ContainerRemoveOptions{Force: true})
|
|
container.Remove(ctx, t, apiClient, top, client.ContainerRemoveOptions{Force: true})
|
|
container.Remove(ctx, t, apiClient, next, client.ContainerRemoveOptions{Force: true})
|
|
}()
|
|
|
|
containerIDs := func(containers []containertypes.Summary) []string {
|
|
var entries []string
|
|
for _, c := range containers {
|
|
entries = append(entries, c.ID)
|
|
}
|
|
return entries
|
|
}
|
|
|
|
t.Run("since", func(t *testing.T) {
|
|
ctx := testutil.StartSpan(ctx, t)
|
|
list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
|
|
All: true,
|
|
Filters: make(client.Filters).Add("since", top),
|
|
})
|
|
assert.NilError(t, err)
|
|
assert.Check(t, is.Contains(containerIDs(list.Items), next))
|
|
})
|
|
|
|
t.Run("before", func(t *testing.T) {
|
|
ctx := testutil.StartSpan(ctx, t)
|
|
list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
|
|
All: true,
|
|
Filters: make(client.Filters).Add("before", top),
|
|
})
|
|
assert.NilError(t, err)
|
|
assert.Check(t, is.Contains(containerIDs(list.Items), prev))
|
|
})
|
|
}
|
|
|
|
// TestListPlatform verifies that containers have a platform set
|
|
func TestContainerList_ImageManifestPlatform(t *testing.T) {
|
|
skip.If(t, testEnv.IsRemoteDaemon)
|
|
skip.If(t, testEnv.DaemonInfo.OSType != "linux")
|
|
skip.If(t, !testEnv.UsingSnapshotter())
|
|
|
|
ctx := setupTest(t)
|
|
apiClient := testEnv.APIClient()
|
|
|
|
id := container.Create(ctx, t, apiClient)
|
|
defer container.Remove(ctx, t, apiClient, id, client.ContainerRemoveOptions{Force: true})
|
|
|
|
list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
|
|
All: true,
|
|
})
|
|
assert.NilError(t, err)
|
|
assert.Assert(t, len(list.Items) > 0)
|
|
|
|
ctr := list.Items[0]
|
|
if assert.Check(t, ctr.ImageManifestDescriptor != nil && ctr.ImageManifestDescriptor.Platform != nil) {
|
|
// Check that at least OS and Architecture have a value. Other values
|
|
// depend on the platform on which we're running the test.
|
|
assert.Equal(t, ctr.ImageManifestDescriptor.Platform.OS, testEnv.DaemonInfo.OSType)
|
|
assert.Check(t, ctr.ImageManifestDescriptor.Platform.Architecture != "")
|
|
}
|
|
}
|
|
|
|
func pollForHealthStatusSummary(ctx context.Context, apiClient client.APIClient, containerID string, healthStatus containertypes.HealthStatus) func(log poll.LogT) poll.Result {
|
|
return func(log poll.LogT) poll.Result {
|
|
list, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
|
|
All: true,
|
|
Filters: make(client.Filters).Add("id", containerID),
|
|
})
|
|
if err != nil {
|
|
return poll.Error(err)
|
|
}
|
|
total := 0
|
|
version := apiClient.ClientVersion()
|
|
for _, ctr := range list.Items {
|
|
if ctr.Health == nil && versions.LessThan(version, "1.52") {
|
|
total++
|
|
} else if ctr.Health != nil && ctr.Health.Status == healthStatus && versions.GreaterThanOrEqualTo(version, "1.52") {
|
|
total++
|
|
}
|
|
}
|
|
|
|
if total == len(list.Items) {
|
|
return poll.Success()
|
|
}
|
|
|
|
return poll.Continue("waiting for container to become %s", healthStatus)
|
|
}
|
|
}
|
|
|
|
func TestContainerList_HealthSummary(t *testing.T) {
|
|
skip.If(t, testEnv.DaemonInfo.OSType == "windows", "FIXME")
|
|
ctx := setupTest(t)
|
|
testcases := []struct {
|
|
apiVersion string
|
|
}{
|
|
{apiVersion: "1.51"},
|
|
{apiVersion: "1.52"},
|
|
}
|
|
|
|
for _, tc := range testcases {
|
|
t.Run(fmt.Sprintf("run with version v%s", tc.apiVersion), func(t *testing.T) {
|
|
apiClient := request.NewAPIClient(t, client.WithAPIVersion(tc.apiVersion))
|
|
|
|
cID := container.Run(ctx, t, apiClient, container.WithTty(true), container.WithWorkingDir("/foo"), func(c *container.TestContainerConfig) {
|
|
c.Config.Healthcheck = &containertypes.HealthConfig{
|
|
Test: []string{"CMD-SHELL", "if [ \"$PWD\" = \"/foo\" ]; then exit 0; else exit 1; fi;"},
|
|
Interval: 50 * time.Millisecond,
|
|
Retries: 3,
|
|
}
|
|
})
|
|
|
|
poll.WaitOn(t, pollForHealthStatusSummary(ctx, apiClient, cID, containertypes.Healthy))
|
|
})
|
|
}
|
|
}
|