Skip to content

Commit 79145a8

Browse files
committed
add test
1 parent 33bfc1a commit 79145a8

File tree

5 files changed

+258
-10
lines changed

5 files changed

+258
-10
lines changed

internal/adc/translator/apisixroute.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,9 @@ func (t *Translator) translateApisixRouteHTTPBackend(tctx *provider.TranslateCon
368368
return nil, err
369369
}
370370
upstream.Nodes = nodes
371-
upstream.Scheme = appProtocolToUpstreamScheme(protocol)
371+
if upstream.Scheme == "" {
372+
upstream.Scheme = appProtocolToUpstreamScheme(protocol)
373+
}
372374
if protocol == internaltypes.AppProtocolWS || protocol == internaltypes.AppProtocolWSS {
373375
*enableWebsocket = ptr.To(true)
374376
}

internal/adc/translator/ingress.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
discoveryv1 "k8s.io/api/discovery/v1"
2626
networkingv1 "k8s.io/api/networking/v1"
2727
"k8s.io/apimachinery/pkg/types"
28+
"k8s.io/utils/ptr"
2829

2930
adctypes "github.com/apache/apisix-ingress-controller/api/adc"
3031
"github.com/apache/apisix-ingress-controller/internal/controller/label"
@@ -111,6 +112,7 @@ func (t *Translator) TranslateIngress(tctx *provider.TranslateContext, obj *netw
111112
if path.Backend.Service == nil {
112113
continue
113114
}
115+
var enableWebsocket *bool
114116

115117
service := adctypes.NewDefaultService()
116118
service.Labels = labels
@@ -169,6 +171,15 @@ func (t *Translator) TranslateIngress(tctx *provider.TranslateContext, obj *netw
169171
break
170172
}
171173
}
174+
if getServicePort != nil && getServicePort.AppProtocol != nil {
175+
if upstream.Scheme == "" {
176+
upstream.Scheme = appProtocolToUpstreamScheme(*getServicePort.AppProtocol)
177+
}
178+
if *getServicePort.AppProtocol == internaltypes.AppProtocolWS ||
179+
*getServicePort.AppProtocol == internaltypes.AppProtocolWSS {
180+
enableWebsocket = ptr.To(true)
181+
}
182+
}
172183
endpointSlices := tctx.EndpointSlices[types.NamespacedName{
173184
Namespace: obj.Namespace,
174185
Name: backendService.Name,
@@ -185,6 +196,7 @@ func (t *Translator) TranslateIngress(tctx *provider.TranslateContext, obj *netw
185196
route := adctypes.NewDefaultRoute()
186197
route.Name = adctypes.ComposeRouteName(obj.Namespace, obj.Name, fmt.Sprintf("%d-%d", i, j))
187198
route.ID = id.GenID(route.Name)
199+
route.EnableWebsocket = enableWebsocket
188200
route.Labels = labels
189201

190202
uris := []string{path.Path}

test/e2e/framework/manifests/nginx.yaml

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,39 @@ data:
4242
location / {
4343
return 200 'Hello, World!';
4444
}
45+
46+
location /ws {
47+
content_by_lua_block {
48+
local server = require "resty.websocket.server"
49+
local wb, err = server:new {
50+
timeout = 5000, -- 5 seconds timeout
51+
max_payload_len = 65535 -- max message length
52+
}
53+
if not wb then
54+
ngx.log(ngx.ERR, "failed to create websocket: ", err)
55+
return ngx.exit(444)
56+
end
57+
58+
while true do
59+
local data, typ, err = wb:recv_frame()
60+
if wb.fatal then
61+
ngx.log(ngx.ERR, "failed to receive frame: ", err)
62+
break
63+
end
64+
65+
if typ == "close" then
66+
wb:send_close()
67+
break
68+
elseif typ == "text" then
69+
wb:send_text(data) -- echo text
70+
elseif typ == "binary" then
71+
wb:send_binary(data) -- echo binary
72+
elseif typ == "ping" then
73+
wb:send_pong()
74+
end
75+
end
76+
}
77+
}
4578
}
4679
}
4780
@@ -77,7 +110,7 @@ spec:
77110
path: /healthz
78111
port: 80
79112
timeoutSeconds: 2
80-
image: "nginx:1.21.4"
113+
image: "openresty/openresty:1.27.1.2-4-bullseye-fat"
81114
imagePullPolicy: IfNotPresent
82115
name: nginx
83116
ports:
@@ -88,7 +121,7 @@ spec:
88121
name: "https"
89122
protocol: "TCP"
90123
volumeMounts:
91-
- mountPath: /etc/nginx/nginx.conf
124+
- mountPath: /usr/local/openresty/nginx/conf/nginx.conf
92125
name: nginx-config
93126
subPath: nginx.conf
94127
- mountPath: /etc/nginx/ssl
@@ -111,6 +144,16 @@ spec:
111144
protocol: TCP
112145
targetPort: 443
113146
appProtocol: https
147+
- name: ws
148+
port: 8080
149+
protocol: TCP
150+
targetPort: 80
151+
appProtocol: kubernetes.io/ws
152+
- name: wss
153+
port: 8443
154+
protocol: TCP
155+
targetPort: 443
156+
appProtocol: kubernetes.io/wss
114157
type: ClusterIP
115158
---
116159
apiVersion: v1

test/e2e/gatewayapi/httproute.go

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,14 @@ package gatewayapi
1919

2020
import (
2121
"context"
22+
"crypto/tls"
2223
"fmt"
2324
"net/http"
25+
"net/url"
2426
"strings"
2527
"time"
2628

29+
"github.com/gorilla/websocket"
2730
. "github.com/onsi/ginkgo/v2"
2831
. "github.com/onsi/gomega"
2932
"github.com/pkg/errors"
@@ -2440,17 +2443,18 @@ spec:
24402443

24412444
})
24422445

2443-
Context("Test AppProtocol", func() {
2444-
var httproute = `
2446+
Context("Test Service With AppProtocol", func() {
2447+
var (
2448+
httproute = `
24452449
apiVersion: gateway.networking.k8s.io/v1
24462450
kind: HTTPRoute
24472451
metadata:
2448-
name: httpbin
2452+
name: nginx
24492453
spec:
24502454
parentRefs:
24512455
- name: %s
24522456
hostnames:
2453-
- httpbin.example
2457+
- api6.com
24542458
rules:
24552459
- matches:
24562460
- path:
@@ -2460,22 +2464,82 @@ spec:
24602464
- name: nginx
24612465
port: 443
24622466
`
2467+
httprouteWithWSS = `
2468+
apiVersion: gateway.networking.k8s.io/v1
2469+
kind: HTTPRoute
2470+
metadata:
2471+
name: nginx-wss
2472+
spec:
2473+
parentRefs:
2474+
- name: %s
2475+
hostnames:
2476+
- api6.com
2477+
rules:
2478+
- matches:
2479+
- path:
2480+
type: Exact
2481+
value: /ws
2482+
backendRefs:
2483+
- name: nginx
2484+
port: 8443
2485+
`
2486+
)
24632487

24642488
BeforeEach(func() {
2465-
beforeEachHTTP()
2489+
beforeEachHTTPS()
24662490
s.DeployNginx(framework.NginxOptions{
24672491
Namespace: s.Namespace(),
24682492
Replicas: ptr.To(int32(1)),
24692493
})
24702494
})
24712495
It("HTTPS backend", func() {
2472-
s.ResourceApplied("HTTPRoute", "httpbin", fmt.Sprintf(httproute, s.Namespace()), 1)
2496+
s.ResourceApplied("HTTPRoute", "nginx", fmt.Sprintf(httproute, s.Namespace()), 1)
24732497
s.RequestAssert(&scaffold.RequestAssert{
24742498
Method: "GET",
24752499
Path: "/get",
2476-
Host: "httpbin.example",
2500+
Host: "api6.com",
24772501
Check: scaffold.WithExpectedStatus(http.StatusOK),
24782502
})
24792503
})
2504+
2505+
It("WWS backend", func() {
2506+
s.ResourceApplied("HTTPRoute", "nginx-wss", fmt.Sprintf(httprouteWithWSS, s.Namespace()), 1)
2507+
time.Sleep(6 * time.Second)
2508+
2509+
By("verify wss connection")
2510+
u := url.URL{
2511+
Scheme: "wss",
2512+
Host: s.GetAPISIXHTTPSEndpoint(),
2513+
Path: "/ws",
2514+
}
2515+
headers := http.Header{"Host": []string{"api6.com"}}
2516+
2517+
hostname := "api6.com"
2518+
2519+
dialer := websocket.Dialer{
2520+
TLSClientConfig: &tls.Config{
2521+
InsecureSkipVerify: true,
2522+
ServerName: hostname,
2523+
},
2524+
}
2525+
2526+
conn, resp, err := dialer.Dial(u.String(), headers)
2527+
Expect(err).ShouldNot(HaveOccurred(), "WebSocket handshake")
2528+
Expect(resp.StatusCode).Should(Equal(http.StatusSwitchingProtocols))
2529+
2530+
defer func() {
2531+
_ = conn.Close()
2532+
}()
2533+
2534+
By("send and receive message through WebSocket")
2535+
testMessage := "hello, this is APISIX"
2536+
err = conn.WriteMessage(websocket.TextMessage, []byte(testMessage))
2537+
Expect(err).ShouldNot(HaveOccurred(), "writing WebSocket message")
2538+
2539+
// Then our echo
2540+
_, msg, err := conn.ReadMessage()
2541+
Expect(err).ShouldNot(HaveOccurred(), "reading echo message")
2542+
Expect(string(msg)).To(Equal(testMessage), "message content verification")
2543+
})
24802544
})
24812545
})

0 commit comments

Comments
 (0)