diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index 4e1f6340a006..1b6daac6d774 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -20,6 +20,7 @@ import ( "crypto/rand" "math/big" "path/filepath" + "regexp" "runtime" "strconv" "strings" @@ -34,6 +35,11 @@ const ( httpAPIs = "eth:1.0 net:1.0 rpc:1.0 web3:1.0" ) +var ( + httpEndpointRegexp = regexp.MustCompile(`HTTP server started\s+endpoint=([^\s]+)`) + wsEndpointRegexp = regexp.MustCompile(`WebSocket enabled\s+url=(ws://[^\s]+)`) +) + // spawns geth with the given command line args, using a set of flags to minimise // memory and disk IO. If the args don't set --datadir, the // child g gets a temporary data directory. @@ -83,9 +89,9 @@ To exit, press ctrl-d or type exit // Tests that a console can be attached to a running node via various means. func TestAttachWelcome(t *testing.T) { var ( - ipc string - httpPort string - wsPort string + ipc string + httpURL string + wsURL string ) // Configure the instance for IPC attachment if runtime.GOOS == "windows" { @@ -94,26 +100,26 @@ func TestAttachWelcome(t *testing.T) { ipc = filepath.Join(t.TempDir(), "geth.ipc") } // And HTTP + WS attachment - p := trulyRandInt(1024, 65533) // Yeah, sometimes this will fail, sorry :P - httpPort = strconv.Itoa(p) - wsPort = strconv.Itoa(p + 1) geth := runMinimalGeth(t, "--miner.etherbase", "0x8605cdbbdb6d264aa742e77020dcbc58fcdce182", "--ipcpath", ipc, - "--http", "--http.port", httpPort, - "--ws", "--ws.port", wsPort) + "--http", "--http.addr", "127.0.0.1", "--http.port", "0", + "--ws", "--ws.addr", "127.0.0.1", "--ws.port", "0") + + httpEndpoint := waitForLogMatch(t, geth, httpEndpointRegexp) + httpURL = "http://" + httpEndpoint + wsURL = waitForLogMatch(t, geth, wsEndpointRegexp) + t.Run("ipc", func(t *testing.T) { waitForEndpoint(t, ipc, 2*time.Minute) testAttachWelcome(t, geth, "ipc:"+ipc, ipcAPIs) }) t.Run("http", func(t *testing.T) { - endpoint := "http://127.0.0.1:" + httpPort - waitForEndpoint(t, endpoint, 2*time.Minute) - testAttachWelcome(t, geth, endpoint, httpAPIs) + waitForEndpoint(t, httpURL, 2*time.Minute) + testAttachWelcome(t, geth, httpURL, httpAPIs) }) t.Run("ws", func(t *testing.T) { - endpoint := "ws://127.0.0.1:" + wsPort - waitForEndpoint(t, endpoint, 2*time.Minute) - testAttachWelcome(t, geth, endpoint, httpAPIs) + waitForEndpoint(t, wsURL, 2*time.Minute) + testAttachWelcome(t, geth, wsURL, httpAPIs) }) geth.Kill() } @@ -151,8 +157,21 @@ To exit, press ctrl-d or type exit attach.ExpectExit() } +func waitForLogMatch(t *testing.T, geth *testgeth, re *regexp.Regexp) string { + t.Helper() + deadline := time.Now().Add(30 * time.Second) + for time.Now().Before(deadline) { + if matches := re.FindStringSubmatch(geth.StderrText()); len(matches) > 1 { + return matches[1] + } + time.Sleep(100 * time.Millisecond) + } + t.Fatalf("timeout waiting for log %q\nstderr:\n%s", re.String(), geth.StderrText()) + return "" +} + // trulyRandInt generates a crypto random integer used by the console tests to -// not clash network ports with other tests running concurrently. +// avoid name collisions (pipe identifiers, ports, etc.) when running concurrently. func trulyRandInt(lo, hi int) int { num, _ := rand.Int(rand.Reader, big.NewInt(int64(hi-lo))) return int(num.Int64()) + lo diff --git a/eth/sync_test.go b/eth/sync_test.go index dc295f27904b..0ad2942e80c1 100644 --- a/eth/sync_test.go +++ b/eth/sync_test.go @@ -88,17 +88,23 @@ func testSnapSyncDisabling(t *testing.T, ethVer uint, snapVer uint) { if err := empty.handler.downloader.BeaconSync(ethconfig.SnapSync, full.chain.CurrentBlock(), nil); err != nil { t.Fatal("sync failed:", err) } - // Downloader internally has to wait for a timer (3s) to be expired before - // exiting. Poll after to determine if sync is disabled. - time.Sleep(time.Second * 3) - for timeout := time.After(time.Second); ; { + // Instead of relying on a fixed sleep, poll for the flag within a generous deadline + // to accommodate slow CI runners + checkTicker := time.NewTicker(100 * time.Millisecond) + defer checkTicker.Stop() + + checkDeadline := time.NewTimer(6 * time.Second) + defer checkDeadline.Stop() + + for { + if !empty.handler.snapSync.Load() { + return + } select { - case <-timeout: + case <-checkTicker.C: + continue + case <-checkDeadline.C: t.Fatalf("snap sync not disabled after successful synchronisation") - case <-time.After(100 * time.Millisecond): - if !empty.handler.snapSync.Load() { - return - } } } } diff --git a/p2p/discover/v5_udp_test.go b/p2p/discover/v5_udp_test.go index 6abe20d7a4c4..5ecd9ff2f893 100644 --- a/p2p/discover/v5_udp_test.go +++ b/p2p/discover/v5_udp_test.go @@ -90,7 +90,7 @@ func startLocalhostV5(t *testing.T, cfg Config) *UDPv5 { } realaddr := socket.LocalAddr().(*net.UDPAddr) ln.SetStaticIP(realaddr.IP) - ln.Set(enr.UDP(realaddr.Port)) + ln.SetFallbackUDP(realaddr.Port) udp, err := ListenV5(socket, ln, cfg) if err != nil { t.Fatal(err)