From 835abe44b095e9313de734f8da470015e946669b Mon Sep 17 00:00:00 2001 From: Yoshiyuki Watanabe <32473622+yoshwata@users.noreply.github.com> Date: Fri, 16 Sep 2022 04:54:18 +0900 Subject: [PATCH] fix(2754): Update build status if SIGTERM is received (#441) --- executor/executor.go | 7 +- launch.go | 76 ++++++++------- launch_test.go | 216 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 236 insertions(+), 63 deletions(-) diff --git a/executor/executor.go b/executor/executor.go index 20008d0..fa19844 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -357,7 +357,7 @@ func Run(path string, env []string, emitter screwdriver.Emitter, build screwdriv code = 3 } _ = c.Process.Signal(syscall.SIGABRT) - terminateSleep(shellBin, sourceDir, true) // kill all running sleep + TerminateSleep(shellBin, sourceDir, true) // kill all running sleep case stepAbort := <-sig: f.Write([]byte{4}) @@ -366,7 +366,7 @@ func Run(path string, env []string, emitter screwdriver.Emitter, build screwdriv code = 1 } _ = c.Process.Signal(syscall.SIGABRT) - terminateSleep(shellBin, sourceDir, false) // kill all running sleep other than sleep $SD_TERMINATION_GRACE_PERIOD_SECS + TerminateSleep(shellBin, sourceDir, false) // kill all running sleep other than sleep $SD_TERMINATION_GRACE_PERIOD_SECS } if err := api.UpdateStepStop(buildID, cmd.Name, code); err != nil { @@ -402,12 +402,11 @@ func Run(path string, env []string, emitter screwdriver.Emitter, build screwdriv firstError = cmdErr } } - terminateSleep(shellBin, sourceDir, true) // kill running sleep $SD_TERMINATION_GRACE_PERIOD_SECS return firstError } // terminate long running sleep process for abort, timeout, n after teardown steps -func terminateSleep(shellBin, sourceDir string, killAll bool) { +func TerminateSleep(shellBin, sourceDir string, killAll bool) { var stdout, stderr bytes.Buffer shargs := []string{"-e", "-c"} cmdStr := "pids=$(ps -ef | grep '[s]leep' | awk '{print $2}'); pidcnt=$(echo $pids | wc -w); if [ $pidcnt -gt 1 ]; then kill $(echo $pids | awk '{$NF=\"\"}1'); else echo $pids; fi;" diff --git a/launch.go b/launch.go index 8fd835a..7297585 100644 --- a/launch.go +++ b/launch.go @@ -39,6 +39,7 @@ var mkdirAll = os.MkdirAll var stat = os.Stat var open = os.Open var executorRun = executor.Run +var TerminateSleep = executor.TerminateSleep var writeFile = ioutil.WriteFile var readFile = ioutil.ReadFile var newEmitter = screwdriver.NewEmitter @@ -171,8 +172,8 @@ sd_build_setup_time_secs{image_name="` + image + `",pipeline_id="` + pipelineId return nil } -// exit sets the build status and exits successfully -func exit(status screwdriver.BuildStatus, buildID int, api screwdriver.API, metaSpace string, statusMessage string) { +// prepareExit sets the build status before exit +func prepareExit(status screwdriver.BuildStatus, buildID int, api screwdriver.API, metaSpace string, statusMessage string) { _ = pushMetrics(status.String(), buildID) if api != nil { var metaInterface map[string]interface{} @@ -194,7 +195,6 @@ func exit(status screwdriver.BuildStatus, buildID int, api screwdriver.API, meta log.Printf("Failed updating the build status: %v", err) } } - cleanExit() } // e.g. scmUri: "github:123456:master", scmName: "screwdriver-cd/launcher" @@ -386,29 +386,29 @@ func convertToArray(i interface{}) (array []int) { } } -func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, storeURL, uiURL, shellBin string, buildTimeout int, buildToken, cacheStrategy, pipelineCacheDir, jobCacheDir, eventCacheDir string, cacheCompress, cacheMd5Check, isLocal bool, cacheMaxSizeInMB int64, cacheMaxGoThreads int64) error { +func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, storeURL, uiURL, shellBin string, buildTimeout int, buildToken, cacheStrategy, pipelineCacheDir, jobCacheDir, eventCacheDir string, cacheCompress, cacheMd5Check, isLocal bool, cacheMaxSizeInMB int64, cacheMaxGoThreads int64) (error, string, string) { var err error emitter, err = newEmitter(emitterPath) envFilepath := "/tmp/env" if err != nil { - return err + return err, "", "" } defer emitter.Close() if err = api.UpdateStepStart(buildID, "sd-setup-launcher"); err != nil { - return fmt.Errorf("Updating sd-setup-launcher start: %v", err) + return fmt.Errorf("Updating sd-setup-launcher start: %v", err), "", "" } log.Print("Setting Build Status to RUNNING") emptyMeta := make(map[string]interface{}) // {"meta":null} are not accepted. This will be {"meta":{}} if err = api.UpdateBuildStatus(screwdriver.Running, emptyMeta, buildID, ""); err != nil { - return fmt.Errorf("Updating build status to RUNNING: %v", err) + return fmt.Errorf("Updating build status to RUNNING: %v", err), "", "" } log.Printf("Fetching Build %d", buildID) build, err := api.BuildFromID(buildID) if err != nil { - return fmt.Errorf("Fetching Build ID %d: %v", buildID, err) + return fmt.Errorf("Fetching Build ID %d: %v", buildID, err), "", "" } buildCreateTime, _ = time.Parse(time.RFC3339, build.Createtime) @@ -417,19 +417,19 @@ func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, s log.Printf("Fetching Job %d", build.JobID) job, err := api.JobFromID(build.JobID) if err != nil { - return fmt.Errorf("Fetching Job ID %d: %v", build.JobID, err) + return fmt.Errorf("Fetching Job ID %d: %v", build.JobID, err), "", "" } log.Printf("Fetching Pipeline %d", job.PipelineID) pipeline, err := api.PipelineFromID(job.PipelineID) if err != nil { - return fmt.Errorf("Fetching Pipeline ID %d: %v", job.PipelineID, err) + return fmt.Errorf("Fetching Pipeline ID %d: %v", job.PipelineID, err), "", "" } log.Printf("Fetching Event %d", build.EventID) event, err := api.EventFromID(build.EventID) if err != nil { - return fmt.Errorf("Fetching Event ID %d: %v", build.EventID, err) + return fmt.Errorf("Fetching Event ID %d: %v", build.EventID, err), "", "" } metaByte := []byte("") @@ -456,7 +456,7 @@ func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, s // Create meta space err = createMetaSpace(metaSpace) if err != nil { - return err + return err, "", "" } // Always merge event meta @@ -472,7 +472,7 @@ func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, s for _, pbID := range parentBuildIDs { mergedMeta, err = SetExternalMeta(api, pipeline.ID, pbID, mergedMeta, metaSpace, metaLog, true) if err != nil { - return fmt.Errorf("Setting meta for Parent Build ID %d: %v", pbID, err) + return fmt.Errorf("Setting meta for Parent Build ID %d: %v", pbID, err), "", "" } } @@ -480,7 +480,7 @@ func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, s } else if len(parentBuildIDs) == 1 { // If has parent build, fetch from parent build mergedMeta, err = SetExternalMeta(api, pipeline.ID, parentBuildIDs[0], mergedMeta, metaSpace, metaLog, false) if err != nil { - return fmt.Errorf("Setting meta for Parent Build ID %d: %v", parentBuildIDs[0], err) + return fmt.Errorf("Setting meta for Parent Build ID %d: %v", parentBuildIDs[0], err), "", "" } metaLog = fmt.Sprintf(`Build(%v)`, parentBuildIDs[0]) @@ -488,7 +488,7 @@ func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, s log.Printf("Fetching Parent Event %d", event.ParentEventID) parentEvent, err := api.EventFromID(event.ParentEventID) if err != nil { - return fmt.Errorf("Fetching Parent Event ID %d: %v", event.ParentEventID, err) + return fmt.Errorf("Fetching Parent Event ID %d: %v", event.ParentEventID, err), "", "" } if parentEvent.Meta != nil { @@ -531,23 +531,23 @@ func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, s metaByte, err = marshal(mergedMeta) if err != nil { - return fmt.Errorf("Parsing Meta JSON: %v", err) + return fmt.Errorf("Parsing Meta JSON: %v", err), "", "" } err = writeFile(metaSpace+"/"+metaFile, metaByte, 0666) if err != nil { - return fmt.Errorf("Writing Parent %v Meta JSON: %v", metaLog, err) + return fmt.Errorf("Writing Parent %v Meta JSON: %v", metaLog, err), "", "" } scm, err := parseScmURI(pipeline.ScmURI, pipeline.ScmRepo.Name) if err != nil { - return err + return err, "", "" } log.Printf("Creating Workspace in %v", rootDir) w, err := createWorkspace(isLocal, rootDir, scm.Host, scm.Org, scm.Repo) if err != nil { - return err + return err, "", "" } sourceDir := w.Src if scm.RootDir != "" { @@ -580,12 +580,12 @@ func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, s err = writeArtifact(w.Artifacts, "steps.json", build.Commands) if err != nil { - return fmt.Errorf("Creating steps.json artifact: %v", err) + return fmt.Errorf("Creating steps.json artifact: %v", err), "", "" } err = writeArtifact(w.Artifacts, "environment.json", build.Environment) if err != nil { - return fmt.Errorf("Creating environment.json artifact: %v", err) + return fmt.Errorf("Creating environment.json artifact: %v", err), "", "" } apiURL, _ := api.GetAPIURL() @@ -647,7 +647,7 @@ func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, s // Get secrets for build secrets, err := api.SecretsForBuild(build) if err != nil { - return fmt.Errorf("Fetching secrets for build %v", build.ID) + return fmt.Errorf("Fetching secrets for build %v", build.ID), "", "" } env, userShellBin := createEnvironment(defaultEnv, secrets, build) @@ -655,7 +655,7 @@ func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, s shellBin = userShellBin } - return executorRun(w.Src, env, emitter, build, api, buildID, shellBin, buildTimeout, envFilepath, sourceDir) + return executorRun(w.Src, env, emitter, build, api, buildID, shellBin, buildTimeout, envFilepath, sourceDir), sourceDir, shellBin } func createEnvironment(base map[string]string, secrets screwdriver.Secrets, build screwdriver.Build) ([]string, string) { @@ -709,18 +709,22 @@ func launchAction(api screwdriver.API, buildID int, rootDir, emitterPath, metaSp log.Printf("Starting Build %v\n", buildID) log.Printf("Cache strategy & directories (pipeline, job, event), compress, md5check, maxsize: %v, %v, %v, %v, %v, %v, %v \n", cacheStrategy, pipelineCacheDir, jobCacheDir, eventCacheDir, cacheCompress, cacheMd5Check, cacheMaxSizeInMB) - if err := launch(api, buildID, rootDir, emitterPath, metaSpace, storeURI, uiURI, shellBin, buildTimeout, buildToken, cacheStrategy, pipelineCacheDir, jobCacheDir, eventCacheDir, cacheCompress, cacheMd5Check, isLocal, cacheMaxSizeInMB, cacheMaxGoThreads); err != nil { + err, sourceDir, launchShellBin := launch(api, buildID, rootDir, emitterPath, metaSpace, storeURI, uiURI, shellBin, buildTimeout, buildToken, cacheStrategy, pipelineCacheDir, jobCacheDir, eventCacheDir, cacheCompress, cacheMd5Check, isLocal, cacheMaxSizeInMB, cacheMaxGoThreads) + if err != nil { if _, ok := err.(executor.ErrStatus); ok { log.Printf("Failure due to non-zero exit code: %v\n", err) } else { log.Printf("Error running launcher: %v\n", err) } - exit(screwdriver.Failure, buildID, api, metaSpace, "") + prepareExit(screwdriver.Failure, buildID, api, metaSpace, "") + TerminateSleep(sourceDir, launchShellBin, true) + cleanExit() return nil } - exit(screwdriver.Success, buildID, api, metaSpace, "") + prepareExit(screwdriver.Success, buildID, api, metaSpace, "") + cleanExit() return nil } @@ -737,7 +741,8 @@ func recoverPanic(buildID int, api screwdriver.API, metaSpace string) { log.Printf("ERROR: Unable to write stacktrace to file: %v", err) } - exit(screwdriver.Failure, buildID, api, metaSpace, "") + prepareExit(screwdriver.Failure, buildID, api, metaSpace, "") + cleanExit() } } @@ -913,9 +918,10 @@ func main() { temporalAPI, err := screwdriver.New(apiURL, token) if err != nil { log.Printf("Error creating temporal Screwdriver API %v: %v", buildID, err) - exit(screwdriver.Failure, buildID, nil, metaSpace, "") + prepareExit(screwdriver.Failure, buildID, nil, metaSpace, "") + cleanExit() } - exit(screwdriver.Failure, buildID, temporalAPI, metaSpace, "Error: Build failed to start. Please check if your image is valid with curl, openssh installed and default user root or sudo NOPASSWD enabled.") + prepareExit(screwdriver.Failure, buildID, temporalAPI, metaSpace, "Error: Build failed to start. Please check if your image is valid with curl, openssh installed and default user root or sudo NOPASSWD enabled.") cleanExit() } @@ -923,13 +929,15 @@ func main() { temporalAPI, err := screwdriver.New(apiURL, token) if err != nil { log.Printf("Error creating temporal Screwdriver API %v: %v", buildID, err) - exit(screwdriver.Failure, buildID, nil, metaSpace, "") + prepareExit(screwdriver.Failure, buildID, nil, metaSpace, "") + cleanExit() } buildToken, err := temporalAPI.GetBuildToken(buildID, c.Int("build-timeout")) if err != nil { log.Printf("Error getting Build Token %v: %v", buildID, err) - exit(screwdriver.Failure, buildID, nil, metaSpace, "") + prepareExit(screwdriver.Failure, buildID, nil, metaSpace, "") + cleanExit() } log.Printf("Launcher process only fetch token.") @@ -957,7 +965,8 @@ func main() { if err != nil { log.Printf("Error creating Screwdriver API %v: %v", buildID, err) - exit(screwdriver.Failure, buildID, nil, metaSpace, "") + prepareExit(screwdriver.Failure, buildID, nil, metaSpace, "") + cleanExit() } defer recoverPanic(buildID, api, metaSpace) @@ -966,7 +975,8 @@ func main() { // This should never happen... log.Println("Unexpected return in launcher. Failing the build.") - exit(screwdriver.Failure, buildID, api, metaSpace, "") + prepareExit(screwdriver.Failure, buildID, api, metaSpace, "") + cleanExit() return nil } app.Run(os.Args) diff --git a/launch_test.go b/launch_test.go index d77acc3..bc771b7 100644 --- a/launch_test.go +++ b/launch_test.go @@ -281,7 +281,20 @@ func TestMain(m *testing.M) { func TestBuildJobPipelineFromID(t *testing.T) { testPipelineID := 9999 api := mockAPI(t, TestBuildID, TestJobID, testPipelineID, "RUNNING") - launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + if err != nil { + t.Errorf("err should be nil") + } + + expectSourceDir := "/sd/workspace/src/github.com/screwdriver-cd/launcher" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "/bin/sh" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } } func TestBuildFromIdError(t *testing.T) { @@ -292,11 +305,21 @@ func TestBuildFromIdError(t *testing.T) { }, } - err := launch(screwdriver.API(api), 0, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), 0, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) if err == nil { t.Errorf("err should not be nil") } + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } + expected := `Fetching Build ID 0` if !strings.Contains(err.Error(), expected) { t.Errorf("err == %q, want %q", err, expected) @@ -311,11 +334,21 @@ func TestEventFromIdError(t *testing.T) { }, } - err := launch(screwdriver.API(api), 0, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), 0, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) if err == nil { t.Errorf("err should not be nil") } + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } + expected := `Fetching Event ID 0` if !strings.Contains(err.Error(), expected) { t.Errorf("err == %q, want %q", err, expected) @@ -329,11 +362,21 @@ func TestJobFromIdError(t *testing.T) { return screwdriver.Job(FakeJob{}), err } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) if err == nil { t.Errorf("err should not be nil") } + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } + expected := fmt.Sprintf(`Fetching Job ID %d`, TestJobID) if !strings.Contains(err.Error(), expected) { t.Errorf("err == %q, want %q", err, expected) @@ -348,11 +391,21 @@ func TestPipelineFromIdError(t *testing.T) { return screwdriver.Pipeline(FakePipeline{}), err } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) if err == nil { t.Fatalf("err should not be nil") } + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } + expected := fmt.Sprintf(`Fetching Pipeline ID %d`, testPipelineID) if !strings.Contains(err.Error(), expected) { t.Errorf("err == %q, want %q", err, expected) @@ -454,11 +507,21 @@ func TestCreateWorkspaceError(t *testing.T) { return nil } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) if err.Error() != "Cannot create meta-space path \"./data/meta\": Spooky error" { t.Errorf("Error is wrong, got %v", err) } + + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } } func TestCreateWorkspaceBadStat(t *testing.T) { @@ -513,12 +576,22 @@ func TestUpdateBuildStatusError(t *testing.T) { return fmt.Errorf("Spooky error") } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) want := "Updating build status to RUNNING: Spooky error" if err.Error() != want { t.Errorf("Error is wrong. got %v, want %v", err, want) } + + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } } func TestUpdateBuildStatusSuccess(t *testing.T) { @@ -820,7 +893,7 @@ func TestSetEnv(t *testing.T) { return nil } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) if err != nil { t.Fatalf("Unexpected error from launch: %v", err) } @@ -830,12 +903,22 @@ func TestSetEnv(t *testing.T) { } } + expectSourceDir := "/sd/workspace/src/github.com/screwdriver-cd/launcher" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "/bin/sh" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } + // in case of no coverage plugins delete(tests, "SD_SONAR_AUTH_URL") delete(tests, "SD_SONAR_HOST") TestEnvVars = map[string]interface{}{} foundEnv = map[string]string{} - err = launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin = launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) if err != nil { t.Fatalf("Unexpected error from launch: %v", err) } @@ -850,12 +933,24 @@ func TestSetEnv(t *testing.T) { return screwdriver.Pipeline(FakePipeline{ID: pipelineID, ScmURI: TestScmURI + ":lib", ScmRepo: TestScmRepo}), nil } tests["SD_SOURCE_DIR"] = tests["SD_SOURCE_DIR"] + "/lib" + tempShellBin := "/bin/bash" TestEnvVars = map[string]interface{}{} foundEnv = map[string]string{} - err = launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin = launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, tempShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) if err != nil { t.Fatalf("Unexpected error from launch: %v", err) } + + expectSourceDir = "/sd/workspace/src/github.com/screwdriver-cd/launcher/lib" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin = "/bin/bash" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } + for k, v := range tests { if foundEnv[k] != v { t.Fatalf("foundEnv[%s] = %s, want %s", k, foundEnv[k], v) @@ -873,10 +968,19 @@ func TestSetEnv(t *testing.T) { tests["SD_PRIVATE_PIPELINE"] = "true" TestEnvVars = map[string]interface{}{} foundEnv = map[string]string{} - err = launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, _, _ = launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) if err != nil { t.Fatalf("Unexpected error from launch: %v", err) } + + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } + for k, v := range tests { if foundEnv[k] != v { t.Fatalf("foundEnv[%s] = %s, want %s", k, foundEnv[k], v) @@ -921,7 +1025,7 @@ func TestEnvSecrets(t *testing.T) { return nil } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, _, _ := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) if err != nil { t.Fatalf("Unexpected error from launch: %v", err) } @@ -1036,7 +1140,7 @@ func TestFetchDefaultMeta(t *testing.T) { return nil } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, _, _ := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) want := []byte("{\"build\":{\"buildId\":\"1234\",\"coverageKey\":\"job:fake\",\"eventId\":\"0\",\"jobId\":\"2345\",\"jobName\":\"main\",\"pipelineId\":\"3456\",\"sha\":\"\"}}") if err != nil || string(defaultMeta) != string(want) { @@ -1060,12 +1164,22 @@ func TestFetchParentBuildsMetaParseError(t *testing.T) { return nil, fmt.Errorf("Testing parsing parent builds meta") } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) expected := fmt.Sprint("Parsing Meta JSON: Testing parsing parent builds meta") if err.Error() != expected { t.Errorf("Error is wrong, got '%v', expected '%v'", err, expected) } + + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } } func TestFetchParentEventMetaParseError(t *testing.T) { @@ -1083,12 +1197,22 @@ func TestFetchParentEventMetaParseError(t *testing.T) { return nil, fmt.Errorf("Testing parsing parent event meta") } - err := launch(screwdriver.API(api), TestEventID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestEventID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) expected := fmt.Sprint("Parsing Meta JSON: Testing parsing parent event meta") if err.Error() != expected { t.Errorf("Error is wrong, got '%v', expected '%v'", err, expected) } + + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } } func TestFetchParentBuildMetaParseError(t *testing.T) { @@ -1118,12 +1242,22 @@ func TestFetchParentBuildMetaParseError(t *testing.T) { return nil, fmt.Errorf("Testing parsing parent build meta") } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) expected := fmt.Sprint("Parsing Meta JSON: Testing parsing parent build meta") if err.Error() != expected { t.Errorf("Error is wrong, got '%v', expected '%v'", err, expected) } + + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } } func TestFetchParentBuildMetaWriteError(t *testing.T) { @@ -1153,12 +1287,22 @@ func TestFetchParentBuildMetaWriteError(t *testing.T) { return fmt.Errorf("Testing writing parent build meta") } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) expected := fmt.Sprintf(`Writing Parent Build(%d) Meta JSON: Testing writing parent build meta`, TestParentBuildID) if err.Error() != expected { t.Errorf("Error is wrong, got '%v', expected '%v'", err, expected) } + + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } } func TestFetchParentBuildsMeta(t *testing.T) { @@ -1234,7 +1378,7 @@ func TestFetchParentBuildsMeta(t *testing.T) { return nil } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, _, _ := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) want := []byte("{\"batman\":\"robin\",\"build\":{\"buildId\":\"1234\",\"coverageKey\":\"job:fake\",\"eventId\":\"0\",\"jobId\":\"2345\",\"jobName\":\"main\",\"pipelineId\":\"3456\",\"sha\":\"\"},\"foo\":{\"bird\":\"twitter\",\"cat\":\"meow\",\"dog\":\"woof\"},\"wonder\":\"woman\"}") wantParent := []byte("{\"batman\":\"robin\",\"foo\":{\"bird\":\"chirp\",\"cat\":\"meow\"}}") @@ -1308,12 +1452,22 @@ func TestFetchParentEventMetaWriteError(t *testing.T) { return fmt.Errorf("Testing writing parent event meta") } - err := launch(screwdriver.API(api), TestEventID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestEventID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) expected := fmt.Sprintf(`Writing Parent Event(%d) Meta JSON: Testing writing parent event meta`, TestParentEventID) if err.Error() != expected { t.Errorf("Error is wrong, got '%v', expected '%v'", err, expected) } + + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } } func TestFetchEventMetaMarshalError(t *testing.T) { @@ -1334,12 +1488,22 @@ func TestFetchEventMetaMarshalError(t *testing.T) { return nil, fmt.Errorf("Testing parsing event meta") } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, sourceDir, shellBin := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) expected := fmt.Sprint("Parsing Meta JSON: Testing parsing event meta") if err.Error() != expected { t.Errorf("Error is wrong, got '%v', expected '%v'", err, expected) } + + expectSourceDir := "" + if sourceDir != expectSourceDir { + t.Errorf("sourceDir == %s, want %s", sourceDir, expectSourceDir) + } + + expectShellBin := "" + if shellBin != expectShellBin { + t.Errorf("shellBin == %s, want %s", shellBin, expectShellBin) + } } func TestMetaWhenStartPipeline(t *testing.T) { @@ -1388,7 +1552,7 @@ func TestMetaWhenStartPipeline(t *testing.T) { return nil } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, _, _ := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) want := fmt.Sprintf(`{ "build_only": "build_value", "build": { @@ -1497,7 +1661,7 @@ func TestMetaWhenTriggeredFromParentBuildWithoutParentBuildMeta(t *testing.T) { return nil } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, _, _ := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) want := fmt.Sprintf(`{ "build_only": "build_value", "event_only": "event_value", @@ -1755,7 +1919,7 @@ func TestMetaWhenTriggeredFromPipelinesByANDLogicWithParentBuildMeta(t *testing. return nil } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, _, _ := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) want := fmt.Sprintf(`{ "build_only": "build_value", "event_only": "event_value", @@ -1948,7 +2112,7 @@ func TestMetaWhenTriggeredFromInnerPipelineByORLogicWithParentBuildMeta(t *testi return nil } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, _, _ := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) want := fmt.Sprintf(`{ "build_only": "build_value", "event_only": "event_value", @@ -2137,7 +2301,7 @@ func TestMetaWhenTriggeredFromExternalPipelineByORLogicWithParentBuildMeta(t *te return nil } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, _, _ := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) want := fmt.Sprintf(`{ "build_only": "build_value", "event_only": "event_value", @@ -2296,7 +2460,7 @@ func TestMetaWhenStartFromAnyJobWithParentEvent(t *testing.T) { return nil } - err := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) + err, _, _ := launch(screwdriver.API(api), TestBuildID, TestWorkspace, TestEmitter, TestMetaSpace, TestStoreURL, TestUIURL, TestShellBin, TestBuildTimeout, TestBuildToken, "", "", "", "", false, false, false, 0, 10000) want := fmt.Sprintf(`{ "build_only": "build_value", "event_only": "event_value",