remove test file
fatheradvisor committed
Nov 3, 2025 at 21:24 UTC
b2eda8136a3b15be9164436c2712fa0b856a758d
1 file changed
-315
cmd/portal-tunnel/tunnel_test.go
deleted
-315
@@ -1,315 +0,0 @@
1
-package main
2
-
3
-import (
4
- "context"
5
- "fmt"
6
- "io"
7
- "net"
8
- "net/http"
9
- "strings"
10
- "testing"
11
- "time"
12
-
13
- "github.com/stretchr/testify/assert"
14
- "github.com/stretchr/testify/require"
15
- "gosuda.org/portal/sdk"
16
-)
17
-
18
-// TestTunnelEndToEnd tests the complete tunnel functionality
19
-func TestTunnelEndToEnd(t *testing.T) {
20
- // Start a local HTTP server
21
- localPort := findFreePort(t)
22
- localAddr := fmt.Sprintf("localhost:%d", localPort)
23
-
24
- localServer := &http.Server{
25
- Addr: localAddr,
26
- Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
27
- w.WriteHeader(http.StatusOK)
28
- w.Write([]byte("Hello from local server!"))
29
- }),
30
- }
31
-
32
- go func() {
33
- localServer.ListenAndServe()
34
- }()
35
- defer localServer.Close()
36
-
37
- // Wait for local server to start
38
- time.Sleep(100 * time.Millisecond)
39
-
40
- // Verify local server is reachable
41
- resp, err := http.Get(fmt.Sprintf("http://%s", localAddr))
42
- require.NoError(t, err)
43
- require.Equal(t, http.StatusOK, resp.StatusCode)
44
- resp.Body.Close()
45
-
46
- t.Logf("✓ Local server started on %s", localAddr)
47
-
48
- // Create relay server (mock or use actual relay server)
49
- // For this test, we'll assume a relay server is running on localhost:4017
50
- relayURL := "ws://localhost:4017/relay"
51
-
52
- // Create credential for tunnel
53
- cred := sdk.NewCredential()
54
- leaseID := cred.ID()
55
- serviceName := fmt.Sprintf("test-tunnel-%d", time.Now().Unix())
56
-
57
- t.Logf("Creating tunnel with:")
58
- t.Logf(" Service name: %s", serviceName)
59
- t.Logf(" Lease ID: %s", leaseID)
60
-
61
- // Create SDK client
62
- client, err := sdk.NewClient(func(c *sdk.RDClientConfig) {
63
- c.BootstrapServers = []string{relayURL}
64
- })
65
- if err != nil {
66
- t.Skipf("Relay server not available: %v", err)
67
- return
68
- }
69
- defer client.Close()
70
-
71
- // Register listener (server side of tunnel)
72
- listener, err := client.Listen(cred, serviceName, []string{"http/1.1"})
73
- require.NoError(t, err)
74
- defer listener.Close()
75
-
76
- t.Logf("✓ Tunnel registered successfully")
77
-
78
- // Start proxy goroutine (simulate portal-tunnel behavior)
79
- ctx, cancel := context.WithCancel(context.Background())
80
- defer cancel()
81
-
82
- proxyErrors := make(chan error, 10)
83
- go func() {
84
- for {
85
- select {
86
- case <-ctx.Done():
87
- return
88
- default:
89
- }
90
-
91
- relayConn, err := listener.Accept()
92
- if err != nil {
93
- select {
94
- case <-ctx.Done():
95
- return
96
- default:
97
- proxyErrors <- fmt.Errorf("accept error: %w", err)
98
- continue
99
- }
100
- }
101
-
102
- // Proxy connection to local server
103
- go func(relayConn net.Conn) {
104
- defer relayConn.Close()
105
-
106
- localConn, err := net.Dial("tcp", localAddr)
107
- if err != nil {
108
- proxyErrors <- fmt.Errorf("local dial error: %w", err)
109
- return
110
- }
111
- defer localConn.Close()
112
-
113
- // Bidirectional copy
114
- errCh := make(chan error, 2)
115
- go func() {
116
- _, err := io.Copy(localConn, relayConn)
117
- errCh <- err
118
- }()
119
- go func() {
120
- _, err := io.Copy(relayConn, localConn)
121
- errCh <- err
122
- }()
123
-
124
- <-errCh
125
- localConn.Close()
126
- relayConn.Close()
127
- <-errCh
128
- }(relayConn)
129
- }
130
- }()
131
-
132
- // Wait for tunnel to be ready
133
- time.Sleep(500 * time.Millisecond)
134
-
135
- t.Logf("✓ Tunnel proxy started")
136
-
137
- // Create a client that will connect through the tunnel
138
- clientCred := sdk.NewCredential()
139
- clientSDK, err := sdk.NewClient(func(c *sdk.RDClientConfig) {
140
- c.BootstrapServers = []string{relayURL}
141
- })
142
- require.NoError(t, err)
143
- defer clientSDK.Close()
144
-
145
- // Connect through the tunnel
146
- tunnelConn, err := clientSDK.Dial(clientCred, leaseID, "http/1.1")
147
- require.NoError(t, err)
148
- defer tunnelConn.Close()
149
-
150
- t.Logf("✓ Connected through tunnel")
151
-
152
- // Send HTTP request through tunnel
153
- req := "GET / HTTP/1.1\r\nHost: test\r\nConnection: close\r\n\r\n"
154
- _, err = tunnelConn.Write([]byte(req))
155
- require.NoError(t, err)
156
-
157
- // Read response
158
- response := make([]byte, 4096)
159
- n, err := tunnelConn.Read(response)
160
- require.NoError(t, err)
161
-
162
- responseStr := string(response[:n])
163
- t.Logf("Received response (%d bytes):\n%s", n, responseStr)
164
-
165
- // Verify response
166
- assert.Contains(t, responseStr, "HTTP/1.1 200 OK")
167
- assert.Contains(t, responseStr, "Hello from local server!")
168
-
169
- t.Logf("✓ Tunnel test completed successfully!")
170
-
171
- // Check for proxy errors
172
- select {
173
- case err := <-proxyErrors:
174
- t.Logf("Proxy error (non-fatal): %v", err)
175
- default:
176
- // No errors
177
- }
178
-}
179
-
180
-// TestProxyConnection tests the proxy connection logic
181
-func TestProxyConnection(t *testing.T) {
182
- // Create a mock local server
183
- localPort := findFreePort(t)
184
- localAddr := fmt.Sprintf("localhost:%d", localPort)
185
-
186
- localListener, err := net.Listen("tcp", localAddr)
187
- require.NoError(t, err)
188
- defer localListener.Close()
189
-
190
- // Local server that echoes back
191
- go func() {
192
- for {
193
- conn, err := localListener.Accept()
194
- if err != nil {
195
- return
196
- }
197
- go func(c net.Conn) {
198
- defer c.Close()
199
- io.Copy(c, c) // Echo back
200
- }(conn)
201
- }
202
- }()
203
-
204
- // Create mock relay connection (using pipes)
205
- relayConn, clientConn := net.Pipe()
206
- defer relayConn.Close()
207
- defer clientConn.Close()
208
-
209
- // Start proxy
210
- go func() {
211
- err := proxyConnection(relayConn, localAddr, 1)
212
- if err != nil && !strings.Contains(err.Error(), "closed") {
213
- t.Logf("Proxy error: %v", err)
214
- }
215
- }()
216
-
217
- // Send data through client side
218
- testData := "Hello, tunnel!"
219
- _, err = clientConn.Write([]byte(testData))
220
- require.NoError(t, err)
221
-
222
- // Read echoed data
223
- buf := make([]byte, len(testData))
224
- n, err := clientConn.Read(buf)
225
- require.NoError(t, err)
226
- assert.Equal(t, testData, string(buf[:n]))
227
-
228
- t.Logf("✓ Proxy connection test passed")
229
-}
230
-
231
-// TestLocalServiceConnectivity tests the local service connectivity check
232
-func TestLocalServiceConnectivity(t *testing.T) {
233
- // Start a local server
234
- localPort := findFreePort(t)
235
- localAddr := fmt.Sprintf("localhost:%d", localPort)
236
-
237
- listener, err := net.Listen("tcp", localAddr)
238
- require.NoError(t, err)
239
- defer listener.Close()
240
-
241
- go func() {
242
- for {
243
- conn, err := listener.Accept()
244
- if err != nil {
245
- return
246
- }
247
- conn.Close()
248
- }
249
- }()
250
-
251
- // Test connectivity (simulating the check in runExpose)
252
- testConn, err := net.Dial("tcp", localAddr)
253
- require.NoError(t, err)
254
- testConn.Close()
255
-
256
- t.Logf("✓ Local service connectivity test passed")
257
-}
258
-
259
-// TestLocalServiceNotReachable tests error handling when local service is not available
260
-func TestLocalServiceNotReachable(t *testing.T) {
261
- // Try to connect to a port that's not listening
262
- localAddr := "localhost:19999"
263
-
264
- _, err := net.Dial("tcp", localAddr)
265
- assert.Error(t, err)
266
- assert.Contains(t, err.Error(), "connection refused")
267
-
268
- t.Logf("✓ Error handling test passed")
269
-}
270
-
271
-// TestPadRight tests the padding utility function
272
-func TestPadRight(t *testing.T) {
273
- tests := []struct {
274
- input string
275
- length int
276
- expected int
277
- }{
278
- {"test", 10, 10},
279
- {"hello", 5, 5},
280
- {"toolong", 3, 7}, // Should not truncate
281
- }
282
-
283
- for _, tt := range tests {
284
- result := padRight(tt.input, tt.length)
285
- assert.Equal(t, tt.expected, len(result))
286
- assert.True(t, strings.HasPrefix(result, tt.input))
287
- }
288
-}
289
-
290
-// TestExtractHost tests the host extraction from WebSocket URL
291
-func TestExtractHost(t *testing.T) {
292
- tests := []struct {
293
- input string
294
- expected string
295
- }{
296
- {"ws://localhost:4017/relay", "localhost:4017"},
297
- {"wss://example.com:443/path", "example.com:443"},
298
- {"ws://192.168.1.1:8080/test", "192.168.1.1:8080"},
299
- {"ws://example.com/", "example.com"},
300
- }
301
-
302
- for _, tt := range tests {
303
- result := extractHost(tt.input)
304
- assert.Equal(t, tt.expected, result, "Failed for input: %s", tt.input)
305
- }
306
-}
307
-
308
-// Helper function to find a free port for testing
309
-func findFreePort(t *testing.T) int {
310
- listener, err := net.Listen("tcp", "localhost:0")
311
- require.NoError(t, err)
312
- port := listener.Addr().(*net.TCPAddr).Port
313
- listener.Close()
314
- return port
315
-}