package service import ( "context" "encoding/json" "net/http" "strings" "testing" "time" "gcy_hpc_server/internal/model" "gcy_hpc_server/internal/slurm" ) func TestProcessTask_DefaultTimeLimit(t *testing.T) { jobID := int32(42) var capturedReq slurm.JobSubmitReq env := newTaskTestEnv(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if err := json.NewDecoder(r.Body).Decode(&capturedReq); err != nil { t.Fatalf("decode request body: %v", err) } json.NewEncoder(w).Encode(slurm.OpenapiJobSubmitResponse{ Result: &slurm.JobSubmitResponseMsg{JobID: &jobID}, }) })) defer env.close() appID := env.createApp(t, "default-tl-app", "#!/bin/bash\necho hello", json.RawMessage(`[]`)) ctx := context.Background() task := &model.Task{ AppName: "default-tl-app", AppID: appID, Status: model.TaskStatusSubmitted, SubmittedAt: time.Now(), Partition: "debug", } taskID, err := env.taskStore.Create(ctx, task) if err != nil { t.Fatalf("create task in DB: %v", err) } err = env.svc.ProcessTask(ctx, taskID) if err != nil { t.Fatalf("ProcessTask: %v", err) } j := capturedReq.Job if j == nil { t.Fatal("Job desc is nil in captured request") } if j.TimeLimit == nil { t.Fatal("TimeLimit should not be nil, got nil") } if j.TimeLimit.Number == nil { t.Fatal("TimeLimit.Number should not be nil, got nil") } if *j.TimeLimit.Number != int64(10080) { t.Errorf("TimeLimit.Number = %d, want %d", *j.TimeLimit.Number, int64(10080)) } } func TestProcessTask_DefaultStdoutStderr(t *testing.T) { jobID := int32(42) var capturedReq slurm.JobSubmitReq env := newTaskTestEnv(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if err := json.NewDecoder(r.Body).Decode(&capturedReq); err != nil { t.Fatalf("decode request body: %v", err) } json.NewEncoder(w).Encode(slurm.OpenapiJobSubmitResponse{ Result: &slurm.JobSubmitResponseMsg{JobID: &jobID}, }) })) defer env.close() appID := env.createApp(t, "default-std-app", "#!/bin/bash\necho hello", json.RawMessage(`[]`)) ctx := context.Background() task := &model.Task{ AppName: "default-std-app", AppID: appID, Status: model.TaskStatusSubmitted, SubmittedAt: time.Now(), Partition: "debug", } taskID, err := env.taskStore.Create(ctx, task) if err != nil { t.Fatalf("create task in DB: %v", err) } err = env.svc.ProcessTask(ctx, taskID) if err != nil { t.Fatalf("ProcessTask: %v", err) } j := capturedReq.Job if j == nil { t.Fatal("Job desc is nil in captured request") } if j.StandardOutput == nil { t.Fatal("StandardOutput should not be nil, got nil") } if !strings.HasSuffix(*j.StandardOutput, "/slurm-%j.out") { t.Errorf("StandardOutput = %q, want suffix /slurm-%%j.out", *j.StandardOutput) } if j.StandardError == nil { t.Fatal("StandardError should not be nil, got nil") } if !strings.HasSuffix(*j.StandardError, "/slurm-%j.err") { t.Errorf("StandardError = %q, want suffix /slurm-%%j.err", *j.StandardError) } } func TestProcessTask_NoOverrideWhenSet(t *testing.T) { jobID := int32(42) var capturedReq slurm.JobSubmitReq env := newTaskTestEnv(t, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if err := json.NewDecoder(r.Body).Decode(&capturedReq); err != nil { t.Fatalf("decode request body: %v", err) } json.NewEncoder(w).Encode(slurm.OpenapiJobSubmitResponse{ Result: &slurm.JobSubmitResponseMsg{JobID: &jobID}, }) })) defer env.close() appID := env.createApp(t, "no-override-app", "#!/bin/bash\necho hello", json.RawMessage(`[]`)) ctx := context.Background() customTL := int32(60) customOut := "/custom/path.out" task := &model.Task{ AppName: "no-override-app", AppID: appID, Status: model.TaskStatusSubmitted, SubmittedAt: time.Now(), Partition: "debug", TimeLimit: &customTL, StandardOutput: &customOut, } taskID, err := env.taskStore.Create(ctx, task) if err != nil { t.Fatalf("create task in DB: %v", err) } err = env.svc.ProcessTask(ctx, taskID) if err != nil { t.Fatalf("ProcessTask: %v", err) } j := capturedReq.Job if j == nil { t.Fatal("Job desc is nil in captured request") } if j.TimeLimit == nil { t.Fatal("TimeLimit should not be nil, got nil") } if j.TimeLimit.Number == nil { t.Fatal("TimeLimit.Number should not be nil, got nil") } if *j.TimeLimit.Number != int64(60) { t.Errorf("TimeLimit.Number = %d, want %d (user value should be preserved)", *j.TimeLimit.Number, int64(60)) } if j.StandardOutput == nil { t.Fatal("StandardOutput should not be nil, got nil") } if *j.StandardOutput != "/custom/path.out" { t.Errorf("StandardOutput = %q, want %q (user value should be preserved)", *j.StandardOutput, "/custom/path.out") } }