Skip to content

Commit 44908ea

Browse files
feat: Add DownloadCopilotMetrics helper method (#4149)
1 parent 33cf038 commit 44908ea

File tree

3 files changed

+167
-0
lines changed

3 files changed

+167
-0
lines changed

github/copilot.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"encoding/json"
1111
"errors"
1212
"fmt"
13+
"net/http"
1314
"time"
1415
)
1516

@@ -800,3 +801,32 @@ func (s *CopilotService) GetOrganizationUsersMetricsReport(ctx context.Context,
800801

801802
return report, resp, nil
802803
}
804+
805+
// DownloadCopilotMetrics downloads a Copilot metrics report from the provided download link
806+
// and returns the metric data. This can be used to download metrics from a link returned by
807+
// GetEnterpriseDailyMetricsReport, GetEnterpriseMetricsReport, GetEnterpriseUsersDailyMetricsReport,
808+
// GetEnterpriseUsersMetricsReport, GetOrganizationDailyMetricsReport, GetOrganizationMetricsReport,
809+
// GetOrganizationUsersDailyMetricsReport, GetOrganizationUsersMetricsReport.
810+
func (s *CopilotService) DownloadCopilotMetrics(ctx context.Context, url string) ([]*CopilotMetrics, *Response, error) {
811+
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
812+
if err != nil {
813+
return nil, nil, err
814+
}
815+
816+
resp, err := s.client.client.Do(req)
817+
if err != nil {
818+
return nil, nil, err
819+
}
820+
defer resp.Body.Close()
821+
822+
if err := CheckResponse(resp); err != nil {
823+
return nil, newResponse(resp), err
824+
}
825+
826+
var metrics []*CopilotMetrics
827+
if err := json.NewDecoder(resp.Body).Decode(&metrics); err != nil {
828+
return nil, newResponse(resp), err
829+
}
830+
831+
return metrics, newResponse(resp), nil
832+
}

github/copilot_test.go

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2778,3 +2778,139 @@ func TestCopilotService_GetOrganizationUsersMetricsReport(t *testing.T) {
27782778
return resp, err
27792779
})
27802780
}
2781+
2782+
func TestCopilotService_DownloadCopilotMetrics(t *testing.T) {
2783+
t.Parallel()
2784+
client, mux, _ := setup(t)
2785+
2786+
mux.HandleFunc("/path/to/download", func(w http.ResponseWriter, r *http.Request) {
2787+
testMethod(t, r, "GET")
2788+
fmt.Fprint(w, `[{
2789+
"date": "2023-01-01",
2790+
"total_active_users": 100,
2791+
"total_engaged_users": 50,
2792+
"copilot_ide_code_completions": {
2793+
"total_engaged_users": 50,
2794+
"languages": [
2795+
{
2796+
"name": "go",
2797+
"total_engaged_users": 10
2798+
}
2799+
],
2800+
"editors": [
2801+
{
2802+
"name": "vscode",
2803+
"total_engaged_users": 10,
2804+
"models": [
2805+
{
2806+
"name": "model1",
2807+
"is_custom_model": false,
2808+
"custom_model_training_date": null,
2809+
"total_engaged_users": 10,
2810+
"languages": [
2811+
{
2812+
"name": "go",
2813+
"total_engaged_users": 10,
2814+
"total_code_suggestions": 100,
2815+
"total_code_acceptances": 50,
2816+
"total_code_lines_suggested": 1000,
2817+
"total_code_lines_accepted": 500
2818+
}
2819+
]
2820+
}
2821+
]
2822+
}
2823+
]
2824+
}
2825+
}]`)
2826+
})
2827+
2828+
ctx := t.Context()
2829+
url := client.BaseURL.String() + "path/to/download"
2830+
got, resp, err := client.Copilot.DownloadCopilotMetrics(ctx, url)
2831+
if err != nil {
2832+
t.Errorf("Copilot.DownloadCopilotMetrics returned error: %v", err)
2833+
}
2834+
if resp.StatusCode != http.StatusOK {
2835+
t.Errorf("Copilot.DownloadCopilotMetrics returned status code: %v", resp.StatusCode)
2836+
}
2837+
2838+
want := []*CopilotMetrics{
2839+
{
2840+
Date: "2023-01-01",
2841+
TotalActiveUsers: Ptr(100),
2842+
TotalEngagedUsers: Ptr(50),
2843+
CopilotIDECodeCompletions: &CopilotIDECodeCompletions{
2844+
TotalEngagedUsers: 50,
2845+
Languages: []*CopilotIDECodeCompletionsLanguage{
2846+
{
2847+
Name: "go",
2848+
TotalEngagedUsers: 10,
2849+
},
2850+
},
2851+
Editors: []*CopilotIDECodeCompletionsEditor{
2852+
{
2853+
Name: "vscode",
2854+
TotalEngagedUsers: 10,
2855+
Models: []*CopilotIDECodeCompletionsModel{
2856+
{
2857+
Name: "model1",
2858+
IsCustomModel: false,
2859+
TotalEngagedUsers: 10,
2860+
Languages: []*CopilotIDECodeCompletionsModelLanguage{
2861+
{
2862+
Name: "go",
2863+
TotalEngagedUsers: 10,
2864+
TotalCodeSuggestions: 100,
2865+
TotalCodeAcceptances: 50,
2866+
TotalCodeLinesSuggested: 1000,
2867+
TotalCodeLinesAccepted: 500,
2868+
},
2869+
},
2870+
},
2871+
},
2872+
},
2873+
},
2874+
},
2875+
},
2876+
}
2877+
2878+
if !cmp.Equal(got, want) {
2879+
t.Errorf("Copilot.DownloadCopilotMetrics returned %+v, want %+v", got, want)
2880+
}
2881+
2882+
// Test unexpected status code
2883+
mux.HandleFunc("/path/to/download/error", func(w http.ResponseWriter, r *http.Request) {
2884+
testMethod(t, r, "GET")
2885+
w.WriteHeader(http.StatusNotFound)
2886+
})
2887+
2888+
urlErr := client.BaseURL.String() + "path/to/download/error"
2889+
_, _, err = client.Copilot.DownloadCopilotMetrics(ctx, urlErr)
2890+
if err == nil {
2891+
t.Error("Copilot.DownloadCopilotMetrics expected error but got none")
2892+
}
2893+
2894+
// Test invalid URL (fails http.NewRequestWithContext)
2895+
_, _, err = client.Copilot.DownloadCopilotMetrics(ctx, "\n")
2896+
if err == nil {
2897+
t.Error("Copilot.DownloadCopilotMetrics expected error for invalid URL, got none")
2898+
}
2899+
2900+
// Test invalid scheme (fails client.Do)
2901+
_, _, err = client.Copilot.DownloadCopilotMetrics(ctx, "invalid-scheme://test")
2902+
if err == nil {
2903+
t.Error("Copilot.DownloadCopilotMetrics expected error for invalid scheme, got none")
2904+
}
2905+
2906+
// Test json decoding error
2907+
mux.HandleFunc("/path/to/download/badjson", func(w http.ResponseWriter, r *http.Request) {
2908+
testMethod(t, r, "GET")
2909+
fmt.Fprint(w, `[{invalid JSON`)
2910+
})
2911+
urlBadJSON := client.BaseURL.String() + "path/to/download/badjson"
2912+
_, _, err = client.Copilot.DownloadCopilotMetrics(ctx, urlBadJSON)
2913+
if err == nil {
2914+
t.Error("Copilot.DownloadCopilotMetrics expected error for bad JSON, got none")
2915+
}
2916+
}

tools/metadata/metadata.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,4 +547,5 @@ var skipServiceMethod = map[string]bool{
547547
"BillingService.GetOrganizationStorageBilling": true,
548548
"BillingService.GetPackagesBilling": true,
549549
"BillingService.GetStorageBilling": true,
550+
"CopilotService.DownloadCopilotMetrics": true,
550551
}

0 commit comments

Comments
 (0)