Path: blob/main/pkg/integrations/azure_exporter/config_test.go
5371 views
package azure_exporter_test12import (3"fmt"4"reflect"5"testing"67"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"8"github.com/stretchr/testify/require"9"github.com/webdevops/azure-metrics-exporter/metrics"1011"github.com/grafana/agent/pkg/integrations/azure_exporter"12)1314func TestConfig_ToScrapeSettings(t *testing.T) {15baseConfig := azure_exporter.Config{16Subscriptions: []string{"subscriptionA"},17ResourceType: "resourceType",18ResourceGraphQueryFilter: "filter_me",19Metrics: []string{"MetricA"},20MetricAggregations: []string{"MiNimUm"},21Timespan: "timespan_me",22IncludedResourceTags: []string{"tag_me"},23MetricNamespace: "namespace_me",24MetricNameTemplate: "name_template_me",25MetricHelpTemplate: "help_template_me",26AzureCloudEnvironment: "azurecloud",27}28baseSettings := metrics.RequestMetricSettings{29Subscriptions: []string{"subscriptionA"},30ResourceType: "resourceType",31Filter: "filter_me",32Timespan: "timespan_me",33Interval: to.Ptr("timespan_me"),34Metrics: []string{"MetricA"},35MetricNamespace: "namespace_me",36Aggregations: []string{"MiNimUm"},37MetricTemplate: "name_template_me",38HelpTemplate: "help_template_me",39TagLabels: []string{"tag_me"},40//Should not be set41Name: "",42MetricTop: nil,43MetricFilter: "",44MetricOrderBy: "",45Cache: nil,46}4748baseConfigValid := t.Run("maps expected fields", func(t *testing.T) {49settings, err := baseConfig.ToScrapeSettings()50require.NoError(t, err)51require.Equal(t, &baseSettings, settings)52})53if !baseConfigValid {54return55}5657tests := []struct {58name string59configModifier func(azure_exporter.Config) azure_exporter.Config60toExpectedSettings func(metrics.RequestMetricSettings) metrics.RequestMetricSettings61}{62{63name: "can set a metric filter for a single dimension",64configModifier: func(config azure_exporter.Config) azure_exporter.Config {65config.IncludedDimensions = []string{"dimension1"}66return config67},68toExpectedSettings: func(settings metrics.RequestMetricSettings) metrics.RequestMetricSettings {69settings.MetricFilter = "dimension1 eq '*'"70settings.MetricTop = to.Ptr[int32](100_000_000)71return settings72},73},74{75name: "can set a metric filter for a multiple dimensions",76configModifier: func(config azure_exporter.Config) azure_exporter.Config {77config.IncludedDimensions = []string{"dimension1", "dimension2", "dimension3"}78return config79},80toExpectedSettings: func(settings metrics.RequestMetricSettings) metrics.RequestMetricSettings {81settings.MetricFilter = "dimension1 eq '*' and dimension2 eq '*' and dimension3 eq '*'"82settings.MetricTop = to.Ptr[int32](100_000_000)83return settings84},85},86{87name: "sets config timespan to setting interval and timespan",88configModifier: func(config azure_exporter.Config) azure_exporter.Config {89config.Timespan = "timespan-value"90return config91},92toExpectedSettings: func(settings metrics.RequestMetricSettings) metrics.RequestMetricSettings {93settings.Timespan = "timespan-value"94settings.Interval = to.Ptr[string]("timespan-value")95return settings96},97},98}99for _, tt := range tests {100t.Run(tt.name, func(t *testing.T) {101fullConfig := tt.configModifier(baseConfig)102expectedSettings := tt.toExpectedSettings(baseSettings)103settings, err := fullConfig.ToScrapeSettings()104require.NoError(t, err)105require.Equal(t, &expectedSettings, settings)106})107}108}109110func TestConfig_Validate(t *testing.T) {111baseConfig := azure_exporter.Config{112Subscriptions: []string{"subscriptionA"},113ResourceType: "resourceType",114Metrics: []string{"MetricA"},115AzureCloudEnvironment: "azurecloud",116}117118baseConfigValid := t.Run("Base Config is Valid", func(t *testing.T) {119err := baseConfig.Validate()120require.NoError(t, err, "Base config was not valid but needs to be for these tests")121})122if !baseConfigValid {123return124}125126tests := []struct {127name string128toInvalidConfig func(azure_exporter.Config) azure_exporter.Config129}{130{131name: "nil Subscriptions",132toInvalidConfig: func(config azure_exporter.Config) azure_exporter.Config {133config.Subscriptions = nil134return config135},136},137{138name: "empty Subscriptions",139toInvalidConfig: func(config azure_exporter.Config) azure_exporter.Config {140config.Subscriptions = []string{}141return config142},143},144{145name: "empty ResourceType",146toInvalidConfig: func(config azure_exporter.Config) azure_exporter.Config {147config.ResourceType = ""148return config149},150},151{152name: "nil metrics",153toInvalidConfig: func(config azure_exporter.Config) azure_exporter.Config {154config.Metrics = nil155return config156},157},158{159name: "empty metrics",160toInvalidConfig: func(config azure_exporter.Config) azure_exporter.Config {161config.Metrics = []string{}162return config163},164},165{166name: "invalid aggregation",167toInvalidConfig: func(config azure_exporter.Config) azure_exporter.Config {168config.MetricAggregations = []string{"I'm Invalid"}169return config170},171},172{173name: "invalid azure_cloud_environment",174toInvalidConfig: func(config azure_exporter.Config) azure_exporter.Config {175config.AzureCloudEnvironment = "Not Real"176return config177},178},179}180for _, tt := range tests {181t.Run(tt.name, func(t *testing.T) {182invalidConfig := tt.toInvalidConfig(baseConfig)183err := invalidConfig.Validate()184require.Error(t, err)185})186}187}188189func TestMergeConfigWithQueryParams_MapsAllExpectedFieldsByYamlNameFromConfig(t *testing.T) {190// We want to be sure all expected fields are mappable by the yaml name and reflect allows us to do that programmatically191thing := reflect.TypeOf(azure_exporter.Config{})192var mappableFields []reflect.StructField193for i := 0; i < thing.NumField(); i++ {194field := thing.Field(i)195//Not available to be mapped via query param196if field.Name == "AzureCloudEnvironment" {197continue198}199200mappableFields = append(mappableFields, field)201}202203for _, mappableField := range mappableFields {204yamlFieldName := mappableField.Tag.Get("yaml")205t.Run(fmt.Sprintf("Can map %s from query param", yamlFieldName), func(t *testing.T) {206urlParams := map[string][]string{}207var fieldValue any208209switch mappableField.Type.String() {210case "string":211value := "fake string 1"212urlParams[yamlFieldName] = []string{value}213fieldValue = value214case "[]string":215value := []string{"fake string 1", "fake string 2"}216fieldValue = value217urlParams[yamlFieldName] = value218default:219t.Fatalf("Attempting to map %s, discovered unexpected type %s", mappableField.Name, mappableField.Type.String())220}221222expectedConfig := &azure_exporter.Config{}223reflect.ValueOf(expectedConfig).Elem().FieldByName(mappableField.Name).Set(reflect.ValueOf(fieldValue))224225actualConfig := azure_exporter.MergeConfigWithQueryParams(azure_exporter.Config{}, urlParams)226require.Equal(t, *expectedConfig, actualConfig)227})228}229}230231232