| // 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. |
| |
| // This file implements integration tests for the checkout package. It depends on a real |
| // gitiles project (fuchsia.googlesource.com/infra/testproject) with real Gerrit |
| // patchsets. These tests are skipped on CQ. since they are integration tests. You can run |
| // them locally by invoking `go test` without the -short flag. |
| package checkout |
| |
| import ( |
| "bytes" |
| "errors" |
| "fmt" |
| "log" |
| "net/url" |
| "os" |
| "os/exec" |
| "strings" |
| "testing" |
| |
| buildbucketpb "go.chromium.org/luci/buildbucket/proto" |
| "go.fuchsia.dev/infra/cmd/build_init/execution" |
| "go.fuchsia.dev/infra/cmd/build_init/testbed" |
| ) |
| |
| // Verifies that a repository is checked out via rebasing a patchset onto a commit when |
| // the build input contains a Gerrit change and Gitiles commit for the input repository. |
| // We always fail if there's a merge conflict when attempting to rebase, so this test only |
| // verifies the case where there is no conflict. |
| func TestCheckoutChange(t *testing.T) { |
| tb := testbed.New(t) |
| tb.Setup() |
| defer tb.Teardown() |
| |
| repo := url.URL{ |
| Scheme: "https", |
| Host: "fuchsia.googlesource.com", |
| Path: "infra/testproject", |
| } |
| input := buildbucketpb.Build_Input{ |
| GitilesCommit: &buildbucketpb.GitilesCommit{ |
| Host: "fuchsia.googlesource.com", |
| Project: "infra/testproject", |
| Id: "813624618670bf1ae072a5e24d05b0bbda7240a0", |
| }, |
| GerritChanges: []*buildbucketpb.GerritChange{{ |
| Host: "fuchsia-review.googlesource.com", |
| Project: "infra/testproject", |
| Change: 284673, |
| Patchset: 3, |
| }}, |
| } |
| if err := doCheckout(input, repo); err != nil { |
| t.Fatal(err) |
| } |
| |
| var stdout, stderr bytes.Buffer |
| executor := execution.NewExecutor(&stdout, &stderr) |
| // Use the path to git loaded in the checkout package's init() function. |
| if err := executor.Exec(git, "log", "--pretty=oneline", "--abbrev-commit"); err != nil { |
| t.Fatal(err, stderr.String()) |
| } |
| t.Log(stdout.String()) |
| t.Log(stderr.String()) |
| |
| actualLog := strings.TrimSpace(stdout.String()) |
| expectedLog := "28d5d51 Add rebased.txt\n8136246 Add README.md" |
| if actualLog != expectedLog { |
| t.Errorf("expected commit log:\n%v\ngot:\n%v", expectedLog, actualLog) |
| } |
| } |
| |
| // Verifies that a repository is checked out from a commit when the build input contains a |
| // Gitiles commit for the input repository. |
| func TestCheckoutCommit(t *testing.T) { |
| tb := testbed.New(t) |
| tb.Setup() |
| defer tb.Teardown() |
| |
| repo := url.URL{ |
| Scheme: "https", |
| Host: "fuchsia.googlesource.com", |
| Path: "infra/testproject", |
| } |
| input := buildbucketpb.Build_Input{ |
| GitilesCommit: &buildbucketpb.GitilesCommit{ |
| Host: "fuchsia.googlesource.com", |
| Project: "infra/testproject", |
| Id: "813624618670bf1ae072a5e24d05b0bbda7240a0", |
| }, |
| } |
| if err := doCheckout(input, repo); err != nil { |
| t.Fatal(err) |
| } |
| |
| var stdout, stderr bytes.Buffer |
| executor := execution.NewExecutor(&stdout, &stderr) |
| |
| // Use the path to git loaded in the checkout package's init() function. |
| if err := executor.Exec(git, "log", "--pretty=oneline", "--abbrev-commit"); err != nil { |
| t.Fatal(err, stderr.String()) |
| } |
| t.Log(stdout.String()) |
| t.Log(stderr.String()) |
| |
| actualLog := strings.TrimSpace(stdout.String()) |
| expectedLog := "8136246 Add README.md" |
| if actualLog != expectedLog { |
| t.Errorf("expected commit log:\n%v\ngot:\n%v", expectedLog, actualLog) |
| } |
| } |
| |
| func TestCheckoutHead(t *testing.T) { |
| tb := testbed.New(t) |
| tb.Setup() |
| defer tb.Teardown() |
| |
| repo := url.URL{ |
| Scheme: "https", |
| Host: "fuchsia.googlesource.com", |
| Path: "infra/testproject", |
| } |
| input := buildbucketpb.Build_Input{ |
| // Empty commit to force a checkout at HEAD. |
| GitilesCommit: &buildbucketpb.GitilesCommit{}, |
| } |
| if err := doCheckout(input, repo); err != nil { |
| t.Fatal(err) |
| } |
| } |
| |
| func doCheckout(input buildbucketpb.Build_Input, repoURL url.URL) error { |
| // Verify the cwd is not a git checkout, but ends up being one after Checkout() |
| // completes. |
| if isInGitCheckout() { |
| return errors.New("failed test precondition: already in a git checkout") |
| } |
| if err := Checkout(input, repoURL, "HEAD"); err != nil { |
| return fmt.Errorf("checkout failed: %v", err) |
| } |
| if !isInGitCheckout() { |
| return errors.New("expected to be in a git checkout after Checkout()") |
| } |
| return nil |
| } |
| |
| func isInGitCheckout() bool { |
| executor := execution.NewExecutor(os.Stderr, os.Stderr) |
| err := executor.Exec(git, "status") |
| if err == nil { |
| log.Println(err) |
| return true |
| } |
| exit, ok := err.(*exec.ExitError) |
| if !ok || exit.ExitCode() == 0 { |
| log.Println(err) |
| return true |
| } |
| return false |
| } |