Skip to content

Commit aa30f92

Browse files
committed
[NE-2183] Add e2e test for gateway conditions
1 parent 3b1818d commit aa30f92

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

test/e2e/gateway_api_test.go

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package e2e
66
import (
77
"context"
88
"fmt"
9+
"math/rand/v2"
910
"strings"
1011
"testing"
1112
"time"
@@ -16,6 +17,9 @@ import (
1617
operatorclient "github.com/openshift/cluster-ingress-operator/pkg/operator/client"
1718
operatorcontroller "github.com/openshift/cluster-ingress-operator/pkg/operator/controller"
1819
util "github.com/openshift/cluster-ingress-operator/pkg/util"
20+
"github.com/stretchr/testify/assert"
21+
"github.com/stretchr/testify/require"
22+
condutils "k8s.io/apimachinery/pkg/api/meta"
1923

2024
corev1 "k8s.io/api/core/v1"
2125
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
@@ -101,6 +105,7 @@ func TestGatewayAPI(t *testing.T) {
101105
t.Run("testGatewayAPIDNS", testGatewayAPIDNS)
102106
t.Run("testGatewayAPIDNSListenerUpdate", testGatewayAPIDNSListenerUpdate)
103107
t.Run("testGatewayAPIDNSListenerWithNoHostname", testGatewayAPIDNSListenerWithNoHostname)
108+
t.Run("testGatewayOpenshiftConditions", testGatewayOpenshiftConditions)
104109

105110
} else {
106111
t.Log("Gateway API Controller not enabled, skipping controller tests")
@@ -587,6 +592,179 @@ func testGatewayAPIDNS(t *testing.T) {
587592
}
588593
})
589594
}
595+
}
596+
597+
// This e2e test will verify the following scenarios:
598+
// 1 - Creating a gateway with the right base domain but outside of `openshift-ingress`
599+
// namespace will not generate a DNSRecord nor add conditions to the gateway
600+
// 2 - Creating a Gateway on `openshift-ingress` namespace using the wrong base
601+
// domain should add DNS conditions that there are no managed zones for this case
602+
// 3 - Creating a Gateway with the right base domain on `openshift-ingress` will
603+
// add the conditions on the gateway reflecting the right status of LoadBalancer and DNSRecord
604+
// 4 - Bumping some label on the Gateway should trigger a reconciliation that will
605+
// bump the generation of conditions
606+
// 5 - Adding a label on DNSRecord and/or Service will trigger a reconciliation
607+
// that should be verified by a newly recorded event
608+
func testGatewayOpenshiftConditions(t *testing.T) {
609+
domain := "gwcondtest." + dnsConfig.Spec.BaseDomain
610+
611+
gatewayClass, err := createGatewayClass(t, operatorcontroller.OpenShiftDefaultGatewayClassName, operatorcontroller.OpenShiftGatewayClassControllerName)
612+
require.NoError(t, err, "failed to create gatewayclass")
613+
614+
t.Run("creating a new gateway outside of 'openshift-ingress' namespace should not get openshift conditions", func(t *testing.T) {
615+
rnd := rand.IntN(1000)
616+
name := fmt.Sprintf("gw-test-%d", rnd)
617+
testDomain := fmt.Sprintf("some-%d.%s", rnd, domain)
618+
gateway, err := createGateway(gatewayClass, name, "default", testDomain)
619+
require.NoError(t, err, "failed to create gateway", "name", name)
620+
t.Cleanup(func() {
621+
require.NoError(t, client.IgnoreNotFound(kclient.Delete(context.TODO(), gateway)), "failed to clean test gateway", "name", name)
622+
})
623+
624+
gateway, err = assertGatewaySuccessful(t, "default", name)
625+
require.NoError(t, err, "failed waiting gateway to be ready")
626+
// Give some time to guarantee our controller will watch the change but ignore it
627+
time.Sleep(time.Second)
628+
629+
// Get gateway a 2nd time ti check the conditions
630+
gateway, err = assertGatewaySuccessful(t, "default", name)
631+
require.NoError(t, err, "failed waiting gateway to have conditions")
632+
require.Nil(t, condutils.FindStatusCondition(gateway.Status.Conditions, "DNSManaged"), "condition should not be present")
633+
require.Nil(t, condutils.FindStatusCondition(gateway.Status.Conditions, "DNSReady"), "condition should not be present")
634+
require.Nil(t, condutils.FindStatusCondition(gateway.Status.Conditions, "LoadBalancerManaged"), "condition should not be present")
635+
require.Nil(t, condutils.FindStatusCondition(gateway.Status.Conditions, "LoadBalancerReady"), "condition should not be present")
636+
})
637+
638+
t.Run("creating a new gateway with the wrong base domain should add openshift conditions reflecting the failure", func(t *testing.T) {
639+
rnd := rand.IntN(1000)
640+
name := fmt.Sprintf("gw-test-%d", rnd)
641+
testDomain := fmt.Sprintf("some-%d.not.something.managed.tld", rnd)
642+
gateway, err := createGateway(gatewayClass, name, operatorcontroller.DefaultOperandNamespace, testDomain)
643+
require.NoError(t, err, "failed to create gateway", "name", name)
644+
t.Cleanup(func() {
645+
require.NoError(t, client.IgnoreNotFound(kclient.Delete(context.TODO(), gateway)), "failed to clean test gateway", "name", name)
646+
})
647+
648+
gateway, err = assertGatewaySuccessful(t, operatorcontroller.DefaultOperandNamespace, name)
649+
require.NoError(t, err, "failed waiting gateway to be ready")
650+
651+
assert.Eventuallyf(t, func() bool {
652+
gw := &gatewayapiv1.Gateway{}
653+
nsName := types.NamespacedName{Namespace: operatorcontroller.DefaultOperandNamespace, Name: name}
654+
if err := kclient.Get(context.Background(), nsName, gw); err != nil {
655+
t.Logf("Failed to get gateway %v: %v; retrying...", nsName, err)
656+
return false
657+
}
658+
659+
if condutils.IsStatusConditionTrue(gw.Status.Conditions, "DNSManaged") &&
660+
condutils.IsStatusConditionPresentAndEqual(gw.Status.Conditions, "DNSReady", metav1.ConditionUnknown) &&
661+
condutils.IsStatusConditionTrue(gw.Status.Conditions, "LoadBalancerManaged") &&
662+
condutils.IsStatusConditionTrue(gw.Status.Conditions, "LoadBalancerReady") {
663+
664+
return true
665+
}
666+
t.Logf("conditions are not yet the expected: %v, retrying...", gw.Status.Conditions)
667+
return false
668+
}, 30*time.Second, 2*time.Second, "error waiting for openshift conditions to be present on Gateway")
669+
})
670+
671+
t.Run("creating a new gateway with the right base domain", func(t *testing.T) {
672+
rnd := rand.IntN(1000)
673+
name := fmt.Sprintf("gw-test-%d", rnd)
674+
testDomain := fmt.Sprintf("some-%d.%s", rnd, domain)
675+
gateway, err := createGateway(gatewayClass, name, operatorcontroller.DefaultOperandNamespace, testDomain)
676+
require.NoError(t, err, "failed to create gateway", "name", name)
677+
t.Cleanup(func() {
678+
require.NoError(t, client.IgnoreNotFound(kclient.Delete(context.TODO(), gateway)), "failed to clean test gateway", "name", name)
679+
})
680+
681+
gateway, err = assertGatewaySuccessful(t, operatorcontroller.DefaultOperandNamespace, name)
682+
require.NoError(t, err, "failed waiting gateway to be ready")
683+
684+
err = assertExpectedDNSRecords(t, map[expectedDnsRecord]bool{
685+
{dnsName: "*." + testDomain + ".", gatewayName: name}: true})
686+
687+
assert.NoError(t, err, "dnsrecord never got ready")
688+
689+
t.Run("should add openshift conditions", func(t *testing.T) {
690+
assert.Eventuallyf(t, func() bool {
691+
gw := &gatewayapiv1.Gateway{}
692+
nsName := types.NamespacedName{Namespace: operatorcontroller.DefaultOperandNamespace, Name: name}
693+
if err := kclient.Get(context.Background(), nsName, gw); err != nil {
694+
t.Logf("Failed to get gateway %v: %v; retrying...", nsName, err)
695+
return false
696+
}
697+
698+
if condutils.IsStatusConditionTrue(gw.Status.Conditions, "DNSManaged") &&
699+
condutils.IsStatusConditionTrue(gw.Status.Conditions, "DNSReady") &&
700+
condutils.IsStatusConditionTrue(gw.Status.Conditions, "LoadBalancerManaged") &&
701+
condutils.IsStatusConditionTrue(gw.Status.Conditions, "LoadBalancerReady") {
702+
703+
return true
704+
}
705+
t.Logf("conditions are not yet the expected: %v, retrying...", gw.Status.Conditions)
706+
return false
707+
}, 30*time.Second, 2*time.Second, "error waiting for openshift conditions to be present on Gateway")
708+
})
709+
710+
t.Run("should bump openshift conditions when the gateway is changed", func(t *testing.T) {
711+
// Try to add a new infrastructure label, forcing the generation to bump
712+
originalGateway := &gatewayapiv1.Gateway{}
713+
assert.Eventually(t, func() bool {
714+
gw := &gatewayapiv1.Gateway{}
715+
nsName := types.NamespacedName{Namespace: operatorcontroller.DefaultOperandNamespace, Name: name}
716+
if err := kclient.Get(context.Background(), nsName, gw); err != nil {
717+
t.Logf("Failed to get gateway %v: %v; retrying...", nsName, err)
718+
return false
719+
}
720+
originalGateway = gw.DeepCopy()
721+
if gw.Spec.Infrastructure == nil {
722+
gw.Spec.Infrastructure = &gatewayapiv1.GatewayInfrastructure{}
723+
}
724+
if gw.Spec.Infrastructure.Labels == nil {
725+
gw.Spec.Infrastructure.Labels = make(map[gatewayapiv1.LabelKey]gatewayapiv1.LabelValue)
726+
}
727+
728+
gw.Spec.Infrastructure.Labels["something"] = "somelabel"
729+
730+
if err := kclient.Patch(context.Background(), gw, client.MergeFrom(originalGateway)); err != nil {
731+
t.Logf("failed to patch gateway %v: %v; retrying...", nsName, err)
732+
return false
733+
}
734+
return true
735+
}, 30*time.Second, 2*time.Second, "timeout waiting to patch the gateway")
736+
737+
gw := &gatewayapiv1.Gateway{}
738+
// Get the Gateway and check if conditions are there, and if their generation are different from the originalGateway value
739+
assert.Eventually(t, func() bool {
740+
nsName := types.NamespacedName{Namespace: operatorcontroller.DefaultOperandNamespace, Name: name}
741+
if err := kclient.Get(context.Background(), nsName, gw); err != nil {
742+
t.Logf("Failed to get gateway %v: %v; retrying...", nsName, err)
743+
return false
744+
}
745+
746+
dnsManaged := condutils.FindStatusCondition(gw.Status.Conditions, "DNSManaged")
747+
dnsReady := condutils.FindStatusCondition(gw.Status.Conditions, "DNSReady")
748+
loadBalancerManaged := condutils.FindStatusCondition(gw.Status.Conditions, "LoadBalancerManaged")
749+
loadBalancerReady := condutils.FindStatusCondition(gw.Status.Conditions, "LoadBalancerReady")
750+
751+
// Check if all conditions are not null and have a different generation from the original one
752+
// before adding the label
753+
if (dnsManaged != nil && dnsManaged.ObservedGeneration != originalGateway.Generation) &&
754+
(dnsReady != nil && dnsReady.ObservedGeneration != originalGateway.Generation) &&
755+
(loadBalancerManaged != nil && loadBalancerManaged.ObservedGeneration != originalGateway.Generation) &&
756+
(loadBalancerReady != nil && loadBalancerReady.ObservedGeneration != originalGateway.Generation) {
757+
return true
758+
}
759+
760+
t.Logf("conditions are not yet the expected: %v, retrying...", gw.Status.Conditions)
761+
return false
762+
}, 30*time.Second, 2*time.Second, "error waiting for openshift conditions to be present on Gateway")
763+
// We expect exactly 6 conditions. If we get more than it, Istio is adding
764+
// more conditions and we need to be aware that Gateway API status.conditons has a maxItems of 8
765+
assert.Len(t, gw.Status.Conditions, 6)
766+
})
767+
})
590768

591769
}
592770

0 commit comments

Comments
 (0)