| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package main |
| |
| import ( |
| "context" |
| "errors" |
| "testing" |
| |
| "time" |
| |
| "github.com/golang/protobuf/ptypes" |
| "github.com/golang/protobuf/ptypes/timestamp" |
| "go.chromium.org/luci/common/clock/testclock" |
| |
| buildbucketpb "go.chromium.org/luci/buildbucket/proto" |
| "go.chromium.org/luci/logdog/client/butlerlib/bootstrap" |
| "go.chromium.org/luci/logdog/client/butlerlib/streamclient" |
| ) |
| |
| func successfulStepFunc(ctx context.Context, build *buildbucketpb.Build) error { |
| return nil |
| } |
| |
| func failingStepFunc(ctx context.Context, build *buildbucketpb.Build) error { |
| return errors.New("failed") |
| } |
| |
| func mockBuildSender() {} |
| |
| func TestBootstrapStepRunner(t *testing.T) { |
| t.Parallel() |
| |
| mockBootstrap := &bootstrap.Bootstrap{ |
| CoordinatorHost: "foohost", |
| Project: "fooproject", |
| Prefix: "fooprefix", |
| Client: streamclient.NewFake("stderr").Client, |
| } |
| |
| var tests = []struct { |
| name string |
| fn stepFunc |
| time time.Time |
| sr bootstrapStepRunner |
| expectedStatus buildbucketpb.Status |
| expectedLogName string |
| expectedLogUrl string |
| expectedTs *timestamp.Timestamp |
| expectedErr bool |
| }{ |
| { |
| "successful step", |
| successfulStepFunc, |
| time.Unix(1500000000, 0), |
| bootstrapStepRunner{ |
| build: &buildbucketpb.Build{Steps: []*buildbucketpb.Step{}}, |
| send: mockBuildSender, |
| bootstrap: mockBootstrap, |
| }, |
| buildbucketpb.Status_SUCCESS, |
| "", |
| "", |
| ×tamp.Timestamp{Seconds: 1500000000}, |
| false, |
| }, |
| { |
| "failing step", |
| failingStepFunc, |
| time.Unix(1500000000, 0), |
| bootstrapStepRunner{ |
| build: &buildbucketpb.Build{Steps: []*buildbucketpb.Step{}}, |
| send: mockBuildSender, |
| bootstrap: mockBootstrap, |
| }, |
| buildbucketpb.Status_INFRA_FAILURE, |
| "stderr", |
| "logdog://foohost/fooproject/fooprefix/+/failing_step/stderr", |
| ×tamp.Timestamp{Seconds: 1500000000}, |
| true, |
| }, |
| } |
| |
| for _, test := range tests { |
| ctx := context.Background() |
| ctx, _ = testclock.UseTime(ctx, test.time) |
| err := test.sr.runStep(ctx, test.name, test.fn) |
| step := test.sr.build.Steps[0] |
| if step.Name != test.name { |
| t.Fatalf("expected step name %s, got %s", test.name, step.Name) |
| } |
| if step.Status != test.expectedStatus { |
| t.Fatalf("expected status %s, got %s", test.expectedStatus, step.Status) |
| } |
| if test.expectedLogName != "" { |
| log := step.Logs[0] |
| if log.Name != test.expectedLogName { |
| t.Fatalf("expected log name %s, got %s", test.expectedLogName, log.Name) |
| } |
| if log.Url != test.expectedLogUrl { |
| t.Fatalf("expected log url %s, got %s", test.expectedLogUrl, log.Url) |
| } |
| } |
| if err == nil { |
| if test.expectedErr { |
| t.Fatalf("expected error, got nil") |
| } |
| } else if !test.expectedErr { |
| t.Fatalf("got unexpected error %v", err) |
| } |
| st, err := ptypes.Timestamp(step.StartTime) |
| if err != nil { |
| t.Fatalf("got unexpected error during start ts conversion %v", err) |
| } |
| et, err := ptypes.Timestamp(step.EndTime) |
| if err != nil { |
| t.Fatalf("got unexpected error during end ts conversion %v", err) |
| } |
| expt, err := ptypes.Timestamp(test.expectedTs) |
| if err != nil { |
| t.Fatalf("got unexpected error during expected ts conversion %v", err) |
| } |
| if !st.Equal(expt) { |
| t.Fatalf("expected start time %s, got %s", expt, st) |
| } |
| if !et.Equal(expt) { |
| t.Fatalf("expected end time %s, got %s", expt, et) |
| } |
| } |
| } |
| |
| func TestBootstrapRecipe(t *testing.T) { |
| t.Parallel() |
| |
| var tests = []struct { |
| sr stepRunner |
| expectedErr bool |
| }{ |
| { |
| &successfulStepRunner{}, |
| false, |
| }, |
| { |
| &failingStepRunner{}, |
| true, |
| }, |
| } |
| |
| for _, test := range tests { |
| ctx := context.Background() |
| err := bootstrapRecipe(ctx, test.sr) |
| if err == nil { |
| if test.expectedErr { |
| t.Fatalf("expected error, got nil") |
| } |
| } else if !test.expectedErr { |
| t.Fatalf("got unexpected error %v", err) |
| } |
| } |
| } |