Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Turn on smarter FakeDockerClient in HollowNode. #15079

Merged
merged 1 commit into from
Oct 6, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions cmd/kubemark/hollow-node.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ func main() {
configFilePath := makeTempDirOrDie("config", testRootDir)
glog.Infof("Using %s as root dir for hollow-kubelet", testRootDir)
fakeDockerClient.VersionInfo = docker.Env{"ApiVersion=1.18"}
fakeDockerClient.ContainerMap = make(map[string]*docker.Container)
fakeDockerClient.EnableSleep = true
kcfg := kubeletapp.SimpleKubelet(
cl,
&fakeDockerClient,
Expand Down
158 changes: 87 additions & 71 deletions pkg/kubelet/dockertools/fake_docker_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package dockertools
import (
"encoding/json"
"fmt"
"math/rand"
"os"
"reflect"
"sort"
Expand Down Expand Up @@ -52,6 +53,7 @@ type FakeDockerClient struct {
Information docker.Env
ExecInspect *docker.ExecInspect
execCmd []string
EnableSleep bool
}

func (f *FakeDockerClient) ClearCalls() {
Expand Down Expand Up @@ -175,27 +177,41 @@ func (f *FakeDockerClient) InspectImage(name string) (*docker.Image, error) {
return f.Image, err
}

// Sleeps random amount of time with the normal distribution with given mean and stddev
// (in milliseconds), we never sleep less than cutOffMillis
func (f *FakeDockerClient) normalSleep(mean, stdDev, cutOffMillis int) {
if !f.EnableSleep {
return
}
cutoff := (time.Duration)(cutOffMillis) * time.Millisecond
delay := (time.Duration)(rand.NormFloat64()*float64(stdDev)+float64(mean)) * time.Millisecond
if delay < cutoff {
delay = cutoff
}
time.Sleep(delay)
}

// CreateContainer is a test-spy implementation of DockerInterface.CreateContainer.
// It adds an entry "create" to the internal method call record.
func (f *FakeDockerClient) CreateContainer(c docker.CreateContainerOptions) (*docker.Container, error) {
f.Lock()
defer f.Unlock()
f.called = append(f.called, "create")
err := f.popError("create")
if err == nil {
f.Created = append(f.Created, c.Name)
// This is not a very good fake. We'll just add this container's name to the list.
// Docker likes to add a '/', so copy that behavior.
name := "/" + c.Name
f.ContainerList = append(f.ContainerList, docker.APIContainers{ID: name, Names: []string{name}, Image: c.Config.Image})
container := docker.Container{ID: name, Name: name, Config: c.Config}
if f.ContainerMap != nil {
containerCopy := container
f.ContainerMap[name] = &containerCopy
}
return &container, nil
if err := f.popError("create"); err != nil {
return nil, err
}
f.Created = append(f.Created, c.Name)
// This is not a very good fake. We'll just add this container's name to the list.
// Docker likes to add a '/', so copy that behavior.
name := "/" + c.Name
f.ContainerList = append(f.ContainerList, docker.APIContainers{ID: name, Names: []string{name}, Image: c.Config.Image})
container := docker.Container{ID: name, Name: name, Config: c.Config}
if f.ContainerMap != nil {
containerCopy := container
f.ContainerMap[name] = &containerCopy
}
return nil, err
f.normalSleep(200, 50, 50)
return &container, nil
}

// StartContainer is a test-spy implementation of DockerInterface.StartContainer.
Expand All @@ -204,37 +220,37 @@ func (f *FakeDockerClient) StartContainer(id string, hostConfig *docker.HostConf
f.Lock()
defer f.Unlock()
f.called = append(f.called, "start")
err := f.popError("start")
if err == nil {

f.Container = &docker.Container{
ID: id,
Name: id, // For testing purpose, we set name to id
Config: &docker.Config{Image: "testimage"},
HostConfig: hostConfig,
State: docker.State{
Running: true,
Pid: os.Getpid(),
StartedAt: time.Now(),
},
NetworkSettings: &docker.NetworkSettings{IPAddress: "1.2.3.4"},
if err := f.popError("start"); err != nil {
return err
}
f.Container = &docker.Container{
ID: id,
Name: id, // For testing purpose, we set name to id
Config: &docker.Config{Image: "testimage"},
HostConfig: hostConfig,
State: docker.State{
Running: true,
Pid: os.Getpid(),
StartedAt: time.Now(),
},
NetworkSettings: &docker.NetworkSettings{IPAddress: "1.2.3.4"},
}
if f.ContainerMap != nil {
container, ok := f.ContainerMap[id]
if !ok {
container = &docker.Container{ID: id, Name: id}
}
if f.ContainerMap != nil {
container, ok := f.ContainerMap[id]
if !ok {
container = &docker.Container{ID: id, Name: id}
}
container.HostConfig = hostConfig
container.State = docker.State{
Running: true,
Pid: os.Getpid(),
StartedAt: time.Now(),
}
container.NetworkSettings = &docker.NetworkSettings{IPAddress: "2.3.4.5"}
f.ContainerMap[id] = container
container.HostConfig = hostConfig
container.State = docker.State{
Running: true,
Pid: os.Getpid(),
StartedAt: time.Now(),
}
container.NetworkSettings = &docker.NetworkSettings{IPAddress: "2.3.4.5"}
f.ContainerMap[id] = container
}
return err
f.normalSleep(200, 50, 50)
return nil
}

// StopContainer is a test-spy implementation of DockerInterface.StopContainer.
Expand All @@ -243,39 +259,39 @@ func (f *FakeDockerClient) StopContainer(id string, timeout uint) error {
f.Lock()
defer f.Unlock()
f.called = append(f.called, "stop")
err := f.popError("stop")
if err == nil {
f.Stopped = append(f.Stopped, id)
var newList []docker.APIContainers
for _, container := range f.ContainerList {
if container.ID == id {
f.ExitedContainerList = append(f.ExitedContainerList, container)
continue
}
newList = append(newList, container)
if err := f.popError("stop"); err != nil {
return err
}
f.Stopped = append(f.Stopped, id)
var newList []docker.APIContainers
for _, container := range f.ContainerList {
if container.ID == id {
f.ExitedContainerList = append(f.ExitedContainerList, container)
continue
}
f.ContainerList = newList
if f.ContainerMap != nil {
container, ok := f.ContainerMap[id]
if !ok {
container = &docker.Container{
ID: id,
Name: id,
State: docker.State{
Running: false,
StartedAt: time.Now().Add(-time.Second),
FinishedAt: time.Now(),
},
}
} else {
container.State.FinishedAt = time.Now()
container.State.Running = false
newList = append(newList, container)
}
f.ContainerList = newList
if f.ContainerMap != nil {
container, ok := f.ContainerMap[id]
if !ok {
container = &docker.Container{
ID: id,
Name: id,
State: docker.State{
Running: false,
StartedAt: time.Now().Add(-time.Second),
FinishedAt: time.Now(),
},
}
f.ContainerMap[id] = container
} else {
container.State.FinishedAt = time.Now()
container.State.Running = false
}

f.ContainerMap[id] = container
}
return err
f.normalSleep(200, 50, 50)
return nil
}

func (f *FakeDockerClient) RemoveContainer(opts docker.RemoveContainerOptions) error {
Expand Down