proxy_test.go
1 // Copyright 2025 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package proxy 16 17 import ( 18 "context" 19 "net" 20 "net/http" 21 "net/http/httptest" 22 "testing" 23 24 "github.com/alibaba/opensandbox/ingress/pkg/sandbox" 25 "github.com/stretchr/testify/assert" 26 ) 27 28 // stubNoSecureProvider is a minimal sandbox.Provider for unit tests (no access-token / secure routing). 29 type stubNoSecureProvider struct{} 30 31 func (stubNoSecureProvider) GetEndpoint(string) (*sandbox.EndpointInfo, error) { 32 return &sandbox.EndpointInfo{Endpoint: "127.0.0.1"}, nil 33 } 34 35 func (stubNoSecureProvider) Start(context.Context) error { return nil } 36 37 // Test_WatchPods is removed as we now use BatchSandbox Provider instead of direct Pod watching 38 39 func TestIsWebSocketRequest(t *testing.T) { 40 proxy := &Proxy{} 41 42 // Valid websocket request 43 req := httptest.NewRequest(http.MethodGet, "/ws", nil) 44 req.Header.Set("Upgrade", "websocket") 45 req.Header.Set("Connection", "Upgrade") 46 assert.True(t, proxy.isWebSocketRequest(req)) 47 48 // Missing upgrade headers 49 req = httptest.NewRequest(http.MethodGet, "/ws", nil) 50 assert.False(t, proxy.isWebSocketRequest(req)) 51 52 // Wrong method 53 req = httptest.NewRequest(http.MethodPost, "/ws", nil) 54 req.Header.Set("Upgrade", "websocket") 55 req.Header.Set("Connection", "Upgrade") 56 assert.False(t, proxy.isWebSocketRequest(req)) 57 } 58 59 func TestParseHostRoute(t *testing.T) { 60 pr, err := parseHostRoute("sandbox-1234.example.com") 61 assert.NoError(t, err) 62 assert.Equal(t, "sandbox", pr.sandboxID) 63 assert.Equal(t, 1234, pr.port) 64 65 pr, err = parseHostRoute("https://alpha-beta-8080.sandbox.test") 66 assert.NoError(t, err) 67 assert.Equal(t, "alpha-beta", pr.sandboxID) 68 assert.Equal(t, 8080, pr.port) 69 70 _, err = parseHostRoute("invalidhost") 71 assert.Error(t, err) 72 73 _, err = parseHostRoute("-1234.example.com") 74 assert.Error(t, err) 75 } 76 77 func TestGetClientIP(t *testing.T) { 78 proxy := &Proxy{} 79 80 req := httptest.NewRequest(http.MethodGet, "/", nil) 81 req.RemoteAddr = "192.0.2.1:12345" 82 assert.Equal(t, "192.0.2.1", proxy.getClientIP(req)) 83 84 req = httptest.NewRequest(http.MethodGet, "/", nil) 85 req.RemoteAddr = "192.0.2.1:12345" 86 req.Header.Set(XRealIP, "203.0.113.5") 87 assert.Equal(t, "203.0.113.5", proxy.getClientIP(req)) 88 89 req = httptest.NewRequest(http.MethodGet, "/", nil) 90 req.RemoteAddr = "192.0.2.1:12345" 91 req.Header.Set(XForwardedFor, "10.0.0.1, 198.51.100.2") 92 assert.Equal(t, "10.0.0.1", proxy.getClientIP(req)) 93 } 94 95 func findAvailablePort() (int, error) { 96 listener, err := net.Listen("tcp", "127.0.0.1:0") 97 if err != nil { 98 return 0, err 99 } 100 defer listener.Close() 101 102 port := listener.Addr().(*net.TCPAddr).Port 103 return port, nil 104 }