mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			248 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			248 lines
		
	
	
		
			7.2 KiB
		
	
	
	
		
			Go
		
	
	
	
package promlib
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"fmt"
 | 
						|
	"net/http"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"github.com/grafana/grafana-plugin-sdk-go/backend"
 | 
						|
	"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
 | 
						|
	"github.com/grafana/grafana-plugin-sdk-go/genproto/pluginv2"
 | 
						|
	"github.com/stretchr/testify/assert"
 | 
						|
	"google.golang.org/protobuf/proto"
 | 
						|
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						|
)
 | 
						|
 | 
						|
func Test_ValidateAdmission(t *testing.T) {
 | 
						|
	t.Run("should return error when MutateAdmission fails and response is nil", func(t *testing.T) {
 | 
						|
		httpProvider := getMockProvider[*healthCheckSuccessRoundTripper]()
 | 
						|
		logger := backend.NewLoggerWith("logger", "test")
 | 
						|
		s := &Service{
 | 
						|
			im:     datasource.NewInstanceManager(newInstanceSettings(httpProvider, logger, mockExtendClientOpts)),
 | 
						|
			logger: logger,
 | 
						|
		}
 | 
						|
 | 
						|
		req := &backend.AdmissionRequest{
 | 
						|
			Kind: backend.GroupVersionKind{
 | 
						|
				Group: "grafana-plugin-sdk-go",
 | 
						|
				Kind:  "DataSourceInstanceSettings",
 | 
						|
			},
 | 
						|
			ObjectBytes: []byte(`{"foo":"bar"}`),
 | 
						|
		}
 | 
						|
 | 
						|
		actual, err := s.ValidateAdmission(context.Background(), req)
 | 
						|
		assert.ErrorContains(t, err, "cannot parse invalid")
 | 
						|
		assert.Nil(t, actual)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("should return ValidationResponse when MutateAdmission succeeds", func(t *testing.T) {
 | 
						|
		httpProvider := getMockProvider[*healthCheckSuccessRoundTripper]()
 | 
						|
		logger := backend.NewLoggerWith("logger", "test")
 | 
						|
		s := &Service{
 | 
						|
			im:     datasource.NewInstanceManager(newInstanceSettings(httpProvider, logger, mockExtendClientOpts)),
 | 
						|
			logger: logger,
 | 
						|
		}
 | 
						|
 | 
						|
		pb := &pluginv2.DataSourceInstanceSettings{
 | 
						|
			ApiVersion: "v0alpha1",
 | 
						|
			Url:        "https://grafana.example.com/",
 | 
						|
		}
 | 
						|
		data, err := proto.Marshal(pb)
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		expected := &backend.ValidationResponse{
 | 
						|
			Allowed: true,
 | 
						|
		}
 | 
						|
 | 
						|
		req := &backend.AdmissionRequest{
 | 
						|
			Kind: backend.GroupVersionKind{
 | 
						|
				Group: "grafana-plugin-sdk-go",
 | 
						|
				Kind:  "DataSourceInstanceSettings",
 | 
						|
			},
 | 
						|
			ObjectBytes: data,
 | 
						|
		}
 | 
						|
 | 
						|
		actual, err := s.ValidateAdmission(context.Background(), req)
 | 
						|
		assert.NoError(t, err)
 | 
						|
		assert.Equal(t, expected, actual)
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
func Test_MutateAdmission(t *testing.T) {
 | 
						|
	t.Run("should fail when Kind and Group do not match expected values", func(t *testing.T) {
 | 
						|
		httpProvider := getMockProvider[*healthCheckSuccessRoundTripper]()
 | 
						|
		logger := backend.NewLoggerWith("logger", "test")
 | 
						|
		s := &Service{
 | 
						|
			im:     datasource.NewInstanceManager(newInstanceSettings(httpProvider, logger, mockExtendClientOpts)),
 | 
						|
			logger: logger,
 | 
						|
		}
 | 
						|
 | 
						|
		expected := getBadRequest("expected DataSourceInstanceSettings protobuf payload")
 | 
						|
 | 
						|
		req := &backend.AdmissionRequest{
 | 
						|
			Kind: backend.GroupVersionKind{
 | 
						|
				Group: "example.k8s.io",
 | 
						|
				Kind:  "Pod",
 | 
						|
			},
 | 
						|
		}
 | 
						|
 | 
						|
		actual, err := s.MutateAdmission(context.Background(), req)
 | 
						|
		assert.NoError(t, err)
 | 
						|
		assert.Equal(t, expected, actual)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("should return an error when object bytes is nil", func(t *testing.T) {
 | 
						|
		httpProvider := getMockProvider[*healthCheckSuccessRoundTripper]()
 | 
						|
		logger := backend.NewLoggerWith("logger", "test")
 | 
						|
		s := &Service{
 | 
						|
			im:     datasource.NewInstanceManager(newInstanceSettings(httpProvider, logger, mockExtendClientOpts)),
 | 
						|
			logger: logger,
 | 
						|
		}
 | 
						|
 | 
						|
		expected := getBadRequest("missing datasource settings")
 | 
						|
 | 
						|
		req := &backend.AdmissionRequest{
 | 
						|
			Kind: backend.GroupVersionKind{
 | 
						|
				Group: "grafana-plugin-sdk-go",
 | 
						|
				Kind:  "DataSourceInstanceSettings",
 | 
						|
			},
 | 
						|
		}
 | 
						|
 | 
						|
		actual, err := s.MutateAdmission(context.Background(), req)
 | 
						|
		assert.NoError(t, err)
 | 
						|
		assert.Equal(t, expected, actual)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("should return an error when protobuf payload conversion fails", func(t *testing.T) {
 | 
						|
		httpProvider := getMockProvider[*healthCheckSuccessRoundTripper]()
 | 
						|
		logger := backend.NewLoggerWith("logger", "test")
 | 
						|
		s := &Service{
 | 
						|
			im:     datasource.NewInstanceManager(newInstanceSettings(httpProvider, logger, mockExtendClientOpts)),
 | 
						|
			logger: logger,
 | 
						|
		}
 | 
						|
 | 
						|
		req := &backend.AdmissionRequest{
 | 
						|
			Kind: backend.GroupVersionKind{
 | 
						|
				Group: "grafana-plugin-sdk-go",
 | 
						|
				Kind:  "DataSourceInstanceSettings",
 | 
						|
			},
 | 
						|
			ObjectBytes: []byte(`{"foo":"bar"}`),
 | 
						|
		}
 | 
						|
 | 
						|
		actual, err := s.MutateAdmission(context.Background(), req)
 | 
						|
		assert.ErrorContains(t, err, "cannot parse invalid")
 | 
						|
		assert.Nil(t, actual)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("should return bad request error when settings APIVersion is invalid", func(t *testing.T) {
 | 
						|
		httpProvider := getMockProvider[*healthCheckSuccessRoundTripper]()
 | 
						|
		logger := backend.NewLoggerWith("logger", "test")
 | 
						|
		s := &Service{
 | 
						|
			im:     datasource.NewInstanceManager(newInstanceSettings(httpProvider, logger, mockExtendClientOpts)),
 | 
						|
			logger: logger,
 | 
						|
		}
 | 
						|
 | 
						|
		pb := &pluginv2.DataSourceInstanceSettings{
 | 
						|
			ApiVersion: "v0alpha2",
 | 
						|
		}
 | 
						|
		data, err := proto.Marshal(pb)
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		expected := getBadRequest(fmt.Sprintf("expected apiVersion: v0alpha1, found: %s", pb.ApiVersion))
 | 
						|
 | 
						|
		req := &backend.AdmissionRequest{
 | 
						|
			Kind: backend.GroupVersionKind{
 | 
						|
				Group: "grafana-plugin-sdk-go",
 | 
						|
				Kind:  "DataSourceInstanceSettings",
 | 
						|
			},
 | 
						|
			ObjectBytes: data,
 | 
						|
		}
 | 
						|
 | 
						|
		actual, err := s.MutateAdmission(context.Background(), req)
 | 
						|
		assert.NoError(t, err)
 | 
						|
		assert.Equal(t, expected, actual)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("should return bad request error when settings URL is invalid", func(t *testing.T) {
 | 
						|
		httpProvider := getMockProvider[*healthCheckSuccessRoundTripper]()
 | 
						|
		logger := backend.NewLoggerWith("logger", "test")
 | 
						|
		s := &Service{
 | 
						|
			im:     datasource.NewInstanceManager(newInstanceSettings(httpProvider, logger, mockExtendClientOpts)),
 | 
						|
			logger: logger,
 | 
						|
		}
 | 
						|
 | 
						|
		pb := &pluginv2.DataSourceInstanceSettings{
 | 
						|
			ApiVersion: "v0alpha1",
 | 
						|
		}
 | 
						|
		data, err := proto.Marshal(pb)
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		expected := getBadRequest("missing URL value")
 | 
						|
 | 
						|
		req := &backend.AdmissionRequest{
 | 
						|
			Kind: backend.GroupVersionKind{
 | 
						|
				Group: "grafana-plugin-sdk-go",
 | 
						|
				Kind:  "DataSourceInstanceSettings",
 | 
						|
			},
 | 
						|
			ObjectBytes: data,
 | 
						|
		}
 | 
						|
 | 
						|
		actual, err := s.MutateAdmission(context.Background(), req)
 | 
						|
		assert.NoError(t, err)
 | 
						|
		assert.Equal(t, expected, actual)
 | 
						|
	})
 | 
						|
 | 
						|
	t.Run("should return successfully mutation response", func(t *testing.T) {
 | 
						|
		httpProvider := getMockProvider[*healthCheckSuccessRoundTripper]()
 | 
						|
		logger := backend.NewLoggerWith("logger", "test")
 | 
						|
		s := &Service{
 | 
						|
			im:     datasource.NewInstanceManager(newInstanceSettings(httpProvider, logger, mockExtendClientOpts)),
 | 
						|
			logger: logger,
 | 
						|
		}
 | 
						|
 | 
						|
		pb := &pluginv2.DataSourceInstanceSettings{
 | 
						|
			ApiVersion: "v0alpha1",
 | 
						|
			Url:        "https://grafana.example.com/",
 | 
						|
		}
 | 
						|
		data, err := proto.Marshal(pb)
 | 
						|
		assert.NoError(t, err)
 | 
						|
 | 
						|
		expected := &backend.MutationResponse{
 | 
						|
			Allowed:     true,
 | 
						|
			ObjectBytes: data,
 | 
						|
		}
 | 
						|
 | 
						|
		req := &backend.AdmissionRequest{
 | 
						|
			Kind: backend.GroupVersionKind{
 | 
						|
				Group: "grafana-plugin-sdk-go",
 | 
						|
				Kind:  "DataSourceInstanceSettings",
 | 
						|
			},
 | 
						|
			ObjectBytes: data,
 | 
						|
		}
 | 
						|
 | 
						|
		actual, err := s.MutateAdmission(context.Background(), req)
 | 
						|
		assert.NoError(t, err)
 | 
						|
		assert.Equal(t, expected, actual)
 | 
						|
	})
 | 
						|
}
 | 
						|
 | 
						|
func Test_getBadRequest(t *testing.T) {
 | 
						|
	t.Run("should get a successful bad request", func(t *testing.T) {
 | 
						|
		msg := "missing URL value"
 | 
						|
 | 
						|
		expected := &backend.MutationResponse{
 | 
						|
			Allowed: false,
 | 
						|
			Result: &backend.StatusResult{
 | 
						|
				Status:  "Failure",
 | 
						|
				Message: "missing URL value",
 | 
						|
				Reason:  string(metav1.StatusReasonBadRequest),
 | 
						|
				Code:    http.StatusBadRequest,
 | 
						|
			},
 | 
						|
		}
 | 
						|
 | 
						|
		actual := getBadRequest(msg)
 | 
						|
		assert.Equal(t, expected, actual)
 | 
						|
	})
 | 
						|
}
 |