1
16
17 package tests
18
19 import (
20 "context"
21 "testing"
22 "time"
23
24 "github.com/stretchr/testify/require"
25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 "k8s.io/apimachinery/pkg/types"
27 "sigs.k8s.io/controller-runtime/pkg/client"
28
29 v1 "sigs.k8s.io/gateway-api/apis/v1"
30 "sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
31 "sigs.k8s.io/gateway-api/conformance/utils/suite"
32 )
33
34 func init() {
35 ConformanceTests = append(ConformanceTests, GatewayStaticAddresses)
36 }
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57 var GatewayStaticAddresses = suite.ConformanceTest{
58 ShortName: "GatewayStaticAddresses",
59 Description: "A Gateway in the gateway-conformance-infra namespace should be able to use previously determined addresses.",
60 Features: []suite.SupportedFeature{
61 suite.SupportGateway,
62 suite.SupportGatewayStaticAddresses,
63 },
64 Manifests: []string{
65 "tests/gateway-static-addresses.yaml",
66 },
67 Test: func(t *testing.T, s *suite.ConformanceTestSuite) {
68 gwNN := types.NamespacedName{
69 Name: "gateway-static-addresses",
70 Namespace: "gateway-conformance-infra",
71 }
72 ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
73 defer cancel()
74
75 t.Logf("waiting for namespace %s and Gateway %s to be ready for testing", gwNN.Namespace, gwNN.Name)
76 kubernetes.GatewayMustHaveLatestConditions(t, s.Client, s.TimeoutConfig, gwNN)
77
78 t.Logf("retrieving Gateway %s/%s and noting the provided addresses", gwNN.Namespace, gwNN.Name)
79 currentGW := &v1.Gateway{}
80 err := s.Client.Get(ctx, gwNN, currentGW)
81 require.NoError(t, err, "error getting Gateway: %v", err)
82 require.Len(t, currentGW.Spec.Addresses, 3, "expected 3 addresses on the Gateway, one invalid, one usable and one unusable. somehow got %d", len(currentGW.Spec.Addresses))
83 invalidAddress := currentGW.Spec.Addresses[0]
84 unusableAddress := currentGW.Spec.Addresses[1]
85 usableAddress := currentGW.Spec.Addresses[2]
86
87 t.Logf("verifying that the Gateway %s/%s is NOT accepted due to an address type that the implementation doesn't support", gwNN.Namespace, gwNN.Name)
88 kubernetes.GatewayMustHaveCondition(t, s.Client, s.TimeoutConfig, gwNN, metav1.Condition{
89 Type: string(v1.GatewayConditionAccepted),
90 Status: metav1.ConditionFalse,
91 Reason: string(v1.GatewayReasonUnsupportedAddress),
92 })
93
94 t.Logf("patching Gateway %s/%s to remove the invalid address %s", gwNN.Namespace, gwNN.Name, invalidAddress.Value)
95 updatedGW := currentGW.DeepCopy()
96 updatedGW.Spec.Addresses = filterAddr(currentGW.Spec.Addresses, invalidAddress)
97 err = s.Client.Patch(ctx, updatedGW, client.MergeFrom(currentGW))
98 require.NoError(t, err, "failed to patch Gateway: %v", err)
99 kubernetes.GatewayMustHaveLatestConditions(t, s.Client, s.TimeoutConfig, gwNN)
100
101 t.Logf("verifying that the Gateway %s/%s is now accepted, but is not programmed due to an address that can't be used", gwNN.Namespace, gwNN.Name)
102 err = s.Client.Get(ctx, gwNN, currentGW)
103 require.NoError(t, err, "error getting Gateway: %v", err)
104 kubernetes.GatewayMustHaveCondition(t, s.Client, s.TimeoutConfig, gwNN, metav1.Condition{
105 Type: string(v1.GatewayConditionAccepted),
106 Status: metav1.ConditionTrue,
107 Reason: string(v1.GatewayReasonAccepted),
108 })
109 kubernetes.GatewayMustHaveCondition(t, s.Client, s.TimeoutConfig, gwNN, metav1.Condition{
110 Type: string(v1.GatewayConditionProgrammed),
111 Status: metav1.ConditionFalse,
112 Reason: string(v1.GatewayReasonAddressNotUsable),
113 })
114
115 t.Logf("patching Gateway %s/%s to remove the unusable address %s", gwNN.Namespace, gwNN.Name, unusableAddress.Value)
116 updatedGW = currentGW.DeepCopy()
117 updatedGW.Spec.Addresses = filterAddr(currentGW.Spec.Addresses, unusableAddress)
118 err = s.Client.Patch(ctx, updatedGW, client.MergeFrom(currentGW))
119 require.NoError(t, err, "failed to patch Gateway: %v", err)
120 kubernetes.GatewayMustHaveLatestConditions(t, s.Client, s.TimeoutConfig, gwNN)
121
122 t.Logf("verifying that the Gateway %s/%s is accepted and programmed with the usable static address %s assigned", gwNN.Namespace, gwNN.Name, usableAddress.Value)
123 err = s.Client.Get(ctx, gwNN, currentGW)
124 require.NoError(t, err, "error getting Gateway: %v", err)
125 kubernetes.GatewayMustHaveCondition(t, s.Client, s.TimeoutConfig, gwNN, metav1.Condition{
126 Type: string(v1.GatewayConditionAccepted),
127 Status: metav1.ConditionTrue,
128 Reason: string(v1.GatewayReasonAccepted),
129 })
130 kubernetes.GatewayMustHaveCondition(t, s.Client, s.TimeoutConfig, gwNN, metav1.Condition{
131 Type: string(v1.GatewayConditionProgrammed),
132 Status: metav1.ConditionTrue,
133 Reason: string(v1.GatewayReasonProgrammed),
134 })
135 kubernetes.GatewayStatusMustHaveListeners(t, s.Client, s.TimeoutConfig, gwNN, finalExpectedListenerState)
136 require.Len(t, currentGW.Spec.Addresses, 1, "expected only 1 address left specified on Gateway")
137 require.Len(t, currentGW.Status.Addresses, 1, "one usable address was provided, so it should be the one reflected in status")
138 require.Equal(t, usableAddress.Type, currentGW.Status.Addresses[0].Type, "expected address type to match the usable address")
139 require.Equal(t, usableAddress.Value, currentGW.Status.Addresses[0].Value, "expected usable address to be assigned")
140 },
141 }
142
143
144
145
146
147 func filterAddr(addrs []v1.GatewayAddress, filter v1.GatewayAddress) (newAddrs []v1.GatewayAddress) {
148 for _, addr := range addrs {
149 if addr.Value != filter.Value {
150 newAddrs = append(newAddrs, addr)
151 }
152 }
153 return
154 }
155
156 var finalExpectedListenerState = []v1.ListenerStatus{
157 {
158 Name: v1.SectionName("http"),
159 SupportedKinds: []v1.RouteGroupKind{{
160 Group: (*v1.Group)(&v1.GroupVersion.Group),
161 Kind: v1.Kind("HTTPRoute"),
162 }},
163 Conditions: []metav1.Condition{
164 {
165 Type: string(v1.ListenerConditionAccepted),
166 Status: metav1.ConditionTrue,
167 Reason: "",
168 },
169 {
170 Type: string(v1.ListenerConditionResolvedRefs),
171 Status: metav1.ConditionTrue,
172 Reason: "",
173 },
174 },
175 AttachedRoutes: 0,
176 },
177 }
178
View as plain text