102 lines
3.2 KiB
Go
102 lines
3.2 KiB
Go
package provider
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"proxy-pool/internal/controller/pool"
|
|
"proxy-pool/internal/domain/activitypool"
|
|
proxyDomain "proxy-pool/internal/domain/proxy"
|
|
)
|
|
|
|
func TestFleetRunsAllUpstreamsAndCancelsSiblingsOnFailure(t *testing.T) {
|
|
started := make(chan string, 2)
|
|
siblingCancelled := make(chan struct{}, 1)
|
|
first := newFleetRuntime(t, "provider-a", coordinatorFunc(func(
|
|
context.Context, string, CoordinationLimits, func(context.Context, LeaderSession) error,
|
|
) error {
|
|
started <- "provider-a"
|
|
return errors.New("provider-a stopped")
|
|
}))
|
|
second := newFleetRuntime(t, "provider-b", coordinatorFunc(func(
|
|
ctx context.Context, _ string, _ CoordinationLimits, _ func(context.Context, LeaderSession) error,
|
|
) error {
|
|
started <- "provider-b"
|
|
<-ctx.Done()
|
|
siblingCancelled <- struct{}{}
|
|
return ctx.Err()
|
|
}))
|
|
fleet, err := NewFleet(first, second)
|
|
if err != nil {
|
|
t.Fatalf("NewFleet(): %v", err)
|
|
}
|
|
|
|
err = fleet.Run(context.Background())
|
|
if err == nil || err.Error() != "provider-a stopped" {
|
|
t.Fatalf("Run() error = %v, want provider-a failure", err)
|
|
}
|
|
seen := map[string]bool{<-started: true, <-started: true}
|
|
if !seen["provider-a"] || !seen["provider-b"] {
|
|
t.Fatalf("started upstreams = %v", seen)
|
|
}
|
|
select {
|
|
case <-siblingCancelled:
|
|
case <-time.After(time.Second):
|
|
t.Fatal("sibling runtime was not cancelled")
|
|
}
|
|
}
|
|
|
|
func TestNewFleetRejectsEmptyNilAndDuplicateUpstreams(t *testing.T) {
|
|
valid := newFleetRuntime(t, "provider-a", coordinatorFunc(func(
|
|
ctx context.Context, _ string, _ CoordinationLimits, _ func(context.Context, LeaderSession) error,
|
|
) error {
|
|
return ctx.Err()
|
|
}))
|
|
tests := []struct {
|
|
name string
|
|
runtimes []*UpstreamRuntime
|
|
}{
|
|
{name: "empty"},
|
|
{name: "nil", runtimes: []*UpstreamRuntime{nil}},
|
|
{name: "duplicate", runtimes: []*UpstreamRuntime{valid, valid}},
|
|
}
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
fleet, err := NewFleet(test.runtimes...)
|
|
if err == nil || fleet != nil {
|
|
t.Fatalf("NewFleet() = (%v, %v), want invalid fleet", fleet, err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func newFleetRuntime(t *testing.T, upstreamID string, coordinator Coordinator) *UpstreamRuntime {
|
|
t.Helper()
|
|
runtime, err := NewUpstreamRuntime(UpstreamRuntimeConfig{
|
|
Provider: runtimeProviderConfig(upstreamID),
|
|
ReconcilePolicy: runtimeReconcilePolicy(),
|
|
ReconcileInterval: time.Second,
|
|
}, UpstreamRuntimeDependencies{
|
|
Coordinator: coordinator,
|
|
Inventory: inventoryReaderFunc(func(context.Context, string, time.Duration) (pool.InventorySnapshot, error) {
|
|
return pool.InventorySnapshot{}, nil
|
|
}),
|
|
Adapter: adapterFunc(func(context.Context) (FetchResponse, error) {
|
|
return FetchResponse{Body: []byte("fixture")}, nil
|
|
}),
|
|
Parser: parserFunc(func(context.Context, []byte) ([]proxyDomain.Proxy, error) {
|
|
return []proxyDomain.Proxy{{ID: "proxy-1"}}, nil
|
|
}),
|
|
Activity: activitySinkFunc(func(context.Context, string, activitypool.FetchedBatch) (activitypool.UpsertResult, error) {
|
|
return activitypool.UpsertResult{Accepted: 1, Inserted: 1}, nil
|
|
}),
|
|
Results: resultRecorderFunc(func(Result) {}),
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("NewUpstreamRuntime(%s): %v", upstreamID, err)
|
|
}
|
|
return runtime
|
|
}
|