diff --git a/test/metric/metric_value_query.go b/test/metric/metric_value_query.go index eea358074..be4a7327c 100644 --- a/test/metric/metric_value_query.go +++ b/test/metric/metric_value_query.go @@ -46,7 +46,7 @@ func (n *MetricValueFetcher) Fetch(namespace, metricName string, metricSpecificD Period: &metricQueryPeriod, Stat: aws.String(string(stat)), }, - Id: aws.String(strings.ToLower(metricName)), + Id: aws.String(strings.ToLower(strings.ReplaceAll(metricName, ".", "_"))), }, } diff --git a/test/metric_value_benchmark/agent_configs/jmx_config.json b/test/metric_value_benchmark/agent_configs/jmx_config.json new file mode 100644 index 000000000..0e12212fe --- /dev/null +++ b/test/metric_value_benchmark/agent_configs/jmx_config.json @@ -0,0 +1,25 @@ +{ + "agent": { + "debug": true + }, + "metrics": { + "namespace": "MetricValueBenchmarkJMXTest", + "force_flush_interval": 5, + "aggregation_dimensions": [ + [ + "InstanceId" + ] + ], + "append_dimensions": { + "InstanceId": "${aws:InstanceId}" + }, + "metrics_collected": { + "jmx": [ + { + "endpoint": "localhost:2020", + "target_system": "jvm,kafka" + } + ] + } + } +} \ No newline at end of file diff --git a/test/metric_value_benchmark/jmx_test.go b/test/metric_value_benchmark/jmx_test.go new file mode 100644 index 000000000..3ab2fe0b0 --- /dev/null +++ b/test/metric_value_benchmark/jmx_test.go @@ -0,0 +1,120 @@ +// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +// SPDX-License-Identifier: MIT + +//go:build !windows + +package metric_value_benchmark + +import ( + "github.com/aws/amazon-cloudwatch-agent-test/util/common" + "log" + + "github.com/aws/amazon-cloudwatch-agent-test/test/metric" + "github.com/aws/amazon-cloudwatch-agent-test/test/metric/dimension" + "github.com/aws/amazon-cloudwatch-agent-test/test/status" + "github.com/aws/amazon-cloudwatch-agent-test/test/test_runner" +) + +const jmxNamespace = "MetricValueBenchmarkJMXTest" + +type JMXTestRunner struct { + test_runner.BaseTestRunner +} + +var _ test_runner.ITestRunner = (*JMXTestRunner)(nil) + +func (t *JMXTestRunner) Validate() status.TestGroupResult { + metricsToFetch := t.GetMeasuredMetrics() + testResults := make([]status.TestResult, len(metricsToFetch)) + for i, metricName := range metricsToFetch { + testResults[i] = t.validateJMXMetric(metricName) + } + + return status.TestGroupResult{ + Name: t.GetTestName(), + TestResults: testResults, + } +} + +func (t *JMXTestRunner) GetTestName() string { + return "JMX" +} + +func (t *JMXTestRunner) GetAgentConfigFileName() string { + return "jmx_config.json" +} + +func (t *JMXTestRunner) SetupBeforeAgentRun() error { + err := t.BaseTestRunner.SetupBeforeAgentRun() + if err != nil { + return err + } + + log.Println("set up zookeeper and kafka") + startJMXCommands := []string{ + "curl https://dlcdn.apache.org/zookeeper/zookeeper-3.9.1/apache-zookeeper-3.9.1-bin.tar.gz -o apache-zookeeper-3.9.1-bin.tar.gz", + "tar -xzf apache-zookeeper-3.9.1-bin.tar.gz", + "mkdir apache-zookeeper-3.9.1-bin/data", + "touch apache-zookeeper-3.9.1-bin/conf/zoo.cfg", + "echo -e 'tickTime = 2000\ndataDir = ../data\nclientPort = 2181\ninitLimit = 5\nsyncLimit = 2\n' >> apache-zookeeper-3.9.1-bin/conf/zoo.cfg", + "apache-zookeeper-3.9.1-bin/bin/zkServer.sh start", + "curl https://dlcdn.apache.org/kafka/3.6.1/kafka_2.13-3.6.1.tgz -o kafka_2.13-3.6.1.tgz", + "tar -xzf kafka_2.13-3.6.1.tgz", + "echo 'KAFKA_JMX_OPTS=\"-Dcom.sun.management.jmxremote.port=2020 -Dcom.sun.management.jmxremote.rmi.port=2021 -Djava.rmi.server.hostname=localhost -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false\"'|cat - kafka_2.13-3.6.1/bin/kafka-run-class.sh > /tmp/kafka-jmx-config && mv /tmp/kafka-jmx-config kafka_2.13-3.6.1/bin/kafka-run-class.sh", + "sudo chmod +x kafka_2.13-3.6.1/bin/kafka-run-class.sh", + "kafka_2.13-3.6.1/bin/kafka-server-start.sh kafka_2.13-3.6.1/config/server.properties >/dev/null 2>&1 &", + } + + err = common.RunCommands(startJMXCommands) + if err != nil { + return err + } + return nil +} + +// the metric name is . but when searching you need to use _ +// because of go sdk +func (t *JMXTestRunner) GetMeasuredMetrics() []string { + return []string{ + "jvm.memory.heap.used", + "jvm.threads.count", + "jvm.gc.collections.elapsed", + "jvm.gc.collections.elapsed", + "kafka.request.count", + "kafka.request.time.50p", + "kafka.network.io", + } +} + +func (t *JMXTestRunner) validateJMXMetric(metricName string) status.TestResult { + testResult := status.TestResult{ + Name: metricName, + Status: status.FAILED, + } + + dims, failed := t.DimensionFactory.GetDimensions([]dimension.Instruction{ + { + Key: "InstanceId", + Value: dimension.UnknownDimensionValue(), + }, + }) + + if len(failed) > 0 { + return testResult + } + + fetcher := metric.MetricValueFetcher{} + values, err := fetcher.Fetch(jmxNamespace, metricName, dims, metric.AVERAGE, metric.HighResolutionStatPeriod) + log.Printf("metric values are %v", values) + if err != nil { + log.Printf("err: %v\n", err) + return testResult + } + + if !metric.IsAllValuesGreaterThanOrEqualToExpectedValue(metricName, values, 0) { + return testResult + } + + testResult.Status = status.SUCCESSFUL + return testResult +} diff --git a/test/metric_value_benchmark/metrics_value_benchmark_test.go b/test/metric_value_benchmark/metrics_value_benchmark_test.go index 8dbdd7390..ec97548b5 100644 --- a/test/metric_value_benchmark/metrics_value_benchmark_test.go +++ b/test/metric_value_benchmark/metrics_value_benchmark_test.go @@ -113,6 +113,7 @@ func getEc2TestRunners(env *environment.MetaData) []*test_runner.TestRunner { {TestRunner: &ProcessesTestRunner{test_runner.BaseTestRunner{DimensionFactory: factory}}}, {TestRunner: &CollectDTestRunner{test_runner.BaseTestRunner{DimensionFactory: factory}}}, {TestRunner: &RenameSSMTestRunner{test_runner.BaseTestRunner{DimensionFactory: factory}}}, + {TestRunner: &JMXTestRunner{test_runner.BaseTestRunner{DimensionFactory: factory}}}, } } return ec2TestRunners @@ -157,5 +158,10 @@ func shouldRunEC2Test(env *environment.MetaData, t *test_runner.TestRunner) bool } _, shouldRun := env.EC2PluginTests[strings.ToLower(t.TestRunner.GetTestName())] _, shouldExclude := env.ExcludedTests[strings.ToLower(t.TestRunner.GetTestName())] - return shouldRun || !shouldExclude + if shouldRun { + return true + } else if len(env.ExcludedTests) != 0 { + return !shouldExclude + } + return false }