mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			162 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			162 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
	
| package api
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"io"
 | |
| 	"net/http"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/grafana/grafana-plugin-sdk-go/backend"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| 
 | |
| 	"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"
 | |
| )
 | |
| 
 | |
| 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 := io.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 := io.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 := io.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
 | |
| }
 |