test(scum): cover supported companion adapters
This commit is contained in:
@@ -2,6 +2,7 @@ package companion
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -20,6 +21,11 @@ type SafeAdapter interface {
|
||||
SpawnVehicle(context.Context, map[string]any) (map[string]any, error)
|
||||
}
|
||||
|
||||
// ServerBoundAdapter lets a versioned adapter prove that it is configured for
|
||||
// the same server as the registration which declared handler availability.
|
||||
// Generic test adapters do not need this optional assertion.
|
||||
type ServerBoundAdapter interface{ ServerBinding() string }
|
||||
|
||||
type HandlerAvailability struct {
|
||||
BoundServerID string
|
||||
ServerVersion string
|
||||
@@ -28,10 +34,11 @@ type HandlerAvailability struct {
|
||||
}
|
||||
type CommandHandler func(context.Context, map[string]any) (map[string]any, error)
|
||||
type HandlerRegistry struct {
|
||||
availability HandlerAvailability
|
||||
handlers map[string]CommandHandler
|
||||
mu sync.Mutex
|
||||
completed map[string]CommandResult
|
||||
availability HandlerAvailability
|
||||
handlers map[string]CommandHandler
|
||||
adapterServer string
|
||||
mu sync.Mutex
|
||||
completed map[string]CommandResult
|
||||
}
|
||||
|
||||
func NewHandlerRegistry(availability HandlerAvailability, adapter SafeAdapter) *HandlerRegistry {
|
||||
@@ -39,6 +46,9 @@ func NewHandlerRegistry(availability HandlerAvailability, adapter SafeAdapter) *
|
||||
if adapter == nil {
|
||||
return registry
|
||||
}
|
||||
if bound, ok := adapter.(ServerBoundAdapter); ok {
|
||||
registry.adapterServer = bound.ServerBinding()
|
||||
}
|
||||
registry.handlers["config.read"] = func(ctx context.Context, _ map[string]any) (map[string]any, error) {
|
||||
return adapter.ReadConfiguration(ctx)
|
||||
}
|
||||
@@ -71,7 +81,7 @@ func (registry *HandlerRegistry) Execute(ctx context.Context, command ClaimedCom
|
||||
if err := validateDeclaredCommandAt(command, time.Now); err != nil {
|
||||
return unsupportedResult("validation-failed"), nil
|
||||
}
|
||||
if strings.TrimSpace(registry.availability.BoundServerID) == "" || !registry.availability.Approved || !registry.availability.Capabilities[command.CommandType] {
|
||||
if strings.TrimSpace(registry.availability.BoundServerID) == "" || !registry.adapterBindingMatches() || !registry.availability.Approved || !registry.availability.Capabilities[command.CommandType] {
|
||||
return unsupportedResult("unsupported"), nil
|
||||
}
|
||||
handler, exists := registry.handlers[command.CommandType]
|
||||
@@ -80,6 +90,9 @@ func (registry *HandlerRegistry) Execute(ctx context.Context, command ClaimedCom
|
||||
}
|
||||
payload, err := handler(ctx, command.Payload)
|
||||
if err != nil {
|
||||
if errors.Is(err, errAdapterUnsupported) {
|
||||
return unsupportedResult("unsupported"), nil
|
||||
}
|
||||
return CommandResult{Status: "failed", Summary: "typed adapter failed", Payload: map[string]any{"result": "failed"}}, nil
|
||||
}
|
||||
result := CommandResult{Status: "succeeded", Summary: "typed adapter completed", Payload: redactTypedPayload(payload)}
|
||||
@@ -89,6 +102,10 @@ func (registry *HandlerRegistry) Execute(ctx context.Context, command ClaimedCom
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (registry *HandlerRegistry) adapterBindingMatches() bool {
|
||||
return registry.adapterServer == "" || registry.adapterServer == registry.availability.BoundServerID
|
||||
}
|
||||
|
||||
func validateDeclaredCommandAt(command ClaimedCommand, now func() time.Time) error {
|
||||
if command.ID == "" || command.ProfileKey != ProfileKey || command.FencingToken == 0 || command.Payload == nil || command.LeaseExpiresAt.IsZero() || command.ExpiresAt.IsZero() || !now().Before(command.LeaseExpiresAt) || !now().Before(command.ExpiresAt) {
|
||||
return fmt.Errorf("invalid command")
|
||||
|
||||
Reference in New Issue
Block a user