Files
grafana/pkg/tsdb/cloudmonitoring/resource_handler_test.go
Emil Tullstedt 656e270bd9 Chore: Upgrade Go to 1.19.2 (#56857)
We also need to upgrade the linter together with the Go version, all the changes should relate to either fixing linting problems or upgrading the Go version used to build Grafana.
2022-10-13 14:53:51 +02:00

311 lines
6.9 KiB
Go

package cloudmonitoring
import (
"context"
"encoding/json"
"fmt"
"io/ioutil" //nolint:staticcheck // No need to change in v8.
"net/http"
"net/http/httptest"
"testing"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_parseResourcePath(t *testing.T) {
tests := []struct {
name string
original string
expectedTarget string
Err require.ErrorAssertionFunc
}{
{
"Path with a subscription",
"/cloudmonitoring/v3/projects/foo",
"/v3/projects/foo",
require.NoError,
},
{
"Malformed path",
"/projects?foo",
"",
require.Error,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
target, err := getTarget(tt.original)
if target != tt.expectedTarget {
t.Errorf("Unexpected target %s expecting %s", target, tt.expectedTarget)
}
tt.Err(t, err)
})
}
}
func Test_doRequest(t *testing.T) {
// test that it forwards the header and body over multiple calls
elements := []string{"1", "2", "3"}
index := 0
fakeResponseFn := func(input []byte) ([]json.RawMessage, string, error) {
results := []json.RawMessage{input}
if index < len(elements) {
return results, "token", nil
}
return results, "", nil
}
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Add("foo", "bar")
_, err := w.Write([]byte(elements[index]))
index++
if err != nil {
t.Fatal(err)
}
}))
req, err := http.NewRequest(http.MethodGet, srv.URL, nil)
if err != nil {
t.Error(err)
}
rw := httptest.NewRecorder()
res := getResources(rw, req, srv.Client(), fakeResponseFn)
if res.Header().Get("foo") != "bar" {
t.Errorf("Unexpected headers: %v", res.Header())
}
result := rw.Result()
body, err := ioutil.ReadAll(result.Body)
if err != nil {
t.Error(err)
}
err = result.Body.Close()
if err != nil {
t.Error(err)
}
if string(body) != "[1,2,3]" {
t.Errorf("Unexpected body: %v", string(body))
}
}
type fakeInstance struct {
services map[string]datasourceService
}
func (f *fakeInstance) Get(pluginContext backend.PluginContext) (instancemgmt.Instance, error) {
return &datasourceInfo{
services: f.services,
}, nil
}
func (f *fakeInstance) Do(pluginContext backend.PluginContext, fn instancemgmt.InstanceCallbackFunc) error {
return nil
}
func Test_setRequestVariables(t *testing.T) {
s := Service{
im: &fakeInstance{
services: map[string]datasourceService{
cloudMonitor: {
url: routes[cloudMonitor].url,
client: &http.Client{},
},
},
},
}
req, err := http.NewRequest(http.MethodGet, "http://foo/cloudmonitoring/v3/projects/bar/metricDescriptors", nil)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
_, _, err = s.setRequestVariables(req, cloudMonitor)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
expectedURL := "https://monitoring.googleapis.com/v3/projects/bar/metricDescriptors"
if req.URL.String() != expectedURL {
t.Errorf("Unexpected result URL. Got %s, expecting %s", req.URL.String(), expectedURL)
}
}
func Test_processData_functions(t *testing.T) {
// metricDescriptors
metricDescriptorResp := metricDescriptorResponse{
Descriptors: []metricDescriptor{
{
ValueType: "INT64",
MetricKind: "DELTA",
Type: "actions.googleapis.com/smarthome_action/local_event_count",
Unit: "1",
Service: "foo",
ServiceShortName: "bar",
DisplayName: "Local event count",
Description: "baz",
},
},
Token: "foo",
}
marshaledMDResponse, _ := json.Marshal(metricDescriptorResp)
metricDescriptorResult := []metricDescriptor{
{
ValueType: "INT64",
MetricKind: "DELTA",
Type: "actions.googleapis.com/smarthome_action/local_event_count",
Unit: "1",
Service: "actions.googleapis.com",
ServiceShortName: "actions",
DisplayName: "Local event count",
Description: "baz",
},
}
marshaledMDResult, _ := json.Marshal(metricDescriptorResult)
// services
serviceResp := serviceResponse{
Services: []serviceDescription{
{
Name: "blah/foo",
DisplayName: "bar",
},
{
Name: "abc",
DisplayName: "",
},
},
}
marshaledServiceResponse, _ := json.Marshal(serviceResp)
serviceResult := []selectableValue{
{
Value: "foo",
Label: "bar",
},
{
Value: "abc",
Label: "abc",
},
}
marshaledServiceResult, _ := json.Marshal(serviceResult)
// slos
sloResp := sloResponse{
SLOs: []sloDescription{
{
Name: "blah/foo",
DisplayName: "bar",
Goal: 0.1,
},
{
Name: "abc",
DisplayName: "xyz",
Goal: 0.2,
},
},
}
marshaledSLOResponse, _ := json.Marshal(sloResp)
sloResult := []selectableValue{
{
Value: "foo",
Label: "bar",
Goal: 0.1,
},
{
Value: "abc",
Label: "xyz",
Goal: 0.2,
},
}
marshaledSLOResult, _ := json.Marshal(sloResult)
// cloudresourcemanager
cloudResourceResp := projectResponse{
Projects: []projectDescription{
{
ProjectID: "foo",
Name: "bar",
},
{
ProjectID: "abc",
Name: "abc",
},
},
}
marshaledCRResponse, _ := json.Marshal(cloudResourceResp)
tests := []struct {
name string
responseFn processResponse
input []byte
result []byte
token string
}{
{
"metricDescriptor",
processMetricDescriptors,
marshaledMDResponse,
marshaledMDResult,
"foo",
},
{
"services",
processServices,
marshaledServiceResponse,
marshaledServiceResult,
"",
},
{
"slos",
processSLOs,
marshaledSLOResponse,
marshaledSLOResult,
"",
},
{
"cloudresourcemanager",
processProjects,
marshaledCRResponse,
marshaledServiceResult,
"",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
results, token, err := test.responseFn(test.input)
if err != nil {
t.Errorf("Unexpected error %v", err)
}
if token != test.token {
t.Errorf("Unexpected token. Got %s, expecting %s", token, test.token)
}
res, err := json.Marshal(results)
if err != nil {
t.Errorf("Unexpected error %v", err)
}
if string(test.result) != string(res) {
t.Errorf("Unexpected result. Got %s, expecting %s", res, test.result)
}
})
}
}
func Test_getGCEDefaultProject(t *testing.T) {
project := "test-project"
s := Service{
im: &fakeInstance{
services: map[string]datasourceService{
cloudMonitor: {
url: routes[cloudMonitor].url,
client: &http.Client{},
},
},
},
gceDefaultProjectGetter: func(ctx context.Context) (string, error) {
return project, nil
},
}
assert.HTTPSuccess(t, s.getGCEDefaultProject, "GET", "/gceDefaultProject", nil)
assert.HTTPBodyContains(t, s.getGCEDefaultProject, "GET", "/gceDefaultProject", nil, fmt.Sprintf("\"%v\"", project))
}