github.com/IBM-Blockchain/fabric-operator@v1.0.4/controllers/ibporderer/ibporderer_controller_test.go (about) 1 /* 2 * Copyright contributors to the Hyperledger Fabric Operator project 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package ibporderer 20 21 import ( 22 "context" 23 "encoding/json" 24 "errors" 25 "fmt" 26 "sync" 27 "time" 28 29 . "github.com/onsi/ginkgo/v2" 30 . "github.com/onsi/gomega" 31 "k8s.io/utils/pointer" 32 33 current "github.com/IBM-Blockchain/fabric-operator/api/v1beta1" 34 orderermocks "github.com/IBM-Blockchain/fabric-operator/controllers/ibporderer/mocks" 35 "github.com/IBM-Blockchain/fabric-operator/controllers/mocks" 36 v1 "github.com/IBM-Blockchain/fabric-operator/pkg/apis/orderer/v1" 37 config "github.com/IBM-Blockchain/fabric-operator/pkg/initializer/orderer/config/v1" 38 "github.com/IBM-Blockchain/fabric-operator/pkg/offering/common" 39 "github.com/IBM-Blockchain/fabric-operator/pkg/operatorerrors" 40 corev1 "k8s.io/api/core/v1" 41 k8serror "k8s.io/apimachinery/pkg/api/errors" 42 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 43 "k8s.io/apimachinery/pkg/runtime" 44 "k8s.io/apimachinery/pkg/types" 45 "sigs.k8s.io/controller-runtime/pkg/client" 46 "sigs.k8s.io/controller-runtime/pkg/event" 47 "sigs.k8s.io/controller-runtime/pkg/reconcile" 48 ) 49 50 var _ = Describe("ReconcileIBPOrderer", func() { 51 const ( 52 testRoleBindingFile = "../../../definitions/orderer/rolebinding.yaml" 53 testServiceAccountFile = "../../../definitions/orderer/serviceaccount.yaml" 54 ) 55 56 var ( 57 reconciler *ReconcileIBPOrderer 58 request reconcile.Request 59 mockKubeClient *mocks.Client 60 mockOrdererReconcile *orderermocks.OrdererReconcile 61 instance *current.IBPOrderer 62 ) 63 64 BeforeEach(func() { 65 mockKubeClient = &mocks.Client{} 66 mockOrdererReconcile = &orderermocks.OrdererReconcile{} 67 nodeNumber := 1 68 instance = ¤t.IBPOrderer{ 69 Spec: current.IBPOrdererSpec{ 70 ClusterSize: 3, 71 NodeNumber: &nodeNumber, 72 }, 73 } 74 instance.Name = "test-orderer" 75 76 mockKubeClient.GetStub = func(ctx context.Context, types types.NamespacedName, obj client.Object) error { 77 switch obj.(type) { 78 case *current.IBPOrderer: 79 o := obj.(*current.IBPOrderer) 80 o.Kind = "IBPOrderer" 81 o.Name = instance.Name 82 83 instance.Status = o.Status 84 } 85 return nil 86 } 87 88 mockKubeClient.UpdateStatusStub = func(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error { 89 switch obj.(type) { 90 case *current.IBPOrderer: 91 o := obj.(*current.IBPOrderer) 92 instance.Status = o.Status 93 } 94 return nil 95 } 96 97 mockKubeClient.ListStub = func(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error { 98 switch obj.(type) { 99 case *corev1.NodeList: 100 nodeList := obj.(*corev1.NodeList) 101 node := corev1.Node{} 102 node.Labels = map[string]string{} 103 node.Labels["topology.kubernetes.io/zone"] = "dal" 104 node.Labels["topology.kubernetes.io/region"] = "us-south" 105 nodeList.Items = append(nodeList.Items, node) 106 case *current.IBPOrdererList: 107 ordererList := obj.(*current.IBPOrdererList) 108 o1 := current.IBPOrderer{} 109 o1.Name = "test-orderer1" 110 o2 := current.IBPOrderer{} 111 o2.Name = "test-orderer2" 112 o3 := current.IBPOrderer{} 113 o3.Name = "test-orderer2" 114 ordererList.Items = []current.IBPOrderer{o1, o2, o3} 115 } 116 return nil 117 } 118 119 reconciler = &ReconcileIBPOrderer{ 120 Offering: mockOrdererReconcile, 121 client: mockKubeClient, 122 scheme: &runtime.Scheme{}, 123 update: map[string][]Update{}, 124 mutex: &sync.Mutex{}, 125 } 126 request = reconcile.Request{ 127 NamespacedName: types.NamespacedName{ 128 Namespace: "test-namespace", 129 Name: "test", 130 }, 131 } 132 }) 133 134 Context("Reconciles", func() { 135 It("does not return an error if the custom resource is 'not found'", func() { 136 notFoundErr := &k8serror.StatusError{ 137 ErrStatus: metav1.Status{ 138 Reason: metav1.StatusReasonNotFound, 139 }, 140 } 141 mockKubeClient.GetReturns(notFoundErr) 142 _, err := reconciler.Reconcile(context.TODO(), request) 143 Expect(err).NotTo(HaveOccurred()) 144 }) 145 146 It("returns an error if the request to get custom resource return any other error besides 'not found'", func() { 147 alreadyExistsErr := &k8serror.StatusError{ 148 ErrStatus: metav1.Status{ 149 Message: "already exists", 150 Reason: metav1.StatusReasonAlreadyExists, 151 }, 152 } 153 mockKubeClient.GetReturns(alreadyExistsErr) 154 _, err := reconciler.Reconcile(context.TODO(), request) 155 Expect(err).To(HaveOccurred()) 156 Expect(err.Error()).To(Equal("already exists")) 157 }) 158 159 It("returns an error if it encountered a non-breaking error", func() { 160 errMsg := "failed to reconcile deployment encountered breaking error" 161 mockOrdererReconcile.ReconcileReturns(common.Result{}, errors.New(errMsg)) 162 _, err := reconciler.Reconcile(context.TODO(), request) 163 Expect(err).To(HaveOccurred()) 164 Expect(err.Error()).To(Equal(fmt.Sprintf("Orderer instance '%s' encountered error: %s", instance.Name, errMsg))) 165 }) 166 167 It("does not return an error if it encountered a breaking error", func() { 168 mockOrdererReconcile.ReconcileReturns(common.Result{}, operatorerrors.New(operatorerrors.InvalidDeploymentCreateRequest, "failed to reconcile deployment encountered breaking error")) 169 _, err := reconciler.Reconcile(context.TODO(), request) 170 Expect(err).NotTo(HaveOccurred()) 171 }) 172 173 Context("set status", func() { 174 It("sets the status to error if error occured during IBPOrderer reconciliation", func() { 175 reconciler.SetStatus(instance, nil, errors.New("ibporderer error")) 176 Expect(instance.Status.Type).To(Equal(current.Error)) 177 Expect(instance.Status.Message).To(Equal("ibporderer error")) 178 }) 179 180 It("sets the status to deploying if pod is not yet running", func() { 181 mockKubeClient.ListStub = func(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error { 182 switch obj.(type) { 183 case *corev1.PodList: 184 podList := obj.(*corev1.PodList) 185 pod := corev1.Pod{} 186 podList.Items = append(podList.Items, pod) 187 return nil 188 case *current.IBPOrdererList: 189 ordererList := obj.(*current.IBPOrdererList) 190 orderer := current.IBPOrderer{} 191 orderer.Status = current.IBPOrdererStatus{ 192 CRStatus: current.CRStatus{ 193 Type: current.Deploying, 194 }, 195 } 196 ordererList.Items = append(ordererList.Items, orderer) 197 return nil 198 } 199 return nil 200 } 201 202 reconciler.SetStatus(instance, nil, nil) 203 Expect(instance.Status.Type).To(Equal(current.Deploying)) 204 }) 205 206 It("sets the status to deployed if pod is running", func() { 207 mockKubeClient.ListStub = func(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error { 208 switch obj.(type) { 209 case *corev1.PodList: 210 podList := obj.(*corev1.PodList) 211 pod := corev1.Pod{ 212 Status: corev1.PodStatus{ 213 Phase: corev1.PodRunning, 214 }, 215 } 216 podList.Items = append(podList.Items, pod) 217 218 return nil 219 case *current.IBPOrdererList: 220 ordererList := obj.(*current.IBPOrdererList) 221 orderer := current.IBPOrderer{} 222 orderer.Status = current.IBPOrdererStatus{ 223 CRStatus: current.CRStatus{ 224 Type: current.Deployed, 225 }, 226 } 227 ordererList.Items = append(ordererList.Items, orderer) 228 return nil 229 } 230 return nil 231 } 232 233 instance.Spec.ClusterSize = 1 234 reconciler.SetStatus(instance, nil, nil) 235 Expect(instance.Status.Type).To(Equal(current.Deployed)) 236 }) 237 238 It("sets the status to warning if the reconcile loop returns a warning status", func() { 239 mockKubeClient.ListStub = func(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error { 240 switch obj.(type) { 241 case *corev1.PodList: 242 podList := obj.(*corev1.PodList) 243 pod := corev1.Pod{ 244 Status: corev1.PodStatus{ 245 Phase: corev1.PodRunning, 246 }, 247 } 248 podList.Items = append(podList.Items, pod) 249 250 return nil 251 case *current.IBPOrdererList: 252 ordererList := obj.(*current.IBPOrdererList) 253 orderer := current.IBPOrderer{} 254 orderer.Status = current.IBPOrdererStatus{ 255 CRStatus: current.CRStatus{ 256 Type: current.Deployed, 257 }, 258 } 259 ordererList.Items = append(ordererList.Items, orderer) 260 return nil 261 } 262 return nil 263 } 264 265 result := &common.Result{ 266 Status: ¤t.CRStatus{ 267 Type: current.Warning, 268 }, 269 } 270 271 instance.Spec.ClusterSize = 1 272 reconciler.SetStatus(instance, result, nil) 273 Expect(instance.Status.Type).To(Equal(current.Warning)) 274 }) 275 276 It("persists warning status if the instance is already in warning state and reconcile loop returns a warning status", func() { 277 mockKubeClient.ListStub = func(ctx context.Context, obj client.ObjectList, opts ...client.ListOption) error { 278 switch obj.(type) { 279 case *corev1.PodList: 280 podList := obj.(*corev1.PodList) 281 pod := corev1.Pod{ 282 Status: corev1.PodStatus{ 283 Phase: corev1.PodRunning, 284 }, 285 } 286 podList.Items = append(podList.Items, pod) 287 288 return nil 289 case *current.IBPOrdererList: 290 ordererList := obj.(*current.IBPOrdererList) 291 orderer := current.IBPOrderer{} 292 orderer.Status = current.IBPOrdererStatus{ 293 CRStatus: current.CRStatus{ 294 Type: current.Deployed, 295 }, 296 } 297 ordererList.Items = append(ordererList.Items, orderer) 298 return nil 299 } 300 return nil 301 } 302 303 result := &common.Result{ 304 Status: ¤t.CRStatus{ 305 Type: current.Warning, 306 }, 307 } 308 309 instance.Spec.ClusterSize = 1 310 instance.Status.Type = current.Warning 311 reconciler.SetStatus(instance, result, nil) 312 Expect(instance.Status.Type).To(Equal(current.Warning)) 313 }) 314 }) 315 }) 316 317 Context("update reconcile", func() { 318 var ( 319 oldOrderer *current.IBPOrderer 320 newOrderer *current.IBPOrderer 321 oldSecret *corev1.Secret 322 newSecret *corev1.Secret 323 e event.UpdateEvent 324 ) 325 326 BeforeEach(func() { 327 configOverride := &config.Orderer{ 328 Orderer: v1.Orderer{ 329 General: v1.General{ 330 LedgerType: "type1", 331 }, 332 }, 333 } 334 configBytes, err := json.Marshal(configOverride) 335 Expect(err).NotTo(HaveOccurred()) 336 337 oldOrderer = ¤t.IBPOrderer{ 338 ObjectMeta: metav1.ObjectMeta{ 339 Name: instance.Name, 340 }, 341 Spec: current.IBPOrdererSpec{ 342 Images: ¤t.OrdererImages{ 343 OrdererTag: "1.4.6-20200101", 344 }, 345 ConfigOverride: &runtime.RawExtension{Raw: configBytes}, 346 }, 347 } 348 349 configOverride2 := &config.Orderer{ 350 Orderer: v1.Orderer{ 351 General: v1.General{ 352 LedgerType: "type2", 353 }, 354 }, 355 } 356 configBytes2, err := json.Marshal(configOverride2) 357 Expect(err).NotTo(HaveOccurred()) 358 newOrderer = ¤t.IBPOrderer{ 359 ObjectMeta: metav1.ObjectMeta{ 360 Name: instance.Name, 361 }, 362 Spec: current.IBPOrdererSpec{ 363 Images: ¤t.OrdererImages{ 364 OrdererTag: "1.4.9-2511004", 365 }, 366 ConfigOverride: &runtime.RawExtension{Raw: configBytes2}, 367 }, 368 } 369 370 e = event.UpdateEvent{ 371 ObjectOld: oldOrderer, 372 ObjectNew: newOrderer, 373 } 374 375 Expect(reconciler.UpdateFunc(e)).To(Equal(true)) 376 377 oldOrderer = ¤t.IBPOrderer{ 378 ObjectMeta: metav1.ObjectMeta{ 379 Name: instance.Name, 380 }, 381 Spec: current.IBPOrdererSpec{ 382 Images: ¤t.OrdererImages{ 383 OrdererTag: "1.4.9-2511004", 384 }, 385 MSPID: "old-mspid", 386 }, 387 } 388 389 newOrderer = ¤t.IBPOrderer{ 390 ObjectMeta: metav1.ObjectMeta{ 391 Name: instance.Name, 392 }, 393 Spec: current.IBPOrdererSpec{ 394 Images: ¤t.OrdererImages{ 395 OrdererTag: "1.4.9-2511004", 396 }, 397 MSPID: "new-mspid", 398 }, 399 } 400 401 e = event.UpdateEvent{ 402 ObjectOld: oldOrderer, 403 ObjectNew: newOrderer, 404 } 405 406 Expect(reconciler.UpdateFunc(e)).To(Equal(true)) 407 408 oldSecret = &corev1.Secret{ 409 ObjectMeta: metav1.ObjectMeta{ 410 Name: fmt.Sprintf("tls-%s-signcert", instance.Name), 411 OwnerReferences: []metav1.OwnerReference{ 412 { 413 Name: instance.Name, 414 Kind: "IBPOrderer", 415 }, 416 }, 417 }, 418 } 419 420 newSecret = &corev1.Secret{ 421 ObjectMeta: metav1.ObjectMeta{ 422 Name: fmt.Sprintf("tls-%s-signcert", instance.Name), 423 OwnerReferences: []metav1.OwnerReference{ 424 { 425 Name: instance.Name, 426 Kind: "IBPOrderer", 427 }, 428 }, 429 }, 430 } 431 e = event.UpdateEvent{ 432 ObjectOld: oldSecret, 433 ObjectNew: newSecret, 434 } 435 436 Expect(reconciler.UpdateFunc(e)).To(Equal(false)) 437 438 oldSecret = &corev1.Secret{ 439 ObjectMeta: metav1.ObjectMeta{ 440 Name: fmt.Sprintf("ecert-%s-signcert", instance.Name), 441 OwnerReferences: []metav1.OwnerReference{ 442 { 443 Name: instance.Name, 444 Kind: "IBPOrderer", 445 }, 446 }, 447 }, 448 Data: map[string][]byte{ 449 "test": []byte("data"), 450 }, 451 } 452 newSecret = &corev1.Secret{ 453 ObjectMeta: metav1.ObjectMeta{ 454 Name: fmt.Sprintf("ecert-%s-signcert", instance.Name), 455 OwnerReferences: []metav1.OwnerReference{ 456 {Name: instance.Name}, 457 }, 458 }, 459 Data: map[string][]byte{ 460 "test": []byte("newdata"), 461 }, 462 } 463 e = event.UpdateEvent{ 464 ObjectOld: oldSecret, 465 ObjectNew: newSecret, 466 } 467 468 Expect(reconciler.UpdateFunc(e)).To(Equal(true)) 469 470 oldSecret = &corev1.Secret{ 471 ObjectMeta: metav1.ObjectMeta{ 472 Name: fmt.Sprintf("tls-%s-admincert", instance.Name), 473 OwnerReferences: []metav1.OwnerReference{ 474 { 475 Name: instance.Name, 476 Kind: "IBPOrderer", 477 }, 478 }, 479 }, 480 } 481 newSecret = &corev1.Secret{ 482 ObjectMeta: metav1.ObjectMeta{ 483 Name: fmt.Sprintf("tls-%s-admincert", instance.Name), 484 OwnerReferences: []metav1.OwnerReference{ 485 { 486 Name: instance.Name, 487 Kind: "IBPOrderer", 488 }, 489 }, 490 }, 491 } 492 e = event.UpdateEvent{ 493 ObjectOld: oldSecret, 494 ObjectNew: newSecret, 495 } 496 497 Expect(reconciler.UpdateFunc(e)).To(Equal(false)) 498 499 oldOrderer = ¤t.IBPOrderer{ 500 ObjectMeta: metav1.ObjectMeta{ 501 Name: instance.Name, 502 }, 503 Spec: current.IBPOrdererSpec{ 504 Images: ¤t.OrdererImages{}, 505 Secret: ¤t.SecretSpec{ 506 MSP: ¤t.MSPSpec{ 507 Component: ¤t.MSP{ 508 SignCerts: "testcert", 509 }, 510 }, 511 }, 512 }, 513 } 514 515 newOrderer = ¤t.IBPOrderer{ 516 ObjectMeta: metav1.ObjectMeta{ 517 Name: instance.Name, 518 }, 519 Spec: current.IBPOrdererSpec{ 520 Images: ¤t.OrdererImages{}, 521 Secret: ¤t.SecretSpec{ 522 MSP: ¤t.MSPSpec{ 523 TLS: ¤t.MSP{ 524 SignCerts: "testcert", 525 }, 526 }, 527 }, 528 }, 529 } 530 531 e = event.UpdateEvent{ 532 ObjectOld: oldOrderer, 533 ObjectNew: newOrderer, 534 } 535 536 Expect(reconciler.UpdateFunc(e)).To(Equal(true)) 537 }) 538 539 It("properly pops update flags from stack", func() { 540 By("popping first update - config overrides", func() { 541 Expect(reconciler.GetUpdateStatus(instance).ConfigOverridesUpdated()).To(Equal(true)) 542 Expect(reconciler.GetUpdateStatus(instance).OrdererTagUpdated()).To(Equal(true)) 543 544 _, err := reconciler.Reconcile(context.TODO(), request) 545 Expect(err).NotTo(HaveOccurred()) 546 }) 547 548 By("popping second update - spec updated", func() { 549 Expect(reconciler.GetUpdateStatus(instance).ConfigOverridesUpdated()).To(Equal(false)) 550 Expect(reconciler.GetUpdateStatus(instance).SpecUpdated()).To(Equal(true)) 551 552 _, err := reconciler.Reconcile(context.TODO(), request) 553 Expect(err).NotTo(HaveOccurred()) 554 }) 555 556 By("popping third update - ecert updated", func() { 557 Expect(reconciler.GetUpdateStatus(instance).TLSCertUpdated()).To(Equal(false)) 558 Expect(reconciler.GetUpdateStatus(instance).EcertUpdated()).To(Equal(true)) 559 560 _, err := reconciler.Reconcile(context.TODO(), request) 561 Expect(err).NotTo(HaveOccurred()) 562 }) 563 564 By("popping fourth update - msp spec updated", func() { 565 Expect(reconciler.GetUpdateStatus(instance).TLSCertUpdated()).To(Equal(false)) 566 Expect(reconciler.GetUpdateStatus(instance).EcertUpdated()).To(Equal(false)) 567 568 Expect(reconciler.GetUpdateStatus(instance).MSPUpdated()).To(Equal(true)) 569 570 _, err := reconciler.Reconcile(context.TODO(), request) 571 Expect(err).NotTo(HaveOccurred()) 572 573 Expect(reconciler.GetUpdateStatus(instance).MSPUpdated()).To(Equal(false)) 574 }) 575 576 }) 577 578 Context("enrollment information changes detection", func() { 579 BeforeEach(func() { 580 oldOrderer = ¤t.IBPOrderer{ 581 ObjectMeta: metav1.ObjectMeta{ 582 Name: instance.Name, 583 }, 584 } 585 586 newOrderer = ¤t.IBPOrderer{ 587 ObjectMeta: metav1.ObjectMeta{ 588 Name: instance.Name, 589 }, 590 } 591 592 e = event.UpdateEvent{ 593 ObjectOld: oldOrderer, 594 ObjectNew: newOrderer, 595 } 596 }) 597 598 It("returns false if new secret is nil", func() { 599 Expect(reconciler.UpdateFunc(e)).To(Equal(false)) 600 Expect(reconciler.GetUpdateStatus(instance).EcertEnroll()).To(Equal(false)) 601 }) 602 603 It("returns false if new secret has ecert msp set along with enrollment inforamtion", func() { 604 oldOrderer.Spec.Secret = ¤t.SecretSpec{ 605 Enrollment: ¤t.EnrollmentSpec{ 606 Component: ¤t.Enrollment{ 607 EnrollID: "id1", 608 }, 609 }, 610 } 611 newOrderer.Spec.Secret = ¤t.SecretSpec{ 612 MSP: ¤t.MSPSpec{ 613 Component: ¤t.MSP{}, 614 }, 615 Enrollment: ¤t.EnrollmentSpec{ 616 Component: ¤t.Enrollment{ 617 EnrollID: "id2", 618 }, 619 }, 620 } 621 622 newOrderer.Spec.Action = current.OrdererAction{ 623 Restart: true, 624 } 625 626 reconciler.UpdateFunc(e) 627 Expect(reconciler.GetUpdateStatusAtElement(instance, 4).EcertEnroll()).To(Equal(false)) 628 }) 629 }) 630 631 Context("update node OU", func() { 632 BeforeEach(func() { 633 oldOrderer = ¤t.IBPOrderer{ 634 ObjectMeta: metav1.ObjectMeta{ 635 Name: instance.Name, 636 }, 637 } 638 639 newOrderer = ¤t.IBPOrderer{ 640 ObjectMeta: metav1.ObjectMeta{ 641 Name: instance.Name, 642 }, 643 } 644 newOrderer.Spec.DisableNodeOU = pointer.Bool(true) 645 646 e = event.UpdateEvent{ 647 ObjectOld: oldOrderer, 648 ObjectNew: newOrderer, 649 } 650 }) 651 652 It("returns true if node ou updated in spec", func() { 653 reconciler.UpdateFunc(e) 654 Expect(reconciler.GetUpdateStatusAtElement(instance, 4).NodeOUUpdated()).To(Equal(true)) 655 }) 656 }) 657 }) 658 659 Context("status updated", func() { 660 var ( 661 oldOrderer *current.IBPOrderer 662 newOrderer *current.IBPOrderer 663 e event.UpdateEvent 664 ) 665 666 BeforeEach(func() { 667 oldOrderer = ¤t.IBPOrderer{ 668 ObjectMeta: metav1.ObjectMeta{ 669 Name: instance.Name, 670 }, 671 Spec: current.IBPOrdererSpec{ 672 Images: ¤t.OrdererImages{}, 673 }, 674 } 675 newOrderer = ¤t.IBPOrderer{ 676 ObjectMeta: metav1.ObjectMeta{ 677 Name: instance.Name, 678 }, 679 Spec: current.IBPOrdererSpec{ 680 Images: ¤t.OrdererImages{}, 681 }, 682 } 683 e = event.UpdateEvent{ 684 ObjectOld: oldOrderer, 685 ObjectNew: newOrderer, 686 } 687 }) 688 689 It("does not set StatusUpdate flag if only heartbeat has changed", func() { 690 oldOrderer.Status.LastHeartbeatTime = time.Now().String() 691 newOrderer.Status.LastHeartbeatTime = time.Now().String() 692 693 Expect(reconciler.UpdateFunc(e)).To(Equal(false)) 694 Expect(reconciler.GetUpdateStatus(instance).StatusUpdated()).To(Equal(false)) 695 }) 696 697 It("sets StatusUpdated flag to true if status type has changed", func() { 698 oldOrderer.Status.Type = "old" 699 newOrderer.Status.Type = "new" 700 701 Expect(reconciler.UpdateFunc(e)).To(Equal(true)) 702 Expect(reconciler.GetUpdateStatus(instance).StatusUpdated()).To(Equal(true)) 703 }) 704 705 It("sets StatusUpdated flag to true if status reason has changed", func() { 706 oldOrderer.Status.Reason = "oldreason" 707 newOrderer.Status.Reason = "newreason" 708 709 Expect(reconciler.UpdateFunc(e)).To(Equal(true)) 710 Expect(reconciler.GetUpdateStatus(instance).StatusUpdated()).To(Equal(true)) 711 }) 712 713 It("sets StatusUpdated flag to true if status message has changed", func() { 714 oldOrderer.Status.Message = "oldmessage" 715 newOrderer.Status.Message = "newmessage" 716 717 Expect(reconciler.UpdateFunc(e)).To(Equal(true)) 718 Expect(reconciler.GetUpdateStatus(instance).StatusUpdated()).To(Equal(true)) 719 }) 720 }) 721 722 Context("append update if missing", func() { 723 It("appends update", func() { 724 updates := []Update{{tlsCertUpdated: true}} 725 updates = reconciler.AppendUpdateIfMissing(updates, Update{ecertUpdated: true}) 726 Expect(len(updates)).To(Equal(2)) 727 }) 728 729 It("doesn't append update that is already in stack", func() { 730 updates := []Update{{tlsCertUpdated: true}} 731 updates = reconciler.AppendUpdateIfMissing(updates, Update{tlsCertUpdated: true}) 732 Expect(len(updates)).To(Equal(1)) 733 }) 734 }) 735 736 Context("push update", func() { 737 It("pushes update only if missing for certificate update", func() { 738 reconciler.PushUpdate(instance.Name, Update{specUpdated: true}) 739 Expect(len(reconciler.update[instance.Name])).To(Equal(1)) 740 reconciler.PushUpdate(instance.Name, Update{tlsCertUpdated: true}) 741 Expect(len(reconciler.update[instance.Name])).To(Equal(2)) 742 reconciler.PushUpdate(instance.Name, Update{ecertUpdated: true}) 743 Expect(len(reconciler.update[instance.Name])).To(Equal(3)) 744 reconciler.PushUpdate(instance.Name, Update{tlsCertUpdated: true}) 745 Expect(len(reconciler.update[instance.Name])).To(Equal(3)) 746 reconciler.PushUpdate(instance.Name, Update{tlsCertUpdated: true, specUpdated: true}) 747 Expect(len(reconciler.update[instance.Name])).To(Equal(4)) 748 }) 749 }) 750 751 Context("add owner reference to secret", func() { 752 var ( 753 secret *corev1.Secret 754 ) 755 756 BeforeEach(func() { 757 secret = &corev1.Secret{} 758 secret.Name = "ecert-test-orderer1-signcert" 759 }) 760 761 It("returns error if fails to get list of orderers", func() { 762 mockKubeClient.ListReturns(errors.New("list error")) 763 _, err := reconciler.AddOwnerReferenceToSecret(secret) 764 Expect(err).To(HaveOccurred()) 765 Expect(err.Error()).To(ContainSubstring("list error")) 766 }) 767 768 It("returns false if secret doesn't belong to any orderers in list", func() { 769 secret.Name = "tls-peer1-signcert" 770 added, err := reconciler.AddOwnerReferenceToSecret(secret) 771 Expect(err).NotTo(HaveOccurred()) 772 Expect(added).To(Equal(false)) 773 }) 774 775 It("returns false if secret's name doesn't match expected format", func() { 776 secret.Name = "orderersecret" 777 added, err := reconciler.AddOwnerReferenceToSecret(secret) 778 Expect(err).NotTo(HaveOccurred()) 779 Expect(added).To(Equal(false)) 780 }) 781 782 It("returns true if owner references added to secret", func() { 783 added, err := reconciler.AddOwnerReferenceToSecret(secret) 784 Expect(err).NotTo(HaveOccurred()) 785 Expect(added).To(Equal(true)) 786 }) 787 788 It("returns true if owner references added to init-rootcert secret", func() { 789 secret.Name = "test-orderer1-init-rootcert" 790 added, err := reconciler.AddOwnerReferenceToSecret(secret) 791 Expect(err).NotTo(HaveOccurred()) 792 Expect(added).To(Equal(true)) 793 }) 794 }) 795 })