blob: 4c7ada3f5ffad63120f6acb901cfcbdf274c7c6d [file] [log] [blame]
Jack Neusfc3b5772019-07-03 11:18:42 -06001// Copyright 2019 The Chromium OS 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.
4package git
5
6import (
Jack Neusabdbe192019-07-15 12:23:22 -06007 "fmt"
Jack Neus07511722019-07-12 15:41:10 -06008 "go.chromium.org/chromiumos/infra/go/internal/cmd"
Jack Neusfc3b5772019-07-03 11:18:42 -06009 "gotest.tools/assert"
Jack Neus0296c732019-07-17 09:35:01 -060010 "io/ioutil"
11 "os"
12 "path/filepath"
Jack Neusfc3b5772019-07-03 11:18:42 -060013 "regexp"
Jack Neusfc3b5772019-07-03 11:18:42 -060014 "testing"
15)
16
Jack Neus07511722019-07-12 15:41:10 -060017func TestRunGit_success(t *testing.T) {
18 CommandRunnerImpl = cmd.FakeCommandRunner{
19 ExpectedDir: "myrepo",
20 ExpectedCmd: []string{"git", "log"},
21 Stdout: "success",
22 }
23
24 output, err := RunGit("myrepo", []string{"log"})
25 assert.NilError(t, err)
26 assert.Equal(t, output.Stdout, "success")
Jack Neusfc3b5772019-07-03 11:18:42 -060027}
28
Jack Neus07511722019-07-12 15:41:10 -060029func TestRunGit_error(t *testing.T) {
30 CommandRunnerImpl = cmd.FakeCommandRunner{
31 ExpectedDir: "myrepo",
32 ExpectedCmd: []string{"git", "log"},
33 Stdout: "I don't feel so go--",
34 Stderr: "sudden death",
35 FailCommand: true,
Jack Neusfc3b5772019-07-03 11:18:42 -060036 }
Jack Neusfc3b5772019-07-03 11:18:42 -060037
Jack Neus07511722019-07-12 15:41:10 -060038 output, err := RunGit("myrepo", []string{"log"})
39 assert.Assert(t, err != nil)
40 assert.Equal(t, output.Stderr, "sudden death")
Jack Neusfc3b5772019-07-03 11:18:42 -060041}
42
43func TestStripRefsHead(t *testing.T) {
44 assert.Equal(t, StripRefsHead("refs/heads/foo"), "foo")
45 assert.Equal(t, StripRefsHead("foo"), "foo")
46}
47
48func TestStripRefs(t *testing.T) {
49 assert.Equal(t, StripRefs("refs/remotes/origin/foo"), "foo")
50 assert.Equal(t, StripRefs("refs/heads/foo"), "foo")
51 assert.Equal(t, StripRefs("foo"), "foo")
52}
53
54func TestNormalizeRef(t *testing.T) {
55 assert.Equal(t, NormalizeRef("refs/heads/foo"), "refs/heads/foo")
56 assert.Equal(t, NormalizeRef("foo"), "refs/heads/foo")
57}
58
59func TestGetCurrentBranch_success(t *testing.T) {
60 fakeGitRepo := "top-secret-project"
61 fakeGitData := "refs/heads/current-branch"
62
Jack Neus07511722019-07-12 15:41:10 -060063 CommandRunnerImpl = cmd.FakeCommandRunner{
64 ExpectedDir: fakeGitRepo,
65 Stdout: fakeGitData,
Jack Neusfc3b5772019-07-03 11:18:42 -060066 }
67 assert.Equal(t, GetCurrentBranch(fakeGitRepo), "current-branch")
68}
69
70func TestGetCurrentBranch_failure(t *testing.T) {
Jack Neus07511722019-07-12 15:41:10 -060071 CommandRunnerImpl = cmd.FakeCommandRunner{
72 FailCommand: true,
Jack Neusfc3b5772019-07-03 11:18:42 -060073 }
74 assert.Equal(t, GetCurrentBranch("project"), "")
75}
76
77func TestMatchBranchName_success(t *testing.T) {
78 fakeGitRepo := "top-secret-project"
79 fakeGitData := "e9cb56bd9af9365b43f82cecf28cc76d49df1f72 refs/heads/foo\n" +
80 "f9c1bb630f4475058d4a9db4aea52fc89d8f7b0d refs/heads/bar\n" +
81 "2102915989de21d9251c11f0a7b5307e175e7677 refs/heads/foobar\n" +
82 "04975f9439ff75502b33d9491155692736e05b07 refs/heads/baz\n"
83
Jack Neus07511722019-07-12 15:41:10 -060084 CommandRunnerImpl = cmd.FakeCommandRunner{
85 ExpectedCmd: []string{"git", "ls-remote", fakeGitRepo},
86 ExpectedDir: fakeGitRepo,
87 Stdout: fakeGitData,
Jack Neusfc3b5772019-07-03 11:18:42 -060088 }
89
90 expectedMatches := []string{"refs/heads/foo", "refs/heads/foobar"}
91 branches, err := MatchBranchName(fakeGitRepo, regexp.MustCompile("Foo"))
92 assert.NilError(t, err)
93 assert.DeepEqual(t, expectedMatches, branches)
94
95 expectedMatches = []string{"refs/heads/foo"}
96 branches, err = MatchBranchName(fakeGitRepo, regexp.MustCompile("Foo$"))
97 assert.NilError(t, err)
98 assert.DeepEqual(t, expectedMatches, branches)
99}
100
101func TestGetRepoRevision(t *testing.T) {
102 sha := "6446dfef4b55689046395c2db7ba7c35377927fe"
Jack Neus07511722019-07-12 15:41:10 -0600103 CommandRunnerImpl = cmd.FakeCommandRunner{
104 ExpectedCmd: []string{"git", "rev-parse", "HEAD"},
105 ExpectedDir: "project",
106 Stdout: sha,
Jack Neusfc3b5772019-07-03 11:18:42 -0600107 }
108 res, err := GetGitRepoRevision("project")
109 assert.NilError(t, err)
110 assert.Equal(t, res, sha)
111}
Jack Neusabdbe192019-07-15 12:23:22 -0600112
113func TestCreateBranch(t *testing.T) {
114 fakeGitRepo := "top-secret-project"
115 branchName := "project z"
116
117 CommandRunnerImpl = cmd.FakeCommandRunner{
118 ExpectedDir: fakeGitRepo,
Jack Neus0296c732019-07-17 09:35:01 -0600119 ExpectedCmd: []string{"git", "checkout", "-B", branchName},
Jack Neusabdbe192019-07-15 12:23:22 -0600120 }
121 assert.NilError(t, CreateBranch(fakeGitRepo, branchName))
122}
123
Jack Neus0296c732019-07-17 09:35:01 -0600124func TestCreateTrackingBranch(t *testing.T) {
125 fakeGitRepo := "repo"
126 branchName := "branch"
127 remoteRef := RemoteRef{
128 Remote: "remote",
129 Ref: "master",
130 }
131 refspec := fmt.Sprintf("%s/%s", remoteRef.Remote, remoteRef.Ref)
132
133 CommandRunnerImpl = &cmd.FakeCommandRunnerMulti{
134 CommandRunners: []cmd.FakeCommandRunner{
135 {
136 ExpectedDir: fakeGitRepo,
137 ExpectedCmd: []string{"git", "fetch", remoteRef.Remote, remoteRef.Ref},
138 },
139 {
140 ExpectedDir: fakeGitRepo,
141 ExpectedCmd: []string{"git", "checkout", "-b", branchName, "-t", refspec},
142 },
143 },
144 }
145
146 err := CreateTrackingBranch(fakeGitRepo, branchName, remoteRef)
147 assert.NilError(t, err)
148}
149
Jack Neusabdbe192019-07-15 12:23:22 -0600150func TestCommitAll(t *testing.T) {
151 fakeGitRepo := "repo"
152 commitMsg := "commit"
153
154 CommandRunnerImpl = &cmd.FakeCommandRunnerMulti{
155 CommandRunners: []cmd.FakeCommandRunner{
156 {
157 ExpectedDir: fakeGitRepo,
158 ExpectedCmd: []string{"git", "add", "-A"},
159 },
160 {
161 ExpectedDir: fakeGitRepo,
162 ExpectedCmd: []string{"git", "commit", "-m", commitMsg},
163 },
164 },
165 }
166
167 err := CommitAll(fakeGitRepo, commitMsg)
168 assert.NilError(t, err)
169}
170
171func TestPushChanges(t *testing.T) {
172 fakeGitRepo := "da-bank"
173 commitMsg := "da-money"
174 localRef := "da-vault"
175
176 remoteRef := RemoteRef{
177 Remote: "da-family",
178 Ref: "da-van",
179 }
180
181 pushStr := fmt.Sprintf("%s:%s", localRef, remoteRef.Ref)
182 CommandRunnerImpl = &cmd.FakeCommandRunnerMulti{
183 CommandRunners: []cmd.FakeCommandRunner{
184 {
185 ExpectedDir: fakeGitRepo,
186 ExpectedCmd: []string{"git", "add", "-A"},
187 },
188 {
189 ExpectedDir: fakeGitRepo,
190 ExpectedCmd: []string{"git", "commit", "-m", commitMsg},
191 },
192 {
193 ExpectedDir: fakeGitRepo,
194 ExpectedCmd: []string{"git", "push", remoteRef.Remote, pushStr, "--dry-run"},
195 },
196 },
197 }
198
199 err := PushChanges(fakeGitRepo, localRef, commitMsg, true, remoteRef)
200 assert.NilError(t, err)
201}
Jack Neus0296c732019-07-17 09:35:01 -0600202
203func TestInit(t *testing.T) {
204 fakeGitRepo := "top-secret-project"
205
206 CommandRunnerImpl = cmd.FakeCommandRunner{
207 ExpectedDir: fakeGitRepo,
208 ExpectedCmd: []string{"git", "init"},
209 }
210 assert.NilError(t, Init(fakeGitRepo, false))
211}
212
213func TestInit_bare(t *testing.T) {
214 fakeGitRepo := "top-secret-project"
215
216 CommandRunnerImpl = cmd.FakeCommandRunner{
217 ExpectedDir: fakeGitRepo,
218 ExpectedCmd: []string{"git", "init", "--bare"},
219 }
220 assert.NilError(t, Init(fakeGitRepo, true))
221}
222
223func TestAddRemote(t *testing.T) {
224 fakeGitRepo := "repo"
225 remoteName := "remote"
226 remoteLoc := "remote/"
227
228 CommandRunnerImpl = cmd.FakeCommandRunner{
229 ExpectedDir: fakeGitRepo,
230 ExpectedCmd: []string{"git", "remote", "add", remoteName, remoteLoc},
231 }
232 assert.NilError(t, AddRemote(fakeGitRepo, remoteName, remoteLoc))
233}
234
235func TestCheckout(t *testing.T) {
236 CommandRunnerImpl = cmd.RealCommandRunner{}
237
238 tmpDir := "gittest_tmp_dir"
239 tmpDir, err := ioutil.TempDir("", tmpDir)
240 defer os.RemoveAll(tmpDir)
241
242 assert.NilError(t, err)
243 // Create repo.
244 assert.NilError(t, Init(tmpDir, false))
245 // Create first branch.
246 assert.NilError(t, CreateBranch(tmpDir, "branch1"))
247 // In order for the ref to be created, need to commit something.
248 assert.NilError(t, ioutil.WriteFile(filepath.Join(tmpDir, "foo"), []byte("foo"), 0644))
249 assert.NilError(t, CommitAll(tmpDir, "init commit"))
250 // Create second branch (will switch to this branch).
251 assert.NilError(t, CreateBranch(tmpDir, "branch2"))
252 // Try checking out a nonexistent branch.
253 assert.ErrorContains(t, Checkout(tmpDir, "branch3"), "did not match any")
254 // Try checking out the first branch.
255 assert.NilError(t, Checkout(tmpDir, "branch1"))
256}
257
258func TestDeleteBranch_success(t *testing.T) {
259 CommandRunnerImpl = cmd.RealCommandRunner{}
260
261 tmpDir := "gittest_tmp_dir"
262 tmpDir, err := ioutil.TempDir("", tmpDir)
263 defer os.RemoveAll(tmpDir)
264 branchName := "newbranch"
265
266 assert.NilError(t, err)
267 // Create repo.
268 assert.NilError(t, Init(tmpDir, false))
269 // Create master branch.
270 assert.NilError(t, CreateBranch(tmpDir, "master"))
271 // In order for the ref to be created, need to commit something.
272 assert.NilError(t, ioutil.WriteFile(filepath.Join(tmpDir, "foo"), []byte("foo"), 0644))
273 assert.NilError(t, CommitAll(tmpDir, "init commit"))
274 // Create branch to be deleted.
275 assert.NilError(t, CreateBranch(tmpDir, branchName))
276 // Switch back to master.
277 assert.NilError(t, Checkout(tmpDir, "master"))
278 err = DeleteBranch(tmpDir, branchName, true)
279 assert.NilError(t, err)
280}
281
282func TestDeleteBranch_inBranch(t *testing.T) {
283 CommandRunnerImpl = cmd.RealCommandRunner{}
284
285 tmpDir := "gittest_tmp_dir"
286 tmpDir, err := ioutil.TempDir("", tmpDir)
287 defer os.RemoveAll(tmpDir)
288 branchName := "newbranch"
289
290 assert.NilError(t, err)
291 // Create repo.
292 assert.NilError(t, Init(tmpDir, false))
293 // Create branch.
294 assert.NilError(t, CreateBranch(tmpDir, branchName))
295 err = DeleteBranch(tmpDir, branchName, true)
296 assert.ErrorContains(t, err, "checked out")
297}
298
299func TestDeleteBranch_unmerged(t *testing.T) {
300 CommandRunnerImpl = cmd.RealCommandRunner{}
301
302 tmpDir := "gittest_tmp_dir"
303 tmpDir, err := ioutil.TempDir("", tmpDir)
304 defer os.RemoveAll(tmpDir)
305 branchName := "newbranch"
306
307 assert.NilError(t, err)
308 // Create repo.
309 assert.NilError(t, Init(tmpDir, false))
310 // Create master branch.
311 assert.NilError(t, CreateBranch(tmpDir, "master"))
312 // In order for the ref to be created, need to commit something.
313 assert.NilError(t, ioutil.WriteFile(filepath.Join(tmpDir, "foo"), []byte("foo"), 0644))
314 assert.NilError(t, CommitAll(tmpDir, "init commit"))
315 // Create test branch.
316 assert.NilError(t, CreateBranch(tmpDir, branchName))
317 // Make a change to branch.
318 assert.NilError(t, ioutil.WriteFile(filepath.Join(tmpDir, "bar"), []byte("bar"), 0644))
319 assert.NilError(t, CommitAll(tmpDir, "init commit"))
320 // Switch back to master.
321 assert.NilError(t, Checkout(tmpDir, "master"))
322 // Should not be able to delete.
323 assert.ErrorContains(t, DeleteBranch(tmpDir, branchName, false), "fully merged")
324}
325
326func TestClone(t *testing.T) {
327 dest := "foo/bar"
328 remote := "remote"
329
330 CommandRunnerImpl = cmd.FakeCommandRunner{
331 ExpectedDir: "foo",
332 ExpectedCmd: []string{"git", "clone", remote, "bar"},
333 }
334 assert.NilError(t, Clone(remote, dest))
335}