github.com/olli-ai/jx/v2@v2.0.400-0.20210921045218-14731b4dd448/pkg/gits/operations/pull_request_op_test.go (about) 1 // +build unit 2 3 package operations_test 4 5 import ( 6 "fmt" 7 "io/ioutil" 8 "net/http" 9 "net/http/httptest" 10 "os" 11 "path/filepath" 12 "strings" 13 "testing" 14 15 "github.com/acarl005/stripansi" 16 "github.com/jenkins-x/jx-logging/pkg/log" 17 18 "github.com/olli-ai/jx/v2/pkg/kube" 19 20 "k8s.io/helm/pkg/proto/hapi/chart" 21 22 "github.com/olli-ai/jx/v2/pkg/helm" 23 24 vault_test "github.com/olli-ai/jx/v2/pkg/vault/mocks" 25 26 helm_test "github.com/olli-ai/jx/v2/pkg/helm/mocks" 27 28 "github.com/olli-ai/jx/v2/pkg/tests" 29 30 "github.com/olli-ai/jx/v2/pkg/util" 31 32 "github.com/olli-ai/jx/v2/pkg/gits/operations" 33 34 "github.com/ghodss/yaml" 35 v1 "github.com/jenkins-x/jx-api/pkg/apis/jenkins.io/v1" 36 "github.com/jenkins-x/jx-api/pkg/client/clientset/versioned" 37 "github.com/olli-ai/jx/v2/pkg/cmd/clients/fake" 38 "github.com/olli-ai/jx/v2/pkg/cmd/opts" 39 "github.com/olli-ai/jx/v2/pkg/cmd/testhelpers" 40 "github.com/olli-ai/jx/v2/pkg/dependencymatrix" 41 "github.com/olli-ai/jx/v2/pkg/gits" 42 gits_test "github.com/olli-ai/jx/v2/pkg/gits/mocks" 43 resources_test "github.com/olli-ai/jx/v2/pkg/kube/resources/mocks" 44 "github.com/petergtz/pegomock" 45 "github.com/stretchr/testify/assert" 46 tektonclient "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" 47 "k8s.io/apimachinery/pkg/runtime" 48 "k8s.io/client-go/kubernetes" 49 ) 50 51 func setupTestPullRequestOperation(t *testing.T) operations.PullRequestOperation { 52 _, _, _, commonOpts, _ := getFakeClientsAndNs(t) 53 54 testOrgName := "testowner" 55 testRepoName := "testrepo" 56 57 commonOpts.SetGit(gits.NewGitFake()) 58 59 o := operations.PullRequestOperation{ 60 CommonOptions: &commonOpts, 61 } 62 63 gitter := gits_test.NewMockGitter() 64 65 fakeRepo, _ := gits.NewFakeRepository(testOrgName, testRepoName, nil, nil) 66 fakeGitProvider := gits.NewFakeProvider(fakeRepo) 67 fakeGitProvider.User.Username = testOrgName 68 69 testhelpers.ConfigureTestOptionsWithResources(o.CommonOptions, 70 []runtime.Object{}, 71 []runtime.Object{}, 72 gitter, 73 fakeGitProvider, 74 nil, 75 resources_test.NewMockInstaller(), 76 ) 77 78 err := testhelpers.CreateTestEnvironmentDir(o.CommonOptions) 79 assert.NoError(t, err) 80 81 pegomock.When(gitter.HasChanges(pegomock.AnyString())).ThenReturn(true, nil) 82 83 return o 84 } 85 86 func TestCreatePullRequest(t *testing.T) { 87 prOpts := setupTestPullRequestOperation(t) 88 89 prOpts.GitURLs = []string{"testowner/testrepo"} 90 prOpts.SrcGitURL = "testowner/testrepo" 91 prOpts.Version = "3.0.0" 92 93 var results *gits.PullRequestInfo 94 var err error 95 96 logOutput := log.CaptureOutput(func() { 97 results, err = prOpts.CreatePullRequest("test", func(dir string, gitInfo *gits.GitRepository) (strings []string, e error) { 98 return []string{"1.0.0", "v1.0.1", "2.0.0"}, nil 99 }) 100 assert.NoError(t, err) 101 assert.NotNil(t, results, "we must have results coming out of the PR creation") 102 }) 103 104 assert.Contains(t, logOutput, "Added label updatebot to Pull Request https://fake.git/testowner/testrepo/pulls/1", 105 "Updatebot label should be added to the PR") 106 107 assert.Equal(t, "chore(deps): bump testowner/testrepo from 1.0.0, 2.0.0 and v1.0.1 to 3.0.0", 108 results.PullRequestArguments.Title, "The PR title should contain the old and new versions") 109 } 110 111 func TestCreatePullRequestsWithLabels(t *testing.T) { 112 prOpts := setupTestPullRequestOperation(t) 113 114 prOpts.GitURLs = []string{"testowner/testrepo"} 115 prOpts.SrcGitURL = "testowner/testrepo" 116 prOpts.Version = "2.0.0" 117 fromVersion := "1.0.0" 118 119 results, err := prOpts.CreatePullRequest("test", func(dir string, gitInfo *gits.GitRepository) (strings []string, e error) { 120 return []string{fromVersion}, nil 121 }) 122 assert.NoError(t, err) 123 assert.NotNil(t, results, "we must have results coming out of the PR creation") 124 125 prNumber := 1 126 assert.Equal(t, prNumber, *results.PullRequest.Number, "This should be PR number %d", prNumber) 127 128 assert.Equal(t, fmt.Sprintf("chore(deps): bump %s from %s to %s", prOpts.SrcGitURL, fromVersion, prOpts.Version), 129 results.PullRequestArguments.Title, "The PR title should contain the old and new versions") 130 131 assert.Equal(t, 1, len(results.PullRequest.Labels), "One label expected") 132 assert.Equal(t, "updatebot", *results.PullRequest.Labels[0].Name, "updatebot label should exist") 133 134 //create second PR with additional label 135 prOpts.GitURLs = []string{"testowner/testrepo"} 136 prOpts.Version = "4.0.0" 137 prOpts.Labels = []string{"test-label"} 138 139 labelResults, err := prOpts.CreatePullRequest("test", func(dir string, gitInfo *gits.GitRepository) (strings []string, e error) { 140 return []string{fromVersion}, nil 141 }) 142 assert.NoError(t, err) 143 assert.NotNil(t, labelResults, "we must have results coming out of the second PR creation") 144 145 prNumber = 2 146 assert.Equal(t, prNumber, *labelResults.PullRequest.Number, "This should be PR number %d", prNumber) 147 148 assert.Equal(t, fmt.Sprintf("chore(deps): bump %s from %s to %s", prOpts.SrcGitURL, fromVersion, prOpts.Version), 149 labelResults.PullRequestArguments.Title, "The PR title should contain the old and new versions") 150 151 assert.Equal(t, 2, len(labelResults.PullRequest.Labels), "Two labels expected") 152 prLabels := []string{} 153 for _, label := range labelResults.PullRequest.Labels { 154 prLabels = append(prLabels, *label.Name) 155 } 156 assert.Contains(t, prLabels, "updatebot", "updatebot label should exist") 157 assert.Contains(t, prLabels, prOpts.Labels[0], fmt.Sprintf("%s label should exist", prOpts.Labels[0])) 158 } 159 160 func TestCreatePullRequestWithMatrixUpdatePaths(t *testing.T) { 161 162 _, _, _, commonOpts, _ := getFakeClientsAndNs(t) 163 164 testOrgName := "testowner" 165 testRepoName := "testrepo" 166 167 commonOpts.SetGit(gits.NewGitFake()) 168 o := operations.PullRequestOperation{ 169 CommonOptions: &commonOpts, 170 } 171 172 viaRepo := "wiley" 173 toVersion := "3.0.0" 174 fromVersion := "1.0.0" 175 toTag := fmt.Sprintf("v%s", toVersion) 176 fromTag := fmt.Sprintf("v%s", fromVersion) 177 host := "fake.git" 178 updates := dependencymatrix.DependencyUpdates{ 179 Updates: []v1.DependencyUpdate{ 180 { 181 DependencyUpdateDetails: v1.DependencyUpdateDetails{ 182 Host: host, 183 Owner: testOrgName, 184 Repo: testRepoName, 185 URL: fmt.Sprintf("https://%s/%s/%s.git", host, testOrgName, testRepoName), 186 ToReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, testRepoName, toTag), 187 ToVersion: toVersion, 188 ToReleaseName: toVersion, 189 FromReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, testRepoName, fromTag), 190 FromReleaseName: fromVersion, 191 FromVersion: fromVersion, 192 }, 193 Paths: []v1.DependencyUpdatePath{ 194 { 195 { 196 Host: host, 197 Owner: testOrgName, 198 Repo: viaRepo, 199 URL: fmt.Sprintf("https://%s/%s/%s.git", host, testOrgName, viaRepo), 200 ToReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, viaRepo, toTag), 201 ToVersion: toVersion, 202 ToReleaseName: toVersion, 203 FromReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, viaRepo, fromTag), 204 FromReleaseName: fromVersion, 205 FromVersion: fromVersion, 206 }, 207 }, 208 }, 209 }, 210 }, 211 } 212 213 updateBytes, err := yaml.Marshal(updates) 214 assert.NoError(t, err) 215 216 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 217 w.Header().Set("Content-Type", "application/yaml") 218 w.WriteHeader(200) 219 fmt.Fprintf(w, string(updateBytes)) 220 })) 221 222 gitter := gits_test.NewMockGitter() 223 224 fakeRepo, _ := gits.NewFakeRepository(testOrgName, testRepoName, nil, nil) 225 fakeRepo.Releases = map[string]*gits.GitRelease{ 226 "release-1": { 227 Name: "Release 1", 228 TagName: "1.0.0", 229 HTMLURL: "fakeUrlv1", 230 }, 231 "release-3": { 232 Name: "Release 3", 233 TagName: "3.0.0", 234 HTMLURL: "fakeUrlv3", 235 Assets: &[]gits.GitReleaseAsset{ 236 { 237 ID: 1, 238 Name: dependencymatrix.DependencyUpdatesAssetName, 239 BrowserDownloadURL: server.URL, 240 ContentType: "application/json", 241 }, 242 }, 243 }, 244 } 245 fakeGitProvider := gits.NewFakeProvider(fakeRepo) 246 fakeGitProvider.User.Username = testOrgName 247 248 testhelpers.ConfigureTestOptionsWithResources(o.CommonOptions, 249 []runtime.Object{}, 250 []runtime.Object{}, 251 gitter, 252 fakeGitProvider, 253 nil, 254 resources_test.NewMockInstaller(), 255 ) 256 257 err = testhelpers.CreateTestEnvironmentDir(o.CommonOptions) 258 assert.NoError(t, err) 259 260 o.GitURLs = []string{"testowner/testrepo"} 261 o.SrcGitURL = "testowner/testrepo" 262 o.Version = "3.0.0" 263 264 pegomock.When(gitter.HasChanges(pegomock.AnyString())).ThenReturn(true, nil) 265 266 var results *gits.PullRequestInfo 267 268 logOutput := log.CaptureOutput(func() { 269 results, err = o.CreatePullRequest("test", func(dir string, gitInfo *gits.GitRepository) (strings []string, e error) { 270 return []string{"1.0.0", "v1.0.1", "2.0.0"}, nil 271 }) 272 assert.NoError(t, err) 273 assert.NotNil(t, results) 274 }) 275 276 assert.Contains(t, stripansi.Strip(logOutput), "Added label updatebot to Pull Request https://fake.git/testowner/testrepo/pulls/1", 277 "Updatebot label should be added to the PR") 278 279 assert.NotNil(t, results, "we must have results coming out of the PR creation") 280 assert.Equal(t, "chore(deps): bump testowner/testrepo from 1.0.0, 2.0.0 and v1.0.1 to 3.0.0", 281 results.PullRequestArguments.Title, "The PR title should contain the old and new versions") 282 } 283 284 func TestCreateDependencyUpdatePRDetails(t *testing.T) { 285 _, _, _, commonOpts, _ := getFakeClientsAndNs(t) 286 287 commonOpts.SetGit(gits.NewGitFake()) 288 o := operations.PullRequestOperation{ 289 CommonOptions: &commonOpts, 290 } 291 292 gitter := gits_test.NewMockGitter() 293 294 testOrgName := "testowner" 295 testRepoName := "testrepo" 296 gitRepo := fmt.Sprintf("%s/%s", testOrgName, testRepoName) 297 fakeRepo, _ := gits.NewFakeRepository(testOrgName, testRepoName, nil, nil) 298 fakeRepo.Releases = map[string]*gits.GitRelease{ 299 "release-1": { 300 Name: "Release 1", 301 TagName: "1.0.0", 302 HTMLURL: "fakeUrlv1", 303 }, 304 "release-2": { 305 Name: "Release 2", 306 TagName: "2.0.0", 307 HTMLURL: "fakeUrlv2", 308 Assets: &[]gits.GitReleaseAsset{ 309 { 310 ID: 1, 311 Name: "Asset1", 312 BrowserDownloadURL: "fakeURL", 313 ContentType: "application/json", 314 }, 315 }, 316 }, 317 } 318 fakeGitProvider := gits.NewFakeProvider(fakeRepo) 319 fakeGitProvider.User.Username = testOrgName 320 321 testhelpers.ConfigureTestOptionsWithResources(o.CommonOptions, 322 []runtime.Object{}, 323 []runtime.Object{}, 324 gitter, 325 fakeGitProvider, 326 nil, 327 resources_test.NewMockInstaller(), 328 ) 329 330 err := testhelpers.CreateTestEnvironmentDir(o.CommonOptions) 331 assert.NoError(t, err) 332 333 componentName := "testComponent" 334 fromVersion := "1.0.0" 335 toVersion := "2.0.0" 336 kind := "fakekind" 337 _, details, _, assets, err := o.CreateDependencyUpdatePRDetails(kind, gitRepo, "", fromVersion, toVersion, componentName) 338 339 assert.Contains(t, details.BranchName, fmt.Sprintf("bump-%s-version", kind)) 340 assert.Contains(t, details.Message, fmt.Sprintf("Update [%s](%s):%s from [%s](fakeUrlv1) to [%s](fakeUrlv2)", gitRepo, gitRepo, componentName, fromVersion, toVersion)) 341 assert.Len(t, assets, 1) 342 } 343 344 func TestAddDependencyMatrixUpdatePaths(t *testing.T) { 345 testOrgName := "testowner" 346 testRepoName := "testrepo" 347 viaRepo := "wiley" 348 toVersion := "3.0.0" 349 fromVersion := "1.0.0" 350 toTag := fmt.Sprintf("v%s", toVersion) 351 fromTag := fmt.Sprintf("v%s", fromVersion) 352 host := "fake.git" 353 updates := dependencymatrix.DependencyUpdates{ 354 Updates: []v1.DependencyUpdate{ 355 { 356 DependencyUpdateDetails: v1.DependencyUpdateDetails{ 357 Host: host, 358 Owner: testOrgName, 359 Repo: testRepoName, 360 URL: fmt.Sprintf("https://%s/%s/%s.git", host, testOrgName, testRepoName), 361 ToReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, testRepoName, toTag), 362 ToVersion: toVersion, 363 ToReleaseName: toVersion, 364 FromReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, testRepoName, fromTag), 365 FromReleaseName: fromVersion, 366 FromVersion: fromVersion, 367 }, 368 Paths: []v1.DependencyUpdatePath{ 369 { 370 { 371 Host: host, 372 Owner: testOrgName, 373 Repo: viaRepo, 374 URL: fmt.Sprintf("https://%s/%s/%s.git", host, testOrgName, viaRepo), 375 ToReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, viaRepo, toTag), 376 ToVersion: toVersion, 377 ToReleaseName: toVersion, 378 FromReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, viaRepo, fromTag), 379 FromReleaseName: fromVersion, 380 FromVersion: fromVersion, 381 }, 382 }, 383 }, 384 }, 385 }, 386 } 387 388 updateBytes, err := yaml.Marshal(updates) 389 assert.NoError(t, err) 390 391 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 392 w.Header().Set("Content-Type", "application/yaml") 393 w.WriteHeader(200) 394 fmt.Fprintf(w, string(updateBytes)) 395 })) 396 397 asset := &gits.GitReleaseAsset{ 398 ID: 1, 399 BrowserDownloadURL: server.URL, 400 ContentType: "application/yaml", 401 Name: dependencymatrix.DependencyUpdatesAssetName, 402 } 403 404 update := &v1.DependencyUpdate{ 405 DependencyUpdateDetails: v1.DependencyUpdateDetails{ 406 Host: host, 407 Owner: testOrgName, 408 Repo: testRepoName, 409 URL: fmt.Sprintf("https://%s/%s/%s.git", host, testOrgName, testRepoName), 410 ToReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, testRepoName, toTag), 411 ToVersion: "2,0,0", 412 ToReleaseName: "2,0,0", 413 FromReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, testRepoName, fromTag), 414 FromReleaseName: fromVersion, 415 FromVersion: fromVersion, 416 }, 417 Paths: []v1.DependencyUpdatePath{ 418 { 419 { 420 Host: host, 421 Owner: testOrgName, 422 Repo: viaRepo, 423 URL: fmt.Sprintf("https://%s/%s/%s.git", host, testOrgName, viaRepo), 424 ToReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, viaRepo, toTag), 425 ToVersion: "2,0,0", 426 ToReleaseName: "2,0,0", 427 FromReleaseHTMLURL: fmt.Sprintf("https://%s/%s/%s/releases/%s", host, testOrgName, viaRepo, fromTag), 428 FromReleaseName: fromVersion, 429 FromVersion: fromVersion, 430 }, 431 }, 432 }, 433 } 434 435 dependencyUpdate, err := operations.AddDependencyMatrixUpdatePaths(asset, update) 436 assert.NoError(t, err) 437 assert.Len(t, dependencyUpdate[0].Paths[0], 2) 438 } 439 440 // Helper method, not supposed to be a test by itself 441 func getFakeClientsAndNs(t *testing.T) (versioned.Interface, tektonclient.Interface, kubernetes.Interface, opts.CommonOptions, string) { 442 commonOpts := opts.NewCommonOptionsWithFactory(fake.NewFakeFactory()) 443 options := &commonOpts 444 testhelpers.ConfigureTestOptions(options, options.Git(), options.Helm()) 445 446 jxClient, ns, err := options.JXClientAndDevNamespace() 447 assert.NoError(t, err, "There shouldn't be any error getting the fake JXClient and DevEnv") 448 449 tektonClient, _, err := options.TektonClient() 450 assert.NoError(t, err, "There shouldn't be any error getting the fake Tekton Client") 451 452 kubeClient, err := options.KubeClient() 453 assert.NoError(t, err, "There shouldn't be any error getting the fake Kube Client") 454 455 return jxClient, tektonClient, kubeClient, commonOpts, ns 456 } 457 458 func TestCreatePullRequestBuildersFn(t *testing.T) { 459 fn := operations.CreatePullRequestBuildersFn("1.0.1") 460 dir, err := ioutil.TempDir("", "") 461 defer func() { 462 err := os.RemoveAll(dir) 463 assert.NoError(t, err) 464 }() 465 assert.NoError(t, err) 466 err = util.CopyDir(filepath.Join("testdata", "CreatePullRequestBuildersFn"), dir, true) 467 assert.NoError(t, err) 468 var gitInfo *gits.GitRepository 469 result, err := fn(dir, gitInfo) 470 assert.NoError(t, err) 471 tests.AssertFileContains(t, filepath.Join(dir, "docker", "gcr.io", "jenkinsxio", "builder-cf.yml"), "version: 1.0.1") 472 tests.AssertFileContains(t, filepath.Join(dir, "docker", "gcr.io", "jenkinsxio", "builder-dlang.yml"), "version: 1.0.1") 473 tests.AssertFileContains(t, filepath.Join(dir, "docker", "gcr.io", "jenkinsxio", "builder-base.yml"), "version: 0.0.1") 474 assert.Contains(t, result, "0.0.1") 475 assert.Contains(t, result, "0.0.2") 476 assert.Len(t, result, 2) 477 } 478 479 func TestCreatePullRequestGitReleasesFn(t *testing.T) { 480 t.Run("found", func(t *testing.T) { 481 pegomock.RegisterMockTestingT(t) 482 commonOpts := &opts.CommonOptions{} 483 gitter := gits.NewGitCLI() 484 roadRunnerOrg, err := gits.NewFakeRepository("acme", "roadrunner", func(dir string) error { 485 return ioutil.WriteFile(filepath.Join(dir, "README"), []byte("TODO"), 0600) 486 }, gitter) 487 assert.NoError(t, err) 488 gitProvider := gits.NewFakeProvider(roadRunnerOrg) 489 roadRunnerOrg.Releases["v1.2.3"] = &gits.GitRelease{ 490 Name: "1.2.3", 491 } 492 helmer := helm_test.NewMockHelmer() 493 494 testhelpers.ConfigureTestOptionsWithResources(commonOpts, 495 []runtime.Object{}, 496 []runtime.Object{ 497 kube.NewPermanentEnvironment("EnvWhereApplicationIsDeployed"), 498 }, 499 gitter, 500 gitProvider, 501 helmer, 502 resources_test.NewMockInstaller(), 503 ) 504 505 pro := operations.PullRequestOperation{ 506 CommonOptions: commonOpts, 507 SrcGitURL: "", 508 Version: "", 509 } 510 511 fn := pro.CreatePullRequestGitReleasesFn("fake.git/acme/roadrunner") 512 dir, err := ioutil.TempDir("", "") 513 defer func() { 514 err := os.RemoveAll(dir) 515 assert.NoError(t, err) 516 }() 517 assert.NoError(t, err) 518 err = util.CopyDir(filepath.Join("testdata", "CreatePullRequestGitReleasesFn"), dir, true) 519 assert.NoError(t, err) 520 oldVersions, err := fn(dir, nil) 521 assert.NoError(t, err) 522 assert.Len(t, oldVersions, 1) 523 assert.Equal(t, "1.2.2", oldVersions[0]) 524 tests.AssertFileContains(t, filepath.Join(dir, "git", "fake.git", "acme", "roadrunner.yml"), "version: 1.2.3") 525 }) 526 t.Run("not-found", func(t *testing.T) { 527 pegomock.RegisterMockTestingT(t) 528 commonOpts := &opts.CommonOptions{} 529 gitter := gits.NewGitCLI() 530 roadRunnerOrg, err := gits.NewFakeRepository("acme", "roadrunner", func(dir string) error { 531 return ioutil.WriteFile(filepath.Join(dir, "README"), []byte("TODO"), 0600) 532 }, gitter) 533 assert.NoError(t, err) 534 gitProvider := gits.NewFakeProvider(roadRunnerOrg) 535 helmer := helm_test.NewMockHelmer() 536 537 testhelpers.ConfigureTestOptionsWithResources(commonOpts, 538 []runtime.Object{}, 539 []runtime.Object{ 540 kube.NewPermanentEnvironment("EnvWhereApplicationIsDeployed"), 541 }, 542 gitter, 543 gitProvider, 544 helmer, 545 resources_test.NewMockInstaller(), 546 ) 547 548 pro := operations.PullRequestOperation{ 549 CommonOptions: commonOpts, 550 SrcGitURL: "", 551 Version: "", 552 } 553 554 fn := pro.CreatePullRequestGitReleasesFn("fake.git/acme/roadrunner") 555 dir, err := ioutil.TempDir("", "") 556 defer func() { 557 err := os.RemoveAll(dir) 558 assert.NoError(t, err) 559 }() 560 assert.NoError(t, err) 561 err = util.CopyDir(filepath.Join("testdata", "CreatePullRequestGitReleasesFn"), dir, true) 562 assert.NoError(t, err) 563 oldVersions, err := fn(dir, nil) 564 assert.Error(t, err) 565 assert.Len(t, oldVersions, 0) 566 tests.AssertFileContains(t, filepath.Join(dir, "git", "fake.git", "acme", "roadrunner.yml"), "version: 1.2.2") 567 }) 568 } 569 570 func TestCreatePullRequestRegexFn(t *testing.T) { 571 t.Run("capture-groups", func(t *testing.T) { 572 573 dir, err := ioutil.TempDir("", "") 574 defer func() { 575 err := os.RemoveAll(dir) 576 assert.NoError(t, err) 577 }() 578 assert.NoError(t, err) 579 err = util.CopyDir(filepath.Join("testdata", "CreatePullRequestRegexFn"), dir, true) 580 assert.NoError(t, err) 581 fn, err := operations.CreatePullRequestRegexFn("1.0.1", "^version: (.*)$", "builder-dlang.yml") 582 assert.NoError(t, err) 583 var gitInfo *gits.GitRepository 584 result, err := fn(dir, gitInfo) 585 assert.NoError(t, err) 586 tests.AssertFileContains(t, filepath.Join(dir, "builder-dlang.yml"), "version: 1.0.1") 587 assert.Contains(t, result, "0.0.1") 588 assert.Len(t, result, 1) 589 }) 590 t.Run("named-capture", func(t *testing.T) { 591 592 dir, err := ioutil.TempDir("", "") 593 defer func() { 594 err := os.RemoveAll(dir) 595 assert.NoError(t, err) 596 }() 597 assert.NoError(t, err) 598 err = util.CopyDir(filepath.Join("testdata", "CreatePullRequestRegexFn"), dir, true) 599 assert.NoError(t, err) 600 fn, err := operations.CreatePullRequestRegexFn("1.0.1", `^version: (?P<version>.*)$`, "builder-dlang.yml") 601 assert.NoError(t, err) 602 var gitInfo *gits.GitRepository 603 result, err := fn(dir, gitInfo) 604 assert.NoError(t, err) 605 tests.AssertFileContains(t, filepath.Join(dir, "builder-dlang.yml"), "version: 1.0.1") 606 assert.Contains(t, result, "0.0.1") 607 assert.Len(t, result, 1) 608 }) 609 t.Run("multiple-named-capture", func(t *testing.T) { 610 611 dir, err := ioutil.TempDir("", "") 612 defer func() { 613 err := os.RemoveAll(dir) 614 assert.NoError(t, err) 615 }() 616 assert.NoError(t, err) 617 err = util.CopyDir(filepath.Join("testdata", "CreatePullRequestRegexFn"), dir, true) 618 assert.NoError(t, err) 619 fn, err := operations.CreatePullRequestRegexFn("1.0.1", `(?m)^(\s*)version: (?P<version>.*)$`, "builder-cf.yml") 620 assert.NoError(t, err) 621 var gitInfo *gits.GitRepository 622 result, err := fn(dir, gitInfo) 623 assert.NoError(t, err) 624 tests.AssertFileContains(t, filepath.Join(dir, "builder-cf.yml"), `abc: 625 version: 1.0.1 626 def: 627 version: 1.0.1`) 628 assert.Contains(t, result, "0.0.1") 629 assert.Contains(t, result, "0.0.2") 630 assert.Len(t, result, 2) 631 }) 632 } 633 634 func TestCreateChartChangeFilesFn(t *testing.T) { 635 t.Run("from-chart-sources", func(t *testing.T) { 636 pegomock.RegisterMockTestingT(t) 637 helmer := helm_test.NewMockHelmer() 638 helm_test.StubFetchChart("acme/roadrunner", "1.0.1", "", &chart.Chart{ 639 Metadata: &chart.Metadata{ 640 Name: "roadrunner", 641 Version: "1.0.1", 642 Sources: []string{ 643 "https://fake.git/acme/roadrunner", 644 }, 645 }, 646 }, helmer) 647 vaultClient := vault_test.NewMockClient() 648 pro := operations.PullRequestOperation{} 649 fn := operations.CreateChartChangeFilesFn("acme/roadrunner", "1.0.1", "charts", &pro, helmer, vaultClient, util.IOFileHandles{}) 650 dir, err := ioutil.TempDir("", "") 651 defer func() { 652 err := os.RemoveAll(dir) 653 assert.NoError(t, err) 654 }() 655 assert.NoError(t, err) 656 err = util.CopyDir(filepath.Join("testdata/TestCreateChartChangeFilesFn"), dir, true) 657 assert.NoError(t, err) 658 answer, err := fn(dir, nil) 659 assert.NoError(t, err) 660 assert.Len(t, answer, 1) 661 assert.Contains(t, answer, "1.0.0") 662 tests.AssertFileContains(t, filepath.Join(dir, "charts", "acme", "roadrunner.yml"), "version: 1.0.1") 663 assert.Equal(t, "https://fake.git/acme/roadrunner", pro.SrcGitURL) 664 assert.Equal(t, "1.0.1", pro.Version) 665 }) 666 t.Run("from-versions", func(t *testing.T) { 667 pegomock.RegisterMockTestingT(t) 668 helmer := helm_test.NewMockHelmer() 669 helm_test.StubFetchChart("acme/wile", "1.0.1", "", &chart.Chart{ 670 Metadata: &chart.Metadata{ 671 Name: "wile", 672 Version: "1.0.1", 673 }, 674 }, helmer) 675 vaultClient := vault_test.NewMockClient() 676 pro := operations.PullRequestOperation{} 677 fn := operations.CreateChartChangeFilesFn("acme/wile", "1.0.1", "charts", &pro, helmer, vaultClient, util.IOFileHandles{}) 678 dir, err := ioutil.TempDir("", "") 679 defer func() { 680 err := os.RemoveAll(dir) 681 assert.NoError(t, err) 682 }() 683 assert.NoError(t, err) 684 err = util.CopyDir(filepath.Join("testdata/TestCreateChartChangeFilesFn"), dir, true) 685 assert.NoError(t, err) 686 answer, err := fn(dir, nil) 687 assert.NoError(t, err) 688 assert.Len(t, answer, 1) 689 assert.Contains(t, answer, "1.0.0") 690 tests.AssertFileContains(t, filepath.Join(dir, "charts", "acme", "wile.yml"), "version: 1.0.1") 691 assert.Equal(t, "https://fake.git/acme/wile", pro.SrcGitURL) 692 assert.Equal(t, "1.0.1", pro.Version) 693 }) 694 t.Run("latest", func(t *testing.T) { 695 pegomock.RegisterMockTestingT(t) 696 helmer := helm_test.NewMockHelmer() 697 pegomock.When(helmer.SearchCharts(pegomock.EqString("acme/wile"), pegomock.EqBool(true))).ThenReturn(pegomock.ReturnValue([]helm.ChartSummary{ 698 { 699 Name: "wile", 700 ChartVersion: "1.0.1", 701 AppVersion: "1.0.1", 702 Description: "", 703 }, 704 { 705 Name: "wile", 706 ChartVersion: "1.0.0", 707 AppVersion: "1.0.0", 708 Description: "", 709 }, 710 }), pegomock.ReturnValue(nil)) 711 helm_test.StubFetchChart("acme/wile", "1.0.1", "", &chart.Chart{ 712 Metadata: &chart.Metadata{ 713 Name: "wile", 714 Version: "1.0.1", 715 }, 716 }, helmer) 717 pegomock.When(helmer.IsRepoMissing("https://acme.com/charts")).ThenReturn(pegomock.ReturnValue(false), pegomock.ReturnValue("acme"), pegomock.ReturnValue(nil)) 718 vaultClient := vault_test.NewMockClient() 719 pro := operations.PullRequestOperation{} 720 fn := operations.CreateChartChangeFilesFn("acme/wile", "", "charts", &pro, helmer, vaultClient, util.IOFileHandles{}) 721 dir, err := ioutil.TempDir("", "") 722 defer func() { 723 err := os.RemoveAll(dir) 724 assert.NoError(t, err) 725 }() 726 assert.NoError(t, err) 727 err = util.CopyDir(filepath.Join("testdata/TestCreateChartChangeFilesFn"), dir, true) 728 assert.NoError(t, err) 729 answer, err := fn(dir, nil) 730 assert.NoError(t, err) 731 assert.Len(t, answer, 1) 732 assert.Contains(t, answer, "1.0.0") 733 tests.AssertFileContains(t, filepath.Join(dir, "charts", "acme", "wile.yml"), "version: 1.0.1") 734 assert.Equal(t, "https://fake.git/acme/wile", pro.SrcGitURL) 735 assert.Equal(t, "1.0.1", pro.Version) 736 }) 737 738 } 739 740 func TestPullRequestOperation_WrapChangeFilesWithCommitFn(t *testing.T) { 741 742 commonOpts := &opts.CommonOptions{} 743 gitter := gits.NewGitCLI() 744 roadRunnerOrg, err := gits.NewFakeRepository("acme", "roadrunner", func(dir string) error { 745 return ioutil.WriteFile(filepath.Join(dir, "README"), []byte("TODO"), 0600) 746 }, gitter) 747 assert.NoError(t, err) 748 wileOrg, err := gits.NewFakeRepository("acme", "wile", func(dir string) error { 749 return ioutil.WriteFile(filepath.Join(dir, "README"), []byte("TODO"), 0600) 750 }, gitter) 751 assert.NoError(t, err) 752 gitProvider := gits.NewFakeProvider(roadRunnerOrg, wileOrg) 753 helmer := helm_test.NewMockHelmer() 754 755 testhelpers.ConfigureTestOptionsWithResources(commonOpts, 756 []runtime.Object{}, 757 []runtime.Object{ 758 kube.NewPermanentEnvironment("EnvWhereApplicationIsDeployed"), 759 }, 760 gitter, 761 gitProvider, 762 helmer, 763 resources_test.NewMockInstaller(), 764 ) 765 766 wrapped := func(dir string, gitInfo *gits.GitRepository) ([]string, error) { 767 return []string{"1.2.2"}, ioutil.WriteFile(filepath.Join(dir, "test.yml"), []byte("version: 1.2.3"), 0600) 768 } 769 pro := operations.PullRequestOperation{ 770 CommonOptions: commonOpts, 771 SrcGitURL: "https://fake.git/acme/wile.git", 772 Version: "1.2.3", 773 } 774 775 dir, err := ioutil.TempDir("", "") 776 defer func() { 777 err := os.RemoveAll(dir) 778 assert.NoError(t, err) 779 }() 780 assert.NoError(t, err) 781 err = gitter.Init(dir) 782 assert.NoError(t, err) 783 err = ioutil.WriteFile(filepath.Join(dir, "test.yml"), []byte("1.2.2"), 0600) 784 assert.NoError(t, err) 785 err = gitter.Add(dir, "*") 786 assert.NoError(t, err) 787 err = gitter.CommitDir(dir, "Initial commit") 788 assert.NoError(t, err) 789 790 gitInfo, err := gits.ParseGitURL("https://fake.git/acme/roadrunner.git") 791 assert.NoError(t, err) 792 793 fn := pro.WrapChangeFilesWithCommitFn("charts", wrapped) 794 result, err := fn(dir, gitInfo) 795 assert.NoError(t, err) 796 assert.Len(t, result, 0) 797 tests.AssertFileContains(t, filepath.Join(dir, "test.yml"), "1.2.3") 798 msg, err := gitter.GetLatestCommitMessage(dir) 799 assert.NoError(t, err) 800 assert.True(t, strings.HasPrefix(msg, "chore(deps): bump acme/wile from 1.2.2 to 1.2.3")) 801 // Without AuthorName and AuthorEmail, there shouldn't be a Signed-off-by message. 802 assert.False(t, strings.Contains(msg, "Signed-off-by:")) 803 804 // Wrap another commit, but this time with AuthorName and AuthorEmail set. 805 wrappedWithAuthor := func(dir string, gitInfo *gits.GitRepository) ([]string, error) { 806 return []string{"1.2.3"}, ioutil.WriteFile(filepath.Join(dir, "test.yml"), []byte("version: 1.2.4"), 0600) 807 } 808 pro.AuthorEmail = "someone@example.com" 809 pro.AuthorName = "Some Author" 810 pro.Version = "1.2.4" 811 fnWithAuthor := pro.WrapChangeFilesWithCommitFn("charts", wrappedWithAuthor) 812 resultWithAuthor, err := fnWithAuthor(dir, gitInfo) 813 assert.NoError(t, err) 814 assert.Len(t, resultWithAuthor, 0) 815 tests.AssertFileContains(t, filepath.Join(dir, "test.yml"), "1.2.4") 816 msgWithAuthor, err := gitter.GetLatestCommitMessage(dir) 817 assert.NoError(t, err) 818 assert.True(t, strings.HasPrefix(msgWithAuthor, "chore(deps): bump acme/wile from 1.2.3 to 1.2.4")) 819 assert.True(t, strings.HasSuffix(msgWithAuthor, "Signed-off-by: Some Author <someone@example.com>")) 820 }