功能修改
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
package validator
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"browser.local/platform/domain"
|
||||
)
|
||||
|
||||
func validGameClientBridgeCompanionManifest() (domain.GameClientBridgeManifest, domain.GamePluginRuntimeProfiles) {
|
||||
bridge := domain.GameClientBridgeManifest{
|
||||
Retention: domain.GameClientBridgeRetention{KeepForSeconds: 86400, MaxRecords: 1000},
|
||||
Companion: domain.GameClientBridgeCompanionDeclaration{
|
||||
ProfileKey: "scum-client-manager",
|
||||
ConfigTemplateKey: "client-config",
|
||||
ConfigSchemaRef: "schemas/companion/config.schema.json",
|
||||
ConfigFormat: "yaml",
|
||||
PlatformBaseURLSource: "run-control",
|
||||
RegistrationProof: "hmac-sha256",
|
||||
ProofMaterialSource: "component-package",
|
||||
ProofMaterialEnv: "SCUM_COMPONENT_PROOF",
|
||||
SessionMode: "component-session",
|
||||
TLSPolicy: "verify-system-roots",
|
||||
HeartbeatIntervalSeconds: 30,
|
||||
CommandPollIntervalSeconds: 5,
|
||||
RequestTimeoutSeconds: 15,
|
||||
},
|
||||
}
|
||||
profiles := domain.GamePluginRuntimeProfiles{ClientManagers: []domain.RuntimeClientManagerProfile{{
|
||||
Key: "scum-client-manager",
|
||||
ConfigTemplates: []domain.RuntimeConfigTemplate{{Key: "client-config", TemplateRef: "config.yaml.example", OutputRef: "config.yaml"}},
|
||||
Health: domain.RuntimeClientManagerHealth{IntervalSeconds: 30, RequiredCapabilities: []string{"component.register", "component.heartbeat", "component.health", "game-client.bridge"}},
|
||||
}}}
|
||||
return bridge, profiles
|
||||
}
|
||||
|
||||
func TestValidateGameClientBridgeCompanionDeclaration(t *testing.T) {
|
||||
bridge, profiles := validGameClientBridgeCompanionManifest()
|
||||
if violations := validateGameClientBridgeManifest("gameClientBridge", bridge, nil, nil, profiles); len(violations) != 0 {
|
||||
t.Fatalf("expected valid companion declaration, got %v", violations)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
expected string
|
||||
mutate func(*domain.GameClientBridgeManifest, *domain.GamePluginRuntimeProfiles)
|
||||
}{
|
||||
{name: "undeclared profile", expected: "profileKey must reference", mutate: func(bridge *domain.GameClientBridgeManifest, _ *domain.GamePluginRuntimeProfiles) {
|
||||
bridge.Companion.ProfileKey = "missing"
|
||||
}},
|
||||
{name: "undeclared template", expected: "configTemplateKey must reference", mutate: func(bridge *domain.GameClientBridgeManifest, _ *domain.GamePluginRuntimeProfiles) {
|
||||
bridge.Companion.ConfigTemplateKey = "missing"
|
||||
}},
|
||||
{name: "unsafe schema", expected: "configSchemaRef", mutate: func(bridge *domain.GameClientBridgeManifest, _ *domain.GamePluginRuntimeProfiles) {
|
||||
bridge.Companion.ConfigSchemaRef = "/etc/config.json"
|
||||
}},
|
||||
{name: "insecure tls", expected: "security policy", mutate: func(bridge *domain.GameClientBridgeManifest, _ *domain.GamePluginRuntimeProfiles) {
|
||||
bridge.Companion.TLSPolicy = "skip-verification"
|
||||
}},
|
||||
{name: "heartbeat mismatch", expected: "must match", mutate: func(bridge *domain.GameClientBridgeManifest, _ *domain.GamePluginRuntimeProfiles) {
|
||||
bridge.Companion.HeartbeatIntervalSeconds = 31
|
||||
}},
|
||||
{name: "missing bridge capability", expected: "game-client.bridge", mutate: func(_ *domain.GameClientBridgeManifest, profiles *domain.GamePluginRuntimeProfiles) {
|
||||
profiles.ClientManagers[0].Health.RequiredCapabilities = []string{"component.register", "component.heartbeat", "component.health"}
|
||||
}},
|
||||
{name: "partial declaration", expected: "profile or config template key", mutate: func(bridge *domain.GameClientBridgeManifest, _ *domain.GamePluginRuntimeProfiles) {
|
||||
bridge.Companion.ProfileKey = ""
|
||||
}},
|
||||
{name: "reserved proof environment", expected: "proofMaterialEnv", mutate: func(bridge *domain.GameClientBridgeManifest, _ *domain.GamePluginRuntimeProfiles) {
|
||||
bridge.Companion.ProofMaterialEnv = "LD_PRELOAD"
|
||||
}},
|
||||
}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
candidateBridge, candidateProfiles := validGameClientBridgeCompanionManifest()
|
||||
test.mutate(&candidateBridge, &candidateProfiles)
|
||||
violations := validateGameClientBridgeManifest("gameClientBridge", candidateBridge, nil, nil, candidateProfiles)
|
||||
if !strings.Contains(strings.Join(violations, "; "), test.expected) {
|
||||
t.Fatalf("expected %q violation, got %v", test.expected, violations)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateClientManagerCompanionConfigInputFailsClosed(t *testing.T) {
|
||||
valid := domain.ClientManagerCompanionConfigInput{
|
||||
SchemaVersion: domain.ClientManagerCompanionConfigSchemaVersion,
|
||||
ConfigTemplateKey: "client-config",
|
||||
ConfigTemplateRef: "config.yaml.example",
|
||||
ConfigOutputRef: "config.yaml",
|
||||
ConfigSchemaRef: "schemas/companion/config.schema.json",
|
||||
ConfigFormat: "yaml",
|
||||
PlatformBaseURLSource: "run-control",
|
||||
InstallationID: "installation-1",
|
||||
ServerInstanceID: "server-1",
|
||||
PluginID: "game.scum",
|
||||
ProfileKey: "scum-client-manager",
|
||||
ArtifactID: "artifact-1",
|
||||
Version: "1.0.0",
|
||||
SourceRevision: "revision-1",
|
||||
TargetOS: "windows",
|
||||
TargetArch: "amd64",
|
||||
KeyGeneration: 1,
|
||||
DeploymentGeneration: 2,
|
||||
Capabilities: []string{"component.register", "component.heartbeat", "component.health", "game-client.bridge"},
|
||||
RegistrationProof: "hmac-sha256",
|
||||
ProofMaterialSource: "component-package",
|
||||
ProofMaterialEnv: "SCUM_COMPONENT_PROOF",
|
||||
SessionMode: "component-session",
|
||||
TLSPolicy: "verify-system-roots",
|
||||
HeartbeatIntervalSeconds: 30,
|
||||
CommandPollIntervalSeconds: 5,
|
||||
RequestTimeoutSeconds: 15,
|
||||
}
|
||||
if err := ValidateClientManagerCompanionConfigInput(valid); err != nil {
|
||||
t.Fatalf("expected valid companion input, got %v", err)
|
||||
}
|
||||
for name, mutate := range map[string]func(*domain.ClientManagerCompanionConfigInput){
|
||||
"insecure tls": func(value *domain.ClientManagerCompanionConfigInput) { value.TLSPolicy = "skip-verification" },
|
||||
"legacy session": func(value *domain.ClientManagerCompanionConfigInput) { value.SessionMode = "shared-token" },
|
||||
"reserved env": func(value *domain.ClientManagerCompanionConfigInput) { value.ProofMaterialEnv = "PATH" },
|
||||
"unsafe template": func(value *domain.ClientManagerCompanionConfigInput) { value.ConfigTemplateRef = "../config.yaml" },
|
||||
} {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
candidate := domain.CopyClientManagerCompanionConfigInput(valid)
|
||||
mutate(&candidate)
|
||||
if err := ValidateClientManagerCompanionConfigInput(candidate); err == nil {
|
||||
t.Fatalf("expected invalid companion input: %+v", candidate)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user