diff --git a/internal/slurm/slurmdb_qos.go b/internal/slurm/slurmdb_qos.go new file mode 100644 index 0000000..836f6f7 --- /dev/null +++ b/internal/slurm/slurmdb_qos.go @@ -0,0 +1,117 @@ +package slurm + +import ( + "context" + "fmt" + "net/url" +) + +type GetQosOptions struct { + Description *string `url:"description,omitempty"` + ID *string `url:"id,omitempty"` + Format *string `url:"format,omitempty"` + Name *string `url:"name,omitempty"` + PreemptMode *string `url:"preempt_mode,omitempty"` + WithDeleted *string `url:"with_deleted,omitempty"` +} + +func (s *SlurmdbQosService) GetQosList(ctx context.Context, opts *GetQosOptions) (*OpenapiSlurmdbdQosResp, *Response, error) { + path := "slurmdb/v0.0.40/qos" + req, err := s.client.NewRequest("GET", path, nil) + if err != nil { + return nil, nil, err + } + + if opts != nil { + u, parseErr := url.Parse(req.URL.String()) + if parseErr != nil { + return nil, nil, parseErr + } + q := u.Query() + if opts.Description != nil { + q.Set("description", *opts.Description) + } + if opts.ID != nil { + q.Set("id", *opts.ID) + } + if opts.Format != nil { + q.Set("format", *opts.Format) + } + if opts.Name != nil { + q.Set("name", *opts.Name) + } + if opts.PreemptMode != nil { + q.Set("preempt_mode", *opts.PreemptMode) + } + if opts.WithDeleted != nil { + q.Set("with_deleted", *opts.WithDeleted) + } + u.RawQuery = q.Encode() + req.URL = u + } + + var result OpenapiSlurmdbdQosResp + resp, err := s.client.Do(ctx, req, &result) + if err != nil { + return nil, resp, err + } + return &result, resp, nil +} + +func (s *SlurmdbQosService) GetQos(ctx context.Context, qosName string, opts *GetQosOptions) (*OpenapiSlurmdbdQosResp, *Response, error) { + path := fmt.Sprintf("slurmdb/v0.0.40/qos/%s", qosName) + req, err := s.client.NewRequest("GET", path, nil) + if err != nil { + return nil, nil, err + } + + if opts != nil { + u, parseErr := url.Parse(req.URL.String()) + if parseErr != nil { + return nil, nil, parseErr + } + q := u.Query() + if opts.WithDeleted != nil { + q.Set("with_deleted", *opts.WithDeleted) + } + u.RawQuery = q.Encode() + req.URL = u + } + + var result OpenapiSlurmdbdQosResp + resp, err := s.client.Do(ctx, req, &result) + if err != nil { + return nil, resp, err + } + return &result, resp, nil +} + +func (s *SlurmdbQosService) PostQos(ctx context.Context, body *OpenapiSlurmdbdQosResp) (*OpenapiSlurmdbdQosResp, *Response, error) { + path := "slurmdb/v0.0.40/qos" + req, err := s.client.NewRequest("POST", path, body) + if err != nil { + return nil, nil, err + } + + var result OpenapiSlurmdbdQosResp + resp, err := s.client.Do(ctx, req, &result) + if err != nil { + return nil, resp, err + } + return &result, resp, nil +} + +func (s *SlurmdbQosService) DeleteQos(ctx context.Context, qosName string) (*OpenapiSlurmdbdQosRemovedResp, *Response, error) { + path := fmt.Sprintf("slurmdb/v0.0.40/qos/%s", qosName) + req, err := s.client.NewRequest("DELETE", path, nil) + if err != nil { + return nil, nil, err + } + + var result OpenapiSlurmdbdQosRemovedResp + resp, err := s.client.Do(ctx, req, &result) + if err != nil { + return nil, resp, err + } + return &result, resp, nil +} diff --git a/internal/slurm/slurmdb_qos_test.go b/internal/slurm/slurmdb_qos_test.go new file mode 100644 index 0000000..5600465 --- /dev/null +++ b/internal/slurm/slurmdb_qos_test.go @@ -0,0 +1,185 @@ +package slurm + +import ( + "context" + "fmt" + "net/http" + "net/http/httptest" + "strings" + "testing" +) + +func TestSlurmdbQosService_GetQosList(t *testing.T) { + mux := http.NewServeMux() + mux.HandleFunc("/slurmdb/v0.0.40/qos", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"qos": []}`) + }) + server := httptest.NewServer(mux) + defer server.Close() + + client, _ := NewClient(server.URL, nil) + resp, _, err := client.SlurmdbQos.GetQosList(context.Background(), nil) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if resp == nil { + t.Fatal("expected non-nil response") + } +} + +func TestSlurmdbQosService_GetQosList_WithOptions(t *testing.T) { + mux := http.NewServeMux() + mux.HandleFunc("/slurmdb/v0.0.40/qos", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + q := r.URL.Query() + if q.Get("description") != "test-desc" { + t.Errorf("expected description=test-desc, got %s", q.Get("description")) + } + if q.Get("id") != "1,2" { + t.Errorf("expected id=1,2, got %s", q.Get("id")) + } + if q.Get("name") != "normal,debug" { + t.Errorf("expected name=normal,debug, got %s", q.Get("name")) + } + if q.Get("with_deleted") != "true" { + t.Errorf("expected with_deleted=true, got %s", q.Get("with_deleted")) + } + fmt.Fprint(w, `{"qos": []}`) + }) + server := httptest.NewServer(mux) + defer server.Close() + + client, _ := NewClient(server.URL, nil) + opts := &GetQosOptions{ + Description: Ptr("test-desc"), + ID: Ptr("1,2"), + Name: Ptr("normal,debug"), + WithDeleted: Ptr("true"), + } + resp, _, err := client.SlurmdbQos.GetQosList(context.Background(), opts) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if resp == nil { + t.Fatal("expected non-nil response") + } +} + +func TestSlurmdbQosService_GetQos(t *testing.T) { + mux := http.NewServeMux() + mux.HandleFunc("/slurmdb/v0.0.40/qos/normal", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + fmt.Fprint(w, `{"qos": [{"name": "normal", "description": "normal QOS"}]}`) + }) + server := httptest.NewServer(mux) + defer server.Close() + + client, _ := NewClient(server.URL, nil) + resp, _, err := client.SlurmdbQos.GetQos(context.Background(), "normal", nil) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if resp == nil { + t.Fatal("expected non-nil response") + } + if len(resp.Qos) != 1 { + t.Fatalf("expected 1 qos, got %d", len(resp.Qos)) + } +} + +func TestSlurmdbQosService_GetQos_WithOptions(t *testing.T) { + mux := http.NewServeMux() + mux.HandleFunc("/slurmdb/v0.0.40/qos/normal", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "GET") + q := r.URL.Query() + if q.Get("with_deleted") != "true" { + t.Errorf("expected with_deleted=true, got %s", q.Get("with_deleted")) + } + fmt.Fprint(w, `{"qos": []}`) + }) + server := httptest.NewServer(mux) + defer server.Close() + + client, _ := NewClient(server.URL, nil) + opts := &GetQosOptions{ + WithDeleted: Ptr("true"), + } + resp, _, err := client.SlurmdbQos.GetQos(context.Background(), "normal", opts) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if resp == nil { + t.Fatal("expected non-nil response") + } +} + +func TestSlurmdbQosService_PostQos(t *testing.T) { + mux := http.NewServeMux() + mux.HandleFunc("/slurmdb/v0.0.40/qos", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "POST") + if ct := r.Header.Get("Content-Type"); ct != "application/json" { + t.Errorf("expected Content-Type application/json, got %s", ct) + } + fmt.Fprint(w, `{"qos": [{"name": "new-qos"}]}`) + }) + server := httptest.NewServer(mux) + defer server.Close() + + client, _ := NewClient(server.URL, nil) + body := &OpenapiSlurmdbdQosResp{} + resp, _, err := client.SlurmdbQos.PostQos(context.Background(), body) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if resp == nil { + t.Fatal("expected non-nil response") + } + if len(resp.Qos) != 1 { + t.Errorf("expected 1 qos, got %d", len(resp.Qos)) + } +} + +func TestSlurmdbQosService_DeleteQos(t *testing.T) { + mux := http.NewServeMux() + mux.HandleFunc("/slurmdb/v0.0.40/qos/old-qos", func(w http.ResponseWriter, r *http.Request) { + testMethod(t, r, "DELETE") + fmt.Fprint(w, `{"removed_qos": ["old-qos"]}`) + }) + server := httptest.NewServer(mux) + defer server.Close() + + client, _ := NewClient(server.URL, nil) + resp, _, err := client.SlurmdbQos.DeleteQos(context.Background(), "old-qos") + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if resp == nil { + t.Fatal("expected non-nil response") + } + if len(resp.RemovedQos) != 1 { + t.Fatalf("expected 1 removed qos, got %d", len(resp.RemovedQos)) + } + if resp.RemovedQos[0] != "old-qos" { + t.Errorf("expected removed_qos=old-qos, got %s", resp.RemovedQos[0]) + } +} + +func TestSlurmdbQosService_Error(t *testing.T) { + mux := http.NewServeMux() + mux.HandleFunc("/slurmdb/v0.0.40/qos", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprint(w, `{"errors": [{"error": "internal error"}]}`) + }) + server := httptest.NewServer(mux) + defer server.Close() + + client, _ := NewClient(server.URL, nil) + _, _, err := client.SlurmdbQos.GetQosList(context.Background(), nil) + if err == nil { + t.Fatal("expected error for 500 response") + } + if !strings.Contains(err.Error(), "500") { + t.Errorf("expected error to contain 500, got %v", err) + } +}