-
Notifications
You must be signed in to change notification settings - Fork 100
Expand file tree
/
Copy pathMetricsE2ET.java
More file actions
129 lines (111 loc) · 6.01 KB
/
MetricsE2ET.java
File metadata and controls
129 lines (111 loc) · 6.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* Copyright 2023 Amazon.com, Inc. or its affiliates.
* Licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package software.amazon.lambda.powertools;
import static org.assertj.core.api.Assertions.assertThat;
import static software.amazon.lambda.powertools.testutils.Infrastructure.FUNCTION_NAME_OUTPUT;
import static software.amazon.lambda.powertools.testutils.lambda.LambdaInvoker.invokeFunction;
import java.time.Clock;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Timeout;
import software.amazon.lambda.powertools.testutils.DataNotReadyException;
import software.amazon.lambda.powertools.testutils.Infrastructure;
import software.amazon.lambda.powertools.testutils.RetryUtils;
import software.amazon.lambda.powertools.testutils.lambda.InvocationResult;
import software.amazon.lambda.powertools.testutils.metrics.MetricsFetcher;
class MetricsE2ET {
private static final String NAMESPACE = "MetricsE2ENamespace_" + UUID.randomUUID();
private static final String SERVICE = "MetricsE2EService_" + UUID.randomUUID();
private static Infrastructure infrastructure;
private static String functionName;
@BeforeAll
@Timeout(value = 10, unit = TimeUnit.MINUTES)
static void setup() {
infrastructure = Infrastructure.builder()
.testName(MetricsE2ET.class.getSimpleName())
.pathToFunction("metrics")
.environmentVariables(
Stream.of(new String[][] {
{ "POWERTOOLS_METRICS_NAMESPACE", NAMESPACE },
{ "POWERTOOLS_SERVICE_NAME", SERVICE }
})
.collect(Collectors.toMap(data -> data[0], data -> data[1])))
.build();
Map<String, String> outputs = infrastructure.deploy();
functionName = outputs.get(FUNCTION_NAME_OUTPUT);
}
@AfterAll
static void tearDown() {
if (infrastructure != null) {
infrastructure.destroy();
}
}
@Test
void test_recordMetrics() {
// GIVEN
Instant currentTimeTruncatedToMinutes = Instant.now(Clock.systemUTC()).truncatedTo(ChronoUnit.MINUTES);
String event1 = "{ \"metrics\": {\"orders\": 1, \"products\": 4}, \"dimensions\": { \"Environment\": \"test\"}, \"highResolution\": \"false\"}";
String event2 = "{ \"metrics\": {\"orders\": 1, \"products\": 8}, \"dimensions\": { \"Environment\": \"test\"}, \"highResolution\": \"true\"}";
// WHEN
InvocationResult invocationResult = invokeFunction(functionName, event1);
invokeFunction(functionName, event2);
// THEN
MetricsFetcher metricsFetcher = new MetricsFetcher();
List<Double> coldStart = metricsFetcher.fetchMetrics(invocationResult.getStart(), invocationResult.getEnd(), 60,
NAMESPACE,
"ColdStart", Stream.of(new String[][] {
{ "FunctionName", functionName },
{ "Service", SERVICE } }).collect(Collectors.toMap(data -> data[0], data -> data[1])));
assertThat(coldStart.get(0)).isEqualTo(1);
List<Double> orderMetrics = RetryUtils.withRetry(() -> {
List<Double> metrics = metricsFetcher.fetchMetrics(invocationResult.getStart(), invocationResult.getEnd(),
60, NAMESPACE, "orders", Collections.singletonMap("Environment", "test"));
if (metrics.get(0) != 2.0) {
throw new DataNotReadyException("Expected 2.0 orders but got " + metrics.get(0));
}
return metrics;
}, "orderMetricsRetry", DataNotReadyException.class).get();
assertThat(orderMetrics.get(0)).isEqualTo(2);
List<Double> productMetrics = metricsFetcher.fetchMetrics(invocationResult.getStart(),
invocationResult.getEnd(), 60, NAMESPACE,
"products", Collections.singletonMap("Environment", "test"));
// When searching across a 1 minute time period with a period of 60 we find both metrics and the sum is 12
assertThat(productMetrics.get(0)).isEqualTo(12);
orderMetrics = metricsFetcher.fetchMetrics(invocationResult.getStart(), invocationResult.getEnd(), 60,
NAMESPACE,
"orders", Collections.singletonMap("Service", SERVICE));
assertThat(orderMetrics.get(0)).isEqualTo(2);
productMetrics = metricsFetcher.fetchMetrics(invocationResult.getStart(), invocationResult.getEnd(), 60,
NAMESPACE,
"products", Collections.singletonMap("Service", SERVICE));
assertThat(productMetrics.get(0)).isEqualTo(12);
Instant searchStartTime = currentTimeTruncatedToMinutes.plusSeconds(15);
Instant searchEndTime = currentTimeTruncatedToMinutes.plusSeconds(45);
List<Double> productMetricDataResult = metricsFetcher.fetchMetrics(searchStartTime, searchEndTime, 1, NAMESPACE,
"products", Collections.singletonMap("Environment", "test"));
// We are searching across the time period the metric was created but with a period of 1 second. Only the high
// resolution metric will be available at this point
assertThat(productMetricDataResult.get(0)).isEqualTo(8);
}
}