sigs.k8s.io/release-sdk@v0.11.1-0.20240417074027-8061fb5e4952/test/integration/git_test.go (about) 1 //go:build integration 2 // +build integration 3 4 /* 5 Copyright 2019 The Kubernetes Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 */ 19 20 package integration 21 22 import ( 23 "os" 24 "path/filepath" 25 "testing" 26 "time" 27 28 "github.com/blang/semver/v4" 29 gogit "github.com/go-git/go-git/v5" 30 "github.com/go-git/go-git/v5/config" 31 "github.com/go-git/go-git/v5/plumbing/object" 32 "github.com/stretchr/testify/require" 33 34 "sigs.k8s.io/release-sdk/git" 35 "sigs.k8s.io/release-utils/command" 36 "sigs.k8s.io/release-utils/util" 37 ) 38 39 var testAuthor = &object.Signature{ 40 Name: "John Doe", 41 Email: "john@doe.org", 42 When: time.Now(), 43 } 44 45 type testRepo struct { 46 sut *git.Repo 47 dir string 48 firstCommit string 49 firstBranchCommit string 50 secondBranchCommit string 51 thirdBranchCommit string 52 branchName string 53 firstTagCommit string 54 firstTagName string 55 secondTagCommit string 56 secondTagName string 57 thirdTagCommit string 58 thirdTagName string 59 testFileName string 60 } 61 62 // newTestRepo creates a test repo with the following structure: 63 // 64 // * commit `thirdBranchCommit` (HEAD -> `branchName`, origin/`branchName`) 65 // | Author: John Doe <john@doe.org> 66 // | 67 // | Fourth commit 68 // | 69 // * commit `secondBranchCommit` (tag: `thirdTagName`, HEAD -> `branchName`, origin/`branchName`) 70 // | Author: John Doe <john@doe.org> 71 // | 72 // | Third commit 73 // | 74 // * commit `firstBranchCommit` (tag: `secondTagName`, HEAD -> `branchName`, origin/`branchName`) 75 // | Author: John Doe <john@doe.org> 76 // | 77 // | Second commit 78 // | 79 // 80 // - commit `firstCommit` (tag: `firstTagName`, origin/master, origin/HEAD, master) 81 // Author: John Doe <john@doe.org> 82 // 83 // First commit 84 func newTestRepo(t *testing.T) *testRepo { 85 // Setup the bare repo as base 86 bareTempDir, err := os.MkdirTemp("", "k8s-test-bare-") 87 require.Nil(t, err) 88 89 bareRepo, err := gogit.PlainInit(bareTempDir, true) 90 require.Nil(t, err) 91 require.NotNil(t, bareRepo) 92 93 // Clone from the bare to be able to add our test data 94 cloneTempDir, err := os.MkdirTemp("", "k8s-test-clone-") 95 require.Nil(t, err) 96 cloneRepo, err := gogit.PlainInit(cloneTempDir, false) 97 require.Nil(t, err) 98 99 // Add the test data set 100 const testFileName = "test-file" 101 require.Nil(t, os.WriteFile( 102 filepath.Join(cloneTempDir, testFileName), 103 []byte("test-content"), 104 os.FileMode(0o644), 105 )) 106 107 worktree, err := cloneRepo.Worktree() 108 require.Nil(t, err) 109 _, err = worktree.Add(testFileName) 110 require.Nil(t, err) 111 112 firstCommit, err := worktree.Commit("First commit", &gogit.CommitOptions{ 113 Author: testAuthor, 114 }) 115 require.Nil(t, err) 116 117 firstTagName := "v1.17.0" 118 firstTagRef, err := cloneRepo.CreateTag(firstTagName, firstCommit, 119 &gogit.CreateTagOptions{ 120 Tagger: testAuthor, 121 Message: firstTagName, 122 }, 123 ) 124 require.Nil(t, err) 125 126 // Create a test branch and a test commit on top 127 branchName := "release-1.17" 128 require.Nil(t, command.NewWithWorkDir( 129 cloneTempDir, "git", "checkout", "-b", branchName, 130 ).RunSuccess()) 131 132 const branchTestFileName = "branch-test-file" 133 require.Nil(t, os.WriteFile( 134 filepath.Join(cloneTempDir, branchTestFileName), 135 []byte("test-content"), 136 os.FileMode(0o644), 137 )) 138 _, err = worktree.Add(branchTestFileName) 139 require.Nil(t, err) 140 141 firstBranchCommit, err := worktree.Commit("Second commit", &gogit.CommitOptions{ 142 Author: testAuthor, 143 All: true, 144 }) 145 require.Nil(t, err) 146 147 secondTagName := "v0.1.1" 148 secondTagRef, err := cloneRepo.CreateTag(secondTagName, firstBranchCommit, 149 &gogit.CreateTagOptions{ 150 Tagger: testAuthor, 151 Message: secondTagName, 152 }, 153 ) 154 require.Nil(t, err) 155 156 const secondBranchTestFileName = "branch-test-file-2" 157 require.Nil(t, os.WriteFile( 158 filepath.Join(cloneTempDir, secondBranchTestFileName), 159 []byte("test-content"), 160 os.FileMode(0o644), 161 )) 162 _, err = worktree.Add(secondBranchTestFileName) 163 require.Nil(t, err) 164 165 secondBranchCommit, err := worktree.Commit("Third commit", &gogit.CommitOptions{ 166 Author: testAuthor, 167 All: true, 168 }) 169 require.Nil(t, err) 170 171 thirdTagName := "v1.17.1" 172 thirdTagRef, err := cloneRepo.CreateTag(thirdTagName, secondBranchCommit, 173 &gogit.CreateTagOptions{ 174 Tagger: testAuthor, 175 Message: thirdTagName, 176 }, 177 ) 178 require.Nil(t, err) 179 180 const thirdBranchTestFileName = "branch-test-file-3" 181 require.Nil(t, os.WriteFile( 182 filepath.Join(cloneTempDir, thirdBranchTestFileName), 183 []byte("test-content"), 184 os.FileMode(0o644), 185 )) 186 _, err = worktree.Add(thirdBranchTestFileName) 187 require.Nil(t, err) 188 189 thirdBranchCommit, err := worktree.Commit("Fourth commit", &gogit.CommitOptions{ 190 Author: testAuthor, 191 All: true, 192 }) 193 require.Nil(t, err) 194 195 // Push the test content into the bare repo 196 _, err = cloneRepo.CreateRemote(&config.RemoteConfig{ 197 Name: git.DefaultRemote, 198 URLs: []string{bareTempDir}, 199 }) 200 require.Nil(t, err) 201 require.Nil(t, cloneRepo.Push(&gogit.PushOptions{ 202 RemoteName: "origin", 203 RefSpecs: []config.RefSpec{"refs/*:refs/*"}, 204 })) 205 206 require.Nil(t, os.RemoveAll(cloneTempDir)) 207 208 // Provide a system under test inside the test repo 209 sut, err := git.CloneOrOpenRepo("", bareTempDir, false, true, nil) 210 require.Nil(t, err) 211 require.Nil(t, command.NewWithWorkDir( 212 sut.Dir(), "git", "checkout", branchName, 213 ).RunSuccess()) 214 215 return &testRepo{ 216 sut: sut, 217 dir: bareTempDir, 218 firstCommit: firstCommit.String(), 219 firstBranchCommit: firstBranchCommit.String(), 220 secondBranchCommit: secondBranchCommit.String(), 221 thirdBranchCommit: thirdBranchCommit.String(), 222 branchName: branchName, 223 firstTagName: firstTagName, 224 firstTagCommit: firstTagRef.Hash().String(), 225 secondTagName: secondTagName, 226 secondTagCommit: secondTagRef.Hash().String(), 227 thirdTagName: thirdTagName, 228 thirdTagCommit: thirdTagRef.Hash().String(), 229 testFileName: filepath.Join(sut.Dir(), testFileName), 230 } 231 } 232 233 func (r *testRepo) cleanup(t *testing.T) { 234 require.Nil(t, os.RemoveAll(r.dir)) 235 require.Nil(t, os.RemoveAll(r.sut.Dir())) 236 } 237 238 func TestSuccessCloneOrOpen(t *testing.T) { 239 testRepo := newTestRepo(t) 240 defer testRepo.cleanup(t) 241 242 secondRepo, err := git.CloneOrOpenRepo(testRepo.sut.Dir(), testRepo.dir, false, true, nil) 243 require.Nil(t, err) 244 245 require.Equal(t, secondRepo.Dir(), testRepo.sut.Dir()) 246 require.Nil(t, secondRepo.Cleanup()) 247 } 248 249 func TestSuccessDescribeTags(t *testing.T) { 250 testRepo := newTestRepo(t) 251 defer testRepo.cleanup(t) 252 253 tag, err := testRepo.sut.Describe( 254 git.NewDescribeOptions(). 255 WithRevision(testRepo.firstTagCommit). 256 WithAbbrev(0). 257 WithTags(), 258 ) 259 require.Nil(t, err) 260 require.Equal(t, testRepo.firstTagName, tag) 261 } 262 263 func TestFailureDescribeTags(t *testing.T) { 264 testRepo := newTestRepo(t) 265 defer testRepo.cleanup(t) 266 267 _, err := testRepo.sut.Describe( 268 git.NewDescribeOptions(). 269 WithRevision("wrong"). 270 WithAbbrev(0). 271 WithTags(), 272 ) 273 require.NotNil(t, err) 274 } 275 276 func TestSuccessHasRemoteBranch(t *testing.T) { 277 testRepo := newTestRepo(t) 278 defer testRepo.cleanup(t) 279 280 for _, repo := range []string{testRepo.branchName, git.DefaultBranch} { 281 branchExists, err := testRepo.sut.HasRemoteBranch(repo) 282 require.Nil(t, err) 283 require.Equal(t, branchExists, true) 284 } 285 } 286 287 func TestFailureHasRemoteBranch(t *testing.T) { 288 testRepo := newTestRepo(t) 289 defer testRepo.cleanup(t) 290 291 // TODO: Let's simulate an actual git/network failure 292 293 branchExists, err := testRepo.sut.HasRemoteBranch("wrong") 294 require.Equal(t, branchExists, false) 295 require.Nil(t, err) 296 } 297 298 func TestSuccessHead(t *testing.T) { 299 testRepo := newTestRepo(t) 300 defer testRepo.cleanup(t) 301 302 head, err := testRepo.sut.Head() 303 require.Nil(t, err) 304 require.Equal(t, testRepo.thirdBranchCommit, head) 305 } 306 307 func TestSuccessMerge(t *testing.T) { 308 testRepo := newTestRepo(t) 309 defer testRepo.cleanup(t) 310 311 err := testRepo.sut.Merge(git.DefaultBranch) 312 require.Nil(t, err) 313 } 314 315 func TestFailureMerge(t *testing.T) { 316 testRepo := newTestRepo(t) 317 defer testRepo.cleanup(t) 318 319 err := testRepo.sut.Merge("wrong") 320 require.NotNil(t, err) 321 } 322 323 func TestSuccessMergeBase(t *testing.T) { 324 testRepo := newTestRepo(t) 325 defer testRepo.cleanup(t) 326 327 mergeBase, err := testRepo.sut.MergeBase(git.DefaultBranch, testRepo.branchName) 328 require.Nil(t, err) 329 require.Equal(t, testRepo.firstCommit, mergeBase) 330 } 331 332 func TestSuccessRevParse(t *testing.T) { 333 testRepo := newTestRepo(t) 334 defer testRepo.cleanup(t) 335 336 mainRev, err := testRepo.sut.RevParse(git.DefaultBranch) 337 require.Nil(t, err) 338 require.Equal(t, testRepo.firstCommit, mainRev) 339 340 branchRev, err := testRepo.sut.RevParse(testRepo.branchName) 341 require.Nil(t, err) 342 require.Equal(t, testRepo.thirdBranchCommit, branchRev) 343 344 tagRev, err := testRepo.sut.RevParse(testRepo.firstTagName) 345 require.Nil(t, err) 346 require.Equal(t, testRepo.firstCommit, tagRev) 347 348 tagRev, err = testRepo.sut.RevParse(testRepo.firstCommit) 349 require.Nil(t, err) 350 require.Equal(t, testRepo.firstCommit, tagRev) 351 } 352 353 func TestSuccessRevTagParse(t *testing.T) { 354 testRepo := newTestRepo(t) 355 defer testRepo.cleanup(t) 356 357 mainRev, err := testRepo.sut.RevParseTag(git.DefaultBranch) 358 require.Nil(t, err) 359 require.Equal(t, testRepo.firstCommit, mainRev) 360 361 branchRev, err := testRepo.sut.RevParseTag(testRepo.branchName) 362 require.Nil(t, err) 363 require.Equal(t, testRepo.thirdBranchCommit, branchRev) 364 365 tagRev, err := testRepo.sut.RevParseTag(testRepo.firstTagName) 366 require.Nil(t, err) 367 require.Equal(t, testRepo.firstCommit, tagRev) 368 } 369 370 func TestFailureRevParse(t *testing.T) { 371 testRepo := newTestRepo(t) 372 defer testRepo.cleanup(t) 373 374 _, err := testRepo.sut.RevParse("wrong") 375 require.NotNil(t, err) 376 } 377 378 func TestFailureRevParseTag(t *testing.T) { 379 testRepo := newTestRepo(t) 380 defer testRepo.cleanup(t) 381 382 _, err := testRepo.sut.RevParseTag("wrong") 383 require.NotNil(t, err) 384 385 _, err = testRepo.sut.RevParseTag(testRepo.firstCommit) 386 require.NotNil(t, err) 387 } 388 389 func TestSuccessRevParseShort(t *testing.T) { 390 testRepo := newTestRepo(t) 391 defer testRepo.cleanup(t) 392 393 mainRev, err := testRepo.sut.RevParseShort(git.DefaultBranch) 394 require.Nil(t, err) 395 require.Equal(t, testRepo.firstCommit[:10], mainRev) 396 397 branchRev, err := testRepo.sut.RevParseShort(testRepo.branchName) 398 require.Nil(t, err) 399 require.Equal(t, testRepo.thirdBranchCommit[:10], branchRev) 400 401 tagRev, err := testRepo.sut.RevParseShort(testRepo.firstTagName) 402 require.Nil(t, err) 403 require.Equal(t, testRepo.firstCommit[:10], tagRev) 404 405 tagRev, err = testRepo.sut.RevParseShort(testRepo.firstCommit) 406 require.Nil(t, err) 407 require.Equal(t, testRepo.firstCommit[:10], tagRev) 408 } 409 410 func TestSuccessRevParseTagShort(t *testing.T) { 411 testRepo := newTestRepo(t) 412 defer testRepo.cleanup(t) 413 414 mainRev, err := testRepo.sut.RevParseTagShort(git.DefaultBranch) 415 require.Nil(t, err) 416 require.Equal(t, testRepo.firstCommit[:10], mainRev) 417 418 branchRev, err := testRepo.sut.RevParseTagShort(testRepo.branchName) 419 require.Nil(t, err) 420 require.Equal(t, testRepo.thirdBranchCommit[:10], branchRev) 421 422 tagRev, err := testRepo.sut.RevParseTagShort(testRepo.firstTagName) 423 require.Nil(t, err) 424 require.Equal(t, testRepo.firstCommit[:10], tagRev) 425 } 426 427 func TestFailureRevParseShort(t *testing.T) { 428 testRepo := newTestRepo(t) 429 defer testRepo.cleanup(t) 430 431 _, err := testRepo.sut.RevParseShort("wrong") 432 require.NotNil(t, err) 433 } 434 435 func TestFailureRevParseTagShort(t *testing.T) { 436 testRepo := newTestRepo(t) 437 defer testRepo.cleanup(t) 438 439 _, err := testRepo.sut.RevParseTagShort("wrong") 440 require.NotNil(t, err) 441 442 _, err = testRepo.sut.RevParseTagShort(testRepo.firstCommit) 443 require.NotNil(t, err) 444 } 445 446 func TestSuccessPush(t *testing.T) { 447 testRepo := newTestRepo(t) 448 defer testRepo.cleanup(t) 449 450 err := testRepo.sut.Push(git.DefaultBranch) 451 require.Nil(t, err) 452 } 453 454 func TestFailurePush(t *testing.T) { 455 testRepo := newTestRepo(t) 456 defer testRepo.cleanup(t) 457 458 err := testRepo.sut.Push("wrong") 459 require.NotNil(t, err) 460 } 461 462 func TestSuccessRemotify(t *testing.T) { 463 newRemote := git.Remotify(git.DefaultBranch) 464 require.Equal(t, git.DefaultRemote+"/"+git.DefaultBranch, newRemote) 465 } 466 467 func TestSuccessIsReleaseBranch(t *testing.T) { 468 require.True(t, git.IsReleaseBranch("release-1.17")) 469 } 470 471 func TestFailureIsReleaseBranch(t *testing.T) { 472 require.False(t, git.IsReleaseBranch("wrong-branch")) 473 } 474 475 func TestSuccessLatestTagForBranch(t *testing.T) { 476 testRepo := newTestRepo(t) 477 defer testRepo.cleanup(t) 478 479 version, err := testRepo.sut.LatestTagForBranch(git.DefaultBranch) 480 require.Nil(t, err) 481 require.Equal(t, testRepo.firstTagName, util.SemverToTagString(version)) 482 } 483 484 func TestSuccessLatestTagForBranchRelease(t *testing.T) { 485 testRepo := newTestRepo(t) 486 defer testRepo.cleanup(t) 487 488 version, err := testRepo.sut.LatestTagForBranch("release-1.17") 489 require.Nil(t, err) 490 require.Equal(t, testRepo.thirdTagName, util.SemverToTagString(version)) 491 } 492 493 func TestFailureLatestTagForBranchInvalidBranch(t *testing.T) { 494 testRepo := newTestRepo(t) 495 defer testRepo.cleanup(t) 496 497 version, err := testRepo.sut.LatestTagForBranch("wrong-branch") 498 require.NotNil(t, err) 499 require.Equal(t, semver.Version{}, version) 500 } 501 502 func TestSuccessLatestPatchToPatch(t *testing.T) { 503 testRepo := newTestRepo(t) 504 defer testRepo.cleanup(t) 505 506 // This test case gets commits from v1.17.0 to v1.17.1 507 result, err := testRepo.sut.LatestPatchToPatch(testRepo.branchName) 508 require.Nil(t, err) 509 require.Equal(t, testRepo.firstCommit, result.StartSHA()) 510 require.Equal(t, testRepo.firstTagName, result.StartRev()) 511 require.Equal(t, testRepo.thirdTagName, result.EndRev()) 512 } 513 514 func TestSuccessLatestPatchToPatchNewTag(t *testing.T) { 515 testRepo := newTestRepo(t) 516 defer testRepo.cleanup(t) 517 518 // This test case gets commits from v1.17.1 to a new v1.17.2 519 nextMinorTag := "v1.17.2" 520 require.Nil(t, command.NewWithWorkDir( 521 testRepo.sut.Dir(), "git", "tag", nextMinorTag, 522 ).RunSuccess()) 523 524 result, err := testRepo.sut.LatestPatchToPatch(testRepo.branchName) 525 require.Nil(t, err) 526 require.Equal(t, testRepo.secondBranchCommit, result.StartSHA()) 527 require.Equal(t, testRepo.thirdTagName, result.StartRev()) 528 require.Equal(t, nextMinorTag, result.EndRev()) 529 } 530 531 func TestFailureLatestPatchToPatchWrongBranch(t *testing.T) { 532 testRepo := newTestRepo(t) 533 defer testRepo.cleanup(t) 534 535 result, err := testRepo.sut.LatestPatchToPatch("wrong-branch") 536 require.NotNil(t, err) 537 require.Equal(t, result, git.DiscoverResult{}) 538 } 539 540 func TestSuccessLatestPatchToLatest(t *testing.T) { 541 testRepo := newTestRepo(t) 542 defer testRepo.cleanup(t) 543 544 // This test case gets commits from v1.17.1 to head of release-1.17 545 result, err := testRepo.sut.LatestPatchToLatest(testRepo.branchName) 546 require.Nil(t, err) 547 require.Equal(t, testRepo.secondBranchCommit, result.StartSHA()) 548 require.Equal(t, testRepo.thirdTagName, result.StartRev()) 549 require.Equal(t, testRepo.thirdBranchCommit, result.EndSHA()) 550 } 551 552 func TestSuccessDry(t *testing.T) { 553 testRepo := newTestRepo(t) 554 defer testRepo.cleanup(t) 555 556 testRepo.sut.SetDry() 557 558 err := testRepo.sut.Push(git.DefaultBranch) 559 require.Nil(t, err) 560 } 561 562 func TestSuccessLatestReleaseBranchMergeBaseToLatest(t *testing.T) { 563 testRepo := newTestRepo(t) 564 defer testRepo.cleanup(t) 565 566 result, err := testRepo.sut.LatestReleaseBranchMergeBaseToLatest() 567 require.Nil(t, err) 568 require.Equal(t, testRepo.firstCommit, result.StartSHA()) 569 require.Equal(t, testRepo.firstTagName, result.StartRev()) 570 require.Equal(t, testRepo.firstCommit, result.EndSHA()) 571 require.Equal(t, git.DefaultBranch, result.EndRev()) 572 } 573 574 func TestFailureLatestReleaseBranchMergeBaseToLatestNoLatestTag(t *testing.T) { 575 testRepo := newTestRepo(t) 576 defer testRepo.cleanup(t) 577 578 require.Nil(t, command.NewWithWorkDir( 579 testRepo.sut.Dir(), "git", "tag", "-d", testRepo.firstTagName, 580 ).RunSuccess()) 581 582 result, err := testRepo.sut.LatestReleaseBranchMergeBaseToLatest() 583 require.NotNil(t, err) 584 require.Equal(t, result, git.DiscoverResult{}) 585 } 586 587 func TestSuccessLatestNonPatchFinalToMinor(t *testing.T) { 588 testRepo := newTestRepo(t) 589 defer testRepo.cleanup(t) 590 591 nextMinorTag := "v1.18.0" 592 require.Nil(t, command.NewWithWorkDir( 593 testRepo.sut.Dir(), "git", "tag", nextMinorTag, 594 ).RunSuccess()) 595 596 result, err := testRepo.sut.LatestNonPatchFinalToMinor() 597 require.Nil(t, err) 598 require.Equal(t, testRepo.firstCommit, result.StartSHA()) 599 require.Equal(t, testRepo.firstTagName, result.StartRev()) 600 require.Equal(t, nextMinorTag, result.EndRev()) 601 } 602 603 func TestFailureLatestNonPatchFinalToMinor(t *testing.T) { 604 testRepo := newTestRepo(t) 605 defer testRepo.cleanup(t) 606 607 result, err := testRepo.sut.LatestNonPatchFinalToMinor() 608 require.NotNil(t, err) 609 require.Equal(t, result, git.DiscoverResult{}) 610 } 611 612 func TestTagsForBranchMain(t *testing.T) { 613 testRepo := newTestRepo(t) 614 defer testRepo.cleanup(t) 615 616 result, err := testRepo.sut.TagsForBranch(git.DefaultBranch) 617 require.Nil(t, err) 618 require.Equal(t, []string{testRepo.firstTagName}, result) 619 } 620 621 func TestTagsForBranchOnBranch(t *testing.T) { 622 testRepo := newTestRepo(t) 623 defer testRepo.cleanup(t) 624 625 result, err := testRepo.sut.TagsForBranch(testRepo.branchName) 626 require.Nil(t, err) 627 require.Equal(t, []string{ 628 testRepo.thirdTagName, 629 testRepo.firstTagName, 630 testRepo.secondTagName, 631 }, result) 632 } 633 634 func TestTagsForBranchFailureWrongBranch(t *testing.T) { 635 testRepo := newTestRepo(t) 636 defer testRepo.cleanup(t) 637 638 result, err := testRepo.sut.TagsForBranch("wrong-branch") 639 require.NotNil(t, err) 640 require.Nil(t, result) 641 } 642 643 func TestCheckoutSuccess(t *testing.T) { 644 testRepo := newTestRepo(t) 645 defer testRepo.cleanup(t) 646 647 require.Nil(t, os.WriteFile( 648 testRepo.testFileName, 649 []byte("hello world"), 650 os.FileMode(0o644), 651 )) 652 res, err := command.NewWithWorkDir( 653 testRepo.sut.Dir(), "git", "diff", "--name-only").Run() 654 require.Nil(t, err) 655 require.True(t, res.Success()) 656 require.Contains(t, res.Output(), filepath.Base(testRepo.testFileName)) 657 658 err = testRepo.sut.Checkout(git.DefaultBranch, testRepo.testFileName) 659 require.Nil(t, err) 660 661 res, err = command.NewWithWorkDir( 662 testRepo.sut.Dir(), "git", "diff", "--name-only").Run() 663 require.Nil(t, err) 664 require.True(t, res.Success()) 665 require.Empty(t, res.Output()) 666 } 667 668 func TestCheckoutFailureWrongRevision(t *testing.T) { 669 testRepo := newTestRepo(t) 670 defer testRepo.cleanup(t) 671 672 err := testRepo.sut.Checkout("wrong") 673 require.NotNil(t, err) 674 require.Contains(t, err.Error(), "checkout wrong did not succeed") 675 } 676 677 func TestAddSuccess(t *testing.T) { 678 testRepo := newTestRepo(t) 679 defer testRepo.cleanup(t) 680 681 f, err := os.CreateTemp(testRepo.sut.Dir(), "test") 682 require.Nil(t, err) 683 require.Nil(t, f.Close()) 684 685 filename := filepath.Base(f.Name()) 686 err = testRepo.sut.Add(filename) 687 require.Nil(t, err) 688 689 res, err := command.NewWithWorkDir( 690 testRepo.sut.Dir(), "git", "diff", "--cached", "--name-only").Run() 691 require.Nil(t, err) 692 require.True(t, res.Success()) 693 require.Contains(t, res.Output(), filename) 694 } 695 696 func TestAddFailureWrongPath(t *testing.T) { 697 testRepo := newTestRepo(t) 698 defer testRepo.cleanup(t) 699 700 err := testRepo.sut.Add("wrong") 701 require.NotNil(t, err) 702 require.Contains(t, err.Error(), "adding file wrong to repository") 703 } 704 705 func TestCommitSuccess(t *testing.T) { 706 testRepo := newTestRepo(t) 707 defer testRepo.cleanup(t) 708 709 commitMessage := "My commit message for this test" 710 err := testRepo.sut.Commit(commitMessage) 711 require.Nil(t, err) 712 713 res, err := command.NewWithWorkDir( 714 testRepo.sut.Dir(), "git", "log", "-1", 715 ).Run() 716 require.Nil(t, err) 717 require.True(t, res.Success()) 718 require.Contains( 719 t, 720 res.Output(), 721 "Author: Kubernetes Release Robot <k8s-release-robot@users.noreply.github.com>", 722 ) 723 require.Contains( 724 t, 725 res.Output(), 726 commitMessage, 727 ) 728 } 729 730 func TestCurrentBranchDefault(t *testing.T) { 731 testRepo := newTestRepo(t) 732 defer testRepo.cleanup(t) 733 734 branch, err := testRepo.sut.CurrentBranch() 735 require.Nil(t, err) 736 require.Equal(t, branch, testRepo.branchName) 737 } 738 739 func TestCurrentBranchMain(t *testing.T) { 740 testRepo := newTestRepo(t) 741 defer testRepo.cleanup(t) 742 require.Nil(t, testRepo.sut.Checkout(git.DefaultBranch)) 743 744 branch, err := testRepo.sut.CurrentBranch() 745 require.Nil(t, err) 746 require.Equal(t, branch, git.DefaultBranch) 747 } 748 749 func TestRmSuccessForce(t *testing.T) { 750 testRepo := newTestRepo(t) 751 defer testRepo.cleanup(t) 752 require.Nil(t, os.WriteFile(testRepo.testFileName, 753 []byte("test"), os.FileMode(0o755)), 754 ) 755 756 require.Nil(t, testRepo.sut.Rm(true, testRepo.testFileName)) 757 758 _, err := os.Stat(testRepo.testFileName) 759 require.True(t, os.IsNotExist(err)) 760 } 761 762 func TestHasRemoteSuccess(t *testing.T) { 763 testRepo := newTestRepo(t) 764 defer testRepo.cleanup(t) 765 766 err := testRepo.sut.AddRemote("test", "owner", "repo", true) 767 require.Nil(t, err) 768 769 remotes, err := testRepo.sut.Remotes() 770 require.Nil(t, err) 771 772 require.Len(t, remotes, 2) 773 774 // The origin remote 775 require.Equal(t, remotes[0].Name(), git.DefaultRemote) 776 require.Len(t, remotes[0].URLs(), 1) 777 require.Equal(t, remotes[0].URLs()[0], testRepo.dir) 778 779 // Or via the API 780 require.True(t, testRepo.sut.HasRemote("origin", testRepo.dir)) 781 782 // The added test remote 783 require.Equal(t, remotes[1].Name(), "test") 784 require.Len(t, remotes[1].URLs(), 1) 785 786 url := git.GetRepoURL("owner", "repo", true) 787 require.Equal(t, remotes[1].URLs()[0], url) 788 789 // Or via the API 790 require.True(t, testRepo.sut.HasRemote("test", url)) 791 } 792 793 func TestHasRemoteFailure(t *testing.T) { 794 testRepo := newTestRepo(t) 795 defer testRepo.cleanup(t) 796 797 require.False(t, testRepo.sut.HasRemote("name", "some-url.com")) 798 } 799 800 func TestRmFailureForce(t *testing.T) { 801 testRepo := newTestRepo(t) 802 defer testRepo.cleanup(t) 803 require.NotNil(t, testRepo.sut.Rm(true, "invalid")) 804 } 805 806 func TestRmSuccess(t *testing.T) { 807 testRepo := newTestRepo(t) 808 defer testRepo.cleanup(t) 809 810 require.Nil(t, testRepo.sut.Rm(true, testRepo.testFileName)) 811 812 _, err := os.Stat(testRepo.testFileName) 813 require.True(t, os.IsNotExist(err)) 814 } 815 816 func TestRmFailureModified(t *testing.T) { 817 testRepo := newTestRepo(t) 818 defer testRepo.cleanup(t) 819 require.Nil(t, os.WriteFile(testRepo.testFileName, 820 []byte("test"), os.FileMode(0o755)), 821 ) 822 require.NotNil(t, testRepo.sut.Rm(false, testRepo.testFileName)) 823 } 824 825 func TestOpenRepoSuccess(t *testing.T) { 826 testRepo := newTestRepo(t) 827 defer testRepo.cleanup(t) 828 829 repo, err := git.OpenRepo(testRepo.sut.Dir()) 830 require.Nil(t, err) 831 require.Equal(t, repo.Dir(), testRepo.sut.Dir()) 832 } 833 834 func TestOpenRepoSuccessSearchGitDot(t *testing.T) { 835 testRepo := newTestRepo(t) 836 defer testRepo.cleanup(t) 837 838 repo, err := git.OpenRepo(filepath.Join(testRepo.sut.Dir(), "not-existing")) 839 require.Nil(t, err) 840 require.Equal(t, repo.Dir(), testRepo.sut.Dir()) 841 } 842 843 func TestOpenRepoFailure(t *testing.T) { 844 repo, err := git.OpenRepo("/invalid") 845 require.NotNil(t, err) 846 require.Nil(t, repo) 847 } 848 849 func TestAddRemoteSuccess(t *testing.T) { 850 testRepo := newTestRepo(t) 851 defer testRepo.cleanup(t) 852 853 err := testRepo.sut.AddRemote("remote", "owner", "repo", true) 854 require.Nil(t, err) 855 } 856 857 func TestAddRemoteFailureAlreadyExisting(t *testing.T) { 858 testRepo := newTestRepo(t) 859 defer testRepo.cleanup(t) 860 861 err := testRepo.sut.AddRemote(git.DefaultRemote, "owner", "repo", true) 862 require.NotNil(t, err) 863 } 864 865 func TestPushToRemoteSuccessRemoteMain(t *testing.T) { 866 testRepo := newTestRepo(t) 867 defer testRepo.cleanup(t) 868 869 err := testRepo.sut.PushToRemote(git.DefaultRemote, git.Remotify(git.DefaultBranch)) 870 require.Nil(t, err) 871 } 872 873 func TestPushToRemoteSuccessBranchTracked(t *testing.T) { 874 testRepo := newTestRepo(t) 875 defer testRepo.cleanup(t) 876 877 err := testRepo.sut.PushToRemote(git.DefaultRemote, testRepo.branchName) 878 require.Nil(t, err) 879 } 880 881 func TestPushToRemoteFailureBranchNotExisting(t *testing.T) { 882 testRepo := newTestRepo(t) 883 defer testRepo.cleanup(t) 884 885 err := testRepo.sut.PushToRemote(git.DefaultRemote, "some-branch") 886 require.NotNil(t, err) 887 } 888 889 func TestLSRemoteSuccess(t *testing.T) { 890 testRepo := newTestRepo(t) 891 defer testRepo.cleanup(t) 892 893 res, err := testRepo.sut.LsRemote() 894 require.Nil(t, err) 895 require.Contains(t, res, testRepo.firstCommit) 896 require.Contains(t, res, testRepo.secondBranchCommit) 897 require.Contains(t, res, testRepo.thirdBranchCommit) 898 } 899 900 func TestLSRemoteFailure(t *testing.T) { 901 testRepo := newTestRepo(t) 902 defer testRepo.cleanup(t) 903 904 res, err := testRepo.sut.LsRemote("invalid") 905 require.NotNil(t, err) 906 require.Empty(t, res) 907 } 908 909 func TestBranchSuccess(t *testing.T) { 910 testRepo := newTestRepo(t) 911 defer testRepo.cleanup(t) 912 913 res, err := testRepo.sut.Branch() 914 require.Nil(t, err) 915 require.Contains(t, res, testRepo.branchName) 916 } 917 918 func TestBranchFailure(t *testing.T) { 919 testRepo := newTestRepo(t) 920 defer testRepo.cleanup(t) 921 922 res, err := testRepo.sut.Branch("--invalid") 923 require.NotNil(t, err) 924 require.Empty(t, res) 925 } 926 927 func TestIsDirtySuccess(t *testing.T) { 928 testRepo := newTestRepo(t) 929 defer testRepo.cleanup(t) 930 931 dirty, err := testRepo.sut.IsDirty() 932 require.Nil(t, err) 933 require.False(t, dirty) 934 } 935 936 func TestIsDirtyFailure(t *testing.T) { 937 testRepo := newTestRepo(t) 938 defer testRepo.cleanup(t) 939 940 require.Nil(t, os.WriteFile( 941 filepath.Join(testRepo.sut.Dir(), "any-file"), 942 []byte("test"), os.FileMode(0o755)), 943 ) 944 945 dirty, err := testRepo.sut.IsDirty() 946 require.Nil(t, err) 947 require.True(t, dirty) 948 } 949 950 func TestSetURLSuccess(t *testing.T) { 951 testRepo := newTestRepo(t) 952 defer testRepo.cleanup(t) 953 954 const remote = "https://example.com" 955 require.Nil(t, testRepo.sut.SetURL(git.DefaultRemote, remote)) 956 remotes, err := testRepo.sut.Remotes() 957 require.Nil(t, err) 958 require.Len(t, remotes, 1) 959 require.Equal(t, git.DefaultRemote, remotes[0].Name()) 960 require.Len(t, remotes[0].URLs(), 1) 961 require.Equal(t, remotes[0].URLs()[0], remote) 962 } 963 964 func TestSetURLFailureRemoteDoesNotExists(t *testing.T) { 965 testRepo := newTestRepo(t) 966 defer testRepo.cleanup(t) 967 968 require.NotNil(t, testRepo.sut.SetURL("some-remote", "")) 969 } 970 971 func TestAllTags(t *testing.T) { 972 testRepo := newTestRepo(t) 973 defer testRepo.cleanup(t) 974 975 tags, err := testRepo.sut.Tags() 976 require.Nil(t, err) 977 require.Len(t, tags, 3) 978 require.Equal(t, tags[0], testRepo.secondTagName) 979 require.Equal(t, tags[1], testRepo.firstTagName) 980 require.Equal(t, tags[2], testRepo.thirdTagName) 981 } 982 983 func TestCommitEmptySuccess(t *testing.T) { 984 testRepo := newTestRepo(t) 985 defer testRepo.cleanup(t) 986 987 commitMessage := "This is an empty commit" 988 require.Nil(t, testRepo.sut.CommitEmpty(commitMessage)) 989 res, err := command.NewWithWorkDir( 990 testRepo.sut.Dir(), "git", "log", "-1", 991 ).Run() 992 require.Nil(t, err) 993 require.True(t, res.Success()) 994 require.Contains(t, res.Output(), commitMessage) 995 } 996 997 func TestTagSuccess(t *testing.T) { 998 testRepo := newTestRepo(t) 999 defer testRepo.cleanup(t) 1000 1001 testTag := "testTag" 1002 require.Nil(t, testRepo.sut.Tag(testTag, "message")) 1003 tags, err := testRepo.sut.TagsForBranch(testRepo.branchName) 1004 require.Nil(t, err) 1005 require.Contains(t, tags, testTag) 1006 } 1007 1008 func TestLatestReleaseBranch(t *testing.T) { 1009 testRepo := newTestRepo(t) 1010 defer testRepo.cleanup(t) 1011 1012 branch, err := testRepo.sut.LatestReleaseBranch() 1013 require.Nil(t, err) 1014 require.Equal(t, testRepo.branchName, branch) 1015 }