layer1: add namespace manager model step 7
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
package utils
|
||||
|
||||
import "time"
|
||||
|
||||
type NamespacePhase string
|
||||
|
||||
const (
|
||||
NamespacePhaseDiscovered NamespacePhase = "discovered"
|
||||
NamespacePhaseRegistering NamespacePhase = "registering"
|
||||
NamespacePhaseActive NamespacePhase = "active"
|
||||
NamespacePhaseDeregistering NamespacePhase = "deregistering"
|
||||
NamespacePhaseRemoved NamespacePhase = "removed"
|
||||
NamespacePhaseFailed NamespacePhase = "failed"
|
||||
)
|
||||
|
||||
type NamespaceSource string
|
||||
|
||||
const (
|
||||
NamespaceSourceEnv NamespaceSource = "env"
|
||||
NamespaceSourceWatcher NamespaceSource = "watcher"
|
||||
NamespaceSourceBackfill NamespaceSource = "backfill"
|
||||
)
|
||||
|
||||
type NamespaceEventType string
|
||||
|
||||
const (
|
||||
NamespaceEventAdd NamespaceEventType = "add"
|
||||
NamespaceEventUpdate NamespaceEventType = "update"
|
||||
NamespaceEventRemove NamespaceEventType = "remove"
|
||||
NamespaceEventResync NamespaceEventType = "resync"
|
||||
)
|
||||
|
||||
type NamespacePartState struct {
|
||||
State string
|
||||
LastError string
|
||||
UpdatedAt time.Time
|
||||
}
|
||||
|
||||
type NamespaceRecord struct {
|
||||
Name string
|
||||
Source NamespaceSource
|
||||
Labels map[string]string
|
||||
Phase NamespacePhase
|
||||
LastError string
|
||||
Generation int64
|
||||
UpdatedAt time.Time
|
||||
RegisteredParts map[string]NamespacePartState
|
||||
}
|
||||
|
||||
type NamespaceEvent struct {
|
||||
Type NamespaceEventType
|
||||
Name string
|
||||
Labels map[string]string
|
||||
Source NamespaceSource
|
||||
ObservedAt time.Time
|
||||
}
|
||||
|
||||
func (nr NamespaceRecord) Clone() NamespaceRecord {
|
||||
clone := nr
|
||||
clone.Labels = cloneStringMap(nr.Labels)
|
||||
clone.RegisteredParts = cloneNamespacePartStates(nr.RegisteredParts)
|
||||
return clone
|
||||
}
|
||||
|
||||
func (nr NamespaceRecord) IsActive() bool {
|
||||
return nr.Phase == NamespacePhaseActive
|
||||
}
|
||||
|
||||
func (nr NamespaceRecord) IsTerminal() bool {
|
||||
return nr.Phase == NamespacePhaseRemoved || nr.Phase == NamespacePhaseFailed
|
||||
}
|
||||
|
||||
func cloneStringMap(input map[string]string) map[string]string {
|
||||
if input == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
clone := make(map[string]string, len(input))
|
||||
for key, value := range input {
|
||||
clone[key] = value
|
||||
}
|
||||
return clone
|
||||
}
|
||||
|
||||
func cloneNamespacePartStates(input map[string]NamespacePartState) map[string]NamespacePartState {
|
||||
if input == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
clone := make(map[string]NamespacePartState, len(input))
|
||||
for key, value := range input {
|
||||
clone[key] = value
|
||||
}
|
||||
return clone
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestNamespaceRecordClone(t *testing.T) {
|
||||
now := time.Now().UTC()
|
||||
record := NamespaceRecord{
|
||||
Name: "tenant-a",
|
||||
Source: NamespaceSourceWatcher,
|
||||
Phase: NamespacePhaseRegistering,
|
||||
Generation: 7,
|
||||
UpdatedAt: now,
|
||||
Labels: map[string]string{
|
||||
"fission.io/managed": "true",
|
||||
},
|
||||
RegisteredParts: map[string]NamespacePartState{
|
||||
"router": {
|
||||
State: "active",
|
||||
UpdatedAt: now,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
clone := record.Clone()
|
||||
clone.Labels["fission.io/managed"] = "false"
|
||||
clone.RegisteredParts["router"] = NamespacePartState{State: "failed", LastError: "boom"}
|
||||
|
||||
if record.Labels["fission.io/managed"] != "true" {
|
||||
t.Fatalf("expected labels to be deep copied")
|
||||
}
|
||||
|
||||
if record.RegisteredParts["router"].State != "active" {
|
||||
t.Fatalf("expected registered parts to be deep copied")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNamespaceRecordIsActive(t *testing.T) {
|
||||
record := NamespaceRecord{Phase: NamespacePhaseActive}
|
||||
if !record.IsActive() {
|
||||
t.Fatalf("expected active phase to be reported as active")
|
||||
}
|
||||
|
||||
record.Phase = NamespacePhaseRegistering
|
||||
if record.IsActive() {
|
||||
t.Fatalf("expected non-active phase to be reported as inactive")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNamespaceRecordIsTerminal(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
phase NamespacePhase
|
||||
expected bool
|
||||
}{
|
||||
{phase: NamespacePhaseRemoved, expected: true},
|
||||
{phase: NamespacePhaseFailed, expected: true},
|
||||
{phase: NamespacePhaseActive, expected: false},
|
||||
{phase: NamespacePhaseRegistering, expected: false},
|
||||
} {
|
||||
record := NamespaceRecord{Phase: test.phase}
|
||||
if record.IsTerminal() != test.expected {
|
||||
t.Fatalf("expected terminal=%v for phase %s", test.expected, test.phase)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user