blob: 1d1f3c33d6f18c7420987932f1f7f996641b0c4d [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.
// 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
}