2020-04-27 10:43:02 -05:00
package azuremonitor
import (
2021-06-11 10:02:24 -05:00
"context"
2020-04-27 10:43:02 -05:00
"fmt"
2021-06-11 10:02:24 -05:00
"net/http"
2020-04-27 10:43:02 -05:00
"net/url"
2021-06-29 03:39:28 -05:00
"strings"
2020-04-27 10:43:02 -05:00
"testing"
"time"
"github.com/google/go-cmp/cmp"
2021-06-07 07:54:51 -05:00
"github.com/grafana/grafana-plugin-sdk-go/backend"
2020-04-27 10:43:02 -05:00
"github.com/stretchr/testify/require"
)
func TestBuildingAzureLogAnalyticsQueries ( t * testing . T ) {
datasource := & AzureLogAnalyticsDatasource { }
fromStart := time . Date ( 2018 , 3 , 15 , 13 , 0 , 0 , 0 , time . UTC ) . In ( time . Local )
2021-06-07 07:54:51 -05:00
timeRange := backend . TimeRange { From : fromStart , To : fromStart . Add ( 34 * time . Minute ) }
2021-05-20 03:16:29 -05:00
2020-04-27 10:43:02 -05:00
tests := [ ] struct {
name string
2021-06-07 07:54:51 -05:00
queryModel [ ] backend . DataQuery
2020-04-27 10:43:02 -05:00
azureLogAnalyticsQueries [ ] * AzureLogAnalyticsQuery
Err require . ErrorAssertionFunc
} {
{
2021-06-07 07:54:51 -05:00
name : "Query with macros should be interpolated" ,
queryModel : [ ] backend . DataQuery {
2021-05-19 11:39:08 -05:00
{
2021-06-07 07:54:51 -05:00
JSON : [ ] byte ( fmt . Sprintf ( ` {
2021-05-19 11:39:08 -05:00
"queryType" : "Azure Log Analytics" ,
2021-06-07 07:54:51 -05:00
"azureLogAnalytics" : {
2021-05-19 11:39:08 -05:00
"resource" : "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace" ,
"query" : "query=Perf | where $__timeFilter() | where $__contains(Computer, 'comp1','comp2') | summarize avg(CounterValue) by bin(TimeGenerated, $__interval), Computer" ,
2021-06-07 07:54:51 -05:00
"resultFormat" : "%s"
}
} ` , timeSeries ) ) ,
RefID : "A" ,
TimeRange : timeRange ,
2021-05-19 11:39:08 -05:00
} ,
} ,
azureLogAnalyticsQueries : [ ] * AzureLogAnalyticsQuery {
{
RefID : "A" ,
ResultFormat : timeSeries ,
URL : "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query" ,
2021-06-07 07:54:51 -05:00
JSON : [ ] byte ( fmt . Sprintf ( ` {
"queryType" : "Azure Log Analytics" ,
"azureLogAnalytics" : {
"resource" : "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace" ,
2021-05-19 11:39:08 -05:00
"query" : "query=Perf | where $__timeFilter() | where $__contains(Computer, 'comp1','comp2') | summarize avg(CounterValue) by bin(TimeGenerated, $__interval), Computer" ,
2021-06-07 07:54:51 -05:00
"resultFormat" : "%s"
}
} ` , timeSeries ) ) ,
Params : url . Values { "query" : { "query=Perf | where ['TimeGenerated'] >= datetime('2018-03-15T13:00:00Z') and ['TimeGenerated'] <= datetime('2018-03-15T13:34:00Z') | where ['Computer'] in ('comp1','comp2') | summarize avg(CounterValue) by bin(TimeGenerated, 34000ms), Computer" } } ,
Target : "query=query%3DPerf+%7C+where+%5B%27TimeGenerated%27%5D+%3E%3D+datetime%28%272018-03-15T13%3A00%3A00Z%27%29+and+%5B%27TimeGenerated%27%5D+%3C%3D+datetime%28%272018-03-15T13%3A34%3A00Z%27%29+%7C+where+%5B%27Computer%27%5D+in+%28%27comp1%27%2C%27comp2%27%29+%7C+summarize+avg%28CounterValue%29+by+bin%28TimeGenerated%2C+34000ms%29%2C+Computer" ,
TimeRange : timeRange ,
2021-05-19 11:39:08 -05:00
} ,
} ,
Err : require . NoError ,
2021-05-20 03:16:29 -05:00
} ,
{
2021-06-07 07:54:51 -05:00
name : "Legacy queries with a workspace GUID should use workspace-centric url" ,
queryModel : [ ] backend . DataQuery {
2020-04-27 10:43:02 -05:00
{
2021-06-07 07:54:51 -05:00
JSON : [ ] byte ( fmt . Sprintf ( ` {
2020-04-27 10:43:02 -05:00
"queryType" : "Azure Log Analytics" ,
2021-06-07 07:54:51 -05:00
"azureLogAnalytics" : {
2020-04-27 10:43:02 -05:00
"workspace" : "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" ,
2021-05-20 03:16:29 -05:00
"query" : "query=Perf" ,
2021-06-07 07:54:51 -05:00
"resultFormat" : "%s"
}
} ` , timeSeries ) ) ,
2021-03-08 00:02:49 -06:00
RefID : "A" ,
2020-04-27 10:43:02 -05:00
} ,
} ,
azureLogAnalyticsQueries : [ ] * AzureLogAnalyticsQuery {
{
RefID : "A" ,
2021-05-19 03:31:27 -05:00
ResultFormat : timeSeries ,
2021-05-19 11:39:08 -05:00
URL : "v1/workspaces/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/query" ,
2021-06-07 07:54:51 -05:00
JSON : [ ] byte ( fmt . Sprintf ( ` {
"queryType" : "Azure Log Analytics" ,
"azureLogAnalytics" : {
2020-05-11 12:11:03 -05:00
"workspace" : "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" ,
2021-05-20 03:16:29 -05:00
"query" : "query=Perf" ,
2021-06-07 07:54:51 -05:00
"resultFormat" : "%s"
}
} ` , timeSeries ) ) ,
2021-05-20 03:16:29 -05:00
Params : url . Values { "query" : { "query=Perf" } } ,
Target : "query=query%3DPerf" ,
} ,
} ,
Err : require . NoError ,
} ,
{
2021-06-07 07:54:51 -05:00
name : "Legacy workspace queries with a resource URI (from a template variable) should use resource-centric url" ,
queryModel : [ ] backend . DataQuery {
2021-05-20 03:16:29 -05:00
{
2021-06-07 07:54:51 -05:00
JSON : [ ] byte ( fmt . Sprintf ( ` {
2021-05-20 03:16:29 -05:00
"queryType" : "Azure Log Analytics" ,
2021-06-07 07:54:51 -05:00
"azureLogAnalytics" : {
2021-05-20 03:16:29 -05:00
"workspace" : "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace" ,
"query" : "query=Perf" ,
2021-06-07 07:54:51 -05:00
"resultFormat" : "%s"
}
} ` , timeSeries ) ) ,
2021-05-20 03:16:29 -05:00
RefID : "A" ,
} ,
} ,
azureLogAnalyticsQueries : [ ] * AzureLogAnalyticsQuery {
{
RefID : "A" ,
ResultFormat : timeSeries ,
URL : "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query" ,
2021-06-07 07:54:51 -05:00
JSON : [ ] byte ( fmt . Sprintf ( ` {
"queryType" : "Azure Log Analytics" ,
"azureLogAnalytics" : {
2021-05-20 03:16:29 -05:00
"workspace" : "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace" ,
"query" : "query=Perf" ,
2021-06-07 07:54:51 -05:00
"resultFormat" : "%s"
}
} ` , timeSeries ) ) ,
2021-05-20 03:16:29 -05:00
Params : url . Values { "query" : { "query=Perf" } } ,
Target : "query=query%3DPerf" ,
} ,
} ,
Err : require . NoError ,
} ,
{
2021-06-07 07:54:51 -05:00
name : "Queries with a Resource should use resource-centric url" ,
queryModel : [ ] backend . DataQuery {
2021-05-20 03:16:29 -05:00
{
2021-06-07 07:54:51 -05:00
JSON : [ ] byte ( fmt . Sprintf ( ` {
2021-05-20 03:16:29 -05:00
"queryType" : "Azure Log Analytics" ,
2021-06-07 07:54:51 -05:00
"azureLogAnalytics" : {
2021-05-20 03:16:29 -05:00
"resource" : "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace" ,
"query" : "query=Perf" ,
2021-06-07 07:54:51 -05:00
"resultFormat" : "%s"
}
} ` , timeSeries ) ) ,
2021-05-20 03:16:29 -05:00
RefID : "A" ,
} ,
} ,
azureLogAnalyticsQueries : [ ] * AzureLogAnalyticsQuery {
{
RefID : "A" ,
ResultFormat : timeSeries ,
URL : "v1/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace/query" ,
2021-06-07 07:54:51 -05:00
JSON : [ ] byte ( fmt . Sprintf ( ` {
"queryType" : "Azure Log Analytics" ,
"azureLogAnalytics" : {
2021-05-20 03:16:29 -05:00
"resource" : "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/cloud-datasources/providers/Microsoft.OperationalInsights/workspaces/AppInsightsTestDataWorkspace" ,
"query" : "query=Perf" ,
2021-06-07 07:54:51 -05:00
"resultFormat" : "%s"
}
} ` , timeSeries ) ) ,
2021-05-20 03:16:29 -05:00
Params : url . Values { "query" : { "query=Perf" } } ,
Target : "query=query%3DPerf" ,
2020-04-27 10:43:02 -05:00
} ,
} ,
Err : require . NoError ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
2021-06-07 07:54:51 -05:00
queries , err := datasource . buildQueries ( tt . queryModel , datasourceInfo { } )
2020-04-27 10:43:02 -05:00
tt . Err ( t , err )
2021-06-07 07:54:51 -05:00
if diff := cmp . Diff ( tt . azureLogAnalyticsQueries [ 0 ] , queries [ 0 ] ) ; diff != "" {
2020-04-27 10:43:02 -05:00
t . Errorf ( "Result mismatch (-want +got):\n%s" , diff )
}
} )
}
}
2021-06-11 10:02:24 -05:00
func TestLogAnalyticsCreateRequest ( t * testing . T ) {
ctx := context . Background ( )
2021-07-16 05:47:26 -05:00
url := "http://ds"
dsInfo := datasourceInfo { }
2020-04-27 10:43:02 -05:00
tests := [ ] struct {
2021-06-11 10:02:24 -05:00
name string
expectedURL string
expectedHeaders http . Header
Err require . ErrorAssertionFunc
2020-04-27 10:43:02 -05:00
} {
{
2021-06-11 10:02:24 -05:00
name : "creates a request" ,
expectedURL : "http://ds/" ,
expectedHeaders : http . Header { "Content-Type" : [ ] string { "application/json" } } ,
Err : require . NoError ,
2020-04-27 10:43:02 -05:00
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
2021-06-11 10:02:24 -05:00
ds := AzureLogAnalyticsDatasource { }
2021-07-16 05:47:26 -05:00
req , err := ds . createRequest ( ctx , dsInfo , url )
2020-04-27 10:43:02 -05:00
tt . Err ( t , err )
2021-06-11 10:02:24 -05:00
if req . URL . String ( ) != tt . expectedURL {
t . Errorf ( "Expecting %s, got %s" , tt . expectedURL , req . URL . String ( ) )
2020-04-27 10:43:02 -05:00
}
2021-06-11 10:02:24 -05:00
if ! cmp . Equal ( req . Header , tt . expectedHeaders ) {
t . Errorf ( "Unexpected HTTP headers: %v" , cmp . Diff ( req . Header , tt . expectedHeaders ) )
2020-04-27 10:43:02 -05:00
}
} )
}
}
2021-06-29 03:39:28 -05:00
func Test_executeQueryErrorWithDifferentLogAnalyticsCreds ( t * testing . T ) {
ds := AzureLogAnalyticsDatasource { }
dsInfo := datasourceInfo {
Services : map [ string ] datasourceService {
azureLogAnalytics : { URL : "http://ds" } ,
} ,
2021-07-14 02:53:24 -05:00
JSONData : map [ string ] interface { } {
"azureLogAnalyticsSameAs" : false ,
} ,
2021-06-29 03:39:28 -05:00
}
ctx := context . TODO ( )
query := & AzureLogAnalyticsQuery {
Params : url . Values { } ,
TimeRange : backend . TimeRange { } ,
}
2021-07-16 05:47:26 -05:00
res := ds . executeQuery ( ctx , query , dsInfo , & http . Client { } , dsInfo . Services [ azureLogAnalytics ] . URL )
2021-06-29 03:39:28 -05:00
if res . Error == nil {
t . Fatal ( "expecting an error" )
}
if ! strings . Contains ( res . Error . Error ( ) , "Log Analytics credentials are no longer supported" ) {
t . Error ( "expecting the error to inform of bad credentials" )
}
}