From ee02e0badc199b72fc8909244bc66ee5c6d87448 Mon Sep 17 00:00:00 2001 From: Brian Cunnie Date: Wed, 3 Aug 2022 16:31:24 -0700 Subject: [PATCH] Integration tests: scan for open port Previously our integration tests bound to port 53, and, if that failed, fell back to binding to port 3553. This commit introduces code to scan for an open port and uses that, which lays the foundation for potentially parallelizing the integration tests. --- src/sslip.io-dns-server/integration_test.go | 38 ++++++++++++++++----- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/sslip.io-dns-server/integration_test.go b/src/sslip.io-dns-server/integration_test.go index 5378a0e..fa3d980 100644 --- a/src/sslip.io-dns-server/integration_test.go +++ b/src/sslip.io-dns-server/integration_test.go @@ -1,6 +1,7 @@ package main_test import ( + "log" "net" "os/exec" "strconv" @@ -17,17 +18,10 @@ import ( var err error var serverCmd *exec.Cmd var serverSession *Session -var port = 53 +var port = getFreePort() var _ = BeforeSuite(func() { // Try to bind to the privileged first (for macOS), the fall back to unprivileged - conn, err := net.ListenUDP("udp", &net.UDPAddr{Port: port}) - if err != nil { - port = 3553 // unprivileged, a.k.a. "Red Box Recorder ADP" from /etc/services - } else { - err = conn.Close() - Expect(err).ToNot(HaveOccurred()) - } serverPath, err := Build("main.go") Expect(err).ToNot(HaveOccurred()) serverCmd = exec.Command(serverPath, "-port", strconv.Itoa(port)) @@ -444,3 +438,31 @@ var _ = Describe("sslip.io-dns-server", func() { ) }) }) + +var listenPort = 1023 // lowest unprivileged port - 1 (immediately incremented) + +// getFreePort should always succeed unless something awful has happened, e.g. port exhaustion +func getFreePort() int { + for { + listenPort += 1 + switch { + case listenPort > 65535: + listenPort = 1023 // we've reached the highest port, start over + case isPortFree(listenPort): + return listenPort + } + } +} + +func isPortFree(port int) bool { + conn, err := net.ListenUDP("udp", &net.UDPAddr{Port: port}) + if err != nil { + return false + } + err = conn.Close() + if err != nil { + log.Printf("I couldn't close port %d", port) + return false + } + return true +}