mirror of https://github.com/grafana/grafana.git
				
				
				
			
		
			
				
	
	
		
			228 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			228 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Go
		
	
	
	
| package elasticsearch
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"encoding/json"
 | |
| 	"testing"
 | |
| 
 | |
| 	"github.com/grafana/grafana-plugin-sdk-go/backend"
 | |
| 	"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
 | |
| 	"github.com/stretchr/testify/require"
 | |
| 
 | |
| 	es "github.com/grafana/grafana/pkg/tsdb/elasticsearch/client"
 | |
| )
 | |
| 
 | |
| type datasourceInfo struct {
 | |
| 	TimeField                  any    `json:"timeField"`
 | |
| 	MaxConcurrentShardRequests any    `json:"maxConcurrentShardRequests,omitempty"`
 | |
| 	Interval                   string `json:"interval"`
 | |
| }
 | |
| 
 | |
| func TestNewInstanceSettings(t *testing.T) {
 | |
| 	t.Run("fields exist", func(t *testing.T) {
 | |
| 		dsInfo := datasourceInfo{
 | |
| 			TimeField:                  "@timestamp",
 | |
| 			MaxConcurrentShardRequests: 5,
 | |
| 		}
 | |
| 		settingsJSON, err := json.Marshal(dsInfo)
 | |
| 		require.NoError(t, err)
 | |
| 
 | |
| 		dsSettings := backend.DataSourceInstanceSettings{
 | |
| 			JSONData: json.RawMessage(settingsJSON),
 | |
| 		}
 | |
| 
 | |
| 		_, err = newInstanceSettings(httpclient.NewProvider())(context.Background(), dsSettings)
 | |
| 		require.NoError(t, err)
 | |
| 	})
 | |
| 
 | |
| 	t.Run("timeField", func(t *testing.T) {
 | |
| 		t.Run("is nil", func(t *testing.T) {
 | |
| 			dsInfo := datasourceInfo{
 | |
| 				MaxConcurrentShardRequests: 5,
 | |
| 				Interval:                   "Daily",
 | |
| 			}
 | |
| 
 | |
| 			settingsJSON, err := json.Marshal(dsInfo)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			dsSettings := backend.DataSourceInstanceSettings{
 | |
| 				JSONData: json.RawMessage(settingsJSON),
 | |
| 			}
 | |
| 
 | |
| 			_, err = newInstanceSettings(httpclient.NewProvider())(context.Background(), dsSettings)
 | |
| 			require.EqualError(t, err, "timeField cannot be cast to string")
 | |
| 		})
 | |
| 
 | |
| 		t.Run("is empty", func(t *testing.T) {
 | |
| 			dsInfo := datasourceInfo{
 | |
| 				MaxConcurrentShardRequests: 5,
 | |
| 				Interval:                   "Daily",
 | |
| 				TimeField:                  "",
 | |
| 			}
 | |
| 
 | |
| 			settingsJSON, err := json.Marshal(dsInfo)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			dsSettings := backend.DataSourceInstanceSettings{
 | |
| 				JSONData: json.RawMessage(settingsJSON),
 | |
| 			}
 | |
| 
 | |
| 			_, err = newInstanceSettings(httpclient.NewProvider())(context.Background(), dsSettings)
 | |
| 			require.EqualError(t, err, "elasticsearch time field name is required")
 | |
| 		})
 | |
| 	})
 | |
| 
 | |
| 	t.Run("maxConcurrentShardRequests", func(t *testing.T) {
 | |
| 		t.Run("no maxConcurrentShardRequests", func(t *testing.T) {
 | |
| 			dsInfo := datasourceInfo{
 | |
| 				TimeField: "@timestamp",
 | |
| 			}
 | |
| 			settingsJSON, err := json.Marshal(dsInfo)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			dsSettings := backend.DataSourceInstanceSettings{
 | |
| 				JSONData: json.RawMessage(settingsJSON),
 | |
| 			}
 | |
| 
 | |
| 			instance, err := newInstanceSettings(httpclient.NewProvider())(context.Background(), dsSettings)
 | |
| 			require.Equal(t, defaultMaxConcurrentShardRequests, instance.(es.DatasourceInfo).MaxConcurrentShardRequests)
 | |
| 			require.NoError(t, err)
 | |
| 		})
 | |
| 
 | |
| 		t.Run("string maxConcurrentShardRequests", func(t *testing.T) {
 | |
| 			dsInfo := datasourceInfo{
 | |
| 				TimeField:                  "@timestamp",
 | |
| 				MaxConcurrentShardRequests: "10",
 | |
| 			}
 | |
| 			settingsJSON, err := json.Marshal(dsInfo)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			dsSettings := backend.DataSourceInstanceSettings{
 | |
| 				JSONData: json.RawMessage(settingsJSON),
 | |
| 			}
 | |
| 
 | |
| 			instance, err := newInstanceSettings(httpclient.NewProvider())(context.Background(), dsSettings)
 | |
| 			require.Equal(t, int64(10), instance.(es.DatasourceInfo).MaxConcurrentShardRequests)
 | |
| 			require.NoError(t, err)
 | |
| 		})
 | |
| 
 | |
| 		t.Run("number maxConcurrentShardRequests", func(t *testing.T) {
 | |
| 			dsInfo := datasourceInfo{
 | |
| 				TimeField:                  "@timestamp",
 | |
| 				MaxConcurrentShardRequests: 10,
 | |
| 			}
 | |
| 			settingsJSON, err := json.Marshal(dsInfo)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			dsSettings := backend.DataSourceInstanceSettings{
 | |
| 				JSONData: json.RawMessage(settingsJSON),
 | |
| 			}
 | |
| 
 | |
| 			instance, err := newInstanceSettings(httpclient.NewProvider())(context.Background(), dsSettings)
 | |
| 			require.Equal(t, int64(10), instance.(es.DatasourceInfo).MaxConcurrentShardRequests)
 | |
| 			require.NoError(t, err)
 | |
| 		})
 | |
| 
 | |
| 		t.Run("zero maxConcurrentShardRequests", func(t *testing.T) {
 | |
| 			dsInfo := datasourceInfo{
 | |
| 				TimeField:                  "@timestamp",
 | |
| 				MaxConcurrentShardRequests: 0,
 | |
| 			}
 | |
| 			settingsJSON, err := json.Marshal(dsInfo)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			dsSettings := backend.DataSourceInstanceSettings{
 | |
| 				JSONData: json.RawMessage(settingsJSON),
 | |
| 			}
 | |
| 
 | |
| 			instance, err := newInstanceSettings(httpclient.NewProvider())(context.Background(), dsSettings)
 | |
| 			require.Equal(t, defaultMaxConcurrentShardRequests, instance.(es.DatasourceInfo).MaxConcurrentShardRequests)
 | |
| 			require.NoError(t, err)
 | |
| 		})
 | |
| 
 | |
| 		t.Run("negative maxConcurrentShardRequests", func(t *testing.T) {
 | |
| 			dsInfo := datasourceInfo{
 | |
| 				TimeField:                  "@timestamp",
 | |
| 				MaxConcurrentShardRequests: -10,
 | |
| 			}
 | |
| 			settingsJSON, err := json.Marshal(dsInfo)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			dsSettings := backend.DataSourceInstanceSettings{
 | |
| 				JSONData: json.RawMessage(settingsJSON),
 | |
| 			}
 | |
| 
 | |
| 			instance, err := newInstanceSettings(httpclient.NewProvider())(context.Background(), dsSettings)
 | |
| 			require.Equal(t, defaultMaxConcurrentShardRequests, instance.(es.DatasourceInfo).MaxConcurrentShardRequests)
 | |
| 			require.NoError(t, err)
 | |
| 		})
 | |
| 
 | |
| 		t.Run("float maxConcurrentShardRequests", func(t *testing.T) {
 | |
| 			dsInfo := datasourceInfo{
 | |
| 				TimeField:                  "@timestamp",
 | |
| 				MaxConcurrentShardRequests: 10.5,
 | |
| 			}
 | |
| 			settingsJSON, err := json.Marshal(dsInfo)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			dsSettings := backend.DataSourceInstanceSettings{
 | |
| 				JSONData: json.RawMessage(settingsJSON),
 | |
| 			}
 | |
| 
 | |
| 			instance, err := newInstanceSettings(httpclient.NewProvider())(context.Background(), dsSettings)
 | |
| 			require.Equal(t, int64(10), instance.(es.DatasourceInfo).MaxConcurrentShardRequests)
 | |
| 			require.NoError(t, err)
 | |
| 		})
 | |
| 
 | |
| 		t.Run("invalid maxConcurrentShardRequests", func(t *testing.T) {
 | |
| 			dsInfo := datasourceInfo{
 | |
| 				TimeField:                  "@timestamp",
 | |
| 				MaxConcurrentShardRequests: "invalid",
 | |
| 			}
 | |
| 			settingsJSON, err := json.Marshal(dsInfo)
 | |
| 			require.NoError(t, err)
 | |
| 
 | |
| 			dsSettings := backend.DataSourceInstanceSettings{
 | |
| 				JSONData: json.RawMessage(settingsJSON),
 | |
| 			}
 | |
| 
 | |
| 			instance, err := newInstanceSettings(httpclient.NewProvider())(context.Background(), dsSettings)
 | |
| 			require.Equal(t, defaultMaxConcurrentShardRequests, instance.(es.DatasourceInfo).MaxConcurrentShardRequests)
 | |
| 			require.NoError(t, err)
 | |
| 		})
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func TestCreateElasticsearchURL(t *testing.T) {
 | |
| 	tt := []struct {
 | |
| 		name     string
 | |
| 		settings es.DatasourceInfo
 | |
| 		req      backend.CallResourceRequest
 | |
| 		expected string
 | |
| 	}{
 | |
| 		{name: "with /_msearch path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "_msearch"}, expected: "http://localhost:9200/_msearch"},
 | |
| 		{name: "with _msearch path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "_msearch"}, expected: "http://localhost:9200/_msearch"},
 | |
| 		{name: "with _msearch path and valid url with /", settings: es.DatasourceInfo{URL: "http://localhost:9200/"}, req: backend.CallResourceRequest{Path: "_msearch"}, expected: "http://localhost:9200/_msearch"},
 | |
| 		{name: "with _mapping path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "/_mapping"}, expected: "http://localhost:9200/_mapping"},
 | |
| 		{name: "with /_mapping path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "/_mapping"}, expected: "http://localhost:9200/_mapping"},
 | |
| 		{name: "with /_mapping path and valid url with /", settings: es.DatasourceInfo{URL: "http://localhost:9200/"}, req: backend.CallResourceRequest{Path: "/_mapping"}, expected: "http://localhost:9200/_mapping"},
 | |
| 		{name: "with abc/_mapping path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "abc/_mapping"}, expected: "http://localhost:9200/abc/_mapping"},
 | |
| 		{name: "with /abc/_mapping path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: "abc/_mapping"}, expected: "http://localhost:9200/abc/_mapping"},
 | |
| 		{name: "with /abc/_mapping path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200/"}, req: backend.CallResourceRequest{Path: "abc/_mapping"}, expected: "http://localhost:9200/abc/_mapping"},
 | |
| 		// This is to support mapping for cluster searches that include ":"
 | |
| 		{name: "with path including :", settings: es.DatasourceInfo{URL: "http://localhost:9200/"}, req: backend.CallResourceRequest{Path: "ab:c/_mapping"}, expected: "http://localhost:9200/ab:c/_mapping"},
 | |
| 		{name: "with \"\" path and valid url and /", settings: es.DatasourceInfo{URL: "http://localhost:9200/"}, req: backend.CallResourceRequest{Path: ""}, expected: "http://localhost:9200/"},
 | |
| 		{name: "with \"\" path and valid url", settings: es.DatasourceInfo{URL: "http://localhost:9200"}, req: backend.CallResourceRequest{Path: ""}, expected: "http://localhost:9200/"},
 | |
| 		{name: "with \"\" path and valid url with path", settings: es.DatasourceInfo{URL: "http://elastic:9200/lb"}, req: backend.CallResourceRequest{Path: ""}, expected: "http://elastic:9200/lb/"},
 | |
| 		{name: "with \"\" path and valid url with path and /", settings: es.DatasourceInfo{URL: "http://elastic:9200/lb/"}, req: backend.CallResourceRequest{Path: ""}, expected: "http://elastic:9200/lb/"},
 | |
| 	}
 | |
| 
 | |
| 	for _, test := range tt {
 | |
| 		t.Run(test.name, func(t *testing.T) {
 | |
| 			url, err := createElasticsearchURL(&test.req, &test.settings)
 | |
| 			require.NoError(t, err)
 | |
| 			require.Equal(t, test.expected, url)
 | |
| 		})
 | |
| 	}
 | |
| }
 |