11package conformance
22
33import (
4+ "context"
45 "fmt"
56 "os"
67 "testing"
8+ "time"
79
810 "github.com/api7/api7-ingress-controller/test/e2e/framework"
911 "github.com/gruntwork-io/terratest/modules/k8s"
12+ "github.com/gruntwork-io/terratest/modules/retry"
13+ "sigs.k8s.io/controller-runtime/pkg/client"
1014
1115 . "github.com/onsi/ginkgo/v2"
1216 . "github.com/onsi/gomega"
17+ gatewayv1 "sigs.k8s.io/gateway-api/apis/v1"
1318)
1419
1520var gatewayClassName = "api7"
@@ -24,15 +29,84 @@ spec:
2429 controllerName: %s
2530` , gatewayClassName , controllerName )
2631
32+ var gatewayProxyYaml = `
33+ apiVersion: gateway.apisix.io/v1alpha1
34+ kind: GatewayProxy
35+ metadata:
36+ name: conformance-gateway-proxy
37+ namespace: %s
38+ spec:
39+ statusAddress:
40+ - %s
41+ provider:
42+ type: ControlPlane
43+ controlPlane:
44+ endpoints:
45+ - %s
46+ auth:
47+ type: AdminKey
48+ adminKey:
49+ value: %s
50+ `
51+
52+ type GatewayProxyOpts struct {
53+ StatusAddress string
54+ AdminKey string
55+ AdminEndpoint string
56+ }
57+
58+ var defaultGatewayProxyOpts GatewayProxyOpts
59+
2760func TestMain (m * testing.M ) {
2861 RegisterFailHandler (Fail )
2962 f := framework .NewFramework ()
3063
3164 f .BeforeSuite ()
3265
33- namespace := "api7ee-conformance-test"
34-
66+ // Check and delete specific namespaces if they exist
3567 kubectl := k8s .NewKubectlOptions ("" , "" , "default" )
68+ namespacesToDelete := []string {
69+ "gateway-conformance-infra" ,
70+ "gateway-conformance-web-backend" ,
71+ "gateway-conformance-app-backend" ,
72+ }
73+
74+ for _ , ns := range namespacesToDelete {
75+ _ , err := k8s .GetNamespaceE (GinkgoT (), kubectl , ns )
76+ if err == nil {
77+ // Namespace exists, delete it
78+ GinkgoT ().Logf ("Deleting existing namespace: %s" , ns )
79+ err := k8s .DeleteNamespaceE (GinkgoT (), kubectl , ns )
80+ if err != nil {
81+ GinkgoT ().Logf ("Error deleting namespace %s: %v" , ns , err )
82+ continue
83+ }
84+
85+ // Wait for deletion to complete by checking until GetNamespaceE returns an error
86+ _ , err = retry .DoWithRetryE (
87+ GinkgoT (),
88+ fmt .Sprintf ("Waiting for namespace %s to be deleted" , ns ),
89+ 30 ,
90+ 5 * time .Second ,
91+ func () (string , error ) {
92+ _ , err := k8s .GetNamespaceE (GinkgoT (), kubectl , ns )
93+ if err != nil {
94+ // Namespace is gone, which is what we want
95+ return "Namespace deleted" , nil
96+ }
97+ return "" , fmt .Errorf ("namespace %s still exists" , ns )
98+ },
99+ )
100+
101+ if err != nil {
102+ GinkgoT ().Logf ("Error waiting for namespace %s to be deleted: %v" , ns , err )
103+ }
104+ } else {
105+ GinkgoT ().Logf ("Namespace %s does not exist or cannot be accessed" , ns )
106+ }
107+ }
108+
109+ namespace := "api7ee-conformance-test"
36110
37111 k8s .KubectlApplyFromString (GinkgoT (), kubectl , gatewayClass )
38112 defer k8s .KubectlDeleteFromString (GinkgoT (), kubectl , gatewayClass )
@@ -71,9 +145,94 @@ func TestMain(m *testing.M) {
71145 StatusAddress : address ,
72146 })
73147
148+ defaultGatewayProxyOpts = GatewayProxyOpts {
149+ StatusAddress : address ,
150+ AdminKey : adminKey ,
151+ AdminEndpoint : framework .DashboardTLSEndpoint ,
152+ }
153+
154+ patchGatewaysForConformanceTest (context .Background (), f .K8sClient )
155+
74156 code := m .Run ()
75157
76158 f .AfterSuite ()
77159
78160 os .Exit (code )
79161}
162+
163+ func patchGatewaysForConformanceTest (ctx context.Context , k8sClient client.Client ) {
164+ var gatewayProxyMap = make (map [string ]bool )
165+
166+ // list all gateways and patch them
167+ patchGateway := func (ctx context.Context , k8sClient client.Client ) bool {
168+ gatewayList := & gatewayv1.GatewayList {}
169+ if err := k8sClient .List (ctx , gatewayList ); err != nil {
170+ return false
171+ }
172+
173+ patched := false
174+ for i := range gatewayList .Items {
175+ gateway := & gatewayList .Items [i ]
176+ GinkgoT ().Logf ("Patching Gateway %s" , gateway .Name )
177+
178+ // check if the gateway already has infrastructure.parametersRef
179+ if gateway .Spec .Infrastructure != nil &&
180+ gateway .Spec .Infrastructure .ParametersRef != nil {
181+ continue
182+ }
183+
184+ // check if the gateway proxy has been created, if not, create it
185+ if ! gatewayProxyMap [gateway .Namespace ] {
186+ gatewayProxy := fmt .Sprintf (gatewayProxyYaml ,
187+ gateway .Namespace ,
188+ defaultGatewayProxyOpts .StatusAddress ,
189+ defaultGatewayProxyOpts .AdminEndpoint ,
190+ defaultGatewayProxyOpts .AdminKey )
191+ kubectl := k8s .NewKubectlOptions ("" , "" , gateway .Namespace )
192+ k8s .KubectlApplyFromString (GinkgoT (), kubectl , gatewayProxy )
193+
194+ // Mark this namespace as having a GatewayProxy
195+ gatewayProxyMap [gateway .Namespace ] = true
196+ }
197+
198+ // add infrastructure.parametersRef
199+ gateway .Spec .Infrastructure = & gatewayv1.GatewayInfrastructure {
200+ ParametersRef : & gatewayv1.LocalParametersReference {
201+ Group : "gateway.apisix.io" ,
202+ Kind : "GatewayProxy" ,
203+ Name : "conformance-gateway-proxy" ,
204+ },
205+ }
206+
207+ if err := k8sClient .Update (ctx , gateway ); err != nil {
208+ GinkgoT ().Logf ("Failed to patch Gateway %s: %v" , gateway .Name , err )
209+ continue
210+ }
211+
212+ patched = true
213+ GinkgoT ().Logf ("Successfully patched Gateway %s with GatewayProxy reference" , gateway .Name )
214+ }
215+
216+ return patched
217+ }
218+
219+ // continuously monitor and patch gateway resources
220+ go func () {
221+ ticker := time .NewTicker (5 * time .Second )
222+ defer ticker .Stop ()
223+
224+ for {
225+ select {
226+ case <- ctx .Done ():
227+ // clean up the gateway proxy
228+ for namespace := range gatewayProxyMap {
229+ kubectl := k8s .NewKubectlOptions ("" , "" , namespace )
230+ _ = k8s .RunKubectlE (GinkgoT (), kubectl , "delete" , "gatewayproxy" , "conformance-gateway-proxy" )
231+ }
232+ return
233+ case <- ticker .C :
234+ patchGateway (ctx , k8sClient )
235+ }
236+ }
237+ }()
238+ }
0 commit comments