package watcher_test import ( "maps" "slices" "testing" "sneak.berlin/go/dnswatcher/internal/state" "sneak.berlin/go/dnswatcher/internal/watcher" ) // TestIPv6AddressInBrackets runs the port checks, not the watcher's // first, on hostname state built here for a hostname at an IPv6 address // whose port 443 the previous check found closed. It is open now. Then // it runs the TLS checks and the port checks again. The port and // certificate keys and the Port Change notification write the address // in brackets, so its last group cannot be read as the port, and the // second port checks keep the certificate entry, whose address they read // back from its key. When a last port check finds port 443 closed, the // certificate entry is removed. Nothing is looked up. func TestIPv6AddressInBrackets(t *testing.T) { t.Parallel() const aaaaType = "AAAA" cfg := defaultTestConfig(t) cfg.Hostnames = []string{host} deps := newTestDeps(t, cfg) w := watcher.NewForTest( cfg, deps.state, nil, deps.portChecker, deps.tlsChecker, deps.notifier, ) w.SetFirstRun(false) deps.state.SetHostnameState(host, saved( map[string]*state.NameserverRecordState{ nsA: answered(map[string][]string{aaaaType: {"2001:db8::1"}}), }, )) deps.state.SetPortState("[2001:db8::1]:443", &state.PortState{ Hostnames: []string{host}, }) w.CheckAllPorts(t.Context()) w.RunTLSChecks(t.Context()) w.CheckAllPorts(t.Context()) snap := deps.state.GetSnapshot() gotPorts := slices.Sorted(maps.Keys(snap.Ports)) wantPorts := []string{"[2001:db8::1]:443", "[2001:db8::1]:80"} if !slices.Equal(gotPorts, wantPorts) { t.Errorf("port entries %v, want %v", gotPorts, wantPorts) } gotCerts := slices.Sorted(maps.Keys(snap.Certificates)) wantCerts := []string{"[2001:db8::1]:443:www.example.net"} if !slices.Equal(gotCerts, wantCerts) { t.Errorf("certificate entries %v, want %v", gotCerts, wantCerts) } title := "Port Change: [2001:db8::1]:443" want := `Hostnames: www.example.net Address: [2001:db8::1]:443 Port now open` got := deps.notifier.getNotifications() if len(got) != 1 || got[0].Title != title || got[0].Message != want { t.Errorf("sent %v, want one %q with message:\n%s", got, title, want) } deps.portChecker.closed = true w.CheckAllPorts(t.Context()) gotCerts = slices.Sorted(maps.Keys(deps.state.GetSnapshot().Certificates)) if len(gotCerts) != 0 { t.Errorf("certificate entries %v with port 443 closed, want none", gotCerts) } }