Skip to content

Commit

Permalink
Merge pull request #2247 from levikobi/conformance-1315
Browse files Browse the repository at this point in the history
Check ResolvedRefs condition in Gateway conformance tests
  • Loading branch information
k8s-ci-robot authored Sep 21, 2023
2 parents 6d8927d + 6ced935 commit 2457533
Show file tree
Hide file tree
Showing 6 changed files with 160 additions and 61 deletions.
51 changes: 36 additions & 15 deletions conformance/tests/gateway-modify-listeners.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,18 @@ var GatewayModifyListeners = suite.ConformanceTest{
Group: (*v1beta1.Group)(&v1beta1.GroupVersion.Group),
Kind: v1beta1.Kind("HTTPRoute"),
}},
Conditions: []metav1.Condition{{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
}},
Conditions: []metav1.Condition{
{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
{
Type: string(v1beta1.ListenerConditionResolvedRefs),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
},
AttachedRoutes: 1,
},
{
Expand All @@ -100,11 +107,18 @@ var GatewayModifyListeners = suite.ConformanceTest{
Group: (*v1beta1.Group)(&v1beta1.GroupVersion.Group),
Kind: v1beta1.Kind("HTTPRoute"),
}},
Conditions: []metav1.Condition{{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
}},
Conditions: []metav1.Condition{
{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
{
Type: string(v1beta1.ListenerConditionResolvedRefs),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
},
AttachedRoutes: 1,
},
}
Expand Down Expand Up @@ -161,11 +175,18 @@ var GatewayModifyListeners = suite.ConformanceTest{
Group: (*v1beta1.Group)(&v1beta1.GroupVersion.Group),
Kind: v1beta1.Kind("HTTPRoute"),
}},
Conditions: []metav1.Condition{{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
}},
Conditions: []metav1.Condition{
{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
{
Type: string(v1beta1.ListenerConditionResolvedRefs),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
},
AttachedRoutes: 1,
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ var GatewaySecretReferenceGrantAllInNamespace = suite.ConformanceTest{
Status: metav1.ConditionTrue,
Reason: string(v1beta1.ListenerReasonProgrammed),
},
{
Type: string(v1beta1.ListenerConditionResolvedRefs),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
},
AttachedRoutes: 0,
}}
Expand Down
5 changes: 5 additions & 0 deletions conformance/tests/gateway-secret-reference-grant-specific.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ var GatewaySecretReferenceGrantSpecific = suite.ConformanceTest{
Status: metav1.ConditionTrue,
Reason: string(v1beta1.ListenerReasonProgrammed),
},
{
Type: string(v1beta1.ListenerConditionResolvedRefs),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
},
AttachedRoutes: 0,
}}
Expand Down
68 changes: 48 additions & 20 deletions conformance/tests/gateway-with-attached-routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,18 @@ var GatewayWithAttachedRoutes = suite.ConformanceTest{
Group: (*v1beta1.Group)(&v1beta1.GroupVersion.Group),
Kind: v1beta1.Kind("HTTPRoute"),
}},
Conditions: []metav1.Condition{{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
}},
Conditions: []metav1.Condition{
{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
{
Type: string(v1beta1.ListenerConditionResolvedRefs),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
},
AttachedRoutes: 1,
}}

Expand All @@ -66,11 +73,18 @@ var GatewayWithAttachedRoutes = suite.ConformanceTest{
Group: (*v1beta1.Group)(&v1beta1.GroupVersion.Group),
Kind: v1beta1.Kind("HTTPRoute"),
}},
Conditions: []metav1.Condition{{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
}},
Conditions: []metav1.Condition{
{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
{
Type: string(v1beta1.ListenerConditionResolvedRefs),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
},
AttachedRoutes: 2,
}}

Expand All @@ -97,11 +111,18 @@ var GatewayWithAttachedRoutesWithPort8080 = suite.ConformanceTest{
Group: (*v1beta1.Group)(&v1beta1.GroupVersion.Group),
Kind: v1beta1.Kind("HTTPRoute"),
}},
Conditions: []metav1.Condition{{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
}},
Conditions: []metav1.Condition{
{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
{
Type: string(v1beta1.ListenerConditionResolvedRefs),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
},
AttachedRoutes: 0,
},
{
Expand All @@ -110,11 +131,18 @@ var GatewayWithAttachedRoutesWithPort8080 = suite.ConformanceTest{
Group: (*v1beta1.Group)(&v1beta1.GroupVersion.Group),
Kind: v1beta1.Kind("HTTPRoute"),
}},
Conditions: []metav1.Condition{{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
}},
Conditions: []metav1.Condition{
{
Type: string(v1beta1.ListenerConditionAccepted),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
{
Type: string(v1beta1.ListenerConditionResolvedRefs),
Status: metav1.ConditionTrue,
Reason: "", // any reason
},
},
AttachedRoutes: 1,
},
}
Expand Down
40 changes: 24 additions & 16 deletions conformance/utils/config/timeout.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ type TimeoutConfig struct {
// Max value for conformant implementation: None
GatewayStatusMustHaveListeners time.Duration

// GatewayListenersMustHaveCondition represents the maximum time for a Gateway to have all listeners with a specific condition.
// Max value for conformant implementation: None
GatewayListenersMustHaveCondition time.Duration

// GWCMustBeAccepted represents the maximum time for a GatewayClass to have an Accepted condition set to true.
// Max value for conformant implementation: None
GWCMustBeAccepted time.Duration
Expand Down Expand Up @@ -91,22 +95,23 @@ type TimeoutConfig struct {
// DefaultTimeoutConfig populates a TimeoutConfig with the default values.
func DefaultTimeoutConfig() TimeoutConfig {
return TimeoutConfig{
CreateTimeout: 60 * time.Second,
DeleteTimeout: 10 * time.Second,
GetTimeout: 10 * time.Second,
GatewayMustHaveAddress: 180 * time.Second,
GatewayStatusMustHaveListeners: 60 * time.Second,
GWCMustBeAccepted: 180 * time.Second,
HTTPRouteMustNotHaveParents: 60 * time.Second,
HTTPRouteMustHaveCondition: 60 * time.Second,
TLSRouteMustHaveCondition: 60 * time.Second,
RouteMustHaveParents: 60 * time.Second,
ManifestFetchTimeout: 10 * time.Second,
MaxTimeToConsistency: 30 * time.Second,
NamespacesMustBeReady: 300 * time.Second,
RequestTimeout: 10 * time.Second,
LatestObservedGenerationSet: 60 * time.Second,
RequiredConsecutiveSuccesses: 3,
CreateTimeout: 60 * time.Second,
DeleteTimeout: 10 * time.Second,
GetTimeout: 10 * time.Second,
GatewayMustHaveAddress: 180 * time.Second,
GatewayStatusMustHaveListeners: 60 * time.Second,
GatewayListenersMustHaveCondition: 60 * time.Second,
GWCMustBeAccepted: 180 * time.Second,
HTTPRouteMustNotHaveParents: 60 * time.Second,
HTTPRouteMustHaveCondition: 60 * time.Second,
TLSRouteMustHaveCondition: 60 * time.Second,
RouteMustHaveParents: 60 * time.Second,
ManifestFetchTimeout: 10 * time.Second,
MaxTimeToConsistency: 30 * time.Second,
NamespacesMustBeReady: 300 * time.Second,
RequestTimeout: 10 * time.Second,
LatestObservedGenerationSet: 60 * time.Second,
RequiredConsecutiveSuccesses: 3,
}
}

Expand All @@ -127,6 +132,9 @@ func SetupTimeoutConfig(timeoutConfig *TimeoutConfig) {
if timeoutConfig.GatewayStatusMustHaveListeners == 0 {
timeoutConfig.GatewayStatusMustHaveListeners = defaultTimeoutConfig.GatewayStatusMustHaveListeners
}
if timeoutConfig.GatewayListenersMustHaveCondition == 0 {
timeoutConfig.GatewayListenersMustHaveCondition = defaultTimeoutConfig.GatewayListenersMustHaveCondition
}
if timeoutConfig.GWCMustBeAccepted == 0 {
timeoutConfig.GWCMustBeAccepted = defaultTimeoutConfig.GWCMustBeAccepted
}
Expand Down
52 changes: 42 additions & 10 deletions conformance/utils/kubernetes/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,12 @@ func MeshNamespacesMustBeReady(t *testing.T, c client.Client, timeoutConfig conf
require.NoErrorf(t, waitErr, "error waiting for %s namespaces to be ready", strings.Join(namespaces, ", "))
}

// GatewayAndHTTPRoutesMustBeAccepted waits until the specified Gateway has an IP
// address assigned to it and the Route has a ParentRef referring to the
// Gateway. The test will fail if these conditions are not met before the
// GatewayAndHTTPRoutesMustBeAccepted waits until:
// 1. The specified Gateway has an IP address assigned to it.
// 2. The route has a ParentRef referring to the Gateway.
// 3. All the gateway's listeners have the ListenerConditionResolvedRefs set to true.
//
// The test will fail if these conditions are not met before the
// timeouts.
func GatewayAndHTTPRoutesMustBeAccepted(t *testing.T, c client.Client, timeoutConfig config.TimeoutConfig, controllerName string, gw GatewayRef, routeNNs ...types.NamespacedName) string {
t.Helper()
Expand Down Expand Up @@ -297,18 +300,24 @@ func GatewayAndHTTPRoutesMustBeAccepted(t *testing.T, c client.Client, timeoutCo
SectionName: listener,
},
ControllerName: v1beta1.GatewayController(controllerName),
Conditions: []metav1.Condition{
{
Type: string(v1beta1.RouteConditionAccepted),
Status: metav1.ConditionTrue,
Reason: string(v1beta1.RouteReasonAccepted),
},
},
Conditions: []metav1.Condition{{
Type: string(v1beta1.RouteConditionAccepted),
Status: metav1.ConditionTrue,
Reason: string(v1beta1.RouteReasonAccepted),
}},
})
}
HTTPRouteMustHaveParents(t, c, timeoutConfig, routeNN, parents, namespaceRequired)
}

resolvedRefsCondition := metav1.Condition{
Type: string(v1beta1.ListenerConditionResolvedRefs),
Status: metav1.ConditionTrue,
Reason: "", // any reason
}

GatewayListenersMustHaveCondition(t, c, timeoutConfig, gw.NamespacedName, resolvedRefsCondition)

return gwAddr
}

Expand Down Expand Up @@ -347,6 +356,29 @@ func WaitForGatewayAddress(t *testing.T, client client.Client, timeoutConfig con
return net.JoinHostPort(ipAddr, port), waitErr
}

// GatewayListenersMustHaveCondition checks if every listener of the specified gateway has a
// certain condition.
func GatewayListenersMustHaveCondition(t *testing.T, client client.Client, timeoutConfig config.TimeoutConfig, gwName types.NamespacedName, condition metav1.Condition) {
t.Helper()

waitErr := wait.PollUntilContextTimeout(context.Background(), 1*time.Second, timeoutConfig.GatewayListenersMustHaveCondition, true, func(ctx context.Context) (bool, error) {
var gw v1beta1.Gateway
if err := client.Get(ctx, gwName, &gw); err != nil {
return false, fmt.Errorf("error fetching Gateway: %w", err)
}

for _, listener := range gw.Status.Listeners {
if !findConditionInList(t, listener.Conditions, condition.Type, string(condition.Status), condition.Reason) {
return false, nil
}
}

return true, nil
})

require.NoErrorf(t, waitErr, "error waiting for Gateway status to have a Condition matching expectations on all listeners")
}

// GatewayMustHaveZeroRoutes validates that the gateway has zero routes attached. The status
// may indicate a single listener with zero attached routes or no listeners.
func GatewayMustHaveZeroRoutes(t *testing.T, client client.Client, timeoutConfig config.TimeoutConfig, gwName types.NamespacedName) {
Expand Down

0 comments on commit 2457533

Please sign in to comment.