- cmd/server/main.go: 使用 logger.NewLogger(cfg.Log) 替代 zap.NewProduction() - internal/app: 依赖注入组装 DB/Slurm/Service/Handler,传递 logger - internal/middleware: RequestLogger 请求日志中间件 - internal/server: 统一响应格式和路由注册 - go.mod: module 更名为 gcy_hpc_server,添加 gin/zap/lumberjack/gorm 依赖 - 日志初始化失败时 fail fast (os.Exit(1)) - GormLevel 从配置传递到 NewGormDB,支持 YAML 独立配置 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
109 lines
2.4 KiB
Go
109 lines
2.4 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"},
|
|
{"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/templates"},
|
|
{"POST", "/api/v1/templates"},
|
|
{"GET", "/api/v1/templates/:id"},
|
|
{"PUT", "/api/v1/templates/:id"},
|
|
{"DELETE", "/api/v1/templates/:id"},
|
|
}
|
|
|
|
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/templates"},
|
|
}
|
|
|
|
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")
|
|
}
|
|
}
|