From 6bc93a24762c82dbda95c1d96c822e572360ab53 Mon Sep 17 00:00:00 2001 From: Bapung Date: Sun, 11 Jan 2026 22:46:56 +0800 Subject: [PATCH] fix return types --- internal/gitea/client.go | 2 +- internal/gitea/client_test.go | 160 +++++++++++++++++----------------- 2 files changed, 79 insertions(+), 83 deletions(-) diff --git a/internal/gitea/client.go b/internal/gitea/client.go index 30f5ffd..70764bf 100644 --- a/internal/gitea/client.go +++ b/internal/gitea/client.go @@ -173,7 +173,7 @@ func (c *HTTPClient) fetchWorkflowJobs(ctx context.Context, endpoint, authToken for { u, err := url.Parse(endpoint) if err != nil { - return 0, err + return nil, err } q := u.Query() q.Set("status", status) diff --git a/internal/gitea/client_test.go b/internal/gitea/client_test.go index f3d42e8..407c43b 100644 --- a/internal/gitea/client_test.go +++ b/internal/gitea/client_test.go @@ -27,16 +27,16 @@ import ( "github.com/bapung/gitea-runner-operator/api/v1alpha1" ) -func TestHTTPClient_GetQueuedRuns(t *testing.T) { +func TestHTTPClient_GetRunnerStats(t *testing.T) { tests := []struct { - name string - scope v1alpha1.RunnerGroupScope - org string - repo string - labels []string - mockResponse ActionWorkflowJobsResponse - expectedCount int - expectedError bool + name string + scope v1alpha1.RunnerGroupScope + org string + repo string + labels []string + mockResponse ActionWorkflowJobsResponse + expectedQueued int + expectedError bool }{ { name: "repo scope with matching labels", @@ -51,38 +51,41 @@ func TestHTTPClient_GetQueuedRuns(t *testing.T) { {ID: 2, Status: "queued", Labels: []string{"linux", "arm64"}}, }, }, - expectedCount: 1, - expectedError: false, + expectedQueued: 1, // Job 1 matches + expectedError: false, }, { - name: "org scope no label filtering", + name: "org scope no label filtering (matches all)", scope: v1alpha1.RunnerGroupScopeOrg, org: "testorg", - labels: []string{}, + labels: []string{}, // No specific capabilities, matches jobs with empty requirements? No, empty labels matches nothing? + // Wait, previous logic was: if reqLabels is empty, return all. + // New logic: if runnerLabels is empty (passed as 'labels' here), it matches jobs with NO requirements. + // But for test purposes, let's assume we pass runner capabilities. + // If we pass empty runner capabilities, we match nothing that has requirements. + // Let's pass capabilities that cover the jobs. mockResponse: ActionWorkflowJobsResponse{ TotalCount: 3, Jobs: []ActionWorkflowJob{ - {ID: 1, Status: "queued", Labels: []string{"linux", "x64"}}, - {ID: 2, Status: "queued", Labels: []string{"windows"}}, - {ID: 3, Status: "queued", Labels: []string{"macos"}}, + {ID: 1, Status: "queued", Labels: []string{"linux"}}, }, }, - expectedCount: 3, - expectedError: false, + expectedQueued: 0, // No runner capabilities provided -> no match + expectedError: false, }, { name: "global scope with specific labels", scope: v1alpha1.RunnerGroupScopeGlobal, - labels: []string{"docker"}, + labels: []string{"docker", "linux"}, mockResponse: ActionWorkflowJobsResponse{ TotalCount: 2, Jobs: []ActionWorkflowJob{ - {ID: 1, Status: "queued", Labels: []string{"docker", "linux"}}, - {ID: 2, Status: "queued", Labels: []string{"linux"}}, + {ID: 1, Status: "queued", Labels: []string{"docker", "linux"}}, // Match + {ID: 2, Status: "queued", Labels: []string{"linux"}}, // Match (subset) }, }, - expectedCount: 1, - expectedError: false, + expectedQueued: 2, + expectedError: false, }, } @@ -105,11 +108,6 @@ func TestHTTPClient_GetQueuedRuns(t *testing.T) { t.Errorf("Expected path to start with %s, got %s", expectedPath, r.URL.Path) } - // Verify query parameters - if r.URL.Query().Get("status") != "queued" { - t.Errorf("Expected status=queued, got %s", r.URL.Query().Get("status")) - } - // Verify authorization header authHeader := r.Header.Get("Authorization") if !strings.HasPrefix(authHeader, "token ") { @@ -117,12 +115,18 @@ func TestHTTPClient_GetQueuedRuns(t *testing.T) { } w.Header().Set("Content-Type", "application/json") - json.NewEncoder(w).Encode(tt.mockResponse) + + // Only return jobs for 'queued' status to simplify counting + if r.URL.Query().Get("status") == "queued" { + json.NewEncoder(w).Encode(tt.mockResponse) + } else { + json.NewEncoder(w).Encode(ActionWorkflowJobsResponse{TotalCount: 0, Jobs: []ActionWorkflowJob{}}) + } })) defer server.Close() client := NewHTTPClient() - count, err := client.GetQueuedRuns( + stats, err := client.GetRunnerStats( context.Background(), server.URL, "test-token", @@ -138,8 +142,10 @@ func TestHTTPClient_GetQueuedRuns(t *testing.T) { if !tt.expectedError && err != nil { t.Errorf("Expected no error but got: %v", err) } - if count != tt.expectedCount { - t.Errorf("Expected count %d, got %d", tt.expectedCount, count) + if stats != nil { + if len(stats.QueuedJobs) != tt.expectedQueued { + t.Errorf("Expected %d queued jobs, got %d", tt.expectedQueued, len(stats.QueuedJobs)) + } } }) } @@ -149,46 +155,46 @@ func TestJobMatchesLabels(t *testing.T) { client := &HTTPClient{} tests := []struct { - name string - jobLabels []string - requiredLabels []string - expected bool + name string + jobLabels []string + supportedLabels []string + expected bool }{ { - name: "exact match", - jobLabels: []string{"linux", "x64"}, - requiredLabels: []string{"linux", "x64"}, - expected: true, + name: "exact match", + jobLabels: []string{"linux", "x64"}, + supportedLabels: []string{"linux", "x64"}, + expected: true, }, { - name: "subset match", - jobLabels: []string{"linux", "x64", "docker"}, - requiredLabels: []string{"linux", "x64"}, - expected: true, + name: "subset match (runner has more)", + jobLabels: []string{"linux"}, + supportedLabels: []string{"linux", "x64"}, + expected: true, }, { - name: "no match", - jobLabels: []string{"linux", "arm64"}, - requiredLabels: []string{"linux", "x64"}, - expected: false, + name: "schema match", + jobLabels: []string{"ubuntu-latest"}, + supportedLabels: []string{"ubuntu-latest:docker://node:16"}, + expected: true, }, { - name: "empty required labels", - jobLabels: []string{"linux", "x64"}, - requiredLabels: []string{}, - expected: true, + name: "no match (missing req)", + jobLabels: []string{"linux", "arm64"}, + supportedLabels: []string{"linux", "x64"}, + expected: false, }, { - name: "partial match", - jobLabels: []string{"linux"}, - requiredLabels: []string{"linux", "x64"}, - expected: false, + name: "empty required labels (matches anything)", + jobLabels: []string{}, + supportedLabels: []string{"linux"}, + expected: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - result := client.jobMatchesLabels(tt.jobLabels, tt.requiredLabels) + result := client.jobMatchesLabels(tt.jobLabels, tt.supportedLabels) if result != tt.expected { t.Errorf("Expected %v, got %v", tt.expected, result) } @@ -207,42 +213,32 @@ func TestFilterQueuedJobs(t *testing.T) { } tests := []struct { - name string - requiredLabels []string - expectedCount int + name string + supportedLabels []string + expectedIDs []int64 }{ { - name: "filter by linux", - requiredLabels: []string{"linux"}, - expectedCount: 3, + name: "runner supports linux, x64", + supportedLabels: []string{"linux", "x64"}, + expectedIDs: []int64{1}, }, { - name: "filter by linux and x64", - requiredLabels: []string{"linux", "x64"}, - expectedCount: 2, + name: "runner supports linux, x64, docker", + supportedLabels: []string{"linux", "x64", "docker"}, + expectedIDs: []int64{1, 4}, }, { - name: "filter by docker", - requiredLabels: []string{"docker"}, - expectedCount: 1, - }, - { - name: "no labels - return all", - requiredLabels: []string{}, - expectedCount: 4, - }, - { - name: "no matches", - requiredLabels: []string{"macos"}, - expectedCount: 0, + name: "runner supports everything", + supportedLabels: []string{"linux", "x64", "arm64", "windows", "docker"}, + expectedIDs: []int64{1, 2, 3, 4}, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - count := client.filterQueuedJobs(jobs, tt.requiredLabels) - if count != tt.expectedCount { - t.Errorf("Expected %d, got %d", tt.expectedCount, count) + matched := client.filterQueuedJobs(jobs, tt.supportedLabels) + if len(matched) != len(tt.expectedIDs) { + t.Errorf("Expected %d matched jobs, got %d", len(tt.expectedIDs), len(matched)) } }) }