blob: c3800296e5beba395ce9719aa0745e7add1e4830 [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"
"context"
"errors"
"fmt"
"log"
"net/url"
"os"
"os/exec"
"strings"
"testing"
buildbucketpb "go.chromium.org/luci/buildbucket/proto"
"go.fuchsia.dev/infra/execution"
)
// 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) {
os.Chdir(t.TempDir())
ctx := context.Background()
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(ctx, 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(ctx, 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) {
os.Chdir(t.TempDir())
ctx := context.Background()
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(ctx, 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(ctx, 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) {
os.Chdir(t.TempDir())
ctx := context.Background()
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(ctx, input, repo); err != nil {
t.Fatal(err)
}
}
func doCheckout(ctx context.Context, 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(ctx) {
return errors.New("failed test precondition: already in a git checkout")
}
if err := Checkout(ctx, input, repoURL, "HEAD", ""); err != nil {
return fmt.Errorf("checkout failed: %v", err)
}
if !isInGitCheckout(ctx) {
return errors.New("expected to be in a git checkout after Checkout()")
}
return nil
}
func isInGitCheckout(ctx context.Context) bool {
executor := execution.NewExecutor(os.Stderr, os.Stderr, "")
err := executor.Exec(ctx, 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
}