2021-07-15 22:45:59 +08:00
package elasticsearch
import (
2023-09-21 17:33:31 +08:00
"context"
2021-07-15 22:45:59 +08:00
"encoding/json"
"testing"
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/stretchr/testify/require"
2023-01-30 16:50:27 +08:00
"github.com/grafana/grafana/pkg/infra/httpclient"
2024-02-13 20:44:08 +08:00
es "github.com/grafana/grafana/pkg/tsdb/elasticsearch/client"
2021-07-15 22:45:59 +08:00
)
type datasourceInfo struct {
2023-08-30 23:46:47 +08:00
TimeField any ` json:"timeField" `
2024-05-13 21:39:37 +08:00
MaxConcurrentShardRequests any ` json:"maxConcurrentShardRequests,omitempty" `
2023-08-30 23:46:47 +08:00
Interval string ` json:"interval" `
2021-07-15 22:45:59 +08:00
}
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 ) ,
}
2023-09-21 17:33:31 +08:00
_ , err = newInstanceSettings ( httpclient . NewProvider ( ) ) ( context . Background ( ) , dsSettings )
2021-07-15 22:45:59 +08:00
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 ) ,
}
2023-09-21 17:33:31 +08:00
_ , err = newInstanceSettings ( httpclient . NewProvider ( ) ) ( context . Background ( ) , dsSettings )
2021-07-15 22:45:59 +08:00
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 ) ,
}
2023-09-21 17:33:31 +08:00
_ , err = newInstanceSettings ( httpclient . NewProvider ( ) ) ( context . Background ( ) , dsSettings )
2021-07-15 22:45:59 +08:00
require . EqualError ( t , err , "elasticsearch time field name is required" )
} )
} )
2024-05-13 21:39:37 +08:00
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 )
} )
} )
2021-07-15 22:45:59 +08:00
}
2024-02-13 20:44:08 +08:00
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 mappings to cross cluster search that includes ":"
{ 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" } ,
}
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 . String ( ) )
} )
}
}