diff --git a/runner/BUILD.bazel b/runner/BUILD.bazel index 57842b6..85503f5 100644 --- a/runner/BUILD.bazel +++ b/runner/BUILD.bazel @@ -20,7 +20,10 @@ go_library( go_test( name = "runner_test", - srcs = ["runner_test.go"], + srcs = [ + "runner_test.go", + "service_instance_test.go", + ], embed = [":runner"], deps = ["//svclib"], ) diff --git a/runner/pgroup_unix.go b/runner/pgroup_unix.go index 270fd6d..447fb79 100644 --- a/runner/pgroup_unix.go +++ b/runner/pgroup_unix.go @@ -3,13 +3,11 @@ package runner import ( - "fmt" "os/exec" "syscall" ) func errnoMeansProcessGone(errno syscall.Errno) bool { - fmt.Println("ERRNO", errno) switch errno { case syscall.ESRCH: return true diff --git a/runner/service_instance.go b/runner/service_instance.go index e645d96..ffa9990 100644 --- a/runner/service_instance.go +++ b/runner/service_instance.go @@ -66,7 +66,10 @@ func (s *ServiceInstance) WaitUntilHealthy(ctx context.Context) error { if s.Type == "task" { err := s.waitErrFn() log.Printf("%s completed.\n", coloredLabel) - return err + if err != nil { + return fmt.Errorf("%s exited with error: %w", coloredLabel, err) + } + return nil } sleepDuration, err := time.ParseDuration(s.HealthCheckInterval) @@ -83,7 +86,7 @@ func (s *ServiceInstance) WaitUntilHealthy(ctx context.Context) error { for { if err := s.Error(); err != nil { - return err + return fmt.Errorf("%s exited with error: %w", coloredLabel, err) } if s.isDone() { @@ -95,7 +98,7 @@ func (s *ServiceInstance) WaitUntilHealthy(ctx context.Context) error { } if err := ctx.Err(); err != nil { - return err + return fmt.Errorf("%s never became healthy: %w", coloredLabel, err) } if s.HealthCheck(ctx, expectedStartDuration) { diff --git a/runner/service_instance_test.go b/runner/service_instance_test.go new file mode 100644 index 0000000..b47f5dc --- /dev/null +++ b/runner/service_instance_test.go @@ -0,0 +1,69 @@ +package runner + +import ( + "context" + "errors" + "strings" + "testing" + + "rules_itest/svclib" +) + +func TestWaitUntilHealthyTaskErrorIncludesLabel(t *testing.T) { + wantErr := errors.New("task failed") + service := &ServiceInstance{ + VersionedServiceSpec: svclib.VersionedServiceSpec{ServiceSpec: svclib.ServiceSpec{ + Type: "task", + Label: "//example:setup", + }}, + waitErrFn: func() error { return wantErr }, + } + + err := service.WaitUntilHealthy(context.Background()) + if !errors.Is(err, wantErr) { + t.Fatalf("WaitUntilHealthy() error = %v, want wrapped %v", err, wantErr) + } + if !strings.Contains(err.Error(), service.Label) { + t.Fatalf("WaitUntilHealthy() error = %q, want service label %q", err, service.Label) + } +} + +func TestWaitUntilHealthyServiceErrorIncludesLabel(t *testing.T) { + wantErr := errors.New("service failed") + service := &ServiceInstance{ + VersionedServiceSpec: svclib.VersionedServiceSpec{ServiceSpec: svclib.ServiceSpec{ + Type: "service", + Label: "//example:server", + HealthCheckInterval: "1ms", + }}, + runErr: wantErr, + } + + err := service.WaitUntilHealthy(context.Background()) + if !errors.Is(err, wantErr) { + t.Fatalf("WaitUntilHealthy() error = %v, want wrapped %v", err, wantErr) + } + if !strings.Contains(err.Error(), service.Label) { + t.Fatalf("WaitUntilHealthy() error = %q, want service label %q", err, service.Label) + } +} + +func TestWaitUntilHealthyContextErrorIncludesLabel(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + cancel() + service := &ServiceInstance{ + VersionedServiceSpec: svclib.VersionedServiceSpec{ServiceSpec: svclib.ServiceSpec{ + Type: "service", + Label: "//example:server", + HealthCheckInterval: "1ms", + }}, + } + + err := service.WaitUntilHealthy(ctx) + if !errors.Is(err, context.Canceled) { + t.Fatalf("WaitUntilHealthy() error = %v, want wrapped context cancellation", err) + } + if !strings.Contains(err.Error(), service.Label) { + t.Fatalf("WaitUntilHealthy() error = %q, want service label %q", err, service.Label) + } +}