Skip to content

Commit 95ab40e

Browse files
committed
Add e2e for accept risks
1 parent 3d589b7 commit 95ab40e

3 files changed

Lines changed: 199 additions & 0 deletions

File tree

.openshift-tests-extension/openshift_payload_cluster-version-operator.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,24 @@
11
[
2+
{
3+
"name": "[Jira:\"Cluster Version Operator\"] cluster-version-operator works well on accept risks. Cluster Version Operator can store accepted risks",
4+
"labels": {},
5+
"resources": {
6+
"isolation": {}
7+
},
8+
"source": "openshift:payload:cluster-version-operator",
9+
"lifecycle": "blocking",
10+
"environmentSelector": {}
11+
},
12+
{
13+
"name": "[Jira:\"Cluster Version Operator\"] cluster-version-operator works well on accept risks. Cluster Version Operator should populate the fields about risks in status",
14+
"labels": {},
15+
"resources": {
16+
"isolation": {}
17+
},
18+
"source": "openshift:payload:cluster-version-operator",
19+
"lifecycle": "blocking",
20+
"environmentSelector": {}
21+
},
222
{
323
"name": "[Jira:\"Cluster Version Operator\"] cluster-version-operator-tests should support passing tests",
424
"labels": {},

test/cvo/accept_risks.go

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package cvo
2+
3+
import (
4+
"context"
5+
configv1 "github.com/openshift/api/config/v1"
6+
"slices"
7+
8+
g "github.com/onsi/ginkgo/v2"
9+
o "github.com/onsi/gomega"
10+
11+
configclientv1 "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
12+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
13+
"k8s.io/client-go/kubernetes"
14+
"k8s.io/client-go/rest"
15+
16+
"github.com/openshift/cluster-version-operator/test/util"
17+
)
18+
19+
var _ = g.Describe(`[Jira:"Cluster Version Operator"] cluster-version-operator works well on accept risks.`, func() {
20+
21+
var (
22+
c *rest.Config
23+
kubeClient kubernetes.Interface
24+
configv1Client *configclientv1.ConfigV1Client
25+
err error
26+
27+
isTechPreviewNoUpgrade bool
28+
isHypershift bool
29+
isMicroShiftCluster bool
30+
)
31+
32+
g.BeforeEach(func() {
33+
c, err = util.LoadRestConfig()
34+
o.Expect(err).To(o.BeNil())
35+
kubeClient, err = kubernetes.NewForConfig(c)
36+
o.Expect(err).To(o.BeNil())
37+
configv1Client, err = configclientv1.NewForConfig(c)
38+
o.Expect(err).To(o.BeNil())
39+
isTechPreviewNoUpgrade = util.IsTechPreviewNoUpgrade(configv1Client)
40+
isHypershift, err = util.IsHypershift(configv1Client)
41+
o.Expect(err).To(o.BeNil())
42+
isMicroShiftCluster, err = util.IsMicroShiftCluster(kubeClient, logger)
43+
o.Expect(err).To(o.BeNil())
44+
45+
if isHypershift {
46+
g.Skip("This test is skipped on a Hypershift cluster")
47+
}
48+
if isMicroShiftCluster {
49+
g.Skip("This test is skipped on a Microshift cluster")
50+
}
51+
if !isTechPreviewNoUpgrade {
52+
g.Skip("This test is skipped because the Tech Preview NoUpgrade is not enabled")
53+
}
54+
})
55+
56+
g.Describe("Cluster Version Operator", func() {
57+
g.It("can store accepted risks", func() {
58+
cv, err := configv1Client.ClusterVersions().Get(context.Background(), "cluster", metav1.GetOptions{})
59+
o.Expect(err).NotTo(o.HaveOccurred())
60+
61+
bk := cv.Spec.DesiredUpdate
62+
if bk != nil {
63+
bk = bk.DeepCopy()
64+
}
65+
66+
g.By("Checking that new risks can be saved")
67+
if cv.Spec.DesiredUpdate == nil {
68+
cv.Spec.DesiredUpdate = &configv1.Update{}
69+
}
70+
cv.Spec.DesiredUpdate.AcceptRisks = append(cv.Spec.DesiredUpdate.AcceptRisks, []configv1.AcceptRisk{
71+
{Name: "riskA"},
72+
{Name: "riskB"},
73+
}...)
74+
75+
cv, err = configv1Client.ClusterVersions().Update(context.Background(), cv, metav1.UpdateOptions{})
76+
o.Expect(err).NotTo(o.HaveOccurred())
77+
o.Expect(slices.Contains(cv.Spec.DesiredUpdate.AcceptRisks, configv1.AcceptRisk{Name: "riskA"})).To(o.BeTrue())
78+
o.Expect(slices.Contains(cv.Spec.DesiredUpdate.AcceptRisks, configv1.AcceptRisk{Name: "riskB"})).To(o.BeTrue())
79+
80+
g.By("Checking that new risks can be removed")
81+
cv.Spec.DesiredUpdate = bk
82+
cv, err = configv1Client.ClusterVersions().Update(context.Background(), cv, metav1.UpdateOptions{})
83+
o.Expect(err).NotTo(o.HaveOccurred())
84+
o.Expect(slices.Contains(cv.Spec.DesiredUpdate.AcceptRisks, configv1.AcceptRisk{Name: "riskA"})).To(o.BeFalse())
85+
o.Expect(slices.Contains(cv.Spec.DesiredUpdate.AcceptRisks, configv1.AcceptRisk{Name: "riskB"})).To(o.BeFalse())
86+
})
87+
88+
g.It("should populate the fields about risks in status", func() {
89+
cv, err := configv1Client.ClusterVersions().Get(context.Background(), "cluster", metav1.GetOptions{})
90+
o.Expect(err).NotTo(o.HaveOccurred())
91+
92+
g.By("Checking that each condition update has risk names")
93+
for _, cu := range cv.Status.ConditionalUpdates {
94+
o.Expect(cu.RiskNames).ShouldNot(o.BeEmpty(), "RiskNames should not be empty")
95+
}
96+
})
97+
})
98+
})

test/util/util.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package util
2+
3+
import (
4+
"context"
5+
"github.com/go-logr/logr"
6+
7+
"time"
8+
9+
o "github.com/onsi/gomega"
10+
11+
configv1 "github.com/openshift/api/config/v1"
12+
configclientv1 "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
13+
corev1 "k8s.io/api/core/v1"
14+
kapierrs "k8s.io/apimachinery/pkg/api/errors"
15+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
16+
"k8s.io/apimachinery/pkg/util/wait"
17+
"k8s.io/client-go/kubernetes"
18+
"k8s.io/client-go/rest"
19+
"k8s.io/client-go/tools/clientcmd"
20+
)
21+
22+
// LoadRestConfig loads Kube Config
23+
func LoadRestConfig() (*rest.Config, error) {
24+
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
25+
clientcmd.NewDefaultClientConfigLoadingRules(),
26+
&clientcmd.ConfigOverrides{},
27+
).ClientConfig()
28+
}
29+
30+
// IsTechPreviewNoUpgrade checks if a cluster is a TechPreviewNoUpgrade cluster
31+
func IsTechPreviewNoUpgrade(c *configclientv1.ConfigV1Client) bool {
32+
featureGate, err := c.FeatureGates().Get(context.Background(), "cluster", metav1.GetOptions{})
33+
if err != nil {
34+
if kapierrs.IsNotFound(err) {
35+
return false
36+
}
37+
o.Expect(err).NotTo(o.HaveOccurred(), "could not retrieve feature-gate: %v", err)
38+
}
39+
return featureGate.Spec.FeatureSet == configv1.TechPreviewNoUpgrade
40+
}
41+
42+
// IsHypershift checks if a cluster is a Hypershift cluster
43+
func IsHypershift(c *configclientv1.ConfigV1Client) (bool, error) {
44+
infrastructure, err := c.Infrastructures().Get(context.Background(), "cluster", metav1.GetOptions{})
45+
if err != nil {
46+
return false, err
47+
}
48+
return infrastructure.Status.ControlPlaneTopology == configv1.ExternalTopologyMode, nil
49+
50+
}
51+
52+
// IsMicroShiftCluster returns "true" if a cluster is MicroShift,
53+
// "false" otherwise. It needs kube-admin client as input.
54+
func IsMicroShiftCluster(kubeClient kubernetes.Interface, logger logr.Logger) (bool, error) {
55+
ctx := context.Background()
56+
var cm *corev1.ConfigMap
57+
duration := 5 * time.Minute
58+
if err := wait.PollUntilContextTimeout(ctx, 10*time.Second, duration, true, func(ctx context.Context) (bool, error) {
59+
// MicroShift cluster contains "microshift-version" configmap in "kube-public" namespace
60+
var err error
61+
cm, err = kubeClient.CoreV1().ConfigMaps("kube-public").Get(ctx, "microshift-version", metav1.GetOptions{})
62+
if err == nil {
63+
return true, nil
64+
}
65+
if kapierrs.IsNotFound(err) {
66+
cm = nil
67+
return true, nil
68+
}
69+
logger.Error(err, "error accessing microshift-version configmap")
70+
return false, nil
71+
}); err != nil {
72+
logger.WithValues("duration", duration).Error(err, "failed to find microshift-version configmap")
73+
return false, err
74+
}
75+
if cm == nil {
76+
logger.Info("microshift-version configmap not found")
77+
return false, nil
78+
}
79+
logger.WithValues("version", cm.Data["version"]).Info("MicroShift cluster has version in ConfigMap")
80+
return true, nil
81+
}

0 commit comments

Comments
 (0)