mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 07:47:56 +00:00
Add unit test for legacy container cleanup
This commit is contained in:
parent
14940edaad
commit
626680d289
266
pkg/kubelet/dockershim/docker_legacy_test.go
Normal file
266
pkg/kubelet/dockershim/docker_legacy_test.go
Normal file
@ -0,0 +1,266 @@
|
||||
/*
|
||||
Copyright 2017 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package dockershim
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
dockercontainer "github.com/docker/engine-api/types/container"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubelet/dockertools"
|
||||
"k8s.io/kubernetes/pkg/kubelet/types"
|
||||
)
|
||||
|
||||
func TestConvertLegacyNameAndLabels(t *testing.T) {
|
||||
for desc, test := range map[string]struct {
|
||||
names []string
|
||||
labels map[string]string
|
||||
expectNames []string
|
||||
expectLabels map[string]string
|
||||
expectError bool
|
||||
}{
|
||||
|
||||
"legacy infra container": {
|
||||
names: []string{"k8s_POD.hash1_podname_podnamespace_poduid_randomid"},
|
||||
labels: map[string]string{
|
||||
types.KubernetesPodNameLabel: "podname",
|
||||
types.KubernetesPodNamespaceLabel: "podnamespace",
|
||||
types.KubernetesPodUIDLabel: "poduid",
|
||||
types.KubernetesContainerNameLabel: "POD",
|
||||
containerHashLabel: "hash",
|
||||
containerRestartCountLabel: "0",
|
||||
},
|
||||
expectNames: []string{"k8s_POD_podname_podnamespace_poduid_0"},
|
||||
expectLabels: map[string]string{
|
||||
types.KubernetesPodNameLabel: "podname",
|
||||
types.KubernetesPodNamespaceLabel: "podnamespace",
|
||||
types.KubernetesPodUIDLabel: "poduid",
|
||||
types.KubernetesContainerNameLabel: "POD",
|
||||
annotationPrefix + containerHashLabel: "hash",
|
||||
annotationPrefix + containerRestartCountLabel: "0",
|
||||
containerTypeLabelKey: containerTypeLabelSandbox,
|
||||
},
|
||||
},
|
||||
"legacy application container": {
|
||||
names: []string{"k8s_containername.hash_podname_podnamespace_poduid_randomid"},
|
||||
labels: map[string]string{
|
||||
types.KubernetesPodNameLabel: "podname",
|
||||
types.KubernetesPodNamespaceLabel: "podnamespace",
|
||||
types.KubernetesPodUIDLabel: "poduid",
|
||||
types.KubernetesContainerNameLabel: "containername",
|
||||
containerHashLabel: "hash",
|
||||
containerRestartCountLabel: "5",
|
||||
containerTerminationMessagePathLabel: "terminationmessagepath",
|
||||
containerTerminationMessagePolicyLabel: "terminationmessagepolicy",
|
||||
containerPreStopHandlerLabel: "prestophandler",
|
||||
containerPortsLabel: "ports",
|
||||
},
|
||||
expectNames: []string{"k8s_containername_podname_podnamespace_poduid_5"},
|
||||
expectLabels: map[string]string{
|
||||
types.KubernetesPodNameLabel: "podname",
|
||||
types.KubernetesPodNamespaceLabel: "podnamespace",
|
||||
types.KubernetesPodUIDLabel: "poduid",
|
||||
types.KubernetesContainerNameLabel: "containername",
|
||||
annotationPrefix + containerHashLabel: "hash",
|
||||
annotationPrefix + containerRestartCountLabel: "5",
|
||||
annotationPrefix + containerTerminationMessagePathLabel: "terminationmessagepath",
|
||||
annotationPrefix + containerTerminationMessagePolicyLabel: "terminationmessagepolicy",
|
||||
annotationPrefix + containerPreStopHandlerLabel: "prestophandler",
|
||||
annotationPrefix + containerPortsLabel: "ports",
|
||||
containerTypeLabelKey: containerTypeLabelContainer,
|
||||
},
|
||||
expectError: false,
|
||||
},
|
||||
"invalid sandbox name": {
|
||||
names: []string{"POD_podname_podnamespace_poduid_0"},
|
||||
expectError: true,
|
||||
},
|
||||
"invalid dockershim container": {
|
||||
names: []string{"containername_podname_podnamespace_poduid_5"},
|
||||
expectError: true,
|
||||
},
|
||||
} {
|
||||
t.Logf("TestCase %q", desc)
|
||||
names, labels, err := convertLegacyNameAndLabels(test.names, test.labels)
|
||||
require.Equal(t, test.expectError, err != nil)
|
||||
assert.Equal(t, test.expectNames, names)
|
||||
assert.Equal(t, test.expectLabels, labels)
|
||||
}
|
||||
}
|
||||
|
||||
// getFakeLegacyContainers returns a list of fake legacy containers.
|
||||
func getFakeLegacyContainers() []*dockertools.FakeContainer {
|
||||
return []*dockertools.FakeContainer{
|
||||
{
|
||||
ID: "12",
|
||||
Name: "k8s_POD.hash1_podname_podnamespace_poduid_randomid",
|
||||
Config: &dockercontainer.Config{
|
||||
Labels: map[string]string{
|
||||
types.KubernetesPodNameLabel: "podname",
|
||||
types.KubernetesPodNamespaceLabel: "podnamespace",
|
||||
types.KubernetesPodUIDLabel: "poduid",
|
||||
types.KubernetesContainerNameLabel: "POD",
|
||||
containerHashLabel: "hash1",
|
||||
containerRestartCountLabel: "0",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "34",
|
||||
Name: "k8s_legacycontainer.hash2_podname_podnamespace_poduid_randomid",
|
||||
Config: &dockercontainer.Config{
|
||||
Labels: map[string]string{
|
||||
types.KubernetesPodNameLabel: "podname",
|
||||
types.KubernetesPodNamespaceLabel: "podnamespace",
|
||||
types.KubernetesPodUIDLabel: "poduid",
|
||||
types.KubernetesContainerNameLabel: "legacyContainer",
|
||||
containerHashLabel: "hash2",
|
||||
containerRestartCountLabel: "5",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// getFakeNewContainers returns a list of fake new containers.
|
||||
func getFakeNewContainers() []*dockertools.FakeContainer {
|
||||
return []*dockertools.FakeContainer{
|
||||
{
|
||||
ID: "56",
|
||||
Name: "k8s_POD_podname_podnamespace_poduid_0",
|
||||
Config: &dockercontainer.Config{
|
||||
Labels: map[string]string{
|
||||
types.KubernetesPodNameLabel: "podname",
|
||||
types.KubernetesPodNamespaceLabel: "podnamespace",
|
||||
types.KubernetesPodUIDLabel: "poduid",
|
||||
types.KubernetesContainerNameLabel: "POD",
|
||||
containerTypeLabelKey: containerTypeLabelSandbox,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: "78",
|
||||
Name: "k8s_newcontainer_podname_podnamespace_poduid_3",
|
||||
Config: &dockercontainer.Config{
|
||||
Labels: map[string]string{
|
||||
types.KubernetesPodNameLabel: "podname",
|
||||
types.KubernetesPodNamespaceLabel: "podnamespace",
|
||||
types.KubernetesPodUIDLabel: "poduid",
|
||||
types.KubernetesContainerNameLabel: "newcontainer",
|
||||
annotationPrefix + containerHashLabel: "hash4",
|
||||
annotationPrefix + containerRestartCountLabel: "3",
|
||||
containerTypeLabelKey: containerTypeLabelContainer,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestListLegacyContainers(t *testing.T) {
|
||||
ds, fDocker, _ := newTestDockerService()
|
||||
newContainers := getFakeLegacyContainers()
|
||||
legacyContainers := getFakeNewContainers()
|
||||
fDocker.SetFakeContainers(append(newContainers, legacyContainers...))
|
||||
|
||||
// ListContainers should list only new containers when legacyCleanup is done.
|
||||
containers, err := ds.ListContainers(nil)
|
||||
assert.NoError(t, err)
|
||||
require.Len(t, containers, 1)
|
||||
assert.Equal(t, "78", containers[0].Id)
|
||||
|
||||
// ListLegacyContainers should list only legacy containers.
|
||||
containers, err = ds.ListLegacyContainers(nil)
|
||||
assert.NoError(t, err)
|
||||
require.Len(t, containers, 1)
|
||||
assert.Equal(t, "34", containers[0].Id)
|
||||
|
||||
// Mark legacyCleanup as not done.
|
||||
ds.legacyCleanup.done = 0
|
||||
|
||||
// ListContainers should list all containers when legacyCleanup is not done.
|
||||
containers, err = ds.ListContainers(nil)
|
||||
assert.NoError(t, err)
|
||||
require.Len(t, containers, 2)
|
||||
assert.Contains(t, []string{containers[0].Id, containers[1].Id}, "34")
|
||||
assert.Contains(t, []string{containers[0].Id, containers[1].Id}, "78")
|
||||
}
|
||||
|
||||
func TestListLegacyPodSandbox(t *testing.T) {
|
||||
ds, fDocker, _ := newTestDockerService()
|
||||
newContainers := getFakeLegacyContainers()
|
||||
legacyContainers := getFakeNewContainers()
|
||||
fDocker.SetFakeContainers(append(newContainers, legacyContainers...))
|
||||
|
||||
// ListPodSandbox should list only new sandboxes when legacyCleanup is done.
|
||||
sandboxes, err := ds.ListPodSandbox(nil)
|
||||
assert.NoError(t, err)
|
||||
require.Len(t, sandboxes, 1)
|
||||
assert.Equal(t, "56", sandboxes[0].Id)
|
||||
|
||||
// ListLegacyPodSandbox should list only legacy sandboxes.
|
||||
sandboxes, err = ds.ListLegacyPodSandbox(nil)
|
||||
assert.NoError(t, err)
|
||||
require.Len(t, sandboxes, 1)
|
||||
assert.Equal(t, "12", sandboxes[0].Id)
|
||||
|
||||
// Mark legacyCleanup as not done.
|
||||
ds.legacyCleanup.done = 0
|
||||
|
||||
// ListPodSandbox should list all sandboxes when legacyCleanup is not done.
|
||||
sandboxes, err = ds.ListPodSandbox(nil)
|
||||
assert.NoError(t, err)
|
||||
require.Len(t, sandboxes, 2)
|
||||
assert.Contains(t, []string{sandboxes[0].Id, sandboxes[1].Id}, "12")
|
||||
assert.Contains(t, []string{sandboxes[0].Id, sandboxes[1].Id}, "56")
|
||||
}
|
||||
|
||||
func TestCheckLegacyCleanup(t *testing.T) {
|
||||
for desc, test := range map[string]struct {
|
||||
containers []*dockertools.FakeContainer
|
||||
done bool
|
||||
}{
|
||||
"no containers": {
|
||||
containers: []*dockertools.FakeContainer{},
|
||||
done: true,
|
||||
},
|
||||
"only new containers": {
|
||||
containers: getFakeNewContainers(),
|
||||
done: true,
|
||||
},
|
||||
"only legacy containers": {
|
||||
containers: getFakeLegacyContainers(),
|
||||
done: false,
|
||||
},
|
||||
"both legacy and new containers": {
|
||||
containers: append(getFakeNewContainers(), getFakeLegacyContainers()...),
|
||||
done: false,
|
||||
},
|
||||
} {
|
||||
t.Logf("TestCase %q", desc)
|
||||
ds, fDocker, _ := newTestDockerService()
|
||||
fDocker.SetFakeContainers(test.containers)
|
||||
ds.legacyCleanup.done = 0
|
||||
|
||||
clean, err := ds.checkLegacyCleanup()
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, test.done, clean)
|
||||
assert.Equal(t, test.done, ds.legacyCleanup.Done())
|
||||
}
|
||||
}
|
@ -41,7 +41,8 @@ func newTestNetworkPlugin(t *testing.T) *mock_network.MockNetworkPlugin {
|
||||
func newTestDockerService() (*dockerService, *dockertools.FakeDockerClient, *clock.FakeClock) {
|
||||
fakeClock := clock.NewFakeClock(time.Time{})
|
||||
c := dockertools.NewFakeDockerClient().WithClock(fakeClock)
|
||||
return &dockerService{client: c, os: &containertest.FakeOS{}, networkPlugin: &network.NoopNetworkPlugin{}, checkpointHandler: NewTestPersistentCheckpointHandler()}, c, fakeClock
|
||||
return &dockerService{client: c, os: &containertest.FakeOS{}, networkPlugin: &network.NoopNetworkPlugin{},
|
||||
legacyCleanup: legacyCleanupFlag{done: 1}, checkpointHandler: NewTestPersistentCheckpointHandler()}, c, fakeClock
|
||||
}
|
||||
|
||||
// TestStatus tests the runtime status logic.
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"os"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -232,6 +233,9 @@ func (f *FakeDockerClient) SetFakeContainers(containers []*FakeContainer) {
|
||||
Names: []string{c.Name},
|
||||
ID: c.ID,
|
||||
}
|
||||
if c.Config != nil {
|
||||
container.Labels = c.Config.Labels
|
||||
}
|
||||
if c.Running {
|
||||
f.RunningContainerList = append(f.RunningContainerList, container)
|
||||
} else {
|
||||
@ -349,7 +353,30 @@ func (f *FakeDockerClient) ListContainers(options dockertypes.ContainerListOptio
|
||||
// TODO(random-liu): Is a fully sorted array needed?
|
||||
containerList = append(containerList, f.ExitedContainerList...)
|
||||
}
|
||||
return containerList, err
|
||||
// TODO: Support other filters.
|
||||
// Filter containers with label filter.
|
||||
labelFilters := options.Filter.Get("label")
|
||||
if len(labelFilters) == 0 {
|
||||
return containerList, err
|
||||
}
|
||||
var filtered []dockertypes.Container
|
||||
for _, container := range containerList {
|
||||
match := true
|
||||
for _, labelFilter := range labelFilters {
|
||||
kv := strings.Split(labelFilter, "=")
|
||||
if len(kv) != 2 {
|
||||
return nil, fmt.Errorf("invalid label filter %q", labelFilter)
|
||||
}
|
||||
if container.Labels[kv[0]] != kv[1] {
|
||||
match = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if match {
|
||||
filtered = append(filtered, container)
|
||||
}
|
||||
}
|
||||
return filtered, err
|
||||
}
|
||||
|
||||
// InspectContainer is a test-spy implementation of DockerInterface.InspectContainer.
|
||||
|
Loading…
Reference in New Issue
Block a user