@@ -20,22 +20,48 @@ import (
2020 "encoding/json"
2121 "fmt"
2222 "io"
23+ "log"
2324 "net/http"
2425 "net/url"
2526 "strings"
2627 "sync"
2728 "time"
2829
30+ "github.com/apache/apisix-ingress-controller/api/v1alpha1"
2931 "github.com/gavv/httpexpect/v2"
32+ "github.com/gruntwork-io/terratest/modules/testing"
3033 "github.com/onsi/gomega"
34+ "github.com/pkg/errors"
35+ "github.com/stretchr/testify/require"
3136 "golang.org/x/net/html"
3237 corev1 "k8s.io/api/core/v1"
3338 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
39+ "k8s.io/apimachinery/pkg/runtime"
40+ "k8s.io/apimachinery/pkg/types"
41+ utilruntime "k8s.io/apimachinery/pkg/util/runtime"
42+ "k8s.io/apimachinery/pkg/util/wait"
3443 "k8s.io/client-go/kubernetes/scheme"
3544 "k8s.io/client-go/tools/remotecommand"
3645 "k8s.io/utils/ptr"
46+ "sigs.k8s.io/controller-runtime/pkg/client"
47+ gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
48+ "sigs.k8s.io/gateway-api/conformance/utils/kubernetes"
3749)
3850
51+ var (
52+ scheme_ = runtime .NewScheme ()
53+ )
54+
55+ func init () {
56+ utilruntime .Must (scheme .AddToScheme (scheme_ ))
57+ if err := gatewayv1 .Install (scheme_ ); err != nil {
58+ panic (err )
59+ }
60+ if err := v1alpha1 .AddToScheme (scheme_ ); err != nil {
61+ panic (err )
62+ }
63+ }
64+
3965func (f * Framework ) NewExpectResponse (httpBody any ) * httpexpect.Response {
4066 body , err := json .Marshal (httpBody )
4167 f .GomegaT .Expect (err ).ShouldNot (gomega .HaveOccurred ())
@@ -369,6 +395,42 @@ func CreateTestZipFile(sourceCode, metadata string) ([]byte, error) {
369395 return zipBuffer .Bytes (), nil
370396}
371397
398+ func HTTPRoutePolicyMustHaveCondition (t testing.TestingT , client client.Client , timeout time.Duration , refNN , hrpNN types.NamespacedName , condition metav1.Condition ) {
399+ _ = v1alpha1 .AddToScheme (client .Scheme ())
400+
401+ err := EventullyHTTPRoutePolicyHaveStatus (client , timeout , hrpNN , func (httpRoutePolicy v1alpha1.HTTPRoutePolicy , status v1alpha1.PolicyStatus ) bool {
402+ var (
403+ ancestors = status .Ancestors
404+ conditionFound bool
405+ )
406+ for _ , ancestor := range ancestors {
407+ if err := kubernetes .ConditionsHaveLatestObservedGeneration (& httpRoutePolicy , ancestor .Conditions ); err != nil {
408+ log .Printf ("HTTPRoutePolicy %s (parentRef=%v) %v" , hrpNN , parentRefToString (ancestor .AncestorRef ), err )
409+ return false
410+ }
411+
412+ if ancestor .AncestorRef .Name == gatewayv1 .ObjectName (refNN .Name ) && (ancestor .AncestorRef .Namespace == nil || string (* ancestor .AncestorRef .Namespace ) == refNN .Namespace ) {
413+ if findConditionInList (t , ancestor .Conditions , condition ) {
414+ conditionFound = true
415+ }
416+ }
417+ }
418+ return conditionFound
419+ })
420+
421+ require .NoError (t , err , "error waiting for HTTPRoutePolicy status to have a Condition matching expectations" )
422+ }
423+
424+ func EventullyHTTPRoutePolicyHaveStatus (client client.Client , timeout time.Duration , hrpNN types.NamespacedName , f func (httpRoutePolicy v1alpha1.HTTPRoutePolicy , status v1alpha1.PolicyStatus ) bool ) error {
425+ return wait .PollUntilContextTimeout (context .Background (), time .Second , timeout , true , func (ctx context.Context ) (done bool , err error ) {
426+ var httpRoutePolicy v1alpha1.HTTPRoutePolicy
427+ if err = client .Get (ctx , hrpNN , & httpRoutePolicy ); err != nil {
428+ return false , errors .Errorf ("error fetching HTTPRoutePolicy %v: %v" , hrpNN , err )
429+ }
430+ return f (httpRoutePolicy , httpRoutePolicy .Status ), nil
431+ })
432+ }
433+
372434func addFileToZip (zipWriter * zip.Writer , fileName , fileContent string ) error {
373435 file , err := zipWriter .Create (fileName )
374436 if err != nil {
@@ -378,3 +440,30 @@ func addFileToZip(zipWriter *zip.Writer, fileName, fileContent string) error {
378440 _ , err = file .Write ([]byte (fileContent ))
379441 return err
380442}
443+
444+ func parentRefToString (p gatewayv1.ParentReference ) string {
445+ if p .Namespace != nil && * p .Namespace != "" {
446+ return fmt .Sprintf ("%v/%v" , p .Namespace , p .Name )
447+ }
448+ return string (p .Name )
449+ }
450+
451+ func findConditionInList (t testing.TestingT , conditions []metav1.Condition , expected metav1.Condition ) bool {
452+ for _ , cond := range conditions {
453+ if cond .Type == expected .Type {
454+ // an empty Status string means "Match any status".
455+ if expected .Status == "" || cond .Status == expected .Status {
456+ // an empty Reason string means "Match any reason".
457+ if expected .Reason == "" || cond .Reason == expected .Reason {
458+ return true
459+ }
460+ log .Printf ("%s condition Reason set to %s, expected %s" , expected .Type , cond .Reason , expected .Reason )
461+ }
462+
463+ log .Printf ("%s condition set to Status %s with Reason %v, expected Status %s" , expected .Type , cond .Status , cond .Reason , expected .Status )
464+ }
465+ }
466+
467+ log .Printf ("%s was not in conditions list [%v]" , expected .Type , conditions )
468+ return false
469+ }
0 commit comments