2022-03-02 22:41:07 +08:00
package metrics
2019-02-09 00:20:31 +08:00
import (
2021-06-11 23:02:24 +08:00
"context"
2019-02-09 01:15:17 +08:00
"encoding/json"
2019-02-09 00:20:31 +08:00
"fmt"
2021-06-11 23:02:24 +08:00
"net/http"
2019-02-10 04:52:44 +08:00
"net/url"
2022-08-10 21:37:51 +08:00
"os"
2020-04-27 23:43:02 +08:00
"path/filepath"
2019-02-09 00:20:31 +08:00
"testing"
"time"
2020-06-02 00:37:39 +08:00
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
2021-06-07 20:54:51 +08:00
"github.com/grafana/grafana-plugin-sdk-go/backend"
2020-06-02 00:37:39 +08:00
"github.com/grafana/grafana-plugin-sdk-go/data"
2022-12-02 20:17:11 +08:00
"github.com/stretchr/testify/assert"
2022-11-04 21:28:38 +08:00
"github.com/stretchr/testify/require"
ptr "github.com/xorcare/pointer"
2019-02-09 00:20:31 +08:00
"github.com/grafana/grafana/pkg/components/simplejson"
2022-11-04 21:28:38 +08:00
"github.com/grafana/grafana/pkg/infra/log"
2022-03-02 22:41:07 +08:00
azTime "github.com/grafana/grafana/pkg/tsdb/azuremonitor/time"
"github.com/grafana/grafana/pkg/tsdb/azuremonitor/types"
2019-02-09 00:20:31 +08:00
)
2020-06-02 00:37:39 +08:00
func TestAzureMonitorBuildQueries ( t * testing . T ) {
datasource := & AzureMonitorDatasource { }
2022-03-02 22:41:07 +08:00
dsInfo := types . DatasourceInfo {
Settings : types . AzureMonitorSettings {
2021-06-07 20:54:51 +08:00
SubscriptionId : "default-subscription" ,
} ,
}
2020-06-02 00:37:39 +08:00
fromStart := time . Date ( 2018 , 3 , 15 , 13 , 0 , 0 , 0 , time . UTC ) . In ( time . Local )
2021-06-07 20:54:51 +08:00
duration , _ := time . ParseDuration ( "400s" )
2022-05-10 22:05:48 +08:00
wildcardFilter := "*"
testFilter := "test"
2020-06-02 00:37:39 +08:00
tests := [ ] struct {
name string
azureMonitorVariedProperties map [ string ] interface { }
azureMonitorQueryTarget string
expectedInterval string
2021-06-07 20:54:51 +08:00
queryInterval time . Duration
2022-10-07 20:57:01 +08:00
expectedURL string
expectedFilter string
2020-06-02 00:37:39 +08:00
} {
{
name : "Parse queries from frontend and build AzureMonitor API queries" ,
azureMonitorVariedProperties : map [ string ] interface { } {
2022-04-26 10:30:28 +08:00
"resourceURI" : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana" ,
"timeGrain" : "PT1M" ,
"top" : "10" ,
2020-06-02 00:37:39 +08:00
} ,
expectedInterval : "PT1M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z" ,
2020-06-02 00:37:39 +08:00
} ,
{
2022-04-26 10:30:28 +08:00
name : "legacy query without resourceURI and time grain set to auto" ,
2020-06-02 00:37:39 +08:00
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "auto" ,
"top" : "10" ,
} ,
2021-06-07 20:54:51 +08:00
queryInterval : duration ,
2020-06-02 00:37:39 +08:00
expectedInterval : "PT15M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT15M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z" ,
2020-06-02 00:37:39 +08:00
} ,
{
2022-04-26 10:30:28 +08:00
name : "legacy query without resourceURI and time grain set to auto" ,
2020-06-02 00:37:39 +08:00
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "auto" ,
"allowedTimeGrainsMs" : [ ] int64 { 60000 , 300000 } ,
"top" : "10" ,
} ,
2021-06-07 20:54:51 +08:00
queryInterval : duration ,
2020-06-02 00:37:39 +08:00
expectedInterval : "PT5M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT5M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z" ,
2020-06-02 00:37:39 +08:00
} ,
{
2022-04-26 10:30:28 +08:00
name : "legacy query without resourceURI and has a dimension filter" ,
2020-06-02 00:37:39 +08:00
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
"dimension" : "blob" ,
"dimensionFilter" : "*" ,
"top" : "30" ,
} ,
2021-06-07 20:54:51 +08:00
queryInterval : duration ,
2020-06-02 00:37:39 +08:00
expectedInterval : "PT1M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30" ,
expectedFilter : "blob eq '*'" ,
2020-06-02 00:37:39 +08:00
} ,
{
2022-04-26 10:30:28 +08:00
name : "legacy query without resourceURI and has a dimension filter and none Dimension" ,
2020-06-02 00:37:39 +08:00
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
"dimension" : "None" ,
"dimensionFilter" : "*" ,
"top" : "10" ,
} ,
2021-06-07 20:54:51 +08:00
queryInterval : duration ,
2020-06-02 00:37:39 +08:00
expectedInterval : "PT1M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z" ,
2020-06-02 00:37:39 +08:00
} ,
2020-07-01 04:26:46 +08:00
{
2022-04-26 10:30:28 +08:00
name : "legacy query without resourceURI and has dimensionFilter*s* property with one dimension" ,
2020-07-01 04:26:46 +08:00
azureMonitorVariedProperties : map [ string ] interface { } {
2020-09-09 03:12:08 +08:00
"timeGrain" : "PT1M" ,
2022-05-10 22:05:48 +08:00
"dimensionFilters" : [ ] types . AzureMonitorDimensionFilter { { Dimension : "blob" , Operator : "eq" , Filter : & wildcardFilter } } ,
2020-09-09 03:12:08 +08:00
"top" : "30" ,
2020-07-01 04:26:46 +08:00
} ,
2021-06-07 20:54:51 +08:00
queryInterval : duration ,
2020-07-01 04:26:46 +08:00
expectedInterval : "PT1M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30" ,
expectedFilter : "blob eq '*'" ,
2020-07-01 04:26:46 +08:00
} ,
{
2022-04-26 10:30:28 +08:00
name : "legacy query without resourceURI and has dimensionFilter*s* property with two dimensions" ,
2020-07-01 04:26:46 +08:00
azureMonitorVariedProperties : map [ string ] interface { } {
2020-09-09 03:12:08 +08:00
"timeGrain" : "PT1M" ,
2022-05-10 22:05:48 +08:00
"dimensionFilters" : [ ] types . AzureMonitorDimensionFilter { { Dimension : "blob" , Operator : "eq" , Filter : & wildcardFilter } , { Dimension : "tier" , Operator : "eq" , Filter : & wildcardFilter } } ,
2020-09-09 03:12:08 +08:00
"top" : "30" ,
2020-07-01 04:26:46 +08:00
} ,
2021-06-07 20:54:51 +08:00
queryInterval : duration ,
2020-07-01 04:26:46 +08:00
expectedInterval : "PT1M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30" ,
expectedFilter : "blob eq '*' and tier eq '*'" ,
2020-07-01 04:26:46 +08:00
} ,
2022-03-29 22:27:09 +08:00
{
2022-04-26 10:30:28 +08:00
name : "legacy query without resourceURI and has a dimension filter without specifying a top" ,
2022-03-29 22:27:09 +08:00
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
"dimension" : "blob" ,
"dimensionFilter" : "*" ,
} ,
queryInterval : duration ,
expectedInterval : "PT1M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z" ,
expectedFilter : "blob eq '*'" ,
2022-03-29 22:27:09 +08:00
} ,
2022-04-30 00:01:13 +08:00
{
name : "has dimensionFilter*s* property with not equals operator" ,
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
2022-05-10 22:05:48 +08:00
"dimensionFilters" : [ ] types . AzureMonitorDimensionFilter { { Dimension : "blob" , Operator : "ne" , Filter : & wildcardFilter , Filters : [ ] string { "test" } } } ,
2022-04-30 00:01:13 +08:00
"top" : "30" ,
} ,
queryInterval : duration ,
expectedInterval : "PT1M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30" ,
expectedFilter : "blob ne 'test'" ,
2022-04-30 00:01:13 +08:00
} ,
{
name : "has dimensionFilter*s* property with startsWith operator" ,
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
2022-05-10 22:05:48 +08:00
"dimensionFilters" : [ ] types . AzureMonitorDimensionFilter { { Dimension : "blob" , Operator : "sw" , Filter : & testFilter } } ,
2022-04-30 00:01:13 +08:00
"top" : "30" ,
} ,
queryInterval : duration ,
expectedInterval : "PT1M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30" ,
expectedFilter : "blob sw 'test'" ,
2022-04-30 00:01:13 +08:00
} ,
{
name : "correctly sets dimension operator to eq (irrespective of operator) when filter value is '*'" ,
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
2022-05-10 22:05:48 +08:00
"dimensionFilters" : [ ] types . AzureMonitorDimensionFilter { { Dimension : "blob" , Operator : "sw" , Filter : & wildcardFilter } , { Dimension : "tier" , Operator : "ne" , Filter : & wildcardFilter } } ,
2022-04-30 00:01:13 +08:00
"top" : "30" ,
} ,
queryInterval : duration ,
expectedInterval : "PT1M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30" ,
expectedFilter : "blob eq '*' and tier eq '*'" ,
2022-04-30 00:01:13 +08:00
} ,
2022-05-10 22:05:48 +08:00
{
name : "correctly constructs target when multiple filter values are provided for the 'eq' operator" ,
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
"dimensionFilters" : [ ] types . AzureMonitorDimensionFilter { { Dimension : "blob" , Operator : "eq" , Filter : & wildcardFilter , Filters : [ ] string { "test" , "test2" } } } ,
"top" : "30" ,
} ,
queryInterval : duration ,
expectedInterval : "PT1M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30" ,
expectedFilter : "blob eq 'test' or blob eq 'test2'" ,
2022-05-10 22:05:48 +08:00
} ,
{
name : "correctly constructs target when multiple filter values are provided for ne 'eq' operator" ,
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
"dimensionFilters" : [ ] types . AzureMonitorDimensionFilter { { Dimension : "blob" , Operator : "ne" , Filter : & wildcardFilter , Filters : [ ] string { "test" , "test2" } } } ,
"top" : "30" ,
} ,
queryInterval : duration ,
expectedInterval : "PT1M" ,
2022-10-07 20:57:01 +08:00
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30" ,
expectedFilter : "blob ne 'test' and blob ne 'test2'" ,
} ,
{
name : "Includes a region" ,
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
"top" : "10" ,
"region" : "westus" ,
} ,
expectedInterval : "PT1M" ,
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines®ion=westus×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z" ,
expectedURL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/providers/microsoft.insights/metrics" ,
} ,
2022-12-02 20:17:11 +08:00
{
name : "Includes a region and a filter" ,
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
"top" : "10" ,
"region" : "westus" ,
"resources" : [ ] types . AzureMonitorResource { { ResourceGroup : "rg" , ResourceName : "vm" } } ,
} ,
expectedInterval : "PT1M" ,
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines®ion=westus×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z" ,
expectedURL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/providers/microsoft.insights/metrics" ,
expectedFilter : "Microsoft.ResourceId eq '/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/vm'" ,
} ,
2022-10-07 20:57:01 +08:00
{
name : "includes a resource as a filter" ,
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
"resources" : [ ] types . AzureMonitorResource { { ResourceGroup : "rg" , ResourceName : "vm" } } ,
} ,
queryInterval : duration ,
expectedInterval : "PT1M" ,
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z" ,
expectedFilter : "Microsoft.ResourceId eq '/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/vm'" ,
} ,
{
name : "includes a resource and a dimesion as filters" ,
azureMonitorVariedProperties : map [ string ] interface { } {
"timeGrain" : "PT1M" ,
"resources" : [ ] types . AzureMonitorResource { { ResourceGroup : "rg" , ResourceName : "vm" } } ,
"dimensionFilters" : [ ] types . AzureMonitorDimensionFilter { { Dimension : "blob" , Operator : "ne" , Filter : & wildcardFilter , Filters : [ ] string { "test" , "test2" } } } ,
"top" : "30" ,
} ,
queryInterval : duration ,
expectedInterval : "PT1M" ,
azureMonitorQueryTarget : "aggregation=Average&api-version=2021-05-01&interval=PT1M&metricnames=Percentage+CPU&metricnamespace=Microsoft.Compute%2FvirtualMachines×pan=2018-03-15T13%3A00%3A00Z%2F2018-03-15T13%3A34%3A00Z&top=30" ,
expectedFilter : "(Microsoft.ResourceId eq '/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/rg/providers/Microsoft.Compute/virtualMachines/vm') and (blob ne 'test' and blob ne 'test2')" ,
2022-05-10 22:05:48 +08:00
} ,
2020-06-02 00:37:39 +08:00
}
commonAzureModelProps := map [ string ] interface { } {
2022-07-27 21:26:32 +08:00
"aggregation" : "Average" ,
"resourceGroup" : "grafanastaging" ,
"resourceName" : "grafana" ,
"metricNamespace" : "Microsoft.Compute/virtualMachines" ,
"metricName" : "Percentage CPU" ,
2019-02-09 00:20:31 +08:00
2020-06-02 00:37:39 +08:00
"alias" : "testalias" ,
"queryType" : "Azure Monitor" ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
for k , v := range commonAzureModelProps {
tt . azureMonitorVariedProperties [ k ] = v
}
2021-06-07 20:54:51 +08:00
azureMonitorJSON , _ := json . Marshal ( tt . azureMonitorVariedProperties )
tsdbQuery := [ ] backend . DataQuery {
{
JSON : [ ] byte ( fmt . Sprintf ( ` {
2019-05-21 18:28:30 +08:00
"subscription" : "12345678-aaaa-bbbb-cccc-123456789abc" ,
2021-06-07 20:54:51 +08:00
"azureMonitor" : % s
} ` , string ( azureMonitorJSON ) ) ) ,
RefID : "A" ,
Interval : tt . queryInterval ,
TimeRange : backend . TimeRange {
From : fromStart ,
To : fromStart . Add ( 34 * time . Minute ) ,
2019-02-09 00:20:31 +08:00
} ,
} ,
}
2019-02-10 08:47:38 +08:00
2022-12-02 20:17:11 +08:00
queries , err := datasource . buildQueries ( log . New ( "test" ) , tsdbQuery , dsInfo )
require . NoError ( t , err )
2022-03-02 22:41:07 +08:00
azureMonitorQuery := & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : tt . expectedURL ,
Target : tt . azureMonitorQueryTarget ,
RefID : "A" ,
Alias : "testalias" ,
2021-06-07 20:54:51 +08:00
TimeRange : backend . TimeRange {
From : fromStart ,
To : fromStart . Add ( 34 * time . Minute ) ,
} ,
2022-12-02 20:17:11 +08:00
}
if tt . azureMonitorVariedProperties [ "region" ] != nil {
// If the region is included, the filter will be added in the Body of the request
azureMonitorQuery . BodyFilter = tt . expectedFilter
} else {
// In other case, the filter will be added in the URL
if tt . expectedFilter != "" {
assert . Equal ( t , tt . expectedFilter , queries [ 0 ] . Params . Get ( "$filter" ) )
} else {
assert . Equal ( t , false , queries [ 0 ] . Params . Has ( "$filter" ) )
}
2022-10-07 20:57:01 +08:00
}
if azureMonitorQuery . URL == "" {
azureMonitorQuery . URL = "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics"
2020-06-02 00:37:39 +08:00
}
2019-07-05 04:47:24 +08:00
2022-03-02 22:41:07 +08:00
if diff := cmp . Diff ( azureMonitorQuery , queries [ 0 ] , cmpopts . IgnoreUnexported ( simplejson . Json { } ) , cmpopts . IgnoreFields ( types . AzureMonitorQuery { } , "Params" ) ) ; diff != "" {
2020-06-02 00:37:39 +08:00
t . Errorf ( "Result mismatch (-want +got):\n%s" , diff )
}
2021-09-28 21:24:18 +08:00
expected := ` http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/ ` +
` TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%222018-03-15T13%3A00%3A00Z%22%2C%22endTime%22%3A%222018-03-15T13%3A34%3A00Z%22%7D%7D/ ` +
` ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C ` +
2022-07-27 21:26:32 +08:00
` %22name%22%3A%22Percentage%20CPU%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22Microsoft.Compute%2FvirtualMachines%22%2C%22metricVisualization%22%3A%7B%22displayName%22%3A%22Percentage%20CPU%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D `
2022-10-07 20:57:01 +08:00
actual , err := getQueryUrl ( queries [ 0 ] , "http://ds" , "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana" , "grafana" )
2021-09-28 21:24:18 +08:00
require . NoError ( t , err )
require . Equal ( t , expected , actual )
2019-02-09 00:20:31 +08:00
} )
2020-06-02 00:37:39 +08:00
}
}
2019-02-09 01:15:17 +08:00
2022-09-12 18:10:51 +08:00
func TestCustomNamespace ( t * testing . T ) {
datasource := & AzureMonitorDatasource { }
t . Run ( "it should set the metricNamespace to a customNamespace value if customNamespace is present as a parameter" , func ( t * testing . T ) {
q := [ ] backend . DataQuery {
{
JSON : [ ] byte ( ` {
"azureMonitor" : {
"customNamespace" : "custom/namespace"
}
} ` ) ,
} ,
}
2022-11-04 21:28:38 +08:00
result , err := datasource . buildQueries ( log . New ( "test" ) , q , types . DatasourceInfo { } )
2022-09-12 18:10:51 +08:00
require . NoError ( t , err )
expected := "custom/namespace"
require . Equal ( t , expected , result [ 0 ] . Params . Get ( "metricnamespace" ) )
} )
}
2020-06-02 00:37:39 +08:00
func makeDates ( startDate time . Time , count int , interval time . Duration ) ( times [ ] time . Time ) {
for i := 0 ; i < count ; i ++ {
times = append ( times , startDate . Add ( interval * time . Duration ( i ) ) )
}
return
}
2019-07-05 04:47:24 +08:00
2021-09-28 21:24:18 +08:00
func makeTestDataLink ( url string ) data . DataLink {
return data . DataLink {
Title : "View in Azure Portal" ,
TargetBlank : true ,
URL : url ,
}
}
2020-06-02 00:37:39 +08:00
func TestAzureMonitorParseResponse ( t * testing . T ) {
2021-09-28 21:24:18 +08:00
// datalinks for the test frames
averageLink := makeTestDataLink ( ` http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ ` +
2022-04-26 10:30:28 +08:00
` ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A4%2C%22namespace%22%3A%22%22%2C ` +
2021-09-28 21:24:18 +08:00
` %22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D ` )
totalLink := makeTestDataLink ( ` http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ ` +
2022-04-26 10:30:28 +08:00
` ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A1%2C%22namespace%22%3A%22%22%2C ` +
2021-09-28 21:24:18 +08:00
` %22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D ` )
maxLink := makeTestDataLink ( ` http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ ` +
2022-04-26 10:30:28 +08:00
` ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A3%2C%22namespace%22%3A%22%22%2C ` +
2021-09-28 21:24:18 +08:00
` %22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D ` )
minLink := makeTestDataLink ( ` http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ ` +
2022-04-26 10:30:28 +08:00
` ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A2%2C%22namespace%22%3A%22%22%2C ` +
2021-09-28 21:24:18 +08:00
` %22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D ` )
countLink := makeTestDataLink ( ` http://ds/#blade/Microsoft_Azure_MonitoringMetrics/Metrics.ReactView/Referer/MetricsExplorer/TimeContext/%7B%22absolute%22%3A%7B%22startTime%22%3A%220001-01-01T00%3A00%3A00Z%22%2C%22endTime%22%3A%220001-01-01T00%3A00%3A00Z%22%7D%7D/ ` +
2022-04-26 10:30:28 +08:00
` ChartDefinition/%7B%22v2charts%22%3A%5B%7B%22metrics%22%3A%5B%7B%22resourceMetadata%22%3A%7B%22id%22%3A%22%2Fsubscriptions%2F12345678-aaaa-bbbb-cccc-123456789abc%2FresourceGroups%2Fgrafanastaging%2Fproviders%2FMicrosoft.Compute%2FvirtualMachines%2Fgrafana%22%7D%2C%22name%22%3A%22%22%2C%22aggregationType%22%3A7%2C%22namespace%22%3A%22%22%2C ` +
2021-09-28 21:24:18 +08:00
` %22metricVisualization%22%3A%7B%22displayName%22%3A%22%22%2C%22resourceDisplayName%22%3A%22grafana%22%7D%7D%5D%7D%5D%7D ` )
2020-06-02 00:37:39 +08:00
tests := [ ] struct {
name string
responseFile string
2022-03-02 22:41:07 +08:00
mockQuery * types . AzureMonitorQuery
2020-06-02 00:37:39 +08:00
expectedFrames data . Frames
queryIntervalMS int64
} {
{
name : "average aggregate time series response" ,
responseFile : "1-azure-monitor-response-avg.json" ,
2022-03-02 22:41:07 +08:00
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
2020-06-02 00:37:39 +08:00
Params : url . Values {
"aggregation" : { "Average" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 8 , 10 , 13 , 0 , 0 , time . UTC ) , 5 , time . Minute ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
2020-10-09 20:15:19 +08:00
data . NewField ( "Percentage CPU" , nil , [ ] * float64 {
ptr . Float64 ( 2.0875 ) , ptr . Float64 ( 2.1525 ) , ptr . Float64 ( 2.155 ) , ptr . Float64 ( 3.6925 ) , ptr . Float64 ( 2.44 ) ,
2021-09-28 21:24:18 +08:00
} ) . SetConfig ( & data . FieldConfig { Unit : "percent" , Links : [ ] data . DataLink { averageLink } } ) ) ,
2020-06-02 00:37:39 +08:00
} ,
} ,
{
name : "total aggregate time series response" ,
responseFile : "2-azure-monitor-response-total.json" ,
2022-03-02 22:41:07 +08:00
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
2020-06-02 00:37:39 +08:00
Params : url . Values {
"aggregation" : { "Total" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 9 , 13 , 29 , 0 , 0 , time . UTC ) , 5 , time . Minute ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { totalLink } } ) ,
2020-10-09 20:15:19 +08:00
data . NewField ( "Percentage CPU" , nil , [ ] * float64 {
ptr . Float64 ( 8.26 ) , ptr . Float64 ( 8.7 ) , ptr . Float64 ( 14.82 ) , ptr . Float64 ( 10.07 ) , ptr . Float64 ( 8.52 ) ,
2021-09-28 21:24:18 +08:00
} ) . SetConfig ( & data . FieldConfig { Unit : "percent" , Links : [ ] data . DataLink { totalLink } } ) ) ,
2020-06-02 00:37:39 +08:00
} ,
} ,
{
name : "maximum aggregate time series response" ,
responseFile : "3-azure-monitor-response-maximum.json" ,
2022-03-02 22:41:07 +08:00
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
2020-06-02 00:37:39 +08:00
Params : url . Values {
"aggregation" : { "Maximum" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 9 , 14 , 26 , 0 , 0 , time . UTC ) , 5 , time . Minute ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { maxLink } } ) ,
2020-10-09 20:15:19 +08:00
data . NewField ( "Percentage CPU" , nil , [ ] * float64 {
ptr . Float64 ( 3.07 ) , ptr . Float64 ( 2.92 ) , ptr . Float64 ( 2.87 ) , ptr . Float64 ( 2.27 ) , ptr . Float64 ( 2.52 ) ,
2021-09-28 21:24:18 +08:00
} ) . SetConfig ( & data . FieldConfig { Unit : "percent" , Links : [ ] data . DataLink { maxLink } } ) ) ,
2020-06-02 00:37:39 +08:00
} ,
} ,
{
name : "minimum aggregate time series response" ,
responseFile : "4-azure-monitor-response-minimum.json" ,
2022-03-02 22:41:07 +08:00
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
2020-06-02 00:37:39 +08:00
Params : url . Values {
"aggregation" : { "Minimum" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 9 , 14 , 43 , 0 , 0 , time . UTC ) , 5 , time . Minute ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { minLink } } ) ,
2020-10-09 20:15:19 +08:00
data . NewField ( "Percentage CPU" , nil , [ ] * float64 {
ptr . Float64 ( 1.51 ) , ptr . Float64 ( 2.38 ) , ptr . Float64 ( 1.69 ) , ptr . Float64 ( 2.27 ) , ptr . Float64 ( 1.96 ) ,
2021-09-28 21:24:18 +08:00
} ) . SetConfig ( & data . FieldConfig { Unit : "percent" , Links : [ ] data . DataLink { minLink } } ) ) ,
2020-06-02 00:37:39 +08:00
} ,
} ,
{
name : "count aggregate time series response" ,
responseFile : "5-azure-monitor-response-count.json" ,
2022-03-02 22:41:07 +08:00
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
2020-06-02 00:37:39 +08:00
Params : url . Values {
"aggregation" : { "Count" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 9 , 14 , 44 , 0 , 0 , time . UTC ) , 5 , time . Minute ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { countLink } } ) ,
2020-10-09 20:15:19 +08:00
data . NewField ( "Percentage CPU" , nil , [ ] * float64 {
ptr . Float64 ( 4 ) , ptr . Float64 ( 4 ) , ptr . Float64 ( 4 ) , ptr . Float64 ( 4 ) , ptr . Float64 ( 4 ) ,
2021-09-28 21:24:18 +08:00
} ) . SetConfig ( & data . FieldConfig { Unit : "percent" , Links : [ ] data . DataLink { countLink } } ) ) ,
2020-06-02 00:37:39 +08:00
} ,
} ,
{
2020-07-01 04:26:46 +08:00
name : "single dimension time series response" ,
responseFile : "6-azure-monitor-response-single-dimension.json" ,
2022-03-02 22:41:07 +08:00
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
2020-06-02 00:37:39 +08:00
Params : url . Values {
"aggregation" : { "Average" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 9 , 15 , 21 , 0 , 0 , time . UTC ) , 6 , time . Hour ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
2020-07-01 04:26:46 +08:00
data . NewField ( "Blob Count" , data . Labels { "blobtype" : "PageBlob" } ,
2021-09-28 21:24:18 +08:00
[ ] * float64 { ptr . Float64 ( 3 ) , ptr . Float64 ( 3 ) , ptr . Float64 ( 3 ) , ptr . Float64 ( 3 ) , ptr . Float64 ( 3 ) , nil } ) . SetConfig ( & data . FieldConfig { Unit : "short" , Links : [ ] data . DataLink { averageLink } } ) ) ,
2020-06-02 00:37:39 +08:00
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 9 , 15 , 21 , 0 , 0 , time . UTC ) , 6 , time . Hour ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
2020-07-01 04:26:46 +08:00
data . NewField ( "Blob Count" , data . Labels { "blobtype" : "BlockBlob" } ,
2021-09-28 21:24:18 +08:00
[ ] * float64 { ptr . Float64 ( 1 ) , ptr . Float64 ( 1 ) , ptr . Float64 ( 1 ) , ptr . Float64 ( 1 ) , ptr . Float64 ( 1 ) , nil } ) . SetConfig ( & data . FieldConfig { Unit : "short" , Links : [ ] data . DataLink { averageLink } } ) ) ,
2020-06-02 00:37:39 +08:00
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 9 , 15 , 21 , 0 , 0 , time . UTC ) , 6 , time . Hour ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
2020-07-01 04:26:46 +08:00
data . NewField ( "Blob Count" , data . Labels { "blobtype" : "Azure Data Lake Storage" } ,
2021-09-28 21:24:18 +08:00
[ ] * float64 { ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) , nil } ) . SetConfig ( & data . FieldConfig { Unit : "short" , Links : [ ] data . DataLink { averageLink } } ) ) ,
2020-06-02 00:37:39 +08:00
} ,
} ,
{
name : "with alias patterns in the query" ,
responseFile : "2-azure-monitor-response-total.json" ,
2022-03-02 22:41:07 +08:00
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
Alias : "custom {{resourcegroup}} {{namespace}} {{resourceName}} {{metric}}" ,
2020-06-02 00:37:39 +08:00
Params : url . Values {
"aggregation" : { "Total" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 9 , 13 , 29 , 0 , 0 , time . UTC ) , 5 , time . Minute ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { totalLink } } ) ,
2020-10-09 20:15:19 +08:00
data . NewField ( "Percentage CPU" , nil , [ ] * float64 {
ptr . Float64 ( 8.26 ) , ptr . Float64 ( 8.7 ) , ptr . Float64 ( 14.82 ) , ptr . Float64 ( 10.07 ) , ptr . Float64 ( 8.52 ) ,
2021-09-28 21:24:18 +08:00
} ) . SetConfig ( & data . FieldConfig { Unit : "percent" , DisplayName : "custom grafanastaging Microsoft.Compute/virtualMachines grafana Percentage CPU" , Links : [ ] data . DataLink { totalLink } } ) ) ,
2020-06-02 00:37:39 +08:00
} ,
} ,
{
2020-07-01 04:26:46 +08:00
name : "single dimension with alias" ,
responseFile : "6-azure-monitor-response-single-dimension.json" ,
2022-03-02 22:41:07 +08:00
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
Alias : "{{dimensionname}}={{DimensionValue}}" ,
2020-06-02 00:37:39 +08:00
Params : url . Values {
"aggregation" : { "Average" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 9 , 15 , 21 , 0 , 0 , time . UTC ) , 6 , time . Hour ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
2020-07-01 04:26:46 +08:00
data . NewField ( "Blob Count" , data . Labels { "blobtype" : "PageBlob" } ,
2021-09-28 21:24:18 +08:00
[ ] * float64 { ptr . Float64 ( 3 ) , ptr . Float64 ( 3 ) , ptr . Float64 ( 3 ) , ptr . Float64 ( 3 ) , ptr . Float64 ( 3 ) , nil } ) . SetConfig ( & data . FieldConfig { Unit : "short" , DisplayName : "blobtype=PageBlob" , Links : [ ] data . DataLink { averageLink } } ) ) ,
2020-06-02 00:37:39 +08:00
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 9 , 15 , 21 , 0 , 0 , time . UTC ) , 6 , time . Hour ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
2020-10-09 20:15:19 +08:00
data . NewField ( "Blob Count" , data . Labels { "blobtype" : "BlockBlob" } , [ ] * float64 {
ptr . Float64 ( 1 ) , ptr . Float64 ( 1 ) , ptr . Float64 ( 1 ) , ptr . Float64 ( 1 ) , ptr . Float64 ( 1 ) , nil ,
2021-09-28 21:24:18 +08:00
} ) . SetConfig ( & data . FieldConfig { Unit : "short" , DisplayName : "blobtype=BlockBlob" , Links : [ ] data . DataLink { averageLink } } ) ) ,
2020-06-02 00:37:39 +08:00
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2019 , 2 , 9 , 15 , 21 , 0 , 0 , time . UTC ) , 6 , time . Hour ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
2020-10-09 20:15:19 +08:00
data . NewField ( "Blob Count" , data . Labels { "blobtype" : "Azure Data Lake Storage" } , [ ] * float64 {
ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) , nil ,
2021-09-28 21:24:18 +08:00
} ) . SetConfig ( & data . FieldConfig { Unit : "short" , DisplayName : "blobtype=Azure Data Lake Storage" , Links : [ ] data . DataLink { averageLink } } ) ) ,
2020-07-01 04:26:46 +08:00
} ,
} ,
{
name : "multiple dimension time series response with label alias" ,
responseFile : "7-azure-monitor-response-multi-dimension.json" ,
2022-03-02 22:41:07 +08:00
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
Alias : "{{resourcegroup}} {Blob Type={{blobtype}}, Tier={{Tier}}}" ,
2020-07-01 04:26:46 +08:00
Params : url . Values {
"aggregation" : { "Average" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2020 , 06 , 30 , 9 , 58 , 0 , 0 , time . UTC ) , 3 , time . Hour ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
2020-07-01 04:26:46 +08:00
data . NewField ( "Blob Capacity" , data . Labels { "blobtype" : "PageBlob" , "tier" : "Standard" } ,
2020-10-09 20:15:19 +08:00
[ ] * float64 { ptr . Float64 ( 675530 ) , ptr . Float64 ( 675530 ) , ptr . Float64 ( 675530 ) } ) . SetConfig (
2021-09-28 21:24:18 +08:00
& data . FieldConfig { Unit : "decbytes" , DisplayName : "danieltest {Blob Type=PageBlob, Tier=Standard}" , Links : [ ] data . DataLink { averageLink } } ) ) ,
2020-07-01 04:26:46 +08:00
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2020 , 06 , 30 , 9 , 58 , 0 , 0 , time . UTC ) , 3 , time . Hour ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
2020-07-01 04:26:46 +08:00
data . NewField ( "Blob Capacity" , data . Labels { "blobtype" : "BlockBlob" , "tier" : "Hot" } ,
2020-10-09 20:15:19 +08:00
[ ] * float64 { ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) } ) . SetConfig (
2021-09-28 21:24:18 +08:00
& data . FieldConfig { Unit : "decbytes" , DisplayName : "danieltest {Blob Type=BlockBlob, Tier=Hot}" , Links : [ ] data . DataLink { averageLink } } ) ) ,
2020-07-01 04:26:46 +08:00
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
makeDates ( time . Date ( 2020 , 06 , 30 , 9 , 58 , 0 , 0 , time . UTC ) , 3 , time . Hour ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
2020-07-01 04:26:46 +08:00
data . NewField ( "Blob Capacity" , data . Labels { "blobtype" : "Azure Data Lake Storage" , "tier" : "Cool" } ,
2020-10-09 20:15:19 +08:00
[ ] * float64 { ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) , ptr . Float64 ( 0 ) } ) . SetConfig (
2021-09-28 21:24:18 +08:00
& data . FieldConfig { Unit : "decbytes" , DisplayName : "danieltest {Blob Type=Azure Data Lake Storage, Tier=Cool}" , Links : [ ] data . DataLink { averageLink } } ) ) ,
2020-06-02 00:37:39 +08:00
} ,
} ,
2020-08-21 23:37:30 +08:00
{
name : "unspecified unit with alias should not panic" ,
responseFile : "8-azure-monitor-response-unspecified-unit.json" ,
2022-03-02 22:41:07 +08:00
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
Alias : "custom" ,
2020-08-21 23:37:30 +08:00
Params : url . Values {
"aggregation" : { "Average" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
2021-06-28 20:28:56 +08:00
data . NewField ( "Time" , nil ,
2021-09-28 21:24:18 +08:00
[ ] time . Time { time . Date ( 2019 , 2 , 8 , 10 , 13 , 0 , 0 , time . UTC ) } ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
2020-10-09 20:15:19 +08:00
data . NewField ( "Percentage CPU" , nil , [ ] * float64 {
ptr . Float64 ( 2.0875 ) ,
2021-09-28 21:24:18 +08:00
} ) . SetConfig ( & data . FieldConfig { DisplayName : "custom" , Links : [ ] data . DataLink { averageLink } } ) ) ,
2020-08-21 23:37:30 +08:00
} ,
} ,
2022-04-26 10:30:28 +08:00
{
name : "with legacy azure monitor query properties and without a resource uri" ,
responseFile : "2-azure-monitor-response-total.json" ,
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
Alias : "custom {{resourcegroup}} {{namespace}} {{resourceName}} {{metric}}" ,
2022-04-26 10:30:28 +08:00
Params : url . Values {
"aggregation" : { "Total" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
data . NewField ( "Time" , nil ,
makeDates ( time . Date ( 2019 , 2 , 9 , 13 , 29 , 0 , 0 , time . UTC ) , 5 , time . Minute ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { totalLink } } ) ,
data . NewField ( "Percentage CPU" , nil , [ ] * float64 {
ptr . Float64 ( 8.26 ) , ptr . Float64 ( 8.7 ) , ptr . Float64 ( 14.82 ) , ptr . Float64 ( 10.07 ) , ptr . Float64 ( 8.52 ) ,
} ) . SetConfig ( & data . FieldConfig { Unit : "percent" , DisplayName : "custom grafanastaging Microsoft.Compute/virtualMachines grafana Percentage CPU" , Links : [ ] data . DataLink { totalLink } } ) ) ,
} ,
} ,
{
name : "with legacy azure monitor query properties and with a resource uri it should use the resource uri" ,
responseFile : "2-azure-monitor-response-total.json" ,
mockQuery : & types . AzureMonitorQuery {
2022-10-07 20:57:01 +08:00
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana/providers/microsoft.insights/metrics" ,
Alias : "custom {{resourcegroup}} {{namespace}} {{resourceName}} {{metric}}" ,
2022-04-26 10:30:28 +08:00
Params : url . Values {
"aggregation" : { "Total" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
data . NewField ( "Time" , nil ,
makeDates ( time . Date ( 2019 , 2 , 9 , 13 , 29 , 0 , 0 , time . UTC ) , 5 , time . Minute ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { totalLink } } ) ,
data . NewField ( "Percentage CPU" , nil , [ ] * float64 {
ptr . Float64 ( 8.26 ) , ptr . Float64 ( 8.7 ) , ptr . Float64 ( 14.82 ) , ptr . Float64 ( 10.07 ) , ptr . Float64 ( 8.52 ) ,
} ) . SetConfig ( & data . FieldConfig { Unit : "percent" , DisplayName : "custom grafanastaging Microsoft.Compute/virtualMachines grafana Percentage CPU" , Links : [ ] data . DataLink { totalLink } } ) ) ,
} ,
} ,
2022-10-07 20:57:01 +08:00
{
name : "multiple time series response" ,
responseFile : "9-azure-monitor-response-multi.json" ,
mockQuery : & types . AzureMonitorQuery {
URL : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/providers/microsoft.insights/metrics" ,
Params : url . Values {
"aggregation" : { "Average" } ,
} ,
} ,
expectedFrames : data . Frames {
data . NewFrame ( "" ,
data . NewField ( "Time" , nil ,
makeDates ( time . Date ( 2019 , 2 , 8 , 10 , 13 , 0 , 0 , time . UTC ) , 5 , time . Minute ) ,
) . SetConfig ( & data . FieldConfig { Links : [ ] data . DataLink { averageLink } } ) ,
data . NewField ( "Percentage CPU" , data . Labels { "microsoft.resourceid" : "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/grafana" } , [ ] * float64 {
ptr . Float64 ( 2.0875 ) , ptr . Float64 ( 2.1525 ) , ptr . Float64 ( 2.155 ) , ptr . Float64 ( 3.6925 ) , ptr . Float64 ( 2.44 ) ,
} ) . SetConfig ( & data . FieldConfig { Unit : "percent" , Links : [ ] data . DataLink { averageLink } } ) ,
) ,
} ,
} ,
2020-06-02 00:37:39 +08:00
}
2019-07-05 04:47:24 +08:00
2020-06-02 00:37:39 +08:00
datasource := & AzureMonitorDatasource { }
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
2020-12-15 16:32:06 +08:00
azData := loadTestFile ( t , "azuremonitor/" + tt . responseFile )
2021-09-28 21:24:18 +08:00
dframes , err := datasource . parseResponse ( azData , tt . mockQuery , "http://ds" )
2020-06-02 00:37:39 +08:00
require . NoError ( t , err )
2021-03-08 14:02:49 +08:00
require . NotNil ( t , dframes )
2019-02-11 08:17:37 +08:00
2021-06-07 20:54:51 +08:00
if diff := cmp . Diff ( tt . expectedFrames , dframes , data . FrameTestCompareOptions ( ) ... ) ; diff != "" {
2020-06-02 00:37:39 +08:00
t . Errorf ( "Result mismatch (-want +got):\n%s" , diff )
2019-02-11 08:17:37 +08:00
}
2020-06-02 00:37:39 +08:00
} )
}
}
2019-02-11 08:17:37 +08:00
2020-06-02 00:37:39 +08:00
func TestFindClosestAllowIntervalMS ( t * testing . T ) {
humanIntervalToMS := map [ string ] int64 {
"3m" : 180000 ,
"5m" : 300000 ,
"10m" : 600000 ,
"15m" : 900000 ,
"1d" : 86400000 ,
"2d" : 172800000 ,
}
tests := [ ] struct {
name string
allowedTimeGrains [ ] int64 // Note: Uses defaults when empty list
inputInterval int64
expectedInterval int64
} {
{
name : "closest to 3m is 5m" ,
allowedTimeGrains : [ ] int64 { } ,
inputInterval : humanIntervalToMS [ "3m" ] ,
expectedInterval : humanIntervalToMS [ "5m" ] ,
} ,
{
name : "closest to 10m is 15m" ,
allowedTimeGrains : [ ] int64 { } ,
inputInterval : humanIntervalToMS [ "10m" ] ,
expectedInterval : humanIntervalToMS [ "15m" ] ,
} ,
{
name : "closest to 2d is 1d" ,
allowedTimeGrains : [ ] int64 { } ,
inputInterval : humanIntervalToMS [ "2d" ] ,
expectedInterval : humanIntervalToMS [ "1d" ] ,
} ,
{
name : "closest to 3m is 1d when 1d is only allowed interval" ,
allowedTimeGrains : [ ] int64 { humanIntervalToMS [ "1d" ] } ,
inputInterval : humanIntervalToMS [ "2d" ] ,
expectedInterval : humanIntervalToMS [ "1d" ] ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
2022-03-02 22:41:07 +08:00
interval := azTime . FindClosestAllowedIntervalMS ( tt . inputInterval , tt . allowedTimeGrains )
2020-06-02 00:37:39 +08:00
require . Equal ( t , tt . expectedInterval , interval )
2019-02-11 08:17:37 +08:00
} )
2020-06-02 00:37:39 +08:00
}
2019-02-09 00:20:31 +08:00
}
2019-02-09 01:15:17 +08:00
2022-03-02 22:41:07 +08:00
func loadTestFile ( t * testing . T , name string ) types . AzureMonitorResponse {
2020-12-15 16:32:06 +08:00
t . Helper ( )
2019-02-09 01:15:17 +08:00
2022-03-02 22:41:07 +08:00
path := filepath . Join ( "../testdata" , name )
2020-12-15 16:32:06 +08:00
// Ignore gosec warning G304 since it's a test
// nolint:gosec
2022-08-10 21:37:51 +08:00
jsonBody , err := os . ReadFile ( path )
2020-12-15 16:32:06 +08:00
require . NoError ( t , err )
2022-03-02 22:41:07 +08:00
var azData types . AzureMonitorResponse
2020-06-02 00:37:39 +08:00
err = json . Unmarshal ( jsonBody , & azData )
2020-12-15 16:32:06 +08:00
require . NoError ( t , err )
return azData
2019-02-09 01:15:17 +08:00
}
2021-06-11 23:02:24 +08:00
func TestAzureMonitorCreateRequest ( t * testing . T ) {
ctx := context . Background ( )
2021-07-16 18:47:26 +08:00
url := "http://ds/"
2021-06-11 23:02:24 +08:00
tests := [ ] struct {
name string
expectedURL string
expectedHeaders http . Header
Err require . ErrorAssertionFunc
} {
{
name : "creates a request" ,
2022-04-08 23:49:46 +08:00
expectedURL : "http://ds/" ,
2021-06-11 23:02:24 +08:00
expectedHeaders : http . Header {
"Content-Type" : [ ] string { "application/json" } ,
} ,
Err : require . NoError ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
ds := AzureMonitorDatasource { }
2022-11-04 21:28:38 +08:00
req , err := ds . createRequest ( ctx , log . New ( "test" ) , url )
2021-06-11 23:02:24 +08:00
tt . Err ( t , err )
if req . URL . String ( ) != tt . expectedURL {
t . Errorf ( "Expecting %s, got %s" , tt . expectedURL , req . URL . String ( ) )
}
if ! cmp . Equal ( req . Header , tt . expectedHeaders ) {
t . Errorf ( "Unexpected HTTP headers: %v" , cmp . Diff ( req . Header , tt . expectedHeaders ) )
}
} )
}
}
2022-04-26 10:30:28 +08:00
func TestExtractResourceNameFromMetricsURL ( t * testing . T ) {
t . Run ( "it should extract the resourceName from a well-formed Metrics URL" , func ( t * testing . T ) {
url := "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/Grafana-Test.VM/providers/microsoft.insights/metrics"
expected := "Grafana-Test.VM"
require . Equal ( t , expected , extractResourceNameFromMetricsURL ( ( url ) ) )
} )
t . Run ( "it should extract the resourceName from a well-formed Metrics URL in a case insensitive manner" , func ( t * testing . T ) {
url := "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/Grafana-Test.VM/pRoViDeRs/MiCrOsOfT.iNsIgHtS/mEtRiCs"
expected := "Grafana-Test.VM"
require . Equal ( t , expected , extractResourceNameFromMetricsURL ( ( url ) ) )
} )
t . Run ( "it should return an empty string if no match is found" , func ( t * testing . T ) {
url := "/subscriptions/12345678-aaaa-bbbb-cccc-123456789abc/resourceGroups/grafanastaging/providers/Microsoft.Compute/virtualMachines/Grafana-Test.VM/providers/microsoft.insights/nope-this-part-does-not-match"
expected := ""
require . Equal ( t , expected , extractResourceNameFromMetricsURL ( ( url ) ) )
} )
}