feat: add idempotent calendar bootstrap
Bootstrap independently reviewed catalogs through audited import, approval, and initial activation transitions, then resume insight scheduling safely.
This commit is contained in:
156
internal/eventcatalog/bootstrap_test.go
Normal file
156
internal/eventcatalog/bootstrap_test.go
Normal file
@@ -0,0 +1,156 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user