go.fuchsia.dev/infra@v0.0.0-20240507153436-9b593402251b/checkout/checkout_integration_test.go (about) 1 // Copyright 2019 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // This file implements integration tests for the checkout package. It depends on a real 6 // gitiles project (fuchsia.googlesource.com/infra/testproject) with real Gerrit 7 // patchsets. These tests are skipped on CQ. since they are integration tests. You can run 8 // them locally by invoking `go test` without the -short flag. 9 package checkout 10 11 import ( 12 "bytes" 13 "context" 14 "errors" 15 "fmt" 16 "net/url" 17 "os" 18 "os/exec" 19 "strings" 20 "testing" 21 22 buildbucketpb "go.chromium.org/luci/buildbucket/proto" 23 "go.fuchsia.dev/infra/execution" 24 ) 25 26 // Verifies that a repository is checked out via rebasing a patchset onto a commit when 27 // the build input contains a Gerrit change and Gitiles commit for the input repository. 28 // We always fail if there's a merge conflict when attempting to rebase, so this test only 29 // verifies the case where there is no conflict. 30 func TestCheckoutChange(t *testing.T) { 31 os.Chdir(t.TempDir()) 32 33 ctx := context.Background() 34 repo := url.URL{ 35 Scheme: "https", 36 Host: "fuchsia.googlesource.com", 37 Path: "infra/testproject", 38 } 39 input := &buildbucketpb.Build_Input{ 40 GitilesCommit: &buildbucketpb.GitilesCommit{ 41 Host: "fuchsia.googlesource.com", 42 Project: "infra/testproject", 43 Id: "813624618670bf1ae072a5e24d05b0bbda7240a0", 44 }, 45 GerritChanges: []*buildbucketpb.GerritChange{{ 46 Host: "fuchsia-review.googlesource.com", 47 Project: "infra/testproject", 48 Change: 284673, 49 Patchset: 3, 50 }}, 51 } 52 if err := doCheckout(ctx, input, repo); err != nil { 53 t.Fatal(err) 54 } 55 56 var stdout, stderr bytes.Buffer 57 executor := execution.NewExecutor(&stdout, &stderr, "") 58 59 // Use the path to git loaded in the checkout package's init() function. 60 if err := executor.Exec(ctx, git, "log", "--pretty=oneline", "--abbrev-commit"); err != nil { 61 t.Fatal(err, stderr.String()) 62 } 63 t.Log(stdout.String()) 64 t.Log(stderr.String()) 65 66 actualLog := strings.TrimSpace(stdout.String()) 67 expectedLog := "28d5d51 Add rebased.txt\n8136246 Add README.md" 68 if actualLog != expectedLog { 69 t.Errorf("expected commit log:\n%s\ngot:\n%s", expectedLog, actualLog) 70 } 71 } 72 73 // Verifies that a repository is checked out from a commit when the build input contains a 74 // Gitiles commit for the input repository. 75 func TestCheckoutCommit(t *testing.T) { 76 os.Chdir(t.TempDir()) 77 78 ctx := context.Background() 79 repo := url.URL{ 80 Scheme: "https", 81 Host: "fuchsia.googlesource.com", 82 Path: "infra/testproject", 83 } 84 input := &buildbucketpb.Build_Input{ 85 GitilesCommit: &buildbucketpb.GitilesCommit{ 86 Host: "fuchsia.googlesource.com", 87 Project: "infra/testproject", 88 Id: "813624618670bf1ae072a5e24d05b0bbda7240a0", 89 }, 90 } 91 if err := doCheckout(ctx, input, repo); err != nil { 92 t.Fatal(err) 93 } 94 95 var stdout, stderr bytes.Buffer 96 executor := execution.NewExecutor(&stdout, &stderr, "") 97 98 // Use the path to git loaded in the checkout package's init() function. 99 if err := executor.Exec(ctx, git, "log", "--pretty=oneline", "--abbrev-commit"); err != nil { 100 t.Fatal(err, stderr.String()) 101 } 102 t.Log(stdout.String()) 103 t.Log(stderr.String()) 104 105 actualLog := strings.TrimSpace(stdout.String()) 106 expectedLog := "8136246 Add README.md" 107 if actualLog != expectedLog { 108 t.Errorf("expected commit log:\n%s\ngot:\n%s", expectedLog, actualLog) 109 } 110 } 111 112 func TestCheckoutHead(t *testing.T) { 113 os.Chdir(t.TempDir()) 114 115 ctx := context.Background() 116 repo := url.URL{ 117 Scheme: "https", 118 Host: "fuchsia.googlesource.com", 119 Path: "infra/testproject", 120 } 121 input := &buildbucketpb.Build_Input{ 122 // Empty commit to force a checkout at HEAD. 123 GitilesCommit: &buildbucketpb.GitilesCommit{}, 124 } 125 if err := doCheckout(ctx, input, repo); err != nil { 126 t.Fatal(err) 127 } 128 } 129 130 func doCheckout(ctx context.Context, input *buildbucketpb.Build_Input, repoURL url.URL) error { 131 // Verify the cwd is not a git checkout, but ends up being one after Checkout() 132 // completes. 133 inGitCheckout, err := isInGitCheckout(ctx) 134 if err != nil { 135 return err 136 } 137 if inGitCheckout { 138 return errors.New("failed test precondition: already in a git checkout") 139 } 140 141 if err := Checkout(ctx, input, repoURL, "HEAD", ""); err != nil { 142 return fmt.Errorf("checkout failed: %w", err) 143 } 144 145 inGitCheckout, err = isInGitCheckout(ctx) 146 if err != nil { 147 return err 148 } 149 if !inGitCheckout { 150 return errors.New("expected to be in a git checkout after Checkout()") 151 } 152 return nil 153 } 154 155 func isInGitCheckout(ctx context.Context) (bool, error) { 156 executor := execution.NewExecutor(os.Stderr, os.Stderr, "") 157 if err := executor.Exec(ctx, git, "status"); err != nil { 158 var errExit *exec.ExitError 159 if errors.As(err, &errExit) && errExit.ExitCode() != 0 { 160 return false, nil 161 } 162 return false, err 163 } 164 return true, nil 165 }