@@ -5,27 +5,22 @@ package placeholder_pages
55
66import  (
77	"fmt" 
8- 	"net/http" 
9- 	"strings" 
108	"testing" 
11- 	"time" 
129
13- 	"github.com/stretchr/testify/assert " 
10+ 	.  "github.com/kedacore/http-add-on/tests/helper " 
1411)
1512
1613const  (
17- 	testName         =  "placeholder-pages-test" 
18- 	testServiceName  =  testName 
19- 	testNamespace    =  testName  +  "-ns" 
14+ 	testName       =  "placeholder-test" 
15+ 	testNamespace  =  testName  +  "-ns" 
2016)
2117
22- type  placeholderTemplateData  struct  {
23- 	TestNamespace    string 
24- 	TestName         string 
25- 	TestServiceName  string 
18+ type  templateData  struct  {
19+ 	TestNamespace  string 
20+ 	TestName       string 
2621}
2722
28- const  placeholderTemplate  =  ` 
23+ const  testTemplate  =  ` 
2924apiVersion: v1 
3025kind: Namespace 
3126metadata: 
@@ -36,8 +31,6 @@ kind: Deployment
3631metadata: 
3732  name: {{.TestName}} 
3833  namespace: {{.TestNamespace}} 
39-   labels: 
40-     app: {{.TestName}} 
4134spec: 
4235  replicas: 1 
4336  selector: 
@@ -49,34 +42,23 @@ spec:
4942        app: {{.TestName}} 
5043    spec: 
5144      containers: 
52- 	  - name: {{.TestName}} 
53- 	    image: registry.k8s.io/e2e-test-images/agnhost:2.45 
54- 	    args: 
55- 	    - netexec 
56- 	    ports: 
57- 	    - name: http 
58- 		  containerPort: 8080 
59- 		  protocol: TCP 
60- 	    readinessProbe: 
61- 		  httpGet: 
62- 		    path: / 
63- 		    port: http 
45+       - name: {{.TestName}} 
46+         image: registry.k8s.io/e2e-test-images/agnhost:2.45 
47+         args: ["netexec"] 
48+         ports: 
49+         - containerPort: 8080 
6450--- 
6551apiVersion: v1 
6652kind: Service 
6753metadata: 
68-   name: {{.TestServiceName }} 
54+   name: {{.TestName }} 
6955  namespace: {{.TestNamespace}} 
70-   labels: 
71-     app: {{.TestName}} 
7256spec: 
7357  ports: 
7458  - port: 80 
7559    targetPort: 8080 
76-     name: http 
7760  selector: 
7861    app: {{.TestName}} 
79-   type: ClusterIP 
8062--- 
8163apiVersion: http.keda.sh/v1alpha1 
8264kind: HTTPScaledObject 
@@ -85,138 +67,71 @@ metadata:
8567  namespace: {{.TestNamespace}} 
8668spec: 
8769  hosts: 
88-   - {{.TestName}} 
89-   pathPrefixes: 
90-   - / 
70+   - {{.TestName}}.test 
9171  scaleTargetRef: 
92-     service: {{.TestServiceName}} 
93-     port: 80 
9472    deployment: {{.TestName}} 
95-   targetPendingRequests: 1 
96-   scaledownPeriod: 60 
73+     service: {{.TestName}} 
74+     port: 80 
75+   replicas: 
76+     min: 0 
77+     max: 10 
9778  placeholderConfig: 
9879    enabled: true 
9980    statusCode: 503 
10081    refreshInterval: 5 
10182    headers: 
102-       X-Service-Status : "warming-up " 
83+       X-Test-Header : "test-value " 
10384` 
10485
10586func  TestPlaceholderPages (t  * testing.T ) {
106- 	// Create test data 
107- 	data  :=  placeholderTemplateData {
108- 		TestNamespace :   testNamespace ,
109- 		TestName :        testName ,
110- 		TestServiceName : testServiceName ,
87+ 	// Setup 
88+ 	data  :=  templateData {
89+ 		TestNamespace : testNamespace ,
90+ 		TestName :      testName ,
11191	}
11292
113- 	// Apply the resources 
114- 	KubectlApplyWithTemplate (t , data , "placeholder-test" , placeholderTemplate )
115- 
116- 	// Ensure cleanup 
93+ 	KubectlApplyWithTemplate (t , data , "placeholder-test" , testTemplate )
11794	defer  func () {
118- 		KubectlDeleteWithTemplate (t , data , "placeholder-test" , placeholderTemplate )
95+ 		KubectlDeleteWithTemplate (t , data , "placeholder-test" , testTemplate )
11996		DeleteNamespace (t , testNamespace )
12097	}()
12198
122- 	// Wait for the deployment to exist with 0 replicas 
123- 	assert .True (t , WaitForDeploymentReplicaReadyCount (t , KubeClient , testName , testNamespace , 0 , 60 , 3 ),
124- 		"deployment should exist with 0 replicas within 1 minute" )
125- 
126- 	// Make a request and verify placeholder is served 
127- 	testPlaceholderResponse (t )
128- 
129- 	// Test that placeholder is served immediately on cold start 
130- 	testImmediatePlaceholderResponse (t )
131- }
132- 
133- func  testPlaceholderResponse (t  * testing.T ) {
134- 	t .Log ("Testing placeholder page response" )
135- 
136- 	interceptorService  :=  GetKubernetesServiceEndpoint (
137- 		t ,
138- 		KubeClient ,
139- 		"keda-http-add-on-interceptor-proxy" ,
140- 		"keda" ,
141- 	)
142- 	interceptorIP  :=  interceptorService .IP 
143- 
144- 	url  :=  fmt .Sprintf ("http://%s" , interceptorIP )
145- 	req , err  :=  http .NewRequest ("GET" , url , nil )
146- 	assert .NoError (t , err )
147- 	req .Host  =  testName 
148- 
149- 	client  :=  & http.Client {
150- 		Timeout : 10  *  time .Second ,
151- 		CheckRedirect : func (req  * http.Request , via  []* http.Request ) error  {
152- 			return  http .ErrUseLastResponse 
153- 		},
154- 	}
155- 
156- 	resp , err  :=  client .Do (req )
157- 	assert .NoError (t , err )
158- 	defer  resp .Body .Close ()
159- 
160- 	// Check that we got a 503 status (default for placeholder) 
161- 	assert .Equal (t , http .StatusServiceUnavailable , resp .StatusCode )
99+ 	// Wait for deployment to scale to 0 
100+ 	assert .True (t ,
101+ 		WaitForDeploymentReplicaReadyCount (t , GetKubernetesClient (t ), testName , testNamespace , 0 , 60 , 3 ),
102+ 		"deployment should scale to 0" )
162103
163- 	// Read response body 
164- 	body  :=  make ([]byte , 1024 )
165- 	n , _  :=  resp .Body .Read (body )
166- 	bodyStr  :=  string (body [:n ])
104+ 	// Make a request through a pod and check placeholder response 
105+ 	curlCmd  :=  fmt .Sprintf ("curl -i -H 'Host: %s.test' http://keda-add-ons-http-interceptor-proxy.keda:8080/" , testName )
167106
168- 	// Verify placeholder content 
169- 	assert .True (t , strings .Contains (bodyStr , testServiceName + " is starting up..." ),
170- 		"response should contain placeholder message" )
171- 	assert .True (t , strings .Contains (bodyStr , "refresh" ),
172- 		"response should contain refresh meta tag" )
173- 
174- 	// Check custom headers 
175- 	assert .Equal (t , "true" , resp .Header .Get ("X-KEDA-HTTP-Placeholder-Served" ),
176- 		"placeholder served header should be present" )
177- 	assert .Equal (t , "warming-up" , resp .Header .Get ("X-Service-Status" ),
178- 		"custom header should be present" )
179- }
180- 
181- func  testImmediatePlaceholderResponse (t  * testing.T ) {
182- 	t .Log ("Testing immediate placeholder page response on cold start" )
183- 
184- 	interceptorService  :=  GetKubernetesServiceEndpoint (
185- 		t ,
186- 		KubeClient ,
187- 		"keda-http-add-on-interceptor-proxy" ,
188- 		"keda" ,
189- 	)
190- 	interceptorIP  :=  interceptorService .IP 
191- 
192- 	url  :=  fmt .Sprintf ("http://%s" , interceptorIP )
193- 	req , err  :=  http .NewRequest ("GET" , url , nil )
194- 	assert .NoError (t , err )
195- 	req .Host  =  testName 
196- 
197- 	client  :=  & http.Client {
198- 		Timeout : 2  *  time .Second , // Short timeout to ensure immediate response 
199- 		CheckRedirect : func (req  * http.Request , via  []* http.Request ) error  {
200- 			return  http .ErrUseLastResponse 
201- 		},
202- 	}
203- 
204- 	// Measure response time 
205- 	start  :=  time .Now ()
206- 	resp , err  :=  client .Do (req )
207- 	duration  :=  time .Since (start )
208- 
209- 	assert .NoError (t , err )
210- 	defer  resp .Body .Close ()
211- 
212- 	// Check that response was immediate (less than 500ms) 
213- 	assert .Less (t , duration .Milliseconds (), int64 (500 ),
214- 		"placeholder should be served immediately, but took %v" , duration )
215- 
216- 	// Check that we got a 503 status 
217- 	assert .Equal (t , http .StatusServiceUnavailable , resp .StatusCode )
218- 
219- 	// Check placeholder header 
220- 	assert .Equal (t , "true" , resp .Header .Get ("X-KEDA-HTTP-Placeholder-Served" ),
221- 		"placeholder served header should be present" )
107+ 	// Create and run a curl pod 
108+ 	curlPod  :=  fmt .Sprintf (` 
109+ apiVersion: v1 
110+ kind: Pod 
111+ metadata: 
112+   name: curl-test 
113+   namespace: %s 
114+ spec: 
115+   containers: 
116+   - name: curl 
117+     image: curlimages/curl 
118+     command: ["sh", "-c", "%s && sleep 5"] 
119+   restartPolicy: Never 
120+ ` , testNamespace , curlCmd )
121+ 
122+ 	KubectlApplyWithTemplate (t , data , "curl-pod" , curlPod )
123+ 	defer  KubectlDeleteWithTemplate (t , data , "curl-pod" , curlPod )
124+ 
125+ 	// Wait and get logs 
126+ 	assert .True (t ,
127+ 		WaitForSuccessfulExecCommandOnSpecificPod (t , "curl-test" , testNamespace , "echo done" , 60 , 3 ),
128+ 		"curl should complete" )
129+ 
130+ 	logs , _  :=  KubectlLogs (t , "curl-test" , testNamespace , "" )
131+ 
132+ 	// Verify placeholder response 
133+ 	assert .Contains (t , logs , "HTTP/1.1 503" , "should return 503 status" )
134+ 	assert .Contains (t , logs , "X-KEDA-HTTP-Placeholder-Served: true" , "should have placeholder header" )
135+ 	assert .Contains (t , logs , "X-Test-Header: test-value" , "should have custom header" )
136+ 	assert .Contains (t , logs , "is starting up" , "should have placeholder message" )
222137}
0 commit comments