diff --git a/main_test.go b/main_test.go index 49cc8fe..d22424a 100644 --- a/main_test.go +++ b/main_test.go @@ -2,6 +2,7 @@ package main import ( "encoding/json" + "io" "net/http" "net/http/httptest" "os" @@ -321,3 +322,104 @@ func TestWriteDefaultConfig_AlreadyExists(t *testing.T) { t.Fatal("expected error when config already exists") } } + +// ---- allFactsForNode -------------------------------------------------------- + +func TestAllFactsForNode_ReturnsSortedFacts(t *testing.T) { + facts := []fact{ + {Certname: "node1", Name: "zebra", Value: rawJSON("z-val")}, + {Certname: "node1", Name: "alpha", Value: rawJSON("a-val")}, + {Certname: "node1", Name: "middle", Value: rawJSON(42)}, + } + srv := newTestServer(t, facts) + defer srv.Close() + + got, err := allFactsForNode(srv.URL+"/pdb/query/v4/facts", "node1") + if err != nil { + t.Fatal(err) + } + if len(got) != 3 { + t.Fatalf("expected 3 facts, got %d", len(got)) + } +} + +func TestAllFactsForNode_QueryContainsCertname(t *testing.T) { + var receivedQuery string + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + receivedQuery = r.URL.Query().Get("query") + w.Header().Set("Content-Type", "application/json") + json.NewEncoder(w).Encode([]fact{}) + })) + defer srv.Close() + + allFactsForNode(srv.URL+"/pdb/query/v4/facts", "mynode.example.com") + if !strings.Contains(receivedQuery, "mynode.example.com") { + t.Fatalf("expected certname in query, got: %s", receivedQuery) + } + if !strings.Contains(receivedQuery, "certname") { + t.Fatalf("expected 'certname' in query, got: %s", receivedQuery) + } +} + +func TestAllFactsForNode_HTTPError(t *testing.T) { + srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + http.Error(w, "internal error", http.StatusInternalServerError) + })) + defer srv.Close() + + _, err := allFactsForNode(srv.URL+"/pdb/query/v4/facts", "node1") + if err == nil { + t.Fatal("expected error for HTTP 500") + } +} + +// ---- run with -a flag ------------------------------------------------------- + +func TestRun_AllFacts_RequiresNode(t *testing.T) { + cfg := config{PuppetDBURL: "http://unused", RoleFact: "enc_role"} + err := run(cfg, "", "", "", "", false, false, false, false, false, false, true) + if err == nil || !strings.Contains(err.Error(), "-a requires -n") { + t.Fatalf("expected -a requires -n error, got: %v", err) + } +} + +func TestRun_AllFacts_PrintsSortedByName(t *testing.T) { + facts := []fact{ + {Certname: "node1", Name: "zzz_fact", Value: rawJSON("last")}, + {Certname: "node1", Name: "aaa_fact", Value: rawJSON("first")}, + {Certname: "node1", Name: "mmm_fact", Value: rawJSON(true)}, + } + srv := newTestServer(t, facts) + defer srv.Close() + + old := os.Stdout + r, w, _ := os.Pipe() + os.Stdout = w + + cfg := config{PuppetDBURL: srv.URL + "/pdb/query/v4/facts", RoleFact: "enc_role"} + err := run(cfg, "node1", "", "", "", false, false, false, false, false, false, true) + + w.Close() + os.Stdout = old + var buf strings.Builder + io.Copy(&buf, r) + out := buf.String() + + if err != nil { + t.Fatal(err) + } + + lines := strings.Split(strings.TrimSpace(out), "\n") + if len(lines) != 3 { + t.Fatalf("expected 3 lines, got %d: %q", len(lines), out) + } + if !strings.HasPrefix(lines[0], "aaa_fact") { + t.Errorf("first line should be aaa_fact, got: %s", lines[0]) + } + if !strings.HasPrefix(lines[1], "mmm_fact") { + t.Errorf("second line should be mmm_fact, got: %s", lines[1]) + } + if !strings.HasPrefix(lines[2], "zzz_fact") { + t.Errorf("third line should be zzz_fact, got: %s", lines[2]) + } +}