Files
hpc/internal/server/server_test.go
dailz b90942de77 fix(task): prevent duplicate Slurm job submission on backend restart
RecoverStuckTasks now skips tasks that already have a slurm_job_id,
and ProcessTask adds a guard before the submitting step to prevent
re-submission even if a task is incorrectly re-enqueued.

Also deprecates POST /api/v1/jobs/submit endpoint (replaced by POST /tasks)
and comments out related handlers and tests.
2026-04-21 10:57:38 +08:00

110 lines
2.6 KiB
Go

package server
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
)
func TestAllRoutesRegistered(t *testing.T) {
r := NewTestRouter()
routes := r.Routes()
expected := []struct {
method string
path string
}{
// {"POST", "/api/v1/jobs/submit"}, // [已弃用] 已被 POST /tasks 取代
{"GET", "/api/v1/jobs"},
{"GET", "/api/v1/jobs/history"},
{"GET", "/api/v1/jobs/:id"},
{"DELETE", "/api/v1/jobs/:id"},
{"GET", "/api/v1/nodes"},
{"GET", "/api/v1/nodes/:name"},
{"GET", "/api/v1/partitions"},
{"GET", "/api/v1/partitions/:name"},
{"GET", "/api/v1/diag"},
{"GET", "/api/v1/applications"},
{"POST", "/api/v1/applications"},
{"GET", "/api/v1/applications/:id"},
{"PUT", "/api/v1/applications/:id"},
{"DELETE", "/api/v1/applications/:id"},
// {"POST", "/api/v1/applications/:id/submit"}, // [已禁用] 已被 POST /tasks 取代
}
routeMap := map[string]bool{}
for _, route := range routes {
key := route.Method + " " + route.Path
routeMap[key] = true
}
for _, exp := range expected {
key := exp.method + " " + exp.path
if !routeMap[key] {
t.Errorf("missing route: %s", key)
}
}
if len(routes) < len(expected) {
t.Errorf("expected at least %d routes, got %d", len(expected), len(routes))
}
}
func TestUnregisteredPathReturns404(t *testing.T) {
r := NewTestRouter()
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/api/v1/nonexistent", nil)
r.ServeHTTP(w, req)
if w.Code != http.StatusNotFound {
t.Fatalf("expected 404 for unregistered path, got %d", w.Code)
}
}
func TestRegisteredPathReturns501(t *testing.T) {
r := NewTestRouter()
endpoints := []struct {
method string
path string
}{
{"GET", "/api/v1/jobs"},
{"GET", "/api/v1/nodes"},
{"GET", "/api/v1/partitions"},
{"GET", "/api/v1/diag"},
{"GET", "/api/v1/applications"},
}
for _, ep := range endpoints {
w := httptest.NewRecorder()
req, _ := http.NewRequest(ep.method, ep.path, nil)
r.ServeHTTP(w, req)
if w.Code != http.StatusNotImplemented {
t.Fatalf("%s %s: expected 501, got %d", ep.method, ep.path, w.Code)
}
var resp APIResponse
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Fatalf("failed to parse response: %v", err)
}
if resp.Success {
t.Fatal("expected success=false")
}
if resp.Error != "not implemented" {
t.Fatalf("expected error 'not implemented', got '%s'", resp.Error)
}
}
}
func TestRouterUsesGinMode(t *testing.T) {
gin.SetMode(gin.TestMode)
r := NewTestRouter()
if r == nil {
t.Fatal("NewRouter returned nil")
}
}