fix: address code review issues on PR #10 (HAN-384)

- runner.go: store fingerprints in local var, call formatter.SetFingerprints()
  instead of mutating caller's *Config; removes Fingerprints field from Config
- fingerprint.go: use singleflight.Group in Query to coalesce concurrent
  probes for the same IP, eliminating the double-probe race
- output layer: add SetFingerprints(map[string]string) to Formatter interface;
  textFormatter and jsonFormatter each hold their own fingerprints field
- formatter_test.go: add TestTextFormatterWriteSummaryShowsVersions and
  TestJSONFormatterWriteSummaryShowsVersions verifying version output

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
Gary Hansen
2026-06-08 02:59:38 +10:00
co-authored by Copilot multica-agent
parent 3e7580b919
commit c96d18859f
7 changed files with 113 additions and 20 deletions
+74
View File
@@ -150,6 +150,80 @@ func TestJSONFormatterProducesValidOutput(t *testing.T) {
}
}
func TestTextFormatterWriteSummaryShowsVersions(t *testing.T) {
ref := traverse.NewReferral("example.com.", dns.TypeA, "com.", 0, 1.0, nil)
serverIP := net.ParseIP("198.41.0.4")
resp := &traverse.Response{
Referral: ref,
Server: serverIP,
Type: traverse.RespAnswer,
}
var buf bytes.Buffer
cfg := DefaultConfig()
cfg.Color = false
cfg.ShowVersions = true
cfg.ShowServers = true
cfg.ShowResults = false
cfg.ShowSummaryResults = false
formatter := NewFormatter(cfg, &buf)
formatter.SetFingerprints(map[string]string{serverIP.String(): "BIND 9.18.1"})
if err := formatter.WriteSummary([]traverse.TraversalResult{{Referral: ref, Response: resp}}); err != nil {
t.Fatalf("WriteSummary: %v", err)
}
out := buf.String()
if !strings.Contains(out, "BIND 9.18.1") {
t.Fatalf("expected version string in text output, got %q", out)
}
}
func TestJSONFormatterWriteSummaryShowsVersions(t *testing.T) {
ref := traverse.NewReferral("example.com.", dns.TypeA, "com.", 0, 1.0, nil)
serverIP := net.ParseIP("198.41.0.4")
resp := &traverse.Response{
Referral: ref,
Server: serverIP,
Type: traverse.RespAnswer,
}
var buf bytes.Buffer
cfg := DefaultConfig()
cfg.Format = FormatJSON
cfg.Domain = "example.com"
cfg.QueryType = "A"
cfg.ShowVersions = true
cfg.ShowServers = true
cfg.ShowResults = false
cfg.ShowSummaryResults = false
formatter := NewFormatter(cfg, &buf)
formatter.SetFingerprints(map[string]string{serverIP.String(): "Unbound 1.17.0"})
if err := formatter.WriteSummary([]traverse.TraversalResult{{Referral: ref, Response: resp}}); err != nil {
t.Fatalf("WriteSummary: %v", err)
}
if err := formatter.Flush(); err != nil {
t.Fatalf("Flush: %v", err)
}
var payload map[string]any
if err := json.Unmarshal(buf.Bytes(), &payload); err != nil {
t.Fatalf("invalid json: %v\n%s", err, buf.String())
}
servers, ok := payload["servers"].([]any)
if !ok || len(servers) == 0 {
t.Fatalf("expected servers in json output, got %v", payload)
}
srv, ok := servers[0].(map[string]any)
if !ok {
t.Fatalf("expected server object, got %T", servers[0])
}
if srv["version"] != "Unbound 1.17.0" {
t.Fatalf("expected version = %q, got %v", "Unbound 1.17.0", srv["version"])
}
}
func TestRunTraversalUsesHooks(t *testing.T) {
answerResp := func() *miekgdns.Msg {
m := new(miekgdns.Msg)