97 lines
4.2 KiB
Go
97 lines
4.2 KiB
Go
package health
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"proxy-pool/internal/domain/activitypool"
|
|
healthDomain "proxy-pool/internal/domain/health"
|
|
)
|
|
|
|
func TestReducerRoutesObservationsToTheirIsolatedStores(t *testing.T) {
|
|
global := &recordingGlobalStore{}
|
|
target := &recordingTargetStore{}
|
|
var policyFacts []healthDomain.Observation
|
|
reducer, err := NewReducer(global, target, func(_ context.Context, observation healthDomain.Observation) (int, error) {
|
|
policyFacts = append(policyFacts, observation)
|
|
return 3, nil
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("NewReducer(): %v", err)
|
|
}
|
|
now := time.Date(2026, 7, 31, 13, 0, 0, 0, time.UTC)
|
|
globalResult, err := reducer.Apply(context.Background(), reducerObservation(healthDomain.LevelBasic, now))
|
|
if err != nil || globalResult.Global == nil || globalResult.Target != nil || len(global.commands) != 1 || len(target.commands) != 0 {
|
|
t.Fatalf("Apply(BASIC) = %+v, %v; global=%d target=%d", globalResult, err, len(global.commands), len(target.commands))
|
|
}
|
|
if global.commands[0].MaxConsecutiveFailures != 3 || global.commands[0].Observation.Level != healthDomain.LevelBasic {
|
|
t.Fatalf("global command = %+v", global.commands[0])
|
|
}
|
|
|
|
targetResult, err := reducer.Apply(context.Background(), reducerObservation(healthDomain.LevelTarget, now.Add(time.Second)))
|
|
if err != nil || targetResult.Global != nil || targetResult.Target == nil || len(global.commands) != 1 || len(target.commands) != 1 {
|
|
t.Fatalf("Apply(TARGET) = %+v, %v; global=%d target=%d", targetResult, err, len(global.commands), len(target.commands))
|
|
}
|
|
if target.commands[0].MaxConsecutiveFailures != 3 || target.commands[0].Observation.Level != healthDomain.LevelTarget {
|
|
t.Fatalf("target command = %+v", target.commands[0])
|
|
}
|
|
if len(policyFacts) != 2 || policyFacts[0].ObservedAt.Location() != time.UTC || policyFacts[1].RoutingName != "route-a" {
|
|
t.Fatalf("policy observations = %+v", policyFacts)
|
|
}
|
|
}
|
|
|
|
func TestReducerRejectsInvalidPolicyAndDoesNotCallStores(t *testing.T) {
|
|
global := &recordingGlobalStore{}
|
|
target := &recordingTargetStore{}
|
|
reducer, err := NewReducer(global, target, func(context.Context, healthDomain.Observation) (int, error) { return 0, nil })
|
|
if err != nil {
|
|
t.Fatalf("NewReducer(): %v", err)
|
|
}
|
|
if _, err := reducer.Apply(context.Background(), reducerObservation(healthDomain.LevelEgress, time.Now())); !errors.Is(err, ErrInvalidThreshold) {
|
|
t.Fatalf("Apply(zero threshold) error = %v, want ErrInvalidThreshold", err)
|
|
}
|
|
if len(global.commands) != 0 || len(target.commands) != 0 {
|
|
t.Fatalf("stores called with invalid policy: global=%d target=%d", len(global.commands), len(target.commands))
|
|
}
|
|
|
|
if reducer, err := NewReducer(nil, target, func(context.Context, healthDomain.Observation) (int, error) { return 1, nil }); err == nil || reducer != nil {
|
|
t.Fatalf("NewReducer(nil global) = (%v, %v)", reducer, err)
|
|
}
|
|
var typedNilGlobal *recordingGlobalStore
|
|
if reducer, err := NewReducer(typedNilGlobal, target, func(context.Context, healthDomain.Observation) (int, error) { return 1, nil }); err == nil || reducer != nil {
|
|
t.Fatalf("NewReducer(typed nil global) = (%v, %v)", reducer, err)
|
|
}
|
|
}
|
|
|
|
func reducerObservation(level healthDomain.Level, observedAt time.Time) healthDomain.Observation {
|
|
observation := healthDomain.Observation{
|
|
TaskID: "task-a", ProxyID: "proxy-a", Level: level, Success: true,
|
|
Latency: time.Millisecond, ObservedAt: observedAt,
|
|
}
|
|
if level == healthDomain.LevelTarget {
|
|
observation.RoutingName = "route-a"
|
|
observation.TargetURL = "https://target.example/check"
|
|
}
|
|
return observation
|
|
}
|
|
|
|
type recordingGlobalStore struct {
|
|
commands []activitypool.GlobalHealthCommand
|
|
}
|
|
|
|
func (store *recordingGlobalStore) ApplyGlobalObservation(_ context.Context, command activitypool.GlobalHealthCommand) (activitypool.Entry, error) {
|
|
store.commands = append(store.commands, command)
|
|
return activitypool.Entry{}, nil
|
|
}
|
|
|
|
type recordingTargetStore struct {
|
|
commands []activitypool.TargetHealthCommand
|
|
}
|
|
|
|
func (store *recordingTargetStore) ApplyTargetObservation(_ context.Context, command activitypool.TargetHealthCommand) (healthDomain.TargetState, error) {
|
|
store.commands = append(store.commands, command)
|
|
return healthDomain.TargetState{Status: healthDomain.TargetAvailable}, nil
|
|
}
|