@@ -6,10 +6,13 @@ import (
66
77 g "github.com/onsi/ginkgo/v2"
88 o "github.com/onsi/gomega"
9+ monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
910 prometheusoperatorv1client "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/typed/monitoring/v1"
1011
12+ "k8s.io/apimachinery/pkg/api/errors"
1113 "k8s.io/apimachinery/pkg/api/meta"
1214 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15+ "k8s.io/apimachinery/pkg/util/intstr"
1316 "k8s.io/apimachinery/pkg/util/sets"
1417 "k8s.io/apimachinery/pkg/util/wait"
1518 "k8s.io/client-go/rest"
@@ -65,6 +68,88 @@ var _ = g.Describe(`[Jira:"Cluster Version Operator"] cluster-version-operator`,
6568 }
6669 })
6770
71+ g .It ("should work with risks from alerts" , g .Label ("OTA-1813" ), g .Label ("Serial" ), g .Label ("Local" ), func () {
72+ // This test case relies on a public service util.FauxinnatiAPIURL
73+ o .Expect (util .SkipIfNetworkRestricted (ctx , c , util .FauxinnatiAPIURL )).To (o .BeNil ())
74+
75+ cv , err := configClient .ClusterVersions ().Get (ctx , external .DefaultClusterVersionName , metav1.GetOptions {})
76+ o .Expect (err ).NotTo (o .HaveOccurred ())
77+
78+ g .By ("Using fauxinnati as the upstream and its simple channel" )
79+ cv .Spec .Upstream = util .FauxinnatiAPIURL
80+ cv .Spec .Channel = "simple"
81+
82+ _ , err = configClient .ClusterVersions ().Update (ctx , cv , metav1.UpdateOptions {})
83+ o .Expect (err ).NotTo (o .HaveOccurred ())
84+ needRecover = true
85+
86+ g .By ("Create a critical alert for testing" )
87+ prometheusRule := & monitoringv1.PrometheusRule {
88+ ObjectMeta : metav1.ObjectMeta {
89+ Name : "testing" ,
90+ Namespace : external .DefaultCVONamespace ,
91+ },
92+ Spec : monitoringv1.PrometheusRuleSpec {
93+ Groups : []monitoringv1.RuleGroup {
94+ {
95+ Name : "test" ,
96+ Rules : []monitoringv1.Rule {
97+ {
98+ Alert : "TestAlertFeatureE2ETestOTA1813" ,
99+ Annotations : map [string ]string {"summary" : "Test summary." , "description" : "Test description." },
100+ Expr : intstr.IntOrString {
101+ Type : intstr .String ,
102+ StrVal : `up{job="cluster-version-operator"} == 1` ,
103+ },
104+ Labels : map [string ]string {"severity" : "critical" , "namespace" : "openshift-cluster-version" , "openShiftUpdatePrecheck" : "true" },
105+ },
106+ },
107+ },
108+ },
109+ },
110+ }
111+ created , err := monitoringClient .PrometheusRules (external .DefaultCVONamespace ).Create (ctx , prometheusRule , metav1.CreateOptions {})
112+ o .Expect (err ).NotTo (o .HaveOccurred ())
113+ defer func () {
114+ err := monitoringClient .PrometheusRules (external .DefaultCVONamespace ).Delete (ctx , created .Name , metav1.DeleteOptions {})
115+ if ! errors .IsNotFound (err ) {
116+ o .Expect (err ).To (o .BeNil ())
117+ }
118+ }()
119+
120+ g .By ("Checking if the risk shows up in ClusterVersion's status" )
121+ o .Expect (wait .PollUntilContextTimeout (ctx , 30 * time .Second , 10 * time .Minute , true , func (ctx context.Context ) (done bool , err error ) {
122+ cv , err := configClient .ClusterVersions ().Get (ctx , external .DefaultClusterVersionName , metav1.GetOptions {})
123+ o .Expect (err ).NotTo (o .HaveOccurred ())
124+ for _ , risk := range cv .Status .ConditionalUpdateRisks {
125+ if risk .Name == "TestAlertFeatureE2ETestOTA1813" {
126+ if c := meta .FindStatusCondition (risk .Conditions , external .ConditionalUpdateRiskConditionTypeApplies ); c != nil {
127+ if c .Status == metav1 .ConditionTrue && external .IsAlertConditionReason (c .Reason ) {
128+ return true , nil
129+ }
130+ }
131+ }
132+ }
133+ return false , nil
134+ })).NotTo (o .HaveOccurred (), "no conditional update risk from alert found in ClusterVersion's status" )
135+
136+ g .By ("Checking that no updates is recommended if alert is firing" )
137+ o .Expect (wait .PollUntilContextTimeout (ctx , 30 * time .Second , 5 * time .Minute , true , func (ctx context.Context ) (done bool , err error ) {
138+ cv , err := configClient .ClusterVersions ().Get (ctx , external .DefaultClusterVersionName , metav1.GetOptions {})
139+ o .Expect (err ).NotTo (o .HaveOccurred ())
140+ if len (cv .Status .AvailableUpdates ) > 0 {
141+ return false , nil
142+ }
143+ for _ , cu := range cv .Status .ConditionalUpdates {
144+ condition := meta .FindStatusCondition (cu .Conditions , external .ConditionalUpdateConditionTypeRecommended )
145+ if condition == nil || condition .Status == metav1 .ConditionTrue || condition .Status == metav1 .ConditionUnknown {
146+ return false , nil
147+ }
148+ }
149+ return true , nil
150+ })).NotTo (o .HaveOccurred (), "still recommending updates while alert is firing" )
151+ })
152+
68153 g .It ("should work with accept risks" , g .Label ("Serial" ), func () {
69154 // This test case relies on a public service util.FauxinnatiAPIURL
70155 o .Expect (util .SkipIfNetworkRestricted (ctx , c , util .FauxinnatiAPIURL )).To (o .BeNil ())
0 commit comments