fix(scheduler): убрать двойной SaveCheckRun (Checker персистит), SetDrift через CountDriftDomains, resolved после error
This commit is contained in:
@@ -24,8 +24,11 @@ type mockStore struct {
|
||||
domains map[uuid.UUID][]store.Domain
|
||||
status map[uuid.UUID]string
|
||||
|
||||
savedCheckRuns []uuid.UUID
|
||||
touchedProjects []uuid.UUID
|
||||
|
||||
// driftCount is what CountDriftDomains returns — a canned system-wide
|
||||
// count, independent of what this RunOnce's due projects touched.
|
||||
driftCount int
|
||||
}
|
||||
|
||||
func newMockStore() *mockStore {
|
||||
@@ -66,11 +69,10 @@ func (m *mockStore) SetDomainStatus(ctx context.Context, domainID uuid.UUID, sta
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *mockStore) SaveCheckRun(ctx context.Context, domainID uuid.UUID, cs diff.Changeset) error {
|
||||
func (m *mockStore) CountDriftDomains(ctx context.Context) (int, error) {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
m.savedCheckRuns = append(m.savedCheckRuns, domainID)
|
||||
return nil
|
||||
return m.driftCount, nil
|
||||
}
|
||||
|
||||
// mockChecker returns a preset Changeset or error per domainID.
|
||||
@@ -127,6 +129,12 @@ func TestRunOnce_NotifiesOnDriftNotOnFirstInSync(t *testing.T) {
|
||||
notifier := &mockNotifier{}
|
||||
m := metrics.New()
|
||||
|
||||
// CountDriftDomains is the real system-wide count, independent of what
|
||||
// this tick touched — set it to something that would NOT match a local
|
||||
// per-tick accumulator (only 1 of 2 domains here drifted) to prove the
|
||||
// gauge comes from the store call, not a local tally.
|
||||
st.driftCount = 7
|
||||
|
||||
sched := New(st, checker, notifier, m)
|
||||
|
||||
if err := sched.RunOnce(context.Background(), time.Now()); err != nil {
|
||||
@@ -150,9 +158,6 @@ func TestRunOnce_NotifiesOnDriftNotOnFirstInSync(t *testing.T) {
|
||||
t.Fatalf("notified status = %q, want drift", notifier.events[0].Status)
|
||||
}
|
||||
|
||||
if len(st.savedCheckRuns) != 2 {
|
||||
t.Fatalf("SaveCheckRun calls = %d, want 2", len(st.savedCheckRuns))
|
||||
}
|
||||
if len(st.touchedProjects) != 1 || st.touchedProjects[0] != projectID {
|
||||
t.Fatalf("TouchScheduleRun calls = %v, want [%s]", st.touchedProjects, projectID)
|
||||
}
|
||||
@@ -163,8 +168,8 @@ func TestRunOnce_NotifiesOnDriftNotOnFirstInSync(t *testing.T) {
|
||||
if got := testutil.ToFloat64(m.ChecksTotal.WithLabelValues(StatusInSync)); got != 1 {
|
||||
t.Fatalf("ChecksTotal{in_sync} = %v, want 1", got)
|
||||
}
|
||||
if got := testutil.ToFloat64(m.DriftDomains); got != 1 {
|
||||
t.Fatalf("DriftDomains gauge = %v, want 1", got)
|
||||
if got := testutil.ToFloat64(m.DriftDomains); got != float64(st.driftCount) {
|
||||
t.Fatalf("DriftDomains gauge = %v, want %d (from CountDriftDomains)", got, st.driftCount)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,10 +234,6 @@ func TestRunOnce_CheckError_StatusErrorAndNotify(t *testing.T) {
|
||||
if got := testutil.ToFloat64(m.ChecksTotal.WithLabelValues(StatusError)); got != 1 {
|
||||
t.Fatalf("ChecksTotal{error} = %v, want 1", got)
|
||||
}
|
||||
// A failed Check has no changeset worth recording.
|
||||
if len(st.savedCheckRuns) != 0 {
|
||||
t.Fatalf("SaveCheckRun calls on error = %d, want 0", len(st.savedCheckRuns))
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldNotify(t *testing.T) {
|
||||
@@ -252,7 +253,7 @@ func TestShouldNotify(t *testing.T) {
|
||||
{"in_sync->error notifies", StatusInSync, StatusError, true},
|
||||
{"in_sync->in_sync is silent", StatusInSync, StatusInSync, false},
|
||||
{"error->drift notifies (still bad, different bad)", StatusError, StatusDrift, true},
|
||||
{"error->in_sync is not the 'resolved' case, per spec", StatusError, StatusInSync, false},
|
||||
{"error->in_sync notifies (resolved after failure)", StatusError, StatusInSync, true},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
|
||||
Reference in New Issue
Block a user