diff --git a/test/cloudwatchlogs/publish_logs_test.go b/test/cloudwatchlogs/publish_logs_test.go index 7cc7fcef5..c931380da 100644 --- a/test/cloudwatchlogs/publish_logs_test.go +++ b/test/cloudwatchlogs/publish_logs_test.go @@ -13,6 +13,7 @@ import ( "testing" "time" + "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types" "github.com/stretchr/testify/assert" "github.com/aws/amazon-cloudwatch-agent-test/environment" @@ -99,11 +100,15 @@ func TestWriteLogsToCloudWatch(t *testing.T) { end := time.Now() // check CWL to ensure we got the expected number of logs in the log stream - ok, err := awsservice.ValidateLogs(instanceId, instanceId, &start, &end, func(logs []string) bool { - return param.numExpectedLogs == len(logs) - }) + err = awsservice.ValidateLogs( + instanceId, + instanceId, + &start, + &end, + awsservice.AssertLogsCount(param.numExpectedLogs), + awsservice.AssertNoDuplicateLogs(), + ) assert.NoError(t, err) - assert.True(t, ok) }) } } @@ -151,23 +156,24 @@ func TestRotatingLogsDoesNotSkipLines(t *testing.T) { end := time.Now() - ok, err := awsservice.ValidateLogs(logGroup, logStream, &start, &end, func(logs []string) bool { - if len(logs) != len(lines) { - return false - } - - for i := 0; i < len(logs); i++ { - expected := strings.ReplaceAll(lines[i], "'", "\"") - actual := strings.ReplaceAll(logs[i], "'", "\"") - if expected != actual { - return false + err := awsservice.ValidateLogs( + logGroup, + logStream, + &start, + &end, + awsservice.AssertLogsCount(len(lines)), + func(events []types.OutputLogEvent) error { + for i := 0; i < len(events); i++ { + expected := strings.ReplaceAll(lines[i], "'", "\"") + actual := strings.ReplaceAll(*events[i].Message, "'", "\"") + if expected != actual { + return fmt.Errorf("actual log event %q does not match the expected %q", actual, expected) + } } - } - - return true - }) + return nil + }, + ) assert.NoError(t, err) - assert.True(t, ok) } func writeLogs(t *testing.T, f *os.File, iterations int) { diff --git a/test/ecs/ecs_metadata/ecs_metadata_test.go b/test/ecs/ecs_metadata/ecs_metadata_test.go index 49f1c19cd..738e9020a 100644 --- a/test/ecs/ecs_metadata/ecs_metadata_test.go +++ b/test/ecs/ecs_metadata/ecs_metadata_test.go @@ -7,12 +7,12 @@ import ( _ "embed" "flag" "fmt" + "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types" "log" "strings" "testing" "time" - "github.com/qri-io/jsonschema" "github.com/stretchr/testify/assert" "github.com/aws/amazon-cloudwatch-agent-test/util/awsservice" @@ -36,8 +36,6 @@ var clusterName = flag.String("clusterName", "", "Please provide the os preferen var schema string func TestValidatingCloudWatchLogs(t *testing.T) { - rs := jsonschema.Must(schema) - start := time.Now() logGroupName := fmt.Sprintf(ECSLogGroupNameFormat, *clusterName) @@ -57,25 +55,25 @@ func TestValidatingCloudWatchLogs(t *testing.T) { end := time.Now() - ok, err := awsservice.ValidateLogs(logGroupName, LogStreamName, &start, &end, func(logs []string) bool { - if len(logs) < 1 { - return false - } - for _, l := range logs { - if !awsservice.MatchEMFLogWithSchema(l, rs, func(s string) bool { - ok := true - if strings.Contains(l, "CloudWatchMetrics") { - ok = ok && strings.Contains(l, "\"Namespace\":\"ECS/ContainerInsights/Prometheus\"") + 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 ok && strings.Contains(l, "\"job\":\"prometheus-redis\"") - }) { - return false - } - } - return true - }) + return nil + }, + awsservice.AssertLogContainsSubstring("\"job\":\"prometheus-redis\""), + ), + ) assert.NoError(t, err) - assert.True(t, ok) break } diff --git a/test/fluent/fluent_test.go b/test/fluent/fluent_test.go index 2acceb5cb..ab42d2c13 100644 --- a/test/fluent/fluent_test.go +++ b/test/fluent/fluent_test.go @@ -11,6 +11,8 @@ import ( "testing" "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/util/awsservice" ) @@ -43,41 +45,47 @@ func TestFluentLogs(t *testing.T) { now := time.Now() for group, fieldsArr := range logGroupToKey { - group := fmt.Sprintf("/aws/containerinsights/%s/%s", env.EKSClusterName, group) + group = fmt.Sprintf("/aws/containerinsights/%s/%s", env.EKSClusterName, group) if !awsservice.IsLogGroupExists(group) { t.Fatalf("fluent log group doesn't exsit: %s", group) } streams := awsservice.GetLogStreams(group) - if len(streams) < 1 { + if len(streams) == 0 { t.Fatalf("fluent log streams are empty for log group: %s", group) } - ok, err := awsservice.ValidateLogs(group, *(streams[0].LogStreamName), nil, &now, func(logs []string) bool { - if len(logs) < 1 { - return false - } - - // only 1 log message gets validate - // log message must include expected fields, and there could be more than 1 set of expected fields per log group - var found = false - for _, fields := range fieldsArr { - match := 0 - for _, field := range fields { - if strings.Contains(logs[0], "\""+field+"\"") { - match += 1 + err := awsservice.ValidateLogs( + group, + *(streams[0].LogStreamName), + nil, + &now, + awsservice.AssertLogsNotEmpty(), + func(events []types.OutputLogEvent) error { + // only 1 log message gets validated + // log message must include expected fields, and there could be more than 1 set of expected fields per log group + var found bool + for _, fields := range fieldsArr { + var match int + for _, field := range fields { + if strings.Contains(*events[0].Message, "\""+field+"\"") { + match += 1 + } + } + if match == len(fields) { + found = true + break } } - if match == len(fields) { - found = true - break + if !found { + return fmt.Errorf("fluent log entry doesn't include expected message fields: %s", *events[0].Message) } - } - return found - }) + return nil + }, + ) - if err != nil || !ok { - t.Fatalf("fluent log entry doesn't include expected message fields for logGroup: %s", group) + if err != nil { + t.Fatalf("failed validation for log group %s: %v", group, err) } } diff --git a/test/metric_value_benchmark/container_insights_test.go b/test/metric_value_benchmark/container_insights_test.go index b7b9f6942..61a04921b 100644 --- a/test/metric_value_benchmark/container_insights_test.go +++ b/test/metric_value_benchmark/container_insights_test.go @@ -8,11 +8,9 @@ package metric_value_benchmark import ( _ "embed" "fmt" - "strings" + "log" "time" - "github.com/qri-io/jsonschema" - "github.com/aws/amazon-cloudwatch-agent-test/environment" "github.com/aws/amazon-cloudwatch-agent-test/test/metric" "github.com/aws/amazon-cloudwatch-agent-test/test/metric/dimension" @@ -113,8 +111,6 @@ func validateLogsForContainerInsights(e *environment.MetaData) status.TestResult Status: status.FAILED, } - rs := jsonschema.Must(emfContainerInsightsSchema) - now := time.Now() group := fmt.Sprintf("/aws/ecs/containerinsights/%s/performance", e.EcsClusterName) @@ -125,26 +121,21 @@ func validateLogsForContainerInsights(e *environment.MetaData) status.TestResult } for _, container := range containers { - validateLogContents := func(s string) bool { - return strings.Contains(s, fmt.Sprintf("\"ContainerInstanceId\":\"%s\"", container.ContainerInstanceId)) - } - - var ok bool stream := fmt.Sprintf("NodeTelemetry-%s", container.ContainerInstanceId) - ok, err = awsservice.ValidateLogs(group, stream, nil, &now, func(logs []string) bool { - if len(logs) < 1 { - return false - } - - for _, l := range logs { - if !awsservice.MatchEMFLogWithSchema(l, rs, validateLogContents) { - return false - } - } - return true - }) - - if err != nil || !ok { + err = awsservice.ValidateLogs( + group, + stream, + nil, + &now, + awsservice.AssertLogsNotEmpty(), + awsservice.AssertPerLog( + awsservice.AssertLogSchema(awsservice.WithSchema(emfContainerInsightsSchema)), + awsservice.AssertLogContainsSubstring(fmt.Sprintf("\"ContainerInstanceId\":\"%s\"", container.ContainerInstanceId)), + ), + ) + + if err != nil { + log.Printf("log validation (%s/%s) for container (%s) failed: %v", group, stream, container.ContainerInstanceId, err) return testResult } } diff --git a/test/metric_value_benchmark/eks_daemonset_test.go b/test/metric_value_benchmark/eks_daemonset_test.go index 75544166d..35e4298a7 100644 --- a/test/metric_value_benchmark/eks_daemonset_test.go +++ b/test/metric_value_benchmark/eks_daemonset_test.go @@ -7,13 +7,12 @@ package metric_value_benchmark import ( "encoding/json" + "errors" "fmt" "log" - "strings" "time" "github.com/aws/aws-sdk-go-v2/service/cloudwatch/types" - "github.com/qri-io/jsonschema" "golang.org/x/exp/slices" "github.com/aws/amazon-cloudwatch-agent-test/environment" @@ -127,43 +126,34 @@ func (e *EKSDaemonTestRunner) validateLogs(env *environment.MetaData) status.Tes } for _, instance := range eKSInstances { - validateLogContents := func(s string) bool { - return strings.Contains(s, fmt.Sprintf("\"ClusterName\":\"%s\"", env.EKSClusterName)) - } - - var ok bool stream := *instance.InstanceName - ok, err = awsservice.ValidateLogs(group, stream, nil, &now, func(logs []string) bool { - if len(logs) < 1 { - log.Println(fmt.Sprintf("failed to get logs for instance: %s", stream)) - return false - } + err = awsservice.ValidateLogs( + group, + stream, + nil, + &now, + awsservice.AssertLogsNotEmpty(), + awsservice.AssertPerLog( + awsservice.AssertLogSchema(func(message string) (string, error) { + var eksClusterType awsservice.EKSClusterType + innerErr := json.Unmarshal([]byte(message), &eksClusterType) + if innerErr != nil { + return "", fmt.Errorf("failed to unmarshal log file: %w", innerErr) + } + + log.Printf("eksClusterType is: %s", eksClusterType.Type) + jsonSchema, ok := eks_resources.EksClusterValidationMap[eksClusterType.Type] + if !ok { + return "", errors.New("invalid cluster type provided") + } + return jsonSchema, nil + }), + awsservice.AssertLogContainsSubstring(fmt.Sprintf("\"ClusterName\":\"%s\"", env.EKSClusterName)), + ), + ) - for _, l := range logs { - var eksClusterType awsservice.EKSClusterType - err := json.Unmarshal([]byte(l), &eksClusterType) - if err != nil { - log.Println("failed to unmarshal log file") - } - - log.Println(fmt.Sprintf("eksClusterType is: %s", eksClusterType.Type)) - jsonSchema, ok := eks_resources.EksClusterValidationMap[eksClusterType.Type] - if !ok { - log.Println("invalid cluster type provided") - return false - } - rs := jsonschema.Must(jsonSchema) - - if !awsservice.MatchEMFLogWithSchema(l, rs, validateLogContents) { - log.Println("failed to match log with schema") - log.Printf("log entry %s json schema %s", l, jsonSchema) - return false - } - } - return true - }) - - if err != nil || !ok { + if err != nil { + log.Printf("log validation (%s/%s) failed: %v", group, stream, err) return testResult } } diff --git a/test/metric_value_benchmark/emf_test.go b/test/metric_value_benchmark/emf_test.go index 32e32efed..a69a785c0 100644 --- a/test/metric_value_benchmark/emf_test.go +++ b/test/metric_value_benchmark/emf_test.go @@ -7,18 +7,16 @@ package metric_value_benchmark import ( _ "embed" - "strings" + "log" "time" - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/qri-io/jsonschema" - "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" "github.com/aws/amazon-cloudwatch-agent-test/util/awsservice" "github.com/aws/amazon-cloudwatch-agent-test/util/common" + "github.com/aws/aws-sdk-go-v2/aws" ) type EMFTestRunner struct { @@ -116,27 +114,20 @@ func validateEMFLogs(group, stream string) status.TestResult { Status: status.FAILED, } - rs := jsonschema.Must(emfMetricValueBenchmarkSchema) - - validateLogContents := func(s string) bool { - return strings.Contains(s, "\"EMFCounter\":5") - } - now := time.Now() - ok, err := awsservice.ValidateLogs(group, stream, nil, &now, func(logs []string) bool { - if len(logs) < 1 { - return false - } - - for _, l := range logs { - if !awsservice.MatchEMFLogWithSchema(l, rs, validateLogContents) { - return false - } - } - return true - }) - - if err != nil || !ok { + err := awsservice.ValidateLogs( + group, + stream, + nil, + &now, + awsservice.AssertLogsNotEmpty(), + awsservice.AssertPerLog( + awsservice.AssertLogSchema(awsservice.WithSchema(emfMetricValueBenchmarkSchema)), + awsservice.AssertLogContainsSubstring("\"EMFCounter\":5"), + ), + ) + if err != nil { + log.Printf("log validation (%s/%s) failed: %v", group, stream, err) return testResult } diff --git a/util/awsservice/cloudwatchlogs.go b/util/awsservice/cloudwatchlogs.go index 18523d842..076025a3e 100644 --- a/util/awsservice/cloudwatchlogs.go +++ b/util/awsservice/cloudwatchlogs.go @@ -6,7 +6,9 @@ package awsservice import ( "context" "errors" + "fmt" "log" + "strings" "time" "github.com/aws/aws-sdk-go-v2/aws" @@ -51,21 +53,26 @@ func DeleteLogGroup(logGroupName string) { // ValidateLogs queries a given LogGroup/LogStream combination given the start and end times, and executes an // arbitrary validator function on the found logs. -func ValidateLogs(logGroup, logStream string, since, until *time.Time, validator func(logs []string) bool) (bool, error) { - log.Printf("Checking %s/%s\n", logGroup, logStream) +func ValidateLogs(logGroup, logStream string, since, until *time.Time, validators ...LogEventsValidator) error { + log.Printf("Checking %s/%s", logGroup, logStream) - foundLogs, err := getLogsSince(logGroup, logStream, since, until) + events, err := getLogsSince(logGroup, logStream, since, until) if err != nil { - return false, err + return err } - return validator(foundLogs), nil + for _, validator := range validators { + if err = validator(events); err != nil { + return err + } + } + return nil } // getLogsSince makes GetLogEvents API calls, paginates through the results for the given time frame, and returns // the raw log strings -func getLogsSince(logGroup, logStream string, since, until *time.Time) ([]string, error) { - foundLogs := make([]string, 0) +func getLogsSince(logGroup, logStream string, since, until *time.Time) ([]types.OutputLogEvent, error) { + var events []types.OutputLogEvent // https://docs.aws.amazon.com/AmazonCloudWatchLogs/latest/APIReference/API_GetLogEvents.html // GetLogEvents can return an empty result while still having more log events on a subsequent page, @@ -103,22 +110,22 @@ func getLogsSince(logGroup, logStream string, since, until *time.Time) ([]string } // if the error is not a ResourceNotFoundException, we should fail here. - return foundLogs, err + return events, err } for _, e := range output.Events { - foundLogs = append(foundLogs, *e.Message) + events = append(events, e) } if nextToken != nil && output.NextForwardToken != nil && *output.NextForwardToken == *nextToken { // From the docs: If you have reached the end of the stream, it returns the same token you passed in. - log.Printf("Done paginating log events for %s/%s and found %d logs", logGroup, logStream, len(foundLogs)) + log.Printf("Done paginating log events for %s/%s and found %d logs", logGroup, logStream, len(events)) break } nextToken = output.NextForwardToken } - return foundLogs, nil + return events, nil } // IsLogGroupExists confirms whether the logGroupName exists or not @@ -161,15 +168,96 @@ func GetLogStreams(logGroupName string) []types.LogStream { return []types.LogStream{} } -func MatchEMFLogWithSchema(logEntry string, s *jsonschema.Schema, logValidator func(string) bool) bool { - keyErrors, e := s.ValidateBytes(context.Background(), []byte(logEntry)) - if e != nil { - log.Println("failed to execute schema validator:", e) - return false - } else if len(keyErrors) > 0 { - log.Printf("failed schema validation: %v\n", keyErrors) - return false +type LogEventValidator func(event types.OutputLogEvent) error + +type LogEventsValidator func(events []types.OutputLogEvent) error + +type SchemaRetriever func(message string) (string, error) + +func WithSchema(schema string) SchemaRetriever { + return func(_ string) (string, error) { + return schema, nil } +} - return logValidator(logEntry) +func AssertLogSchema(schemaRetriever SchemaRetriever) LogEventValidator { + return func(event types.OutputLogEvent) error { + message := *event.Message + if schemaRetriever == nil { + return errors.New("nil schema retriever") + } + schema, err := schemaRetriever(*event.Message) + if err != nil { + return fmt.Errorf("unable to retrieve schema: %w", err) + } + keyErrors, err := jsonschema.Must(schema).ValidateBytes(context.Background(), []byte(message)) + if err != nil { + return fmt.Errorf("failed to execute schema validator: %w", err) + } else if len(keyErrors) > 0 { + return fmt.Errorf("failed schema validation: %v | schema: %s | log: %s", keyErrors, schema, message) + } + return nil + } +} + +func AssertLogContainsSubstring(substr string) LogEventValidator { + return func(event types.OutputLogEvent) error { + if !strings.Contains(*event.Message, substr) { + return fmt.Errorf("log event message missing substring (%s): %s", substr, *event.Message) + } + return nil + } +} + +// AssertPerLog runs each validator on each of the log events. Fails fast. +func AssertPerLog(validators ...LogEventValidator) LogEventsValidator { + return func(events []types.OutputLogEvent) error { + for _, event := range events { + for _, validator := range validators { + if err := validator(event); err != nil { + return err + } + } + } + return nil + } +} + +func AssertLogsNotEmpty() LogEventsValidator { + return func(events []types.OutputLogEvent) error { + if len(events) == 0 { + return errors.New("no log events") + } + return nil + } +} + +func AssertLogsCount(count int) LogEventsValidator { + return func(events []types.OutputLogEvent) error { + if len(events) != count { + return fmt.Errorf("actual log events count (%v) does not match expected (%v)", len(events), count) + } + return nil + } +} + +func AssertNoDuplicateLogs() LogEventsValidator { + return func(events []types.OutputLogEvent) error { + byTimestamp := make(map[int64]map[string]struct{}) + for _, event := range events { + message := *event.Message + timestamp := *event.Timestamp + messages, ok := byTimestamp[timestamp] + if !ok { + messages = map[string]struct{}{} + byTimestamp[timestamp] = messages + } + _, ok = messages[message] + if !ok { + return fmt.Errorf("duplicate message found at %v | message: %s", time.UnixMilli(timestamp), message) + } + messages[message] = struct{}{} + } + return nil + } } diff --git a/validator/validators/basic/basic_validator.go b/validator/validators/basic/basic_validator.go index f50c7479e..a99096504 100644 --- a/validator/validators/basic/basic_validator.go +++ b/validator/validators/basic/basic_validator.go @@ -9,7 +9,8 @@ import ( "strings" "time" - "github.com/aws/aws-sdk-go-v2/service/cloudwatch/types" + cwtypes "github.com/aws/aws-sdk-go-v2/service/cloudwatch/types" + cwltypes "github.com/aws/aws-sdk-go-v2/service/cloudwatchlogs/types" "github.com/aws/aws-sdk-go/aws" "go.uber.org/multierr" @@ -60,18 +61,18 @@ func (s *BasicValidator) CheckData(startTime, endTime time.Time) error { ec2InstanceId = awsservice.GetInstanceId() metricNamespace = s.vConfig.GetMetricNamespace() validationMetric = s.vConfig.GetMetricValidation() - validationLog = s.vConfig.GetLogValidation() + logValidations = s.vConfig.GetLogValidation() ) for _, metric := range validationMetric { - metricDimensions := []types.Dimension{ + metricDimensions := []cwtypes.Dimension{ { Name: aws.String("InstanceId"), Value: aws.String(ec2InstanceId), }, } for _, dimension := range metric.MetricDimension { - metricDimensions = append(metricDimensions, types.Dimension{ + metricDimensions = append(metricDimensions, cwtypes.Dimension{ Name: aws.String(dimension.Name), Value: aws.String(dimension.Value), }) @@ -82,8 +83,8 @@ func (s *BasicValidator) CheckData(startTime, endTime time.Time) error { } } - for _, log := range validationLog { - err := s.ValidateLogs(log.LogStream, log.LogValue, log.LogLevel, log.LogSource, log.LogLines, startTime, endTime) + for _, logValidation := range logValidations { + err := s.ValidateLogs(logValidation.LogStream, logValidation.LogValue, logValidation.LogLevel, logValidation.LogSource, logValidation.LogLines, startTime, endTime) if err != nil { multiErr = multierr.Append(multiErr, err) } @@ -105,40 +106,40 @@ func (s *BasicValidator) Cleanup() error { return nil } -func (s *BasicValidator) ValidateLogs(logStream, logLine, logLevel, logSource string, numberOfLogLine int, startTime, endTime time.Time) error { - var ( - logGroup = awsservice.GetInstanceId() - ) - log.Printf("Start to validate log '%s' with number of logs lines %d within log group %s, log stream %s, start time %v and end time %v", logLine, numberOfLogLine, logGroup, logStream, startTime, endTime) - ok, err := awsservice.ValidateLogs(logGroup, logStream, &startTime, &endTime, func(logs []string) bool { - if len(logs) < 1 { - return false - } - actualNumberOfLogLines := 0 - for _, l := range logs { - switch logSource { - case "WindowsEvents": - if logLevel != "" && strings.Contains(l, logLine) && strings.Contains(l, logLevel) { - actualNumberOfLogLines += 1 - } - default: - if strings.Contains(l, logLine) { - actualNumberOfLogLines += 1 +func (s *BasicValidator) ValidateLogs(logStream, logLine, logLevel, logSource string, expectedMinimumEventCount int, startTime, endTime time.Time) error { + logGroup := awsservice.GetInstanceId() + log.Printf("Start to validate that substring '%s' has at least %d log event(s) within log group %s, log stream %s, between %v and %v", logLine, expectedMinimumEventCount, logGroup, logStream, startTime, endTime) + return awsservice.ValidateLogs( + logGroup, + logStream, + &startTime, + &endTime, + awsservice.AssertLogsNotEmpty(), + awsservice.AssertNoDuplicateLogs(), + func(events []cwltypes.OutputLogEvent) error { + var actualEventCount int + for _, event := range events { + message := *event.Message + switch logSource { + case "WindowsEvents": + if logLevel != "" && strings.Contains(message, logLine) && strings.Contains(message, logLevel) { + actualEventCount += 1 + } + default: + if strings.Contains(message, logLine) { + actualEventCount += 1 + } } } - } - - return numberOfLogLine <= actualNumberOfLogLines - }) - - if !ok || err != nil { - return fmt.Errorf("\n the number of log line for '%s' is %d which does not match the actual number with log group %s, log stream %s, start time %v and end time %v with err %v", logLine, numberOfLogLine, logGroup, logStream, startTime, endTime, err) - } - - return nil + if actualEventCount < expectedMinimumEventCount { + return fmt.Errorf("log event count for %q in %s/%s between %v and %v is %d which is less than the expected %d", logLine, logGroup, logStream, startTime, endTime, actualEventCount, expectedMinimumEventCount) + } + return nil + }, + ) } -func (s *BasicValidator) ValidateMetric(metricName, metricNamespace string, metricDimensions []types.Dimension, metricValue float64, metricSampleCount int, startTime, endTime time.Time) error { +func (s *BasicValidator) ValidateMetric(metricName, metricNamespace string, metricDimensions []cwtypes.Dimension, metricValue float64, metricSampleCount int, startTime, endTime time.Time) error { var ( boundAndPeriod = s.vConfig.GetAgentCollectionPeriod().Seconds() ) @@ -174,18 +175,18 @@ func (s *BasicValidator) ValidateMetric(metricName, metricNamespace string, metr return nil } -func (s *BasicValidator) buildMetricQueries(metricName, metricNamespace string, metricDimensions []types.Dimension) []types.MetricDataQuery { +func (s *BasicValidator) buildMetricQueries(metricName, metricNamespace string, metricDimensions []cwtypes.Dimension) []cwtypes.MetricDataQuery { var metricQueryPeriod = int32(s.vConfig.GetAgentCollectionPeriod().Seconds()) - metricInformation := types.Metric{ + metricInformation := cwtypes.Metric{ Namespace: aws.String(metricNamespace), MetricName: aws.String(metricName), Dimensions: metricDimensions, } - metricDataQueries := []types.MetricDataQuery{ + metricDataQueries := []cwtypes.MetricDataQuery{ { - MetricStat: &types.MetricStat{ + MetricStat: &cwtypes.MetricStat{ Metric: &metricInformation, Period: &metricQueryPeriod, Stat: aws.String(string(models.AVERAGE)),