|
4 | 4 | "context" |
5 | 5 | "fmt" |
6 | 6 | "os/exec" |
| 7 | + "path/filepath" |
7 | 8 | "strings" |
8 | 9 | "time" |
9 | 10 |
|
@@ -609,4 +610,270 @@ var _ = g.Describe("[sig-operator][Jira:OLM] OLMv0 should", func() { |
609 | 610 |
|
610 | 611 | }) |
611 | 612 |
|
| 613 | + g.It("PolarionID:21080-[OTP][Skipped:Disconnected]Check metrics[Serial]", g.Label("NonHyperShiftHOST"), func() { |
| 614 | + exutil.SkipOnProxyCluster(oc) |
| 615 | + |
| 616 | + var ( |
| 617 | + buildPruningBaseDir = exutil.FixturePath("testdata", "olm") |
| 618 | + ogTemplate = filepath.Join(buildPruningBaseDir, "operatorgroup.yaml") |
| 619 | + subFile = filepath.Join(buildPruningBaseDir, "olm-subscription.yaml") |
| 620 | + |
| 621 | + data olmv0util.PrometheusQueryResult |
| 622 | + err error |
| 623 | + exists bool |
| 624 | + metricsBefore olmv0util.Metrics |
| 625 | + metricsAfter olmv0util.Metrics |
| 626 | + olmToken string |
| 627 | + ) |
| 628 | + |
| 629 | + oc.SetupProject() |
| 630 | + ns := oc.Namespace() |
| 631 | + itName := g.CurrentSpecReport().FullText() |
| 632 | + og := olmv0util.OperatorGroupDescription{ |
| 633 | + Name: "test-21080-group", |
| 634 | + Namespace: ns, |
| 635 | + Template: ogTemplate, |
| 636 | + } |
| 637 | + g.By("create the learn-operator CatalogSource") |
| 638 | + catsrcImageTemplate := filepath.Join(buildPruningBaseDir, "catalogsource-image.yaml") |
| 639 | + catsrc := olmv0util.CatalogSourceDescription{ |
| 640 | + Name: "catsrc-21080", |
| 641 | + Namespace: ns, |
| 642 | + DisplayName: "QE Operators", |
| 643 | + Publisher: "OpenShift QE", |
| 644 | + SourceType: "grpc", |
| 645 | + Address: "quay.io/olmqe/learn-operator-index:v25", |
| 646 | + Template: catsrcImageTemplate, |
| 647 | + } |
| 648 | + defer catsrc.Delete(itName, dr) |
| 649 | + catsrc.CreateWithCheck(oc, itName, dr) |
| 650 | + |
| 651 | + sub := olmv0util.SubscriptionDescription{ |
| 652 | + SubName: "sub-21080", |
| 653 | + Namespace: ns, |
| 654 | + CatalogSourceName: "catsrc-21080", |
| 655 | + CatalogSourceNamespace: ns, |
| 656 | + IpApproval: "Automatic", |
| 657 | + Channel: "beta", |
| 658 | + OperatorPackage: "learn", |
| 659 | + SingleNamespace: true, |
| 660 | + Template: subFile, |
| 661 | + } |
| 662 | + |
| 663 | + g.By("1, check if this operator ready for installing") |
| 664 | + e2e.Logf("Check if %v exists in the %v catalog", sub.OperatorPackage, sub.CatalogSourceName) |
| 665 | + exists, err = olmv0util.ClusterPackageExistsInNamespace(oc, sub, ns) |
| 666 | + if !exists { |
| 667 | + g.Skip(fmt.Sprintf("%s does not exist in the cluster", sub.OperatorPackage)) |
| 668 | + } |
| 669 | + o.Expect(err).NotTo(o.HaveOccurred()) |
| 670 | + o.Expect(exists).To(o.BeTrue()) |
| 671 | + |
| 672 | + g.By("2, Get token & pods so that access the Prometheus") |
| 673 | + olmToken, err = exutil.GetSAToken(oc, "prometheus-k8s", "openshift-monitoring") |
| 674 | + o.Expect(err).NotTo(o.HaveOccurred()) |
| 675 | + o.Expect(olmToken).NotTo(o.BeEmpty()) |
| 676 | + |
| 677 | + // the reason why use it is to workaround the Network policy since OCP4.20 |
| 678 | + g.By("2-1, get Prometheus Pod IP address") |
| 679 | + PrometheusPodIP, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("pod", "-n", "openshift-monitoring", "prometheus-k8s-0", "-o=jsonpath={.status.podIP}").Output() |
| 680 | + o.Expect(err).NotTo(o.HaveOccurred()) |
| 681 | + |
| 682 | + g.By("3, Collect olm metrics before installing an operator") |
| 683 | + metricsBefore = olmv0util.GetMetrics(oc, olmToken, data, metricsBefore, sub.SubName, PrometheusPodIP) |
| 684 | + e2e.Logf("\nbefore {csv_count, csv_upgrade_count, catalog_source_count, install_plan_count, subscription_count, subscription_sync_total}\n%v", metricsBefore) |
| 685 | + |
| 686 | + g.By("4, Start to subscribe to etcdoperator") |
| 687 | + og.Create(oc, itName, dr) |
| 688 | + defer sub.Delete(itName, dr) // remove the subscription after test |
| 689 | + sub.Create(oc, itName, dr) |
| 690 | + |
| 691 | + g.By("4.5 Check for latest version") |
| 692 | + defer sub.DeleteCSV(itName, dr) // remove the csv after test |
| 693 | + olmv0util.NewCheck("expect", exutil.AsAdmin, exutil.WithoutNamespace, exutil.Compare, "Succeeded", exutil.Ok, []string{"csv", "learn-operator.v0.0.3", "-n", ns, "-o=jsonpath={.status.phase}"}).Check(oc) |
| 694 | + |
| 695 | + g.By("5, learnoperator is at v0.0.3, start to collect olm metrics after") |
| 696 | + // The prometheus-k8s-0 IP might be changed, so rerun it here. |
| 697 | + PrometheusPodIP, err = oc.AsAdmin().WithoutNamespace().Run("get").Args("pod", "-n", "openshift-monitoring", "prometheus-k8s-0", "-o=jsonpath={.status.podIP}").Output() |
| 698 | + o.Expect(err).NotTo(o.HaveOccurred()) |
| 699 | + metricsAfter = olmv0util.GetMetrics(oc, olmToken, data, metricsAfter, sub.SubName, PrometheusPodIP) |
| 700 | + g.By("6, Check results") |
| 701 | + e2e.Logf("{csv_count csv_upgrade_count catalog_source_count install_plan_count subscription_count subscription_sync_total}") |
| 702 | + e2e.Logf("%v", metricsBefore) |
| 703 | + e2e.Logf("%v", metricsAfter) |
| 704 | + g.By("All PASS\n") |
| 705 | + }) |
| 706 | + |
| 707 | + g.It("PolarionID:21953-[OTP]Ensure that operator deployment is in the master node", g.Label("NonHyperShiftHOST"), func() { |
| 708 | + exutil.SkipBaselineCaps(oc, "None") |
| 709 | + var ( |
| 710 | + err error |
| 711 | + msg string |
| 712 | + olmErrs = true |
| 713 | + olmJpath = "-o=jsonpath={@.spec.template.spec.nodeSelector}" |
| 714 | + olmNamespace = "openshift-marketplace" |
| 715 | + olmNodeName string |
| 716 | + olmPodFullName string |
| 717 | + olmPodName = "marketplace-operator" |
| 718 | + nodeRole = "node-role.kubernetes.io/master" |
| 719 | + nodes string |
| 720 | + nodeStatus bool |
| 721 | + pod string |
| 722 | + pods string |
| 723 | + status []string |
| 724 | + x []string |
| 725 | + ) |
| 726 | + |
| 727 | + g.By("Get deployment") |
| 728 | + msg, err = oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "-n", olmNamespace, olmPodName, olmJpath).Output() |
| 729 | + if err != nil { |
| 730 | + e2e.Logf("Unable to get deployment -n %v %v %v.", olmNamespace, olmPodName, olmJpath) |
| 731 | + } |
| 732 | + o.Expect(err).NotTo(o.HaveOccurred()) |
| 733 | + if len(msg) < 1 || !strings.Contains(msg, nodeRole) { |
| 734 | + e2e.Failf("Could not find %v variable %v for %v: %v", olmJpath, nodeRole, olmPodName, msg) |
| 735 | + } |
| 736 | + |
| 737 | + g.By("Look at pods") |
| 738 | + // look for the marketplace-operator pod's full name |
| 739 | + pods, err = oc.AsAdmin().WithoutNamespace().Run("get").Args("pods", "-n", olmNamespace, "-o", "wide").Output() |
| 740 | + if err != nil { |
| 741 | + e2e.Logf("Unable to query pods -n %v %v %v.", olmNamespace, err, pods) |
| 742 | + } |
| 743 | + o.Expect(err).NotTo(o.HaveOccurred()) |
| 744 | + o.Expect(pods).NotTo(o.ContainSubstring("No resources found")) |
| 745 | + // e2e.Logf("Pods %v ", pods) |
| 746 | + |
| 747 | + for _, pod = range strings.Split(pods, "\n") { |
| 748 | + if len(pod) <= 0 { |
| 749 | + continue |
| 750 | + } |
| 751 | + // Find the node in the pod |
| 752 | + if strings.Contains(pod, olmPodName) { |
| 753 | + x = strings.Fields(pod) |
| 754 | + olmPodFullName = x[0] |
| 755 | + // olmNodeName = x[6] |
| 756 | + olmNodeName, err = oc.AsAdmin().WithoutNamespace().Run("get").Args("pods", "-n", olmNamespace, olmPodFullName, "-o=jsonpath={.spec.nodeName}").Output() |
| 757 | + o.Expect(err).NotTo(o.HaveOccurred()) |
| 758 | + olmErrs = false |
| 759 | + // e2e.Logf("Found pod is %v", pod) |
| 760 | + break |
| 761 | + } |
| 762 | + } |
| 763 | + if olmErrs { |
| 764 | + e2e.Failf("Unable to find the full pod name for %v in %v: %v.", olmPodName, olmNamespace, pods) |
| 765 | + } |
| 766 | + |
| 767 | + g.By("Query node label value") |
| 768 | + // Look at the setting for the node to be on the master |
| 769 | + olmErrs = true |
| 770 | + nodes, err = oc.AsAdmin().WithoutNamespace().Run("get").Args("nodes", "-n", olmNamespace, olmNodeName, "-o=jsonpath={.metadata.labels}").Output() |
| 771 | + if err != nil { |
| 772 | + e2e.Failf("Unable to query nodes -n %v %v %v.", olmNamespace, err, nodes) |
| 773 | + } |
| 774 | + o.Expect(err).NotTo(o.HaveOccurred()) |
| 775 | + o.Expect(nodes).To(o.ContainSubstring("node-role.kubernetes.io/master")) |
| 776 | + |
| 777 | + g.By("look at oc get nodes") |
| 778 | + // Found the setting, verify that it's really on the master node |
| 779 | + msg, err = oc.AsAdmin().WithoutNamespace().Run("get").Args("nodes", "-n", olmNamespace, olmNodeName, "--show-labels", "--no-headers").Output() |
| 780 | + if err != nil { |
| 781 | + e2e.Failf("Unable to query the %v node of pod %v for %v's status", olmNodeName, olmPodFullName, msg) |
| 782 | + } |
| 783 | + o.Expect(err).NotTo(o.HaveOccurred()) |
| 784 | + o.Expect(msg).NotTo(o.ContainSubstring("No resources found")) |
| 785 | + status = strings.Fields(msg) |
| 786 | + if strings.Contains(status[2], "master") { |
| 787 | + olmErrs = false |
| 788 | + nodeStatus = true |
| 789 | + e2e.Logf("node %v is a %v", olmNodeName, status[2]) |
| 790 | + } |
| 791 | + if olmErrs || !nodeStatus { |
| 792 | + e2e.Failf("The node %v of %v pod is not a master:%v", olmNodeName, olmPodFullName, msg) |
| 793 | + } |
| 794 | + g.By("Finish") |
| 795 | + e2e.Logf("The pod %v is on the master node %v", olmPodFullName, olmNodeName) |
| 796 | + }) |
| 797 | + |
| 798 | + g.It("PolarionID:43135-[OTP]PackageServer respects single-node configuration[Slow][Disruptive]", g.Label("NonHyperShiftHOST"), func() { |
| 799 | + g.By("1) get the cluster infrastructure") |
| 800 | + infra, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("infrastructures", "cluster", "-o=jsonpath={.status.infrastructureTopology}").Output() |
| 801 | + if err != nil { |
| 802 | + e2e.Failf("Fail to get the cluster infra") |
| 803 | + } |
| 804 | + num, err := oc.AsAdmin().WithoutNamespace().Run("get").Args("-n", "openshift-operator-lifecycle-manager", "deployment", "packageserver", "-o=jsonpath={.status.replicas}").Output() |
| 805 | + o.Expect(err).NotTo(o.HaveOccurred()) |
| 806 | + if infra == "SingleReplica" { |
| 807 | + e2e.Logf("This is a SNO cluster") |
| 808 | + g.By("2) check if only have one packageserver pod") |
| 809 | + if num != "1" { |
| 810 | + e2e.Failf("!!!Fail, should only have 1 packageserver pod, but get %s!", num) |
| 811 | + } |
| 812 | + // make sure the CVO recover if any error in the follow steps |
| 813 | + defer func() { |
| 814 | + _, err = oc.AsAdmin().WithoutNamespace().Run("scale").Args("--replicas", "1", "deployment/cluster-version-operator", "-n", "openshift-cluster-version").Output() |
| 815 | + if err != nil { |
| 816 | + e2e.Failf("Defer: fail to enable CVO") |
| 817 | + } |
| 818 | + }() |
| 819 | + g.By("3) stop CVO") |
| 820 | + _, err := oc.AsAdmin().WithoutNamespace().Run("scale").Args("--replicas", "0", "deployment/cluster-version-operator", "-n", "openshift-cluster-version").Output() |
| 821 | + if err != nil { |
| 822 | + e2e.Failf("Fail to stop CVO") |
| 823 | + } |
| 824 | + g.By("4) stop the PSM") |
| 825 | + _, err = oc.AsAdmin().WithoutNamespace().Run("scale").Args("--replicas", "0", "deployment/package-server-manager", "-n", "openshift-operator-lifecycle-manager").Output() |
| 826 | + if err != nil { |
| 827 | + e2e.Failf("Fail to stop the PSM") |
| 828 | + } |
| 829 | + g.By("5) patch the replica to 3") |
| 830 | + // oc get csv packageserver -o=jsonpath={.spec.install.spec.deployments[?(@.name==\"packageserver\")].spec.replicas} |
| 831 | + // oc patch csv/packageserver -p '{"spec":{"install":{"spec":{"deployments":[{"name":"packageserver", "spec":{"replicas":3, "template":{}, "selector":{"matchLabels":{"app":"packageserver"}}}}]}}}}' --type=merge |
| 832 | + // oc patch deploy/packageserver -p '{"spec":{"replicas":3}}' --type=merge |
| 833 | + // should update CSV |
| 834 | + olmv0util.PatchResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "-n", "openshift-operator-lifecycle-manager", "csv", "packageserver", "-p", "{\"spec\":{\"install\":{\"spec\":{\"deployments\":[{\"name\":\"packageserver\", \"spec\":{\"replicas\":3, \"template\":{}, \"selector\":{\"matchLabels\":{\"app\":\"packageserver\"}}}}]}}}}", "--type=merge") |
| 835 | + olmv0util.PatchResource(oc, exutil.AsAdmin, exutil.WithoutNamespace, "-n", "openshift-operator-lifecycle-manager", "deployment", "packageserver", "-p", "{\"spec\":{\"replicas\":3}}", "--type=merge") |
| 836 | + err = wait.PollUntilContextTimeout(context.TODO(), 3*time.Second, 60*time.Second, false, func(ctx context.Context) (bool, error) { |
| 837 | + num, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "packageserver", "-n", "openshift-operator-lifecycle-manager", "-o=jsonpath={.status.availableReplicas}").Output() |
| 838 | + e2e.Logf("packageserver replicas is %s", num) |
| 839 | + if num != "3" { |
| 840 | + return false, nil |
| 841 | + } |
| 842 | + return true, nil |
| 843 | + }) |
| 844 | + exutil.AssertWaitPollNoErr(err, "packageserver replicas is not 3") |
| 845 | + g.By("6) enable CVO") |
| 846 | + _, err = oc.AsAdmin().WithoutNamespace().Run("scale").Args("--replicas", "1", "deployment/cluster-version-operator", "-n", "openshift-cluster-version").Output() |
| 847 | + if err != nil { |
| 848 | + e2e.Failf("Fail to enable CVO") |
| 849 | + } |
| 850 | + g.By("7) check if the PSM back") |
| 851 | + err = wait.PollUntilContextTimeout(context.TODO(), 3*time.Second, 60*time.Second, false, func(ctx context.Context) (bool, error) { |
| 852 | + num, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "package-server-manager", "-n", "openshift-operator-lifecycle-manager", "-o=jsonpath={.status.replicas}").Output() |
| 853 | + if num != "1" { |
| 854 | + return false, nil |
| 855 | + } |
| 856 | + return true, nil |
| 857 | + }) |
| 858 | + exutil.AssertWaitPollNoErr(err, "package-server-manager replicas is not reback to 1") |
| 859 | + g.By("8) check if the packageserver pods number back to 1") |
| 860 | + // for some SNO clusters, reback may take 10 mins around |
| 861 | + err = wait.PollUntilContextTimeout(context.TODO(), 10*time.Second, 600*time.Second, false, func(ctx context.Context) (bool, error) { |
| 862 | + num, _ := oc.AsAdmin().WithoutNamespace().Run("get").Args("deployment", "packageserver", "-n", "openshift-operator-lifecycle-manager", "-o=jsonpath={.status.availableReplicas}").Output() |
| 863 | + if num != "1" { |
| 864 | + return false, nil |
| 865 | + } |
| 866 | + return true, nil |
| 867 | + }) |
| 868 | + exutil.AssertWaitPollNoErr(err, "packageserver replicas is not reback to 1") |
| 869 | + } else { |
| 870 | + // HighlyAvailable |
| 871 | + e2e.Logf("This is HA cluster, not SNO") |
| 872 | + g.By("2) check if only have two packageserver pods") |
| 873 | + if num != "2" { |
| 874 | + e2e.Failf("!!!Fail, should only have 2 packageserver pods, but get %s!", num) |
| 875 | + } |
| 876 | + } |
| 877 | + }) |
| 878 | + |
612 | 879 | }) |
0 commit comments