Skip to content

Commit

Permalink
refactor(metrics): standardize unit tests with other utilities (#1414)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
arnabrahman authored Apr 24, 2023
1 parent bae753f commit 1077366
Show file tree
Hide file tree
Showing 4 changed files with 1,893 additions and 675 deletions.
7 changes: 2 additions & 5 deletions packages/metrics/src/Metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Callback, Context, Handler } from 'aws-lambda';
import { Utility } from '@aws-lambda-powertools/commons';
import { MetricsInterface } from '.';
import { ConfigServiceInterface, EnvironmentVariablesService } from './config';
import { MAX_DIMENSION_COUNT, MAX_METRICS_SIZE, DEFAULT_NAMESPACE, COLD_START_METRIC } from './constants';
import {
MetricsOptions,
Dimensions,
Expand All @@ -16,10 +17,6 @@ import {
StoredMetric,
} from './types';

const MAX_METRICS_SIZE = 100;
const MAX_DIMENSION_COUNT = 29;
const DEFAULT_NAMESPACE = 'default_namespace';

/**
* ## Intro
* Metrics creates custom metrics asynchronously by logging metrics to standard output following Amazon CloudWatch Embedded Metric Format (EMF).
Expand Down Expand Up @@ -228,7 +225,7 @@ class Metrics extends Utility implements MetricsInterface {
if (this.functionName != null) {
singleMetric.addDimension('function_name', this.functionName);
}
singleMetric.addMetric('ColdStart', MetricUnits.Count, 1);
singleMetric.addMetric(COLD_START_METRIC, MetricUnits.Count, 1);
}

public clearDefaultDimensions(): void {
Expand Down
4 changes: 4 additions & 0 deletions packages/metrics/src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export const COLD_START_METRIC = 'ColdStart';
export const DEFAULT_NAMESPACE = 'default_namespace';
export const MAX_METRICS_SIZE = 100;
export const MAX_DIMENSION_COUNT = 29;
29 changes: 28 additions & 1 deletion packages/metrics/tests/helpers/metricsUtils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { CloudWatch } from 'aws-sdk';
import promiseRetry from 'promise-retry';
import { Metrics } from '../../src';
import { ExtraOptions, MetricUnits } from '../../src/types';
import { Context, Handler } from 'aws-lambda';
import { LambdaInterface } from '@aws-lambda-powertools/commons';

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

export { getMetrics };
const setupDecoratorLambdaHandler = (metrics: Metrics, options: ExtraOptions = {}): Handler => {

class LambdaFunction implements LambdaInterface {
@metrics.logMetrics(options)
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
public async handler<TEvent>(_event: TEvent, _context: Context): Promise<string> {
metrics.addMetric('decorator-lambda-test-metric', MetricUnits.Count, 1);

return 'Lambda invoked!';
}
}

const handlerClass = new LambdaFunction();
const handler = handlerClass.handler.bind(handlerClass);

return handler;
};

export {
getMetrics,
setupDecoratorLambdaHandler
};

Loading

0 comments on commit 1077366

Please sign in to comment.