diff --git a/packages/@aws-cdk/aws-scheduler-alpha/lib/group.ts b/packages/@aws-cdk/aws-scheduler-alpha/lib/group.ts index 3bd5f5809ec13..7f737a91eca2e 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/lib/group.ts +++ b/packages/@aws-cdk/aws-scheduler-alpha/lib/group.ts @@ -202,7 +202,7 @@ abstract class GroupBase extends Resource implements IGroup { * * @default - sum over 5 minutes */ - metricSentToDLQ(props?: cloudwatch.MetricOptions): cloudwatch.Metric { + public metricSentToDLQ(props?: cloudwatch.MetricOptions): cloudwatch.Metric { return this.metric('InvocationsSentToDeadLetterCount', props); } diff --git a/packages/@aws-cdk/aws-scheduler-alpha/test/group.test.ts b/packages/@aws-cdk/aws-scheduler-alpha/test/group.test.ts index 3f59a10903c4b..e0de97b02ce30 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/test/group.test.ts +++ b/packages/@aws-cdk/aws-scheduler-alpha/test/group.test.ts @@ -279,20 +279,33 @@ describe('Schedule Group', () => { }, }); }); +}); - test('Target Error Metrics', () => { +describe('Schedule Group Metrics', () => { + test.each([ + ['metricTargetErrors', 'TargetErrorCount'], + ['metricThrottled', 'InvocationThrottleCount'], + ['metricAttempts', 'InvocationAttemptCount'], + ['metricTargetThrottled', 'TargetErrorThrottledCount'], + ['metricDropped', 'InvocationDroppedCount'], + ['metricSentToDLQ', 'InvocationsSentToDeadLetterCount'], + ['metricSentToDLQTruncated', 'InvocationsSentToDeadLetterCount_Truncated_MessageSizeExceeded'], + ])('calling %s creates alarm for %s metric', (metricMethodName, metricName) => { // GIVEN + const app = new App(); const props: GroupProps = { groupName: 'MyGroup', }; + const stack = new Stack(app, 'Stack', { env: { region: 'us-east-1', account: '123456789012' } }); const group = new Group(stack, 'TestGroup', props); // WHEN - const metricTargetErrors = group.metricTargetErrors({ + const metricMethod = (group as any)[metricMethodName].bind(group); // Get the method dynamically + const metricTargetErrors = metricMethod({ period: Duration.minutes(1), }); - new cw.Alarm(stack, 'GroupTargetErrorAlarm', { + new cw.Alarm(stack, `Group${metricName}Alarm`, { metric: metricTargetErrors, evaluationPeriods: 1, threshold: 1, @@ -306,7 +319,41 @@ describe('Schedule Group', () => { Value: 'MyGroup', }), ]), - MetricName: 'TargetErrorCount', + MetricName: metricName, + Namespace: 'AWS/Scheduler', + }); + }); + + test('Invocations Failed to Deliver to DLQ Metrics', () => { + // GIVEN + const app = new App(); + const props: GroupProps = { + groupName: 'MyGroup', + }; + const stack = new Stack(app, 'Stack', { env: { region: 'us-east-1', account: '123456789012' } }); + const group = new Group(stack, 'TestGroup', props); + const errorCode = '403'; + + // WHEN + const metricFailedToBeSentToDLQ = group.metricFailedToBeSentToDLQ(errorCode, { + period: Duration.minutes(1), + }); + + new cw.Alarm(stack, 'GroupFailedInvocationsToDLQAlarm', { + metric: metricFailedToBeSentToDLQ, + evaluationPeriods: 1, + threshold: 1, + }); + + // THEN + Template.fromStack(stack).hasResourceProperties('AWS::CloudWatch::Alarm', { + Dimensions: Match.arrayWith([ + Match.objectLike({ + Name: 'ScheduleGroup', + Value: 'MyGroup', + }), + ]), + MetricName: `InvocationsFailedToBeSentToDeadLetterCount_${errorCode}`, Namespace: 'AWS/Scheduler', }); }); diff --git a/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts b/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts index d12ca608820d3..416679e2667d2 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts +++ b/packages/@aws-cdk/aws-scheduler-alpha/test/schedule-expression.test.ts @@ -118,7 +118,7 @@ describe('schedule expression', () => { }); test('one-time expression with invalid date throws', () => { - expect(() => ScheduleExpression.at(new Date('13-20-1969'))).toThrowError('Invalid date'); + expect(() => ScheduleExpression.at(new Date('13-20-1969'))).toThrow('Invalid date'); }); }); @@ -130,13 +130,13 @@ describe('fractional minutes checks', () => { }); test('rate cannot be a fractional amount of minutes (defined with minutes)', () => { - expect(()=> { - ScheduleExpression.rate(Duration.minutes(5/3)); + expect(() => { + ScheduleExpression.rate(Duration.minutes(5 / 3)); }).toThrow(/must be a whole number of/); }); test('rate cannot be a fractional amount of minutes (defined with hours)', () => { - expect(()=> { + expect(() => { ScheduleExpression.rate(Duration.hours(1.03)); }).toThrow(/cannot be converted into a whole number of/); }); @@ -149,7 +149,7 @@ describe('fractional minutes checks', () => { test('rate cannot be less than 1 minute (defined with minutes as fractions)', () => { expect(() => { - ScheduleExpression.rate(Duration.minutes(1/2)); + ScheduleExpression.rate(Duration.minutes(1 / 2)); }).toThrow(/must be a whole number of/); }); @@ -164,4 +164,9 @@ describe('fractional minutes checks', () => { ScheduleExpression.rate(Duration.minutes(10)) .expressionString); }); -}); \ No newline at end of file + + test('literal schedule expression', () => { + expect('rate(1 hour)').toEqual( + ScheduleExpression.expression('rate(1 hour)').expressionString); + }); +}); diff --git a/packages/@aws-cdk/aws-scheduler-alpha/test/schedule.test.ts b/packages/@aws-cdk/aws-scheduler-alpha/test/schedule.test.ts index 92b395f6eaf8e..6f21fa7ca3cbf 100644 --- a/packages/@aws-cdk/aws-scheduler-alpha/test/schedule.test.ts +++ b/packages/@aws-cdk/aws-scheduler-alpha/test/schedule.test.ts @@ -64,13 +64,22 @@ describe('Schedule', () => { }); }); - test('returns metric for delivery of failed invocations to DLQ', () => { + test.each([ + ['metricAllThrottled', 'InvocationThrottleCount'], + ['metricAllErrors', 'TargetErrorCount'], + ['metricAllAttempts', 'InvocationAttemptCount'], + ['metricAllTargetThrottled', 'TargetErrorThrottledCount'], + ['metricAllDropped', 'InvocationDroppedCount'], + ['metricAllSentToDLQ', 'InvocationsSentToDeadLetterCount'], + ['metricAllSentToDLQTruncated', 'InvocationsSentToDeadLetterCount_Truncated_MessageSizeExceeded'], + + ])('returns expected metric for %s', (metricMethodName: string, metricName: string) => { // WHEN - const metric = Schedule.metricAllFailedToBeSentToDLQ(); + const metric = (Schedule as any)[metricMethodName](); // THEN expect(metric.namespace).toEqual('AWS/Scheduler'); - expect(metric.metricName).toEqual('InvocationsFailedToBeSentToDeadLetterCount'); + expect(metric.metricName).toEqual(metricName); expect(metric.dimensions).toBeUndefined(); expect(metric.statistic).toEqual('Sum'); expect(metric.period).toEqual(Duration.minutes(5)); @@ -88,6 +97,18 @@ describe('Schedule', () => { expect(metric.period).toEqual(Duration.minutes(5)); }); + test('returns metric for delivery of failed invocations to DLQ with no error code', () => { + // WHEN + const metric = Schedule.metricAllFailedToBeSentToDLQ(); + + // THEN + expect(metric.namespace).toEqual('AWS/Scheduler'); + expect(metric.metricName).toEqual('InvocationsFailedToBeSentToDeadLetterCount'); + expect(metric.dimensions).toBeUndefined(); + expect(metric.statistic).toEqual('Sum'); + expect(metric.period).toEqual(Duration.minutes(5)); + }); + test('returns metric for all errors with provided statistic and period', () => { // WHEN const metric = Schedule.metricAllErrors({