feat: add UE4SS DLL runtime extension
This commit is contained in:
@@ -85,6 +85,65 @@ func TestCoreServiceServerLifecycleWorkflows(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoreServiceFreezesReadyDLLExtensionIntoWindowsStartJob(t *testing.T) {
|
||||
svc, sessionToken := newLifecycleRunService(t)
|
||||
setLifecycleEndpointTarget(t, svc, "windows", "amd64")
|
||||
plugin := createLifecyclePlugin(t, svc)
|
||||
attachReadyLifecycleDLLExtension(t, svc, &plugin)
|
||||
|
||||
created, err := svc.CreateServerInstanceWorkflow(domain.ServerLifecycleCreate{ID: "server-dll", PluginID: plugin.ID, RunEndpointID: "run-local", Name: "SCUM DLL", IdempotencyKey: "idem-dll-create", ProfileKey: "local"})
|
||||
if err != nil {
|
||||
t.Fatalf("create DLL lifecycle server: %v", err)
|
||||
}
|
||||
claimAndCompleteLifecycleJobForServer(t, svc, sessionToken, created.Instance.ID, domain.LifecycleCapabilityInstall, domain.JobStateSucceeded)
|
||||
ready, err := svc.GetServerInstance(created.Instance.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("get ready DLL server: %v", err)
|
||||
}
|
||||
|
||||
started, err := svc.StartServerInstance(domain.ServerLifecycleCommand{ServerInstanceID: ready.ID, ExpectedConfigVersion: ready.ConfigVersion, IdempotencyKey: "idem-dll-start"})
|
||||
if err != nil {
|
||||
t.Fatalf("start DLL lifecycle server: %v", err)
|
||||
}
|
||||
if len(started.Job.ExecutionInput.DLLExtensions) != 1 {
|
||||
t.Fatalf("expected one frozen DLL plan, got %+v", started.Job.ExecutionInput)
|
||||
}
|
||||
if got := started.Job.ExecutionInput.DLLExtensions[0]; got.Key != "scum-simple-rcon" || got.Checksum != "sha256:"+strings.Repeat("a", 64) || got.ReleaseURL != "https://cdn.npc0.com/scum_simple_rcon_ue4s.dll" {
|
||||
t.Fatalf("unexpected frozen DLL plan: %+v", got)
|
||||
}
|
||||
|
||||
plugin.RuntimeProfiles.DLLExtensions[0].Checksum = "sha256:" + strings.Repeat("c", 64)
|
||||
if err := svc.store.GamePlugins().Update(plugin); err != nil {
|
||||
t.Fatalf("update plugin after start fence: %v", err)
|
||||
}
|
||||
claim, err := svc.ClaimRunJob(domain.RunJobClaim{RunEndpointID: "run-local", SessionToken: sessionToken, Capabilities: []string{domain.LifecycleCapabilityStart}, Capacity: domain.RunCapacity{MaxJobs: 1}})
|
||||
if err != nil || !claim.HasJob || len(claim.Job.ExecutionInput.DLLExtensions) != 1 {
|
||||
t.Fatalf("claim frozen start job: claim=%+v err=%v", claim, err)
|
||||
}
|
||||
if got := claim.Job.ExecutionInput.DLLExtensions[0].Checksum; got != "sha256:"+strings.Repeat("a", 64) {
|
||||
t.Fatalf("queued start job was not fenced to the original DLL pin: %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoreServiceRejectsLinuxDLLExtensionStartBeforeDispatch(t *testing.T) {
|
||||
svc, sessionToken := newLifecycleRunService(t)
|
||||
setLifecycleEndpointTarget(t, svc, "windows", "amd64")
|
||||
plugin := createLifecyclePlugin(t, svc)
|
||||
attachReadyLifecycleDLLExtension(t, svc, &plugin)
|
||||
created, err := svc.CreateServerInstanceWorkflow(domain.ServerLifecycleCreate{ID: "server-dll-linux", PluginID: plugin.ID, RunEndpointID: "run-local", Name: "SCUM DLL Linux", IdempotencyKey: "idem-dll-linux-create", ProfileKey: "local"})
|
||||
if err != nil {
|
||||
t.Fatalf("create DLL lifecycle server: %v", err)
|
||||
}
|
||||
claimAndCompleteLifecycleJobForServer(t, svc, sessionToken, created.Instance.ID, domain.LifecycleCapabilityInstall, domain.JobStateSucceeded)
|
||||
ready, _ := svc.GetServerInstance(created.Instance.ID)
|
||||
setLifecycleEndpointTarget(t, svc, "linux", "amd64")
|
||||
|
||||
_, err = svc.StartServerInstance(domain.ServerLifecycleCommand{ServerInstanceID: ready.ID, ExpectedConfigVersion: ready.ConfigVersion, IdempotencyKey: "idem-dll-linux-start"})
|
||||
if err == nil || !strings.Contains(err.Error(), "unsupported_extension_platform") {
|
||||
t.Fatalf("expected explicit Linux DLL rejection, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCoreServiceServerLifecycleRejectsInvalidCommands(t *testing.T) {
|
||||
svc := newTestCoreService()
|
||||
plugin, endpoint := createPluginAndRunEndpoint(t, svc)
|
||||
@@ -272,6 +331,34 @@ func createLifecyclePlugin(t *testing.T, svc *CoreService) domain.GamePlugin {
|
||||
return plugin
|
||||
}
|
||||
|
||||
func attachReadyLifecycleDLLExtension(t *testing.T, svc *CoreService, plugin *domain.GamePlugin) {
|
||||
t.Helper()
|
||||
plugin.RuntimeProfiles.LifecycleProfiles[0].Platforms = []string{"windows"}
|
||||
plugin.RuntimeProfiles.LifecycleProfiles[0].DLLExtensionRefs = []string{"scum-simple-rcon"}
|
||||
plugin.RuntimeProfiles.DLLExtensions = []domain.RuntimeDLLExtensionProfile{{
|
||||
Key: "scum-simple-rcon", DisplayName: "SCUM Simple RCON", Kind: "ue4ss-dll", Activation: "server-start", Version: "0.1.0", ReleaseState: "ready",
|
||||
ReleaseURL: "https://cdn.npc0.com/scum_simple_rcon_ue4s.dll", Checksum: "sha256:" + strings.Repeat("a", 64), SizeBytes: 1024,
|
||||
TargetKey: "ue4ss/scum-simple-rcon", ModKey: "scum_simple_rcon", DLLRef: "ue4ss/Mods/scum_simple_rcon/dlls/main.dll",
|
||||
SCUMExecutableChecksum: "sha256:" + strings.Repeat("b", 64), UE4SSABI: "ue4ss-3.0", SupportedTargets: []domain.RuntimeTarget{{OS: "windows", Arch: "amd64"}}, UpdateOnStart: true, RCONPort: 27015,
|
||||
}}
|
||||
if err := svc.store.GamePlugins().Update(*plugin); err != nil {
|
||||
t.Fatalf("attach ready DLL extension: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func setLifecycleEndpointTarget(t *testing.T, svc *CoreService, platform string, architecture string) {
|
||||
t.Helper()
|
||||
endpoint, err := svc.store.RunEndpoints().Get("run-local")
|
||||
if err != nil {
|
||||
t.Fatalf("get lifecycle endpoint: %v", err)
|
||||
}
|
||||
endpoint.Platform = platform
|
||||
endpoint.Architecture = architecture
|
||||
if err := svc.store.RunEndpoints().Update(endpoint); err != nil {
|
||||
t.Fatalf("set lifecycle endpoint target: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func claimAndCompleteLifecycleJob(t *testing.T, svc *CoreService, sessionToken string, capability string, state domain.JobState) {
|
||||
t.Helper()
|
||||
claimAndCompleteLifecycleJobForServer(t, svc, sessionToken, "", capability, state)
|
||||
|
||||
Reference in New Issue
Block a user