package actions_test import ( "github.com/containrrr/watchtower/internal/actions" "github.com/containrrr/watchtower/pkg/container" "github.com/containrrr/watchtower/pkg/types" dockerContainer "github.com/docker/docker/api/types/container" "github.com/docker/go-connections/nat" "time" . "github.com/containrrr/watchtower/internal/actions/mocks" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("the update action", func() { var client MockClient When("watchtower has been instructed to clean up", func() { BeforeEach(func() { pullImages := false removeVolumes := false client = CreateMockClient( &TestData{ NameOfContainerToKeep: "test-container-02", Containers: []container.Container{ CreateMockContainer( "test-container-01", "test-container-01", "fake-image:latest", time.Now().AddDate(0, 0, -1)), CreateMockContainer( "test-container-02", "test-container-02", "fake-image:latest", time.Now()), CreateMockContainer( "test-container-02", "test-container-02", "fake-image:latest", time.Now()), }, }, pullImages, removeVolumes, ) }) When("there are multiple containers using the same image", func() { It("should only try to remove the image once", func() { _, err := actions.Update(client, types.UpdateParams{Cleanup: true}) Expect(err).NotTo(HaveOccurred()) Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1)) }) }) When("there are multiple containers using different images", func() { It("should try to remove each of them", func() { client.TestData.Containers = append( client.TestData.Containers, CreateMockContainer( "unique-test-container", "unique-test-container", "unique-fake-image:latest", time.Now(), ), ) _, err := actions.Update(client, types.UpdateParams{Cleanup: true}) Expect(err).NotTo(HaveOccurred()) Expect(client.TestData.TriedToRemoveImageCount).To(Equal(2)) }) }) When("performing a rolling restart update", func() { It("should try to remove the image once", func() { _, err := actions.Update(client, types.UpdateParams{Cleanup: true, RollingRestart: true}) Expect(err).NotTo(HaveOccurred()) Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1)) }) }) }) When("watchtower has been instructed to monitor only", func() { When("certain containers are set to monitor only", func() { BeforeEach(func() { client = CreateMockClient( &TestData{ NameOfContainerToKeep: "test-container-02", Containers: []container.Container{ CreateMockContainer( "test-container-01", "test-container-01", "fake-image1:latest", time.Now()), CreateMockContainerWithConfig( "test-container-02", "test-container-02", "fake-image2:latest", false, false, time.Now(), &dockerContainer.Config{ Labels: map[string]string{ "com.centurylinklabs.watchtower.monitor-only": "true", }, }), }, }, false, false, ) }) It("should not update those containers", func() { _, err := actions.Update(client, types.UpdateParams{Cleanup: true}) Expect(err).NotTo(HaveOccurred()) Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1)) }) }) When("monitor only is set globally", func() { BeforeEach(func() { client = CreateMockClient( &TestData{ Containers: []container.Container{ CreateMockContainer( "test-container-01", "test-container-01", "fake-image:latest", time.Now()), CreateMockContainer( "test-container-02", "test-container-02", "fake-image:latest", time.Now()), }, }, false, false, ) }) It("should not update any containers", func() { _, err := actions.Update(client, types.UpdateParams{MonitorOnly: true}) Expect(err).NotTo(HaveOccurred()) Expect(client.TestData.TriedToRemoveImageCount).To(Equal(0)) }) }) }) When("watchtower has been instructed to run lifecycle hooks", func() { When("prupddate script returns 1", func() { BeforeEach(func() { client = CreateMockClient( &TestData{ //NameOfContainerToKeep: "test-container-02", Containers: []container.Container{ CreateMockContainerWithConfig( "test-container-02", "test-container-02", "fake-image2:latest", true, false, time.Now(), &dockerContainer.Config{ Labels: map[string]string{ "com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "190", "com.centurylinklabs.watchtower.lifecycle.pre-update": "/PreUpdateReturn1.sh", }, ExposedPorts: map[nat.Port]struct{}{}, }), }, }, false, false, ) }) It("should not update those containers", func() { _, err := actions.Update(client, types.UpdateParams{Cleanup: true, LifecycleHooks: true}) Expect(err).NotTo(HaveOccurred()) Expect(client.TestData.TriedToRemoveImageCount).To(Equal(0)) }) }) When("prupddate script returns 75", func() { BeforeEach(func() { client = CreateMockClient( &TestData{ //NameOfContainerToKeep: "test-container-02", Containers: []container.Container{ CreateMockContainerWithConfig( "test-container-02", "test-container-02", "fake-image2:latest", true, false, time.Now(), &dockerContainer.Config{ Labels: map[string]string{ "com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "190", "com.centurylinklabs.watchtower.lifecycle.pre-update": "/PreUpdateReturn75.sh", }, ExposedPorts: map[nat.Port]struct{}{}, }), }, }, false, false, ) }) It("should not update those containers", func() { _, err := actions.Update(client, types.UpdateParams{Cleanup: true, LifecycleHooks: true}) Expect(err).NotTo(HaveOccurred()) Expect(client.TestData.TriedToRemoveImageCount).To(Equal(0)) }) }) When("prupddate script returns 0", func() { BeforeEach(func() { client = CreateMockClient( &TestData{ //NameOfContainerToKeep: "test-container-02", Containers: []container.Container{ CreateMockContainerWithConfig( "test-container-02", "test-container-02", "fake-image2:latest", true, false, time.Now(), &dockerContainer.Config{ Labels: map[string]string{ "com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "190", "com.centurylinklabs.watchtower.lifecycle.pre-update": "/PreUpdateReturn0.sh", }, ExposedPorts: map[nat.Port]struct{}{}, }), }, }, false, false, ) }) It("should update those containers", func() { _, err := actions.Update(client, types.UpdateParams{Cleanup: true, LifecycleHooks: true}) Expect(err).NotTo(HaveOccurred()) Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1)) }) }) When("container is not running", func() { BeforeEach(func() { client = CreateMockClient( &TestData{ //NameOfContainerToKeep: "test-container-02", Containers: []container.Container{ CreateMockContainerWithConfig( "test-container-02", "test-container-02", "fake-image2:latest", false, false, time.Now(), &dockerContainer.Config{ Labels: map[string]string{ "com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "190", "com.centurylinklabs.watchtower.lifecycle.pre-update": "/PreUpdateReturn1.sh", }, ExposedPorts: map[nat.Port]struct{}{}, }), }, }, false, false, ) }) It("skip running preupdate", func() { _, err := actions.Update(client, types.UpdateParams{Cleanup: true, LifecycleHooks: true}) Expect(err).NotTo(HaveOccurred()) Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1)) }) }) When("container is restarting", func() { BeforeEach(func() { client = CreateMockClient( &TestData{ //NameOfContainerToKeep: "test-container-02", Containers: []container.Container{ CreateMockContainerWithConfig( "test-container-02", "test-container-02", "fake-image2:latest", false, true, time.Now(), &dockerContainer.Config{ Labels: map[string]string{ "com.centurylinklabs.watchtower.lifecycle.pre-update-timeout": "190", "com.centurylinklabs.watchtower.lifecycle.pre-update": "/PreUpdateReturn1.sh", }, ExposedPorts: map[nat.Port]struct{}{}, }), }, }, false, false, ) }) It("skip running preupdate", func() { _, err := actions.Update(client, types.UpdateParams{Cleanup: true, LifecycleHooks: true}) Expect(err).NotTo(HaveOccurred()) Expect(client.TestData.TriedToRemoveImageCount).To(Equal(1)) }) }) }) })