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
22 changes: 14 additions & 8 deletions generator/test_case_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,10 @@ var testTypeToTestConfig = map[string][]testConfig{
testDir: "./test/otel_collect/database_insights",
excludedOs: map[string]struct{}{"ol8": {}, "ubuntu-25": {}},
},
{
testDir: "./test/otel_collect/database_insights_mysql",
excludedOs: map[string]struct{}{"ol8": {}, "ubuntu-25": {}},
},
{testDir: "./test/otel_collect/host_metrics"},
{testDir: "./test/otel_collect/otlp"},
{
Expand Down Expand Up @@ -553,10 +557,11 @@ 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/database_insights_mysql": {},
"./test/otel_collect/host_metrics": {},
"./test/otel_collect/otlp": {},
"./test/otel_collect/prometheus": {},
},
testConfigOverrides: map[string]testConfig{
"./test/metric_value_benchmark": {
Expand All @@ -574,10 +579,11 @@ 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/database_insights_mysql": {},
"./test/otel_collect/host_metrics": {},
"./test/otel_collect/otlp": {},
"./test/otel_collect/prometheus": {},
},
testConfigOverrides: map[string]testConfig{
"./test/metric_value_benchmark": {
Expand Down
5 changes: 4 additions & 1 deletion terraform/eks/daemon/efa/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 21.0"

name = "integ-${module.common.testing_id}"
name = "cwagent-eks-integ-${module.common.testing_id}"
kubernetes_version = var.k8s_version

# Full role name (<=64); the module's "<name>-cluster-" name_prefix would exceed the 38-char cap.
iam_role_use_name_prefix = false

vpc_id = aws_vpc.efa_test_vpc.id
subnet_ids = aws_subnet.efa_test_public_subnet[*].id

Expand Down
8 changes: 7 additions & 1 deletion terraform/eks/daemon/liscsi/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,13 @@ resource "null_resource" "validator" {
kubectl get svc -n kube-system -l app.kubernetes.io/name=ec2-instance-store-plugin 2>/dev/null || echo "No LIS CSI service found"
echo "=== Running go test ==="
cd ../../../..
go test ${var.test_dir} -timeout 1h -eksClusterName=${aws_eks_cluster.this.name} -computeType=EKS -v -eksDeploymentStrategy=DAEMON -instanceId=${data.aws_instance.eks_node_detail.instance_id}
i=0
while [ $i -lt 3 ]; do
i=$((i+1))
go test ${var.test_dir} -timeout 1h -eksClusterName=${aws_eks_cluster.this.name} -computeType=EKS -v -eksDeploymentStrategy=DAEMON -instanceId=${data.aws_instance.eks_node_detail.instance_id} && exit 0
sleep 60
done
exit 1
EOT
}
}
5 changes: 4 additions & 1 deletion terraform/eks/daemon/otel-multi-efa/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 21.0"

name = "cwagent-mefa-${module.common.testing_id}"
name = "cwagent-eks-integ-${module.common.testing_id}"
kubernetes_version = var.k8s_version

# Full role name (<=64); the module's "<name>-cluster-" name_prefix would exceed the 38-char cap.
iam_role_use_name_prefix = false

vpc_id = aws_vpc.efa_test_vpc.id
subnet_ids = aws_subnet.efa_test_public_subnet[*].id

Expand Down
5 changes: 2 additions & 3 deletions test/app_signals_service_events/metrics_routing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,8 @@ func TestAppSignalsMetricsRouting(t *testing.T) {

// OTLP validation: otlphttpexporter debug log shows request to monitoring endpoint
t.Run("service_events_sent_to_otlp_monitoring_endpoint", func(t *testing.T) {
assert.Contains(t, agentLogStr,
`"Preparing to make HTTP request","url":"https://monitoring.us-west-2.amazonaws.com/v1/metrics"`,
"otlphttpexporter should log HTTP request to monitoring endpoint for ServiceEvents metrics")
assert.Regexp(t, `"Preparing to make HTTP request".*"url":"https://monitoring\.us-west-2\.amazonaws\.com/v1/metrics"`, agentLogStr,
"otlphttpexporter should log an HTTP request to the monitoring endpoint for ServiceEvents metrics")
})

// OTLP validation: query the PromQL API to confirm the metric was actually ingested
Expand Down
4 changes: 1 addition & 3 deletions test/app_signals_service_events/service_events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,7 @@ func TestAppSignalsOnPremCredentialsStartup(t *testing.T) {

agentLog := common.ReadAgentLogfile(common.AgentLogFile)
assert.NotContains(t, agentLog, "could not retrieve credential provider",
"sigv4auth should not eagerly resolve credentials via IMDS when a credentials file is provided")
assert.NotContains(t, agentLog, "no EC2 IMDS role found",
"sigv4auth should use the provided credentials file instead of requiring IMDS")
"sigv4auth should resolve credentials from the file, not fail over to IMDS")

assertAgentStable(t,
"agent should start in onPrem mode with a credentials file even when IMDS is disabled")
Expand Down
118 changes: 118 additions & 0 deletions test/assume_role/assume_role_scan_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

//go:build !windows

package assume_role

import (
"strings"
"testing"

"github.com/stretchr/testify/assert"

"github.com/aws/amazon-cloudwatch-agent-test/environment"
)

const (
testAccountID = "111122223333"
testInstanceArn = "arn:aws:ec2:us-west-2:111122223333:instance/i-0abcdef1234567890"
)

// v2Log mirrors the aws-sdk-go-v2 / smithy RequestResponseLogger output, which emits
// "D! Request\n" followed by httputil.DumpRequestOut and has no trailing marker.
const v2Log = `2026/07/03 18:05:10 D! Request
POST / HTTP/1.1
Host: sts.us-west-2.amazonaws.com
User-Agent: aws-sdk-go-v2/1.41.5 os/linux lang/go
Content-Length: 199
Authorization: AWS4-HMAC-SHA256 Credential=AKIA/20260703/us-west-2/sts/aws4_request, SignedHeaders=content-length;content-type;host;x-amz-date;x-amz-security-token;x-amz-source-account;x-amz-source-arn, Signature=abc
Content-Type: application/x-www-form-urlencoded; charset=utf-8
X-Amz-Date: 20260703T180510Z
X-Amz-Security-Token: token
X-Amz-Source-Account: 111122223333
X-Amz-Source-Arn: arn:aws:ec2:us-west-2:111122223333:instance/i-0abcdef1234567890
Accept-Encoding: gzip

Action=AssumeRole&DurationSeconds=900&RoleArn=arn%3Aaws%3Aiam%3A%3A111122223333%3Arole%2Fcwa-integ-assume-role-all_context_keys&RoleSessionName=123&Version=2011-06-15
2026/07/03 18:05:10 D! Response
HTTP/1.1 200 OK
`

// v1Log mirrors the legacy aws-sdk-go v1 wire log with POST-SIGN start and dashed end markers.
const v1Log = `2026/07/03 18:05:10 I! ---[ REQUEST POST-SIGN ]-----------------------------
POST / HTTP/1.1
Host: sts.us-west-2.amazonaws.com
X-Amz-Source-Account: 111122223333
X-Amz-Source-Arn: arn:aws:ec2:us-west-2:111122223333:instance/i-0abcdef1234567890

Action=AssumeRole&Version=2011-06-15
-----------------------------------------------------
`

func TestScanForConfusedDeputyHeaders(t *testing.T) {
metadata = &environment.MetaData{
AccountId: testAccountID,
InstanceArn: testInstanceArn,
}

cases := []struct {
name string
log string
want bool
}{
{name: "sdk v2 format", log: v2Log, want: true},
{name: "sdk v1 format", log: v1Log, want: true},
{
name: "assume role request missing headers",
log: `2026/07/03 18:05:10 D! Request
POST / HTTP/1.1
Host: sts.us-west-2.amazonaws.com

Action=AssumeRole&Version=2011-06-15
`,
want: false,
},
{
name: "headers present but not an assume role request",
log: `2026/07/03 18:05:10 D! Request
POST / HTTP/1.1
Host: monitoring.us-west-2.amazonaws.com
X-Amz-Source-Account: 111122223333
X-Amz-Source-Arn: arn:aws:ec2:us-west-2:111122223333:instance/i-0abcdef1234567890

Action=PutMetricData&Version=2010-08-01
`,
want: false,
},
{
name: "wrong account and arn",
log: `2026/07/03 18:05:10 D! Request
POST / HTTP/1.1
X-Amz-Source-Account: 123456789012
X-Amz-Source-Arn: arn:aws:ec2:us-west-2:123456789012:instance/i-1234567890abcdef0

Action=AssumeRole&Version=2011-06-15
`,
want: false,
},
{name: "no debug logs", log: "2026/07/03 18:05:10 I! Agent started\n", want: false},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
assert.Equal(t, tc.want, scanForConfusedDeputyHeaders(strings.NewReader(tc.log)))
})
}
}

func TestBlockStartDetection(t *testing.T) {
assert.True(t, isRequestBlockStart("2026/07/03 18:05:10 D! Request"))
assert.True(t, isRequestBlockStart("... ---[ REQUEST POST-SIGN ]-----------------------------"))
assert.False(t, isRequestBlockStart("2026/07/03 18:05:10 D! Response"))
assert.False(t, isRequestBlockStart("Action=AssumeRole&Version=2011-06-15"))

assert.True(t, isHTTPDebugBlockStart("2026/07/03 18:05:10 D! Response"))
assert.True(t, isHTTPDebugBlockStart("2026/07/03 18:05:10 D! Request"))
assert.False(t, isHTTPDebugBlockStart("X-Amz-Source-Account: 111122223333"))
}
Loading
Loading