22// SPDX-License-Identifier: MIT-0
33
44/**
5- * Test metrics decorator
5+ * Test metrics standard functions
66 *
7- * @group e2e/metrics/decorator
7+ * @group e2e/metrics/standardFunctions
88 */
99
1010import { randomUUID } from 'crypto' ;
@@ -19,43 +19,44 @@ const cloudwatchClient = new AWS.CloudWatch();
1919const lambdaClient = new AWS . Lambda ( ) ;
2020
2121const integTestApp = new App ( ) ;
22- const stack = new Stack ( integTestApp , 'ExampleIntegTest ' ) ;
22+ const stack = new Stack ( integTestApp , 'MetricsE2EStandardFunctionsStack ' ) ;
2323
24- describe ( 'coldstart' , ( ) => {
25- it ( 'can be deploy succcessfully' , async ( ) => {
26- // GIVEN
27- const startTime = new Date ( ) ;
28- const expectedNamespace = randomUUID ( ) ; // to easily find metrics back at assert phase
29- const expectedServiceName = 'MyFunctionWithStandardHandler' ;
30- const expectedMetricName = 'MyMetric' ;
31- const expectedMetricUnit = MetricUnits . Count ;
32- const expectedMetricValue = '1' ;
33- const expectedDefaultDimensions = { MyDimension : 'MyValue' } ;
34- const expectedExtraDimension = { MyExtraDimension : 'MyExtraValue' } ;
35- const expectedSingleMetricDimension = { MySingleMetricDim : 'MySingleValue' } ;
36- const expectedSingleMetricName = 'MySingleMetric' ;
37- const expectedSingleMetricUnit = MetricUnits . Percent ;
38- const expectedSingleMetricValue = '2' ;
39- const functionName = 'MyFunctionWithStandardHandler' ;
40- new lambda . NodejsFunction ( stack , 'MyFunction' , {
41- functionName : functionName ,
42- environment : {
43- EXPECTED_NAMESPACE : expectedNamespace ,
44- EXPECTED_SERVICE_NAME : expectedServiceName ,
45- EXPECTED_METRIC_NAME : expectedMetricName ,
46- EXPECTED_METRIC_UNIT : expectedMetricUnit ,
47- EXPECTED_METRIC_VALUE : expectedMetricValue ,
48- EXPECTED_DEFAULT_DIMENSIONS : JSON . stringify ( expectedDefaultDimensions ) ,
49- EXPECTED_EXTRA_DIMENSION : JSON . stringify ( expectedExtraDimension ) ,
50- EXPECTED_SINGLE_METRIC_DIMENSION : JSON . stringify ( expectedSingleMetricDimension ) ,
51- EXPECTED_SINGLE_METRIC_NAME : expectedSingleMetricName ,
52- EXPECTED_SINGLE_METRIC_UNIT : expectedSingleMetricUnit ,
53- EXPECTED_SINGLE_METRIC_VALUE : expectedSingleMetricValue ,
54- } ,
55- } ) ;
24+ // GIVEN
25+ const startTime = new Date ( ) ;
26+ const expectedNamespace = randomUUID ( ) ; // to easily find metrics back at assert phase
27+ const expectedServiceName = 'MyFunctionWithStandardHandler' ;
28+ const expectedMetricName = 'MyMetric' ;
29+ const expectedMetricUnit = MetricUnits . Count ;
30+ const expectedMetricValue = '1' ;
31+ const expectedDefaultDimensions = { MyDimension : 'MyValue' } ;
32+ const expectedExtraDimension = { MyExtraDimension : 'MyExtraValue' } ;
33+ const expectedSingleMetricDimension = { MySingleMetricDim : 'MySingleValue' } ;
34+ const expectedSingleMetricName = 'MySingleMetric' ;
35+ const expectedSingleMetricUnit = MetricUnits . Percent ;
36+ const expectedSingleMetricValue = '2' ;
37+ const functionName = 'MyFunctionWithStandardHandler' ;
38+ new lambda . NodejsFunction ( stack , 'MyFunction' , {
39+ functionName : functionName ,
40+ tracing : Tracing . ACTIVE ,
41+ environment : {
42+ EXPECTED_NAMESPACE : expectedNamespace ,
43+ EXPECTED_SERVICE_NAME : expectedServiceName ,
44+ EXPECTED_METRIC_NAME : expectedMetricName ,
45+ EXPECTED_METRIC_UNIT : expectedMetricUnit ,
46+ EXPECTED_METRIC_VALUE : expectedMetricValue ,
47+ EXPECTED_DEFAULT_DIMENSIONS : JSON . stringify ( expectedDefaultDimensions ) ,
48+ EXPECTED_EXTRA_DIMENSION : JSON . stringify ( expectedExtraDimension ) ,
49+ EXPECTED_SINGLE_METRIC_DIMENSION : JSON . stringify ( expectedSingleMetricDimension ) ,
50+ EXPECTED_SINGLE_METRIC_NAME : expectedSingleMetricName ,
51+ EXPECTED_SINGLE_METRIC_UNIT : expectedSingleMetricUnit ,
52+ EXPECTED_SINGLE_METRIC_VALUE : expectedSingleMetricValue ,
53+ } ,
54+ } ) ;
5655
57- const stackArtifact = integTestApp . synth ( ) . getStackByName ( stack . stackName ) ;
56+ const stackArtifact = integTestApp . synth ( ) . getStackByName ( stack . stackName ) ;
5857
58+ describe ( 'happy cases' , ( ) => {
59+ beforeAll ( async ( ) => {
5960 const sdkProvider = await SdkProvider . withAwsCliCompatibleDefaults ( {
6061 profile : process . env . AWS_PROFILE ,
6162 } ) ;
@@ -66,7 +67,11 @@ describe('coldstart', () => {
6667 await cloudFormation . deployStack ( {
6768 stack : stackArtifact ,
6869 } ) ;
69- // and invoked
70+ } , 200000 ) ;
71+
72+ it ( 'capture ColdStart Metric' , async ( ) => {
73+ // WHEN
74+ // invoked
7075 await lambdaClient
7176 . invoke ( {
7277 FunctionName : functionName ,
@@ -106,27 +111,82 @@ describe('coldstart', () => {
106111 MetricName : 'ColdStart' ,
107112 Statistics : [ 'Sum' ] ,
108113 } ,
109- undefined ,
114+ undefined
110115 )
111116 . promise ( ) ;
112117
113118 // Despite lambda has been called twice, coldstart metric sum should only be 1
114119 const singleDataPoint = coldStartMetricStat . Datapoints ? coldStartMetricStat . Datapoints [ 0 ] : { } ;
115120 expect ( singleDataPoint . Sum ) . toBe ( 1 ) ;
116- } , 9000000 ) ;
117- } ) ;
121+ } , 15000 ) ;
118122
119- afterAll ( async ( ) => {
120- if ( ! process . env . DISABLE_TEARDOWN ) {
121- const stackArtifact = integTestApp . synth ( ) . getStackByName ( stack . stackName ) ;
123+ it ( 'produce added Metric with the default and extra one dimensions' , async ( ) => {
124+ // GIVEN
125+ const invocationCount = 2 ;
122126
123- const sdkProvider = await SdkProvider . withAwsCliCompatibleDefaults ( {
124- profile : process . env . AWS_PROFILE ,
125- } ) ;
126- const cloudFormation = new CloudFormationDeployments ( { sdkProvider } ) ;
127+ // WHEN
128+ // invoked
129+ for ( let i = 0 ; i < invocationCount ; i ++ ) {
130+ await lambdaClient
131+ . invoke ( {
132+ FunctionName : functionName ,
133+ } )
134+ . promise ( ) ;
135+ }
127136
128- await cloudFormation . destroyStack ( {
129- stack : stackArtifact ,
130- } ) ;
131- }
132- } , 9000000 ) ;
137+ // THEN
138+ // sleep to allow metrics to be collected
139+ await new Promise ( ( resolve ) => setTimeout ( resolve , 10000 ) ) ;
140+
141+ // Check metric dimensions
142+ const metrics = await cloudwatchClient
143+ . listMetrics ( {
144+ Namespace : expectedNamespace ,
145+ MetricName : expectedMetricName ,
146+ } )
147+ . promise ( ) ;
148+ expect ( metrics . Metrics ?. length ) . toBe ( 1 ) ;
149+ const metric = metrics . Metrics ?. [ 0 ] ;
150+ const expectedDimensions = [
151+ { Name : 'service' , Value : expectedServiceName } ,
152+ { Name : Object . keys ( expectedDefaultDimensions ) [ 0 ] , Value : expectedDefaultDimensions . MyDimension } ,
153+ { Name : Object . keys ( expectedExtraDimension ) [ 0 ] , Value : expectedExtraDimension . MyExtraDimension } ,
154+ ] ;
155+ expect ( metric ?. Dimensions ) . toStrictEqual ( expectedDimensions ) ;
156+
157+ // Check coldstart metric value
158+ const metricStat = await cloudwatchClient
159+ . getMetricStatistics (
160+ {
161+ Namespace : expectedNamespace ,
162+ StartTime : new Date ( startTime . getTime ( ) - 60 * 1000 ) , // minus 1 minute,
163+ Dimensions : expectedDimensions ,
164+ EndTime : new Date ( new Date ( ) . getTime ( ) + 60 * 1000 ) ,
165+ Period : 60 ,
166+ MetricName : expectedMetricName ,
167+ Statistics : [ 'Sum' ] ,
168+ } ,
169+ undefined
170+ )
171+ . promise ( ) ;
172+
173+ // Since lambda has been called twice in this test and potentially more in others, metric sum should be at least of expectedMetricValue * invocationCount
174+ const singleDataPoint = metricStat . Datapoints ? metricStat . Datapoints [ 0 ] : { } ;
175+ expect ( singleDataPoint . Sum ) . toBeGreaterThanOrEqual ( parseInt ( expectedMetricValue ) * invocationCount ) ;
176+ } , 15000 ) ;
177+
178+ afterAll ( async ( ) => {
179+ if ( ! process . env . DISABLE_TEARDOWN ) {
180+ const stackArtifact = integTestApp . synth ( ) . getStackByName ( stack . stackName ) ;
181+
182+ const sdkProvider = await SdkProvider . withAwsCliCompatibleDefaults ( {
183+ profile : process . env . AWS_PROFILE ,
184+ } ) ;
185+ const cloudFormation = new CloudFormationDeployments ( { sdkProvider } ) ;
186+
187+ await cloudFormation . destroyStack ( {
188+ stack : stackArtifact ,
189+ } ) ;
190+ }
191+ } , 200000 ) ;
192+ } ) ;
0 commit comments