Skip to content
Merged
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
4 changes: 4 additions & 0 deletions generator/test_case_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@ var testTypeToTestConfig = map[string][]testConfig{
testDir: "./test/emf",
targets: map[string]map[string]struct{}{"metadataEnabled": {"enabled": {}}},
},
{
testDir: "./test/ecs/ecs_sd",
targets: map[string]map[string]struct{}{"metadataEnabled": {"enabled": {}}},
},
},
"eks_addon": {
{
Expand Down
8 changes: 7 additions & 1 deletion terraform/ecs_ec2/daemon/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,13 @@ resource "null_resource" "validator" {
command = <<-EOT
echo "Validating metrics/logs"
cd ../../..
go test ${var.test_dir} -timeout 0 -computeType=ECS -ecsLaunchType=EC2 -ecsDeploymentStrategy=DAEMON -cwagentConfigSsmParamName=${local.cwagent_config_ssm_param_name} -clusterArn=${aws_ecs_cluster.cluster.arn} -cwagentECSServiceName=${aws_ecs_service.cwagent_service.name} -v
go test ${var.test_dir} -timeout 0 \
-computeType=ECS \
-ecsLaunchType=EC2 \
-ecsDeploymentStrategy=DAEMON \
-cwagentConfigSsmParamName=${local.cwagent_config_ssm_param_name} \
-clusterArn=${aws_ecs_cluster.cluster.arn} \
-cwagentECSServiceName=${aws_ecs_service.cwagent_service.name} -v
EOT
}
depends_on = [aws_ecs_service.cwagent_service, aws_ecs_service.extra_apps_service, null_resource.disable_metadata]
Expand Down
7 changes: 6 additions & 1 deletion terraform/ecs_fargate/linux/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,12 @@ resource "null_resource" "validator" {
command = <<-EOT
echo "Validating metrics/logs"
cd ../../..
go test ${var.test_dir} -clusterName=${aws_ecs_cluster.cluster.name} -v
go test ${var.test_dir} \
-computeType=ECS \
-ecsLaunchType=FARGATE \
-ecsDeploymentStrategy=DAEMON \
-clusterArn=${aws_ecs_cluster.cluster.arn} \
-v
EOT
}
depends_on = [aws_ecs_service.cwagent_service, aws_ecs_service.extra_apps_service]
Expand Down
121 changes: 121 additions & 0 deletions test/ecs/ecs_sd/ecs_servicediscovery_runner.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

//go:build !windows

package ecs_sd

import (
_ "embed"
"fmt"
"log"
"strings"
"time"

"github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types"

"github.com/aws/amazon-cloudwatch-agent-test/environment"
"github.com/aws/amazon-cloudwatch-agent-test/test/status"
"github.com/aws/amazon-cloudwatch-agent-test/test/test_runner"
"github.com/aws/amazon-cloudwatch-agent-test/util/awsservice"
)

const (
MaxRetryCount = 15
// Log group format: https://github.com/aws/amazon-cloudwatch-agent/blob/5ef3dba446cb56a4c2306878592b5d14300ae82f/translator/translate/otel/exporter/awsemf/prometheus.go#L38
ECSLogGroupNameFormat = "/aws/ecs/containerinsights/%s/prometheus"
// Log stream based on job name in extra_apps.tpl:https://github.com/aws/amazon-cloudwatch-agent-test/blob/main/test/ecs/ecs_sd/resources/extra_apps.tpl#L41
LogStreamName = "prometheus-redis"
)

//go:embed resources/emf_prometheus_redis_schema.json
var schema string

type ECSServiceDiscoveryTestRunner struct {
test_runner.BaseTestRunner
}

func (t ECSServiceDiscoveryTestRunner) GetTestName() string {
return "ecs_servicediscovery"
}

func (t ECSServiceDiscoveryTestRunner) GetAgentConfigFileName() string {
return ""
}

func (t ECSServiceDiscoveryTestRunner) GetMeasuredMetrics() []string {
// dummy function to satisfy the interface
return []string{}
}

func (t ECSServiceDiscoveryTestRunner) Validate() status.TestGroupResult {
var testResults []status.TestResult
testResults = append(testResults, t.ValidateCloudWatchLogs())

return status.TestGroupResult{
Name: t.GetTestName(),
TestResults: testResults,
}
}

func (t ECSServiceDiscoveryTestRunner) ValidateCloudWatchLogs() status.TestResult {
env := environment.GetEnvironmentMetaData()
logGroupName := fmt.Sprintf(ECSLogGroupNameFormat, env.EcsClusterName)

testResult := status.TestResult{
Name: fmt.Sprintf("Retrieve Test LogGroup: %s", logGroupName),
Status: status.FAILED,
}

logGroupFound, err := t.ValidateLogGroupFormat(logGroupName)

if logGroupFound {
if err != nil {
log.Printf("ECS ServiceDiscovery Test LogGroups invalid\n")
testResult.Name = err.Error()
testResult.Status = status.FAILED
} else {
testResult.Status = status.SUCCESSFUL
}
awsservice.DeleteLogGroupAndStream(logGroupName, LogStreamName)
}
return testResult
}

func (t ECSServiceDiscoveryTestRunner) ValidateLogGroupFormat(logGroupName string) (bool, error) {
start := time.Now()

for retries := 0; retries < MaxRetryCount; retries++ {
if awsservice.IsLogGroupExists(logGroupName) {
end := time.Now()
return true, t.ValidateLogsContent(logGroupName, start, end)
}

log.Printf("Retry %d/%d: Log group not found. Waiting 20 seconds...\n", retries+1, MaxRetryCount)
time.Sleep(20 * time.Second)
}

log.Printf("ECS ServiceDiscovery Test has exhausted %v retry times", MaxRetryCount)
return false, fmt.Errorf("Test Retries Exhausted: %d", MaxRetryCount)
}

func (t ECSServiceDiscoveryTestRunner) ValidateLogsContent(logGroupName string, start time.Time, end time.Time) error {
return awsservice.ValidateLogs(
logGroupName,
LogStreamName,
&start,
&end,
awsservice.AssertLogsNotEmpty(),
awsservice.AssertPerLog(
awsservice.AssertLogSchema(awsservice.WithSchema(schema)),
func(event types.OutputLogEvent) error {
if strings.Contains(*event.Message, "CloudWatchMetrics") &&
!strings.Contains(*event.Message, "\"Namespace\":\"ECS/ContainerInsights/Prometheus\"") {
return fmt.Errorf("emf log found for non ECS/ContainerInsights/Prometheus namespace: %s", *event.Message)
}
return nil
},
awsservice.AssertLogContainsSubstring("\"job\":\"prometheus-redis\""),
),
)
}
102 changes: 38 additions & 64 deletions test/ecs/ecs_sd/ecs_servicediscovery_test.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: MIT

//go:build !windows

package ecs_sd

import (
_ "embed"
"flag"
"fmt"
"log"
"strings"
"testing"
"time"

"github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"

"github.com/aws/amazon-cloudwatch-agent-test/util/awsservice"
"github.com/aws/amazon-cloudwatch-agent-test/environment"
"github.com/aws/amazon-cloudwatch-agent-test/test/status"
"github.com/aws/amazon-cloudwatch-agent-test/test/test_runner"
)

/*
Expand All @@ -29,70 +26,47 @@ Implementation:
2) Check if expected Prometheus EMF data is correctly published as logs and metrics to CloudWatch
*/

const (
RetryTime = 15
// Log group format: https://github.com/aws/amazon-cloudwatch-agent/blob/5ef3dba446cb56a4c2306878592b5d14300ae82f/translator/translate/otel/exporter/awsemf/prometheus.go#L38
ECSLogGroupNameFormat = "/aws/ecs/containerinsights/%s/prometheus"
// Log stream based on job name in extra_apps.tpl:https://github.com/aws/amazon-cloudwatch-agent-test/blob/main/test/ecs/ecs_sd/resources/extra_apps.tpl#L41
LogStreamName = "prometheus-redis"
var (
ecsTestRunners []*test_runner.ECSTestRunner
)

var clusterName = flag.String("clusterName", "", "Please provide the os preference, valid value: windows/linux.")

//go:embed resources/emf_prometheus_redis_schema.json
var schema string

func TestValidatingCloudWatchLogs(t *testing.T) {

logGroupName, logGroupFound, start, end := ValidateLogGroupFormat(t)
func getEcsTestRunners(env *environment.MetaData) []*test_runner.ECSTestRunner {
if len(ecsTestRunners) == 0 {

ValidateLogsContent(t, logGroupName, start, end)

if logGroupFound {
awsservice.DeleteLogGroupAndStream(logGroupName, LogStreamName)
ecsTestRunners = []*test_runner.ECSTestRunner{
{
Runner: &ECSServiceDiscoveryTestRunner{},
RunStrategy: &test_runner.ECSAgentRunStrategy{},
Env: *env,
},
}
}
return ecsTestRunners
}

func ValidateLogGroupFormat(t *testing.T) (string, bool, time.Time, time.Time) {
start := time.Now()
logGroupName := fmt.Sprintf(ECSLogGroupNameFormat, *clusterName)
var _ test_runner.ITestRunner = (*ECSServiceDiscoveryTestRunner)(nil)

func init() {
environment.RegisterEnvironmentMetaDataFlags()
}

var logGroupFound bool
for currentRetry := 1; ; currentRetry++ {
func TestECSServiceDiscoveryTestSuite(t *testing.T) {
suite.Run(t, new(ECSServiceDiscoveryTestSuite))
}

if currentRetry == RetryTime {
t.Fatalf("Test has exhausted %v retry time", RetryTime)
}
type ECSServiceDiscoveryTestSuite struct {
suite.Suite
test_runner.TestSuite
}

if !awsservice.IsLogGroupExists(logGroupName) {
log.Printf("Current retry: %v/%v and begin to sleep for 20s \n", currentRetry, RetryTime)
time.Sleep(20 * time.Second)
continue
}
break
}
end := time.Now()
return logGroupName, logGroupFound, start, end
func (suite *ECSServiceDiscoveryTestSuite) GetSuiteName() string {
return "ECSServiceDiscovery"
}

func ValidateLogsContent(t *testing.T, logGroupName string, start time.Time, end time.Time) {
err := awsservice.ValidateLogs(
logGroupName,
LogStreamName,
&start,
&end,
awsservice.AssertLogsNotEmpty(),
awsservice.AssertPerLog(
awsservice.AssertLogSchema(awsservice.WithSchema(schema)),
func(event types.OutputLogEvent) error {
if strings.Contains(*event.Message, "CloudWatchMetrics") &&
!strings.Contains(*event.Message, "\"Namespace\":\"ECS/ContainerInsights/Prometheus\"") {
return fmt.Errorf("emf log found for non ECS/ContainerInsights/Prometheus namespace: %s", *event.Message)
}
return nil
},
awsservice.AssertLogContainsSubstring("\"job\":\"prometheus-redis\""),
),
)
assert.NoError(t, err)
func (suite *ECSServiceDiscoveryTestSuite) TestAllInSuite() {
env := environment.GetEnvironmentMetaData()
for _, ecsTestRunner := range getEcsTestRunners(env) {
ecsTestRunner.Run(suite, env)
}
suite.Assert().Equal(status.SUCCESSFUL, suite.Result.GetStatus(), "ECS ServiceDiscovery Test Suite Failed")
}
9 changes: 2 additions & 7 deletions test/statsd/statsd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,8 @@ type StatsDTestSuite struct {
test_runner.TestSuite
}

Comment thread
Paramadon marked this conversation as resolved.
func (suite *StatsDTestSuite) SetupSuite() {
fmt.Println(">>>> Starting StatsDTestSuite")
}

func (suite *StatsDTestSuite) TearDownSuite() {
Comment thread
Paramadon marked this conversation as resolved.
suite.Result.Print()
fmt.Println(">>>> Finished StatsDTestSuite")
func (suite *StatsDTestSuite) GetSuiteName() string {
return "StatsDTestSuite"
}

func init() {
Expand Down
2 changes: 1 addition & 1 deletion test/test_runner/ecs_test_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func (t *ECSTestRunner) Run(s ITestSuite, e *environment.MetaData) {
if len(agentConfigFileName) != 0 {
err := t.RunStrategy.RunAgentStrategy(e, t.Runner.GetAgentConfigFileName())
if err != nil {
log.Printf("Failed to run agent with config for the given testm err:%v", err)
log.Printf("Failed to run agent with config for the given test err:%v", err)
s.AddToSuiteResult(status.TestGroupResult{
Name: t.Runner.GetTestName(),
TestResults: []status.TestResult{
Expand Down