Skip to content

Commit 1077366

Browse files
authored
refactor(metrics): standardize unit tests with other utilities (#1414)
* test: cleanup unit tests * test: store metrics * test: create multiple metrics * test: addMetric default resolution * test: addMetric will group values for same metric name * test: addMetric throws error while adding same metric with different unit * test: addMetric will publish metrics if stored metrics count has reached max metric size threshold * test: addMetric will not publish if stored metrics count has not reached max metric size threshold * test: addDimension storing dimension * test: addDimension giving error if number of dimensions exceeds the maximum allowed * test: addDimensions should add multiple dimensions * test: addDimensions should update existing dimension value if added again * test: addDimensions should throw error if maximum dimension count crosses * test: addMetadata should add metadata * test: clearDimensions should clear dimensions * test: clearMetadata should clear all metadata * test: clearMetrics should clear all stored metrics * test: setDefaultDimensions should set default dimensions object * test: setDefaultDimensions should throw error if default dimensions reaches maximum allowed * test: clearDefaultDimensions should clear all default dimensions * test: singleMetric should return a single metric object * test: throwOnEmptyMetrics will set the throwOnEmptyMetrics flag to true * test: setFunctionName should set the function name * test: logMetrics should log metrics * test: logMetrics should capture cold start metrics * test: logMetrics should throw error if no metrics are added and throwOnEmptyMetrics is set to true * test: logMetrics should set default dimensions if passed in the options * test: logMetrics should throw error if lambda handler throws any error * test: serializeMetrics should print warning, if no namespace provided in constructor or environment variable * feat: metrics helper * test: createMetrics should return appropriate values for no constructor params and no environment variables * test: createMetrics should return appropriate instance when constructor params are set * test: serializeMetricscreateMetrics should return right object compliant with Cloudwatch EMF * test: serializeMetricscreateMetrics should log service dimensions correctly * test: serializeMetricscreateMetrics should log other dimensions correctly * refactor: clearDimensions should not clear default dimensions * test: serializeMetrics should log metadata correctly * test: serializeMetrics should throw error on empty metrics when throwOnEmptyMetrics is true * test: serializeMetrics should log namespaces properly * test: serializeMetrics should log metric values properly * test: serializeMetrics should log properly * test: serializeMetrics should show warning if no metrics are added * test: serializeMetrics should should call serializeMetrics && log the stringified return value of serializeMetrics * test: serializeMetrics should call clearMetrics function * test: serializeMetrics should call clearDimensions function * test: serializeMetrics should call clearMetadata function * test: serializeMetrics should call addMetric with correct parameters * test: serializeMetrics should call setDefaultDimensions with correct parameters * test: serializeMetrics should call addDimension depending on functionName value * test: serializeMetrics should not call any function, if there is no cold start * refactor: extract reusable constants to a separate file * refactor: import default namespace from constants * refactor: use MAX_METRICS_SIZE from constants * refactor: use MAX_DIMENSION_COUNT from constants * refactor: use MAX_DIMENSION_COUNT in max dimension allowed tests * refactor: extract cold start metric in constants * refactor: use createMetrics helper function to create Metrics instance * refactor: set namespace for all the Metrics instance * style: formatting in test steps * test: cleanup POWERTOOLS_METRICS_NAMESPACE env after test completion inside serializeMetrics * test: error messages for various errors * docs: decorator function comments * refactor: format test metric name * style: rearrange tests by name * fix: default namespace test for serializeMetrics function * fix: remove redundant deletion of process env * test: addDimension should update existing dimension value if same dimension is added again * style: rephrase test description for addDimensions * style: rephrase test description for addMetadata * style: rephrase test description for addMetric * test: addMetric should publish metrics on every call if singleMetric is true * style: rephrase test description for captureColdStartMetric * test: clearDefaultDimensions should only clear default dimensions * style: rephrase test description of clearDimensions * style: rephrase test description of clearMetrics * refactor: common functionality inside beforeEach for logMetrics test * refactor: publish metrics test for logMetrics * refactor: capture cold start test for logMetrics * refactor: call throwOnEmptyMetrics test for logMetrics * refactor: set default dimensions test for logMetrics * refactor: separate decorator lambda function generation for logMetrics test * refactor: publishStoredMetrics tests * improv: test return values for serializeMetrics. This will help visualize the output of serializeMetrics for different inputs * refactor: tests for setDefaultDimensions * style: spacing in Metrics class * refactor: function export for metricsUtils * refactor: LooseObject interface in metrics tests * refactor: range error tests for max dimension count * refactor: test range error for max dimension in addDimension * refactor: range error tests for max metric size * refactor: test namespace value from constant * style: redundant curly braces * refactor: replace createMetrics helper with new Metrics(...). This helper will be removed/deprecated from all utilities(i.e. createLogger) in the next major release. So, avoiding it is logical. * test: constructor method of Metrics class. Removing createMetrics helper function and related tests impacts 100% code coverage. So, instead createMetrics tests can be used as constructor method tests for Metrics class. As a result 100% test coverage will not be impacted. * refactor: remove createMetrics helper function related codes
1 parent bae753f commit 1077366

File tree

4 files changed

+1893
-675
lines changed

4 files changed

+1893
-675
lines changed

packages/metrics/src/Metrics.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Callback, Context, Handler } from 'aws-lambda';
22
import { Utility } from '@aws-lambda-powertools/commons';
33
import { MetricsInterface } from '.';
44
import { ConfigServiceInterface, EnvironmentVariablesService } from './config';
5+
import { MAX_DIMENSION_COUNT, MAX_METRICS_SIZE, DEFAULT_NAMESPACE, COLD_START_METRIC } from './constants';
56
import {
67
MetricsOptions,
78
Dimensions,
@@ -16,10 +17,6 @@ import {
1617
StoredMetric,
1718
} from './types';
1819

19-
const MAX_METRICS_SIZE = 100;
20-
const MAX_DIMENSION_COUNT = 29;
21-
const DEFAULT_NAMESPACE = 'default_namespace';
22-
2320
/**
2421
* ## Intro
2522
* Metrics creates custom metrics asynchronously by logging metrics to standard output following Amazon CloudWatch Embedded Metric Format (EMF).
@@ -228,7 +225,7 @@ class Metrics extends Utility implements MetricsInterface {
228225
if (this.functionName != null) {
229226
singleMetric.addDimension('function_name', this.functionName);
230227
}
231-
singleMetric.addMetric('ColdStart', MetricUnits.Count, 1);
228+
singleMetric.addMetric(COLD_START_METRIC, MetricUnits.Count, 1);
232229
}
233230

234231
public clearDefaultDimensions(): void {

packages/metrics/src/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export const COLD_START_METRIC = 'ColdStart';
2+
export const DEFAULT_NAMESPACE = 'default_namespace';
3+
export const MAX_METRICS_SIZE = 100;
4+
export const MAX_DIMENSION_COUNT = 29;

packages/metrics/tests/helpers/metricsUtils.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { CloudWatch } from 'aws-sdk';
22
import promiseRetry from 'promise-retry';
3+
import { Metrics } from '../../src';
4+
import { ExtraOptions, MetricUnits } from '../../src/types';
5+
import { Context, Handler } from 'aws-lambda';
6+
import { LambdaInterface } from '@aws-lambda-powertools/commons';
37

48
const getMetrics = async (cloudWatchClient: CloudWatch, namespace: string, metric: string, expectedMetrics: number): Promise<CloudWatch.ListMetricsOutput> => {
59
const retryOptions = { retries: 20, minTimeout: 5_000, maxTimeout: 10_000, factor: 1.25 };
@@ -21,4 +25,27 @@ const getMetrics = async (cloudWatchClient: CloudWatch, namespace: string, metri
2125
}, retryOptions);
2226
};
2327

24-
export { getMetrics };
28+
const setupDecoratorLambdaHandler = (metrics: Metrics, options: ExtraOptions = {}): Handler => {
29+
30+
class LambdaFunction implements LambdaInterface {
31+
@metrics.logMetrics(options)
32+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
33+
// @ts-ignore
34+
public async handler<TEvent>(_event: TEvent, _context: Context): Promise<string> {
35+
metrics.addMetric('decorator-lambda-test-metric', MetricUnits.Count, 1);
36+
37+
return 'Lambda invoked!';
38+
}
39+
}
40+
41+
const handlerClass = new LambdaFunction();
42+
const handler = handlerClass.handler.bind(handlerClass);
43+
44+
return handler;
45+
};
46+
47+
export {
48+
getMetrics,
49+
setupDecoratorLambdaHandler
50+
};
51+

0 commit comments

Comments
 (0)