From a27fe22d2ec3b1c0f0fd17f9a71e11fd32e85ee5 Mon Sep 17 00:00:00 2001 From: Florian Veaux Date: Tue, 16 Jan 2024 11:32:58 +0100 Subject: [PATCH] Add mutex state to getFreePort testutil (#22080) --- pkg/networkdevice/testutils/freeport.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pkg/networkdevice/testutils/freeport.go b/pkg/networkdevice/testutils/freeport.go index ed8a04ae6742c..74eed3db5a48b 100644 --- a/pkg/networkdevice/testutils/freeport.go +++ b/pkg/networkdevice/testutils/freeport.go @@ -9,11 +9,36 @@ package testutils import ( "net" + "sync" +) + +var ( + globalMutex sync.Mutex // Prevent the util function to be called concurrently + usedPorts = make(map[uint16]bool) ) // GetFreePort finds a free port to use for testing. // Borrowed from: https://github.com/phayes/freeport/blame/master/freeport.go#L8-L20 func GetFreePort() (uint16, error) { + globalMutex.Lock() + defer globalMutex.Unlock() + + var lastError error + for retries := 0; retries < 5; retries++ { + port, err := getSingleFreePort() + if err != nil { + lastError = err + continue + } + if _, ok := usedPorts[port]; !ok { + usedPorts[port] = true + return port, nil + } + } + return 0, lastError +} + +func getSingleFreePort() (uint16, error) { addr, err := net.ResolveTCPAddr("tcp", "localhost:0") if err != nil { return 0, err