Skip to content

Commit a7fa4c5

Browse files
committed
NE-2097: e2e - Add cleanup helpers for GatewayAPI resources
This commit introduces helper functions to clean up Gateway, GatewayClass, and OLM operator after e2e tests. These functions are integrated into the GatewayAPI and GatewayAPI upgrade tests to prevent conflicts and ensure a clean environment for subsequent runs.
1 parent 8912229 commit a7fa4c5

File tree

12 files changed

+1162
-6
lines changed

12 files changed

+1162
-6
lines changed

test/e2e/gateway_api_test.go

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,19 @@ func TestGatewayAPI(t *testing.T) {
8383

8484
// Defer the cleanup of the test gateway.
8585
t.Cleanup(func() {
86-
testGateway := gatewayapiv1.Gateway{ObjectMeta: metav1.ObjectMeta{Name: testGatewayName, Namespace: operatorcontroller.DefaultOperandNamespace}}
87-
if err := kclient.Delete(context.TODO(), &testGateway); err != nil {
88-
if errors.IsNotFound(err) {
89-
return
86+
// Keeping test resources for must-gather if test failed.
87+
if !t.Failed() {
88+
t.Logf("Cleaning Gateway, GatewayClass and OSSM operator...")
89+
if err := cleanupGateway(t, "openshift-ingress", "test-gateway", "openshift-default"); err != nil {
90+
t.Errorf("Failed to cleanup gateway: %v", err)
91+
}
92+
if err := cleanupGatewayClass(t, "openshift-default"); err != nil {
93+
t.Errorf("Failed to cleanup gatewayclass: %v", err)
94+
}
95+
if err := cleanupOLMOperator(t, "openshift-operators", "servicemeshoperator3.openshift-operators"); err != nil {
96+
t.Errorf("Failed to cleanup OSSM operator: %v", err)
9097
}
91-
t.Errorf("failed to delete gateway %q: %v", testGateway.Name, err)
9298
}
93-
// TODO: Uninstall OSSM after test is completed.
9499
})
95100

96101
t.Run("testGatewayAPIResources", testGatewayAPIResources)

test/e2e/gateway_api_upgrade_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ func TestOSSMOperatorUpgradeViaIntermediateVersions(t *testing.T) {
3535
t.Skip("Gateway API featuregates are not enabled, skipping TestOSSMOperatorUpgradeViaIntermediateVersions")
3636
}
3737

38+
t.Cleanup(func() {
39+
// Keeping test resources for must-gather if test failed.
40+
if !t.Failed() {
41+
t.Logf("Cleaning GatewayClass and OSSM operator...")
42+
if err := cleanupGatewayClass(t, "openshift-default"); err != nil {
43+
t.Errorf("Failed to cleanup gatewayclass: %v", err)
44+
}
45+
if err := cleanupOLMOperator(t, "openshift-operators", "servicemeshoperator3.openshift-operators"); err != nil {
46+
t.Errorf("Failed to cleanup OSSM operator: %v", err)
47+
}
48+
}
49+
})
50+
3851
var (
3952
initialOSSMVersion = "servicemeshoperator3.v3.0.0"
4053
initialIstioVersion = "v1.24.3"

test/e2e/operator_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
operatorv1 "github.com/openshift/api/operator/v1"
3232
iov1 "github.com/openshift/api/operatoringress/v1"
3333
routev1 "github.com/openshift/api/route/v1"
34+
olmv1 "github.com/operator-framework/api/pkg/operators/v1"
3435

3536
configclientset "github.com/openshift/client-go/config/clientset/versioned"
3637
"github.com/openshift/cluster-ingress-operator/pkg/manifests"
@@ -173,6 +174,12 @@ func TestMain(m *testing.M) {
173174
}
174175
kclient = kubeClient
175176

177+
// GatewayAPI tests need to clean up the OSSM operator.
178+
if olmv1.AddToScheme(operatorclient.GetScheme()); err != nil {
179+
fmt.Printf("failed to install olmv1 scheme: %s\n", err)
180+
os.Exit(1)
181+
}
182+
176183
configClient, err = configclientset.NewForConfig(kubeConfig)
177184
if err != nil {
178185
fmt.Printf("failed to create config client: %s\n", err)

test/e2e/util_gatewayapi_test.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
v1 "github.com/openshift/api/operatoringress/v1"
2121
operatorcontroller "github.com/openshift/cluster-ingress-operator/pkg/operator/controller"
2222
util "github.com/openshift/cluster-ingress-operator/pkg/util"
23+
olmv1 "github.com/operator-framework/api/pkg/operators/v1"
2324
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
2425

2526
"github.com/google/go-cmp/cmp"
@@ -30,6 +31,7 @@ import (
3031
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3132
kerrors "k8s.io/apimachinery/pkg/api/errors"
3233
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
34+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
3335
"k8s.io/apimachinery/pkg/types"
3436
"k8s.io/apimachinery/pkg/util/wait"
3537

@@ -180,6 +182,105 @@ func deleteExistingVAP(t *testing.T, vapName string) error {
180182
return nil
181183
}
182184

185+
// cleanupGateway deletes the given gateway and waits for the corresponding Istio proxy deployment to disappear.
186+
func cleanupGateway(t *testing.T, namespace, name, gcname string) error {
187+
t.Helper()
188+
189+
gw := &gatewayapiv1.Gateway{ObjectMeta: metav1.ObjectMeta{Namespace: namespace, Name: name}}
190+
if err := kclient.Delete(context.Background(), gw); err != nil && !kerrors.IsNotFound(err) {
191+
return fmt.Errorf(`failed to delete gateway "%s/%s": %w`, namespace, name, err)
192+
}
193+
t.Logf(`Deleted gateway "%s/%s"`, namespace, name)
194+
195+
depl := &appsv1.Deployment{}
196+
istioName := types.NamespacedName{Namespace: operatorcontroller.DefaultOperandNamespace, Name: name + "-" + gcname}
197+
if err := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 1*time.Minute, false, func(context context.Context) (bool, error) {
198+
if err := kclient.Get(context, istioName, depl); err != nil {
199+
if !kerrors.IsNotFound(err) {
200+
t.Logf("Failed to get deployment %q, retrying...", istioName)
201+
return false, nil
202+
}
203+
} else {
204+
t.Logf("Deployment %q still exists, retrying...", istioName)
205+
return false, nil
206+
}
207+
return true, nil
208+
}); err != nil {
209+
return fmt.Errorf("timed out waiting for deployment %v to disappear", istioName)
210+
}
211+
t.Logf("Deleted deployment %q", istioName)
212+
213+
return nil
214+
}
215+
216+
// cleanupGatewayClass deletes the given gatewayclass and waits for the corresponding Istiod deployment to disappear.
217+
func cleanupGatewayClass(t *testing.T, name string) error {
218+
t.Helper()
219+
220+
gc := &gatewayapiv1.GatewayClass{ObjectMeta: metav1.ObjectMeta{Name: name}}
221+
if err := kclient.Delete(context.Background(), gc); err != nil && !kerrors.IsNotFound(err) {
222+
return fmt.Errorf("failed to delete gatewayclass %q: %w", name, err)
223+
}
224+
t.Logf("Deleted gatewayclass %q", name)
225+
226+
depl := &appsv1.Deployment{}
227+
istiodName := types.NamespacedName{Namespace: operatorcontroller.DefaultOperandNamespace, Name: "istiod-" + name}
228+
if err := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 1*time.Minute, false, func(context context.Context) (bool, error) {
229+
if err := kclient.Get(context, istiodName, depl); err != nil {
230+
if !kerrors.IsNotFound(err) {
231+
t.Logf("Failed to get deployment %q, retrying...", istiodName)
232+
return false, nil
233+
}
234+
} else {
235+
t.Logf("Deployment %q still exists, retrying...", istiodName)
236+
return false, nil
237+
}
238+
return true, nil
239+
}); err != nil {
240+
return fmt.Errorf("timed out waiting for deployment %v to disappear", istiodName)
241+
}
242+
t.Logf("Deleted deployment %q", istiodName)
243+
244+
return nil
245+
}
246+
247+
// cleanupOLMOperator deletes all components associated with the given OLM operator, including the operator resource itself.
248+
func cleanupOLMOperator(t *testing.T, namespace, name string) error {
249+
operatorName := types.NamespacedName{Namespace: namespace, Name: name}
250+
operator := &olmv1.Operator{}
251+
if err := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, 1*time.Minute, false, func(context context.Context) (bool, error) {
252+
if err := kclient.Get(context, operatorName, operator); err != nil {
253+
t.Logf("Failed to get operator %q, retrying...", operatorName)
254+
return false, nil
255+
}
256+
return true, nil
257+
}); err != nil {
258+
return fmt.Errorf("timed out getting operator %v", operatorName)
259+
}
260+
261+
if operator.Status.Components != nil {
262+
for _, compRef := range operator.Status.Components.Refs {
263+
if compRef.Kind != "CustomResourceDefinition" {
264+
unstructuredObj := &unstructured.Unstructured{}
265+
unstructuredObj.SetAPIVersion(compRef.APIVersion)
266+
unstructuredObj.SetKind(compRef.Kind)
267+
unstructuredObj.SetName(compRef.Name)
268+
unstructuredObj.SetNamespace(namespace)
269+
if err := kclient.Delete(context.Background(), unstructuredObj); err != nil && !kerrors.IsNotFound(err) {
270+
return fmt.Errorf(`failed to delete operator component "%s/%s/%s/%s": %w`, compRef.APIVersion, compRef.Kind, namespace, compRef.Name, err)
271+
}
272+
t.Logf(`Deleted operator component "%s/%s/%s/%s"`, compRef.APIVersion, compRef.Kind, namespace, compRef.Name)
273+
}
274+
}
275+
}
276+
if err := kclient.Delete(context.Background(), operator); err != nil && !kerrors.IsNotFound(err) {
277+
return fmt.Errorf("failed to delete operator %q: %w", operatorName, err)
278+
}
279+
t.Logf("Deleted operator %q", operatorName)
280+
281+
return nil
282+
}
283+
183284
// createHttpRoute checks if the HTTPRoute can be created.
184285
// If it can't an error is returned.
185286
func createHttpRoute(namespace, routeName, parentNamespace, hostname, backendRefname string, gateway *gatewayapiv1.Gateway) (*gatewayapiv1.HTTPRoute, error) {

vendor/github.com/operator-framework/api/pkg/operators/v1/doc.go

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/operator-framework/api/pkg/operators/v1/groupversion_info.go

Lines changed: 28 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/operator-framework/api/pkg/operators/v1/olmconfig_types.go

Lines changed: 90 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)