From 9832720c1cedd6e81d6064857cbd5524c93ef43f Mon Sep 17 00:00:00 2001 From: Marco Pracucci Date: Thu, 19 Mar 2020 10:02:39 +0100 Subject: [PATCH 1/3] Introduced a basic logger to the integration tests framework Signed-off-by: Marco Pracucci --- integration/e2e/logger.go | 43 +++++++++++++++++++++++++++++++++++++ integration/e2e/scenario.go | 25 +++++++++++---------- integration/e2e/service.go | 28 +++++++++++------------- 3 files changed, 68 insertions(+), 28 deletions(-) create mode 100644 integration/e2e/logger.go diff --git a/integration/e2e/logger.go b/integration/e2e/logger.go new file mode 100644 index 00000000000..1b9349bfa84 --- /dev/null +++ b/integration/e2e/logger.go @@ -0,0 +1,43 @@ +package e2e + +import ( + "fmt" + "io" + "os" + "strings" + "time" + + "github.com/go-kit/kit/log" +) + +// Global logger to use in integration tests. We use a global logger to simplify +// writing integration tests and avoiding having to pass the logger instance +// every time. +var logger log.Logger + +func init() { + logger = NewLogger(os.Stdout) +} + +type Logger struct { + w io.Writer +} + +func NewLogger(w io.Writer) *Logger { + return &Logger{ + w: w, + } +} + +func (l *Logger) Log(keyvals ...interface{}) error { + log := strings.Builder{} + log.WriteString(time.Now().Format("15:04:05")) + + for _, v := range keyvals { + log.WriteString(" " + fmt.Sprint(v)) + } + + log.WriteString("\n") + l.w.Write([]byte(log.String())) + return nil +} diff --git a/integration/e2e/scenario.go b/integration/e2e/scenario.go index b23945f6e92..f0c6074a4a6 100644 --- a/integration/e2e/scenario.go +++ b/integration/e2e/scenario.go @@ -54,7 +54,7 @@ func NewScenario(networkName string) (*Scenario, error) { // Setup the docker network. if out, err := RunCommandAndGetOutput("docker", "network", "create", networkName); err != nil { - fmt.Println(string(out)) + logger.Log(string(out)) s.clean() return nil, errors.Wrapf(err, "create docker network '%s'", networkName) } @@ -90,8 +90,7 @@ func (s *Scenario) StartAndWaitReady(services ...Service) error { func (s *Scenario) Start(services ...Service) error { for _, service := range services { - // TODO(bwplotka): Some basic logger would be nice. - fmt.Println("Starting", service.Name()) + logger.Log("Starting", service.Name()) // Ensure another service with the same name doesn't exist. if s.isRegistered(service.Name()) { @@ -153,7 +152,7 @@ func (s *Scenario) Close() { // TODO(bwplotka): Add comments. func (s *Scenario) clean() { if err := os.RemoveAll(s.sharedDir); err != nil { - fmt.Println("error while removing sharedDir", s.sharedDir, "err:", err) + logger.Log("error while removing sharedDir", s.sharedDir, "err:", err) } } @@ -161,7 +160,7 @@ func (s *Scenario) shutdown() { // Kill the services in the opposite order. for i := len(s.services) - 1; i >= 0; i-- { if err := s.services[i].Kill(); err != nil { - fmt.Println("Unable to kill service", s.services[i].Name(), ":", err.Error()) + logger.Log("Unable to kill service", s.services[i].Name(), ":", err.Error()) } } @@ -181,13 +180,13 @@ func (s *Scenario) shutdown() { } if out, err = RunCommandAndGetOutput("docker", "rm", "--force", containerID); err != nil { - fmt.Println(string(out)) - fmt.Println("Unable to cleanup leftover container", containerID, ":", err.Error()) + logger.Log(string(out)) + logger.Log("Unable to cleanup leftover container", containerID, ":", err.Error()) } } } else { - fmt.Println(string(out)) - fmt.Println("Unable to cleanup leftover containers:", err.Error()) + logger.Log(string(out)) + logger.Log("Unable to cleanup leftover containers:", err.Error()) } // Teardown the docker network. In case the network does not exists (ie. this function @@ -195,8 +194,8 @@ func (s *Scenario) shutdown() { // an error which may be misleading. if ok, err := existDockerNetwork(s.networkName); ok || err != nil { if out, err := RunCommandAndGetOutput("docker", "network", "rm", s.networkName); err != nil { - fmt.Println(string(out)) - fmt.Println("Unable to remove docker network", s.networkName, ":", err.Error()) + logger.Log(string(out)) + logger.Log("Unable to remove docker network", s.networkName, ":", err.Error()) } } } @@ -204,8 +203,8 @@ func (s *Scenario) shutdown() { func existDockerNetwork(networkName string) (bool, error) { out, err := RunCommandAndGetOutput("docker", "network", "ls", "--quiet", "--filter", fmt.Sprintf("name=%s", networkName)) if err != nil { - fmt.Println(string(out)) - fmt.Println("Unable to check if docker network", networkName, "exists:", err.Error()) + logger.Log(string(out)) + logger.Log("Unable to check if docker network", networkName, "exists:", err.Error()) } return strings.TrimSpace(string(out)) != "", nil diff --git a/integration/e2e/service.go b/integration/e2e/service.go index e7827df66f2..395ea533908 100644 --- a/integration/e2e/service.go +++ b/integration/e2e/service.go @@ -4,16 +4,15 @@ import ( "bytes" "context" "fmt" - "io" "io/ioutil" "math" - "os" "os/exec" "regexp" "strconv" "strings" "time" + "github.com/go-kit/kit/log" "github.com/pkg/errors" io_prometheus_client "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" @@ -104,8 +103,8 @@ func (s *ConcreteService) Start(networkName, sharedDir string) (err error) { }() cmd := exec.Command("docker", s.buildDockerRunArgs(networkName, sharedDir)...) - cmd.Stdout = &LinePrefixWriter{prefix: s.name + ": ", wrapped: os.Stdout} - cmd.Stderr = &LinePrefixWriter{prefix: s.name + ": ", wrapped: os.Stderr} + cmd.Stdout = &LinePrefixLogger{prefix: s.name + ": ", logger: logger} + cmd.Stderr = &LinePrefixLogger{prefix: s.name + ": ", logger: logger} if err = cmd.Start(); err != nil { return err } @@ -142,7 +141,7 @@ func (s *ConcreteService) Start(networkName, sharedDir string) (err error) { } s.networkPortsContainerToLocal[containerPort] = localPort } - fmt.Println("Ports for container:", s.containerName(), "Mapping:", s.networkPortsContainerToLocal) + logger.Log("Ports for container:", s.containerName(), "Mapping:", s.networkPortsContainerToLocal) return nil } @@ -151,10 +150,10 @@ func (s *ConcreteService) Stop() error { return nil } - fmt.Println("Stopping", s.name) + logger.Log("Stopping", s.name) if out, err := RunCommandAndGetOutput("docker", "stop", "--time=30", s.containerName()); err != nil { - fmt.Println(string(out)) + logger.Log(string(out)) return err } s.usedNetworkName = "" @@ -167,10 +166,10 @@ func (s *ConcreteService) Kill() error { return nil } - fmt.Println("Killing", s.name) + logger.Log("Killing", s.name) if out, err := RunCommandAndGetOutput("docker", "stop", "--time=0", s.containerName()); err != nil { - fmt.Println(string(out)) + logger.Log(string(out)) return err } s.usedNetworkName = "" @@ -405,12 +404,12 @@ func (p *CmdReadinessProbe) Ready(service *ConcreteService) error { return err } -type LinePrefixWriter struct { - prefix string - wrapped io.Writer +type LinePrefixLogger struct { + prefix string + logger log.Logger } -func (w *LinePrefixWriter) Write(p []byte) (n int, err error) { +func (w *LinePrefixLogger) Write(p []byte) (n int, err error) { for _, line := range strings.Split(string(p), "\n") { // Skip empty lines line = strings.TrimSpace(line) @@ -419,8 +418,7 @@ func (w *LinePrefixWriter) Write(p []byte) (n int, err error) { } // Write the prefix + line to the wrapped writer - _, err := w.wrapped.Write([]byte(w.prefix + line + "\n")) - if err != nil { + if err := w.logger.Log(w.prefix + line); err != nil { return 0, err } } From c6089246269f91f5b93906156fc0e60a167dac2b Mon Sep 17 00:00:00 2001 From: Marco Pracucci Date: Thu, 19 Mar 2020 10:11:47 +0100 Subject: [PATCH 2/3] Fixed linter Signed-off-by: Marco Pracucci --- integration/e2e/logger.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/integration/e2e/logger.go b/integration/e2e/logger.go index 1b9349bfa84..d4b309acab1 100644 --- a/integration/e2e/logger.go +++ b/integration/e2e/logger.go @@ -38,6 +38,7 @@ func (l *Logger) Log(keyvals ...interface{}) error { } log.WriteString("\n") - l.w.Write([]byte(log.String())) - return nil + + _, err := l.w.Write([]byte(log.String())) + return err } From 329b4a94cd3dd1f087591c493b55e98d402c7f93 Mon Sep 17 00:00:00 2001 From: Marco Pracucci Date: Thu, 19 Mar 2020 10:37:13 +0100 Subject: [PATCH 3/3] Increased integration tests timeout in CI Signed-off-by: Marco Pracucci --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e3ae684ad7d..54dfc1bd4b1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -156,7 +156,7 @@ jobs: export CORTEX_IMAGE="${CORTEX_IMAGE_PREFIX}cortex:${CIRCLE_TAG:-$(./tools/image-tag)}" export CORTEX_CHECKOUT_DIR="/home/circleci/.go_workspace/src/github.com/cortexproject/cortex" echo "Running integration tests with image: $CORTEX_IMAGE" - go test -tags=requires_docker -timeout 300s -v -count=1 ./integration/... + go test -tags=requires_docker -timeout 600s -v -count=1 ./integration/... build: <<: *defaults