Skip to content

Commit

Permalink
more robust nextPort (#103)
Browse files Browse the repository at this point in the history
* more robust nextPort

in tests we use nextPort to find the next open port on the test machine to listen on, this is fragile as it sometimes returns a port that isn't available.

ensure that we cannot connect to the port before we return it

* do not check for context canceled where it won't happen
  • Loading branch information
ClaytonNorthey92 authored Apr 30, 2024
1 parent 48f8b29 commit 55b8f52
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 17 deletions.
36 changes: 26 additions & 10 deletions e2e/e2e_ext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"sort"
"strings"
"sync"
"syscall"
"testing"
"time"

Expand Down Expand Up @@ -260,13 +261,28 @@ func createTestDB(ctx context.Context, t *testing.T) (bfgd.Database, string, *sq
return db, u.String(), sdb, cleanup
}

func nextPort() int {
port, err := freeport.GetFreePort()
if err != nil && !errors.Is(err, context.Canceled) {
panic(err)
}
func nextPort(ctx context.Context, t *testing.T) int {
for {
select {
case <-ctx.Done():
t.Fatal(ctx.Err())
default:
}

port, err := freeport.GetFreePort()
if err != nil {
t.Fatal(err)
}

if _, err := net.DialTimeout("tcp", net.JoinHostPort("localhost", fmt.Sprintf("%d", port)), 1*time.Second); err != nil {
if errors.Is(err, syscall.ECONNREFUSED) {
// connection error, port is open
return port
}

return port
t.Fatal(err)
}
}
}

func createPopm(ctx context.Context, t *testing.T, bfgUrl string, bfgPrivateWsUrl string) (*popm.Miner, error) {
Expand All @@ -283,8 +299,8 @@ func createPopm(ctx context.Context, t *testing.T, bfgUrl string, bfgPrivateWsUr
}

func createBfgServerWithAuth(ctx context.Context, t *testing.T, pgUri string, electrumxAddr string, btcStartHeight uint64, auth bool) (*bfg.Server, string, string, string) {
bfgPrivateListenAddress := fmt.Sprintf(":%d", nextPort())
bfgPublicListenAddress := fmt.Sprintf(":%d", nextPort())
bfgPrivateListenAddress := fmt.Sprintf(":%d", nextPort(ctx, t))
bfgPublicListenAddress := fmt.Sprintf(":%d", nextPort(ctx, t))

bfgServer, err := bfg.NewServer(&bfg.Config{
PrivateListenAddress: bfgPrivateListenAddress,
Expand Down Expand Up @@ -324,7 +340,7 @@ func createBfgServer(ctx context.Context, t *testing.T, pgUri string, electrumxA
}

func createBssServer(ctx context.Context, t *testing.T, bfgWsurl string) (*bss.Server, string, string) {
bssListenAddress := fmt.Sprintf(":%d", nextPort())
bssListenAddress := fmt.Sprintf(":%d", nextPort(ctx, t))

bssServer, err := bss.NewServer(&bss.Config{
BFGURL: bfgWsurl,
Expand Down Expand Up @@ -362,7 +378,7 @@ func reverseAndEncodeEncodedHash(encodedHash string) string {
}

func createMockElectrumxServer(ctx context.Context, t *testing.T, l2Keystone *hemi.L2Keystone, btx []byte) (string, func()) {
addr := fmt.Sprintf("localhost:%d", nextPort())
addr := fmt.Sprintf("localhost:%d", nextPort(ctx, t))

listener, err := net.Listen("tcp", addr)
if err != nil {
Expand Down
31 changes: 24 additions & 7 deletions service/tbc/tbc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import (
"errors"
"fmt"
"io"
"net"
"os"
"slices"
"strconv"
"strings"
"syscall"
"testing"
"time"

Expand Down Expand Up @@ -1891,13 +1893,28 @@ func getEndpointWithRetries(ctx context.Context, container testcontainers.Contai
return "", lastError
}

func nextPort() int {
ports, err := freeport.GetFreePorts(1000)
if err != nil && !errors.Is(err, context.Canceled) {
panic(err)
}
func nextPort(ctx context.Context, t *testing.T) int {
for {
select {
case <-ctx.Done():
t.Fatal(ctx.Err())
default:
}

return ports[time.Now().Unix()%int64(len(ports))]
port, err := freeport.GetFreePort()
if err != nil {
t.Fatal(err)
}

if _, err := net.DialTimeout("tcp", net.JoinHostPort("localhost", fmt.Sprintf("%d", port)), 1*time.Second); err != nil {
if errors.Is(err, syscall.ECONNREFUSED) {
// connection error, port is open
return port
}

t.Fatal(err)
}
}
}

func createTbcServer(ctx context.Context, t *testing.T, mappedPeerPort nat.Port) (*Server, string) {
Expand All @@ -1911,7 +1928,7 @@ func createTbcServer(ctx context.Context, t *testing.T, mappedPeerPort nat.Port)
if err := os.RemoveAll(home); err != nil {
t.Fatal(err)
}
tcbListenAddress := fmt.Sprintf(":%d", nextPort())
tcbListenAddress := fmt.Sprintf(":%d", nextPort(ctx, t))

cfg := NewDefaultConfig()
cfg.LevelDBHome = home
Expand Down

0 comments on commit 55b8f52

Please sign in to comment.