Skip to content

Commit b0bfd36

Browse files
committed
NE-2097: e2e - Add TestOSSMOperatorUpgradeViaIntermediateVersions
The `TestOSSMOperatorUpgradeViaIntermediateVersions` test verifies that the OSSM operator correctly upgrades through intermediate versions. It ensures the upgrade logic automatically approves each InstallPlan along the upgrade graph until the desired version is reached. This test is not added to the suite of all tests because it will be run in a dedicated CI job to avoid conflicts with existing GatewayAPI jobs which install the latest supported version of OSSM operator and Istio.
1 parent 1a9b2da commit b0bfd36

File tree

1 file changed

+181
-0
lines changed

1 file changed

+181
-0
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
//go:build e2e
2+
// +build e2e
3+
4+
package e2e
5+
6+
import (
7+
"context"
8+
"testing"
9+
"time"
10+
11+
"k8s.io/apimachinery/pkg/types"
12+
"k8s.io/apimachinery/pkg/util/wait"
13+
"k8s.io/apiserver/pkg/storage/names"
14+
gatewayapiv1 "sigs.k8s.io/gateway-api/apis/v1"
15+
16+
configv1 "github.com/openshift/api/config/v1"
17+
"github.com/openshift/api/features"
18+
)
19+
20+
// TestOSSMOperatorUpgradeViaIntermediateVersions verifies that the OSSM operator
21+
// correctly upgrades through intermediate versions. It ensures the upgrade logic automatically approves
22+
// each InstallPlan along the upgrade graph until the desired version is reached.
23+
func TestOSSMOperatorUpgradeViaIntermediateVersions(t *testing.T) {
24+
gatewayAPIEnabled, err := isFeatureGateEnabled(features.FeatureGateGatewayAPI)
25+
if err != nil {
26+
t.Fatalf("Error checking feature gate enabled status: %v", err)
27+
}
28+
29+
gatewayAPIControllerEnabled, err := isFeatureGateEnabled(features.FeatureGateGatewayAPIController)
30+
if err != nil {
31+
t.Fatalf("Error checking controller feature gate enabled status: %v", err)
32+
}
33+
34+
if !gatewayAPIEnabled || !gatewayAPIControllerEnabled {
35+
t.Skip("Gateway API featuregates are not enabled, skipping TestOSSMOperatorUpgradeViaIntermediateVersions")
36+
}
37+
38+
var (
39+
initialOSSMVersion = "servicemeshoperator3.v3.0.0"
40+
initialIstioVersion = "v1.24.3"
41+
upgradeOSSMVersion = "servicemeshoperator3.v3.1.0"
42+
upgradeIstioVersion = "v1.26.2"
43+
)
44+
45+
// Installation.
46+
t.Logf("Creating GatewayClass with OSSMversion %q ans Istio version %q...", initialOSSMVersion, initialIstioVersion)
47+
gatewayClass := buildGatewayClass("openshift-default", "openshift.io/gateway-controller/v1")
48+
gatewayClass.Annotations = map[string]string{
49+
"unsupported.do-not-use.openshift.io/ossm-version": initialOSSMVersion,
50+
"unsupported.do-not-use.openshift.io/istio-version": initialIstioVersion,
51+
}
52+
if err := kclient.Create(context.TODO(), gatewayClass); err != nil {
53+
t.Fatalf("Failed to create gatewayclass %s: %v", gatewayClass.Name, err)
54+
}
55+
t.Log("Checking for the Subscription...")
56+
if err := assertSubscription(t, openshiftOperatorsNamespace, expectedSubscriptionName); err != nil {
57+
t.Fatalf("Failed to find expected Subscription %s: %v", expectedSubscriptionName, err)
58+
}
59+
t.Log("Checking for the CatalogSource...")
60+
if err := assertCatalogSource(t, expectedCatalogSourceNamespace, expectedCatalogSourceName); err != nil {
61+
t.Fatalf("Failed to find expected CatalogSource %s: %v", expectedCatalogSourceName, err)
62+
}
63+
t.Log("Checking for the OSSM operator deployment...")
64+
if err := assertOSSMOperatorWithConfig(t, initialOSSMVersion, 2*time.Second, 60*time.Second); err != nil {
65+
t.Fatalf("Failed to find expected Istio operator: %v", err)
66+
}
67+
t.Log("Checking for the Istio CR...")
68+
if err := assertIstioWithConfig(t, initialIstioVersion); err != nil {
69+
t.Fatalf("Failed to find expected Istio: %v", err)
70+
}
71+
t.Log("Checking for the GatewayClass readiness...")
72+
if _, err := assertGatewayClassSuccessful(t, "openshift-default"); err != nil {
73+
t.Fatalf("Failed to find successful GatewayClass: %v", err)
74+
}
75+
76+
// Upgrade.
77+
t.Logf("Upgrading GatewayClass to version %q and Istio version %q...", upgradeOSSMVersion, upgradeIstioVersion)
78+
if err := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 30*time.Second, false, func(context context.Context) (bool, error) {
79+
gc := &gatewayapiv1.GatewayClass{}
80+
if err := kclient.Get(context, types.NamespacedName{Name: gatewayClass.Name}, gc); err != nil {
81+
t.Logf("Failed to get GatewayClass %q: %v, retrying...", gatewayClass.Name, err)
82+
return false, nil
83+
}
84+
gc.Annotations = map[string]string{
85+
"unsupported.do-not-use.openshift.io/ossm-version": upgradeOSSMVersion,
86+
"unsupported.do-not-use.openshift.io/istio-version": upgradeIstioVersion,
87+
}
88+
if err := kclient.Update(context, gc); err != nil {
89+
t.Logf("Failed to update GatewayClass %q: %v, retrying...", gc.Name, err)
90+
return false, nil
91+
}
92+
t.Logf("GatewayClass %q has been updated to version %q", gc.Name, upgradeOSSMVersion)
93+
return true, nil
94+
}); err != nil {
95+
t.Fatalf("Failed to update GatewayClass to next version: %v", err)
96+
}
97+
t.Log("Checking for the status...")
98+
progressingNotDegraded := []configv1.ClusterOperatorStatusCondition{
99+
{
100+
Type: configv1.OperatorProgressing,
101+
Status: configv1.ConditionTrue,
102+
Reason: "OSSMOperatorUpgrading",
103+
},
104+
{
105+
Type: configv1.OperatorDegraded,
106+
Status: configv1.ConditionFalse,
107+
Reason: "IngressNotDegraded",
108+
},
109+
}
110+
if err := waitForClusterOperatorConditions(t, kclient, progressingNotDegraded...); err != nil {
111+
t.Fatalf("Operator should be Progressing=True and Degraded=False while upgrading: %v", err)
112+
}
113+
t.Log("Checking for the OSSM operator deployment...")
114+
if err := assertOSSMOperatorWithConfig(t, upgradeOSSMVersion, 2*time.Second, 2*time.Minute); err != nil {
115+
t.Fatalf("failed to find expected Istio operator: %v", err)
116+
}
117+
t.Log("Re-checking for the status...")
118+
notProgressingNotDegraded := []configv1.ClusterOperatorStatusCondition{
119+
{
120+
Type: configv1.OperatorProgressing,
121+
Status: configv1.ConditionFalse,
122+
Reason: "AsExpectedAndOSSMOperatorUpToDate",
123+
},
124+
{
125+
Type: configv1.OperatorDegraded,
126+
Status: configv1.ConditionFalse,
127+
Reason: "IngressNotDegraded",
128+
},
129+
}
130+
if err := waitForClusterOperatorConditions(t, kclient, notProgressingNotDegraded...); err != nil {
131+
t.Fatalf("Operator should be Progressing=False and Degraded=False once upgrade reached desired version: %v", err)
132+
}
133+
t.Log("Checking for the GatewayClass readiness...")
134+
if _, err := assertGatewayClassSuccessful(t, "openshift-default"); err != nil {
135+
t.Fatalf("Failed to find successful GatewayClass: %v", err)
136+
}
137+
t.Log("Checking for the Istio CR...")
138+
if err := assertIstioWithConfig(t, upgradeIstioVersion); err != nil {
139+
t.Fatalf("Failed to find expected Istio: %v", err)
140+
}
141+
}
142+
143+
// testConnectivity tests the connectivity to an HTTPRoute.
144+
func testConnectivity(t *testing.T, gatewayClass *gatewayapiv1.GatewayClass) {
145+
t.Helper()
146+
147+
// Use the dnsConfig base domain set up in TestMain.
148+
domain := "gws." + dnsConfig.Spec.BaseDomain
149+
150+
t.Log("Creating gateway...")
151+
testGateway, err := createGateway(gatewayClass, "test-upgrade-gateway", "openshift-ingress", domain)
152+
if err != nil {
153+
t.Fatalf("Gateway could not be created: %v", err)
154+
}
155+
// The gateway is cleaned up in TestGatewayAPI.
156+
157+
// Create a test namespace that cleans itself up and sets up its own service account and role binding.
158+
ns := createNamespace(t, names.SimpleNameGenerator.GenerateName("test-e2e-gwapi-upgrade-"))
159+
routeName := names.SimpleNameGenerator.GenerateName("test-hostname-") + "." + domain
160+
161+
t.Log("Creating httproute...")
162+
if _, err = createHttpRoute(ns.Name, "test-httproute", "openshift-ingress", routeName, "test-upgrade-gateway-openshift-default", testGateway); err != nil {
163+
t.Fatalf("HTTPRoute could not be created: %v", err)
164+
}
165+
// The http route is cleaned up when the namespace is deleted.
166+
167+
t.Log("Making sure the gateway is accepted...")
168+
if _, err := assertGatewaySuccessful(t, testGateway.Namespace, testGateway.Name); err != nil {
169+
t.Fatalf("Failed to find successful gateway: %v", err)
170+
}
171+
172+
t.Log("Making sure the httproute is accepted...")
173+
if _, err := assertHttpRouteSuccessful(t, ns.Name, "test-httproute", testGateway); err != nil {
174+
t.Fatalf("Failed to find successful httproute: %v", err)
175+
}
176+
177+
t.Log("Validating the connectivity to the backend application via the httproute...")
178+
if err := assertHttpRouteConnection(t, routeName, testGateway); err != nil {
179+
t.Fatalf("Failed to find successful httproute: %v", err)
180+
}
181+
}

0 commit comments

Comments
 (0)