Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions generator/test_case_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ var testTypeToTestConfig = map[string][]testConfig{
},
"ec2_linux_onprem": {
{testDir: "./test/cloudwatchlogs"},
{testDir: "./test/otel_collect/linux/otlp"},
{testDir: "./test/otel_collect/linux/host_metrics"},
{testDir: "./test/otel_collect/linux/prometheus"},
},
testTypeKeyEc2Linux: {
{testDir: "./test/ca_bundle"},
Expand Down Expand Up @@ -137,10 +140,10 @@ var testTypeToTestConfig = map[string][]testConfig{
testDir: "./test/otel_collect/database_insights",
excludedOs: map[string]struct{}{"ol8": {}, "ubuntu-25": {}},
},
{testDir: "./test/otel_collect/host_metrics"},
{testDir: "./test/otel_collect/otlp"},
{testDir: "./test/otel_collect/linux/host_metrics"},
{testDir: "./test/otel_collect/linux/otlp"},
{
testDir: "./test/otel_collect/prometheus",
testDir: "./test/otel_collect/linux/prometheus",
excludedOs: map[string]struct{}{"rhel8": {}, "ol8": {}, "sles-15": {}},
},
{
Expand Down Expand Up @@ -323,6 +326,9 @@ var testTypeToTestConfig = map[string][]testConfig{
targets: map[string]map[string]struct{}{"os": {"win-2019": {}}},
},
{testDir: "../../../test/ssm_document"},
{testDir: "../../../test/otel_collect/windows/otlp"},
{testDir: "../../../test/otel_collect/windows/host_metrics"},
{testDir: "../../../test/otel_collect/windows/prometheus"},
// assume role test doesn't add much value, and it already being tested with linux
//{testDir: "../../../test/assume_role"},
},
Expand Down Expand Up @@ -374,6 +380,10 @@ var testTypeToTestConfig = map[string][]testConfig{
testDir: "./test/ecs/service_discovery",
targets: map[string]map[string]struct{}{"metadataEnabled": {"enabled": {}}},
},
{
testDir: "./test/otel_collect/ecs/otlp",
targets: map[string]map[string]struct{}{"metadataEnabled": {"enabled": {}}},
},
},
"eks_addon": {
{
Expand Down Expand Up @@ -553,10 +563,10 @@ var partitionTests = map[string]partition{
tests: []string{testTypeKeyEc2Linux},
ami: []string{"cloudwatch-agent-integration-test-aarch64-al2023*"},
excludedTestDirs: map[string]struct{}{
"./test/otel_collect/database_insights": {},
"./test/otel_collect/host_metrics": {},
"./test/otel_collect/otlp": {},
"./test/otel_collect/prometheus": {},
"./test/otel_collect/database_insights": {},
"./test/otel_collect/linux/host_metrics": {},
"./test/otel_collect/linux/otlp": {},
"./test/otel_collect/linux/prometheus": {},
},
testConfigOverrides: map[string]testConfig{
"./test/metric_value_benchmark": {
Expand All @@ -574,10 +584,10 @@ var partitionTests = map[string]partition{
tests: []string{testTypeKeyEc2Linux},
ami: []string{"cloudwatch-agent-integration-test-aarch64-al2023*"},
excludedTestDirs: map[string]struct{}{
"./test/otel_collect/database_insights": {},
"./test/otel_collect/host_metrics": {},
"./test/otel_collect/otlp": {},
"./test/otel_collect/prometheus": {},
"./test/otel_collect/database_insights": {},
"./test/otel_collect/linux/host_metrics": {},
"./test/otel_collect/linux/otlp": {},
"./test/otel_collect/linux/prometheus": {},
},
testConfigOverrides: map[string]testConfig{
"./test/metric_value_benchmark": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
[
{
"name": "cloudwatch_agent",
"image": "${cwagent_image}",
"essential": true,
"secrets": [
{
"name": "CW_CONFIG_CONTENT",
"valueFrom": "${cwagent_ssm_parameter_arn}"
},
{
"name": "PROMETHEUS_CONFIG_CONTENT",
"valueFrom": "${prometheus_ssm_parameter_arn}"
}
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-region": "${region}",
"awslogs-stream-prefix": "${testing_id}",
"awslogs-group": "${log_group}"
}
},
"cpu": 1,
"memory": 2048
},
{
"name": "otlp_pusher",
"image": "curlimages/curl:8.10.1",
"essential": false,
"links": [
"cloudwatch_agent"
],
"environment": [
{
"name": "TEST_ID",
"value": "${testing_id}"
}
],
"entryPoint": [
"sh",
"-c"
],
"command": [
"while true; do S=$$(date +%s); NOW=$${S}000000000; START=$$((S-10))000000000; curl -s -X POST http://cloudwatch_agent:4318/v1/metrics -H 'Content-Type: application/json' -d '{\"resourceMetrics\":[{\"resource\":{\"attributes\":[{\"key\":\"TestId\",\"value\":{\"stringValue\":\"'\"$${TEST_ID}\"'\"}}]},\"scopeMetrics\":[{\"metrics\":[{\"name\":\"otlp_test_counter\",\"sum\":{\"dataPoints\":[{\"asInt\":\"1\",\"startTimeUnixNano\":\"'\"$${START}\"'\",\"timeUnixNano\":\"'\"$${NOW}\"'\",\"attributes\":[{\"key\":\"TestId\",\"value\":{\"stringValue\":\"'\"$${TEST_ID}\"'\"}}]}],\"aggregationTemporality\":1,\"isMonotonic\":true}},{\"name\":\"otlp_test_gauge\",\"gauge\":{\"dataPoints\":[{\"asDouble\":42.0,\"timeUnixNano\":\"'\"$${NOW}\"'\",\"attributes\":[{\"key\":\"TestId\",\"value\":{\"stringValue\":\"'\"$${TEST_ID}\"'\"}}]}]}}]}]}]}'; sleep 10; done"
],
"logConfiguration": {
"logDriver": "awslogs",
"options": {
"awslogs-region": "${region}",
"awslogs-stream-prefix": "${testing_id}-pusher",
"awslogs-group": "${log_group}"
}
},
"cpu": 1,
"memory": 256
}
]
87 changes: 87 additions & 0 deletions test/otel_collect/ecs/otlp/otlp_ecs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

//go:build !windows

package otlp

import (
"strings"
"testing"
"time"

"github.com/stretchr/testify/suite"

"github.com/aws/amazon-cloudwatch-agent-test/environment"
"github.com/aws/amazon-cloudwatch-agent-test/test/otel_collect/otlpvalidation"
"github.com/aws/amazon-cloudwatch-agent-test/test/status"
"github.com/aws/amazon-cloudwatch-agent-test/test/test_runner"
)

func init() {
environment.RegisterEnvironmentMetaDataFlags()
}

// clusterNamePrefix matches the ECS cluster naming in terraform/ecs_ec2/daemon.
const clusterNamePrefix = "cwagent-integ-test-cluster-"

// ECSOtlpTestRunner validates that a workload (sidecar) running on the ECS daemon
// can publish OTLP metrics to the agent's OTLP receiver and have them reach CloudWatch.
type ECSOtlpTestRunner struct {
test_runner.BaseTestRunner
}

var _ test_runner.ITestRunner = (*ECSOtlpTestRunner)(nil)

func (t *ECSOtlpTestRunner) GetTestName() string { return "ecs_otlp" }

// GetAgentConfigFileName returns "" — config is pre-loaded by Terraform via SSM, no restart needed.
func (t *ECSOtlpTestRunner) GetAgentConfigFileName() string { return "" }

func (t *ECSOtlpTestRunner) GetMeasuredMetrics() []string {
return []string{"otlp_test_counter", "otlp_test_gauge"}
}

func (t *ECSOtlpTestRunner) Validate() status.TestGroupResult {
env := environment.GetEnvironmentMetaData()
// Give the sidecar time to push and the agent to export before querying.
time.Sleep(3 * time.Minute)
// Isolate by the per-run testing_id, which the sidecar stamps as the TestId
// attribute and is embedded in the ECS cluster ARN.
labels := map[string]string{
"TestId": testIDFromClusterArn(env.EcsClusterArn),
}
return otlpvalidation.ValidateOtlpMetricsWithLabels(t.GetTestName(), env.Region, t.GetMeasuredMetrics(), labels)
}

// testIDFromClusterArn extracts the testing_id suffix from the ECS cluster ARN.
func testIDFromClusterArn(clusterArn string) string {
if i := strings.LastIndex(clusterArn, clusterNamePrefix); i != -1 {
return clusterArn[i+len(clusterNamePrefix):]
}
return clusterArn
}

func TestECSOtlpSuite(t *testing.T) {
suite.Run(t, new(ECSOtlpTestSuite))
}

type ECSOtlpTestSuite struct {
suite.Suite
test_runner.TestSuite
}

func (suite *ECSOtlpTestSuite) GetSuiteName() string {
return "ECSOtlp"
}

func (suite *ECSOtlpTestSuite) TestAllInSuite() {
env := environment.GetEnvironmentMetaData()
ecsTestRunner := &test_runner.ECSTestRunner{
Runner: &ECSOtlpTestRunner{},
RunStrategy: &test_runner.ECSAgentRunStrategy{},
Env: *env,
}
ecsTestRunner.Run(suite, env)
suite.Assert().Equal(status.SUCCESSFUL, suite.Result.GetStatus(), "ECS OTLP Test Suite Failed")
}
14 changes: 14 additions & 0 deletions test/otel_collect/ecs/otlp/resources/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"agent": {
"run_as_user": "root"
},
"opentelemetry": {
"cluster_name": "cwagent-ecs-integ-test",
"collect": {
"otlp": {
"grpc_endpoint": "0.0.0.0:4317",
"http_endpoint": "0.0.0.0:4318"
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"agent": {
"region": "us-west-2"
},
"opentelemetry": {
"cluster_name": "integ-test-cluster",
"collect": {
"host_metrics": {
"collection_interval": 30
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,8 @@ type HostMetricsTestRunner struct {
var _ test_runner.ITestRunner = (*HostMetricsTestRunner)(nil)

func (t *HostMetricsTestRunner) Validate() status.TestGroupResult {
return otlpvalidation.ValidateOtlpMetricsWithLabels(t.GetTestName(), t.env.Region, t.GetMeasuredMetrics(), map[string]string{
"@resource.host.id": t.env.InstanceId,
})
return otlpvalidation.ValidateOtlpMetricsWithLabels(t.GetTestName(), t.env.Region, t.GetMeasuredMetrics(),
otlpvalidation.ResourceHostIDLabels(t.env.AgentStartCommand, t.env.InstanceId))
}

func (t *HostMetricsTestRunner) GetTestName() string { return "HostMetrics" }
Expand Down
14 changes: 14 additions & 0 deletions test/otel_collect/linux/otlp/agent_configs/otlp_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"agent": {
"region": "us-west-2"
},
"opentelemetry": {
"cluster_name": "integ-test-cluster",
"collect": {
"otlp": {
"grpc_endpoint": "127.0.0.1:4317",
"http_endpoint": "127.0.0.1:4318"
}
}
}
}
Loading
Loading