blob: 3344e807d2fba83767f7c55d08c69b0454d19501 [file] [log] [blame]
// 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,
"",
"",
&timestamp.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",
&timestamp.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)
}
}
}