docker_service_test.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package dockershim
  14. import (
  15. "errors"
  16. "math/rand"
  17. "testing"
  18. "time"
  19. "github.com/blang/semver"
  20. dockertypes "github.com/docker/docker/api/types"
  21. "github.com/golang/mock/gomock"
  22. "github.com/stretchr/testify/assert"
  23. "github.com/stretchr/testify/require"
  24. "k8s.io/apimachinery/pkg/util/clock"
  25. runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
  26. "k8s.io/kubernetes/pkg/kubelet/checkpointmanager"
  27. containertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
  28. "k8s.io/kubernetes/pkg/kubelet/dockershim/libdocker"
  29. "k8s.io/kubernetes/pkg/kubelet/dockershim/network"
  30. nettest "k8s.io/kubernetes/pkg/kubelet/dockershim/network/testing"
  31. "k8s.io/kubernetes/pkg/kubelet/util/cache"
  32. )
  33. // newTestNetworkPlugin returns a mock plugin that implements network.NetworkPlugin
  34. func newTestNetworkPlugin(t *testing.T) *nettest.MockNetworkPlugin {
  35. ctrl := gomock.NewController(t)
  36. return nettest.NewMockNetworkPlugin(ctrl)
  37. }
  38. type mockCheckpointManager struct {
  39. checkpoint map[string]*PodSandboxCheckpoint
  40. }
  41. func (ckm *mockCheckpointManager) CreateCheckpoint(checkpointKey string, checkpoint checkpointmanager.Checkpoint) error {
  42. ckm.checkpoint[checkpointKey] = checkpoint.(*PodSandboxCheckpoint)
  43. return nil
  44. }
  45. func (ckm *mockCheckpointManager) GetCheckpoint(checkpointKey string, checkpoint checkpointmanager.Checkpoint) error {
  46. *(checkpoint.(*PodSandboxCheckpoint)) = *(ckm.checkpoint[checkpointKey])
  47. return nil
  48. }
  49. func (ckm *mockCheckpointManager) RemoveCheckpoint(checkpointKey string) error {
  50. _, ok := ckm.checkpoint[checkpointKey]
  51. if ok {
  52. delete(ckm.checkpoint, "moo")
  53. }
  54. return nil
  55. }
  56. func (ckm *mockCheckpointManager) ListCheckpoints() ([]string, error) {
  57. var keys []string
  58. for key := range ckm.checkpoint {
  59. keys = append(keys, key)
  60. }
  61. return keys, nil
  62. }
  63. func newMockCheckpointManager() checkpointmanager.CheckpointManager {
  64. return &mockCheckpointManager{checkpoint: make(map[string]*PodSandboxCheckpoint)}
  65. }
  66. func newTestDockerService() (*dockerService, *libdocker.FakeDockerClient, *clock.FakeClock) {
  67. fakeClock := clock.NewFakeClock(time.Time{})
  68. c := libdocker.NewFakeDockerClient().WithClock(fakeClock).WithVersion("1.11.2", "1.23").WithRandSource(rand.NewSource(0))
  69. pm := network.NewPluginManager(&network.NoopNetworkPlugin{})
  70. ckm := newMockCheckpointManager()
  71. return &dockerService{
  72. client: c,
  73. os: &containertest.FakeOS{},
  74. network: pm,
  75. checkpointManager: ckm,
  76. networkReady: make(map[string]bool),
  77. }, c, fakeClock
  78. }
  79. func newTestDockerServiceWithVersionCache() (*dockerService, *libdocker.FakeDockerClient, *clock.FakeClock) {
  80. ds, c, fakeClock := newTestDockerService()
  81. ds.versionCache = cache.NewObjectCache(
  82. func() (interface{}, error) {
  83. return ds.getDockerVersion()
  84. },
  85. time.Hour*10,
  86. )
  87. return ds, c, fakeClock
  88. }
  89. // TestStatus tests the runtime status logic.
  90. func TestStatus(t *testing.T) {
  91. ds, fDocker, _ := newTestDockerService()
  92. assertStatus := func(expected map[string]bool, status *runtimeapi.RuntimeStatus) {
  93. conditions := status.GetConditions()
  94. assert.Equal(t, len(expected), len(conditions))
  95. for k, v := range expected {
  96. for _, c := range conditions {
  97. if k == c.Type {
  98. assert.Equal(t, v, c.Status)
  99. }
  100. }
  101. }
  102. }
  103. // Should report ready status if version returns no error.
  104. statusResp, err := ds.Status(getTestCTX(), &runtimeapi.StatusRequest{})
  105. require.NoError(t, err)
  106. assertStatus(map[string]bool{
  107. runtimeapi.RuntimeReady: true,
  108. runtimeapi.NetworkReady: true,
  109. }, statusResp.Status)
  110. // Should not report ready status if version returns error.
  111. fDocker.InjectError("version", errors.New("test error"))
  112. statusResp, err = ds.Status(getTestCTX(), &runtimeapi.StatusRequest{})
  113. assert.NoError(t, err)
  114. assertStatus(map[string]bool{
  115. runtimeapi.RuntimeReady: false,
  116. runtimeapi.NetworkReady: true,
  117. }, statusResp.Status)
  118. // Should not report ready status is network plugin returns error.
  119. mockPlugin := newTestNetworkPlugin(t)
  120. ds.network = network.NewPluginManager(mockPlugin)
  121. defer mockPlugin.Finish()
  122. mockPlugin.EXPECT().Status().Return(errors.New("network error"))
  123. statusResp, err = ds.Status(getTestCTX(), &runtimeapi.StatusRequest{})
  124. assert.NoError(t, err)
  125. assertStatus(map[string]bool{
  126. runtimeapi.RuntimeReady: true,
  127. runtimeapi.NetworkReady: false,
  128. }, statusResp.Status)
  129. }
  130. func TestVersion(t *testing.T) {
  131. ds, _, _ := newTestDockerService()
  132. expectedVersion := &dockertypes.Version{Version: "1.11.2", APIVersion: "1.23.0"}
  133. v, err := ds.getDockerVersion()
  134. require.NoError(t, err)
  135. assert.Equal(t, expectedVersion, v)
  136. expectedAPIVersion := &semver.Version{Major: 1, Minor: 23, Patch: 0}
  137. apiVersion, err := ds.getDockerAPIVersion()
  138. require.NoError(t, err)
  139. assert.Equal(t, expectedAPIVersion, apiVersion)
  140. }
  141. func TestAPIVersionWithCache(t *testing.T) {
  142. ds, _, _ := newTestDockerServiceWithVersionCache()
  143. expected := &semver.Version{Major: 1, Minor: 23, Patch: 0}
  144. version, err := ds.getDockerAPIVersion()
  145. require.NoError(t, err)
  146. assert.Equal(t, expected, version)
  147. }