package vault import ( "context" "encoding/json" "fmt" "net/http" "net/http/httptest" "strings" "sync" "testing" ) func TestSeed(t *testing.T) { var mu sync.Mutex records := map[string]Record{ "short/api": {Data: map[string]any{"private_key": "PLACEHOLDER"}, Version: 1}, "short/public": {Data: map[string]any{"public_key": "PLACEHOLDER"}, Version: 1}, } s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { mu.Lock() defer mu.Unlock() path := strings.TrimPrefix(r.URL.Path, "/v1/secret/data/") record, ok := records[path] if !ok { http.NotFound(w, r) return } if r.Method == http.MethodGet { json.NewEncoder(w).Encode(map[string]any{"data": map[string]any{"data": record.Data, "metadata": map[string]int{"version": record.Version}}}) return } var request struct { Data map[string]any `json:"data"` Options struct { CAS int `json:"cas"` } `json:"options"` } if err := json.NewDecoder(r.Body).Decode(&request); err != nil { t.Error(err) } if request.Options.CAS != record.Version { w.WriteHeader(400) return } records[path] = Record{Data: request.Data, Version: record.Version + 1} fmt.Fprint(w, `{}`) })) defer s.Close() c := Client{URL: s.URL, HTTP: s.Client()} ctx := context.Background() if err := c.Seed(ctx, "short/api"); err != nil { t.Fatal(err) } key := records["short/api"].Data["private_key"] for range 2 { if err := c.Seed(ctx, "short/api"); err != nil { t.Fatal(err) } } if records["short/api"].Version != 2 || records["short/api"].Data["private_key"] != key { t.Fatal("repeat seed rotated API identity") } if records["short/public"].Version != 2 || len(records["short/public"].Data) != 1 { t.Fatal("public publication contains private material or redundant writes") } records["short/public"] = Record{Data: map[string]any{"public_key": "PLACEHOLDER"}, Version: 3} if err := c.Seed(ctx, "short/api"); err != nil { t.Fatal(err) } if records["short/api"].Data["private_key"] != key || records["short/public"].Version != 4 { t.Fatal("interrupted seed did not resume without rotation") } records["short/api"] = Record{Data: map[string]any{"private_key": "PLACEHOLDER"}, Version: 5} records["short/public"] = Record{Data: map[string]any{"public_key": "PLACEHOLDER"}, Version: 5} var tasks sync.WaitGroup for range 8 { tasks.Go(func() { _ = c.Seed(ctx, "short/api") }) } tasks.Wait() if err := c.Seed(ctx, "short/api"); err != nil { t.Fatal(err) } if records["short/api"].Version != 6 || records["short/public"].Version != 6 { t.Fatal("concurrent bootstrap rotated or republished the API identity") } }