From a9f70e3994d090dab7e8fa10f1e24c19b67ea5cb Mon Sep 17 00:00:00 2001 From: Samuel Macko Date: Wed, 5 Aug 2020 12:06:59 +0200 Subject: [PATCH] [v2] Unique MetricName for each Trigger in ScaledObject (#966) Signed-off-by: samuelmacko --- pkg/scalers/artemis_scaler.go | 7 ++-- pkg/scalers/artemis_scaler_test.go | 25 ++++++++++++ pkg/scalers/aws_cloudwatch_scaler.go | 3 +- pkg/scalers/aws_cloudwatch_test.go | 25 ++++++++++++ pkg/scalers/aws_kinesis_stream_scaler.go | 5 +-- pkg/scalers/aws_kinesis_stream_test.go | 25 ++++++++++++ pkg/scalers/aws_sqs_queue_scaler.go | 2 +- pkg/scalers/aws_sqs_queue_test.go | 25 ++++++++++++ pkg/scalers/azure_blob_scaler.go | 2 +- pkg/scalers/azure_blob_scaler_test.go | 26 +++++++++++++ pkg/scalers/azure_eventhub_scaler.go | 2 +- pkg/scalers/azure_eventhub_scaler_test.go | 25 ++++++++++++ pkg/scalers/azure_monitor_scaler.go | 2 +- pkg/scalers/azure_monitor_scaler_test.go | 25 ++++++++++++ pkg/scalers/azure_queue_scaler.go | 2 +- pkg/scalers/azure_queue_scaler_test.go | 26 +++++++++++++ pkg/scalers/azure_servicebus_scaler.go | 10 ++++- pkg/scalers/azure_servicebus_scaler_test.go | 26 +++++++++++++ pkg/scalers/cron_scaler.go | 11 +++++- pkg/scalers/cron_scaler_test.go | 26 +++++++++++++ pkg/scalers/gcp_pub_sub_scaler.go | 7 ++-- pkg/scalers/gcp_pubsub_scaler_test.go | 25 ++++++++++++ pkg/scalers/huawei_cloudeye_scaler.go | 2 +- pkg/scalers/huawei_cloudeye_test.go | 25 ++++++++++++ pkg/scalers/kafka_scaler.go | 2 +- pkg/scalers/kafka_scaler_test.go | 25 ++++++++++++ pkg/scalers/liiklus_scaler.go | 2 +- pkg/scalers/liiklus_scaler_test.go | 25 ++++++++++++ pkg/scalers/mysql_scaler.go | 8 +++- pkg/scalers/mysql_scaler_test.go | 32 +++++++++++++-- pkg/scalers/postgresql_scaler.go | 8 +++- pkg/scalers/postgresql_scaler_test.go | 43 +++++++++++++++++++++ pkg/scalers/prometheus_scaler.go | 2 +- pkg/scalers/prometheus_scaler_test.go | 25 ++++++++++++ pkg/scalers/rabbitmq_scaler.go | 2 +- pkg/scalers/rabbitmq_scaler_test.go | 25 ++++++++++++ pkg/scalers/redis_scaler.go | 3 +- pkg/scalers/redis_scaler_test.go | 25 ++++++++++++ pkg/scalers/redis_streams_scaler.go | 4 +- pkg/scalers/redis_streams_scaler_test.go | 30 ++++++++++++++ pkg/scalers/stan_scaler.go | 2 +- pkg/scalers/stan_scaler_test.go | 25 ++++++++++++ 42 files changed, 610 insertions(+), 37 deletions(-) create mode 100644 pkg/scalers/postgresql_scaler_test.go diff --git a/pkg/scalers/artemis_scaler.go b/pkg/scalers/artemis_scaler.go index 88388840d74..c41ba4c4292 100644 --- a/pkg/scalers/artemis_scaler.go +++ b/pkg/scalers/artemis_scaler.go @@ -39,9 +39,8 @@ type artemisMonitoring struct { } const ( - artemisQueueLengthMetricName = "queueLength" - artemisMetricType = "External" - defaultArtemisQueueLength = 10 + artemisMetricType = "External" + defaultArtemisQueueLength = 10 ) var artemisLog = logf.Log.WithName("artemis_queue_scaler") @@ -184,7 +183,7 @@ func (s *artemisScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetMetricValue := resource.NewQuantity(int64(s.metadata.queueLength), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: artemisQueueLengthMetricName, + Name: fmt.Sprintf("%s-%s-%s", "artemis", s.metadata.brokerName, s.metadata.queueName), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/artemis_scaler_test.go b/pkg/scalers/artemis_scaler_test.go index 181e95ac470..3a865df3fb6 100644 --- a/pkg/scalers/artemis_scaler_test.go +++ b/pkg/scalers/artemis_scaler_test.go @@ -14,6 +14,11 @@ type parseArtemisMetadataTestData struct { isError bool } +type artemisMetricIdentifier struct { + metadataTestData *parseArtemisMetadataTestData + name string +} + var sampleArtemisResolvedEnv = map[string]string{ username: "artemis", password: "artemis", @@ -49,6 +54,10 @@ var testArtemisMetadata = []parseArtemisMetadataTestData{ {map[string]string{"managementEndpoint": "localhost:8161", "queueName": "queue1", "brokerName": "broker-activemq", "brokerAddress": "test", "username": "myUserName", "password": "myPassword"}, false}, } +var artemisMetricIdentifiers = []artemisMetricIdentifier{ + {&testArtemisMetadata[7], "artemis-broker-activemq-queue1"}, +} + var testArtemisMetadataWithEmptyAuthParams = []parseArtemisMetadataTestData{ // nothing passed {map[string]string{}, true}, @@ -101,3 +110,19 @@ func TestArtemisParseMetadata(t *testing.T) { } } } + +func TestArtemisGetMetricSpecForScaling(t *testing.T) { + for _, testData := range artemisMetricIdentifiers { + meta, err := parseArtemisMetadata(sampleArtemisResolvedEnv, testData.metadataTestData.metadata, nil) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockArtemisScaler := artemisScaler{meta} + + metricSpec := mockArtemisScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/aws_cloudwatch_scaler.go b/pkg/scalers/aws_cloudwatch_scaler.go index 111cef3564c..e3f6c6dc206 100644 --- a/pkg/scalers/aws_cloudwatch_scaler.go +++ b/pkg/scalers/aws_cloudwatch_scaler.go @@ -176,8 +176,7 @@ func (c *awsCloudwatchScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetMetricValue := resource.NewQuantity(int64(c.metadata.targetMetricValue), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: fmt.Sprintf("%s-%s-%s", strings.ReplaceAll(c.metadata.namespace, "/", "-"), - c.metadata.dimensionName, c.metadata.dimensionValue), + Name: fmt.Sprintf("%s-%s-%s-%s", "aws-cloudwatch", strings.ReplaceAll(c.metadata.namespace, "/", "-"), c.metadata.dimensionName, c.metadata.dimensionValue), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/aws_cloudwatch_test.go b/pkg/scalers/aws_cloudwatch_test.go index 4ad1c10cf10..8a64aa82392 100644 --- a/pkg/scalers/aws_cloudwatch_test.go +++ b/pkg/scalers/aws_cloudwatch_test.go @@ -26,6 +26,11 @@ type parseAWSCloudwatchMetadataTestData struct { comment string } +type awsCloudwatchMetricIdentifier struct { + metadataTestData *parseAWSCloudwatchMetadataTestData + name string +} + var testAWSCloudwatchMetadata = []parseAWSCloudwatchMetadataTestData{ {map[string]string{}, testAWSAuthentication, true, "Empty structures"}, // properly formed cloudwatch query and awsRegion @@ -161,6 +166,10 @@ var testAWSCloudwatchMetadata = []parseAWSCloudwatchMetadataTestData{ "with AWS Role assigned on KEDA operator itself"}, } +var awsCloudwatchMetricIdentifiers = []awsCloudwatchMetricIdentifier{ + {&testAWSCloudwatchMetadata[1], "aws-cloudwatch-AWS-SQS-QueueName-keda"}, +} + func TestCloudwatchParseMetadata(t *testing.T) { for _, testData := range testAWSCloudwatchMetadata { _, err := parseAwsCloudwatchMetadata(testData.metadata, testAWSCloudwatchResolvedEnv, testData.authParams) @@ -172,3 +181,19 @@ func TestCloudwatchParseMetadata(t *testing.T) { } } } + +func TestAWSCloudwatchGetMetricSpecForScaling(t *testing.T) { + for _, testData := range awsCloudwatchMetricIdentifiers { + meta, err := parseAwsCloudwatchMetadata(testData.metadataTestData.metadata, testAWSCloudwatchResolvedEnv, testData.metadataTestData.authParams) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockAWSCloudwatchScaler := awsCloudwatchScaler{meta} + + metricSpec := mockAWSCloudwatchScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/aws_kinesis_stream_scaler.go b/pkg/scalers/aws_kinesis_stream_scaler.go index 2cda2238247..7585fc99765 100644 --- a/pkg/scalers/aws_kinesis_stream_scaler.go +++ b/pkg/scalers/aws_kinesis_stream_scaler.go @@ -20,8 +20,7 @@ import ( ) const ( - awsKinesisStreamMetricName = "ShardCount" - targetShardCountDefault = 2 + targetShardCountDefault = 2 ) type awsKinesisStreamScaler struct { @@ -104,7 +103,7 @@ func (s *awsKinesisStreamScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec targetShardCountQty := resource.NewQuantity(int64(s.metadata.targetShardCount), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: fmt.Sprintf("%s-%s-%s", "AWS-Kinesis-Stream", awsKinesisStreamMetricName, s.metadata.streamName), + Name: fmt.Sprintf("%s-%s", "AWS-Kinesis-Stream", s.metadata.streamName), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/aws_kinesis_stream_test.go b/pkg/scalers/aws_kinesis_stream_test.go index ba55f3df1ff..200f8f7799c 100644 --- a/pkg/scalers/aws_kinesis_stream_test.go +++ b/pkg/scalers/aws_kinesis_stream_test.go @@ -31,6 +31,11 @@ type parseAWSKinesisMetadataTestData struct { comment string } +type awsKinesisMetricIdentifier struct { + metadataTestData *parseAWSKinesisMetadataTestData + name string +} + var testAWSKinesisMetadata = []parseAWSKinesisMetadataTestData{ { metadata: map[string]string{}, @@ -170,6 +175,10 @@ var testAWSKinesisMetadata = []parseAWSKinesisMetadataTestData{ comment: "with AWS Role assigned on KEDA operator itself"}, } +var awsKinesisMetricIdentifiers = []awsKinesisMetricIdentifier{ + {&testAWSKinesisMetadata[1], "AWS-Kinesis-Stream-test"}, +} + func TestKinesisParseMetadata(t *testing.T) { for _, testData := range testAWSKinesisMetadata { result, err := parseAwsKinesisStreamMetadata(testData.metadata, testAWSKinesisAuthentication, testData.authParams) @@ -185,3 +194,19 @@ func TestKinesisParseMetadata(t *testing.T) { } } } + +func TestAWSKinesisGetMetricSpecForScaling(t *testing.T) { + for _, testData := range awsKinesisMetricIdentifiers { + meta, err := parseAwsKinesisStreamMetadata(testData.metadataTestData.metadata, testAWSKinesisAuthentication, testData.metadataTestData.authParams) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockAWSKinesisStreamScaler := awsKinesisStreamScaler{meta} + + metricSpec := mockAWSKinesisStreamScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/aws_sqs_queue_scaler.go b/pkg/scalers/aws_sqs_queue_scaler.go index 9e4c9dd48df..03c78af8aec 100644 --- a/pkg/scalers/aws_sqs_queue_scaler.go +++ b/pkg/scalers/aws_sqs_queue_scaler.go @@ -120,7 +120,7 @@ func (s *awsSqsQueueScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetQueueLengthQty := resource.NewQuantity(int64(s.metadata.targetQueueLength), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: fmt.Sprintf("%s-%s-%s", "AWS-SQS-Queue", awsSqsQueueMetricName, s.metadata.queueName), + Name: fmt.Sprintf("%s-%s", "AWS-SQS-Queue", s.metadata.queueName), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/aws_sqs_queue_test.go b/pkg/scalers/aws_sqs_queue_test.go index 0b55484e889..7105e4e6704 100644 --- a/pkg/scalers/aws_sqs_queue_test.go +++ b/pkg/scalers/aws_sqs_queue_test.go @@ -31,6 +31,11 @@ type parseAWSSQSMetadataTestData struct { comment string } +type awsSQSMetricIdentifier struct { + metadataTestData *parseAWSSQSMetadataTestData + name string +} + var testAWSSQSMetadata = []parseAWSSQSMetadataTestData{ {map[string]string{}, testAWSSQSAuthentication, @@ -130,6 +135,10 @@ var testAWSSQSMetadata = []parseAWSSQSMetadataTestData{ "with AWS Role assigned on KEDA operator itself"}, } +var awsSQSMetricIdentifiers = []awsSQSMetricIdentifier{ + {&testAWSSQSMetadata[1], "AWS-SQS-Queue-DeleteArtifactQ"}, +} + func TestSQSParseMetadata(t *testing.T) { for _, testData := range testAWSSQSMetadata { _, err := parseAwsSqsQueueMetadata(testData.metadata, testAWSSQSAuthentication, testData.authParams) @@ -141,3 +150,19 @@ func TestSQSParseMetadata(t *testing.T) { } } } + +func TestAWSSQSGetMetricSpecForScaling(t *testing.T) { + for _, testData := range awsSQSMetricIdentifiers { + meta, err := parseAwsSqsQueueMetadata(testData.metadataTestData.metadata, testAWSSQSAuthentication, testData.metadataTestData.authParams) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockAWSSQSScaler := awsSqsQueueScaler{meta} + + metricSpec := mockAWSSQSScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/azure_blob_scaler.go b/pkg/scalers/azure_blob_scaler.go index c311be4d7f3..24d93d29cb6 100644 --- a/pkg/scalers/azure_blob_scaler.go +++ b/pkg/scalers/azure_blob_scaler.go @@ -155,7 +155,7 @@ func (s *azureBlobScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetBlobCount := resource.NewQuantity(int64(s.metadata.targetBlobCount), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: blobCountMetricName, + Name: fmt.Sprintf("%s-%s", "azure-blob", s.metadata.blobContainerName), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/azure_blob_scaler_test.go b/pkg/scalers/azure_blob_scaler_test.go index a69f4bc5373..5e7737eabd8 100644 --- a/pkg/scalers/azure_blob_scaler_test.go +++ b/pkg/scalers/azure_blob_scaler_test.go @@ -14,6 +14,11 @@ type parseAzBlobMetadataTestData struct { podIdentity string } +type azBlobMetricIdentifier struct { + metadataTestData *parseAzBlobMetadataTestData + name string +} + var testAzBlobMetadata = []parseAzBlobMetadataTestData{ // nothing passed {map[string]string{}, true, testAzBlobResolvedEnv, map[string]string{}, ""}, @@ -33,6 +38,11 @@ var testAzBlobMetadata = []parseAzBlobMetadataTestData{ {map[string]string{"blobContainerName": "sample_container", "blobCount": "5"}, false, testAzBlobResolvedEnv, map[string]string{"connection": "value"}, "none"}, } +var azBlobMetricIdentifiers = []azBlobMetricIdentifier{ + {&testAzBlobMetadata[1], "azure-blob-sample"}, + {&testAzBlobMetadata[4], "azure-blob-sample_container"}, +} + func TestAzBlobParseMetadata(t *testing.T) { for _, testData := range testAzBlobMetadata { _, podIdentity, err := parseAzureBlobMetadata(testData.metadata, testData.resolvedEnv, testData.authParams, testData.podIdentity) @@ -48,3 +58,19 @@ func TestAzBlobParseMetadata(t *testing.T) { } } } + +func TestAzBlobGetMetricSpecForScaling(t *testing.T) { + for _, testData := range azBlobMetricIdentifiers { + meta, podIdentity, err := parseAzureBlobMetadata(testData.metadataTestData.metadata, testData.metadataTestData.resolvedEnv, testData.metadataTestData.authParams, testData.metadataTestData.podIdentity) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockAzBlobScaler := azureBlobScaler{meta, podIdentity} + + metricSpec := mockAzBlobScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/azure_eventhub_scaler.go b/pkg/scalers/azure_eventhub_scaler.go index a17870386d6..57ddbe97970 100644 --- a/pkg/scalers/azure_eventhub_scaler.go +++ b/pkg/scalers/azure_eventhub_scaler.go @@ -209,7 +209,7 @@ func (scaler *AzureEventHubScaler) GetMetricSpecForScaling() []v2beta2.MetricSpe targetMetricVal := resource.NewQuantity(scaler.metadata.threshold, resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: thresholdMetricName, + Name: fmt.Sprintf("%s-%s-%s", "azure-eventhub", scaler.metadata.eventHubInfo.EventHubConnection, scaler.metadata.eventHubInfo.EventHubConsumerGroup), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/azure_eventhub_scaler_test.go b/pkg/scalers/azure_eventhub_scaler_test.go index 0d44a2926c8..973e780475c 100644 --- a/pkg/scalers/azure_eventhub_scaler_test.go +++ b/pkg/scalers/azure_eventhub_scaler_test.go @@ -28,6 +28,11 @@ type parseEventHubMetadataTestData struct { isError bool } +type eventHubMetricIdentifier struct { + metadataTestData *parseEventHubMetadataTestData + name string +} + type resolvedEnvTestData struct { resolvedEnv map[string]string isError bool @@ -51,6 +56,10 @@ var parseEventHubMetadataDataset = []parseEventHubMetadataTestData{ {map[string]string{"storageConnection": storageConnectionSetting, "consumerGroup": eventHubConsumerGroup, "connection": eventHubConnectionSetting, "blobContainer": testContainerName}, false}, } +var eventHubMetricIdentifiers = []eventHubMetricIdentifier{ + {&parseEventHubMetadataDataset[1], "azure-eventhub-none-testEventHubConsumerGroup"}, +} + var testEventHubScaler = AzureEventHubScaler{ metadata: &EventHubMetadata{ eventHubInfo: azure.EventHubInfo{ @@ -407,3 +416,19 @@ func DeleteContainerInStorage(ctx context.Context, endpoint *url.URL, credential } return nil } + +func TestEventHubGetMetricSpecForScaling(t *testing.T) { + for _, testData := range eventHubMetricIdentifiers { + meta, err := parseAzureEventHubMetadata(testData.metadataTestData.metadata, sampleEventHubResolvedEnv) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockEventHubScaler := AzureEventHubScaler{meta, nil} + + metricSpec := mockEventHubScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/azure_monitor_scaler.go b/pkg/scalers/azure_monitor_scaler.go index 9ff0e0f280d..91305a06a6c 100644 --- a/pkg/scalers/azure_monitor_scaler.go +++ b/pkg/scalers/azure_monitor_scaler.go @@ -167,7 +167,7 @@ func (s *azureMonitorScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetMetricVal := resource.NewQuantity(int64(s.metadata.targetValue), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: azureMonitorMetricName, + Name: fmt.Sprintf("%s-%s-%s-%s", "azure-monitor", s.metadata.azureMonitorInfo.ResourceURI, s.metadata.azureMonitorInfo.ResourceGroupName, s.metadata.azureMonitorInfo.Name), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/azure_monitor_scaler_test.go b/pkg/scalers/azure_monitor_scaler_test.go index 5a3c496cd87..95a9b9c5ef3 100644 --- a/pkg/scalers/azure_monitor_scaler_test.go +++ b/pkg/scalers/azure_monitor_scaler_test.go @@ -9,6 +9,11 @@ type parseAzMonitorMetadataTestData struct { authParams map[string]string } +type azMonitorMetricIdentifier struct { + metadataTestData *parseAzMonitorMetadataTestData + name string +} + var testAzMonitorResolvedEnv = map[string]string{ "CLIENT_ID": "xxx", "CLIENT_PASSWORD": "yyy", @@ -49,6 +54,10 @@ var testParseAzMonitorMetadata = []parseAzMonitorMetadataTestData{ {map[string]string{"resourceURI": "test/resource/uri", "tenantId": "123", "subscriptionId": "456", "resourceGroupName": "test", "metricName": "metric", "metricAggregationInterval": "0:15:0", "metricAggregationType": "Average", "targetValue": "5"}, false, map[string]string{}, map[string]string{"activeDirectoryClientId": "zzz", "activeDirectoryClientPassword": "password"}}, } +var azMonitorMetricIdentifiers = []azMonitorMetricIdentifier{ + {&testParseAzMonitorMetadata[1], "azure-monitor-test/resource/uri-test-metric"}, +} + func TestAzMonitorParseMetadata(t *testing.T) { for _, testData := range testParseAzMonitorMetadata { _, err := parseAzureMonitorMetadata(testData.metadata, testData.resolvedEnv, testData.authParams) @@ -60,3 +69,19 @@ func TestAzMonitorParseMetadata(t *testing.T) { } } } + +func TestAzMonitorGetMetricSpecForScaling(t *testing.T) { + for _, testData := range azMonitorMetricIdentifiers { + meta, err := parseAzureMonitorMetadata(testData.metadataTestData.metadata, testData.metadataTestData.resolvedEnv, testData.metadataTestData.authParams) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockAzMonitorScaler := azureMonitorScaler{meta} + + metricSpec := mockAzMonitorScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/azure_queue_scaler.go b/pkg/scalers/azure_queue_scaler.go index 7ac73112127..3cc77247500 100644 --- a/pkg/scalers/azure_queue_scaler.go +++ b/pkg/scalers/azure_queue_scaler.go @@ -136,7 +136,7 @@ func (s *azureQueueScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetQueueLengthQty := resource.NewQuantity(int64(s.metadata.targetQueueLength), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: queueLengthMetricName, + Name: fmt.Sprintf("%s-%s", "azure-queue", s.metadata.queueName), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/azure_queue_scaler_test.go b/pkg/scalers/azure_queue_scaler_test.go index bca9b1b0b96..ce4d44d65a1 100644 --- a/pkg/scalers/azure_queue_scaler_test.go +++ b/pkg/scalers/azure_queue_scaler_test.go @@ -14,6 +14,11 @@ type parseAzQueueMetadataTestData struct { podIdentity string } +type azQueueMetricIdentifier struct { + metadataTestData *parseAzQueueMetadataTestData + name string +} + var testAzQueueMetadata = []parseAzQueueMetadataTestData{ // nothing passed {map[string]string{}, true, testAzQueueResolvedEnv, map[string]string{}, ""}, @@ -39,6 +44,11 @@ var testAzQueueMetadata = []parseAzQueueMetadataTestData{ {map[string]string{"queueName": "sample", "queueLength": "5"}, false, testAzQueueResolvedEnv, map[string]string{"connection": "value"}, "none"}, } +var azQueueMetricIdentifiers = []azQueueMetricIdentifier{ + {&testAzQueueMetadata[1], "azure-queue-sample"}, + {&testAzQueueMetadata[4], "azure-queue-sample_queue"}, +} + func TestAzQueueParseMetadata(t *testing.T) { for _, testData := range testAzQueueMetadata { _, podIdentity, err := parseAzureQueueMetadata(testData.metadata, testData.resolvedEnv, testData.authParams, testData.podIdentity) @@ -53,3 +63,19 @@ func TestAzQueueParseMetadata(t *testing.T) { } } } + +func TestAzQueueGetMetricSpecForScaling(t *testing.T) { + for _, testData := range azQueueMetricIdentifiers { + meta, podIdentity, err := parseAzureQueueMetadata(testData.metadataTestData.metadata, testData.metadataTestData.resolvedEnv, testData.metadataTestData.authParams, testData.metadataTestData.podIdentity) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockAzQueueScaler := azureQueueScaler{meta, podIdentity} + + metricSpec := mockAzQueueScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/azure_servicebus_scaler.go b/pkg/scalers/azure_servicebus_scaler.go index ab2d0eb1613..f5cd79bd2b6 100755 --- a/pkg/scalers/azure_servicebus_scaler.go +++ b/pkg/scalers/azure_servicebus_scaler.go @@ -77,7 +77,7 @@ func parseAzureServiceBusMetadata(resolvedEnv, metadata, authParams map[string]s meta.entityType = Queue if _, ok := metadata["subscriptionName"]; ok { - return nil, fmt.Errorf("No subscription name provided with topic name") + return nil, fmt.Errorf("Subscription name provided with queue name") } } @@ -146,9 +146,15 @@ func (s *azureServiceBusScaler) Close() error { // Returns the metric spec to be used by the HPA func (s *azureServiceBusScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetLengthQty := resource.NewQuantity(int64(s.metadata.targetLength), resource.DecimalSI) + metricName := "azure-servicebus" + if s.metadata.entityType == Queue { + metricName = fmt.Sprintf("%s-%s", metricName, s.metadata.queueName) + } else { + metricName = fmt.Sprintf("%s-%s-%s", metricName, s.metadata.topicName, s.metadata.subscriptionName) + } externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: queueLengthMetricName, + Name: metricName, }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/azure_servicebus_scaler_test.go b/pkg/scalers/azure_servicebus_scaler_test.go index 9dff84df029..4a63a41dfe3 100755 --- a/pkg/scalers/azure_servicebus_scaler_test.go +++ b/pkg/scalers/azure_servicebus_scaler_test.go @@ -22,6 +22,11 @@ type parseServiceBusMetadataTestData struct { podIdentity string } +type azServiceBusMetricIdentifier struct { + metadataTestData *parseServiceBusMetadataTestData + name string +} + // not testing connections so it doesn't matter what the resolved env value is for this var sampleResolvedEnv = map[string]string{ connectionSetting: "none", @@ -51,6 +56,11 @@ var parseServiceBusMetadataDataset = []parseServiceBusMetadataTestData{ {map[string]string{"queueName": queueName, "namespace": namespaceName}, false, Queue, map[string]string{}, "azure"}, } +var azServiceBusMetricIdentifiers = []azServiceBusMetricIdentifier{ + {&parseServiceBusMetadataDataset[1], "azure-servicebus-testqueue"}, + {&parseServiceBusMetadataDataset[2], "azure-servicebus-testtopic-testsubscription"}, +} + var getServiceBusLengthTestScalers = []azureServiceBusScaler{ {metadata: &azureServiceBusMetadata{ entityType: Queue, @@ -119,3 +129,19 @@ func TestGetServiceBusLength(t *testing.T) { } } } + +func TestAzServiceBusGetMetricSpecForScaling(t *testing.T) { + for _, testData := range azServiceBusMetricIdentifiers { + meta, err := parseAzureServiceBusMetadata(sampleResolvedEnv, testData.metadataTestData.metadata, testData.metadataTestData.authParams, testData.metadataTestData.podIdentity) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockAzServiceBusScalerScaler := azureServiceBusScaler{meta, testData.metadataTestData.podIdentity} + + metricSpec := mockAzServiceBusScalerScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/cron_scaler.go b/pkg/scalers/cron_scaler.go index ead164c3296..735be5bb871 100644 --- a/pkg/scalers/cron_scaler.go +++ b/pkg/scalers/cron_scaler.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "strconv" + "strings" "time" "github.com/robfig/cron/v3" @@ -128,13 +129,21 @@ func (s *cronScaler) Close() error { return nil } +func parseCronTimeFormat(s string) string { + s = strings.ReplaceAll(s, " ", "") + s = strings.ReplaceAll(s, "*", "x") + s = strings.ReplaceAll(s, "/", "Sl") + s = strings.ReplaceAll(s, "?", "Qm") + return s +} + // GetMetricSpecForScaling returns the metric spec for the HPA func (s *cronScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { specReplicas := 1 targetMetricValue := resource.NewQuantity(int64(specReplicas), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: cronMetricName, + Name: fmt.Sprintf("%s-%s-%s-%s", "cron", strings.ReplaceAll(s.metadata.timezone, "/", "-"), parseCronTimeFormat(s.metadata.start), parseCronTimeFormat(s.metadata.end)), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/cron_scaler_test.go b/pkg/scalers/cron_scaler_test.go index e8db631fc38..53268113cf3 100644 --- a/pkg/scalers/cron_scaler_test.go +++ b/pkg/scalers/cron_scaler_test.go @@ -12,6 +12,11 @@ type parseCronMetadataTestData struct { isError bool } +type cronMetricIdentifier struct { + metadataTestData *parseCronMetadataTestData + name string +} + // A complete valid metadata example for reference var validCronMetadata = map[string]string{ "timezone": "Etc/UTC", @@ -27,6 +32,10 @@ var testCronMetadata = []parseCronMetadataTestData{ {map[string]string{"start": "30 * * * *", "end": "45 * * * *", "desiredReplicas": "10"}, true}, } +var cronMetricIdentifiers = []cronMetricIdentifier{ + {&testCronMetadata[1], "cron-Etc-UTC-00xxThu-5923xxThu"}, +} + var tz, _ = time.LoadLocation(validCronMetadata["timezone"]) var currentDay = time.Now().In(tz).Weekday().String() @@ -62,3 +71,20 @@ func TestGetMetrics(t *testing.T) { assert.Equal(t, metrics[0].Value.Value(), int64(1)) } } + + +func TestCronGetMetricSpecForScaling(t *testing.T) { + for _, testData := range cronMetricIdentifiers { + meta, err := parseCronMetadata(testData.metadataTestData.metadata, nil) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockCronScaler := cronScaler{meta} + + metricSpec := mockCronScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} \ No newline at end of file diff --git a/pkg/scalers/gcp_pub_sub_scaler.go b/pkg/scalers/gcp_pub_sub_scaler.go index b644e9b1b42..227ca9e29f0 100644 --- a/pkg/scalers/gcp_pub_sub_scaler.go +++ b/pkg/scalers/gcp_pub_sub_scaler.go @@ -14,9 +14,8 @@ import ( ) const ( - pubSubSubscriptionSizeMetricName = "GCPPubSubSubscriptionSize" - defaultTargetSubscriptionSize = 5 - pubSubStackDriverMetricName = "pubsub.googleapis.com/subscription/num_undelivered_messages" + defaultTargetSubscriptionSize = 5 + pubSubStackDriverMetricName = "pubsub.googleapis.com/subscription/num_undelivered_messages" ) type pubsubScaler struct { @@ -104,7 +103,7 @@ func (s *pubsubScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: pubSubSubscriptionSizeMetricName, + Name: fmt.Sprintf("%s-%s", "gcp", s.metadata.subscriptionName), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/gcp_pubsub_scaler_test.go b/pkg/scalers/gcp_pubsub_scaler_test.go index 844a4fa21d9..beffb07a04b 100644 --- a/pkg/scalers/gcp_pubsub_scaler_test.go +++ b/pkg/scalers/gcp_pubsub_scaler_test.go @@ -13,6 +13,11 @@ type parsePubSubMetadataTestData struct { isError bool } +type gcpPubSubMetricIdentifier struct { + metadataTestData *parsePubSubMetadataTestData + name string +} + var testPubSubMetadata = []parsePubSubMetadataTestData{ {map[string]string{}, true}, // all properly formed @@ -27,6 +32,10 @@ var testPubSubMetadata = []parsePubSubMetadataTestData{ {map[string]string{"subscriptionName": "mysubscription", "subscriptionSize": "AA", "credentials": "SAMPLE_CREDS"}, true}, } +var gcpPubSubMetricIdentifiers = []gcpPubSubMetricIdentifier{ + {&testPubSubMetadata[1], "gcp-mysubscription"}, +} + func TestPubSubParseMetadata(t *testing.T) { for _, testData := range testPubSubMetadata { _, err := parsePubSubMetadata(testData.metadata, testPubSubResolvedEnv) @@ -38,3 +47,19 @@ func TestPubSubParseMetadata(t *testing.T) { } } } + +func TestGcpPubSubGetMetricSpecForScaling(t *testing.T) { + for _, testData := range gcpPubSubMetricIdentifiers { + meta, err := parsePubSubMetadata(testData.metadataTestData.metadata, testPubSubResolvedEnv) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockGcpPubSubScaler := pubsubScaler{meta} + + metricSpec := mockGcpPubSubScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/huawei_cloudeye_scaler.go b/pkg/scalers/huawei_cloudeye_scaler.go index c40015d3c4a..c056d3a2f58 100644 --- a/pkg/scalers/huawei_cloudeye_scaler.go +++ b/pkg/scalers/huawei_cloudeye_scaler.go @@ -242,7 +242,7 @@ func (h *huaweiCloudeyeScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetMetricValue := resource.NewQuantity(int64(h.metadata.targetMetricValue), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: fmt.Sprintf("%s-%s-%s-%s", strings.ReplaceAll(h.metadata.namespace, ".", "-"), + Name: fmt.Sprintf("%s-%s-%s-%s-%s", "huawei-cloudeye", strings.ReplaceAll(h.metadata.namespace, ".", "-"), h.metadata.metricsName, h.metadata.dimensionName, h.metadata.dimensionValue), }, diff --git a/pkg/scalers/huawei_cloudeye_test.go b/pkg/scalers/huawei_cloudeye_test.go index d426ef25dbc..532898b68c4 100644 --- a/pkg/scalers/huawei_cloudeye_test.go +++ b/pkg/scalers/huawei_cloudeye_test.go @@ -22,6 +22,11 @@ type parseHuaweiCloudeyeMetadataTestData struct { comment string } +type huaweiCloudeyeMetricIdentifier struct { + metadataTestData *parseHuaweiCloudeyeMetadataTestData + name string +} + var testHuaweiAuthenticationWithCloud = map[string]string{ "IdentityEndpoint": testHuaweiCloudeyeIdentityEndpoint, "ProjectID": testHuaweiCloudeyeProjectID, @@ -134,6 +139,10 @@ var testHuaweiCloudeyeMetadata = []parseHuaweiCloudeyeMetadataTestData{ "metadata miss minMetricValue"}, } +var huaweiCloudeyeMetricIdentifiers = []huaweiCloudeyeMetricIdentifier{ + {&testHuaweiCloudeyeMetadata[0], "huawei-cloudeye-SYS-ELB-mb_l7_qps-lbaas_instance_id-5e052238-0346-xxb0-86ea-92d9f33e29d2"}, +} + func TestHuaweiCloudeyeParseMetadata(t *testing.T) { for _, testData := range testHuaweiCloudeyeMetadata { _, err := parseHuaweiCloudeyeMetadata(testData.metadata, testData.authParams) @@ -145,3 +154,19 @@ func TestHuaweiCloudeyeParseMetadata(t *testing.T) { } } } + +func TestHuaweiCloudeyeGetMetricSpecForScaling(t *testing.T) { + for _, testData := range huaweiCloudeyeMetricIdentifiers { + meta, err := parseHuaweiCloudeyeMetadata(testData.metadataTestData.metadata, testData.metadataTestData.authParams) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockHuaweiCloudeyeScaler := huaweiCloudeyeScaler{meta} + + metricSpec := mockHuaweiCloudeyeScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/kafka_scaler.go b/pkg/scalers/kafka_scaler.go index cb57db287c5..e3ef8c56a2f 100644 --- a/pkg/scalers/kafka_scaler.go +++ b/pkg/scalers/kafka_scaler.go @@ -343,7 +343,7 @@ func (s *kafkaScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetMetricValue := resource.NewQuantity(s.metadata.lagThreshold, resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: lagThresholdMetricName, + Name: fmt.Sprintf("%s-%s-%s", "kafka", s.metadata.topic, s.metadata.group), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/kafka_scaler_test.go b/pkg/scalers/kafka_scaler_test.go index e5680a8d67c..ccd4483f68f 100644 --- a/pkg/scalers/kafka_scaler_test.go +++ b/pkg/scalers/kafka_scaler_test.go @@ -15,6 +15,11 @@ type parseKafkaMetadataTestData struct { offsetResetPolicy offsetResetPolicy } +type kafkaMetricIdentifier struct { + metadataTestData *parseKafkaMetadataTestData + name string +} + // A complete valid metadata example for reference var validMetadata = map[string]string{ "bootstrapServers": "broker1:9092,broker2:9092", @@ -51,6 +56,10 @@ var parseKafkaMetadataTestDataset = []parseKafkaMetadataTestData{ {map[string]string{"bootstrapServers": "foo:9092,bar:9092", "consumerGroup": "my-group", "topic": "my-topic", "offsetResetPolicy": "earliest"}, false, 2, []string{"foo:9092", "bar:9092"}, "my-group", "my-topic", offsetResetPolicy("earliest")}, } +var kafkaMetricIdentifiers = []kafkaMetricIdentifier{ + {&parseKafkaMetadataTestDataset[4], "kafka-my-topic-my-group"}, +} + func TestGetBrokers(t *testing.T) { for _, testData := range parseKafkaMetadataTestDataset { meta, err := parseKafkaMetadata(nil, testData.metadata, validWithAuthParams) @@ -102,3 +111,19 @@ func TestGetBrokers(t *testing.T) { } } } + +func TestKafkaGetMetricSpecForScaling(t *testing.T) { + for _, testData := range kafkaMetricIdentifiers { + meta, err := parseKafkaMetadata(nil, testData.metadataTestData.metadata, validWithAuthParams) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockKafkaScaler := kafkaScaler{meta, nil, nil} + + metricSpec := mockKafkaScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/liiklus_scaler.go b/pkg/scalers/liiklus_scaler.go index a18f67e0771..8630937d99d 100644 --- a/pkg/scalers/liiklus_scaler.go +++ b/pkg/scalers/liiklus_scaler.go @@ -81,7 +81,7 @@ func (s *liiklusScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetMetricValue := resource.NewQuantity(s.metadata.lagThreshold, resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: liiklusLagThresholdMetricName, + Name: fmt.Sprintf("%s-%s-%s", "liiklus", s.metadata.topic, s.metadata.group), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/liiklus_scaler_test.go b/pkg/scalers/liiklus_scaler_test.go index 677da24b50e..087c3ca1a2a 100644 --- a/pkg/scalers/liiklus_scaler_test.go +++ b/pkg/scalers/liiklus_scaler_test.go @@ -19,6 +19,11 @@ type parseLiiklusMetadataTestData struct { threshold int64 } +type liiklusMetricIdentifier struct { + metadataTestData *parseLiiklusMetadataTestData + name string +} + var parseLiiklusMetadataTestDataset = []parseLiiklusMetadataTestData{ {map[string]string{}, errors.New("no topic provided"), "", "", "", 0}, {map[string]string{"topic": "foo"}, errors.New("no liiklus API address provided"), "", "", "", 0}, @@ -27,6 +32,10 @@ var parseLiiklusMetadataTestDataset = []parseLiiklusMetadataTestData{ {map[string]string{"topic": "foo", "address": "bar:6565", "group": "mygroup", "lagThreshold": "15"}, nil, "bar:6565", "mygroup", "foo", 15}, } +var liiklusMetricIdentifiers = []liiklusMetricIdentifier{ + {&parseLiiklusMetadataTestDataset[4], "liiklus-foo-mygroup"}, +} + func TestLiiklusParseMetadata(t *testing.T) { for _, testData := range parseLiiklusMetadataTestDataset { meta, err := parseLiiklusMetadata(testData.metadata) @@ -156,3 +165,19 @@ func TestLiiklusScalerGetMetricsBehavior(t *testing.T) { } } + +func TestLiiklusGetMetricSpecForScaling(t *testing.T) { + for _, testData := range liiklusMetricIdentifiers { + meta, err := parseLiiklusMetadata(testData.metadataTestData.metadata) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockLiiklusScaler := liiklusScaler{meta, nil, nil} + + metricSpec := mockLiiklusScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/mysql_scaler.go b/pkg/scalers/mysql_scaler.go index 9b42d6ed3bc..6508c702e9d 100644 --- a/pkg/scalers/mysql_scaler.go +++ b/pkg/scalers/mysql_scaler.go @@ -185,9 +185,15 @@ func (s *mySQLScaler) getQueryResult() (int, error) { // GetMetricSpecForScaling returns the MetricSpec for the Horizontal Pod Autoscaler func (s *mySQLScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetQueryValue := resource.NewQuantity(int64(s.metadata.queryValue), resource.DecimalSI) + metricName := "mysql" + if s.metadata.connectionString != "" { + metricName = fmt.Sprintf("%s-%s", metricName, s.metadata.connectionString) + } else { + metricName = fmt.Sprintf("%s-%s", metricName, s.metadata.dbName) + } externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: mySQLMetricName, + Name: metricName, }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/mysql_scaler_test.go b/pkg/scalers/mysql_scaler_test.go index 75fc46b494b..3f01f9056b9 100644 --- a/pkg/scalers/mysql_scaler_test.go +++ b/pkg/scalers/mysql_scaler_test.go @@ -14,13 +14,23 @@ type parseMySQLMetadataTestData struct { raisesError bool } +type mySQLMetricIdentifier struct { + metadataTestData *parseMySQLMetadataTestData + name string +} + var testMySQLMetdata = []parseMySQLMetadataTestData{ // No metadata - {metdadata: map[string]string{}, raisesError: true}, + {map[string]string{}, true}, // connectionString - {metdadata: map[string]string{"query": "query", "queryValue": "12", "connectionString": "test_value"}, raisesError: false}, + {map[string]string{"query": "query", "queryValue": "12", "connectionString": "test_value"}, false}, // Params instead of conn str - {metdadata: map[string]string{"query": "query", "queryValue": "12", "host": "test_host", "port": "test_port", "username": "test_username", "password": "test_password", "dbName": "test_dbname"}, raisesError: false}, + {map[string]string{"query": "query", "queryValue": "12", "host": "test_host", "port": "test_port", "username": "test_username", "password": "test_password", "dbName": "test_dbname"}, false}, +} + +var mySQLMetricIdentifiers = []mySQLMetricIdentifier{ + {&testMySQLMetdata[1], "mysql-test_value"}, + {&testMySQLMetdata[2], "mysql-test_dbname"}, } func TestParseMySQLMetadata(t *testing.T) { @@ -55,3 +65,19 @@ func TestMetadataToConnectionStrBuildNew(t *testing.T) { t.Errorf("%s != %s", expected, connStr) } } + +func TestMySQLGetMetricSpecForScaling(t *testing.T) { + for _, testData := range mySQLMetricIdentifiers { + meta, err := parseMySQLMetadata(map[string]string{"test_value": "test_value"}, testData.metadataTestData.metdadata, nil) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockMySQLScaler := mySQLScaler{meta, nil} + + metricSpec := mockMySQLScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/postgresql_scaler.go b/pkg/scalers/postgresql_scaler.go index 808db29c1cd..eed9c3eddb3 100644 --- a/pkg/scalers/postgresql_scaler.go +++ b/pkg/scalers/postgresql_scaler.go @@ -184,9 +184,15 @@ func (s *postgreSQLScaler) getActiveNumber() (int, error) { // GetMetricSpecForScaling returns the MetricSpec for the Horizontal Pod Autoscaler func (s *postgreSQLScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetQueryValue := resource.NewQuantity(int64(s.metadata.targetQueryValue), resource.DecimalSI) + metricName := "postgresql" + if s.metadata.connection != "" { + metricName = fmt.Sprintf("%s-%s", metricName, s.metadata.connection) + } else { + metricName = fmt.Sprintf("%s-%s", metricName, s.metadata.dbName) + } externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: pgMetricName, + Name: metricName, }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/postgresql_scaler_test.go b/pkg/scalers/postgresql_scaler_test.go new file mode 100644 index 00000000000..873aa6734dc --- /dev/null +++ b/pkg/scalers/postgresql_scaler_test.go @@ -0,0 +1,43 @@ +package scalers + +import ( + "testing" +) + +type parsePostgreSQLMetadataTestData struct { + metdadata map[string]string + isError bool +} + +type postgreSQLMetricIdentifier struct { + metadataTestData *parsePostgreSQLMetadataTestData + name string +} + +var testPostgreSQLMetdata = []parsePostgreSQLMetadataTestData{ + // connection + {map[string]string{"query": "test_query", "targetQueryValue": "5", "connection": "test_connection_string"}, false}, + // dbName + {map[string]string{"query": "test_query", "targetQueryValue": "5", "host": "test_host", "port": "test_port", "userName": "test_user_name", "dbName": "test_db_name", "sslmode": "test_ssl_mode"}, false}, +} + +var postgreSQLMetricIdentifiers = []postgreSQLMetricIdentifier{ + {&testPostgreSQLMetdata[0], "postgresql-test_connection_string"}, + {&testPostgreSQLMetdata[1], "postgresql-test_db_name"}, +} + +func TestPosgresSQLGetMetricSpecForScaling(t *testing.T) { + for _, testData := range postgreSQLMetricIdentifiers { + meta, err := parsePostgreSQLMetadata(map[string]string{"test_connection_string": "test_connection_string"}, testData.metadataTestData.metdadata, nil) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockPostgresSQLScaler := postgreSQLScaler{meta, nil} + + metricSpec := mockPostgresSQLScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/prometheus_scaler.go b/pkg/scalers/prometheus_scaler.go index f1691bc90fe..c42a60318de 100644 --- a/pkg/scalers/prometheus_scaler.go +++ b/pkg/scalers/prometheus_scaler.go @@ -113,7 +113,7 @@ func (s *prometheusScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetMetricValue := resource.NewQuantity(int64(s.metadata.threshold), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: s.metadata.metricName, + Name: fmt.Sprintf("%s-%s-%s", "prometheus", s.metadata.serverAddress, s.metadata.metricName), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/prometheus_scaler_test.go b/pkg/scalers/prometheus_scaler_test.go index af076a7cf90..dd8e3a22940 100644 --- a/pkg/scalers/prometheus_scaler_test.go +++ b/pkg/scalers/prometheus_scaler_test.go @@ -9,6 +9,11 @@ type parsePrometheusMetadataTestData struct { isError bool } +type prometheusMetricIdentifier struct { + metadataTestData *parsePrometheusMetadataTestData + name string +} + var testPromMetadata = []parsePrometheusMetadataTestData{ {map[string]string{}, true}, // all properly formed @@ -25,6 +30,10 @@ var testPromMetadata = []parsePrometheusMetadataTestData{ {map[string]string{"serverAddress": "http://localhost:9090", "metricName": "http_requests_total", "threshold": "100", "query": "up"}, false}, } +var prometheusMetricIdentifiers = []prometheusMetricIdentifier{ + {&testPromMetadata[1], "prometheus-http://localhost:9090-http_requests_total"}, +} + func TestPrometheusParseMetadata(t *testing.T) { for _, testData := range testPromMetadata { _, err := parsePrometheusMetadata(testData.metadata, map[string]string{}) @@ -36,3 +45,19 @@ func TestPrometheusParseMetadata(t *testing.T) { } } } + +func TestPrometheusGetMetricSpecForScaling(t *testing.T) { + for _, testData := range prometheusMetricIdentifiers { + meta, err := parsePrometheusMetadata(testData.metadataTestData.metadata, nil) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockPrometheusScaler := prometheusScaler{meta} + + metricSpec := mockPrometheusScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/rabbitmq_scaler.go b/pkg/scalers/rabbitmq_scaler.go index beee26f5fea..ca3affe81aa 100644 --- a/pkg/scalers/rabbitmq_scaler.go +++ b/pkg/scalers/rabbitmq_scaler.go @@ -237,7 +237,7 @@ func (s *rabbitMQScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetMetricValue := resource.NewQuantity(int64(s.metadata.queueLength), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: rabbitQueueLengthMetricName, + Name: fmt.Sprintf("%s-%s", "rabbitmq", s.metadata.queueName), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/rabbitmq_scaler_test.go b/pkg/scalers/rabbitmq_scaler_test.go index dbacdc805a6..ee2047c266f 100644 --- a/pkg/scalers/rabbitmq_scaler_test.go +++ b/pkg/scalers/rabbitmq_scaler_test.go @@ -20,6 +20,11 @@ type parseRabbitMQMetadataTestData struct { authParams map[string]string } +type rabbitMQMetricIdentifier struct { + metadataTestData *parseRabbitMQMetadataTestData + name string +} + var sampleRabbitMqResolvedEnv = map[string]string{ host: "amqp://user:sercet@somehost.com:5236/vhost", apiHost: "https://user:secret@somehost.com/vhost", @@ -42,6 +47,10 @@ var testRabbitMQMetadata = []parseRabbitMQMetadataTestData{ {map[string]string{"queueLength": "10", "queueName": "sample", "apiHost": apiHost, "includeUnacked": "true"}, false, map[string]string{}}, } +var rabbitMQMetricIdentifiers = []rabbitMQMetricIdentifier{ + {&testRabbitMQMetadata[1], "rabbitmq-sample"}, +} + func TestRabbitMQParseMetadata(t *testing.T) { for _, testData := range testRabbitMQMetadata { _, err := parseRabbitMQMetadata(sampleRabbitMqResolvedEnv, testData.metadata, testData.authParams) @@ -147,3 +156,19 @@ func TestGetQueueInfo(t *testing.T) { } } } + +func TestRabbitMQGetMetricSpecForScaling(t *testing.T) { + for _, testData := range rabbitMQMetricIdentifiers { + meta, err := parseRabbitMQMetadata(map[string]string{"myHostSecret": "myHostSecret"}, testData.metadataTestData.metadata, nil) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockRabbitMQScaler := rabbitMQScaler{meta, nil, nil} + + metricSpec := mockRabbitMQScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/redis_scaler.go b/pkg/scalers/redis_scaler.go index c803ca346af..644413aae57 100644 --- a/pkg/scalers/redis_scaler.go +++ b/pkg/scalers/redis_scaler.go @@ -16,7 +16,6 @@ import ( ) const ( - listLengthMetricName = "RedisListLength" defaultTargetListLength = 5 defaultRedisAddress = "redis-master.default.svc.cluster.local:6379" defaultRedisPassword = "" @@ -161,7 +160,7 @@ func (s *redisScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetListLengthQty := resource.NewQuantity(int64(s.metadata.targetListLength), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: listLengthMetricName, + Name: fmt.Sprintf("%s-%s", "redis", s.metadata.listName), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/redis_scaler_test.go b/pkg/scalers/redis_scaler_test.go index a19e9686091..db64ccd6b77 100644 --- a/pkg/scalers/redis_scaler_test.go +++ b/pkg/scalers/redis_scaler_test.go @@ -16,6 +16,11 @@ type parseRedisMetadataTestData struct { authParams map[string]string } +type redisMetricIdentifier struct { + metadataTestData *parseRedisMetadataTestData + name string +} + var testRedisMetadata = []parseRedisMetadataTestData{ // nothing passed {map[string]string{}, true, map[string]string{}}, @@ -37,6 +42,10 @@ var testRedisMetadata = []parseRedisMetadataTestData{ {map[string]string{"listName": "mylist", "listLength": "0", "address": "REDIS_WRONG"}, true, map[string]string{"password": ""}}, } +var redisMetricIdentifiers = []redisMetricIdentifier{ + {&testRedisMetadata[1], "redis-mylist"}, +} + func TestRedisParseMetadata(t *testing.T) { for _, testData := range testRedisMetadata { _, err := parseRedisMetadata(testData.metadata, testRedisResolvedEnv, testData.authParams) @@ -48,3 +57,19 @@ func TestRedisParseMetadata(t *testing.T) { } } } + +func TestRedisGetMetricSpecForScaling(t *testing.T) { + for _, testData := range redisMetricIdentifiers { + meta, err := parseRedisMetadata(testData.metadataTestData.metadata, testRedisResolvedEnv, testData.metadataTestData.authParams) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockRedisScaler := redisScaler{meta} + + metricSpec := mockRedisScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/redis_streams_scaler.go b/pkg/scalers/redis_streams_scaler.go index 7eda4156d85..000092970d9 100644 --- a/pkg/scalers/redis_streams_scaler.go +++ b/pkg/scalers/redis_streams_scaler.go @@ -16,8 +16,6 @@ import ( ) const ( - pendingEntriesCountMetricName = "RedisStreamPendingEntriesCount" - // defaults defaultTargetPendingEntriesCount = 5 defaultAddress = "redis-master.default.svc.cluster.local:6379" @@ -214,7 +212,7 @@ func (s *redisStreamsScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetPendingEntriesCount := resource.NewQuantity(int64(s.metadata.targetPendingEntriesCount), resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: pendingEntriesCountMetricName, + Name: fmt.Sprintf("%s-%s-%s", "redis-streams", s.metadata.streamName, s.metadata.consumerGroupName), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/redis_streams_scaler_test.go b/pkg/scalers/redis_streams_scaler_test.go index b7bec841810..b3c2ca3d03c 100644 --- a/pkg/scalers/redis_streams_scaler_test.go +++ b/pkg/scalers/redis_streams_scaler_test.go @@ -103,3 +103,33 @@ type redisStreamsTestMetadata struct { isError bool authParams map[string]string } + +func TestRedisStreamsGetMetricSpecForScaling(t *testing.T) { + + type redisStreamsMetricIdentifier struct { + metadataTestData *redisStreamsTestMetadata + name string + } + + var redisStreamsTestData = []redisStreamsTestMetadata{ + {map[string]string{"stream": "my-stream", "consumerGroup": "my-stream-consumer-group", "pendingEntriesCount": "5", "address": "REDIS_SERVICE", "password": "REDIS_PASSWORD", "databaseIndex": "0", "enableTLS": "true"}, false, nil}, + } + + var redisStreamMetricIdentifiers = []redisStreamsMetricIdentifier{ + {&redisStreamsTestData[0], "redis-streams-my-stream-my-stream-consumer-group"}, + } + + for _, testData := range redisStreamMetricIdentifiers { + meta, err := parseRedisStreamsMetadata(testData.metadataTestData.metadata, map[string]string{"REDIS_SERVICE": "my-address"}, nil) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockRedisStreamsScaler := redisStreamsScaler{meta, nil} + + metricSpec := mockRedisStreamsScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +} diff --git a/pkg/scalers/stan_scaler.go b/pkg/scalers/stan_scaler.go index 91014464823..2edfd354fb1 100644 --- a/pkg/scalers/stan_scaler.go +++ b/pkg/scalers/stan_scaler.go @@ -183,7 +183,7 @@ func (s *stanScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { targetMetricValue := resource.NewQuantity(s.metadata.lagThreshold, resource.DecimalSI) externalMetric := &v2beta2.ExternalMetricSource{ Metric: v2beta2.MetricIdentifier{ - Name: lagThresholdMetricName, + Name: fmt.Sprintf("%s-%s-%s-%s", "stan", s.metadata.queueGroup, s.metadata.durableName, s.metadata.subject), }, Target: v2beta2.MetricTarget{ Type: v2beta2.AverageValueMetricType, diff --git a/pkg/scalers/stan_scaler_test.go b/pkg/scalers/stan_scaler_test.go index dc36b2dac65..60d12a90d0d 100644 --- a/pkg/scalers/stan_scaler_test.go +++ b/pkg/scalers/stan_scaler_test.go @@ -9,6 +9,11 @@ type parseStanMetadataTestData struct { isError bool } +type stanMetricIdentifier struct { + metadataTestData *parseStanMetadataTestData + name string +} + var testStanMetadata = []parseStanMetadataTestData{ // nothing passed {map[string]string{}, true}, @@ -22,6 +27,10 @@ var testStanMetadata = []parseStanMetadataTestData{ {map[string]string{"natsServerMonitoringEndpoint": "stan-nats-ss", "queueGroup": "grp1", "durableName": "ImDurable", "subject": "mySubject"}, false}, } +var stanMetricIdentifiers = []stanMetricIdentifier{ + {&testStanMetadata[4], "stan-grp1-ImDurable-mySubject"}, +} + func TestStanParseMetadata(t *testing.T) { for _, testData := range testStanMetadata { _, err := parseStanMetadata(testData.metadata) @@ -33,3 +42,19 @@ func TestStanParseMetadata(t *testing.T) { } } } + +func TestStanGetMetricSpecForScaling(t *testing.T) { + for _, testData := range stanMetricIdentifiers { + meta, err := parseStanMetadata(testData.metadataTestData.metadata) + if err != nil { + t.Fatal("Could not parse metadata:", err) + } + mockStanScaler := stanScaler{nil, meta} + + metricSpec := mockStanScaler.GetMetricSpecForScaling() + metricName := metricSpec[0].External.Metric.Name + if metricName != testData.name { + t.Error("Wrong External metric source name:", metricName) + } + } +}