@@ -1764,6 +1764,114 @@ func TestServePort_CustomPort(t *testing.T) {
17641764 }
17651765}
17661766
1767+ // ---------------------------------------------------------------------------
1768+ // isPortFree / findFreePort tests
1769+ // ---------------------------------------------------------------------------
1770+
1771+ // TestIsPortFree_FreePort verifies that isPortFree returns true for a port
1772+ // that nothing is bound to.
1773+ func TestIsPortFree_FreePort (t * testing.T ) {
1774+ // Grab an ephemeral port from the OS, then close the listener before
1775+ // calling isPortFree so the port is genuinely free.
1776+ ln , err := net .Listen ("tcp" , "127.0.0.1:0" )
1777+ if err != nil {
1778+ t .Fatalf ("listen: %v" , err )
1779+ }
1780+ port := ln .Addr ().(* net.TCPAddr ).Port
1781+ ln .Close ()
1782+
1783+ if ! isPortFree (port ) {
1784+ t .Errorf ("isPortFree(%d) = false, want true for an unbound port" , port )
1785+ }
1786+ }
1787+
1788+ // TestIsPortFree_BusyPort verifies that isPortFree returns false when
1789+ // a listener is already bound to the port.
1790+ func TestIsPortFree_BusyPort (t * testing.T ) {
1791+ ln , err := net .Listen ("tcp" , "127.0.0.1:0" )
1792+ if err != nil {
1793+ t .Fatalf ("listen: %v" , err )
1794+ }
1795+ defer ln .Close ()
1796+ port := ln .Addr ().(* net.TCPAddr ).Port
1797+
1798+ if isPortFree (port ) {
1799+ t .Errorf ("isPortFree(%d) = true, want false while a listener holds the port" , port )
1800+ }
1801+ }
1802+
1803+ // TestFindFreePort_ReturnsStartWhenFree verifies that findFreePort returns the
1804+ // start port itself when that port is not in use.
1805+ func TestFindFreePort_ReturnsStartWhenFree (t * testing.T ) {
1806+ // Use an ephemeral port that the OS just freed.
1807+ ln , err := net .Listen ("tcp" , "127.0.0.1:0" )
1808+ if err != nil {
1809+ t .Fatalf ("listen: %v" , err )
1810+ }
1811+ port := ln .Addr ().(* net.TCPAddr ).Port
1812+ ln .Close ()
1813+
1814+ got := findFreePort (port )
1815+ if got != port {
1816+ t .Errorf ("findFreePort(%d) = %d, want %d when port is free" , port , got , port )
1817+ }
1818+ }
1819+
1820+ // TestFindFreePort_SkipsBusyPort verifies that findFreePort skips over a busy
1821+ // port and returns the next free one.
1822+ func TestFindFreePort_SkipsBusyPort (t * testing.T ) {
1823+ // Bind a listener on the first port so it is unavailable.
1824+ ln , err := net .Listen ("tcp" , "127.0.0.1:0" )
1825+ if err != nil {
1826+ t .Fatalf ("listen: %v" , err )
1827+ }
1828+ defer ln .Close ()
1829+ busyPort := ln .Addr ().(* net.TCPAddr ).Port
1830+
1831+ got := findFreePort (busyPort )
1832+ if got == 0 {
1833+ t .Fatalf ("findFreePort(%d) = 0; expected a free port to be found" , busyPort )
1834+ }
1835+ if got <= busyPort {
1836+ t .Errorf ("findFreePort(%d) = %d; want a port > %d (busy port skipped)" , busyPort , got , busyPort )
1837+ }
1838+ // The returned port must actually be free.
1839+ if ! isPortFree (got ) {
1840+ t .Errorf ("findFreePort returned port %d, but isPortFree(%d) = false" , got , got )
1841+ }
1842+ }
1843+
1844+ // TestFindFreePort_ReturnsZeroWhenRangeExhausted verifies that findFreePort
1845+ // returns 0 when all ports in the search range are occupied.
1846+ func TestFindFreePort_ReturnsZeroWhenRangeExhausted (t * testing.T ) {
1847+ // Bind listeners on 100 consecutive ports starting at startPort.
1848+ // We use high ephemeral ports to avoid system conflicts.
1849+ const startPort = 59900
1850+ const count = 100
1851+ listeners := make ([]net.Listener , 0 , count )
1852+ for i := 0 ; i < count ; i ++ {
1853+ ln , err := net .Listen ("tcp" , fmt .Sprintf ("127.0.0.1:%d" , startPort + i ))
1854+ if err != nil {
1855+ // If we can't bind all 100 ports (e.g. some already taken), skip the test.
1856+ for _ , l := range listeners {
1857+ l .Close ()
1858+ }
1859+ t .Skipf ("could not bind port %d: %v" , startPort + i , err )
1860+ }
1861+ listeners = append (listeners , ln )
1862+ }
1863+ defer func () {
1864+ for _ , l := range listeners {
1865+ l .Close ()
1866+ }
1867+ }()
1868+
1869+ got := findFreePort (startPort )
1870+ if got != 0 {
1871+ t .Errorf ("findFreePort(%d) = %d, want 0 when all ports in range are busy" , startPort , got )
1872+ }
1873+ }
1874+
17671875// ---------------------------------------------------------------------------
17681876// buildServeArgs tests
17691877// ---------------------------------------------------------------------------
0 commit comments