Files
hpc/cmd/server/main_test.go
dailz 10bb15e5b2 feat(handler): add Application handler, routes, and wiring
Add ApplicationHandler with CRUD + Submit endpoints. Register 6 routes, wire in app.go, update main_test.go references. 22 handler tests.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-13 17:10:54 +08:00

125 lines
3.7 KiB
Go

package main
import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"gcy_hpc_server/internal/handler"
"gcy_hpc_server/internal/model"
"gcy_hpc_server/internal/server"
"gcy_hpc_server/internal/service"
"gcy_hpc_server/internal/slurm"
"gcy_hpc_server/internal/store"
"go.uber.org/zap"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
)
func newTestDB() *gorm.DB {
db, _ := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{Logger: logger.Default.LogMode(logger.Silent)})
db.AutoMigrate(&model.Application{})
return db
}
func TestRouterRegistration(t *testing.T) {
slurmSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]interface{}{"jobs": []interface{}{}})
}))
defer slurmSrv.Close()
client, _ := slurm.NewClientWithOpts(slurmSrv.URL, slurm.WithHTTPClient(slurmSrv.Client()))
jobSvc := service.NewJobService(client, zap.NewNop())
appStore := store.NewApplicationStore(newTestDB())
appSvc := service.NewApplicationService(appStore, jobSvc, "", zap.NewNop())
appH := handler.NewApplicationHandler(appSvc, zap.NewNop())
router := server.NewRouter(
handler.NewJobHandler(jobSvc, zap.NewNop()),
handler.NewClusterHandler(service.NewClusterService(client, zap.NewNop()), zap.NewNop()),
appH,
nil,
)
routes := router.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/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"},
}
routeMap := map[string]bool{}
for _, r := range routes {
routeMap[r.Method+" "+r.Path] = 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 TestSmokeGetJobsEndpoint(t *testing.T) {
slurmSrv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(map[string]interface{}{"jobs": []interface{}{}})
}))
defer slurmSrv.Close()
client, _ := slurm.NewClientWithOpts(slurmSrv.URL, slurm.WithHTTPClient(slurmSrv.Client()))
jobSvc := service.NewJobService(client, zap.NewNop())
appStore := store.NewApplicationStore(newTestDB())
appSvc := service.NewApplicationService(appStore, jobSvc, "", zap.NewNop())
appH := handler.NewApplicationHandler(appSvc, zap.NewNop())
router := server.NewRouter(
handler.NewJobHandler(jobSvc, zap.NewNop()),
handler.NewClusterHandler(service.NewClusterService(client, zap.NewNop()), zap.NewNop()),
appH,
nil,
)
w := httptest.NewRecorder()
req, _ := http.NewRequest(http.MethodGet, "/api/v1/jobs", nil)
router.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200, got %d: %s", w.Code, w.Body.String())
}
var resp map[string]interface{}
if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil {
t.Fatalf("failed to parse response: %v", err)
}
if success, ok := resp["success"].(bool); !ok || !success {
t.Fatalf("expected success=true, got %v", resp["success"])
}
}