Files
Amirhossein Khalili 5673b60ba6 feat: add idempotent calendar bootstrap
Bootstrap independently reviewed catalogs through audited import, approval, and initial activation transitions, then resume insight scheduling safely.
2026-08-23 02:24:16 +08:00

157 lines
5.3 KiB
Go

package eventcatalog
import (
"context"
"errors"
"reflect"
"testing"
)
func TestBootstrapCatalogTransitionsToActive(t *testing.T) {
t.Parallel()
store := &bootstrapStoreFake{}
createdJobs := 7
result, err := BootstrapCatalog(t.Context(), store, validCoveredImport(), 1405, "reviewer", "operator", func(context.Context) (int, error) {
return createdJobs, nil
})
if err != nil {
t.Fatal(err)
}
if want := []string{"IMPORTED", "APPROVED", "ACTIVATED"}; !reflect.DeepEqual(result.Transitions, want) {
t.Fatalf("transitions=%v, want %v", result.Transitions, want)
}
if result.Status != CatalogStatusActive || result.NoOp || result.CreatedJobs != createdJobs {
t.Fatalf("result=%+v", result)
}
}
func TestBootstrapCatalogResumesAndNoOps(t *testing.T) {
t.Parallel()
tests := []struct {
name string
status CatalogStatus
transitions []string
}{
{name: "draft", status: CatalogStatusDraft, transitions: []string{"APPROVED", "ACTIVATED"}},
{name: "approved", status: CatalogStatusApproved, transitions: []string{"ACTIVATED"}},
{name: "active", status: CatalogStatusActive},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
input := validCoveredImport()
store := &bootstrapStoreFake{state: stateFromImport(input, test.status), active: stateFromImport(input, CatalogStatusActive)}
if test.status != CatalogStatusActive {
store.active = CatalogState{}
}
result, err := BootstrapCatalog(t.Context(), store, input, 1405, "reviewer", "operator", func(context.Context) (int, error) { return 0, nil })
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(result.Transitions, test.transitions) {
t.Fatalf("transitions=%v, want %v", result.Transitions, test.transitions)
}
if result.NoOp != (test.status == CatalogStatusActive) {
t.Fatalf("no_op=%t", result.NoOp)
}
})
}
}
func TestBootstrapCatalogFailsClosed(t *testing.T) {
t.Parallel()
input := validCoveredImport()
tests := []struct {
name string
state CatalogState
active CatalogState
mutate func(*Import)
}{
{name: "retired version", state: stateFromImport(input, CatalogStatusRetired)},
{name: "different active version", active: CatalogState{Version: "newer", Status: CatalogStatusActive}},
{name: "checksum mismatch", state: stateFromImport(input, CatalogStatusDraft), mutate: func(input *Import) { input.SourceChecksum = "different" }},
{name: "metadata mismatch", state: stateFromImport(input, CatalogStatusDraft), mutate: func(input *Import) { input.SourceVersion = "different" }},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
t.Parallel()
candidate := input
if test.mutate != nil {
test.mutate(&candidate)
}
store := &bootstrapStoreFake{state: test.state, active: test.active}
_, err := BootstrapCatalog(t.Context(), store, candidate, 1405, "reviewer", "operator", func(context.Context) (int, error) { return 0, nil })
if !errors.Is(err, ErrCatalogConflict) {
t.Fatalf("error=%v, want ErrCatalogConflict", err)
}
if len(store.transitions) != 0 {
t.Fatalf("unexpected transitions=%v", store.transitions)
}
})
}
}
func TestBootstrapCatalogRejectsInvalidReviewAndRetriesScheduling(t *testing.T) {
t.Parallel()
input := validCoveredImport()
input.SourceChecksum = "review-required-before-activation"
store := &bootstrapStoreFake{}
if _, err := BootstrapCatalog(t.Context(), store, input, 1405, "reviewer", "operator", func(context.Context) (int, error) { return 0, nil }); err == nil {
t.Fatal("expected placeholder checksum error")
}
input = validCoveredImport()
store = &bootstrapStoreFake{state: stateFromImport(input, CatalogStatusActive), active: stateFromImport(input, CatalogStatusActive)}
wantErr := errors.New("scheduling failed")
if _, err := BootstrapCatalog(t.Context(), store, input, 1405, "reviewer", "operator", func(context.Context) (int, error) { return 0, wantErr }); !errors.Is(err, wantErr) {
t.Fatalf("error=%v, want scheduling error", err)
}
result, err := BootstrapCatalog(t.Context(), store, input, 1405, "reviewer", "operator", func(context.Context) (int, error) { return 2, nil })
if err != nil || result.CreatedJobs != 2 || result.NoOp {
t.Fatalf("result=%+v error=%v", result, err)
}
}
type bootstrapStoreFake struct {
state CatalogState
active CatalogState
transitions []string
}
func (f *bootstrapStoreFake) CatalogState(context.Context, string) (CatalogState, error) {
if f.state.Version == "" {
return CatalogState{}, ErrCatalogNotFound
}
return f.state, nil
}
func (f *bootstrapStoreFake) ActiveCatalogState(context.Context) (CatalogState, error) {
if f.active.Version == "" {
return CatalogState{}, ErrCatalogNotFound
}
return f.active, nil
}
func (f *bootstrapStoreFake) ImportDraft(_ context.Context, input Import) error {
f.state = stateFromImport(input, CatalogStatusDraft)
f.transitions = append(f.transitions, "IMPORTED")
return nil
}
func (f *bootstrapStoreFake) Approve(_ context.Context, _ string, _ string) error {
f.state.Status = CatalogStatusApproved
f.transitions = append(f.transitions, "APPROVED")
return nil
}
func (f *bootstrapStoreFake) ActivateInitial(_ context.Context, _ string, _ string) error {
f.state.Status = CatalogStatusActive
f.active = f.state
f.transitions = append(f.transitions, "ACTIVATED")
return nil
}