Skip to content

Commit

Permalink
fix(tracer, metrics): use polling instead of fixed wait in e2e tests (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Balabanov committed Mar 14, 2022
1 parent 0c2fec6 commit 6d4ab75
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 99 deletions.
38 changes: 36 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions packages/metrics/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"typedocMain": "src/index.ts",
"devDependencies": {
"@types/promise-retry": "^1.1.3",
"promise-retry": "^2.0.1"
},
"files": [
"lib"
],
Expand Down
38 changes: 15 additions & 23 deletions packages/metrics/tests/e2e/decorator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import { SdkProvider } from 'aws-cdk/lib/api/aws-auth';
import { CloudFormationDeployments } from 'aws-cdk/lib/api/cloudformation-deployments';
import * as AWS from 'aws-sdk';
import { MetricUnits } from '../../src';
import { getMetrics } from '../helpers/metricsUtils';

const ONE_MINUTE = 1000 * 60;

const cloudwatchClient = new AWS.CloudWatch();
const lambdaClient = new AWS.Lambda();
Expand Down Expand Up @@ -80,10 +83,7 @@ describe('happy cases', () => {
.promise();
}

// THEN
// sleep to allow metrics to be collected
await new Promise((resolve) => setTimeout(resolve, 15000));
}, 200000);
}, ONE_MINUTE * 3);

it('capture ColdStart Metric', async () => {
const expectedDimensions = [
Expand All @@ -92,12 +92,8 @@ describe('happy cases', () => {
{ Name: Object.keys(expectedDefaultDimensions)[0], Value: expectedDefaultDimensions.MyDimension },
];
// Check coldstart metric dimensions
const coldStartMetrics = await cloudwatchClient
.listMetrics({
Namespace: expectedNamespace,
MetricName: 'ColdStart',
})
.promise();
const coldStartMetrics = await getMetrics(cloudwatchClient, expectedNamespace, 'ColdStart', 1);

expect(coldStartMetrics.Metrics?.length).toBe(1);
const coldStartMetric = coldStartMetrics.Metrics?.[0];
expect(coldStartMetric?.Dimensions).toStrictEqual(expectedDimensions);
Expand All @@ -124,16 +120,12 @@ describe('happy cases', () => {
// Despite lambda has been called twice, coldstart metric sum should only be 1
const singleDataPoint = coldStartMetricStat.Datapoints ? coldStartMetricStat.Datapoints[0] : {};
expect(singleDataPoint?.Sum).toBe(1);
}, 15000);
}, ONE_MINUTE * 3);

it('produce added Metric with the default and extra one dimensions', async () => {
// Check metric dimensions
const metrics = await cloudwatchClient
.listMetrics({
Namespace: expectedNamespace,
MetricName: expectedMetricName,
})
.promise();
const metrics = await getMetrics(cloudwatchClient, expectedNamespace, expectedMetricName, 1);

expect(metrics.Metrics?.length).toBe(1);
const metric = metrics.Metrics?.[0];
const expectedDimensions = [
Expand All @@ -144,16 +136,16 @@ describe('happy cases', () => {
expect(metric?.Dimensions).toStrictEqual(expectedDimensions);

// Check coldstart metric value
const adjustedStartTime = new Date(startTime.getTime() - 60 * 1000);
const endTime = new Date(new Date().getTime() + 60 * 1000);
const adjustedStartTime = new Date(startTime.getTime() - 3 * ONE_MINUTE);
const endTime = new Date(new Date().getTime() + ONE_MINUTE);
console.log(`Manual command: aws cloudwatch get-metric-statistics --namespace ${expectedNamespace} --metric-name ${expectedMetricName} --start-time ${Math.floor(adjustedStartTime.getTime()/1000)} --end-time ${Math.floor(endTime.getTime()/1000)} --statistics 'Sum' --period 60 --dimensions '${JSON.stringify(expectedDimensions)}'`);
const metricStat = await cloudwatchClient
.getMetricStatistics(
{
Namespace: expectedNamespace,
StartTime: new Date(startTime.getTime() - 60 * 1000), // minus 1 minute,
StartTime: adjustedStartTime,
Dimensions: expectedDimensions,
EndTime: new Date(new Date().getTime() + 60 * 1000),
EndTime: endTime,
Period: 60,
MetricName: expectedMetricName,
Statistics: ['Sum'],
Expand All @@ -165,7 +157,7 @@ describe('happy cases', () => {
// Since lambda has been called twice in this test and potentially more in others, metric sum should be at least of expectedMetricValue * invocationCount
const singleDataPoint = metricStat.Datapoints ? metricStat.Datapoints[0] : {};
expect(singleDataPoint?.Sum).toBeGreaterThanOrEqual(parseInt(expectedMetricValue) * invocationCount);
}, 15000);
}, ONE_MINUTE * 3);

afterAll(async () => {
if (!process.env.DISABLE_TEARDOWN) {
Expand All @@ -181,5 +173,5 @@ describe('happy cases', () => {
quiet: true,
});
}
}, 200000);
}, ONE_MINUTE * 3);
});
35 changes: 15 additions & 20 deletions packages/metrics/tests/e2e/standardFunctions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import { SdkProvider } from 'aws-cdk/lib/api/aws-auth';
import { CloudFormationDeployments } from 'aws-cdk/lib/api/cloudformation-deployments';
import * as AWS from 'aws-sdk';
import { MetricUnits } from '../../src';
import { getMetrics } from '../helpers/metricsUtils';

const ONE_MINUTE = 1000 * 60;

const cloudwatchClient = new AWS.CloudWatch();
const lambdaClient = new AWS.Lambda();
Expand Down Expand Up @@ -83,16 +86,12 @@ describe('happy cases', () => {
// THEN
// sleep to allow metrics to be collected
await new Promise((resolve) => setTimeout(resolve, 15000));
}, 200000);
}, ONE_MINUTE * 3);

it('capture ColdStart Metric', async () => {
// Check coldstart metric dimensions
const coldStartMetrics = await cloudwatchClient
.listMetrics({
Namespace: expectedNamespace,
MetricName: 'ColdStart',
})
.promise();
const coldStartMetrics = await getMetrics(cloudwatchClient, expectedNamespace, 'ColdStart', 1);

expect(coldStartMetrics.Metrics?.length).toBe(1);
const coldStartMetric = coldStartMetrics.Metrics?.[0];
expect(coldStartMetric?.Dimensions).toStrictEqual([{ Name: 'service', Value: expectedServiceName }]);
Expand All @@ -119,16 +118,12 @@ describe('happy cases', () => {
// Despite lambda has been called twice, coldstart metric sum should only be 1
const singleDataPoint = coldStartMetricStat.Datapoints ? coldStartMetricStat.Datapoints[0] : {};
expect(singleDataPoint?.Sum).toBe(1);
}, 15000);
}, ONE_MINUTE * 3);

it('produce added Metric with the default and extra one dimensions', async () => {
// Check metric dimensions
const metrics = await cloudwatchClient
.listMetrics({
Namespace: expectedNamespace,
MetricName: expectedMetricName,
})
.promise();
const metrics = await getMetrics(cloudwatchClient, expectedNamespace, expectedMetricName, 1);

expect(metrics.Metrics?.length).toBe(1);
const metric = metrics.Metrics?.[0];
const expectedDimensions = [
Expand All @@ -139,16 +134,16 @@ describe('happy cases', () => {
expect(metric?.Dimensions).toStrictEqual(expectedDimensions);

// Check coldstart metric value
const adjustedStartTime = new Date(startTime.getTime() - 60 * 1000);
const endTime = new Date(new Date().getTime() + 60 * 1000);
const adjustedStartTime = new Date(startTime.getTime() - 3 * ONE_MINUTE);
const endTime = new Date(new Date().getTime() + ONE_MINUTE);
console.log(`Manual command: aws cloudwatch get-metric-statistics --namespace ${expectedNamespace} --metric-name ${expectedMetricName} --start-time ${Math.floor(adjustedStartTime.getTime()/1000)} --end-time ${Math.floor(endTime.getTime()/1000)} --statistics 'Sum' --period 60 --dimensions '${JSON.stringify(expectedDimensions)}'`);
const metricStat = await cloudwatchClient
.getMetricStatistics(
{
Namespace: expectedNamespace,
StartTime: new Date(startTime.getTime() - 60 * 1000), // minus 1 minute,
StartTime: adjustedStartTime,
Dimensions: expectedDimensions,
EndTime: new Date(new Date().getTime() + 60 * 1000),
EndTime: endTime,
Period: 60,
MetricName: expectedMetricName,
Statistics: ['Sum'],
Expand All @@ -160,7 +155,7 @@ describe('happy cases', () => {
// Since lambda has been called twice in this test and potentially more in others, metric sum should be at least of expectedMetricValue * invocationCount
const singleDataPoint = metricStat.Datapoints ? metricStat.Datapoints[0] : {};
expect(singleDataPoint.Sum).toBeGreaterThanOrEqual(parseInt(expectedMetricValue) * invocationCount);
}, 15000);
}, ONE_MINUTE * 3);

afterAll(async () => {
if (!process.env.DISABLE_TEARDOWN) {
Expand All @@ -176,5 +171,5 @@ describe('happy cases', () => {
quiet: true,
});
}
}, 200000);
}, ONE_MINUTE * 3);
});
24 changes: 24 additions & 0 deletions packages/metrics/tests/helpers/metricsUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { CloudWatch } from 'aws-sdk';
import promiseRetry from 'promise-retry';

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 };

return promiseRetry(async (retry: (err?: Error) => never, _: number) => {

const result = await cloudWatchClient
.listMetrics({
Namespace: namespace,
MetricName: metric,
})
.promise();

if (result.Metrics?.length !== expectedMetrics) {
retry(new Error(`Expected ${expectedMetrics} metrics, got ${result.Metrics?.length} for ${namespace}.${metric}`));
}

return result;
}, retryOptions);
};

export { getMetrics };
4 changes: 3 additions & 1 deletion packages/tracing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
"main": "./lib/index.js",
"types": "./lib/index.d.ts",
"devDependencies": {
"@aws-sdk/client-dynamodb": "^3.52.0"
"@aws-sdk/client-dynamodb": "^3.52.0",
"@types/promise-retry": "^1.1.3",
"promise-retry": "^2.0.1"
},
"files": [
"lib"
Expand Down
Loading

0 comments on commit 6d4ab75

Please sign in to comment.