You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
tailscale/net/porttrack/porttrack_test.go

95 lines
2.2 KiB

// Copyright (c) Tailscale Inc & contributors
// SPDX-License-Identifier: BSD-3-Clause
package porttrack
import (
"context"
"errors"
"fmt"
"net"
"net/http"
"testing"
)
func TestCollectorAndListen(t *testing.T) {
c := NewCollector(t)
labels := []string{"main", "plaintext", "debug"}
ports := make([]int, len(labels))
for i, label := range labels {
ln, err := Listen("tcp", c.Addr(label))
if err != nil {
t.Fatalf("Listen(%q): %v", label, err)
}
defer ln.Close()
p, err := c.Port(t.Context(), label)
if err != nil {
t.Fatalf("Port(%q): %v", label, err)
}
ports[i] = p
}
// All ports should be distinct non-zero values.
seen := map[int]string{}
for i, label := range labels {
if ports[i] == 0 {
t.Errorf("Port(%q) = 0", label)
}
if prev, ok := seen[ports[i]]; ok {
t.Errorf("Port(%q) = Port(%q) = %d", label, prev, ports[i])
}
seen[ports[i]] = label
}
}
func TestListenPassthrough(t *testing.T) {
ln, err := Listen("tcp", "localhost:0")
if err != nil {
t.Fatalf("Listen passthrough: %v", err)
}
defer ln.Close()
if ln.Addr().(*net.TCPAddr).Port == 0 {
t.Fatal("expected non-zero port")
}
}
func TestRoundTrip(t *testing.T) {
c := NewCollector(t)
ln, err := Listen("tcp", c.Addr("http"))
if err != nil {
t.Fatalf("Listen: %v", err)
}
defer ln.Close()
// Start a server on the listener.
go http.Serve(ln, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNoContent)
}))
port, err := c.Port(t.Context(), "http")
if err != nil {
t.Fatalf("Port: %v", err)
}
resp, err := http.Get(fmt.Sprintf("http://localhost:%d/", port))
if err != nil {
t.Fatalf("http.Get: %v", err)
}
resp.Body.Close()
if resp.StatusCode != http.StatusNoContent {
t.Fatalf("status = %d, want %d", resp.StatusCode, http.StatusNoContent)
}
}
func TestPortContextCancelled(t *testing.T) {
c := NewCollector(t)
// Nobody will ever report "never", so Port should block until ctx is done.
ctx, cancel := context.WithCancel(t.Context())
cancel()
_, err := c.Port(ctx, "never")
if !errors.Is(err, context.Canceled) {
t.Fatalf("Port with cancelled context: got %v, want %v", err, context.Canceled)
}
}