From 178e654abbdf5ed79eda840cd0a775b52ab69669 Mon Sep 17 00:00:00 2001 From: Facundo Medica <14063057+facundomedica@users.noreply.github.com> Date: Mon, 6 Feb 2023 10:29:18 -0300 Subject: [PATCH] test: use a queue of open ports for tests (#14893) Co-authored-by: Marko (cherry picked from commit 5e57be076e6338829a7ec89ea182a77c8ba2dc77) # Conflicts: # testutil/network/network.go # testutil/network/util.go # x/genutil/client/cli/init_test.go --- testutil/network/network.go | 63 +++++++++++++++++++++++++++++-- testutil/network/util.go | 31 +++++++++++++++ x/genutil/client/cli/init_test.go | 5 +++ 3 files changed, 95 insertions(+), 4 deletions(-) diff --git a/testutil/network/network.go b/testutil/network/network.go index c063dfb17647..6112917202a5 100644 --- a/testutil/network/network.go +++ b/testutil/network/network.go @@ -58,7 +58,30 @@ import ( ) // package-wide network lock to only allow one test network at a time -var lock = new(sync.Mutex) +var ( + lock = new(sync.Mutex) + portPool = make(chan string, 200) +) + +func init() { + closeFns := []func() error{} + for i := 0; i < 200; i++ { + _, port, closeFn, err := FreeTCPAddr() + if err != nil { + panic(err) + } + + portPool <- port + closeFns = append(closeFns, closeFn) + } + + for _, closeFn := range closeFns { + err := closeFn() + if err != nil { + panic(err) + } + } +} // AppConstructor defines a function which accepts a network configuration and // creates an ABCI Application to provide to Tendermint. @@ -340,11 +363,18 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) { if cfg.APIAddress != "" { apiListenAddr = cfg.APIAddress } else { +<<<<<<< HEAD var err error apiListenAddr, _, err = server.FreeTCPAddr() if err != nil { return nil, err +======= + if len(portPool) == 0 { + return nil, fmt.Errorf("failed to get port for API server") +>>>>>>> 5e57be076 (test: use a queue of open ports for tests (#14893)) } + port := <-portPool + apiListenAddr = fmt.Sprintf("tcp://0.0.0.0:%s", port) } appCfg.API.Address = apiListenAddr @@ -357,21 +387,33 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) { if cfg.RPCAddress != "" { tmCfg.RPC.ListenAddress = cfg.RPCAddress } else { +<<<<<<< HEAD rpcAddr, _, err := server.FreeTCPAddr() if err != nil { return nil, err +======= + if len(portPool) == 0 { + return nil, fmt.Errorf("failed to get port for RPC server") +>>>>>>> 5e57be076 (test: use a queue of open ports for tests (#14893)) } - tmCfg.RPC.ListenAddress = rpcAddr + port := <-portPool + tmCfg.RPC.ListenAddress = fmt.Sprintf("tcp://0.0.0.0:%s", port) } if cfg.GRPCAddress != "" { appCfg.GRPC.Address = cfg.GRPCAddress } else { +<<<<<<< HEAD _, grpcPort, err := server.FreeTCPAddr() if err != nil { return nil, err +======= + if len(portPool) == 0 { + return nil, fmt.Errorf("failed to get port for GRPC server") +>>>>>>> 5e57be076 (test: use a queue of open ports for tests (#14893)) } - appCfg.GRPC.Address = fmt.Sprintf("0.0.0.0:%s", grpcPort) + port := <-portPool + appCfg.GRPC.Address = fmt.Sprintf("0.0.0.0:%s", port) } appCfg.GRPC.Enable = true @@ -409,17 +451,30 @@ func New(l Logger, baseDir string, cfg Config) (*Network, error) { tmCfg.Moniker = nodeDirName monikers[i] = nodeDirName +<<<<<<< HEAD proxyAddr, _, err := server.FreeTCPAddr() if err != nil { return nil, err +======= + if len(portPool) == 0 { + return nil, fmt.Errorf("failed to get port for Proxy server") +>>>>>>> 5e57be076 (test: use a queue of open ports for tests (#14893)) } + port := <-portPool + proxyAddr := fmt.Sprintf("tcp://0.0.0.0:%s", port) tmCfg.ProxyApp = proxyAddr +<<<<<<< HEAD p2pAddr, _, err := server.FreeTCPAddr() if err != nil { return nil, err +======= + if len(portPool) == 0 { + return nil, fmt.Errorf("failed to get port for Proxy server") +>>>>>>> 5e57be076 (test: use a queue of open ports for tests (#14893)) } - + port = <-portPool + p2pAddr := fmt.Sprintf("tcp://0.0.0.0:%s", port) tmCfg.P2P.ListenAddress = p2pAddr tmCfg.P2P.AddrBookStrict = false tmCfg.P2P.AllowDuplicateIP = true diff --git a/testutil/network/util.go b/testutil/network/util.go index f1bfa5268875..0a87517ca759 100644 --- a/testutil/network/util.go +++ b/testutil/network/util.go @@ -7,6 +7,7 @@ import ( "path/filepath" "time" +<<<<<<< HEAD "github.com/tendermint/tendermint/node" "github.com/tendermint/tendermint/p2p" pvm "github.com/tendermint/tendermint/privval" @@ -14,6 +15,15 @@ import ( "github.com/tendermint/tendermint/rpc/client/local" "github.com/tendermint/tendermint/types" tmtime "github.com/tendermint/tendermint/types/time" +======= + "github.com/cometbft/cometbft/node" + "github.com/cometbft/cometbft/p2p" + pvm "github.com/cometbft/cometbft/privval" + "github.com/cometbft/cometbft/proxy" + "github.com/cometbft/cometbft/rpc/client/local" + "github.com/cometbft/cometbft/types" + tmtime "github.com/cometbft/cometbft/types/time" +>>>>>>> 5e57be076 (test: use a queue of open ports for tests (#14893)) "github.com/cosmos/cosmos-sdk/server/api" servergrpc "github.com/cosmos/cosmos-sdk/server/grpc" @@ -202,3 +212,24 @@ func writeFile(name string, dir string, contents []byte) error { return nil } +<<<<<<< HEAD +======= + +// Get a free address for a test tendermint server +// protocol is either tcp, http, etc +func FreeTCPAddr() (addr, port string, closeFn func() error, err error) { + l, err := net.Listen("tcp", "localhost:0") + if err != nil { + return "", "", nil, err + } + + closeFn = func() error { + return l.Close() + } + + portI := l.Addr().(*net.TCPAddr).Port + port = fmt.Sprintf("%d", portI) + addr = fmt.Sprintf("tcp://0.0.0.0:%s", port) + return +} +>>>>>>> 5e57be076 (test: use a queue of open ports for tests (#14893)) diff --git a/x/genutil/client/cli/init_test.go b/x/genutil/client/cli/init_test.go index e836f5a9e99f..692e82606708 100644 --- a/x/genutil/client/cli/init_test.go +++ b/x/genutil/client/cli/init_test.go @@ -208,8 +208,13 @@ func TestStartStandAlone(t *testing.T) { app, err := mock.NewApp(home, logger) require.NoError(t, err) +<<<<<<< HEAD svrAddr, _, err := server.FreeTCPAddr() +======= + svrAddr, _, closeFn, err := network.FreeTCPAddr() +>>>>>>> 5e57be076 (test: use a queue of open ports for tests (#14893)) require.NoError(t, err) + require.NoError(t, closeFn()) svr, err := abci_server.NewServer(svrAddr, "socket", app) require.NoError(t, err, "error creating listener")