Files

112 lines
3.4 KiB
Go

package server
import (
"os"
"path/filepath"
"testing"
"github.com/langgenius/dify/dify-agent-runtime/internal/jobmode"
)
func TestMaterializeStdioStatusDoesNotRequirePanePipe(t *testing.T) {
service, row := setupModeTestService(t, jobmode.Stdio, StatusRunning)
pipeInactive := false
view, err := service.materializeStatusView(row, true, &pipeInactive)
if err != nil {
t.Fatalf("materializeStatusView: %v", err)
}
if view.Status != StatusRunning {
t.Errorf("status = %q, want %q", view.Status, StatusRunning)
}
}
func TestMaterializeStdioStatusUsesExitArtifactsWithoutPipeDrainMarker(t *testing.T) {
service, row := setupModeTestService(t, jobmode.Stdio, StatusRunning)
jobDir := filepath.Join(service.config.JobsDir(), row.JobID)
if err := os.WriteFile(filepath.Join(jobDir, "runner-exit-code"), []byte("7\n"), 0600); err != nil {
t.Fatal(err)
}
const endedAt = "2026-08-04T10:00:00Z"
if err := os.WriteFile(filepath.Join(jobDir, "runner-ended-at"), []byte(endedAt+"\n"), 0600); err != nil {
t.Fatal(err)
}
view, err := service.materializeStatusView(row, false, nil)
if err != nil {
t.Fatalf("materializeStatusView: %v", err)
}
if view.Status != StatusExited || !view.Done {
t.Errorf("view = status %q done %v, want exited and done", view.Status, view.Done)
}
if view.ExitCode == nil || *view.ExitCode != 7 {
t.Errorf("exit code = %v, want 7", view.ExitCode)
}
if view.EndedAt == nil || *view.EndedAt != endedAt {
t.Errorf("ended_at = %v, want %s", view.EndedAt, endedAt)
}
}
func TestMaterializeStdioStatusMarksMissingSessionWithIncompleteArtifactsLost(t *testing.T) {
service, row := setupModeTestService(t, jobmode.Stdio, StatusRunning)
jobDir := filepath.Join(service.config.JobsDir(), row.JobID)
if err := os.WriteFile(filepath.Join(jobDir, "runner-exit-code"), []byte("0\n"), 0600); err != nil {
t.Fatal(err)
}
view, err := service.materializeStatusView(row, false, nil)
if err != nil {
t.Fatalf("materializeStatusView: %v", err)
}
if view.Status != StatusLost {
t.Errorf("status = %q, want %q", view.Status, StatusLost)
}
}
func setupModeTestService(t *testing.T, mode jobmode.Mode, status JobStatusName) (*Service, *JobRow) {
t.Helper()
stateDir := t.TempDir()
config := mustDefaultConfig(t)
config.StateDir = stateDir
config.RuntimeDir = filepath.Join(stateDir, "runtime")
if err := os.MkdirAll(config.JobsDir(), 0700); err != nil {
t.Fatal(err)
}
db := setupTestDB(t, stateDir)
t.Cleanup(func() { _ = db.Close() })
service := NewService(config)
service.db = db
const jobID = "mode-test-job"
jobDir := filepath.Join(config.JobsDir(), jobID)
if err := os.MkdirAll(jobDir, 0700); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(jobDir, "output.log"), nil, 0600); err != nil {
t.Fatal(err)
}
row := &JobRow{
JobID: jobID,
ScriptPath: "jobs/mode-test-job/script",
OutputPath: "jobs/mode-test-job/output.log",
Mode: mode,
Cwd: "/tmp",
TerminalCols: 80,
TerminalRows: 24,
Status: status,
SessionName: JobSessionName(jobID),
PaneTarget: JobPaneTarget(jobID),
CreatedAt: "2026-08-04T09:00:00Z",
UpdatedAt: "2026-08-04T09:00:00Z",
}
inserted, err := db.InsertJob(row)
if err != nil || !inserted {
t.Fatalf("InsertJob: inserted=%v err=%v", inserted, err)
}
persisted, err := db.GetJob(jobID)
if err != nil {
t.Fatalf("GetJob: %v", err)
}
return service, persisted
}