Skip to content

Commit

Permalink
Fix some flaky tests related to pick port (v2ray#985)
Browse files Browse the repository at this point in the history
* Fix some tests to PickPort correctly

* Add retry logic for two socks tests

Two socks tests listen for both TCP and UDP with same port number, in some cases the port is not available
Add retry logic for server core, start server core and client core separately
Extract a common method

* Add retry logic for two dokodemo tests

Two dokodemo tests listen for 5 ports, in some cases they are not available
Add retry logic for client core, start server and client separately
  • Loading branch information
yuhan6665 committed Mar 12, 2022
1 parent c1a54ae commit 94c249a
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 158 deletions.
2 changes: 1 addition & 1 deletion core/xray_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestXrayClose(t *testing.T) {
Address: net.NewIPOrDomain(net.LocalHostIP),
Port: uint32(0),
NetworkList: &net.NetworkList{
Network: []net.Network{net.Network_TCP, net.Network_UDP},
Network: []net.Network{net.Network_TCP},
},
}),
},
Expand Down
18 changes: 18 additions & 0 deletions testing/scenarios/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"runtime"
"sync"
"syscall"
"testing"
"time"

"github.com/golang/protobuf/proto"
Expand Down Expand Up @@ -235,3 +236,20 @@ func testTCPConn2(conn net.Conn, payloadSize int, timeout time.Duration) func()
return nil
}
}

func WaitConnAvailableWithTest(t *testing.T, testFunc func() error) bool {
for i := 1; ; i++ {
if i > 10 {
t.Log("All attempts failed to test tcp conn")
return false
}
time.Sleep(time.Millisecond * 10)
if err := testFunc(); err != nil {
t.Log("err ", err)
} else {
t.Log("success with", i, "attempts")
break
}
}
return true
}
176 changes: 101 additions & 75 deletions testing/scenarios/dokodemo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,55 +64,68 @@ func TestDokodemoTCP(t *testing.T) {
},
},
}
server, err := InitializeServerConfig(serverConfig)
common.Must(err)
defer CloseServer(server)

clientPort := uint32(tcp.PickPort())
clientPortRange := uint32(5)
clientConfig := &core.Config{
App: []*serial.TypedMessage{
serial.ToTypedMessage(&log.Config{
ErrorLogLevel: clog.Severity_Debug,
ErrorLogType: log.LogType_Console,
}),
},
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortList: &net.PortList{Range: []*net.PortRange{{From: clientPort, To: clientPort + clientPortRange}}},
Listen: net.NewIPOrDomain(net.LocalHostIP),
}),
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
Address: net.NewIPOrDomain(dest.Address),
Port: uint32(dest.Port),
NetworkList: &net.NetworkList{
Network: []net.Network{net.Network_TCP},
},
retry := 1
clientPort := uint32(tcp.PickPort())
for {
clientConfig := &core.Config{
App: []*serial.TypedMessage{
serial.ToTypedMessage(&log.Config{
ErrorLogLevel: clog.Severity_Debug,
ErrorLogType: log.LogType_Console,
}),
},
},
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
{
Address: net.NewIPOrDomain(net.LocalHostIP),
Port: uint32(serverPort),
User: []*protocol.User{
{
Account: serial.ToTypedMessage(&vmess.Account{
Id: userID.String(),
}),
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortList: &net.PortList{Range: []*net.PortRange{{From: clientPort, To: clientPort + clientPortRange}}},
Listen: net.NewIPOrDomain(net.LocalHostIP),
}),
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
Address: net.NewIPOrDomain(dest.Address),
Port: uint32(dest.Port),
NetworkList: &net.NetworkList{
Network: []net.Network{net.Network_TCP},
},
}),
},
},
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
{
Address: net.NewIPOrDomain(net.LocalHostIP),
Port: uint32(serverPort),
User: []*protocol.User{
{
Account: serial.ToTypedMessage(&vmess.Account{
Id: userID.String(),
}),
},
},
},
},
},
}),
}),
},
},
},
}
}

servers, err := InitializeServerConfigs(serverConfig, clientConfig)
common.Must(err)
defer CloseAllServers(servers)
server, _ := InitializeServerConfig(clientConfig)
if server != nil && WaitConnAvailableWithTest(t, testTCPConn(net.Port(clientPort), 1024, time.Second*2)) {
defer CloseServer(server)
break
}
retry++
if retry > 5 {
t.Fatal("All attempts failed to start client")
}
clientPort = uint32(tcp.PickPort())
}

for port := clientPort; port <= clientPort+clientPortRange; port++ {
if err := testTCPConn(net.Port(port), 1024, time.Second*2)(); err != nil {
Expand Down Expand Up @@ -155,49 +168,62 @@ func TestDokodemoUDP(t *testing.T) {
},
},
}
server, err := InitializeServerConfig(serverConfig)
common.Must(err)
defer CloseServer(server)

clientPort := uint32(udp.PickPort())
clientPortRange := uint32(5)
clientConfig := &core.Config{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortList: &net.PortList{Range: []*net.PortRange{{From: clientPort, To: clientPort + clientPortRange}}},
Listen: net.NewIPOrDomain(net.LocalHostIP),
}),
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
Address: net.NewIPOrDomain(dest.Address),
Port: uint32(dest.Port),
NetworkList: &net.NetworkList{
Network: []net.Network{net.Network_UDP},
},
}),
retry := 1
clientPort := uint32(udp.PickPort())
for {
clientConfig := &core.Config{
Inbound: []*core.InboundHandlerConfig{
{
ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{
PortList: &net.PortList{Range: []*net.PortRange{{From: clientPort, To: clientPort + clientPortRange}}},
Listen: net.NewIPOrDomain(net.LocalHostIP),
}),
ProxySettings: serial.ToTypedMessage(&dokodemo.Config{
Address: net.NewIPOrDomain(dest.Address),
Port: uint32(dest.Port),
NetworkList: &net.NetworkList{
Network: []net.Network{net.Network_UDP},
},
}),
},
},
},
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
{
Address: net.NewIPOrDomain(net.LocalHostIP),
Port: uint32(serverPort),
User: []*protocol.User{
{
Account: serial.ToTypedMessage(&vmess.Account{
Id: userID.String(),
}),
Outbound: []*core.OutboundHandlerConfig{
{
ProxySettings: serial.ToTypedMessage(&outbound.Config{
Receiver: []*protocol.ServerEndpoint{
{
Address: net.NewIPOrDomain(net.LocalHostIP),
Port: uint32(serverPort),
User: []*protocol.User{
{
Account: serial.ToTypedMessage(&vmess.Account{
Id: userID.String(),
}),
},
},
},
},
},
}),
}),
},
},
},
}
}

servers, err := InitializeServerConfigs(serverConfig, clientConfig)
common.Must(err)
defer CloseAllServers(servers)
server, _ := InitializeServerConfig(clientConfig)
if server != nil && WaitConnAvailableWithTest(t, testUDPConn(net.Port(clientPort), 1024, time.Second*2)) {
defer CloseServer(server)
break
}
retry++
if retry > 5 {
t.Fatal("All attempts failed to start client")
}
clientPort = uint32(udp.PickPort())
}

var errg errgroup.Group
for port := clientPort; port <= clientPort+clientPortRange; port++ {
Expand Down
2 changes: 1 addition & 1 deletion testing/scenarios/feature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ func TestProxyOverKCP(t *testing.T) {
defer tcpServer.Close()

serverUserID := protocol.NewID(uuid.New())
serverPort := tcp.PickPort()
serverPort := udp.PickPort()
serverConfig := &core.Config{
Inbound: []*core.InboundHandlerConfig{
{
Expand Down
Loading

0 comments on commit 94c249a

Please sign in to comment.