mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
	
	
		
			161 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
		
		
			
		
	
	
			161 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
|  | package api | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"context" | ||
|  | 	"io/ioutil" | ||
|  | 	"net/http" | ||
|  | 	"testing" | ||
|  | 
 | ||
|  | 	"github.com/grafana/grafana-plugin-sdk-go/backend" | ||
|  | 	"github.com/grafana/grafana/pkg/api/routing" | ||
|  | 	"github.com/grafana/grafana/pkg/plugins" | ||
|  | 	"github.com/grafana/grafana/pkg/plugins/backendplugin" | ||
|  | 	"github.com/grafana/grafana/pkg/setting" | ||
|  | 	"github.com/grafana/grafana/pkg/web/webtest" | ||
|  | 	"github.com/stretchr/testify/require" | ||
|  | ) | ||
|  | 
 | ||
|  | func TestPluginMetricsEndpoint(t *testing.T) { | ||
|  | 	t.Run("Endpoint is enabled, basic auth disabled", func(t *testing.T) { | ||
|  | 		hs := &HTTPServer{ | ||
|  | 			Cfg: &setting.Cfg{ | ||
|  | 				MetricsEndpointEnabled:           true, | ||
|  | 				MetricsEndpointBasicAuthUsername: "", | ||
|  | 				MetricsEndpointBasicAuthPassword: "", | ||
|  | 			}, | ||
|  | 			pluginClient: &fakePluginClientMetrics{ | ||
|  | 				store: map[string][]byte{ | ||
|  | 					"test-plugin": []byte("http_errors=2"), | ||
|  | 				}, | ||
|  | 			}, | ||
|  | 		} | ||
|  | 
 | ||
|  | 		s := webtest.NewServer(t, routing.NewRouteRegister()) | ||
|  | 		s.Mux.Use(hs.pluginMetricsEndpoint) | ||
|  | 
 | ||
|  | 		t.Run("Endpoint matches and plugin is registered", func(t *testing.T) { | ||
|  | 			req := s.NewGetRequest("/metrics/plugins/test-plugin") | ||
|  | 			resp, err := s.Send(req) | ||
|  | 			require.NoError(t, err) | ||
|  | 			require.NotNil(t, resp) | ||
|  | 
 | ||
|  | 			body, err := ioutil.ReadAll(resp.Body) | ||
|  | 			require.NoError(t, err) | ||
|  | 			require.Equal(t, "http_errors=2", string(body)) | ||
|  | 			require.NoError(t, resp.Body.Close()) | ||
|  | 			require.Equal(t, http.StatusOK, resp.StatusCode) | ||
|  | 			require.Equal(t, "text/plain", resp.Header.Get("Content-Type")) | ||
|  | 		}) | ||
|  | 
 | ||
|  | 		t.Run("Endpoint matches and plugin is not registered", func(t *testing.T) { | ||
|  | 			req := s.NewGetRequest("/metrics/plugins/plugin-not-registered") | ||
|  | 			resp, err := s.Send(req) | ||
|  | 			require.NoError(t, err) | ||
|  | 			require.NotNil(t, resp) | ||
|  | 
 | ||
|  | 			body, err := ioutil.ReadAll(resp.Body) | ||
|  | 			require.NoError(t, err) | ||
|  | 			require.Empty(t, string(body)) | ||
|  | 			require.NoError(t, resp.Body.Close()) | ||
|  | 			require.Equal(t, http.StatusNotFound, resp.StatusCode) | ||
|  | 		}) | ||
|  | 
 | ||
|  | 		t.Run("Endpoint does not match", func(t *testing.T) { | ||
|  | 			req := s.NewGetRequest("/foo") | ||
|  | 			resp, err := s.Send(req) | ||
|  | 			require.NoError(t, err) | ||
|  | 			require.NotNil(t, resp) | ||
|  | 			require.NoError(t, resp.Body.Close()) | ||
|  | 			require.Equal(t, http.StatusNotFound, resp.StatusCode) | ||
|  | 		}) | ||
|  | 	}) | ||
|  | 
 | ||
|  | 	t.Run("Endpoint and basic auth is enabled", func(t *testing.T) { | ||
|  | 		hs := &HTTPServer{ | ||
|  | 			Cfg: &setting.Cfg{ | ||
|  | 				MetricsEndpointEnabled:           true, | ||
|  | 				MetricsEndpointBasicAuthUsername: "user", | ||
|  | 				MetricsEndpointBasicAuthPassword: "pwd", | ||
|  | 			}, | ||
|  | 			pluginClient: &fakePluginClientMetrics{ | ||
|  | 				store: map[string][]byte{ | ||
|  | 					"test-plugin": []byte("http_errors=2"), | ||
|  | 				}, | ||
|  | 			}, | ||
|  | 		} | ||
|  | 
 | ||
|  | 		s := webtest.NewServer(t, routing.NewRouteRegister()) | ||
|  | 		s.Mux.Use(hs.pluginMetricsEndpoint) | ||
|  | 
 | ||
|  | 		t.Run("When plugin is registered, wrong basic auth credentials should return 401", func(t *testing.T) { | ||
|  | 			req := s.NewGetRequest("/metrics/plugins/test-plugin") | ||
|  | 			req.SetBasicAuth("user2", "pwd2") | ||
|  | 			resp, err := s.Send(req) | ||
|  | 			require.NoError(t, err) | ||
|  | 			require.NotNil(t, resp) | ||
|  | 
 | ||
|  | 			require.NoError(t, err) | ||
|  | 			require.NoError(t, resp.Body.Close()) | ||
|  | 			require.Equal(t, http.StatusUnauthorized, resp.StatusCode) | ||
|  | 		}) | ||
|  | 
 | ||
|  | 		t.Run("When plugin is registered, correct basic auth credentials should return 200", func(t *testing.T) { | ||
|  | 			req := s.NewGetRequest("/metrics/plugins/test-plugin") | ||
|  | 			req.SetBasicAuth("user", "pwd") | ||
|  | 			resp, err := s.Send(req) | ||
|  | 			require.NoError(t, err) | ||
|  | 			require.NotNil(t, resp) | ||
|  | 
 | ||
|  | 			body, err := ioutil.ReadAll(resp.Body) | ||
|  | 			require.NoError(t, err) | ||
|  | 			require.Equal(t, "http_errors=2", string(body)) | ||
|  | 			require.NoError(t, resp.Body.Close()) | ||
|  | 			require.Equal(t, http.StatusOK, resp.StatusCode) | ||
|  | 			require.Equal(t, "text/plain", resp.Header.Get("Content-Type")) | ||
|  | 		}) | ||
|  | 	}) | ||
|  | 
 | ||
|  | 	t.Run("Endpoint is disabled", func(t *testing.T) { | ||
|  | 		hs := &HTTPServer{ | ||
|  | 			Cfg: &setting.Cfg{ | ||
|  | 				MetricsEndpointEnabled: false, | ||
|  | 			}, | ||
|  | 			pluginClient: &fakePluginClientMetrics{ | ||
|  | 				store: map[string][]byte{ | ||
|  | 					"test-plugin": []byte("http_errors=2"), | ||
|  | 				}, | ||
|  | 			}, | ||
|  | 		} | ||
|  | 
 | ||
|  | 		s := webtest.NewServer(t, routing.NewRouteRegister()) | ||
|  | 		s.Mux.Use(hs.pluginMetricsEndpoint) | ||
|  | 
 | ||
|  | 		t.Run("When plugin is registered, should return 404", func(t *testing.T) { | ||
|  | 			req := s.NewGetRequest("/metrics/plugins/test-plugin") | ||
|  | 			resp, err := s.Send(req) | ||
|  | 			require.NoError(t, err) | ||
|  | 			require.NotNil(t, resp) | ||
|  | 			require.NoError(t, resp.Body.Close()) | ||
|  | 			require.Equal(t, http.StatusNotFound, resp.StatusCode) | ||
|  | 		}) | ||
|  | 	}) | ||
|  | } | ||
|  | 
 | ||
|  | type fakePluginClientMetrics struct { | ||
|  | 	plugins.Client | ||
|  | 
 | ||
|  | 	store map[string][]byte | ||
|  | } | ||
|  | 
 | ||
|  | func (c *fakePluginClientMetrics) CollectMetrics(ctx context.Context, req *backend.CollectMetricsRequest) (*backend.CollectMetricsResult, error) { | ||
|  | 	metrics, exists := c.store[req.PluginContext.PluginID] | ||
|  | 
 | ||
|  | 	if !exists { | ||
|  | 		return nil, backendplugin.ErrPluginNotRegistered | ||
|  | 	} | ||
|  | 
 | ||
|  | 	return &backend.CollectMetricsResult{ | ||
|  | 		PrometheusMetrics: metrics, | ||
|  | 	}, nil | ||
|  | } |