Fix run log ingest and terminal console layout

This commit is contained in:
npc0-hue
2026-08-03 12:49:46 +08:00
parent 1d5fb586d0
commit a1bf3aa86a
15 changed files with 390 additions and 34 deletions
+109 -2
View File
@@ -114,6 +114,10 @@ func TestCoreServiceCreateListGetWorkflows(t *testing.T) {
if _, err := svc.GetJob(job.ID); err != nil {
t.Fatalf("get job: %v", err)
}
streams, err := svc.ListLogStreams(domain.LogStreamFilter{ServerInstanceID: instance.ID})
if err != nil || len(streams) != 2 {
t.Fatalf("expected default job stdout/stderr streams, len=%d err=%v streams=%+v", len(streams), err, streams)
}
jobs, err := svc.ListJobs(domain.JobFilter{RunEndpointID: endpoint.ID})
if err != nil || len(jobs) != 1 {
t.Fatalf("list jobs: len=%d err=%v", len(jobs), err)
@@ -154,8 +158,8 @@ func TestCoreServiceCreateListGetWorkflows(t *testing.T) {
if _, err := svc.GetLogStream(stream.ID); err != nil {
t.Fatalf("get log stream: %v", err)
}
streams, err := svc.ListLogStreams(domain.LogStreamFilter{ServerInstanceID: instance.ID})
if err != nil || len(streams) != 1 {
streams, err = svc.ListLogStreams(domain.LogStreamFilter{ServerInstanceID: instance.ID})
if err != nil || len(streams) != 3 {
t.Fatalf("list log streams: len=%d err=%v", len(streams), err)
}
@@ -183,6 +187,109 @@ func TestCoreServiceCreateListGetWorkflows(t *testing.T) {
}
}
func TestCoreServiceCreateRemoteProgramJobCreatesManagementLogStreams(t *testing.T) {
svc := newTestCoreService()
plugin, endpoint := createPluginAndRunEndpoint(t, svc)
plugin.RequiredRunCapabilities = append(plugin.RequiredRunCapabilities, domain.JobCapabilityRemoteRunProgram)
if err := svc.store.GamePlugins().Update(plugin); err != nil {
t.Fatalf("update plugin capabilities: %v", err)
}
endpoint.Capabilities = append(endpoint.Capabilities, domain.JobCapabilityRemoteRunProgram)
if err := svc.store.RunEndpoints().Update(endpoint); err != nil {
t.Fatalf("update endpoint capabilities: %v", err)
}
instance, err := svc.CreateServerInstance(domain.ServerInstance{
ID: "server-terminal",
PluginID: plugin.ID,
RunEndpointID: endpoint.ID,
Name: "SCUM Terminal",
})
if err != nil {
t.Fatalf("create server instance: %v", err)
}
job, err := svc.CreateJob(domain.Job{
ID: "job-terminal",
ServerInstanceID: instance.ID,
RunEndpointID: endpoint.ID,
Capability: domain.JobCapabilityRemoteRunProgram,
TargetKey: "protected-program",
InputRef: "input://protected-program/job-terminal",
IdempotencyKey: "idem-terminal",
})
if err != nil {
t.Fatalf("create remote program job: %v", err)
}
streams, err := svc.ListLogStreams(domain.LogStreamFilter{ServerInstanceID: instance.ID})
if err != nil {
t.Fatalf("list log streams: %v", err)
}
if len(streams) != 4 {
t.Fatalf("expected stdout/stderr plus management program streams, got %+v", streams)
}
want := map[string]domain.LogStreamSource{
"stdout": domain.LogStreamSourceProcess,
"stderr": domain.LogStreamSourceProcess,
"management-program.stdout": domain.LogStreamSourceManagementProgram,
"management-program.stderr": domain.LogStreamSourceManagementProgram,
}
for _, stream := range streams {
source, ok := want[stream.StreamKey]
if !ok {
t.Fatalf("unexpected stream key: %+v", stream)
}
if stream.Source != source || stream.ID != jobLogStreamID(job.ID, stream.StreamKey) {
t.Fatalf("unexpected stream metadata: %+v", stream)
}
delete(want, stream.StreamKey)
}
if len(want) != 0 {
t.Fatalf("missing streams: %+v", want)
}
}
func TestCoreServiceStartupRecoversLegacyJobLogStreams(t *testing.T) {
store := repo.NewMemoryStore()
seed := newCoreService(store, func() time.Time { return fixedTime })
plugin, endpoint := createPluginAndRunEndpoint(t, seed)
plugin.RequiredRunCapabilities = append(plugin.RequiredRunCapabilities, domain.JobCapabilityRemoteRunProgram)
if err := seed.store.GamePlugins().Update(plugin); err != nil {
t.Fatalf("update plugin capabilities: %v", err)
}
endpoint.Capabilities = append(endpoint.Capabilities, domain.JobCapabilityRemoteRunProgram)
if err := seed.store.RunEndpoints().Update(endpoint); err != nil {
t.Fatalf("update endpoint capabilities: %v", err)
}
if _, err := seed.CreateServerInstance(domain.ServerInstance{ID: "legacy-terminal-server", PluginID: plugin.ID, RunEndpointID: endpoint.ID, Name: "Legacy Terminal"}); err != nil {
t.Fatalf("create server instance: %v", err)
}
if err := store.Jobs().Create(domain.Job{
ID: "legacy-terminal-job",
ServerInstanceID: "legacy-terminal-server",
RunEndpointID: endpoint.ID,
Capability: domain.JobCapabilityRemoteRunProgram,
TargetKey: "protected-program",
InputRef: "input://protected-program/legacy-terminal-job",
IdempotencyKey: "legacy-terminal",
State: domain.JobStateQueued,
CreatedAt: fixedTime,
UpdatedAt: fixedTime,
}); err != nil {
t.Fatalf("seed legacy job: %v", err)
}
before, err := seed.ListLogStreams(domain.LogStreamFilter{ServerInstanceID: "legacy-terminal-server"})
if err != nil || len(before) != 0 {
t.Fatalf("expected no seeded streams before recovery, len=%d err=%v streams=%+v", len(before), err, before)
}
recovered, err := NewCoreServiceWithDurableStores(store, NewMemoryLogBodyStore(), NewMemoryArtifactBodyStore())
if err != nil {
t.Fatalf("recover durable service: %v", err)
}
after, err := recovered.ListLogStreams(domain.LogStreamFilter{ServerInstanceID: "legacy-terminal-server"})
if err != nil || len(after) != 4 {
t.Fatalf("expected recovered job log streams, len=%d err=%v streams=%+v", len(after), err, after)
}
}
func TestCoreServiceRejectsInvalidServerDependencies(t *testing.T) {
svc := newTestCoreService()
plugin, endpoint := createPluginAndRunEndpoint(t, svc)