test: refactor/simplify container mock builders (#1495)

pull/1481/head
nils måsén 2 years ago committed by GitHub
parent d5d711bd14
commit a4d00bfd75
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -33,8 +33,8 @@ var _ = Describe("the client", func() {
mockServer.Close() mockServer.Close()
}) })
Describe("WarnOnHeadPullFailed", func() { Describe("WarnOnHeadPullFailed", func() {
containerUnknown := *mockContainerWithImageName("unknown.repo/prefix/imagename:latest") containerUnknown := *MockContainer(WithImageName("unknown.repo/prefix/imagename:latest"))
containerKnown := *mockContainerWithImageName("docker.io/prefix/imagename:latest") containerKnown := *MockContainer(WithImageName("docker.io/prefix/imagename:latest"))
When(`warn on head failure is set to "always"`, func() { When(`warn on head failure is set to "always"`, func() {
c := dockerClient{ClientOptions: ClientOptions{WarnOnHeadFailed: WarnAlways}} c := dockerClient{ClientOptions: ClientOptions{WarnOnHeadFailed: WarnAlways}}
@ -64,7 +64,7 @@ var _ = Describe("the client", func() {
When("the image consist of a pinned hash", func() { When("the image consist of a pinned hash", func() {
It("should gracefully fail with a useful message", func() { It("should gracefully fail with a useful message", func() {
c := dockerClient{} c := dockerClient{}
pinnedContainer := *mockContainerWithImageName("sha256:fa5269854a5e615e51a72b17ad3fd1e01268f278a6684c8ed3c5f0cdce3f230b") pinnedContainer := *MockContainer(WithImageName("sha256:fa5269854a5e615e51a72b17ad3fd1e01268f278a6684c8ed3c5f0cdce3f230b"))
c.PullImage(context.Background(), pinnedContainer) c.PullImage(context.Background(), pinnedContainer)
}) })
}) })

@ -0,0 +1,66 @@
package container
import (
"github.com/docker/docker/api/types"
dockerContainer "github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
)
type MockContainerUpdate func(*types.ContainerJSON, *types.ImageInspect)
func MockContainer(updates ...MockContainerUpdate) *Container {
containerInfo := types.ContainerJSON{
ContainerJSONBase: &types.ContainerJSONBase{
ID: "container_id",
Image: "image",
Name: "test-containrrr",
HostConfig: &dockerContainer.HostConfig{},
},
Config: &dockerContainer.Config{
Labels: map[string]string{},
},
}
image := types.ImageInspect{
ID: "image_id",
}
for _, update := range updates {
update(&containerInfo, &image)
}
return NewContainer(&containerInfo, &image)
}
func WithPortBindings(portBindingSources ...string) MockContainerUpdate {
return func(c *types.ContainerJSON, i *types.ImageInspect) {
portBindings := nat.PortMap{}
for _, pbs := range portBindingSources {
portBindings[nat.Port(pbs)] = []nat.PortBinding{}
}
c.HostConfig.PortBindings = portBindings
}
}
func WithImageName(name string) MockContainerUpdate {
return func(c *types.ContainerJSON, i *types.ImageInspect) {
c.Config.Image = name
i.RepoTags = append(i.RepoTags, name)
}
}
func WithLinks(links []string) MockContainerUpdate {
return func(c *types.ContainerJSON, i *types.ImageInspect) {
c.HostConfig.Links = links
}
}
func WithLabels(labels map[string]string) MockContainerUpdate {
return func(c *types.ContainerJSON, i *types.ImageInspect) {
c.Config.Labels = labels
}
}
func WithContainerState(state types.ContainerState) MockContainerUpdate {
return func(cnt *types.ContainerJSON, img *types.ImageInspect) {
cnt.State = &state
}
}

@ -1,8 +1,6 @@
package container package container
import ( import (
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
. "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo"
. "github.com/onsi/gomega" . "github.com/onsi/gomega"
@ -12,7 +10,7 @@ var _ = Describe("the container", func() {
Describe("VerifyConfiguration", func() { Describe("VerifyConfiguration", func() {
When("verifying a container with no image info", func() { When("verifying a container with no image info", func() {
It("should return an error", func() { It("should return an error", func() {
c := mockContainerWithPortBindings() c := MockContainer(WithPortBindings())
c.imageInfo = nil c.imageInfo = nil
err := c.VerifyConfiguration() err := c.VerifyConfiguration()
Expect(err).To(Equal(errorNoImageInfo)) Expect(err).To(Equal(errorNoImageInfo))
@ -20,7 +18,7 @@ var _ = Describe("the container", func() {
}) })
When("verifying a container with no container info", func() { When("verifying a container with no container info", func() {
It("should return an error", func() { It("should return an error", func() {
c := mockContainerWithPortBindings() c := MockContainer(WithPortBindings())
c.containerInfo = nil c.containerInfo = nil
err := c.VerifyConfiguration() err := c.VerifyConfiguration()
Expect(err).To(Equal(errorNoContainerInfo)) Expect(err).To(Equal(errorNoContainerInfo))
@ -28,7 +26,7 @@ var _ = Describe("the container", func() {
}) })
When("verifying a container with no config", func() { When("verifying a container with no config", func() {
It("should return an error", func() { It("should return an error", func() {
c := mockContainerWithPortBindings() c := MockContainer(WithPortBindings())
c.containerInfo.Config = nil c.containerInfo.Config = nil
err := c.VerifyConfiguration() err := c.VerifyConfiguration()
Expect(err).To(Equal(errorInvalidConfig)) Expect(err).To(Equal(errorInvalidConfig))
@ -36,7 +34,7 @@ var _ = Describe("the container", func() {
}) })
When("verifying a container with no host config", func() { When("verifying a container with no host config", func() {
It("should return an error", func() { It("should return an error", func() {
c := mockContainerWithPortBindings() c := MockContainer(WithPortBindings())
c.containerInfo.HostConfig = nil c.containerInfo.HostConfig = nil
err := c.VerifyConfiguration() err := c.VerifyConfiguration()
Expect(err).To(Equal(errorInvalidConfig)) Expect(err).To(Equal(errorInvalidConfig))
@ -44,14 +42,14 @@ var _ = Describe("the container", func() {
}) })
When("verifying a container with no port bindings", func() { When("verifying a container with no port bindings", func() {
It("should not return an error", func() { It("should not return an error", func() {
c := mockContainerWithPortBindings() c := MockContainer(WithPortBindings())
err := c.VerifyConfiguration() err := c.VerifyConfiguration()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
}) })
}) })
When("verifying a container with port bindings, but no exposed ports", func() { When("verifying a container with port bindings, but no exposed ports", func() {
It("should make the config compatible with updating", func() { It("should make the config compatible with updating", func() {
c := mockContainerWithPortBindings("80/tcp") c := MockContainer(WithPortBindings("80/tcp"))
c.containerInfo.Config.ExposedPorts = nil c.containerInfo.Config.ExposedPorts = nil
Expect(c.VerifyConfiguration()).To(Succeed()) Expect(c.VerifyConfiguration()).To(Succeed())
@ -61,7 +59,7 @@ var _ = Describe("the container", func() {
}) })
When("verifying a container with port bindings and exposed ports is non-nil", func() { When("verifying a container with port bindings and exposed ports is non-nil", func() {
It("should return an error", func() { It("should return an error", func() {
c := mockContainerWithPortBindings("80/tcp") c := MockContainer(WithPortBindings("80/tcp"))
c.containerInfo.Config.ExposedPorts = map[nat.Port]struct{}{"80/tcp": {}} c.containerInfo.Config.ExposedPorts = map[nat.Port]struct{}{"80/tcp": {}}
err := c.VerifyConfiguration() err := c.VerifyConfiguration()
Expect(err).ToNot(HaveOccurred()) Expect(err).ToNot(HaveOccurred())
@ -71,10 +69,10 @@ var _ = Describe("the container", func() {
When("asked for metadata", func() { When("asked for metadata", func() {
var c *Container var c *Container
BeforeEach(func() { BeforeEach(func() {
c = mockContainerWithLabels(map[string]string{ c = MockContainer(WithLabels(map[string]string{
"com.centurylinklabs.watchtower.enable": "true", "com.centurylinklabs.watchtower.enable": "true",
"com.centurylinklabs.watchtower": "true", "com.centurylinklabs.watchtower": "true",
}) }))
}) })
It("should return its name on calls to .Name()", func() { It("should return its name on calls to .Name()", func() {
name := c.Name() name := c.Name()
@ -91,36 +89,28 @@ var _ = Describe("the container", func() {
enabled, exists := c.Enabled() enabled, exists := c.Enabled()
Expect(enabled).To(BeTrue()) Expect(enabled).To(BeTrue())
Expect(enabled).NotTo(BeFalse())
Expect(exists).To(BeTrue()) Expect(exists).To(BeTrue())
Expect(exists).NotTo(BeFalse())
}) })
It("should return false, true if present but not true on calls to .Enabled()", func() { It("should return false, true if present but not true on calls to .Enabled()", func() {
c = mockContainerWithLabels(map[string]string{"com.centurylinklabs.watchtower.enable": "false"}) c = MockContainer(WithLabels(map[string]string{"com.centurylinklabs.watchtower.enable": "false"}))
enabled, exists := c.Enabled() enabled, exists := c.Enabled()
Expect(enabled).To(BeFalse()) Expect(enabled).To(BeFalse())
Expect(enabled).NotTo(BeTrue())
Expect(exists).To(BeTrue()) Expect(exists).To(BeTrue())
Expect(exists).NotTo(BeFalse())
}) })
It("should return false, false if not present on calls to .Enabled()", func() { It("should return false, false if not present on calls to .Enabled()", func() {
c = mockContainerWithLabels(map[string]string{"lol": "false"}) c = MockContainer(WithLabels(map[string]string{"lol": "false"}))
enabled, exists := c.Enabled() enabled, exists := c.Enabled()
Expect(enabled).To(BeFalse()) Expect(enabled).To(BeFalse())
Expect(enabled).NotTo(BeTrue())
Expect(exists).To(BeFalse()) Expect(exists).To(BeFalse())
Expect(exists).NotTo(BeTrue())
}) })
It("should return false, false if present but not parsable .Enabled()", func() { It("should return false, false if present but not parsable .Enabled()", func() {
c = mockContainerWithLabels(map[string]string{"com.centurylinklabs.watchtower.enable": "falsy"}) c = MockContainer(WithLabels(map[string]string{"com.centurylinklabs.watchtower.enable": "falsy"}))
enabled, exists := c.Enabled() enabled, exists := c.Enabled()
Expect(enabled).To(BeFalse()) Expect(enabled).To(BeFalse())
Expect(enabled).NotTo(BeTrue())
Expect(exists).To(BeFalse()) Expect(exists).To(BeFalse())
Expect(exists).NotTo(BeTrue())
}) })
When("checking if its a watchtower instance", func() { When("checking if its a watchtower instance", func() {
It("should return true if the label is set to true", func() { It("should return true if the label is set to true", func() {
@ -128,31 +118,31 @@ var _ = Describe("the container", func() {
Expect(isWatchtower).To(BeTrue()) Expect(isWatchtower).To(BeTrue())
}) })
It("should return false if the label is present but set to false", func() { It("should return false if the label is present but set to false", func() {
c = mockContainerWithLabels(map[string]string{"com.centurylinklabs.watchtower": "false"}) c = MockContainer(WithLabels(map[string]string{"com.centurylinklabs.watchtower": "false"}))
isWatchtower := c.IsWatchtower() isWatchtower := c.IsWatchtower()
Expect(isWatchtower).To(BeFalse()) Expect(isWatchtower).To(BeFalse())
}) })
It("should return false if the label is not present", func() { It("should return false if the label is not present", func() {
c = mockContainerWithLabels(map[string]string{"funny.label": "false"}) c = MockContainer(WithLabels(map[string]string{"funny.label": "false"}))
isWatchtower := c.IsWatchtower() isWatchtower := c.IsWatchtower()
Expect(isWatchtower).To(BeFalse()) Expect(isWatchtower).To(BeFalse())
}) })
It("should return false if there are no labels", func() { It("should return false if there are no labels", func() {
c = mockContainerWithLabels(map[string]string{}) c = MockContainer(WithLabels(map[string]string{}))
isWatchtower := c.IsWatchtower() isWatchtower := c.IsWatchtower()
Expect(isWatchtower).To(BeFalse()) Expect(isWatchtower).To(BeFalse())
}) })
}) })
When("fetching the custom stop signal", func() { When("fetching the custom stop signal", func() {
It("should return the signal if its set", func() { It("should return the signal if its set", func() {
c = mockContainerWithLabels(map[string]string{ c = MockContainer(WithLabels(map[string]string{
"com.centurylinklabs.watchtower.stop-signal": "SIGKILL", "com.centurylinklabs.watchtower.stop-signal": "SIGKILL",
}) }))
stopSignal := c.StopSignal() stopSignal := c.StopSignal()
Expect(stopSignal).To(Equal("SIGKILL")) Expect(stopSignal).To(Equal("SIGKILL"))
}) })
It("should return an empty string if its not set", func() { It("should return an empty string if its not set", func() {
c = mockContainerWithLabels(map[string]string{}) c = MockContainer(WithLabels(map[string]string{}))
stopSignal := c.StopSignal() stopSignal := c.StopSignal()
Expect(stopSignal).To(Equal("")) Expect(stopSignal).To(Equal(""))
}) })
@ -160,22 +150,22 @@ var _ = Describe("the container", func() {
When("fetching the image name", func() { When("fetching the image name", func() {
When("the zodiac label is present", func() { When("the zodiac label is present", func() {
It("should fetch the image name from it", func() { It("should fetch the image name from it", func() {
c = mockContainerWithLabels(map[string]string{ c = MockContainer(WithLabels(map[string]string{
"com.centurylinklabs.zodiac.original-image": "the-original-image", "com.centurylinklabs.zodiac.original-image": "the-original-image",
}) }))
imageName := c.ImageName() imageName := c.ImageName()
Expect(imageName).To(Equal(imageName)) Expect(imageName).To(Equal(imageName))
}) })
}) })
It("should return the image name", func() { It("should return the image name", func() {
name := "image-name:3" name := "image-name:3"
c = mockContainerWithImageName(name) c = MockContainer(WithImageName(name))
imageName := c.ImageName() imageName := c.ImageName()
Expect(imageName).To(Equal(name)) Expect(imageName).To(Equal(name))
}) })
It("should assume latest if no tag is supplied", func() { It("should assume latest if no tag is supplied", func() {
name := "image-name" name := "image-name"
c = mockContainerWithImageName(name) c = MockContainer(WithImageName(name))
imageName := c.ImageName() imageName := c.ImageName()
Expect(imageName).To(Equal(name + ":latest")) Expect(imageName).To(Equal(name + ":latest"))
}) })
@ -184,33 +174,33 @@ var _ = Describe("the container", func() {
When("fetching container links", func() { When("fetching container links", func() {
When("the depends on label is present", func() { When("the depends on label is present", func() {
It("should fetch depending containers from it", func() { It("should fetch depending containers from it", func() {
c = mockContainerWithLabels(map[string]string{ c = MockContainer(WithLabels(map[string]string{
"com.centurylinklabs.watchtower.depends-on": "postgres", "com.centurylinklabs.watchtower.depends-on": "postgres",
}) }))
links := c.Links() links := c.Links()
Expect(links).To(SatisfyAll(ContainElement("postgres"), HaveLen(1))) Expect(links).To(SatisfyAll(ContainElement("postgres"), HaveLen(1)))
}) })
It("should fetch depending containers if there are many", func() { It("should fetch depending containers if there are many", func() {
c = mockContainerWithLabels(map[string]string{ c = MockContainer(WithLabels(map[string]string{
"com.centurylinklabs.watchtower.depends-on": "postgres,redis", "com.centurylinklabs.watchtower.depends-on": "postgres,redis",
}) }))
links := c.Links() links := c.Links()
Expect(links).To(SatisfyAll(ContainElement("postgres"), ContainElement("redis"), HaveLen(2))) Expect(links).To(SatisfyAll(ContainElement("postgres"), ContainElement("redis"), HaveLen(2)))
}) })
It("should fetch depending containers if label is blank", func() { It("should fetch depending containers if label is blank", func() {
c = mockContainerWithLabels(map[string]string{ c = MockContainer(WithLabels(map[string]string{
"com.centurylinklabs.watchtower.depends-on": "", "com.centurylinklabs.watchtower.depends-on": "",
}) }))
links := c.Links() links := c.Links()
Expect(links).To(HaveLen(0)) Expect(links).To(HaveLen(0))
}) })
}) })
When("the depends on label is not present", func() { When("the depends on label is not present", func() {
It("should fetch depending containers from host config links", func() { It("should fetch depending containers from host config links", func() {
c = mockContainerWithLinks([]string{ c = MockContainer(WithLinks([]string{
"redis:test-containrrr", "redis:test-containrrr",
"postgres:test-containrrr", "postgres:test-containrrr",
}) }))
links := c.Links() links := c.Links()
Expect(links).To(SatisfyAll(ContainElement("redis"), ContainElement("postgres"), HaveLen(2))) Expect(links).To(SatisfyAll(ContainElement("redis"), ContainElement("postgres"), HaveLen(2)))
}) })
@ -219,10 +209,10 @@ var _ = Describe("the container", func() {
When("there is a pre or post update timeout", func() { When("there is a pre or post update timeout", func() {
It("should return minute values", func() { It("should return minute values", func() {
c = mockContainerWithLabels(map[string]string{ c = MockContainer(WithLabels(map[string]string{
"com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "3", "com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "3",
"com.centurylinklabs.watchtower.lifecycle.post-update-timeout": "5", "com.centurylinklabs.watchtower.lifecycle.post-update-timeout": "5",
}) }))
preTimeout := c.PreUpdateTimeout() preTimeout := c.PreUpdateTimeout()
Expect(preTimeout).To(Equal(3)) Expect(preTimeout).To(Equal(3))
postTimeout := c.PostUpdateTimeout() postTimeout := c.PostUpdateTimeout()
@ -232,53 +222,3 @@ var _ = Describe("the container", func() {
}) })
}) })
func mockContainerWithPortBindings(portBindingSources ...string) *Container {
mockContainer := mockContainerWithLabels(nil)
mockContainer.imageInfo = &types.ImageInspect{}
hostConfig := &container.HostConfig{
PortBindings: nat.PortMap{},
}
for _, pbs := range portBindingSources {
hostConfig.PortBindings[nat.Port(pbs)] = []nat.PortBinding{}
}
mockContainer.containerInfo.HostConfig = hostConfig
return mockContainer
}
func mockContainerWithImageName(name string) *Container {
mockContainer := mockContainerWithLabels(nil)
mockContainer.containerInfo.Config.Image = name
return mockContainer
}
func mockContainerWithLinks(links []string) *Container {
content := types.ContainerJSON{
ContainerJSONBase: &types.ContainerJSONBase{
ID: "container_id",
Image: "image",
Name: "test-containrrr",
HostConfig: &container.HostConfig{
Links: links,
},
},
Config: &container.Config{
Labels: map[string]string{},
},
}
return NewContainer(&content, nil)
}
func mockContainerWithLabels(labels map[string]string) *Container {
content := types.ContainerJSON{
ContainerJSONBase: &types.ContainerJSONBase{
ID: "container_id",
Image: "image",
Name: "test-containrrr",
},
Config: &container.Config{
Labels: labels,
},
}
return NewContainer(&content, nil)
}

Loading…
Cancel
Save