129 lines
3.7 KiB
Go
129 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// cobblerWire is the exact cobbler-wire document encapi serves for a node with
|
|
// a single role in the develop environment.
|
|
const cobblerWire = "classes:\n" +
|
|
" roles::infra::storage::vault: {}\n" +
|
|
"environment: develop\n" +
|
|
"parameters: {}\n"
|
|
|
|
// goldenENC is the reshaped ENC document the previous python script produced
|
|
// from cobblerWire (verified byte-for-byte against uv/python yaml.dump).
|
|
const goldenENC = "classes:\n" +
|
|
"- roles::infra::storage::vault\n" +
|
|
"environment: develop\n" +
|
|
"parameters:\n" +
|
|
" enc_env: develop\n" +
|
|
" enc_role:\n" +
|
|
" - roles::infra::storage::vault\n"
|
|
|
|
func TestRunGoldenOutput(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if r.URL.Path != "/cblr/svc/op/puppet/hostname/host.example" {
|
|
http.NotFound(w, r)
|
|
return
|
|
}
|
|
w.Header().Set("Content-Type", "application/x-yaml")
|
|
_, _ = w.Write([]byte(cobblerWire))
|
|
}))
|
|
defer srv.Close()
|
|
|
|
t.Setenv("ENCAPI_URL", srv.URL)
|
|
var out bytes.Buffer
|
|
if err := run([]string{"encapic", "host.example"}, &out); err != nil {
|
|
t.Fatalf("run returned error: %v", err)
|
|
}
|
|
if out.String() != goldenENC {
|
|
t.Errorf("output mismatch\n--- want ---\n%s\n--- got ---\n%s", goldenENC, out.String())
|
|
}
|
|
}
|
|
|
|
func TestRun404FailsNonZero(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
http.Error(w, `{"error":"not found"}`, http.StatusNotFound)
|
|
}))
|
|
defer srv.Close()
|
|
|
|
t.Setenv("ENCAPI_URL", srv.URL)
|
|
var out bytes.Buffer
|
|
err := run([]string{"encapic", "ghost.example"}, &out)
|
|
if err == nil {
|
|
t.Fatalf("expected error on 404, got nil")
|
|
}
|
|
if out.Len() != 0 {
|
|
t.Errorf("expected no stdout on failure, got %q", out.String())
|
|
}
|
|
if !strings.Contains(err.Error(), "404") {
|
|
t.Errorf("error should mention 404, got %v", err)
|
|
}
|
|
}
|
|
|
|
func TestRun500FailsNonZero(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
http.Error(w, "boom", http.StatusInternalServerError)
|
|
}))
|
|
defer srv.Close()
|
|
|
|
t.Setenv("ENCAPI_URL", srv.URL)
|
|
var out bytes.Buffer
|
|
if err := run([]string{"encapic", "host.example"}, &out); err == nil {
|
|
t.Fatalf("expected error on 500, got nil")
|
|
}
|
|
}
|
|
|
|
func TestFetchTimeout(t *testing.T) {
|
|
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
time.Sleep(200 * time.Millisecond)
|
|
_, _ = w.Write([]byte(cobblerWire))
|
|
}))
|
|
defer srv.Close()
|
|
|
|
// Use a client with a tiny timeout to exercise the timeout path quickly.
|
|
client := &http.Client{Timeout: 20 * time.Millisecond}
|
|
resp, err := client.Get(srv.URL + "/cblr/svc/op/puppet/hostname/host.example")
|
|
if err == nil {
|
|
_ = resp.Body.Close()
|
|
t.Fatalf("expected timeout error, got none")
|
|
}
|
|
}
|
|
|
|
func TestRunUsage(t *testing.T) {
|
|
var out bytes.Buffer
|
|
if err := run([]string{"encapic"}, &out); err == nil {
|
|
t.Fatalf("expected usage error with no args")
|
|
}
|
|
if err := run([]string{"encapic", "a", "b"}, &out); err == nil {
|
|
t.Fatalf("expected usage error with too many args")
|
|
}
|
|
}
|
|
|
|
func TestRunVersion(t *testing.T) {
|
|
var out bytes.Buffer
|
|
if err := run([]string{"encapic", "--version"}, &out); err != nil {
|
|
t.Fatalf("version returned error: %v", err)
|
|
}
|
|
if !strings.Contains(out.String(), "encapic") {
|
|
t.Errorf("version output = %q", out.String())
|
|
}
|
|
}
|
|
|
|
func TestDefaultBaseURLCompiledIn(t *testing.T) {
|
|
// Guard against accidental changes to the in-cluster default.
|
|
if err := os.Unsetenv("ENCAPI_URL"); err != nil {
|
|
t.Fatalf("unsetenv: %v", err)
|
|
}
|
|
if defaultBaseURL != "http://encapi.encapi.svc.cluster.local" {
|
|
t.Errorf("defaultBaseURL = %q", defaultBaseURL)
|
|
}
|
|
}
|