github.com/jenkins-x/jx/v2@v2.1.155/pkg/kube/activity_test.go (about) 1 // +build unit 2 3 package kube_test 4 5 import ( 6 "fmt" 7 "strconv" 8 "testing" 9 "time" 10 11 jenkinsio_v1 "github.com/jenkins-x/jx-api/pkg/apis/jenkins.io/v1" 12 v1 "github.com/jenkins-x/jx-api/pkg/apis/jenkins.io/v1" 13 jxfake "github.com/jenkins-x/jx-api/pkg/client/clientset/versioned/fake" 14 "github.com/jenkins-x/jx/v2/pkg/cmd/testhelpers" 15 "github.com/jenkins-x/jx/v2/pkg/gits" 16 appsv1 "k8s.io/api/apps/v1" 17 k8s_v1 "k8s.io/api/core/v1" 18 19 typev1 "github.com/jenkins-x/jx-api/pkg/client/clientset/versioned/typed/jenkins.io/v1" 20 "github.com/jenkins-x/jx/v2/pkg/cmd/clients" 21 "github.com/jenkins-x/jx/v2/pkg/cmd/opts" 22 "github.com/jenkins-x/jx/v2/pkg/kube" 23 "github.com/stretchr/testify/assert" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 kube_mocks "k8s.io/client-go/kubernetes/fake" 26 ) 27 28 func TestGenerateBuildNumber(t *testing.T) { 29 commonOpts := opts.NewCommonOptionsWithFactory(clients.NewFactory()) 30 options := &commonOpts 31 testhelpers.ConfigureTestOptions(options, options.Git(), options.Helm()) 32 33 jxClient, ns, err := options.JXClientAndDevNamespace() 34 assert.NoError(t, err, "Creating JX client") 35 if err != nil { 36 return 37 } 38 39 activities := jxClient.JenkinsV1().PipelineActivities(ns) 40 41 org := "jstrachan" 42 repo := "cheese" 43 branch := "master" 44 45 results := []string{} 46 expected := []string{} 47 for i := 1; i < 4; i++ { 48 buildNumberText := strconv.Itoa(i) 49 pID := kube.NewPipelineID(repo, org, branch) 50 pipelines := getPipelines(activities) 51 build, activity, err := kube.GenerateBuildNumber(activities, pipelines, pID) 52 if assert.NoError(t, err, "GenerateBuildNumber %d", i) { 53 if assert.NotNil(t, activity, "No PipelineActivity returned!") { 54 results = append(results, build) 55 assert.Equal(t, buildNumberText, activity.Spec.Build, "Build number for PipelineActivity %s", activity.Name) 56 } 57 } 58 expected = append(expected, buildNumberText) 59 } 60 assert.Equal(t, expected, results, "generated build numbers") 61 } 62 63 func getPipelines(activities typev1.PipelineActivityInterface) []*v1.PipelineActivity { 64 pipelineList, _ := activities.List(metav1.ListOptions{}) 65 pipelines := []*v1.PipelineActivity{} 66 for _, pipeline := range pipelineList.Items { 67 copy := pipeline 68 pipelines = append(pipelines, ©) 69 } 70 return pipelines 71 } 72 73 func TestCreateOrUpdateActivities(t *testing.T) { 74 t.Parallel() 75 76 nsObj := &k8s_v1.Namespace{ 77 ObjectMeta: metav1.ObjectMeta{ 78 Name: "jx-testing", 79 Namespace: "testing_ns", 80 }, 81 } 82 83 secret := &k8s_v1.Secret{} 84 mockKubeClient := kube_mocks.NewSimpleClientset(nsObj, secret) 85 86 ingressConfig := &k8s_v1.ConfigMap{ 87 ObjectMeta: metav1.ObjectMeta{ 88 Name: kube.ConfigMapIngressConfig, 89 }, 90 Data: map[string]string{"key1": "value1", "domain": "test-domain", "config.yml": ""}, 91 } 92 93 mockKubeClient.CoreV1().ConfigMaps(nsObj.Namespace).Create(ingressConfig) 94 mockTektonDeployment := &appsv1.Deployment{ 95 ObjectMeta: metav1.ObjectMeta{ 96 Name: kube.DeploymentTektonController, 97 }, 98 } 99 mockKubeClient.AppsV1().Deployments(nsObj.Namespace).Create(mockTektonDeployment) 100 jxClient := jxfake.NewSimpleClientset() 101 102 const ( 103 expectedName = "demo-2" 104 expectedBuild = "2" 105 expectedEnvironment = "staging" 106 expectedOrganisation = "test-org" 107 ) 108 expectedPipeline := expectedOrganisation + "/" + expectedName + "/master" 109 110 key := kube.PipelineActivityKey{ 111 Name: expectedName, 112 Pipeline: expectedPipeline, 113 Build: expectedBuild, 114 GitInfo: &gits.GitRepository{ 115 Name: expectedName, 116 Organisation: expectedOrganisation, 117 URL: "https://github.com/" + expectedOrganisation + "/" + expectedName, 118 }, 119 } 120 121 for i := 1; i < 3; i++ { 122 a, _, err := key.GetOrCreate(jxClient, nsObj.Namespace) 123 assert.Nil(t, err) 124 assert.Equal(t, expectedName, a.Name) 125 spec := &a.Spec 126 assert.Equal(t, expectedPipeline, spec.Pipeline) 127 assert.Equal(t, expectedBuild, spec.Build) 128 } 129 130 // lazy add a PromotePullRequest 131 promoteKey := kube.PromoteStepActivityKey{ 132 PipelineActivityKey: key, 133 Environment: expectedEnvironment, 134 } 135 136 promotePullRequestStarted := func(a *v1.PipelineActivity, s *v1.PipelineActivityStep, ps *v1.PromoteActivityStep, p *v1.PromotePullRequestStep) error { 137 assert.NotNil(t, a) 138 assert.NotNil(t, p) 139 if p.StartedTimestamp == nil { 140 p.StartedTimestamp = &metav1.Time{ 141 Time: time.Now(), 142 } 143 } 144 return nil 145 } 146 147 err := promoteKey.OnPromotePullRequest(mockKubeClient, jxClient, nsObj.Namespace, promotePullRequestStarted) 148 assert.Nil(t, err) 149 150 promoteStarted := func(a *v1.PipelineActivity, s *v1.PipelineActivityStep, ps *v1.PromoteActivityStep, p *v1.PromoteUpdateStep) error { 151 assert.NotNil(t, a) 152 assert.NotNil(t, p) 153 kube.CompletePromotionUpdate(a, s, ps, p) 154 return nil 155 } 156 157 err = promoteKey.OnPromoteUpdate(mockKubeClient, jxClient, nsObj.Namespace, promoteStarted) 158 assert.Nil(t, err) 159 160 // lets validate that we added a PromotePullRequest step 161 a, err := jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Get(expectedName, metav1.GetOptions{}) 162 assert.NotNil(t, a, "should have a PipelineActivity for %s", expectedName) 163 steps := a.Spec.Steps 164 assert.Equal(t, 2, len(steps), "Should have 2 steps!") 165 step := a.Spec.Steps[0] 166 stage := step.Stage 167 assert.NotNil(t, stage, "step 0 should have a Stage") 168 assert.Equal(t, v1.ActivityStepKindTypeStage, step.Kind, "step - kind") 169 assert.Equal(t, v1.ActivityStatusTypeSucceeded, stage.Status, "step 0 Stage status") 170 assert.NotNil(t, stage.StartedTimestamp, "stage should have a StartedTimestamp") 171 assert.NotNil(t, stage.CompletedTimestamp, "stage should have a CompletedTimestamp") 172 173 step = a.Spec.Steps[1] 174 promote := step.Promote 175 assert.NotNil(t, promote, "step 1 should have a Promote") 176 assert.Equal(t, v1.ActivityStepKindTypePromote, step.Kind, "step 1 kind") 177 178 pullRequestStep := promote.PullRequest 179 assert.NotNil(t, pullRequestStep, "Promote should have a PullRequest") 180 assert.NotNil(t, pullRequestStep.StartedTimestamp, "Promote should have a PullRequest.StartedTimestamp") 181 assert.NotNil(t, pullRequestStep.CompletedTimestamp, "Promote should not have a PullRequest.CompletedTimestamp") 182 183 updateStep := promote.Update 184 assert.NotNil(t, updateStep, "Promote should have an Update") 185 assert.NotNil(t, updateStep.StartedTimestamp, "Promote should have a Update.StartedTimestamp") 186 assert.NotNil(t, updateStep.CompletedTimestamp, "Promote should have a Update.CompletedTimestamp") 187 188 assert.NotNil(t, promote.StartedTimestamp, "promote should have a StartedTimestamp") 189 assert.NotNil(t, promote.CompletedTimestamp, "promote should have a CompletedTimestamp") 190 191 assert.Equal(t, v1.ActivityStatusTypeSucceeded, pullRequestStep.Status, "pullRequestStep status") 192 assert.Equal(t, v1.ActivityStatusTypeSucceeded, updateStep.Status, "updateStep status") 193 assert.Equal(t, v1.ActivityStatusTypeSucceeded, promote.Status, "promote status") 194 assert.Equal(t, v1.ActivityStatusTypeSucceeded, a.Spec.Status, "activity status") 195 196 //tests.Debugf("Has Promote %#v\n", promote) 197 } 198 199 func TestCreateOrUpdateActivityForBatchBuild(t *testing.T) { 200 t.Parallel() 201 202 nsObj := &k8s_v1.Namespace{ 203 ObjectMeta: metav1.ObjectMeta{ 204 Name: "jx-testing", 205 Namespace: "testing_ns", 206 }, 207 } 208 209 jxClient := jxfake.NewSimpleClientset() 210 211 const ( 212 expectedName = "demo-2" 213 expectedBuild = "2" 214 expectedOrganisation = "test-org" 215 ) 216 expectedPipeline := expectedOrganisation + "/" + expectedName + "/master" 217 218 key := kube.PipelineActivityKey{ 219 Name: expectedName, 220 Pipeline: expectedPipeline, 221 Build: expectedBuild, 222 GitInfo: &gits.GitRepository{ 223 Name: expectedName, 224 Organisation: expectedOrganisation, 225 URL: "https://github.com/" + expectedOrganisation + "/" + expectedName, 226 }, 227 PullRefs: map[string]string{ 228 "1": "sha1", 229 "2": "sha2", 230 }, 231 } 232 233 _, err := jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Create(&v1.PipelineActivity{ 234 ObjectMeta: metav1.ObjectMeta{ 235 Name: "PA0", 236 Labels: map[string]string{ 237 "lastCommitSha": "sha1", 238 "branch": "PR-1", 239 }, 240 }, 241 Spec: v1.PipelineActivitySpec{ 242 Build: "1", 243 }, 244 }) 245 assert.NoError(t, err) 246 247 // lets create a build PA for the same PR but with a different SHA so we can check we discard it later 248 _, err = jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Create(&v1.PipelineActivity{ 249 ObjectMeta: metav1.ObjectMeta{ 250 Name: "PA0-2", 251 Labels: map[string]string{ 252 "lastCommitSha": "sha3", 253 "branch": "PR-1", 254 }, 255 }, 256 Spec: v1.PipelineActivitySpec{ 257 Build: "5", 258 }, 259 }) 260 assert.NoError(t, err) 261 262 //lets create a few "builds" for PR-2 with the same SHA so we can check if we choose the right one 263 for i := 1; i < 4; i++ { 264 _, err = jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Create(&v1.PipelineActivity{ 265 ObjectMeta: metav1.ObjectMeta{ 266 Name: fmt.Sprintf("PA%d", i), 267 Labels: map[string]string{ 268 "lastCommitSha": "sha2", 269 "branch": "PR-2", 270 }, 271 }, 272 Spec: v1.PipelineActivitySpec{ 273 Build: strconv.Itoa(i), 274 }, 275 }) 276 assert.NoError(t, err) 277 } 278 279 a, _, err := key.GetOrCreate(jxClient, nsObj.Namespace) 280 assert.Nil(t, err) 281 assert.Equal(t, expectedName, a.Name) 282 spec := &a.Spec 283 assert.Equal(t, expectedPipeline, spec.Pipeline) 284 assert.Equal(t, expectedBuild, spec.Build) 285 286 pa1, err := jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Get("PA0", metav1.GetOptions{}) 287 assert.NoError(t, err) 288 289 pa3, err := jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Get("PA3", metav1.GetOptions{}) 290 assert.NoError(t, err) 291 292 assert.Len(t, a.Spec.BatchPipelineActivity.ComprisingPulLRequests, 2, "There should be %d PRs information in the ComprisingPullRequests property", 2) 293 exists := false 294 for _, i := range a.Spec.BatchPipelineActivity.ComprisingPulLRequests { 295 if i.PullRequestNumber == "PR-1" { 296 assert.NotEqual(t, "5", i.LastBuildNumberForCommit) 297 } 298 if i.PullRequestNumber == "PR-2" { 299 exists = true 300 assert.Equal(t, "3", i.LastBuildNumberForCommit) 301 assert.Equal(t, "sha2", i.LastBuildSHA) 302 } 303 } 304 assert.True(t, exists, "There should be a Pull Request called PR-2 within the ComprisingPullRequests property") 305 assert.Equal(t, expectedBuild, pa1.Spec.BatchPipelineActivity.BatchBuildNumber, "The batch build number that is going to merge this PR should be %s", expectedBuild) 306 assert.Equal(t, expectedBuild, pa3.Spec.BatchPipelineActivity.BatchBuildNumber, "The batch build number that is going to merge this PR should be %s", expectedBuild) 307 } 308 309 func TestCreateOrUpdateActivityForBatchBuildWithoutExistingActivities(t *testing.T) { 310 t.Parallel() 311 312 nsObj := &k8s_v1.Namespace{ 313 ObjectMeta: metav1.ObjectMeta{ 314 Name: "jx-testing", 315 Namespace: "testing_ns", 316 }, 317 } 318 319 jxClient := jxfake.NewSimpleClientset() 320 321 const ( 322 expectedName = "demo-2" 323 expectedBuild = "2" 324 expectedOrganisation = "test-org" 325 ) 326 expectedPipeline := expectedOrganisation + "/" + expectedName + "/master" 327 328 key := kube.PipelineActivityKey{ 329 Name: expectedName, 330 Pipeline: expectedPipeline, 331 Build: expectedBuild, 332 GitInfo: &gits.GitRepository{ 333 Name: expectedName, 334 Organisation: expectedOrganisation, 335 URL: "https://github.com/" + expectedOrganisation + "/" + expectedName, 336 }, 337 PullRefs: map[string]string{ 338 "1": "sha1", 339 "2": "sha2", 340 }, 341 } 342 343 //lets create a few "builds" for PR-2 with the same SHA so we can check if we choose the right one 344 for i := 1; i < 4; i++ { 345 _, err := jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Create(&v1.PipelineActivity{ 346 ObjectMeta: metav1.ObjectMeta{ 347 Name: fmt.Sprintf("PA%d", i), 348 Labels: map[string]string{ 349 "lastCommitSha": "sha2", 350 "branch": "PR-2", 351 }, 352 }, 353 Spec: v1.PipelineActivitySpec{ 354 Build: strconv.Itoa(i), 355 }, 356 }) 357 assert.NoError(t, err) 358 } 359 360 a, _, err := key.GetOrCreate(jxClient, nsObj.Namespace) 361 assert.Nil(t, err) 362 assert.Equal(t, expectedName, a.Name) 363 spec := &a.Spec 364 assert.Equal(t, expectedPipeline, spec.Pipeline) 365 assert.Equal(t, expectedBuild, spec.Build) 366 367 pa3, err := jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Get("PA3", metav1.GetOptions{}) 368 assert.NoError(t, err) 369 370 assert.Len(t, a.Spec.BatchPipelineActivity.ComprisingPulLRequests, 1, "There should be %d PRs information in the ComprisingPullRequests property", 1) 371 exists := false 372 for _, i := range a.Spec.BatchPipelineActivity.ComprisingPulLRequests { 373 if i.PullRequestNumber == "PR-2" { 374 exists = true 375 assert.Equal(t, "3", i.LastBuildNumberForCommit) 376 } 377 } 378 assert.True(t, exists, "There should be a Pull Request called PR-2 within the ComprisingPullRequests property") 379 assert.Equal(t, expectedBuild, pa3.Spec.BatchPipelineActivity.BatchBuildNumber, "The batch build number that is going to merge this PR should be %s", expectedBuild) 380 } 381 382 func TestCreateOrUpdatePRActivityWithLastCommitSHA(t *testing.T) { 383 t.Parallel() 384 385 nsObj := &k8s_v1.Namespace{ 386 ObjectMeta: metav1.ObjectMeta{ 387 Name: "jx-testing", 388 Namespace: "testing_ns", 389 }, 390 } 391 392 jxClient := jxfake.NewSimpleClientset() 393 394 const ( 395 expectedName = "demo-2" 396 expectedBuild = "2" 397 expectedOrganisation = "test-org" 398 ) 399 expectedPipeline := expectedOrganisation + "/" + expectedName + "/master" 400 401 key := kube.PipelineActivityKey{ 402 Name: expectedName, 403 Pipeline: expectedPipeline, 404 Build: expectedBuild, 405 GitInfo: &gits.GitRepository{ 406 Name: expectedName, 407 Organisation: expectedOrganisation, 408 URL: "https://github.com/" + expectedOrganisation + "/" + expectedName, 409 }, 410 PullRefs: map[string]string{ 411 "1": "sha1", 412 }, 413 } 414 415 a, _, err := key.GetOrCreate(jxClient, nsObj.Namespace) 416 assert.Nil(t, err) 417 assert.Equal(t, expectedName, a.Name) 418 spec := &a.Spec 419 assert.Equal(t, expectedPipeline, spec.Pipeline) 420 assert.Equal(t, expectedBuild, spec.Build) 421 422 assert.Equal(t, "sha1", a.ObjectMeta.Labels[v1.LabelLastCommitSha]) 423 } 424 425 func TestBatchReconciliationWithTwoPRBuildExecutions(t *testing.T) { 426 t.Parallel() 427 428 nsObj := &k8s_v1.Namespace{ 429 ObjectMeta: metav1.ObjectMeta{ 430 Name: "jx-testing", 431 Namespace: "testing_ns", 432 }, 433 } 434 435 jxClient := jxfake.NewSimpleClientset() 436 437 const ( 438 expectedName = "demo-2" 439 expectedBuild = "2" 440 expectedOrganisation = "test-org" 441 expectedBatchBuild = "1" 442 ) 443 444 prPAName := fmt.Sprintf("%s-%s-pr1-1", expectedOrganisation, expectedName) 445 pr1PA := &v1.PipelineActivity{ 446 ObjectMeta: metav1.ObjectMeta{ 447 Name: prPAName, 448 Labels: map[string]string{ 449 v1.LabelBranch: "PR-1", 450 v1.LabelLastCommitSha: "sha1", 451 v1.LabelBuild: "1", 452 }, 453 }, 454 Spec: v1.PipelineActivitySpec{ 455 GitOwner: expectedOrganisation, 456 GitRepository: expectedName, 457 Build: "1", 458 BatchPipelineActivity: v1.BatchPipelineActivity{ 459 BatchBuildNumber: expectedBatchBuild, 460 }, 461 }, 462 } 463 464 _, err := jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Create(pr1PA) 465 assert.NoError(t, err) 466 467 batchPAName := fmt.Sprintf("%s-%s-batch-1", expectedOrganisation, expectedName) 468 batchPA := &v1.PipelineActivity{ 469 ObjectMeta: metav1.ObjectMeta{ 470 Name: batchPAName, 471 Labels: map[string]string{ 472 v1.LabelBranch: "batch", 473 v1.LabelLastCommitSha: "testSha", 474 v1.LabelBuild: expectedBatchBuild, 475 }, 476 }, 477 Spec: v1.PipelineActivitySpec{ 478 GitOwner: expectedOrganisation, 479 GitRepository: expectedName, 480 Build: expectedBatchBuild, 481 BatchPipelineActivity: v1.BatchPipelineActivity{ 482 ComprisingPulLRequests: []v1.PullRequestInfo{ 483 {PullRequestNumber: "PR-1", LastBuildNumberForCommit: "1"}, 484 }, 485 }, 486 }, 487 } 488 489 _, err = jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Create(batchPA) 490 assert.NoError(t, err) 491 492 expectedPipeline := expectedOrganisation + "/" + expectedName + "/PR-1" 493 key := kube.PipelineActivityKey{ 494 Name: expectedName, 495 Pipeline: expectedPipeline, 496 Build: expectedBuild, 497 GitInfo: &gits.GitRepository{ 498 Name: expectedName, 499 Organisation: expectedOrganisation, 500 URL: "https://github.com/" + expectedOrganisation + "/" + expectedName, 501 }, 502 PullRefs: map[string]string{ 503 expectedBuild: "sha1", 504 }, 505 } 506 507 a, _, err := key.GetOrCreate(jxClient, nsObj.Namespace) 508 assert.Nil(t, err) 509 assert.Equal(t, expectedBatchBuild, a.Spec.BatchPipelineActivity.BatchBuildNumber, "The batch build in the BatchPipeline of the PR should be 1") 510 511 o := metav1.GetOptions{} 512 batchPA, err = jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Get(batchPAName, o) 513 assert.Equal(t, expectedBuild, batchPA.Spec.BatchPipelineActivity.ComprisingPulLRequests[0].LastBuildNumberForCommit, "The build number for the comprising PR should be 2") 514 515 pr1PA, err = jxClient.JenkinsV1().PipelineActivities(nsObj.Namespace).Get(prPAName, o) 516 assert.Empty(t, pr1PA.Spec.BatchPipelineActivity.BatchBuildNumber, "The batch build number for the second PR should be empty") 517 518 assert.Equal(t, expectedBatchBuild, a.Spec.BatchPipelineActivity.BatchBuildNumber, "The batch build number for the second execution of the PR should be 1") 519 } 520 521 func TestCreatePipelineDetails(t *testing.T) { 522 expectedGitOwner := "jstrachan" 523 expectedGitRepo := "myapp" 524 expectedBranch := "master" 525 expectedPipeline := expectedGitOwner + "/" + expectedGitRepo + "/" + expectedBranch 526 expectedBuild := "3" 527 expectedContext := "release" 528 529 pipelines := []*v1.PipelineActivity{ 530 { 531 ObjectMeta: metav1.ObjectMeta{ 532 Name: "a1", 533 }, 534 Spec: v1.PipelineActivitySpec{ 535 Pipeline: expectedPipeline, 536 Build: expectedBuild, 537 }, 538 }, 539 { 540 ObjectMeta: metav1.ObjectMeta{ 541 Name: "a2", 542 }, 543 Spec: v1.PipelineActivitySpec{ 544 GitOwner: expectedGitOwner, 545 GitRepository: expectedGitRepo, 546 Build: expectedBuild, 547 Context: expectedContext, 548 }, 549 }, 550 } 551 for _, pipeline := range pipelines { 552 d1 := kube.CreatePipelineDetails(pipeline) 553 name := pipeline.Name 554 if assert.NotNil(t, d1, "%s did not create a PipelineDetails", name) { 555 assert.Equal(t, expectedGitOwner, d1.GitOwner, "%s GitOwner", name) 556 assert.Equal(t, expectedGitRepo, d1.GitRepository, "%s GitRepository", name) 557 assert.Equal(t, expectedBranch, d1.BranchName, "%s BranchName", name) 558 assert.Equal(t, expectedPipeline, d1.Pipeline, "%s Pipeline", name) 559 assert.Equal(t, expectedBuild, d1.Build, "%s Build", name) 560 if pipeline.Spec.Context != "" { 561 assert.Equal(t, expectedContext, d1.Context, "%s Context", name) 562 } 563 } 564 } 565 } 566 567 func TestPipelineID(t *testing.T) { 568 t.Parallel() 569 570 // A simple ID. 571 pID := kube.NewPipelineID("o1", "r1", "b1") 572 validatePipelineID(t, pID, "o1/r1/b1", "o1-r1-b1") 573 574 // Upper case allowed in our ID, but not in the K8S 'name'. 575 pID = kube.NewPipelineID("OwNeR1", "rEpO1", "BrAnCh1") 576 validatePipelineID(t, pID, "OwNeR1/rEpO1/BrAnCh1", "owner1-repo1-branch1") 577 578 //Punctuation other than '-' and '.' not allowed in K8S 'name'. Note that this isn't currently handled by the 579 //system - the illegal characters are not yet encoded & will be rejected by K8S. 580 pID = kube.NewPipelineID("O/N!R@1", "therepo", "thebranch") 581 validatePipelineID(t, pID, "O/N!R@1/therepo/thebranch", "o-n!r@1-therepo-thebranch") 582 } 583 584 func TestSortActivities(t *testing.T) { 585 t.Parallel() 586 date1 := metav1.Date(2009, time.September, 10, 23, 0, 0, 0, time.UTC) 587 date2 := metav1.Date(2009, time.October, 10, 23, 0, 0, 0, time.UTC) 588 date3 := metav1.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) 589 date4 := metav1.Date(2009, time.December, 10, 23, 0, 0, 0, time.UTC) 590 591 activities := []jenkinsio_v1.PipelineActivity{ 592 { 593 ObjectMeta: metav1.ObjectMeta{ 594 Name: "a1", 595 }, 596 Spec: v1.PipelineActivitySpec{ 597 StartedTimestamp: &date3, 598 }, 599 }, 600 { 601 ObjectMeta: metav1.ObjectMeta{ 602 Name: "a2", 603 }, 604 Spec: v1.PipelineActivitySpec{ 605 StartedTimestamp: &date2, 606 }, 607 }, 608 { 609 ObjectMeta: metav1.ObjectMeta{ 610 Name: "a3", 611 }, 612 Spec: v1.PipelineActivitySpec{ 613 StartedTimestamp: &date1, 614 }, 615 }, 616 { 617 ObjectMeta: metav1.ObjectMeta{ 618 Name: "a4", 619 }, 620 Spec: v1.PipelineActivitySpec{ 621 StartedTimestamp: &date4, 622 }, 623 }, 624 } 625 626 kube.SortActivities(activities) 627 628 assert.Equal(t, "a3", activities[0].Name, "Activity 0") 629 assert.Equal(t, "a2", activities[1].Name, "Activity 1") 630 assert.Equal(t, "a1", activities[2].Name, "Activity 2") 631 assert.Equal(t, "a4", activities[3].Name, "Activity 3") 632 } 633 634 func TestSortActivitiesWithPendingCases(t *testing.T) { 635 t.Parallel() 636 date1 := metav1.Date(2009, time.September, 10, 23, 0, 0, 0, time.UTC) 637 date2 := metav1.Date(2009, time.October, 10, 23, 0, 0, 0, time.UTC) 638 date3 := metav1.Date(2009, time.November, 10, 23, 0, 0, 0, time.UTC) 639 640 activities := []jenkinsio_v1.PipelineActivity{ 641 { 642 ObjectMeta: metav1.ObjectMeta{ 643 Name: "a1", 644 }, 645 Spec: v1.PipelineActivitySpec{ 646 StartedTimestamp: &date3, 647 }, 648 }, 649 { 650 ObjectMeta: metav1.ObjectMeta{ 651 Name: "a2", 652 }, 653 Spec: v1.PipelineActivitySpec{ 654 StartedTimestamp: &date2, 655 }, 656 }, 657 { 658 ObjectMeta: metav1.ObjectMeta{ 659 Name: "a3", 660 }, 661 Spec: v1.PipelineActivitySpec{ 662 StartedTimestamp: &date1, 663 }, 664 }, 665 { 666 ObjectMeta: metav1.ObjectMeta{ 667 Name: "p", 668 }, 669 Spec: v1.PipelineActivitySpec{ 670 StartedTimestamp: nil, 671 }, 672 }, 673 } 674 675 kube.SortActivities(activities) 676 677 assert.Equal(t, "a3", activities[0].Name, "Activity 0") 678 assert.Equal(t, "a2", activities[1].Name, "Activity 1") 679 assert.Equal(t, "a1", activities[2].Name, "Activity 2") 680 assert.Equal(t, "p", activities[3].Name, "Activity 3") 681 } 682 683 func validatePipelineID(t *testing.T, pID kube.PipelineID, expectedID string, expectedName string) { 684 assert.Equal(t, expectedID, pID.ID) 685 assert.Equal(t, expectedName, pID.Name) 686 }