From 1cba3d08509720f18ffb6dc1ef898abb7b1542cc Mon Sep 17 00:00:00 2001 From: yuhan6665 <1588741+yuhan6665@users.noreply.github.com> Date: Thu, 23 Sep 2021 23:59:00 -0400 Subject: [PATCH] Fix flaky TestVMessDynamicPort (#723) --- testing/scenarios/common.go | 17 ++++ testing/scenarios/vmess_test.go | 145 +++++++++++++++++++++----------- 2 files changed, 111 insertions(+), 51 deletions(-) diff --git a/testing/scenarios/common.go b/testing/scenarios/common.go index 66bf9e37fab..9f3d1711364 100644 --- a/testing/scenarios/common.go +++ b/testing/scenarios/common.go @@ -143,6 +143,23 @@ func CloseAllServers(servers []*exec.Cmd) { }) } +func CloseServer(server *exec.Cmd) { + log.Record(&log.GeneralMessage{ + Severity: log.Severity_Info, + Content: "Closing server.", + }) + if runtime.GOOS == "windows" { + server.Process.Kill() + } else { + server.Process.Signal(syscall.SIGTERM) + } + server.Process.Wait() + log.Record(&log.GeneralMessage{ + Severity: log.Severity_Info, + Content: "Server closed.", + }) +} + func withDefaultApps(config *core.Config) *core.Config { config.App = append(config.App, serial.ToTypedMessage(&dispatcher.Config{})) config.App = append(config.App, serial.ToTypedMessage(&proxyman.InboundConfig{})) diff --git a/testing/scenarios/vmess_test.go b/testing/scenarios/vmess_test.go index 96db0940693..137bb8f15b0 100644 --- a/testing/scenarios/vmess_test.go +++ b/testing/scenarios/vmess_test.go @@ -36,59 +36,87 @@ func TestVMessDynamicPort(t *testing.T) { defer tcpServer.Close() userID := protocol.NewID(uuid.New()) + + retry := 1 serverPort := tcp.PickPort() - serverConfig := &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{ - PortRange: net.SinglePortRange(serverPort), - Listen: net.NewIPOrDomain(net.LocalHostIP), - }), - ProxySettings: serial.ToTypedMessage(&inbound.Config{ - User: []*protocol.User{ - { - Account: serial.ToTypedMessage(&vmess.Account{ - Id: userID.String(), - }), - }, - }, - Detour: &inbound.DetourConfig{ - To: "detour", - }, + for { + serverConfig := &core.Config{ + App: []*serial.TypedMessage{ + serial.ToTypedMessage(&log.Config{ + ErrorLogLevel: clog.Severity_Debug, + ErrorLogType: log.LogType_Console, }), }, - { - ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ - PortRange: &net.PortRange{ - From: uint32(serverPort + 1), - To: uint32(serverPort + 100), - }, - Listen: net.NewIPOrDomain(net.LocalHostIP), - AllocationStrategy: &proxyman.AllocationStrategy{ - Type: proxyman.AllocationStrategy_Random, - Concurrency: &proxyman.AllocationStrategy_AllocationStrategyConcurrency{ - Value: 2, + Inbound: []*core.InboundHandlerConfig{ + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort), + Listen: net.NewIPOrDomain(net.LocalHostIP), + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{ + User: []*protocol.User{ + { + Account: serial.ToTypedMessage(&vmess.Account{ + Id: userID.String(), + }), + }, }, - Refresh: &proxyman.AllocationStrategy_AllocationStrategyRefresh{ - Value: 5, + Detour: &inbound.DetourConfig{ + To: "detour", }, - }, - }), - ProxySettings: serial.ToTypedMessage(&inbound.Config{}), - Tag: "detour", + }), + }, + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: net.SinglePortRange(serverPort + 100), + 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}, + }, + }), + }, + { + ReceiverSettings: serial.ToTypedMessage(&proxyman.ReceiverConfig{ + PortRange: &net.PortRange{ + From: uint32(serverPort + 1), + To: uint32(serverPort + 99), + }, + Listen: net.NewIPOrDomain(net.LocalHostIP), + AllocationStrategy: &proxyman.AllocationStrategy{ + Type: proxyman.AllocationStrategy_Random, + Concurrency: &proxyman.AllocationStrategy_AllocationStrategyConcurrency{ + Value: 2, + }, + Refresh: &proxyman.AllocationStrategy_AllocationStrategyRefresh{ + Value: 5, + }, + }, + }), + ProxySettings: serial.ToTypedMessage(&inbound.Config{}), + Tag: "detour", + }, }, - }, - Outbound: []*core.OutboundHandlerConfig{ - { - ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + Outbound: []*core.OutboundHandlerConfig{ + { + ProxySettings: serial.ToTypedMessage(&freedom.Config{}), + }, }, - }, + } + + server, _ := InitializeServerConfig(serverConfig) + if server != nil && tcpConnAvailableAtPort(t, serverPort+100) { + defer CloseServer(server) + break + } + retry++ + if retry > 5 { + t.Fatal("All attempts failed to start server") + } + serverPort = tcp.PickPort() } clientPort := tcp.PickPort() @@ -135,15 +163,30 @@ func TestVMessDynamicPort(t *testing.T) { }, } - servers, err := InitializeServerConfigs(serverConfig, clientConfig) + server, err := InitializeServerConfig(clientConfig) common.Must(err) - defer CloseAllServers(servers) + defer CloseServer(server) - for i := 0; i < 10; i++ { - if err := testTCPConn(clientPort, 1024, time.Second*2)(); err != nil { - t.Error(err) + if !tcpConnAvailableAtPort(t, clientPort) { + t.Fail() + } +} + +func tcpConnAvailableAtPort(t *testing.T, port net.Port) 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 := testTCPConn(port, 1024, time.Second*2)(); err != nil { + t.Log("err ", err) + } else { + t.Log("success with", i, "attempts") + break } } + return true } func TestVMessGCM(t *testing.T) {