package networking import ( "os" "path/filepath" "reflect" "strings" "testing" ) const sampleHosts = `# static table 127.0.0.1 localhost ::1 localhost ip6-localhost 192.168.1.10 server server.local # the box ` func TestParseHosts(t *testing.T) { got := parseHosts(sampleHosts) want := []HostEntry{ {IP: "127.0.0.1", Hostnames: []string{"localhost"}}, {IP: "::1", Hostnames: []string{"localhost", "ip6-localhost"}}, {IP: "192.168.1.10", Hostnames: []string{"server", "server.local"}}, } if !reflect.DeepEqual(got, want) { t.Errorf("parseHosts:\n got %+v\nwant %+v", got, want) } } func TestUpsertAndDeleteHost(t *testing.T) { path := filepath.Join(t.TempDir(), "hosts") if err := os.WriteFile(path, []byte(sampleHosts), 0644); err != nil { t.Fatal(err) } old := hostsFile hostsFile = path defer func() { hostsFile = old }() // Update an existing IP — comments and other lines must survive. if err := upsertHost("192.168.1.10", []string{"web", "web.local"}); err != nil { t.Fatal(err) } data, _ := os.ReadFile(path) if !strings.Contains(string(data), "# static table") || !strings.Contains(string(data), "ip6-localhost") { t.Errorf("upsert clobbered other lines:\n%s", data) } entries := parseHosts(string(data)) if e := findHost(entries, "192.168.1.10"); e == nil || !reflect.DeepEqual(e.Hostnames, []string{"web", "web.local"}) { t.Errorf("upsert did not update entry: %+v", entries) } // Add a new IP. if err := upsertHost("10.0.0.5", []string{"db"}); err != nil { t.Fatal(err) } entries = parseHosts(mustRead(t, path)) if findHost(entries, "10.0.0.5") == nil { t.Errorf("upsert did not append new entry: %+v", entries) } // Delete it again. removed, err := deleteHost("10.0.0.5") if err != nil || !removed { t.Fatalf("delete failed: removed=%v err=%v", removed, err) } if findHost(parseHosts(mustRead(t, path)), "10.0.0.5") != nil { t.Error("entry still present after delete") } // Deleting a missing IP reports not-removed. if removed, _ := deleteHost("8.8.8.8"); removed { t.Error("expected removed=false for missing IP") } } func findHost(entries []HostEntry, ip string) *HostEntry { for i := range entries { if entries[i].IP == ip { return &entries[i] } } return nil } func mustRead(t *testing.T, path string) string { t.Helper() data, err := os.ReadFile(path) if err != nil { t.Fatal(err) } return string(data) }