From a14b57aaa9cbda890d0521d345f61d26500db7eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antoni=20Ro=C5=9Bciszewski?= Date: Mon, 13 Feb 2017 12:40:05 +0100 Subject: [PATCH] Add tests for all of the dependencies --- dependencies/config/config.go | 15 +- dependencies/config/config_suite_test.go | 13 ++ dependencies/config/config_test.go | 167 ++++++++++++------ dependencies/container/container.go | 7 +- .../container/container_suite_test.go | 13 ++ dependencies/container/container_test.go | 71 ++++++-- dependencies/daemonset/daemonset.go | 13 +- .../daemonset/daemonset_suite_test.go | 13 ++ dependencies/daemonset/daemonset_test.go | 100 +++++++++-- dependencies/job/job.go | 4 +- dependencies/job/job_suite_test.go | 13 ++ dependencies/job/job_test.go | 60 ++++--- dependencies/service/service.go | 5 +- dependencies/service/service_suite_test.go | 13 ++ dependencies/service/service_test.go | 67 +++++-- dependencies/socket/socket.go | 12 +- dependencies/socket/socket_suite_test.go | 13 ++ dependencies/socket/socket_test.go | 68 +++++++ entrypoint/entrypoint_test.go | 1 - mocks/daemonset.go | 20 ++- mocks/endpoints.go | 24 ++- mocks/job.go | 9 +- mocks/pod.go | 33 +++- mocks/service.go | 11 +- 24 files changed, 614 insertions(+), 151 deletions(-) create mode 100644 dependencies/config/config_suite_test.go create mode 100644 dependencies/container/container_suite_test.go create mode 100644 dependencies/daemonset/daemonset_suite_test.go create mode 100644 dependencies/job/job_suite_test.go create mode 100644 dependencies/service/service_suite_test.go create mode 100644 dependencies/socket/socket_suite_test.go create mode 100644 dependencies/socket/socket_test.go diff --git a/dependencies/config/config.go b/dependencies/config/config.go index 81f9a5f..937211e 100644 --- a/dependencies/config/config.go +++ b/dependencies/config/config.go @@ -66,26 +66,27 @@ func (c Config) IsResolved(entrypoint entry.EntrypointInterface) (bool, error) { if err := createDirectory(c.GetName()); err != nil { return false, fmt.Errorf("Couldn't create directory: %v", err) } - if err := createAndTemplateConfig(c.GetName(), c.params, c.prefix); err != nil { + if err := c.createAndTemplateConfig(); err != nil { return false, fmt.Errorf("Cannot template %s: %v", c.GetName(), err) } return true, nil } -func createAndTemplateConfig(name string, params configParams, prefix string) (err error) { - config, err := os.Create(name) +func (c Config) createAndTemplateConfig() (err error) { + config, err := os.Create(c.name) if err != nil { return err } - file := filepath.Base(name) - temp := template.Must(template.New(file).ParseFiles(getSrcConfig(prefix, file))) - if err = temp.Execute(config, params); err != nil { + file := filepath.Base(c.name) + + temp := template.Must(template.New(file).ParseFiles(getSrcConfig(c.prefix, file))) + if err = temp.Execute(config, c.params); err != nil { return err } - return } + func (c Config) GetName() string { return c.name } diff --git a/dependencies/config/config_suite_test.go b/dependencies/config/config_suite_test.go new file mode 100644 index 0000000..6508e6d --- /dev/null +++ b/dependencies/config/config_suite_test.go @@ -0,0 +1,13 @@ +package config_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Config Suite") +} diff --git a/dependencies/config/config_test.go b/dependencies/config/config_test.go index e97c288..e6e83a7 100644 --- a/dependencies/config/config_test.go +++ b/dependencies/config/config_test.go @@ -1,76 +1,141 @@ -package config +package config_test import ( "fmt" "io/ioutil" "net" "os" - "strings" - "testing" + "path/filepath" - mocks "github.com/stackanetes/kubernetes-entrypoint/mocks" + . "github.com/stackanetes/kubernetes-entrypoint/dependencies/config" + "github.com/stackanetes/kubernetes-entrypoint/entrypoint" + "github.com/stackanetes/kubernetes-entrypoint/mocks" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) -func prepareEnv() (err error) { +const ( + testDir = "/tmp" + interfaceName = "INTERFACE_NAME" + testConfigName = "KUBERNETES_ENTRYPOINT_TEST_CONFIG" + + testConfigContentsFormat = "TEST_CONFIG %s\n" + + // configPath = "/tmp/lgtm" + templatePrefix = "/tmp/templates" +) + +var testEntrypoint entrypoint.EntrypointInterface +var testConfigContents string +var testConfigPath string +var testTemplatePath string +var hostname string + +// var testClient cli.ClientInterface + +func init() { + var err error + testConfigContents = fmt.Sprintf(testConfigContentsFormat, "{{ .HOSTNAME }}") + + testTemplatePath = fmt.Sprintf("%s/%s/%s", templatePrefix, testConfigName, testConfigName) + testConfigPath = fmt.Sprintf("%s/%s", testDir, testConfigName) + + hostname, err = os.Hostname() + + if err != nil { + fmt.Errorf("Could not get hostname", err) + } +} + +func setupOsEnvironment() (err error) { ifaces, err := net.Interfaces() if err != nil { return err } ifaceName := ifaces[0].Name - os.Setenv("INTERFACE_NAME", ifaceName) - return nil - + return os.Setenv(interfaceName, ifaceName) } -func createTemplate(template string) (err error) { - configContent := []byte("LGTM {{ .HOSTNAME }}\n") - if err = createDirectory(template); err != nil { - return fmt.Errorf("Couldn't create directory in tmp: %v", err) - } +func teardownOsEnvironment() (err error) { + return os.Unsetenv(interfaceName) +} - if err = ioutil.WriteFile(template, configContent, 0644); err != nil { +func setupConfigTemplate(templatePath string) (err error) { + configContent := []byte(testConfigContents) + if err := os.MkdirAll(filepath.Dir(templatePath), 0755); err != nil { return err } + + if err = ioutil.WriteFile(templatePath, configContent, 0644); err != nil { + return err + } + return - } -func TestIsResolved(t *testing.T) { - name := "/tmp/lgtm" - template := "/tmp/templates/lgtm/lgtm" - hostname, err := os.Hostname() - if err != nil { - t.Errorf("couldn't get hostname", err) + +func teardownConfigTemplate(templatePath string) (err error) { + if err := os.RemoveAll(templatePath); err != nil { + return err } - entry := mocks.NewEntrypoint() - - err = prepareEnv() - if err != nil { - t.Errorf("Something went wrong: %v", err) - } - - if err = createTemplate(template); err != nil { - t.Errorf("Couldn't create %s template: %v", template, err) - } - - config, err := NewConfig(name, "/tmp/templates") - if err != nil { - t.Errorf("Cannot create config dep: %v", err) - } - if _, err := config.IsResolved(entry); err != nil { - t.Errorf("Something went wrong: %v", err) - } - - result, err := ioutil.ReadFile(name) - if err != nil { - t.Errorf("Something went wrong file %s: doesnt exist: %v", name, err) - } - - expectedFile := fmt.Sprintf("LGTM %s", hostname) - - same := strings.Compare(strings.TrimRight(string(result[:]), "\n"), expectedFile) - if same != 0 { - t.Errorf("Expected: %s got: %s: same %v", expectedFile, string(result[:]), same) - } + return } + +var _ = Describe("Config", func() { + + BeforeEach(func() { + err := setupOsEnvironment() + Expect(err).NotTo(HaveOccurred()) + + err = setupConfigTemplate(testTemplatePath) + Expect(err).NotTo(HaveOccurred()) + + testEntrypoint = mocks.NewEntrypoint() + }) + + AfterEach(func() { + err := teardownOsEnvironment() + Expect(err).NotTo(HaveOccurred()) + + err = teardownConfigTemplate(testTemplatePath) + Expect(err).NotTo(HaveOccurred()) + }) + + It("creates new config from file", func() { + config, err := NewConfig(testConfigPath, templatePrefix) + + Expect(config).NotTo(Equal(nil)) + Expect(err).NotTo(HaveOccurred()) + }) + + It("checks the name of a newly created config file", func() { + config, _ := NewConfig(testConfigPath, templatePrefix) + + Expect(config.GetName()).To(Equal(testConfigPath)) + }) + + It("checks the format of a newly created config file", func() { + config, _ := NewConfig(testConfigPath, templatePrefix) + config.IsResolved(testEntrypoint) + + result, err := ioutil.ReadFile(fmt.Sprintf("%s/%s", testDir, testConfigName)) + Expect(err).NotTo(HaveOccurred()) + + expectedFile := fmt.Sprintf(testConfigContentsFormat, hostname) + + readConfig := string(result[:]) + Expect(readConfig).To(BeEquivalentTo(expectedFile)) + }) + + It("checks resolution of a config", func() { + config, _ := NewConfig(testConfigPath, templatePrefix) + + isResolved, err := config.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(true)) + Expect(err).NotTo(HaveOccurred()) + }) + +}) diff --git a/dependencies/container/container.go b/dependencies/container/container.go index f76428f..b6fde1b 100644 --- a/dependencies/container/container.go +++ b/dependencies/container/container.go @@ -2,11 +2,14 @@ package container import ( "fmt" + "os" + entry "github.com/stackanetes/kubernetes-entrypoint/entrypoint" "github.com/stackanetes/kubernetes-entrypoint/util/env" - "os" ) +const PodNameNotSetError = "Environment variable POD_NAME not set" + type Container struct { name string } @@ -28,7 +31,7 @@ func NewContainer(name string) Container { func (c Container) IsResolved(entrypoint entry.EntrypointInterface) (bool, error) { myPodName := os.Getenv("POD_NAME") if myPodName == "" { - return false, fmt.Errorf("Environment variable POD_NAME not set") + return false, fmt.Errorf(PodNameNotSetError) } pod, err := entrypoint.Client().Pods(entrypoint.GetNamespace()).Get(myPodName) if err != nil { diff --git a/dependencies/container/container_suite_test.go b/dependencies/container/container_suite_test.go new file mode 100644 index 0000000..698a15e --- /dev/null +++ b/dependencies/container/container_suite_test.go @@ -0,0 +1,13 @@ +package container_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestContainer(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Container Suite") +} diff --git a/dependencies/container/container_test.go b/dependencies/container/container_test.go index 0909bae..5fb1e73 100644 --- a/dependencies/container/container_test.go +++ b/dependencies/container/container_test.go @@ -1,18 +1,67 @@ -package container +package container_test import ( + "fmt" "os" - "testing" + . "github.com/stackanetes/kubernetes-entrypoint/dependencies/container" + "github.com/stackanetes/kubernetes-entrypoint/entrypoint" "github.com/stackanetes/kubernetes-entrypoint/mocks" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) -func TestResolveContainer(t *testing.T) { - entrypoint := mocks.NewEntrypoint() - c := NewContainer("container_test") - os.Setenv("POD_NAME", "lgtm") - _, err := c.IsResolved(entrypoint) - if err != nil { - t.Errorf("Resolving container failed: %v", err) - } -} +const ( + podEnvVariableName = "POD_NAME" +) + +var testEntrypoint entrypoint.EntrypointInterface + +var _ = Describe("Container", func() { + + BeforeEach(func() { + err := os.Setenv(podEnvVariableName, mocks.PodEnvVariableValue) + Expect(err).NotTo(HaveOccurred()) + + testEntrypoint = mocks.NewEntrypoint() + }) + + It("checks the name of a newly created container", func() { + container := NewContainer(mocks.MockContainerName) + + Expect(container.GetName()).To(Equal(mocks.MockContainerName)) + }) + + It(fmt.Sprintf("checks container resolution failure with %s not set", podEnvVariableName), func() { + os.Unsetenv(podEnvVariableName) + container := NewContainer(mocks.MockContainerName) + + isResolved, err := container.IsResolved(testEntrypoint) + Expect(isResolved).To(Equal(false)) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal(PodNameNotSetError)) + }) + + It("checks resolution of a succeeding container", func() { + container := NewContainer(mocks.MockContainerName) + + isResolved, err := container.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(true)) + Expect(err).NotTo(HaveOccurred()) + }) + + It(fmt.Sprintf("fails to resolve a mocked container for a given %s value", podEnvVariableName), func() { + err := os.Setenv(podEnvVariableName, "INVALID_POD_LIST_VALUE") + Expect(err).NotTo(HaveOccurred()) + + container := NewContainer(mocks.PodNotPresent) + Expect(container).NotTo(Equal(nil)) + + var isResolved bool + isResolved, err = container.IsResolved(testEntrypoint) + Expect(isResolved).To(Equal(false)) + Expect(err).To(BeNil()) + }) +}) diff --git a/dependencies/daemonset/daemonset.go b/dependencies/daemonset/daemonset.go index f6064be..409859c 100644 --- a/dependencies/daemonset/daemonset.go +++ b/dependencies/daemonset/daemonset.go @@ -11,6 +11,11 @@ import ( "k8s.io/client-go/pkg/labels" ) +const ( + PodNameEnvVar = "POD_NAME" + PodNameNotSetErrorFormat = "Env POD_NAME not set. Daemonset dependency %s will be ignored!" +) + type Daemonset struct { name string podName string @@ -31,12 +36,12 @@ func init() { } func NewDaemonset(name string) (*Daemonset, error) { - if os.Getenv("POD_NAME") == "" { - return nil, fmt.Errorf("Env POD_NAME not set. Daemonset dependency %s will be ignored!", name) + if os.Getenv(PodNameEnvVar) == "" { + return nil, fmt.Errorf(PodNameNotSetErrorFormat, name) } return &Daemonset{ name: name, - podName: os.Getenv("POD_NAME"), + podName: os.Getenv(PodNameEnvVar), }, nil } @@ -57,7 +62,7 @@ func (d Daemonset) IsResolved(entrypoint entry.EntrypointInterface) (bool, error myPod, err := entrypoint.Client().Pods(entrypoint.GetNamespace()).Get(d.podName) if err != nil { - panic(fmt.Sprintf("Getting POD: %v failed : %v", myPodName, err)) + return false, fmt.Errorf("Getting POD: %v failed : %v", myPodName, err) } myHost := myPod.Status.HostIP diff --git a/dependencies/daemonset/daemonset_suite_test.go b/dependencies/daemonset/daemonset_suite_test.go new file mode 100644 index 0000000..2e836ad --- /dev/null +++ b/dependencies/daemonset/daemonset_suite_test.go @@ -0,0 +1,13 @@ +package daemonset_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestDaemonset(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Daemonset Suite") +} diff --git a/dependencies/daemonset/daemonset_test.go b/dependencies/daemonset/daemonset_test.go index 534957a..e862b10 100644 --- a/dependencies/daemonset/daemonset_test.go +++ b/dependencies/daemonset/daemonset_test.go @@ -1,22 +1,92 @@ -package daemonset +package daemonset_test import ( + "fmt" "os" - "testing" - mocks "github.com/stackanetes/kubernetes-entrypoint/mocks" + . "github.com/stackanetes/kubernetes-entrypoint/dependencies/daemonset" + "github.com/stackanetes/kubernetes-entrypoint/entrypoint" + "github.com/stackanetes/kubernetes-entrypoint/mocks" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) -func TestResolveDaemonset(t *testing.T) { - entrypoint := mocks.NewEntrypoint() - os.Setenv("POD_NAME", "podlist") - daemonset, err := NewDaemonset("lgtm") - if err != nil { - t.Errorf("Cannot initialize daemonset: %v", err) - } - status, err := daemonset.IsResolved(entrypoint) - if err != nil { - t.Errorf("Something went wrong status: %s : %v", status, err) - } +const ( + podEnvVariableValue = "podlist" +) -} +var testEntrypoint entrypoint.EntrypointInterface + +var _ = Describe("Daemonset", func() { + + BeforeEach(func() { + err := os.Setenv(PodNameEnvVar, podEnvVariableValue) + Expect(err).NotTo(HaveOccurred()) + + testEntrypoint = mocks.NewEntrypoint() + }) + + It(fmt.Sprintf("checks failure of new daemonset creation without %s set", PodNameEnvVar), func() { + os.Unsetenv(PodNameEnvVar) + daemonset, err := NewDaemonset(mocks.SucceedingDaemonsetName) + + Expect(daemonset).To(BeNil()) + Expect(err.Error()).To(Equal(fmt.Sprintf(PodNameNotSetErrorFormat, mocks.SucceedingDaemonsetName))) + }) + + It(fmt.Sprintf("creates new daemonset with %s set and checks its name", PodNameEnvVar), func() { + daemonset, err := NewDaemonset(mocks.SucceedingDaemonsetName) + Expect(daemonset).NotTo(Equal(nil)) + Expect(err).NotTo(HaveOccurred()) + + Expect(daemonset.GetName()).To(Equal(mocks.SucceedingDaemonsetName)) + }) + + It("checks resolution of a succeeding daemonset", func() { + daemonset, _ := NewDaemonset(mocks.SucceedingDaemonsetName) + + isResolved, err := daemonset.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(true)) + Expect(err).NotTo(HaveOccurred()) + }) + + It("checks resolution failure of a daemonset with incorrect name", func() { + daemonset, _ := NewDaemonset(mocks.FailingDaemonsetName) + + isResolved, err := daemonset.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(false)) + Expect(err).To(HaveOccurred()) + }) + + It("checks resolution failure of a daemonset with incorrect match labels", func() { + daemonset, _ := NewDaemonset(mocks.IncorrectMatchLabelsDaemonsetName) + + isResolved, err := daemonset.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(false)) + Expect(err).To(HaveOccurred()) + }) + + It(fmt.Sprintf("checks resolution failure of a daemonset with incorrect %s value", PodNameEnvVar), func() { + // Set POD_NAME to value not present in the mocks + os.Setenv(PodNameEnvVar, mocks.PodNotPresent) + daemonset, _ := NewDaemonset(mocks.IncorrectMatchLabelsDaemonsetName) + + isResolved, err := daemonset.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(false)) + Expect(err).To(HaveOccurred()) + }) + + It("checks resolution failure of a daemonset with none of the pods with Ready status", func() { + daemonset, _ := NewDaemonset(mocks.NotReadyMatchLabelsDaemonsetName) + + isResolved, err := daemonset.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(false)) + Expect(err).To(HaveOccurred()) + }) +}) diff --git a/dependencies/job/job.go b/dependencies/job/job.go index ff1a729..00c6331 100644 --- a/dependencies/job/job.go +++ b/dependencies/job/job.go @@ -7,6 +7,8 @@ import ( "github.com/stackanetes/kubernetes-entrypoint/util/env" ) +const FailingStatusFormat = "Job %v is not completed yet" + type Job struct { name string } @@ -31,7 +33,7 @@ func (j Job) IsResolved(entrypoint entry.EntrypointInterface) (bool, error) { return false, err } if job.Status.Succeeded == 0 { - return false, fmt.Errorf("Job %v is not completed yet", j.GetName()) + return false, fmt.Errorf(FailingStatusFormat, j.GetName()) } return true, nil } diff --git a/dependencies/job/job_suite_test.go b/dependencies/job/job_suite_test.go new file mode 100644 index 0000000..b459b2d --- /dev/null +++ b/dependencies/job/job_suite_test.go @@ -0,0 +1,13 @@ +package job_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestJob(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Job Suite") +} diff --git a/dependencies/job/job_test.go b/dependencies/job/job_test.go index 5ff84dd..86db058 100644 --- a/dependencies/job/job_test.go +++ b/dependencies/job/job_test.go @@ -1,27 +1,47 @@ -package job +package job_test import ( - mocks "github.com/stackanetes/kubernetes-entrypoint/mocks" - "testing" + "fmt" + + . "github.com/stackanetes/kubernetes-entrypoint/dependencies/job" + "github.com/stackanetes/kubernetes-entrypoint/entrypoint" + "github.com/stackanetes/kubernetes-entrypoint/mocks" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) -func TestResolveNewJob(t *testing.T) { +const testJobName = "TEST_JOB" - entrypoint := mocks.NewEntrypoint() - job := NewJob("lgtm") - status, err := job.IsResolved(entrypoint) - if status != true { - t.Errorf("Resolving job failed: %v", err) - } -} +var testEntrypoint entrypoint.EntrypointInterface -func TestFailResolveNewJob(t *testing.T) { +var _ = Describe("Job", func() { - entrypoint := mocks.NewEntrypoint() - job := NewJob("fail") - _, err := job.IsResolved(entrypoint) - expectedError := "Job fail is not completed yet" - if err.Error() != expectedError { - t.Errorf("Something went wrong: %v", err) - } -} + BeforeEach(func() { + testEntrypoint = mocks.NewEntrypoint() + }) + + It("checks the name of a newly created job", func() { + job := NewJob(testJobName) + + Expect(job.GetName()).To(Equal(testJobName)) + }) + + It("checks resolution of a succeeding job", func() { + job := NewJob(mocks.SucceedingJobName) + + isResolved, err := job.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(true)) + Expect(err).NotTo(HaveOccurred()) + }) + + It("checks resolution failure of a failing job", func() { + job := NewJob(mocks.FailingJobName) + + isResolved, err := job.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(false)) + Expect(err.Error()).To(Equal(fmt.Sprintf(FailingStatusFormat, job.GetName()))) + }) +}) diff --git a/dependencies/service/service.go b/dependencies/service/service.go index db413f3..18b7dd7 100644 --- a/dependencies/service/service.go +++ b/dependencies/service/service.go @@ -2,10 +2,13 @@ package service import ( "fmt" + entry "github.com/stackanetes/kubernetes-entrypoint/entrypoint" "github.com/stackanetes/kubernetes-entrypoint/util/env" ) +const FailingStatusFormat = "Service %v has no endpoints" + type Service struct { name string } @@ -32,7 +35,7 @@ func (s Service) IsResolved(entrypoint entry.EntrypointInterface) (bool, error) if len(e.Subsets) > 0 { return true, nil } - return false, fmt.Errorf("Service %v has no endpoints", s.GetName()) + return false, fmt.Errorf(FailingStatusFormat, s.GetName()) } func (s Service) GetName() string { diff --git a/dependencies/service/service_suite_test.go b/dependencies/service/service_suite_test.go new file mode 100644 index 0000000..0bcf098 --- /dev/null +++ b/dependencies/service/service_suite_test.go @@ -0,0 +1,13 @@ +package service_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestService(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Service Suite") +} diff --git a/dependencies/service/service_test.go b/dependencies/service/service_test.go index 2add391..3639f5b 100644 --- a/dependencies/service/service_test.go +++ b/dependencies/service/service_test.go @@ -1,26 +1,55 @@ -package service +package service_test import ( + "fmt" + + . "github.com/stackanetes/kubernetes-entrypoint/dependencies/service" + "github.com/stackanetes/kubernetes-entrypoint/entrypoint" "github.com/stackanetes/kubernetes-entrypoint/mocks" - "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" ) -func TestResolveService(t *testing.T) { - entrypoint := mocks.NewEntrypoint() - s := NewService("lgtm") - _, err := s.IsResolved(entrypoint) - if err != nil { - t.Errorf("Checking condition fail with: %v", err) - } +const testServiceName = "TEST_SERVICE" -} +var testEntrypoint entrypoint.EntrypointInterface -func TestResolveServiceFail(t *testing.T) { - entrypoint := mocks.NewEntrypoint() - s := NewService("fail") - _, err := s.IsResolved(entrypoint) - expectedError := "Mock endpoint didnt work" - if err.Error() != expectedError { - t.Errorf("Checking condition fail with: %v", err) - } -} +var _ = Describe("Service", func() { + + BeforeEach(func() { + testEntrypoint = mocks.NewEntrypoint() + }) + + It("checks the name of a newly created service", func() { + service := NewService(testServiceName) + + Expect(service.GetName()).To(Equal(testServiceName)) + }) + + It("checks resolution of a succeeding service", func() { + service := NewService(mocks.SucceedingServiceName) + + isResolved, err := service.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(true)) + Expect(err).NotTo(HaveOccurred()) + }) + + It("checks resolution failure of a failing service", func() { + service := NewService(mocks.FailingServiceName) + + isResolved, err := service.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(false)) + Expect(err.Error()).To(Equal(mocks.MockEndpointError)) + }) + + It("checks resolution failure of a succeeding service with removed subsets", func() { + service := NewService(mocks.EmptySubsetsServiceName) + + isResolved, err := service.IsResolved(testEntrypoint) + Expect(isResolved).To(Equal(false)) + Expect(err.Error()).To(Equal(fmt.Sprintf(FailingStatusFormat, service.GetName()))) + }) +}) diff --git a/dependencies/socket/socket.go b/dependencies/socket/socket.go index d1c1839..b251be1 100644 --- a/dependencies/socket/socket.go +++ b/dependencies/socket/socket.go @@ -2,9 +2,15 @@ package socket import ( "fmt" + "os" + entry "github.com/stackanetes/kubernetes-entrypoint/entrypoint" "github.com/stackanetes/kubernetes-entrypoint/util/env" - "os" +) + +const ( + NonExistingErrorFormat = "Socket %v doesn't exists" + NoPermsErrorFormat = "I have no permission to %v" ) type Socket struct { @@ -34,10 +40,10 @@ func (s Socket) IsResolved(entrypoint entry.EntrypointInterface) (bool, error) { return true, nil } if os.IsNotExist(err) { - return false, fmt.Errorf("Socket %v doesn't exists", s.GetName()) + return false, fmt.Errorf(NonExistingErrorFormat, s.GetName()) } if os.IsPermission(err) { - return false, fmt.Errorf("I have no permission to %v", s.GetName()) + return false, fmt.Errorf(NoPermsErrorFormat, s.GetName()) } return false, err } diff --git a/dependencies/socket/socket_suite_test.go b/dependencies/socket/socket_suite_test.go new file mode 100644 index 0000000..023a521 --- /dev/null +++ b/dependencies/socket/socket_suite_test.go @@ -0,0 +1,13 @@ +package socket_test + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "testing" +) + +func TestSocket(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Socket Suite") +} diff --git a/dependencies/socket/socket_test.go b/dependencies/socket/socket_test.go new file mode 100644 index 0000000..3dd4e3e --- /dev/null +++ b/dependencies/socket/socket_test.go @@ -0,0 +1,68 @@ +package socket_test + +import ( + "fmt" + "os" + + . "github.com/stackanetes/kubernetes-entrypoint/dependencies/socket" + "github.com/stackanetes/kubernetes-entrypoint/entrypoint" + "github.com/stackanetes/kubernetes-entrypoint/mocks" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +const ( + existingSocketPath = "/tmp/k8s-existing-socket" + nonExistingSocketPath = "/tmp/k8s-nonexisting-socket" + noPermsSocketPath = "/root/k8s-no-permission-socket" +) + +var testEntrypoint entrypoint.EntrypointInterface + +var _ = Describe("Socket", func() { + + BeforeEach(func() { + testEntrypoint = mocks.NewEntrypoint() + + _, err := os.Create(existingSocketPath) + Expect(err).NotTo(HaveOccurred()) + + }) + + It("checks the name of a newly created socket", func() { + socket := NewSocket(existingSocketPath) + + Expect(socket.GetName()).To(Equal(existingSocketPath)) + }) + + It("resolves an existing socket socket", func() { + socket := NewSocket(existingSocketPath) + + isResolved, err := socket.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(true)) + Expect(err).NotTo(HaveOccurred()) + }) + + It("fails on trying to resolve a nonexisting socket", func() { + socket := NewSocket(nonExistingSocketPath) + + isResolved, err := socket.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(false)) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal(fmt.Sprintf(NonExistingErrorFormat, socket.GetName()))) + }) + + It("fails on trying to resolve a socket without permissions", func() { + socket := NewSocket(noPermsSocketPath) + + isResolved, err := socket.IsResolved(testEntrypoint) + + Expect(isResolved).To(Equal(false)) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(Equal(fmt.Sprintf(NoPermsErrorFormat, socket.GetName()))) + }) + +}) diff --git a/entrypoint/entrypoint_test.go b/entrypoint/entrypoint_test.go index 5f61a13..a2bf9d8 100644 --- a/entrypoint/entrypoint_test.go +++ b/entrypoint/entrypoint_test.go @@ -37,7 +37,6 @@ func (d dummyResolver) GetName() (name string) { func init() { testClient = mocks.NewClient() testEntrypoint = mocks.NewEntrypointInNamespace(testNamespace) - } func registerNilResolver() { diff --git a/mocks/daemonset.go b/mocks/daemonset.go index 674df60..6b43862 100644 --- a/mocks/daemonset.go +++ b/mocks/daemonset.go @@ -14,18 +14,34 @@ import ( type dClient struct { } +const ( + SucceedingDaemonsetName = "DAEMONSET_SUCCEED" + FailingDaemonsetName = "DAEMONSET_FAIL" + + IncorrectMatchLabelsDaemonsetName = "DAEMONSET_INCORRECT_MATCH_LABELS" + NotReadyMatchLabelsDaemonsetName = "DAEMONSET_NOT_READY_MATCH_LABELS" +) + func (d dClient) Get(name string) (*extensions.DaemonSet, error) { - if name != "lgtm" { + matchLabelName := MockContainerName + + if name == FailingDaemonsetName { return nil, fmt.Errorf("Mock daemonset didnt work") + } else if name == IncorrectMatchLabelsDaemonsetName { + matchLabelName = IncorrectMatchLabel + } else if name == NotReadyMatchLabelsDaemonsetName { + matchLabelName = NotReadyMatchLabel } + ds := &extensions.DaemonSet{ ObjectMeta: v1.ObjectMeta{Name: name}, Spec: extensions.DaemonSetSpec{ Selector: &unversioned.LabelSelector{ - MatchLabels: map[string]string{"name": "test"}, + MatchLabels: map[string]string{"name": matchLabelName}, }, }, } + return ds, nil } func (d dClient) Create(ds *extensions.DaemonSet) (*extensions.DaemonSet, error) { diff --git a/mocks/endpoints.go b/mocks/endpoints.go index 81fa03e..08b656e 100644 --- a/mocks/endpoints.go +++ b/mocks/endpoints.go @@ -13,20 +13,32 @@ import ( type eClient struct { } +const ( + MockEndpointError = "Mock endpoint didnt work" +) + func (e eClient) Get(name string) (*v1.Endpoints, error) { - if name != "lgtm" { - return nil, fmt.Errorf("Mock endpoint didnt work") + if name == FailingServiceName { + return nil, fmt.Errorf(MockEndpointError) } - endpoint := &v1.Endpoints{ - ObjectMeta: v1.ObjectMeta{Name: name}, - Subsets: []v1.EndpointSubset{ + + subsets := []v1.EndpointSubset{} + + if name != EmptySubsetsServiceName { + subsets = []v1.EndpointSubset{ { Addresses: []v1.EndpointAddress{ {IP: "127.0.0.1"}, }, }, - }, + } } + + endpoint := &v1.Endpoints{ + ObjectMeta: v1.ObjectMeta{Name: name}, + Subsets: subsets, + } + return endpoint, nil } func (e eClient) Create(ds *v1.Endpoints) (*v1.Endpoints, error) { diff --git a/mocks/job.go b/mocks/job.go index d3816b2..e26a308 100644 --- a/mocks/job.go +++ b/mocks/job.go @@ -10,16 +10,21 @@ import ( "k8s.io/client-go/pkg/watch" ) +const ( + SucceedingJobName = "succeed" + FailingJobName = "fail" +) + type jClient struct { } func (j jClient) Get(name string) (*batch.Job, error) { - if name == "lgtm" { + if name == SucceedingJobName { return &batch.Job{ Status: batch.JobStatus{Succeeded: 1}, }, nil } - if name == "fail" { + if name == FailingJobName { return &batch.Job{ Status: batch.JobStatus{Succeeded: 0}, }, nil diff --git a/mocks/pod.go b/mocks/pod.go index 2c35476..50647d5 100644 --- a/mocks/pod.go +++ b/mocks/pod.go @@ -11,16 +11,31 @@ import ( "k8s.io/client-go/rest" ) +const MockContainerName = "TEST_CONTAINER" + type pClient struct { } +const ( + PodNotPresent = "NOT_PRESENT" + PodEmptyContainerStatuses = "EMPTY_CONTAINTER_STATUSES" + PodEnvVariableValue = "podlist" + + IncorrectMatchLabel = "INCORRECT" + NotReadyMatchLabel = "INCORRECT" +) + func (p pClient) Get(name string) (*v1.Pod, error) { + if name == PodNotPresent { + return nil, fmt.Errorf("Could not get pod with the name %s", name) + } + return &v1.Pod{ ObjectMeta: v1.ObjectMeta{Name: name}, Status: v1.PodStatus{ ContainerStatuses: []v1.ContainerStatus{ { - Name: "container_test", + Name: MockContainerName, Ready: true, }, }, @@ -42,10 +57,20 @@ func (p pClient) DeleteCollection(options *v1.DeleteOptions, listOptions v1.List } func (p pClient) List(options v1.ListOptions) (*v1.PodList, error) { + if options.LabelSelector == "name=INCORRECT" { + return nil, fmt.Errorf("Client received incorrect pod label names") + } + + readyStatus := true + + if options.LabelSelector == "name=NOT_READY" { + readyStatus = false + } + return &v1.PodList{ Items: []v1.Pod{ { - ObjectMeta: v1.ObjectMeta{Name: "podList"}, + ObjectMeta: v1.ObjectMeta{Name: PodEnvVariableValue}, Status: v1.PodStatus{ HostIP: "127.0.01", Conditions: []v1.PodCondition{ @@ -56,8 +81,8 @@ func (p pClient) List(options v1.ListOptions) (*v1.PodList, error) { }, ContainerStatuses: []v1.ContainerStatus{ { - Name: "container_test", - Ready: true, + Name: MockContainerName, + Ready: readyStatus, }, }, }, diff --git a/mocks/service.go b/mocks/service.go index 08d8a62..5bfadfc 100644 --- a/mocks/service.go +++ b/mocks/service.go @@ -13,9 +13,16 @@ import ( type sClient struct { } +const ( + MockServiceError = "Mock service didnt work" + SucceedingServiceName = "succeed" + EmptySubsetsServiceName = "empty-subsets" + FailingServiceName = "fail" +) + func (s sClient) Get(name string) (*v1.Service, error) { - if name != "lgtm" { - return nil, fmt.Errorf("Mock service didnt work") + if name == FailingServiceName { + return nil, fmt.Errorf(MockServiceError) } return &v1.Service{ ObjectMeta: v1.ObjectMeta{Name: name},