Various fixes for the fake docker client

* Properly return ImageNotFoundError
 * Support inject "Images" or "ImageInspects" and keep both in sync.
 * Remove the FakeDockerPuller and let FakeDockerClient subsumes its
   functinality. This reduces the overhead to maintain both objects.
 * Various small fixes and refactoring of the testing utils.
pull/6/head
Yu-Ju Hong 2017-03-01 17:18:02 -08:00
parent c89e9cdbf1
commit 516848c37d
6 changed files with 166 additions and 130 deletions

View File

@ -23,6 +23,7 @@ import (
"testing"
"time"
dockertypes "github.com/docker/engine-api/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -102,14 +103,15 @@ func TestContainerStatus(t *testing.T) {
sConfig := makeSandboxConfig("foo", "bar", "1", 0)
labels := map[string]string{"abc.xyz": "foo"}
annotations := map[string]string{"foo.bar.baz": "abc"}
config := makeContainerConfig(sConfig, "pause", "iamimage", 0, labels, annotations)
imageName := "iamimage"
config := makeContainerConfig(sConfig, "pause", imageName, 0, labels, annotations)
var defaultTime time.Time
dt := defaultTime.UnixNano()
ct, st, ft := dt, dt, dt
state := runtimeapi.ContainerState_CONTAINER_CREATED
imageRef := DockerImageIDPrefix + imageName
// The following variables are not set in FakeDockerClient.
imageRef := DockerImageIDPrefix + ""
exitCode := int32(0)
var reason, message string
@ -129,11 +131,14 @@ func TestContainerStatus(t *testing.T) {
Annotations: config.Annotations,
}
fDocker.InjectImages([]dockertypes.Image{{ID: imageName}})
// Create the container.
fClock.SetTime(time.Now().Add(-1 * time.Hour))
expected.CreatedAt = fClock.Now().UnixNano()
const sandboxId = "sandboxid"
id, err := ds.CreateContainer(sandboxId, config, sConfig)
assert.NoError(t, err)
// Check internal labels
c, err := fDocker.InspectContainer(id)

View File

@ -28,7 +28,7 @@ import (
func TestRemoveImage(t *testing.T) {
ds, fakeDocker, _ := newTestDockerService()
id := "1111"
fakeDocker.Image = &dockertypes.ImageInspect{ID: id, RepoTags: []string{"foo"}}
fakeDocker.InjectImageInspects([]dockertypes.ImageInspect{{ID: id, RepoTags: []string{"foo"}}})
ds.RemoveImage(&runtimeapi.ImageSpec{Image: id})
fakeDocker.AssertCallDetails(dockertools.NewCalledDetail("inspect_image", nil),
dockertools.NewCalledDetail("remove_image", []interface{}{id, dockertypes.ImageRemoveOptions{PruneChildren: true}}))
@ -37,7 +37,7 @@ func TestRemoveImage(t *testing.T) {
func TestRemoveImageWithMultipleTags(t *testing.T) {
ds, fakeDocker, _ := newTestDockerService()
id := "1111"
fakeDocker.Image = &dockertypes.ImageInspect{ID: id, RepoTags: []string{"foo", "bar"}}
fakeDocker.InjectImageInspects([]dockertypes.ImageInspect{{ID: id, RepoTags: []string{"foo", "bar"}}})
ds.RemoveImage(&runtimeapi.ImageSpec{Image: id})
fakeDocker.AssertCallDetails(dockertools.NewCalledDetail("inspect_image", nil),
dockertools.NewCalledDetail("remove_image", []interface{}{"foo", dockertypes.ImageRemoveOptions{PruneChildren: true}}),

View File

@ -21,6 +21,7 @@ import (
"testing"
"github.com/blang/semver"
dockertypes "github.com/docker/engine-api/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -265,29 +266,37 @@ func TestGetSecurityOptSeparator(t *testing.T) {
}
func TestEnsureSandboxImageExists(t *testing.T) {
sandboxImage := "gcr.io/test/image"
for desc, test := range map[string]struct {
inject error
calls []string
err bool
injectImage bool
injectErr error
calls []string
err bool
}{
"should not pull image when it already exists": {
inject: nil,
calls: []string{"inspect_image"},
injectImage: true,
injectErr: nil,
calls: []string{"inspect_image"},
},
"should pull image when it doesn't exist": {
inject: dockertools.ImageNotFoundError{ID: "image_id"},
calls: []string{"inspect_image", "pull"},
injectImage: false,
injectErr: dockertools.ImageNotFoundError{ID: "image_id"},
calls: []string{"inspect_image", "pull"},
},
"should return error when inspect image fails": {
inject: fmt.Errorf("arbitrary error"),
calls: []string{"inspect_image"},
err: true,
injectImage: false,
injectErr: fmt.Errorf("arbitrary error"),
calls: []string{"inspect_image"},
err: true,
},
} {
t.Logf("TestCase: %q", desc)
_, fakeDocker, _ := newTestDockerService()
fakeDocker.InjectError("inspect_image", test.inject)
err := ensureSandboxImageExists(fakeDocker, "gcr.io/test/image")
if test.injectImage {
fakeDocker.InjectImages([]dockertypes.Image{{ID: sandboxImage}})
}
fakeDocker.InjectError("inspect_image", test.injectErr)
err := ensureSandboxImageExists(fakeDocker, sandboxImage)
assert.NoError(t, fakeDocker.AssertCalls(test.calls))
assert.Equal(t, test.err, err != nil)
}

View File

@ -398,7 +398,7 @@ func TestListImages(t *testing.T) {
func TestDeleteImage(t *testing.T) {
manager, fakeDocker := newTestDockerManager()
fakeDocker.Image = &dockertypes.ImageInspect{ID: "1111", RepoTags: []string{"foo"}}
fakeDocker.InjectImages([]dockertypes.Image{{ID: "1111", RepoTags: []string{"foo"}}})
manager.RemoveImage(kubecontainer.ImageSpec{Image: "1111"})
fakeDocker.AssertCallDetails(NewCalledDetail("inspect_image", nil), NewCalledDetail("remove_image",
[]interface{}{"1111", dockertypes.ImageRemoveOptions{PruneChildren: true}}))
@ -406,7 +406,7 @@ func TestDeleteImage(t *testing.T) {
func TestDeleteImageWithMultipleTags(t *testing.T) {
manager, fakeDocker := newTestDockerManager()
fakeDocker.Image = &dockertypes.ImageInspect{ID: "1111", RepoTags: []string{"foo", "bar"}}
fakeDocker.InjectImages([]dockertypes.Image{{ID: "1111", RepoTags: []string{"foo", "bar"}}})
manager.RemoveImage(kubecontainer.ImageSpec{Image: "1111"})
fakeDocker.AssertCallDetails(NewCalledDetail("inspect_image", nil),
NewCalledDetail("remove_image", []interface{}{"foo", dockertypes.ImageRemoveOptions{PruneChildren: true}}),
@ -609,9 +609,6 @@ func TestSyncPodCreateNetAndContainer(t *testing.T) {
func TestSyncPodCreatesNetAndContainerPullsImage(t *testing.T) {
dm, fakeDocker := newTestDockerManagerWithRealImageManager()
dm.podInfraContainerImage = "foo/infra_image:v1"
puller := dm.dockerPuller.(*FakeDockerPuller)
puller.HasImages = []string{}
dm.podInfraContainerImage = "foo/infra_image:v1"
pod := makePod("foo", &v1.PodSpec{
Containers: []v1.Container{
{Name: "bar", Image: "foo/something:v0", ImagePullPolicy: "IfNotPresent"},
@ -622,17 +619,12 @@ func TestSyncPodCreatesNetAndContainerPullsImage(t *testing.T) {
verifyCalls(t, fakeDocker, []string{
// Create pod infra container.
"inspect_image", "create", "start", "inspect_container", "inspect_container",
"inspect_image", "pull", "inspect_image", "create", "start", "inspect_container", "inspect_container",
// Create container.
"inspect_image", "create", "start", "inspect_container",
"inspect_image", "pull", "inspect_image", "create", "start", "inspect_container",
})
fakeDocker.Lock()
if !reflect.DeepEqual(puller.ImagesPulled, []string{"foo/infra_image:v1", "foo/something:v0"}) {
t.Errorf("unexpected pulled containers: %v", puller.ImagesPulled)
}
fakeDocker.Unlock()
assert.NoError(t, fakeDocker.AssertImagesPulled([]string{"foo/infra_image:v1", "foo/something:v0"}))
assert.NoError(t, fakeDocker.AssertCreatedByNameWithOrder([]string{"POD", "bar"}))
}
@ -1277,22 +1269,25 @@ func TestVerifyNonRoot(t *testing.T) {
// success cases
"non-root runAsUser": {
container: &v1.Container{
Image: "foobar",
SecurityContext: &v1.SecurityContext{
RunAsUser: &nonRootUid,
},
},
},
"numeric non-root image user": {
container: &v1.Container{},
container: &v1.Container{Image: "foobar"},
inspectImage: &dockertypes.ImageInspect{
ID: "foobar",
Config: &dockercontainer.Config{
User: "1",
},
},
},
"numeric non-root image user with gid": {
container: &v1.Container{},
container: &v1.Container{Image: "foobar"},
inspectImage: &dockertypes.ImageInspect{
ID: "foobar",
Config: &dockercontainer.Config{
User: "1:2",
},
@ -1302,6 +1297,7 @@ func TestVerifyNonRoot(t *testing.T) {
// failure cases
"root runAsUser": {
container: &v1.Container{
Image: "foobar",
SecurityContext: &v1.SecurityContext{
RunAsUser: &rootUid,
},
@ -1309,8 +1305,9 @@ func TestVerifyNonRoot(t *testing.T) {
expectedError: "container's runAsUser breaks non-root policy",
},
"non-numeric image user": {
container: &v1.Container{},
container: &v1.Container{Image: "foobar"},
inspectImage: &dockertypes.ImageInspect{
ID: "foobar",
Config: &dockercontainer.Config{
User: "foo",
},
@ -1318,8 +1315,9 @@ func TestVerifyNonRoot(t *testing.T) {
expectedError: "non-numeric user",
},
"numeric root image user": {
container: &v1.Container{},
container: &v1.Container{Image: "foobar"},
inspectImage: &dockertypes.ImageInspect{
ID: "foobar",
Config: &dockercontainer.Config{
User: "0",
},
@ -1327,8 +1325,9 @@ func TestVerifyNonRoot(t *testing.T) {
expectedError: "container has no runAsUser and image will run as root",
},
"numeric root image user with gid": {
container: &v1.Container{},
container: &v1.Container{Image: "foobar"},
inspectImage: &dockertypes.ImageInspect{
ID: "foobar",
Config: &dockercontainer.Config{
User: "0:1",
},
@ -1336,19 +1335,22 @@ func TestVerifyNonRoot(t *testing.T) {
expectedError: "container has no runAsUser and image will run as root",
},
"nil image in inspect": {
container: &v1.Container{},
container: &v1.Container{Image: "foobar"},
inspectImage: nil,
expectedError: "unable to inspect image",
expectedError: ImageNotFoundError{"foobar"}.Error(),
},
"nil config in image inspect": {
container: &v1.Container{},
inspectImage: &dockertypes.ImageInspect{},
container: &v1.Container{Image: "foobar"},
inspectImage: &dockertypes.ImageInspect{ID: "foobar"},
expectedError: "unable to inspect image",
},
}
for k, v := range tests {
fakeDocker.Image = v.inspectImage
fakeDocker.ResetImages()
if v.inspectImage != nil {
fakeDocker.InjectImageInspects([]dockertypes.ImageInspect{*v.inspectImage})
}
err := dm.verifyNonRoot(v.container)
if v.expectedError == "" && err != nil {
t.Errorf("case[%q]: unexpected error: %v", k, err)
@ -1435,8 +1437,8 @@ func TestGetIPCMode(t *testing.T) {
func TestSyncPodWithPullPolicy(t *testing.T) {
dm, fakeDocker := newTestDockerManagerWithRealImageManager()
puller := dm.dockerPuller.(*FakeDockerPuller)
puller.HasImages = []string{"foo/existing_one:v1", "foo/want:latest"}
fakeDocker.InjectImages([]dockertypes.Image{{ID: "foo/existing_one:v1"}, {ID: "foo/want:latest"}})
dm.podInfraContainerImage = "foo/infra_image:v1"
pod := makePod("foo", &v1.PodSpec{
@ -1465,13 +1467,11 @@ func TestSyncPodWithPullPolicy(t *testing.T) {
result := runSyncPod(t, dm, fakeDocker, pod, nil, true)
verifySyncResults(t, expectedResults, result)
assert.NoError(t, fakeDocker.AssertImagesPulled([]string{"foo/infra_image:v1", "foo/pull_always_image:v1", "foo/pull_if_not_present_image:v1"}))
fakeDocker.Lock()
defer fakeDocker.Unlock()
pulledImageSorted := puller.ImagesPulled[:]
sort.Strings(pulledImageSorted)
assert.Equal(t, []string{"foo/infra_image:v1", "foo/pull_always_image:v1", "foo/pull_if_not_present_image:v1"}, pulledImageSorted)
if len(fakeDocker.Created) != 5 {
t.Errorf("unexpected containers created %v", fakeDocker.Created)
}
@ -1485,33 +1485,28 @@ func TestSyncPodWithFailure(t *testing.T) {
tests := map[string]struct {
container v1.Container
dockerError map[string]error
pullerError []error
expected []*kubecontainer.SyncResult
}{
"PullImageFailure": {
v1.Container{Name: "bar", Image: "foo/real_image:v1", ImagePullPolicy: v1.PullAlways},
map[string]error{},
[]error{fmt.Errorf("can't pull image")},
map[string]error{"pull": fmt.Errorf("can't pull image")},
[]*kubecontainer.SyncResult{{kubecontainer.StartContainer, "bar", images.ErrImagePull, "can't pull image"}},
},
"CreateContainerFailure": {
v1.Container{Name: "bar", Image: "foo/already_present:v2"},
map[string]error{"create": fmt.Errorf("can't create container")},
[]error{},
[]*kubecontainer.SyncResult{{kubecontainer.StartContainer, "bar", kubecontainer.ErrRunContainer, "can't create container"}},
},
"StartContainerFailure": {
v1.Container{Name: "bar", Image: "foo/already_present:v2"},
map[string]error{"start": fmt.Errorf("can't start container")},
[]error{},
[]*kubecontainer.SyncResult{{kubecontainer.StartContainer, "bar", kubecontainer.ErrRunContainer, "can't start container"}},
},
}
for _, test := range tests {
dm, fakeDocker := newTestDockerManagerWithRealImageManager()
puller := dm.dockerPuller.(*FakeDockerPuller)
puller.HasImages = []string{test.container.Image}
fakeDocker.InjectImages([]dockertypes.Image{{ID: test.container.Image}})
// Pretend that the pod infra container has already been created, so that
// we can run the user containers.
fakeDocker.SetFakeRunningContainers([]*FakeContainer{{
@ -1519,7 +1514,6 @@ func TestSyncPodWithFailure(t *testing.T) {
Name: "/k8s_POD." + strconv.FormatUint(generatePodInfraContainerHash(pod), 16) + "_foo_new_12345678_0",
}})
fakeDocker.InjectErrors(test.dockerError)
puller.ErrorsToInject = test.pullerError
pod.Spec.Containers = []v1.Container{test.container}
result := runSyncPod(t, dm, fakeDocker, pod, nil, true)
verifySyncResults(t, test.expected, result)

View File

@ -33,7 +33,6 @@ import (
dockercontainer "github.com/docker/engine-api/types/container"
"k8s.io/client-go/util/clock"
"k8s.io/kubernetes/pkg/api/v1"
)
type calledDetail struct {
@ -53,7 +52,7 @@ type FakeDockerClient struct {
RunningContainerList []dockertypes.Container
ExitedContainerList []dockertypes.Container
ContainerMap map[string]*dockertypes.ContainerJSON
Image *dockertypes.ImageInspect
ImageInspects map[string]*dockertypes.ImageInspect
Images []dockertypes.Image
Errors map[string]error
called []calledDetail
@ -61,10 +60,13 @@ type FakeDockerClient struct {
EnableTrace bool
// Created, Started, Stopped and Removed all contain container docker ID
Created []string
Started []string
Stopped []string
Removed []string
Created []string
Started []string
Stopped []string
Removed []string
// Images pulled by ref (name or ID).
ImagesPulled []string
VersionInfo dockertypes.Version
Information dockertypes.Info
ExecInspect *dockertypes.ContainerExecInspect
@ -87,10 +89,9 @@ func NewFakeDockerClient() *FakeDockerClient {
Errors: make(map[string]error),
ContainerMap: make(map[string]*dockertypes.ContainerJSON),
Clock: clock.RealClock{},
// default this to an empty result, so that we never have a nil non-error response from InspectImage
Image: &dockertypes.ImageInspect{},
// default this to true, so that we trace calls, image pulls and container lifecycle
EnableTrace: true,
EnableTrace: true,
ImageInspects: make(map[string]*dockertypes.ImageInspect),
}
}
@ -207,8 +208,9 @@ func convertFakeContainer(f *FakeContainer) *dockertypes.ContainerJSON {
}
return &dockertypes.ContainerJSON{
ContainerJSONBase: &dockertypes.ContainerJSONBase{
ID: f.ID,
Name: f.Name,
ID: f.ID,
Name: f.Name,
Image: f.Config.Image,
State: &dockertypes.ContainerState{
Running: f.Running,
ExitCode: f.ExitCode,
@ -313,28 +315,17 @@ func (f *FakeDockerClient) AssertCreatedByName(created []string) error {
if err != nil {
return err
}
sort.StringSlice(created).Sort()
sort.StringSlice(actualCreated).Sort()
if !reflect.DeepEqual(created, actualCreated) {
return fmt.Errorf("expected %#v, got %#v", created, actualCreated)
}
return nil
return sortedStringSlicesEqual(created, actualCreated)
}
func (f *FakeDockerClient) AssertStoppedByName(stopped []string) error {
f.Lock()
defer f.Unlock()
actualStopped, err := f.idsToNames(f.Stopped)
if err != nil {
return err
}
sort.StringSlice(stopped).Sort()
sort.StringSlice(actualStopped).Sort()
if !reflect.DeepEqual(stopped, actualStopped) {
return fmt.Errorf("expected %#v, got %#v", stopped, actualStopped)
}
return nil
return sortedStringSlicesEqual(stopped, actualStopped)
}
func (f *FakeDockerClient) AssertStopped(stopped []string) error {
@ -342,10 +333,22 @@ func (f *FakeDockerClient) AssertStopped(stopped []string) error {
defer f.Unlock()
// Copy stopped to avoid modifying it.
actualStopped := append([]string{}, f.Stopped...)
sort.StringSlice(stopped).Sort()
sort.StringSlice(actualStopped).Sort()
if !reflect.DeepEqual(stopped, actualStopped) {
return fmt.Errorf("expected %#v, got %#v", stopped, actualStopped)
return sortedStringSlicesEqual(stopped, actualStopped)
}
func (f *FakeDockerClient) AssertImagesPulled(pulled []string) error {
f.Lock()
defer f.Unlock()
// Copy pulled to avoid modifying it.
actualPulled := append([]string{}, f.ImagesPulled...)
return sortedStringSlicesEqual(pulled, actualPulled)
}
func sortedStringSlicesEqual(expected, actual []string) error {
sort.StringSlice(expected).Sort()
sort.StringSlice(actual).Sort()
if !reflect.DeepEqual(expected, actual) {
return fmt.Errorf("expected %#v, got %#v", expected, actual)
}
return nil
}
@ -453,8 +456,13 @@ func (f *FakeDockerClient) InspectImageByRef(name string) (*dockertypes.ImageIns
f.Lock()
defer f.Unlock()
f.appendCalled(calledDetail{name: "inspect_image"})
err := f.popError("inspect_image")
return f.Image, err
if err := f.popError("inspect_image"); err != nil {
return nil, err
}
if result, ok := f.ImageInspects[name]; ok {
return result, nil
}
return nil, ImageNotFoundError{name}
}
// InspectImageByID is a test-spy implementation of DockerInterface.InspectImageByID.
@ -463,8 +471,13 @@ func (f *FakeDockerClient) InspectImageByID(name string) (*dockertypes.ImageInsp
f.Lock()
defer f.Unlock()
f.appendCalled(calledDetail{name: "inspect_image"})
err := f.popError("inspect_image")
return f.Image, err
if err := f.popError("inspect_image"); err != nil {
return nil, err
}
if result, ok := f.ImageInspects[name]; ok {
return result, nil
}
return nil, ImageNotFoundError{name}
}
// Sleeps random amount of time with the normal distribution with given mean and stddev
@ -508,7 +521,9 @@ func (f *FakeDockerClient) CreateContainer(c dockertypes.ContainerCreateConfig)
}, f.RunningContainerList...)
f.ContainerMap[id] = convertFakeContainer(&FakeContainer{
ID: id, Name: name, Config: c.Config, HostConfig: c.HostConfig, CreatedAt: f.Clock.Now()})
f.normalSleep(100, 25, 25)
return &dockertypes.ContainerCreateResponse{ID: id}, nil
}
@ -615,15 +630,11 @@ func (f *FakeDockerClient) PullImage(image string, auth dockertypes.AuthConfig,
err := f.popError("pull")
if err == nil {
authJson, _ := json.Marshal(auth)
f.Image = &dockertypes.ImageInspect{
ID: image,
RepoTags: []string{image},
// Image size is required to be non-zero for CRI integration.
VirtualSize: fakeImageSize,
Size: fakeImageSize,
Config: &dockercontainer.Config{},
}
inspect := createImageInspectFromRef(image)
f.ImageInspects[image] = inspect
f.appendPulled(fmt.Sprintf("%s using %s", image, string(authJson)))
f.Images = append(f.Images, *createImageFromImageInspect(*inspect))
f.ImagesPulled = append(f.ImagesPulled, image)
}
return err
}
@ -666,12 +677,16 @@ func (f *FakeDockerClient) InspectExec(id string) (*dockertypes.ContainerExecIns
}
func (f *FakeDockerClient) ListImages(opts dockertypes.ImageListOptions) ([]dockertypes.Image, error) {
f.Lock()
defer f.Unlock()
f.appendCalled(calledDetail{name: "list_images"})
err := f.popError("list_images")
return f.Images, err
}
func (f *FakeDockerClient) RemoveImage(image string, opts dockertypes.ImageRemoveOptions) ([]dockertypes.ImageDelete, error) {
f.Lock()
defer f.Unlock()
f.appendCalled(calledDetail{name: "remove_image", arguments: []interface{}{image, opts}})
err := f.popError("remove_image")
if err == nil {
@ -689,6 +704,25 @@ func (f *FakeDockerClient) InjectImages(images []dockertypes.Image) {
f.Lock()
defer f.Unlock()
f.Images = append(f.Images, images...)
for _, i := range images {
f.ImageInspects[i.ID] = createImageInspectFromImage(i)
}
}
func (f *FakeDockerClient) ResetImages() {
f.Lock()
defer f.Unlock()
f.Images = []dockertypes.Image{}
f.ImageInspects = make(map[string]*dockertypes.ImageInspect)
}
func (f *FakeDockerClient) InjectImageInspects(inspects []dockertypes.ImageInspect) {
f.Lock()
defer f.Unlock()
for _, i := range inspects {
f.Images = append(f.Images, *createImageFromImageInspect(i))
f.ImageInspects[i.ID] = &i
}
}
func (f *FakeDockerClient) updateContainerStatus(id, status string) {
@ -713,44 +747,43 @@ func (f *FakeDockerClient) ResizeContainerTTY(id string, height, width int) erro
return nil
}
// FakeDockerPuller is a stub implementation of DockerPuller.
type FakeDockerPuller struct {
sync.Mutex
HasImages []string
ImagesPulled []string
// Every pull will return the first error here, and then reslice
// to remove it. Will give nil errors if this slice is empty.
ErrorsToInject []error
func createImageInspectFromRef(ref string) *dockertypes.ImageInspect {
return &dockertypes.ImageInspect{
ID: ref,
RepoTags: []string{ref},
// Image size is required to be non-zero for CRI integration.
VirtualSize: fakeImageSize,
Size: fakeImageSize,
Config: &dockercontainer.Config{},
}
}
// Pull records the image pull attempt, and optionally injects an error.
func (f *FakeDockerPuller) Pull(image string, secrets []v1.Secret) (err error) {
f.Lock()
defer f.Unlock()
f.ImagesPulled = append(f.ImagesPulled, image)
if len(f.ErrorsToInject) > 0 {
err = f.ErrorsToInject[0]
f.ErrorsToInject = f.ErrorsToInject[1:]
func createImageInspectFromImage(image dockertypes.Image) *dockertypes.ImageInspect {
return &dockertypes.ImageInspect{
ID: image.ID,
RepoTags: image.RepoTags,
// Image size is required to be non-zero for CRI integration.
VirtualSize: fakeImageSize,
Size: fakeImageSize,
Config: &dockercontainer.Config{},
}
return err
}
func (f *FakeDockerPuller) GetImageRef(name string) (string, error) {
f.Lock()
defer f.Unlock()
if f.HasImages == nil {
return name, nil
func createImageFromImageInspect(inspect dockertypes.ImageInspect) *dockertypes.Image {
return &dockertypes.Image{
ID: inspect.ID,
RepoTags: inspect.RepoTags,
// Image size is required to be non-zero for CRI integration.
VirtualSize: fakeImageSize,
Size: fakeImageSize,
}
for _, s := range f.HasImages {
if s == name {
return s, nil
}
}
return "", nil
}
// dockerTimestampToString converts the timestamp to string
func dockerTimestampToString(t time.Time) string {
return t.Format(time.RFC3339Nano)
}
func (f *FakeDockerClient) ImageHistory(id string) ([]dockertypes.ImageHistory, error) {
f.Lock()
defer f.Unlock()
@ -764,8 +797,3 @@ func (f *FakeDockerClient) InjectImageHistory(data map[string][]dockertypes.Imag
defer f.Unlock()
f.ImageHistoryMap = data
}
// dockerTimestampToString converts the timestamp to string
func dockerTimestampToString(t time.Time) string {
return t.Format(time.RFC3339Nano)
}

View File

@ -52,7 +52,7 @@ func NewFakeDockerManager(
dm := NewDockerManager(client, recorder, livenessManager, containerRefManager, fakePodGetter, machineInfo, podInfraContainerImage, qps,
burst, containerLogsDir, osInterface, networkPlugin, runtimeHelper, httpClient, &NativeExecHandler{},
fakeOOMAdjuster, fakeProcFs, false, imageBackOff, false, false, true, "/var/lib/kubelet/seccomp")
dm.dockerPuller = &FakeDockerPuller{}
dm.dockerPuller = newDockerPuller(client)
// ttl of version cache is set to 0 so we always call version api directly in tests.
dm.versionCache = cache.NewObjectCache(