Ctrl K
ComunidadGuías…

utils/portbind_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package utils

import (
	"errors"
	"strings"
	"syscall"
	"testing"
)

// The bind is the check: a taken port is passed over for the next, and any
// other failure ends the search with it.
func TestBindFreePortPassesOverTakenPorts(t *testing.T) {
	var tried []uint32
	port, err := BindFreePort(func(p uint32) error {
		tried = append(tried, p)
		if len(tried) < 3 {
			return syscall.EADDRINUSE
		}
		return nil
	})
	if err != nil || len(tried) != 3 || port != tried[2] || tried[0] == tried[1] {
		t.Fatalf("got port %d, err %v, tried %v", port, err, tried)
	}

	boom := errors.New("boom")
	tried = nil
	if _, err := BindFreePort(func(p uint32) error { tried = append(tried, p); return boom }); !errors.Is(err, boom) || len(tried) != 1 {
		t.Fatalf("a failure other than a taken port: err %v after %d tries", err, len(tried))
	}

	if _, err := BindFreePort(func(uint32) error { return syscall.EADDRINUSE }); !errors.Is(err, syscall.EADDRINUSE) || !strings.Contains(err.Error(), "every port from") {
		t.Fatalf("every port taken: %v", err)
	}
}

// The candidates are the ports above the ephemeral range where it is known
// and ends below 65535, else the ports from 1024 up; every candidate is tried
// once, from a random start, so that runs started together try different
// ones first.
func TestBindFreePortTriesEachPortAboveTheEphemeralRangeOnce(t *testing.T) {
	for _, c := range []struct {
		name      string
		hi        uint32
		known     bool
		lo, count uint32
	}{
		{"a known range", 60999, true, 61000, 4536},
		{"a range up to 65535", 65535, true, 1024, 64512},
		{"an unknown range", 0, false, 1024, 64512},
	} {
		firsts := map[uint32]bool{}
		for draw := 0; draw < 20; draw++ {
			seen := map[uint32]bool{}
			_, err := bindFreePortAbove(func() (uint32, uint32, bool) { return 32768, c.hi, c.known }, func(p uint32) error {
				if len(seen) == 0 {
					firsts[p] = true
				}
				if p < c.lo || seen[p] {
					t.Fatalf("%s: tried port %d (below %d, or again)", c.name, p, c.lo)
				}
				seen[p] = true
				return syscall.EADDRINUSE
			})
			if err == nil || uint32(len(seen)) != c.count {
				t.Fatalf("%s: tried %d ports, want %d (err %v)", c.name, len(seen), c.count, err)
			}
		}
		if len(firsts) < 2 {
			t.Fatalf("%s: 20 searches all began at %v: not from a random start", c.name, firsts)
		}
	}
}

// The ports the caller holds are never tried, and every other candidate is.
func TestBindFreePortNeverTriesAHeldPort(t *testing.T) {
	held := []uint32{61000, 63333, 65535}
	tried := map[uint32]bool{}
	_, err := bindFreePortAbove(func() (uint32, uint32, bool) { return 32768, 60999, true }, func(p uint32) error {
		tried[p] = true
		return syscall.EADDRINUSE
	}, held...)
	for _, p := range held {
		if tried[p] {
			t.Fatalf("held port %d was tried", p)
		}
	}
	if err == nil || len(tried) != 4536-len(held) {
		t.Fatalf("tried %d ports, want %d (err %v)", len(tried), 4536-len(held), err)
	}
}

// PortTaken names what holds the port where it can, and says it cannot
// where it cannot.
func TestPortTakenNamesTheHolderWhereItCan(t *testing.T) {
	if got := PortTaken(1); got != "port 1 is taken ("+unnamedHolder+")" {
		t.Fatalf("a port nothing here holds: %q", got)
	}
}