2015-03-11 21:55:06 +00:00
|
|
|
/*
|
2016-06-03 00:25:58 +00:00
|
|
|
Copyright 2015 The Kubernetes Authors.
|
2015-03-11 21:55:06 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2016-02-25 23:40:44 +00:00
|
|
|
package testing
|
2015-03-11 21:55:06 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2015-05-26 19:37:10 +00:00
|
|
|
"io"
|
2015-03-11 21:55:06 +00:00
|
|
|
"reflect"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
2015-08-05 22:03:47 +00:00
|
|
|
"k8s.io/kubernetes/pkg/api"
|
2016-02-25 23:40:44 +00:00
|
|
|
. "k8s.io/kubernetes/pkg/kubelet/container"
|
2015-11-10 22:18:47 +00:00
|
|
|
"k8s.io/kubernetes/pkg/types"
|
2016-03-09 02:58:24 +00:00
|
|
|
"k8s.io/kubernetes/pkg/util/flowcontrol"
|
2015-08-05 22:03:47 +00:00
|
|
|
"k8s.io/kubernetes/pkg/volume"
|
2015-03-11 21:55:06 +00:00
|
|
|
)
|
|
|
|
|
2016-06-20 22:14:08 +00:00
|
|
|
type FakePod struct {
|
|
|
|
Pod *Pod
|
|
|
|
NetnsPath string
|
|
|
|
}
|
|
|
|
|
2015-03-11 21:55:06 +00:00
|
|
|
// FakeRuntime is a fake container runtime for testing.
|
|
|
|
type FakeRuntime struct {
|
|
|
|
sync.Mutex
|
|
|
|
CalledFunctions []string
|
2016-06-20 22:14:08 +00:00
|
|
|
PodList []*FakePod
|
|
|
|
AllPodList []*FakePod
|
2015-05-26 19:37:10 +00:00
|
|
|
ImageList []Image
|
2015-12-05 00:06:25 +00:00
|
|
|
APIPodStatus api.PodStatus
|
|
|
|
PodStatus PodStatus
|
2015-03-11 21:55:06 +00:00
|
|
|
StartedPods []string
|
|
|
|
KilledPods []string
|
|
|
|
StartedContainers []string
|
|
|
|
KilledContainers []string
|
2015-05-26 19:37:10 +00:00
|
|
|
VersionInfo string
|
2016-01-14 23:16:07 +00:00
|
|
|
APIVersionInfo string
|
2015-10-21 20:04:10 +00:00
|
|
|
RuntimeType string
|
2015-03-11 21:55:06 +00:00
|
|
|
Err error
|
2015-10-02 13:45:46 +00:00
|
|
|
InspectErr error
|
2016-03-03 10:01:15 +00:00
|
|
|
StatusErr error
|
2015-03-11 21:55:06 +00:00
|
|
|
}
|
|
|
|
|
2015-05-26 19:37:10 +00:00
|
|
|
// FakeRuntime should implement Runtime.
|
|
|
|
var _ Runtime = &FakeRuntime{}
|
|
|
|
|
|
|
|
type FakeVersion struct {
|
|
|
|
Version string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (fv *FakeVersion) String() string {
|
|
|
|
return fv.Version
|
|
|
|
}
|
|
|
|
|
|
|
|
func (fv *FakeVersion) Compare(other string) (int, error) {
|
|
|
|
result := 0
|
|
|
|
if fv.Version > other {
|
|
|
|
result = 1
|
|
|
|
} else if fv.Version < other {
|
|
|
|
result = -1
|
|
|
|
}
|
|
|
|
return result, nil
|
|
|
|
}
|
|
|
|
|
2016-02-25 23:40:44 +00:00
|
|
|
type podsGetter interface {
|
|
|
|
GetPods(bool) ([]*Pod, error)
|
|
|
|
}
|
|
|
|
|
2015-03-11 21:55:06 +00:00
|
|
|
type FakeRuntimeCache struct {
|
2015-04-14 00:38:18 +00:00
|
|
|
getter podsGetter
|
2015-03-11 21:55:06 +00:00
|
|
|
}
|
|
|
|
|
2015-04-14 00:38:18 +00:00
|
|
|
func NewFakeRuntimeCache(getter podsGetter) RuntimeCache {
|
|
|
|
return &FakeRuntimeCache{getter}
|
2015-03-11 21:55:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntimeCache) GetPods() ([]*Pod, error) {
|
2015-04-14 00:38:18 +00:00
|
|
|
return f.getter.GetPods(false)
|
2015-03-11 21:55:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntimeCache) ForceUpdateIfOlder(time.Time) error {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// ClearCalls resets the FakeRuntime to the initial state.
|
|
|
|
func (f *FakeRuntime) ClearCalls() {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = []string{}
|
2016-06-20 22:14:08 +00:00
|
|
|
f.PodList = []*FakePod{}
|
|
|
|
f.AllPodList = []*FakePod{}
|
2015-12-05 00:06:25 +00:00
|
|
|
f.APIPodStatus = api.PodStatus{}
|
2015-03-11 21:55:06 +00:00
|
|
|
f.StartedPods = []string{}
|
|
|
|
f.KilledPods = []string{}
|
|
|
|
f.StartedContainers = []string{}
|
|
|
|
f.KilledContainers = []string{}
|
2015-05-26 19:37:10 +00:00
|
|
|
f.VersionInfo = ""
|
2015-10-21 20:04:10 +00:00
|
|
|
f.RuntimeType = ""
|
2015-03-11 21:55:06 +00:00
|
|
|
f.Err = nil
|
2015-10-02 13:45:46 +00:00
|
|
|
f.InspectErr = nil
|
2016-03-03 10:01:15 +00:00
|
|
|
f.StatusErr = nil
|
2015-03-11 21:55:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntime) assertList(expect []string, test []string) error {
|
|
|
|
if !reflect.DeepEqual(expect, test) {
|
|
|
|
return fmt.Errorf("expected %#v, got %#v", expect, test)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// AssertCalls test if the invoked functions are as expected.
|
|
|
|
func (f *FakeRuntime) AssertCalls(calls []string) error {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
return f.assertList(calls, f.CalledFunctions)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntime) AssertStartedPods(pods []string) error {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
return f.assertList(pods, f.StartedPods)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntime) AssertKilledPods(pods []string) error {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
return f.assertList(pods, f.KilledPods)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntime) AssertStartedContainers(containers []string) error {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
return f.assertList(containers, f.StartedContainers)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntime) AssertKilledContainers(containers []string) error {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
return f.assertList(containers, f.KilledContainers)
|
|
|
|
}
|
|
|
|
|
2015-10-21 20:04:10 +00:00
|
|
|
func (f *FakeRuntime) Type() string {
|
|
|
|
return f.RuntimeType
|
|
|
|
}
|
|
|
|
|
2015-05-26 19:37:10 +00:00
|
|
|
func (f *FakeRuntime) Version() (Version, error) {
|
2015-03-11 21:55:06 +00:00
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "Version")
|
2015-05-26 19:37:10 +00:00
|
|
|
return &FakeVersion{Version: f.VersionInfo}, f.Err
|
2015-03-11 21:55:06 +00:00
|
|
|
}
|
|
|
|
|
2016-01-14 23:16:07 +00:00
|
|
|
func (f *FakeRuntime) APIVersion() (Version, error) {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "APIVersion")
|
|
|
|
return &FakeVersion{Version: f.APIVersionInfo}, f.Err
|
|
|
|
}
|
|
|
|
|
2016-03-03 10:01:15 +00:00
|
|
|
func (f *FakeRuntime) Status() error {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "Status")
|
|
|
|
return f.StatusErr
|
|
|
|
}
|
|
|
|
|
2015-03-11 21:55:06 +00:00
|
|
|
func (f *FakeRuntime) GetPods(all bool) ([]*Pod, error) {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
2016-06-20 22:14:08 +00:00
|
|
|
var pods []*Pod
|
|
|
|
|
2015-03-11 21:55:06 +00:00
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "GetPods")
|
2015-08-07 21:42:21 +00:00
|
|
|
if all {
|
2016-06-20 22:14:08 +00:00
|
|
|
for _, fakePod := range f.AllPodList {
|
|
|
|
pods = append(pods, fakePod.Pod)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for _, fakePod := range f.PodList {
|
|
|
|
pods = append(pods, fakePod.Pod)
|
|
|
|
}
|
2015-08-07 21:42:21 +00:00
|
|
|
}
|
2016-06-20 22:14:08 +00:00
|
|
|
return pods, f.Err
|
2015-03-11 21:55:06 +00:00
|
|
|
}
|
|
|
|
|
2016-03-09 02:58:24 +00:00
|
|
|
func (f *FakeRuntime) SyncPod(pod *api.Pod, _ api.PodStatus, _ *PodStatus, _ []api.Secret, backOff *flowcontrol.Backoff) (result PodSyncResult) {
|
2015-03-11 21:55:06 +00:00
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
2015-05-01 21:39:52 +00:00
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "SyncPod")
|
2015-03-11 21:55:06 +00:00
|
|
|
f.StartedPods = append(f.StartedPods, string(pod.UID))
|
|
|
|
for _, c := range pod.Spec.Containers {
|
|
|
|
f.StartedContainers = append(f.StartedContainers, c.Name)
|
|
|
|
}
|
2016-01-12 10:19:13 +00:00
|
|
|
// TODO(random-liu): Add SyncResult for starting and killing containers
|
|
|
|
if f.Err != nil {
|
|
|
|
result.Fail(f.Err)
|
|
|
|
}
|
|
|
|
return
|
2015-03-11 21:55:06 +00:00
|
|
|
}
|
|
|
|
|
2016-04-27 03:30:59 +00:00
|
|
|
func (f *FakeRuntime) KillPod(pod *api.Pod, runningPod Pod, gracePeriodOverride *int64) error {
|
2015-03-11 21:55:06 +00:00
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "KillPod")
|
2015-08-20 01:57:58 +00:00
|
|
|
f.KilledPods = append(f.KilledPods, string(runningPod.ID))
|
|
|
|
for _, c := range runningPod.Containers {
|
2015-03-11 21:55:06 +00:00
|
|
|
f.KilledContainers = append(f.KilledContainers, c.Name)
|
|
|
|
}
|
|
|
|
return f.Err
|
|
|
|
}
|
|
|
|
|
2015-03-20 23:03:30 +00:00
|
|
|
func (f *FakeRuntime) RunContainerInPod(container api.Container, pod *api.Pod, volumeMap map[string]volume.VolumePlugin) error {
|
2015-03-11 21:55:06 +00:00
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "RunContainerInPod")
|
|
|
|
f.StartedContainers = append(f.StartedContainers, container.Name)
|
|
|
|
|
|
|
|
pod.Spec.Containers = append(pod.Spec.Containers, container)
|
|
|
|
for _, c := range pod.Spec.Containers {
|
|
|
|
if c.Name == container.Name { // Container already in the pod.
|
|
|
|
return f.Err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pod.Spec.Containers = append(pod.Spec.Containers, container)
|
|
|
|
return f.Err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntime) KillContainerInPod(container api.Container, pod *api.Pod) error {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "KillContainerInPod")
|
|
|
|
f.KilledContainers = append(f.KilledContainers, container.Name)
|
|
|
|
|
|
|
|
var containers []api.Container
|
|
|
|
for _, c := range pod.Spec.Containers {
|
|
|
|
if c.Name == container.Name {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
containers = append(containers, c)
|
|
|
|
}
|
|
|
|
return f.Err
|
|
|
|
}
|
|
|
|
|
2015-12-05 00:06:25 +00:00
|
|
|
func (f *FakeRuntime) GetPodStatus(uid types.UID, name, namespace string) (*PodStatus, error) {
|
2015-03-11 21:55:06 +00:00
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "GetPodStatus")
|
2015-05-26 19:37:10 +00:00
|
|
|
status := f.PodStatus
|
|
|
|
return &status, f.Err
|
2015-03-11 21:55:06 +00:00
|
|
|
}
|
|
|
|
|
2015-10-07 17:58:05 +00:00
|
|
|
func (f *FakeRuntime) ExecInContainer(containerID ContainerID, cmd []string, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error {
|
2015-05-26 19:37:10 +00:00
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "ExecInContainer")
|
|
|
|
return f.Err
|
|
|
|
}
|
|
|
|
|
2015-10-07 17:58:05 +00:00
|
|
|
func (f *FakeRuntime) AttachContainer(containerID ContainerID, stdin io.Reader, stdout, stderr io.WriteCloser, tty bool) error {
|
2015-07-28 04:48:55 +00:00
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "AttachContainer")
|
|
|
|
return f.Err
|
|
|
|
}
|
|
|
|
|
2015-10-07 17:58:05 +00:00
|
|
|
func (f *FakeRuntime) GetContainerLogs(pod *api.Pod, containerID ContainerID, logOptions *api.PodLogOptions, stdout, stderr io.Writer) (err error) {
|
2015-05-26 19:37:10 +00:00
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "GetContainerLogs")
|
|
|
|
return f.Err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntime) PullImage(image ImageSpec, pullSecrets []api.Secret) error {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "PullImage")
|
|
|
|
return f.Err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntime) IsImagePresent(image ImageSpec) (bool, error) {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "IsImagePresent")
|
|
|
|
for _, i := range f.ImageList {
|
|
|
|
if i.ID == image.Image {
|
2015-10-02 13:45:46 +00:00
|
|
|
return true, nil
|
2015-05-26 19:37:10 +00:00
|
|
|
}
|
|
|
|
}
|
2015-10-02 13:45:46 +00:00
|
|
|
return false, f.InspectErr
|
2015-05-26 19:37:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntime) ListImages() ([]Image, error) {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "ListImages")
|
|
|
|
return f.ImageList, f.Err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntime) RemoveImage(image ImageSpec) error {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "RemoveImage")
|
|
|
|
index := 0
|
|
|
|
for i := range f.ImageList {
|
|
|
|
if f.ImageList[i].ID == image.Image {
|
|
|
|
index = i
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
f.ImageList = append(f.ImageList[:index], f.ImageList[index+1:]...)
|
|
|
|
|
|
|
|
return f.Err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *FakeRuntime) PortForward(pod *Pod, port uint16, stream io.ReadWriteCloser) error {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "PortForward")
|
|
|
|
return f.Err
|
|
|
|
}
|
2015-10-03 15:39:15 +00:00
|
|
|
|
2016-05-03 00:49:02 +00:00
|
|
|
func (f *FakeRuntime) GetNetNS(containerID ContainerID) (string, error) {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "GetNetNS")
|
2016-06-20 22:14:08 +00:00
|
|
|
|
|
|
|
for _, fp := range f.AllPodList {
|
|
|
|
for _, c := range fp.Pod.Containers {
|
|
|
|
if c.ID == containerID {
|
|
|
|
return fp.NetnsPath, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-05-03 00:49:02 +00:00
|
|
|
return "", f.Err
|
|
|
|
}
|
|
|
|
|
2016-06-22 14:44:33 +00:00
|
|
|
func (f *FakeRuntime) GetPodContainerID(pod *Pod) (ContainerID, error) {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "GetPodContainerID")
|
|
|
|
return ContainerID{}, f.Err
|
|
|
|
}
|
|
|
|
|
2016-06-14 21:45:41 +00:00
|
|
|
func (f *FakeRuntime) GarbageCollect(gcPolicy ContainerGCPolicy, ready bool) error {
|
2015-10-03 15:39:15 +00:00
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "GarbageCollect")
|
|
|
|
return f.Err
|
|
|
|
}
|
2016-03-29 00:05:02 +00:00
|
|
|
|
|
|
|
func (f *FakeRuntime) ImageStats() (*ImageStats, error) {
|
|
|
|
f.Lock()
|
|
|
|
defer f.Unlock()
|
|
|
|
|
|
|
|
f.CalledFunctions = append(f.CalledFunctions, "ImageStats")
|
|
|
|
return nil, f.Err
|
|
|
|
}
|