Bootstrap independently reviewed catalogs through audited import, approval, and initial activation transitions, then resume insight scheduling safely.
157 lines
5.3 KiB
Go
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
|
|
}
|