build-tracker: deploy to MSP (#61510)

Bring it into [year 2024] 🎉 will be building on this as part of #60455 OKR, so having a more convenient deploy method would be cool

MSP PR: https://github.com/sourcegraph/managed-services/pull/1011

## Test plan

testing this live 👁️
This commit is contained in:
Noah S-C 2024-04-03 11:49:57 +01:00 committed by GitHub
parent e3891e9153
commit c3ec21e436
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 199 additions and 225 deletions

View File

@ -1,16 +1,27 @@
load("//dev:go_defs.bzl", "go_test")
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
load("//dev:oci_defs.bzl", "image_repository", "oci_image", "oci_push", "oci_tarball")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("@container_structure_test//:defs.bzl", "container_structure_test")
load("//dev:msp_delivery.bzl", "msp_delivery")
go_library(
name = "build-tracker_lib",
srcs = ["main.go"],
srcs = [
"background.go",
"main.go",
],
importpath = "github.com/sourcegraph/sourcegraph/dev/build-tracker",
visibility = ["//visibility:private"],
deps = [
"//dev/build-tracker/build",
"//dev/build-tracker/config",
"//dev/build-tracker/notify",
"//internal/goroutine",
"//internal/version",
"//lib/background",
"//lib/errors",
"//lib/managedservicesplatform/runtime",
"@com_github_gorilla_mux//:mux",
"@com_github_sourcegraph_log//:log",
],
@ -36,9 +47,59 @@ go_test(
"//dev/build-tracker/config",
"//dev/build-tracker/notify",
"//dev/team",
"//internal/goroutine",
"@com_github_buildkite_go_buildkite_v3//buildkite",
"@com_github_gorilla_mux//:mux",
"@com_github_sourcegraph_log//logtest",
"@com_github_stretchr_testify//require",
],
)
pkg_tar(
name = "tar_build-tracker",
srcs = [":build-tracker"],
)
oci_image(
name = "image",
base = "@wolfi_base",
entrypoint = [
"/sbin/tini",
"--",
"/build-tracker",
],
tars = [":tar_build-tracker"],
user = "sourcegraph",
)
oci_tarball(
name = "image_tarball",
image = ":image",
repo_tags = ["build-tracker:candidate"],
)
container_structure_test(
name = "image_test",
timeout = "short",
configs = ["image_test.yaml"],
driver = "docker",
image = ":image",
tags = [
"exclusive",
"requires-network",
],
)
oci_push(
name = "candidate_push",
image = ":image",
repository = image_repository("build-tracker"),
)
# automatic deployment not enabled for initial testing
# msp_delivery(
# name = "msp_deploy",
# gcp_project = "build-tracker-prod-59bf",
# msp_service_id = "build-tracker",
# repository = "us.gcr.io/sourcegraph-dev/build-tracker",
# )

View File

@ -1,17 +0,0 @@
FROM golang:1.19.8-alpine@sha256:841c160ed35923d96c95c52403c4e6db5decd9cbce034aa851e412ade5d4b74f AS build-tracker-build
ENV GO111MODULE on
ENV GOARCH amd64
ENV GOOS linux
COPY . /repo
WORKDIR /repo/dev/build-tracker
RUN go build -o /build-tracker .
FROM sourcegraph/alpine-3.14:213466_2023-04-17_5.0-bdda34a71619@sha256:6354a4ff578b685e36c8fbde81f62125ae0011b047fb2cc22d1b0de616b3c59a AS build-tracker
RUN apk --no-cache add tzdata
COPY --from=build-tracker-build /build-tracker /usr/local/bin/build-tracker
ENTRYPOINT ["build-tracker"]

View File

@ -0,0 +1,29 @@
package main
import (
"context"
"time"
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/dev/build-tracker/build"
"github.com/sourcegraph/sourcegraph/internal/goroutine"
)
func deleteOldBuilds(logger log.Logger, store *build.Store, every, window time.Duration) goroutine.BackgroundRoutine {
return goroutine.NewPeriodicGoroutine(context.Background(), goroutine.HandlerFunc(func(ctx context.Context) error {
oldBuilds := make([]int, 0)
now := time.Now()
for _, b := range store.FinishedBuilds() {
finishedAt := *b.FinishedAt
delta := now.Sub(finishedAt.Time)
if delta >= window {
logger.Debug("build past age window", log.Int("buildNumber", *b.Number), log.Time("FinishedAt", finishedAt.Time), log.Duration("window", window))
oldBuilds = append(oldBuilds, *b.Number)
}
}
logger.Info("deleting old builds", log.Int("oldBuildCount", len(oldBuilds)))
store.DelByBuildNumber(oldBuilds...)
return nil
}), goroutine.WithInterval(every))
}

View File

@ -1,13 +0,0 @@
#!/usr/bin/env bash
# This script builds the build-tracker docker image.
cd "$(dirname "${BASH_SOURCE[0]}")/../.."
set -eu
IMAGE="us-central1-docker.pkg.dev/sourcegraph-ci/build-tracker/build-tracker"
echo "--- docker build build-tracker $(pwd)"
docker build -f dev/build-tracker/Dockerfile -t "$IMAGE" "$(pwd)" \
#docker push $IMAGE

View File

@ -5,5 +5,5 @@ go_library(
srcs = ["config.go"],
importpath = "github.com/sourcegraph/sourcegraph/dev/build-tracker/config",
visibility = ["//visibility:public"],
deps = ["//lib/errors"],
deps = ["//lib/managedservicesplatform/runtime"],
)

View File

@ -1,82 +1,24 @@
package config
import (
"os"
"strconv"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
import "github.com/sourcegraph/sourcegraph/lib/managedservicesplatform/runtime"
const DefaultChannel = "#william-buildchecker-webhook-test"
type Config struct {
BuildkiteToken string
SlackToken string
GithubToken string
SlackChannel string
Production bool
DebugPassword string
}
func NewFromEnv() (*Config, error) {
var c Config
err := envVar("BUILDKITE_WEBHOOK_TOKEN", &c.BuildkiteToken)
if err != nil {
return nil, err
}
err = envVar("SLACK_TOKEN", &c.SlackToken)
if err != nil {
return nil, err
}
err = envVar("GITHUB_TOKEN", &c.GithubToken)
if err != nil {
return nil, err
}
err = envVar("SLACK_CHANNEL", &c.SlackChannel)
if err != nil {
c.SlackChannel = DefaultChannel
}
err = envVar("BUILDTRACKER_PRODUCTION", &c.Production)
if err != nil {
c.Production = false
}
func (c *Config) Load(env *runtime.Env) {
c.BuildkiteToken = env.Get("BUILDKITE_WEBHOOK_TOKEN", "", "")
c.SlackToken = env.Get("SLACK_TOKEN", "", "")
c.SlackChannel = env.Get("SLACK_CHANNEL", DefaultChannel, "")
c.Production = env.GetBool("BUILDTRACKER_PRODUCTION", "false", "")
if c.Production {
_ = envVar("BUILDTRACKER_DEBUG_PASSWORD", &c.DebugPassword)
if c.DebugPassword == "" {
return nil, errors.New("BUILDTRACKER_DEBUG_PASSWORD is required when BUILDTRACKER_PRODUCTION is true")
}
c.DebugPassword = env.Get("BUIDLTRACKER_DEBUG_PASSWORD", "", "")
}
return &c, nil
}
func envVar[T any](name string, target *T) error {
value, exists := os.LookupEnv(name)
if !exists {
return errors.Newf("%s not found in environment", name)
}
switch p := any(target).(type) {
case *bool:
{
v, err := strconv.ParseBool(value)
if err != nil {
return err
}
*p = v
}
case *string:
{
*p = value
}
default:
panic(errors.Newf("unsuporrted target type %T", target))
}
return nil
}

View File

@ -0,0 +1,15 @@
schemaVersion: "2.0.0"
commandTests:
- name: "binary is runnable"
command: "/build-tracker"
envVars:
- key: "SANITY_CHECK"
value: "true"
- name: "not running as root"
command: "/usr/bin/id"
args:
- -u
excludedOutput: ["^0"]
exitCode: 0

View File

@ -3,6 +3,7 @@ package main
import (
"flag"
"fmt"
"os"
"testing"
"github.com/buildkite/go-buildkite/v3/buildkite"
@ -15,8 +16,10 @@ import (
"github.com/sourcegraph/sourcegraph/dev/team"
)
var RunSlackIntegrationTest = flag.Bool("RunSlackIntegrationTest", false, "Run Slack integration tests")
var RunGitHubIntegrationTest = flag.Bool("RunGitHubIntegrationTest", false, "Run Github integration tests")
var (
RunSlackIntegrationTest = flag.Bool("RunSlackIntegrationTest", false, "Run Slack integration tests")
RunGitHubIntegrationTest = flag.Bool("RunGitHubIntegrationTest", false, "Run Github integration tests")
)
type TestJobLine struct {
title string
@ -78,14 +81,9 @@ func TestLargeAmountOfFailures(t *testing.T) {
}
logger := logtest.NoOp(t)
conf, err := config.NewFromEnv()
if err != nil {
t.Fatal(err)
}
client := notify.NewClient(logger, os.Getenv("SLACK_TOKEN"), config.DefaultChannel)
client := notify.NewClient(logger, conf.SlackToken, conf.GithubToken, config.DefaultChannel)
err = client.Send(info)
err := client.Send(info)
if err != nil {
t.Fatalf("failed to send build: %s", err)
}
@ -120,14 +118,9 @@ func TestGetTeammateFromBuild(t *testing.T) {
}
logger := logtest.NoOp(t)
conf, err := config.NewFromEnv()
if err != nil {
t.Fatal(err)
}
conf.SlackChannel = config.DefaultChannel
t.Run("with nil author, commit author is still retrieved", func(t *testing.T) {
client := notify.NewClient(logger, conf.SlackToken, conf.GithubToken, conf.SlackChannel)
client := notify.NewClient(logger, os.Getenv("SLACK_TOKEN"), config.DefaultChannel)
num := 160000
commit := "ca7c44f79984ff8d645b580bfaaf08ce9a37a05d"
@ -141,7 +134,7 @@ func TestGetTeammateFromBuild(t *testing.T) {
Number: &num,
Commit: &commit,
},
Pipeline: &build.Pipeline{buildkite.Pipeline{
Pipeline: &build.Pipeline{Pipeline: buildkite.Pipeline{
Name: &pipelineID,
}},
Steps: map[string]*build.Step{},
@ -153,7 +146,7 @@ func TestGetTeammateFromBuild(t *testing.T) {
require.Equal(t, teammate.Name, "Leo Papaloizos")
})
t.Run("commit author preferred over build author", func(t *testing.T) {
client := notify.NewClient(logger, conf.SlackToken, conf.GithubToken, conf.SlackChannel)
client := notify.NewClient(logger, os.Getenv("SLACK_TOKEN"), config.DefaultChannel)
num := 160000
commit := "78926a5b3b836a8a104a5d5adf891e5626b1e405"
@ -171,7 +164,7 @@ func TestGetTeammateFromBuild(t *testing.T) {
Email: "william.bezuidenhout@sourcegraph.com",
},
},
Pipeline: &build.Pipeline{buildkite.Pipeline{
Pipeline: &build.Pipeline{Pipeline: buildkite.Pipeline{
Name: &pipelineID,
}},
Steps: map[string]*build.Step{},
@ -182,7 +175,7 @@ func TestGetTeammateFromBuild(t *testing.T) {
require.Equal(t, teammate.Name, "Ryan Slade")
})
t.Run("retrieving teammate for build populates cache", func(t *testing.T) {
client := notify.NewClient(logger, conf.SlackToken, conf.GithubToken, conf.SlackChannel)
client := notify.NewClient(logger, os.Getenv("SLACK_TOKEN"), config.DefaultChannel)
num := 160000
commit := "78926a5b3b836a8a104a5d5adf891e5626b1e405"
@ -200,7 +193,7 @@ func TestGetTeammateFromBuild(t *testing.T) {
Email: "william.bezuidenhout@sourcegraph.com",
},
},
Pipeline: &build.Pipeline{buildkite.Pipeline{
Pipeline: &build.Pipeline{Pipeline: buildkite.Pipeline{
Name: &pipelineID,
}},
Steps: map[string]*build.Step{},
@ -219,12 +212,7 @@ func TestSlackNotification(t *testing.T) {
}
logger := logtest.NoOp(t)
conf, err := config.NewFromEnv()
if err != nil {
t.Fatal(err)
}
client := notify.NewClient(logger, conf.SlackToken, conf.GithubToken, config.DefaultChannel)
client := notify.NewClient(logger, os.Getenv("SLACK_TOKEN"), config.DefaultChannel)
// Each child test needs to increment this number, otherwise notifications will be overwritten
buildNumber := 160000
@ -442,12 +430,13 @@ func TestServerNotify(t *testing.T) {
}
logger := logtest.NoOp(t)
conf, err := config.NewFromEnv()
if err != nil {
t.Fatal(err)
conf := config.Config{
BuildkiteToken: os.Getenv("BUILDKITE_WEBHOOK_TOKEN"),
SlackToken: os.Getenv("SLACK_TOKEN"),
SlackChannel: os.Getenv("SLACK_CHANNEL"),
}
server := NewServer(logger, *conf)
server := NewServer(":8080", logger, conf)
num := 160000
url := "http://www.google.com"
@ -474,7 +463,7 @@ func TestServerNotify(t *testing.T) {
URL: &url,
Commit: &commit,
},
Pipeline: &build.Pipeline{buildkite.Pipeline{
Pipeline: &build.Pipeline{Pipeline: buildkite.Pipeline{
Name: &pipelineID,
}},
Steps: map[string]*build.Step{
@ -483,7 +472,7 @@ func TestServerNotify(t *testing.T) {
}
// post a new notification
err = server.notifyIfFailed(build)
err := server.notifyIfFailed(build)
if err != nil {
t.Fatalf("failed to send slack notification: %v", err)
}

View File

@ -1,7 +1,9 @@
package main
import (
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"strconv"
@ -14,12 +16,17 @@ import (
"github.com/sourcegraph/sourcegraph/dev/build-tracker/build"
"github.com/sourcegraph/sourcegraph/dev/build-tracker/config"
"github.com/sourcegraph/sourcegraph/dev/build-tracker/notify"
"github.com/sourcegraph/sourcegraph/internal/version"
"github.com/sourcegraph/sourcegraph/lib/background"
"github.com/sourcegraph/sourcegraph/lib/errors"
"github.com/sourcegraph/sourcegraph/lib/managedservicesplatform/runtime"
)
var ErrInvalidToken = errors.New("buildkite token is invalid")
var ErrInvalidHeader = errors.New("Header of request is invalid")
var ErrUnwantedEvent = errors.New("Unwanted event received")
var (
ErrInvalidToken = errors.New("buildkite token is invalid")
ErrInvalidHeader = errors.New("Header of request is invalid")
ErrUnwantedEvent = errors.New("Unwanted event received")
)
var nowFunc = time.Now
@ -41,13 +48,13 @@ type Server struct {
}
// NewServer creatse a new server to listen for Buildkite webhook events.
func NewServer(logger log.Logger, c config.Config) *Server {
func NewServer(addr string, logger log.Logger, c config.Config) *Server {
logger = logger.Scoped("server")
server := &Server{
logger: logger,
store: build.NewBuildStore(logger),
config: &c,
notifyClient: notify.NewClient(logger, c.SlackToken, c.GithubToken, c.SlackChannel),
notifyClient: notify.NewClient(logger, c.SlackToken, c.SlackChannel),
}
// Register routes the the server will be responding too
@ -60,12 +67,28 @@ func NewServer(logger log.Logger, c config.Config) *Server {
server.http = &http.Server{
Handler: r,
Addr: ":8080",
Addr: addr,
}
return server
}
func (s *Server) Start() {
if err := s.http.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
s.logger.Error("error stopping server", log.Error(err))
}
}
func (s *Server) Stop() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := s.http.Shutdown(ctx); err != nil {
s.logger.Error("error shutting down server", log.Error(err))
} else {
s.logger.Info("server stopped")
}
}
func (s *Server) handleGetBuild(w http.ResponseWriter, req *http.Request) {
if s.config.Production {
user, pass, ok := req.BasicAuth()
@ -192,40 +215,6 @@ func (s *Server) notifyIfFailed(b *build.Build) error {
return nil
}
func (s *Server) deleteOldBuilds(window time.Duration) {
oldBuilds := make([]int, 0)
now := nowFunc()
for _, b := range s.store.FinishedBuilds() {
finishedAt := *b.FinishedAt
delta := now.Sub(finishedAt.Time)
if delta >= window {
s.logger.Debug("build past age window", log.Int("buildNumber", *b.Number), log.Time("FinishedAt", finishedAt.Time), log.Duration("window", window))
oldBuilds = append(oldBuilds, *b.Number)
}
}
s.logger.Info("deleting old builds", log.Int("oldBuildCount", len(oldBuilds)))
s.store.DelByBuildNumber(oldBuilds...)
}
func (s *Server) startCleaner(every, window time.Duration) func() {
ticker := time.NewTicker(every)
done := make(chan interface{})
go func() {
for {
select {
case <-ticker.C:
s.deleteOldBuilds(window)
case <-done:
ticker.Stop()
return
}
}
}()
return func() { done <- nil }
}
// processEvent processes a BuildEvent received from Buildkite. If the event is for a `build.finished` event we get the
// full build which includes all recorded jobs for the build and send a notification.
// processEvent delegates the decision to actually send a notifcation
@ -285,33 +274,21 @@ func determineBuildStatusNotification(logger log.Logger, b *build.Build) *notify
return &info
}
// Serve starts the http server and listens for buildkite build events to be sent on the route "/buildkite"
func main() {
sync := log.Init(log.Resource{
Name: "BuildTracker",
Namespace: "CI",
})
defer sync.Sync()
logger := log.Scoped("BuildTracker")
serverConf, err := config.NewFromEnv()
if err != nil {
logger.Fatal("failed to get config from env", log.Error(err))
}
logger.Info("config loaded from environment", log.Object("config", log.String("SlackChannel", serverConf.SlackChannel), log.Bool("Production", serverConf.Production)))
server := NewServer(logger, *serverConf)
stopFn := server.startCleaner(CleanUpInterval, BuildExpiryWindow)
defer stopFn()
if server.config.Production {
server.logger.Info("server is in production mode!")
} else {
server.logger.Info("server is in development mode!")
}
if err := server.http.ListenAndServe(); err != nil {
logger.Fatal("server exited with error", log.Error(err))
}
runtime.Start[config.Config](Service{})
}
type Service struct{}
// Initialize implements runtime.Service.
func (s Service) Initialize(ctx context.Context, logger log.Logger, contract runtime.Contract, config config.Config) (background.Routine, error) {
logger.Info("config loaded from environment", log.Object("config", log.String("SlackChannel", config.SlackChannel), log.Bool("Production", config.Production)))
return background.CombinedRoutine{
NewServer(fmt.Sprintf(":%d", contract.Port), logger, config),
deleteOldBuilds(logger, nil, CleanUpInterval, BuildExpiryWindow),
}, nil
}
func (s Service) Name() string { return "build-tracker" }
func (s Service) Version() string { return version.Version() }

View File

@ -18,18 +18,6 @@ import (
const StepShowLimit = 5
type cacheItem[T any] struct {
Value T
Timestamp time.Time
}
func newCacheItem[T any](value T) *cacheItem[T] {
return &cacheItem[T]{
Value: value,
Timestamp: time.Now(),
}
}
type NotificationClient interface {
Send(info *BuildNotification) error
GetNotification(buildNumber int) *SlackNotification
@ -101,7 +89,7 @@ func NewSlackNotification(id, channel string, info *BuildNotification, author st
}
}
func NewClient(logger log.Logger, slackToken, githubToken, channel string) *Client {
func NewClient(logger log.Logger, slackToken, channel string) *Client {
debug := os.Getenv("BUILD_TRACKER_SLACK_DEBUG") == "1"
slackClient := slack.New(slackToken, slack.OptionDebug(debug))

View File

@ -1,6 +1,7 @@
package main
import (
"context"
"encoding/json"
"net/http"
"net/http/httptest"
@ -15,6 +16,7 @@ import (
"github.com/sourcegraph/sourcegraph/dev/build-tracker/build"
"github.com/sourcegraph/sourcegraph/dev/build-tracker/config"
"github.com/sourcegraph/sourcegraph/dev/build-tracker/notify"
"github.com/sourcegraph/sourcegraph/internal/goroutine"
)
func TestGetBuild(t *testing.T) {
@ -23,7 +25,7 @@ func TestGetBuild(t *testing.T) {
req, _ := http.NewRequest(http.MethodGet, "/-/debug/1234", nil)
req = mux.SetURLVars(req, map[string]string{"buildNumber": "1234"})
t.Run("401 Unauthorized when in production mode and incorrect credentials", func(t *testing.T) {
server := NewServer(logger, config.Config{Production: true, DebugPassword: "this is a test"})
server := NewServer(":8080", logger, config.Config{Production: true, DebugPassword: "this is a test"})
rec := httptest.NewRecorder()
server.handleGetBuild(rec, req)
@ -36,7 +38,7 @@ func TestGetBuild(t *testing.T) {
})
t.Run("404 for build that does not exist", func(t *testing.T) {
server := NewServer(logger, config.Config{})
server := NewServer(":8080", logger, config.Config{})
rec := httptest.NewRecorder()
server.handleGetBuild(rec, req)
@ -44,7 +46,7 @@ func TestGetBuild(t *testing.T) {
})
t.Run("get marshalled json for build", func(t *testing.T) {
server := NewServer(logger, config.Config{})
server := NewServer(":8080", logger, config.Config{})
rec := httptest.NewRecorder()
num := 1234
@ -97,7 +99,7 @@ func TestGetBuild(t *testing.T) {
})
t.Run("200 with valid credentials in production mode", func(t *testing.T) {
server := NewServer(logger, config.Config{Production: true, DebugPassword: "this is a test"})
server := NewServer(":8080", logger, config.Config{Production: true, DebugPassword: "this is a test"})
rec := httptest.NewRecorder()
req.SetBasicAuth("devx", server.config.DebugPassword)
@ -129,7 +131,7 @@ func TestOldBuildsGetDeleted(t *testing.T) {
}
t.Run("All old builds get removed", func(t *testing.T) {
server := NewServer(logger, config.Config{})
server := NewServer(":8080", logger, config.Config{})
b := finishedBuild(1, "passed", time.Now().AddDate(-1, 0, 0))
server.store.Set(b)
@ -139,9 +141,10 @@ func TestOldBuildsGetDeleted(t *testing.T) {
b = finishedBuild(3, "failed", time.Now().AddDate(0, 0, -1))
server.store.Set(b)
stopFunc := server.startCleaner(10*time.Millisecond, 24*time.Hour)
ctx, cancel := context.WithCancel(context.Background())
go goroutine.MonitorBackgroundRoutines(ctx, deleteOldBuilds(logger, server.store, 10*time.Millisecond, 24*time.Hour))
time.Sleep(20 * time.Millisecond)
stopFunc()
cancel()
builds := server.store.FinishedBuilds()
@ -150,7 +153,7 @@ func TestOldBuildsGetDeleted(t *testing.T) {
}
})
t.Run("1 build left after old builds are removed", func(t *testing.T) {
server := NewServer(logger, config.Config{})
server := NewServer(":8080", logger, config.Config{})
b := finishedBuild(1, "canceled", time.Now().AddDate(-1, 0, 0))
server.store.Set(b)
@ -160,9 +163,10 @@ func TestOldBuildsGetDeleted(t *testing.T) {
b = finishedBuild(3, "failed", time.Now())
server.store.Set(b)
stopFunc := server.startCleaner(10*time.Millisecond, 24*time.Hour)
ctx, cancel := context.WithCancel(context.Background())
go goroutine.MonitorBackgroundRoutines(ctx, deleteOldBuilds(logger, server.store, 10*time.Millisecond, 24*time.Hour))
time.Sleep(20 * time.Millisecond)
stopFunc()
cancel()
builds := server.store.FinishedBuilds()
@ -170,7 +174,6 @@ func TestOldBuildsGetDeleted(t *testing.T) {
t.Errorf("Expected one build to be left over. Got %d, wanted %d", len(builds), 1)
}
})
}
type MockNotificationClient struct {
@ -231,7 +234,7 @@ func TestProcessEvent(t *testing.T) {
return &build.Event{Name: build.EventBuildFinished, Build: buildkite.Build{State: &state, Number: &buildNumber, Pipeline: pipeline}, Job: job.Job}
}
t.Run("no send notification on unfinished builds", func(t *testing.T) {
server := NewServer(logger, config.Config{})
server := NewServer(":8080", logger, config.Config{})
mockNotifyClient := &MockNotificationClient{}
server.notifyClient = mockNotifyClient
buildNumber := 1234
@ -248,7 +251,7 @@ func TestProcessEvent(t *testing.T) {
})
t.Run("failed build sends notification", func(t *testing.T) {
server := NewServer(logger, config.Config{})
server := NewServer(":8080", logger, config.Config{})
mockNotifyClient := &MockNotificationClient{}
server.notifyClient = mockNotifyClient
buildNumber := 1234
@ -264,7 +267,7 @@ func TestProcessEvent(t *testing.T) {
})
t.Run("passed build sends notification", func(t *testing.T) {
server := NewServer(logger, config.Config{})
server := NewServer(":8080", logger, config.Config{})
mockNotifyClient := &MockNotificationClient{}
server.notifyClient = mockNotifyClient
buildNumber := 1234
@ -280,7 +283,7 @@ func TestProcessEvent(t *testing.T) {
})
t.Run("failed build, then passed build sends fixed notification", func(t *testing.T) {
server := NewServer(logger, config.Config{})
server := NewServer(":8080", logger, config.Config{})
mockNotifyClient := &MockNotificationClient{}
server.notifyClient = mockNotifyClient
buildNumber := 1234