// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package portlist import ( "net" "testing" "tailscale.com/tstest" ) func TestGetList(t *testing.T) { tstest.ResourceCheck(t) var p Poller pl, err := p.getList() if err != nil { t.Fatal(err) } for i, p := range pl { t.Logf("[%d] %+v", i, p) } t.Logf("As String: %v", pl.String()) } func TestIgnoreLocallyBoundPorts(t *testing.T) { tstest.ResourceCheck(t) ln, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Skipf("failed to bind: %v", err) } defer ln.Close() ta := ln.Addr().(*net.TCPAddr) port := ta.Port var p Poller pl, err := p.getList() if err != nil { t.Fatal(err) } for _, p := range pl { if p.Proto == "tcp" && int(p.Port) == port { t.Fatal("didn't expect to find test's localhost ephemeral port") } } } func TestEqualLessThan(t *testing.T) { tests := []struct { name string a, b Port want bool }{ { "Port a < b", Port{Proto: "tcp", Port: 100, Process: "proc1"}, Port{Proto: "tcp", Port: 101, Process: "proc1"}, true, }, { "Port a > b", Port{Proto: "tcp", Port: 101, Process: "proc1"}, Port{Proto: "tcp", Port: 100, Process: "proc1"}, false, }, { "Proto a < b", Port{Proto: "tcp", Port: 100, Process: "proc1"}, Port{Proto: "udp", Port: 100, Process: "proc1"}, true, }, { "Proto a < b", Port{Proto: "udp", Port: 100, Process: "proc1"}, Port{Proto: "tcp", Port: 100, Process: "proc1"}, false, }, { "Process a < b", Port{Proto: "tcp", Port: 100, Process: "proc1"}, Port{Proto: "tcp", Port: 100, Process: "proc2"}, true, }, { "Process a > b", Port{Proto: "tcp", Port: 100, Process: "proc2"}, Port{Proto: "tcp", Port: 100, Process: "proc1"}, false, }, { "Port evaluated first", Port{Proto: "udp", Port: 100, Process: "proc2"}, Port{Proto: "tcp", Port: 101, Process: "proc1"}, true, }, { "Proto evaluated second", Port{Proto: "tcp", Port: 100, Process: "proc2"}, Port{Proto: "udp", Port: 100, Process: "proc1"}, true, }, { "Process evaluated fourth", Port{Proto: "tcp", Port: 100, Process: "proc1"}, Port{Proto: "tcp", Port: 100, Process: "proc2"}, true, }, { "equal", Port{Proto: "tcp", Port: 100, Process: "proc1"}, Port{Proto: "tcp", Port: 100, Process: "proc1"}, false, }, } for _, tt := range tests { got := tt.a.lessThan(&tt.b) if got != tt.want { t.Errorf("%s: Equal = %v; want %v", tt.name, got, tt.want) } lessBack := tt.b.lessThan(&tt.a) if got && lessBack { t.Errorf("%s: both a and b report being less than each other", tt.name) } wantEqual := !got && !lessBack gotEqual := tt.a.equal(&tt.b) if gotEqual != wantEqual { t.Errorf("%s: equal = %v; want %v", tt.name, gotEqual, wantEqual) } } } func BenchmarkGetList(b *testing.B) { benchmarkGetList(b, false) } func BenchmarkGetListIncremental(b *testing.B) { benchmarkGetList(b, true) } func benchmarkGetList(b *testing.B, incremental bool) { b.ReportAllocs() var p Poller for i := 0; i < b.N; i++ { pl, err := p.getList() if err != nil { b.Fatal(err) } if incremental { p.prev = pl } } }