Skip to content

Commit a095ba9

Browse files
authored
feat: Add append_dimensions tests for collectd, ethtool, and cpu plugins (#647)
* feat: Add append_dimensions tests for collectd, ethtool, and cpu plugins * Address CR feedback: use shared helpers, extract summary table - Refactor CollectdFleetAggregationTestRunner to use DimensionSpec helpers instead of manual dimension.Instruction construction - Add EC2-specific comment for hardcoded 'ena' driver name - Change fmt.Printf to log.Printf in isAllValuesGreaterThanOrEqualToZero to preserve timestamps in output - Move printTestSummaryTable and testDescriptions to test_summary_helpers.go
1 parent dc378a6 commit a095ba9

20 files changed

Lines changed: 1062 additions & 105 deletions
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"agent": {
3+
"metrics_collection_interval": 10,
4+
"run_as_user": "root",
5+
"debug": true,
6+
"logfile": ""
7+
},
8+
"metrics": {
9+
"namespace": "CollectdAppendDimensionsTest",
10+
"aggregation_dimensions": [
11+
["InstanceId", "InstanceType", "host", "type"]
12+
],
13+
"metrics_collected": {
14+
"collectd": {
15+
"metrics_aggregation_interval": 30,
16+
"collectd_security_level": "none",
17+
"append_dimensions": {
18+
"InstanceId": "${aws:InstanceId}",
19+
"InstanceType": "${aws:InstanceType}"
20+
}
21+
}
22+
},
23+
"force_flush_interval": 5
24+
}
25+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"agent": {
3+
"metrics_collection_interval": 10,
4+
"run_as_user": "root",
5+
"debug": true,
6+
"logfile": ""
7+
},
8+
"metrics": {
9+
"namespace": "CollectdFleetAggregationTest",
10+
"aggregation_dimensions": [
11+
["Component", "type", "InstanceId"],
12+
["Component", "type"],
13+
["Component", "type", "host"]
14+
],
15+
"metrics_collected": {
16+
"collectd": {
17+
"metrics_aggregation_interval": 30,
18+
"collectd_security_level": "none",
19+
"append_dimensions": {
20+
"InstanceId": "${aws:InstanceId}",
21+
"Component": "WebServer"
22+
}
23+
}
24+
},
25+
"force_flush_interval": 5
26+
}
27+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"agent": {
3+
"metrics_collection_interval": 10,
4+
"run_as_user": "root",
5+
"debug": true,
6+
"logfile": ""
7+
},
8+
"metrics": {
9+
"namespace": "CollectdGlobalAppendDimensionsTest",
10+
"aggregation_dimensions": [
11+
["InstanceId", "InstanceType", "type"]
12+
],
13+
"append_dimensions": {
14+
"InstanceId": "${aws:InstanceId}",
15+
"InstanceType": "${aws:InstanceType}"
16+
},
17+
"metrics_collected": {
18+
"collectd": {
19+
"metrics_aggregation_interval": 30,
20+
"collectd_security_level": "none"
21+
}
22+
},
23+
"force_flush_interval": 5
24+
}
25+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"agent": {
3+
"metrics_collection_interval": 10,
4+
"run_as_user": "root",
5+
"debug": true,
6+
"logfile": ""
7+
},
8+
"metrics": {
9+
"namespace": "CollectdNoAppendDimensionsTest",
10+
"aggregation_dimensions": [
11+
["host", "type"]
12+
],
13+
"metrics_collected": {
14+
"collectd": {
15+
"metrics_aggregation_interval": 30,
16+
"collectd_security_level": "none"
17+
}
18+
},
19+
"force_flush_interval": 5
20+
}
21+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"agent": {
3+
"metrics_collection_interval": 10,
4+
"run_as_user": "root",
5+
"debug": true,
6+
"logfile": ""
7+
},
8+
"metrics": {
9+
"namespace": "CpuGlobalAppendDimensionsTest",
10+
"aggregation_dimensions": [
11+
["InstanceId", "InstanceType", "cpu"]
12+
],
13+
"append_dimensions": {
14+
"InstanceId": "${aws:InstanceId}",
15+
"InstanceType": "${aws:InstanceType}"
16+
},
17+
"metrics_collected": {
18+
"cpu": {
19+
"measurement": ["time_active"]
20+
}
21+
},
22+
"force_flush_interval": 5
23+
}
24+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"agent": {
3+
"metrics_collection_interval": 10,
4+
"run_as_user": "root",
5+
"debug": true,
6+
"logfile": ""
7+
},
8+
"metrics": {
9+
"namespace": "EthtoolAppendDimensionsTest",
10+
"aggregation_dimensions": [
11+
["InstanceId", "InstanceType", "interface", "driver"]
12+
],
13+
"append_dimensions": {
14+
"InstanceId": "${aws:InstanceId}",
15+
"InstanceType": "${aws:InstanceType}"
16+
},
17+
"metrics_collected": {
18+
"ethtool": {
19+
"interface_include": ["eth0", "ens5"],
20+
"metrics_include": ["queue_0_tx_cnt", "queue_0_rx_cnt"]
21+
}
22+
},
23+
"force_flush_interval": 5
24+
}
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"agent": {
3+
"metrics_collection_interval": 10,
4+
"run_as_user": "root",
5+
"debug": true,
6+
"logfile": ""
7+
},
8+
"metrics": {
9+
"namespace": "EthtoolPluginAppendDimensionsTest",
10+
"aggregation_dimensions": [
11+
["InstanceId", "InstanceType", "host", "interface", "driver"]
12+
],
13+
"metrics_collected": {
14+
"ethtool": {
15+
"interface_include": ["eth0", "ens5"],
16+
"metrics_include": ["queue_0_tx_cnt", "queue_0_rx_cnt"],
17+
"append_dimensions": {
18+
"InstanceId": "${aws:InstanceId}",
19+
"InstanceType": "${aws:InstanceType}"
20+
}
21+
}
22+
},
23+
"force_flush_interval": 5
24+
}
25+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
//go:build !windows
5+
6+
package metric_dimension
7+
8+
import (
9+
"log"
10+
"time"
11+
12+
"github.com/aws/amazon-cloudwatch-agent-test/test/metric"
13+
"github.com/aws/amazon-cloudwatch-agent-test/test/status"
14+
"github.com/aws/amazon-cloudwatch-agent-test/test/test_runner"
15+
"github.com/aws/amazon-cloudwatch-agent-test/util/common"
16+
)
17+
18+
// CollectdAppendDimensionsTestRunner tests plugin-level append_dimensions for collectd.
19+
//
20+
// Per the CloudWatch Agent documentation, plugin-level append_dimensions ADDS dimensions
21+
// to the metrics without dropping existing dimensions like 'host'. This is different from
22+
// global append_dimensions which drops the 'host' dimension.
23+
//
24+
// This test validates that with plugin-level append_dimensions:
25+
// 1. The configured dimensions (InstanceId, InstanceType) ARE added
26+
// 2. The original 'host' dimension from collectd protocol is KEPT (not dropped)
27+
type CollectdAppendDimensionsTestRunner struct {
28+
test_runner.BaseTestRunner
29+
}
30+
31+
var _ test_runner.ITestRunner = (*CollectdAppendDimensionsTestRunner)(nil)
32+
33+
func (t *CollectdAppendDimensionsTestRunner) Validate() status.TestGroupResult {
34+
metricsToFetch := t.GetMeasuredMetrics()
35+
testResults := make([]status.TestResult, len(metricsToFetch))
36+
for i, metricName := range metricsToFetch {
37+
testResults[i] = t.validateCollectdAppendDimensionMetric(metricName)
38+
}
39+
40+
return status.TestGroupResult{
41+
Name: t.GetTestName(),
42+
TestResults: testResults,
43+
}
44+
}
45+
46+
func (t *CollectdAppendDimensionsTestRunner) GetTestName() string {
47+
return "CollectdAppendDimensions"
48+
}
49+
50+
func (t *CollectdAppendDimensionsTestRunner) GetAgentConfigFileName() string {
51+
return "collectd_append_dimensions.json"
52+
}
53+
54+
func (t *CollectdAppendDimensionsTestRunner) SetupAfterAgentRun() error {
55+
return common.SendCollectDMetrics(2, time.Second, t.GetAgentRunDuration())
56+
}
57+
58+
func (t *CollectdAppendDimensionsTestRunner) GetMeasuredMetrics() []string {
59+
return []string{"collectd_gauge_1_value"}
60+
}
61+
62+
func (t *CollectdAppendDimensionsTestRunner) GetAgentRunDuration() time.Duration {
63+
return 2 * time.Minute
64+
}
65+
66+
func (t *CollectdAppendDimensionsTestRunner) validateCollectdAppendDimensionMetric(metricName string) status.TestResult {
67+
metricType := metric.GetCollectDMetricType(metricName)
68+
ns := "CollectdAppendDimensionsTest"
69+
70+
// With plugin-level append_dimensions, BOTH the configured dimensions AND the original
71+
// host dimension should be present.
72+
specs := append(EC2Dims(), HostDim(), ExactDim("type", metricType))
73+
74+
result := ValidateDimensionsPresent(&t.BaseTestRunner, ns, metricName, specs)
75+
if result.Status == status.SUCCESSFUL {
76+
log.Printf("Verified: plugin-level append_dimensions adds InstanceId/InstanceType while keeping host dimension")
77+
}
78+
return result
79+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
//go:build !windows
5+
6+
package metric_dimension
7+
8+
import (
9+
"log"
10+
"time"
11+
12+
"github.com/aws/amazon-cloudwatch-agent-test/test/metric"
13+
"github.com/aws/amazon-cloudwatch-agent-test/test/status"
14+
"github.com/aws/amazon-cloudwatch-agent-test/test/test_runner"
15+
"github.com/aws/amazon-cloudwatch-agent-test/util/common"
16+
)
17+
18+
// CollectdFleetAggregationTestRunner tests fleet aggregation with plugin-level append_dimensions.
19+
//
20+
// This test uses plugin-level append_dimensions (under metrics_collected.collectd.append_dimensions)
21+
// which ADDS dimensions without dropping the 'host' dimension. The aggregation_dimensions config
22+
// controls which dimension combinations are published to CloudWatch.
23+
//
24+
// The test validates:
25+
// 1. Aggregated metrics with [Component, type] dimensions exist (fleet-wide aggregation)
26+
// 2. Aggregated metrics with [Component, type, InstanceId] dimensions exist (per-instance)
27+
// 3. The host dimension is KEPT (plugin-level behavior) - verified via aggregation_dimensions
28+
type CollectdFleetAggregationTestRunner struct {
29+
test_runner.BaseTestRunner
30+
}
31+
32+
var _ test_runner.ITestRunner = (*CollectdFleetAggregationTestRunner)(nil)
33+
34+
func (t *CollectdFleetAggregationTestRunner) Validate() status.TestGroupResult {
35+
metricsToFetch := t.GetMeasuredMetrics()
36+
testResults := make([]status.TestResult, len(metricsToFetch))
37+
for i, metricName := range metricsToFetch {
38+
testResults[i] = t.validateCollectdFleetAggregationMetric(metricName)
39+
}
40+
41+
return status.TestGroupResult{
42+
Name: t.GetTestName(),
43+
TestResults: testResults,
44+
}
45+
}
46+
47+
func (t *CollectdFleetAggregationTestRunner) GetTestName() string {
48+
return "CollectdFleetAggregation"
49+
}
50+
51+
func (t *CollectdFleetAggregationTestRunner) GetAgentConfigFileName() string {
52+
return "collectd_fleet_aggregation.json"
53+
}
54+
55+
func (t *CollectdFleetAggregationTestRunner) SetupAfterAgentRun() error {
56+
return common.SendCollectDMetrics(2, time.Second, t.GetAgentRunDuration())
57+
}
58+
59+
func (t *CollectdFleetAggregationTestRunner) GetMeasuredMetrics() []string {
60+
return []string{"collectd_gauge_1_value"}
61+
}
62+
63+
func (t *CollectdFleetAggregationTestRunner) GetAgentRunDuration() time.Duration {
64+
return 2 * time.Minute
65+
}
66+
67+
func (t *CollectdFleetAggregationTestRunner) validateCollectdFleetAggregationMetric(metricName string) status.TestResult {
68+
metricType := metric.GetCollectDMetricType(metricName)
69+
ns := "CollectdFleetAggregationTest"
70+
71+
// Test 1: Fleet-aggregated dimensions (Component + type from aggregation_dimensions)
72+
fleetSpecs := []DimensionSpec{
73+
ExactDim("Component", "WebServer"),
74+
ExactDim("type", metricType),
75+
}
76+
result := ValidateDimensionsPresent(&t.BaseTestRunner, ns, metricName, fleetSpecs)
77+
if result.Status != status.SUCCESSFUL {
78+
return result
79+
}
80+
81+
// Test 2: Per-instance aggregated dimensions (Component + type + InstanceId)
82+
instanceSpecs := []DimensionSpec{
83+
ExactDim("Component", "WebServer"),
84+
ExactDim("type", metricType),
85+
{Key: "InstanceId"},
86+
}
87+
result = ValidateDimensionsPresent(&t.BaseTestRunner, ns, metricName, instanceSpecs)
88+
if result.Status != status.SUCCESSFUL {
89+
return result
90+
}
91+
92+
// Test 3: Host dimension is KEPT (plugin-level append_dimensions does NOT drop host)
93+
hostSpecs := []DimensionSpec{
94+
ExactDim("Component", "WebServer"),
95+
ExactDim("type", metricType),
96+
HostDim(),
97+
}
98+
result = ValidateDimensionsPresent(&t.BaseTestRunner, ns, metricName, hostSpecs)
99+
if result.Status == status.SUCCESSFUL {
100+
log.Printf("Verified: plugin-level append_dimensions keeps host dimension and aggregation_dimensions controls published combinations")
101+
}
102+
return result
103+
}

0 commit comments

Comments
 (0)