fix: avoid panic in inbound test

This commit is contained in:
wwqgtxx 2025-04-18 11:40:37 +08:00
parent 69ce4d0f8c
commit bad61f918f
9 changed files with 122 additions and 52 deletions

View file

@ -19,17 +19,23 @@ func testInboundAnyTLS(t *testing.T, inboundOptions inbound.AnyTLSOption, outbou
}
inboundOptions.Users = map[string]string{"test": userUUID}
in, err := inbound.NewAnyTLS(&inboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
tunnel := NewHttpTestTunnel()
defer tunnel.Close()
err = in.Listen(tunnel)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer in.Close()
addrPort, err := netip.ParseAddrPort(in.Address())
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
outboundOptions.Name = "anytls_outbound"
outboundOptions.Server = addrPort.Addr().String()
@ -37,7 +43,9 @@ func testInboundAnyTLS(t *testing.T, inboundOptions inbound.AnyTLSOption, outbou
outboundOptions.Password = userUUID
out, err := outbound.NewAnyTLS(outboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer out.Close()
tunnel.DoTest(t, out)

View file

@ -132,7 +132,9 @@ func NewHttpTestTunnel() *TestTunnel {
go http.Serve(ln, r)
testFn := func(t *testing.T, proxy C.ProxyAdapter, proto string) {
req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s://%s%s", proto, remoteAddr, httpPath), nil)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
req = req.WithContext(ctx)
var dstPort uint16 = 80
@ -145,7 +147,9 @@ func NewHttpTestTunnel() *TestTunnel {
DstPort: dstPort,
}
instance, err := proxy.DialContext(ctx, metadata)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer instance.Close()
transport := &http.Transport{
@ -174,14 +178,18 @@ func NewHttpTestTunnel() *TestTunnel {
defer client.CloseIdleConnections()
resp, err := client.Do(req)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
data, err := io.ReadAll(resp.Body)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
assert.Equal(t, httpData, data)
}
tunnel := &TestTunnel{
@ -212,27 +220,31 @@ func NewHttpTestTunnel() *TestTunnel {
CloseFn: ln.Close,
DoTestFn: func(t *testing.T, proxy C.ProxyAdapter) {
// Sequential testing for debugging
testFn(t, proxy, "http")
testFn(t, proxy, "https")
t.Run("Sequential", func(t *testing.T) {
testFn(t, proxy, "http")
testFn(t, proxy, "https")
})
// Concurrent testing to detect stress
wg := sync.WaitGroup{}
num := 50
for i := 0; i < num; i++ {
wg.Add(1)
go func() {
testFn(t, proxy, "https")
defer wg.Done()
}()
}
for i := 0; i < num; i++ {
wg.Add(1)
go func() {
testFn(t, proxy, "http")
defer wg.Done()
}()
}
wg.Wait()
t.Run("Concurrent", func(t *testing.T) {
wg := sync.WaitGroup{}
const num = 50
for i := 0; i < num; i++ {
wg.Add(1)
go func() {
testFn(t, proxy, "https")
defer wg.Done()
}()
}
for i := 0; i < num; i++ {
wg.Add(1)
go func() {
testFn(t, proxy, "http")
defer wg.Done()
}()
}
wg.Wait()
})
},
}
return tunnel

View file

@ -19,17 +19,23 @@ func testInboundHysteria2(t *testing.T, inboundOptions inbound.Hysteria2Option,
}
inboundOptions.Users = map[string]string{"test": userUUID}
in, err := inbound.NewHysteria2(&inboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
tunnel := NewHttpTestTunnel()
defer tunnel.Close()
err = in.Listen(tunnel)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer in.Close()
addrPort, err := netip.ParseAddrPort(in.Address())
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
outboundOptions.Name = "hysteria2_outbound"
outboundOptions.Server = addrPort.Addr().String()
@ -37,7 +43,9 @@ func testInboundHysteria2(t *testing.T, inboundOptions inbound.Hysteria2Option,
outboundOptions.Password = userUUID
out, err := outbound.NewHysteria2(outboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer out.Close()
tunnel.DoTest(t, out)

View file

@ -32,7 +32,9 @@ func testSingMux(t *testing.T, tunnel *TestTunnel, out outbound.ProxyAdapter) {
Protocol: protocol,
}
out, err := outbound.NewSingMux(singMuxOption, &notCloseProxyAdapter{out})
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer out.Close()
tunnel.DoTest(t, out)

View file

@ -57,17 +57,23 @@ func testInboundShadowSocks0(t *testing.T, inboundOptions inbound.ShadowSocksOpt
}
inboundOptions.Password = password
in, err := inbound.NewShadowSocks(&inboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
tunnel := NewHttpTestTunnel()
defer tunnel.Close()
err = in.Listen(tunnel)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer in.Close()
addrPort, err := netip.ParseAddrPort(in.Address())
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
outboundOptions.Name = "shadowsocks_outbound"
outboundOptions.Server = addrPort.Addr().String()
@ -75,7 +81,9 @@ func testInboundShadowSocks0(t *testing.T, inboundOptions inbound.ShadowSocksOpt
outboundOptions.Password = password
out, err := outbound.NewShadowSocks(outboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer out.Close()
tunnel.DoTest(t, out)

View file

@ -21,17 +21,23 @@ func testInboundTrojan(t *testing.T, inboundOptions inbound.TrojanOption, outbou
{Username: "test", Password: userUUID},
}
in, err := inbound.NewTrojan(&inboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
tunnel := NewHttpTestTunnel()
defer tunnel.Close()
err = in.Listen(tunnel)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer in.Close()
addrPort, err := netip.ParseAddrPort(in.Address())
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
outboundOptions.Name = "trojan_outbound"
outboundOptions.Server = addrPort.Addr().String()
@ -39,7 +45,9 @@ func testInboundTrojan(t *testing.T, inboundOptions inbound.TrojanOption, outbou
outboundOptions.Password = userUUID
out, err := outbound.NewTrojan(outboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer out.Close()
tunnel.DoTest(t, out)

View file

@ -48,24 +48,32 @@ func testInboundTuic0(t *testing.T, inboundOptions inbound.TuicOption, outboundO
Port: "0",
}
in, err := inbound.NewTuic(&inboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
tunnel := NewHttpTestTunnel()
defer tunnel.Close()
err = in.Listen(tunnel)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer in.Close()
addrPort, err := netip.ParseAddrPort(in.Address())
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
outboundOptions.Name = "tuic_outbound"
outboundOptions.Server = addrPort.Addr().String()
outboundOptions.Port = int(addrPort.Port())
out, err := outbound.NewTuic(outboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer out.Close()
tunnel.DoTest(t, out)

View file

@ -21,17 +21,23 @@ func testInboundVless(t *testing.T, inboundOptions inbound.VlessOption, outbound
{Username: "test", UUID: userUUID, Flow: "xtls-rprx-vision"},
}
in, err := inbound.NewVless(&inboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
tunnel := NewHttpTestTunnel()
defer tunnel.Close()
err = in.Listen(tunnel)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer in.Close()
addrPort, err := netip.ParseAddrPort(in.Address())
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
outboundOptions.Name = "vless_outbound"
outboundOptions.Server = addrPort.Addr().String()
@ -39,7 +45,9 @@ func testInboundVless(t *testing.T, inboundOptions inbound.VlessOption, outbound
outboundOptions.UUID = userUUID
out, err := outbound.NewVless(outboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer out.Close()
tunnel.DoTest(t, out)

View file

@ -21,17 +21,23 @@ func testInboundVMess(t *testing.T, inboundOptions inbound.VmessOption, outbound
{Username: "test", UUID: userUUID, AlterID: 0},
}
in, err := inbound.NewVmess(&inboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
tunnel := NewHttpTestTunnel()
defer tunnel.Close()
err = in.Listen(tunnel)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer in.Close()
addrPort, err := netip.ParseAddrPort(in.Address())
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
outboundOptions.Name = "vmess_outbound"
outboundOptions.Server = addrPort.Addr().String()
@ -41,7 +47,9 @@ func testInboundVMess(t *testing.T, inboundOptions inbound.VmessOption, outbound
outboundOptions.Cipher = "auto"
out, err := outbound.NewVmess(outboundOptions)
assert.NoError(t, err)
if !assert.NoError(t, err) {
return
}
defer out.Close()
tunnel.DoTest(t, out)