Skip to content

Commit

Permalink
chore: extract and extend DynamoDB dashboard tests
Browse files Browse the repository at this point in the history
  • Loading branch information
eoinsha committed Nov 28, 2023
1 parent c4deb00 commit 971e40a
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 209 deletions.
6 changes: 4 additions & 2 deletions core/dashboards/dashboard.ts
Expand Up @@ -573,7 +573,8 @@ export default function addDashboard (dashboardConfig: SlicWatchInputDashboardCo
dimensions: {
LoadBalancer: loadBalancerFullName
},
stat
stat,
yAxis: metricConfig.yAxis
})
}
}
Expand Down Expand Up @@ -619,7 +620,8 @@ export default function addDashboard (dashboardConfig: SlicWatchInputDashboardCo
LoadBalancer: loadBalancerFullName,
TargetGroup: targetGroupFullName
},
stat
stat,
yAxis: metricConfig.yAxis
})
}
}
Expand Down
182 changes: 182 additions & 0 deletions core/dashboards/tests/dashboard-alb.test.ts
@@ -0,0 +1,182 @@
import { merge } from 'lodash'
import { test } from 'tap'
import { type MetricWidgetProperties } from 'cloudwatch-dashboard-types'

import { type ResourceType } from '../../cf-template'
import addDashboard from '../dashboard'
import defaultConfig from '../../inputs/default-config'

import { albCfTemplate, createTestCloudFormationTemplate, getDashboardFromTemplate, getDashboardWidgetsByTitle } from '../../tests/testing-utils'

test('dashboard contains configured ALB resources', (t) => {
t.test('dashboards includes ALB metrics', (t) => {
const template = createTestCloudFormationTemplate(albCfTemplate)
addDashboard(defaultConfig.dashboard, template)
const { dashboard } = getDashboardFromTemplate(template)

const widgets = getDashboardWidgetsByTitle(dashboard,
/ALB/,
/Target Group/
)

const [albWidget, targetGroupWidget] = widgets
t.ok(albWidget)
t.ok(targetGroupWidget)
t.same((albWidget.properties as MetricWidgetProperties).metrics, [
['AWS/ApplicationELB', 'HTTPCode_ELB_5XX_Count', 'LoadBalancer', '${alb.LoadBalancerFullName}', { stat: 'Sum', yAxis: 'left' }],
['AWS/ApplicationELB', 'RejectedConnectionCount', 'LoadBalancer', '${alb.LoadBalancerFullName}', { stat: 'Sum', yAxis: 'left' }]
])
t.same((targetGroupWidget.properties as MetricWidgetProperties).metrics, [
['AWS/ApplicationELB', 'HTTPCode_Target_5XX_Count', 'LoadBalancer', '${alb.LoadBalancerFullName}', 'TargetGroup', '${AlbEventAlbTargetGrouphttpListener.TargetGroupFullName}', { stat: 'Sum', yAxis: 'left' }],
['AWS/ApplicationELB', 'UnHealthyHostCount', 'LoadBalancer', '${alb.LoadBalancerFullName}', 'TargetGroup', '${AlbEventAlbTargetGrouphttpListener.TargetGroupFullName}', { stat: 'Average', yAxis: 'left' }],
['AWS/ApplicationELB', 'LambdaInternalError', 'LoadBalancer', '${alb.LoadBalancerFullName}', 'TargetGroup', '${AlbEventAlbTargetGrouphttpListener.TargetGroupFullName}', { stat: 'Sum', yAxis: 'left' }],
['AWS/ApplicationELB', 'LambdaUserError', 'LoadBalancer', '${alb.LoadBalancerFullName}', 'TargetGroup', '${AlbEventAlbTargetGrouphttpListener.TargetGroupFullName}', { stat: 'Sum', yAxis: 'left' }]
])

t.end()
})

t.test('service config overrides take precedence', (t) => {
const template = createTestCloudFormationTemplate(albCfTemplate)

const config = merge({}, defaultConfig.dashboard, {
widgets: {
ApplicationELB: {
metricPeriod: 900,
width: 8,
height: 12,
HTTPCode_ELB_5XX_Count: {
Statistic: ['Average'],
enabled: false
},
RejectedConnectionCount: {
Statistic: ['ts90'],
yAxis: 'right'
}
},
ApplicationELBTarget: {
metricPeriod: 900,
width: 24,
height: 12,
HTTPCode_Target_5XX_Count: {
Statistic: ['ts80'],
yAxis: 'right'
},
UnHealthyHostCount: {
Statistic: ['Count'],
yAxis: 'right'
},
LambdaInternalError: {
Statistic: ['P99'],
yAxis: 'left'
},
LambdaUserError: {
Statistic: ['Sum'],
enabled: false
}
}
}
})

addDashboard(config, template)
const { dashboard } = getDashboardFromTemplate(template)

const widgets = getDashboardWidgetsByTitle(dashboard,
/ALB/,
/Target Group/
)

const [albWidget, targetGroupWidget] = widgets
t.ok(albWidget)
t.ok(targetGroupWidget)
t.same((albWidget.properties as MetricWidgetProperties).metrics, [
['AWS/ApplicationELB', 'RejectedConnectionCount', 'LoadBalancer', '${alb.LoadBalancerFullName}', { stat: 'ts90', yAxis: 'right' }]
])
t.same((targetGroupWidget.properties as MetricWidgetProperties).metrics, [
['AWS/ApplicationELB', 'HTTPCode_Target_5XX_Count', 'LoadBalancer', '${alb.LoadBalancerFullName}', 'TargetGroup', '${AlbEventAlbTargetGrouphttpListener.TargetGroupFullName}', { stat: 'ts80', yAxis: 'right' }],
['AWS/ApplicationELB', 'UnHealthyHostCount', 'LoadBalancer', '${alb.LoadBalancerFullName}', 'TargetGroup', '${AlbEventAlbTargetGrouphttpListener.TargetGroupFullName}', { stat: 'Count', yAxis: 'right' }],
['AWS/ApplicationELB', 'LambdaInternalError', 'LoadBalancer', '${alb.LoadBalancerFullName}', 'TargetGroup', '${AlbEventAlbTargetGrouphttpListener.TargetGroupFullName}', { stat: 'P99', yAxis: 'left' }]
])

for (const widget of widgets) {
const props: MetricWidgetProperties = widget.properties as MetricWidgetProperties
t.ok((props.metrics?.length ?? 0) > 0)
t.equal(props.period, 900)
t.equal(props.view, 'timeSeries')
}

t.end()
})

t.test('resource config overrides take precedence', (t) => {
const template = createTestCloudFormationTemplate(albCfTemplate)
const resources = template.Resources as ResourceType
resources.alb.Metadata = {
slicWatch: {
dashboard: {
HTTPCode_ELB_5XX_Count: {
Statistic: ['Average'],
enabled: false
},
RejectedConnectionCount: {
Statistic: ['ts90'],
yAxis: 'right'
}
}
}
}

resources.AlbEventAlbTargetGrouphttpListener.Metadata = {
slicWatch: {
dashboard: {
HTTPCode_Target_5XX_Count: {
Statistic: ['ts99'],
yAxis: 'right'
},
UnHealthyHostCount: {
Statistic: ['Count'],
yAxis: 'right',
enabled: false
},
LambdaInternalError: {
Statistic: ['P99'],
yAxis: 'left'
},
LambdaUserError: {
Statistic: ['Sum'],
enabled: false
}
}
}
}
addDashboard(defaultConfig.dashboard, template)
const { dashboard } = getDashboardFromTemplate(template)

const widgets = getDashboardWidgetsByTitle(dashboard,
/ALB/,
/Target Group/
)

const [albWidget, targetGroupWidget] = widgets
t.ok(albWidget)
t.ok(targetGroupWidget)
t.same((albWidget.properties as MetricWidgetProperties).metrics, [
['AWS/ApplicationELB', 'RejectedConnectionCount', 'LoadBalancer', '${alb.LoadBalancerFullName}', { stat: 'ts90', yAxis: 'right' }]
])
t.same((targetGroupWidget.properties as MetricWidgetProperties).metrics, [
['AWS/ApplicationELB', 'HTTPCode_Target_5XX_Count', 'LoadBalancer', '${alb.LoadBalancerFullName}', 'TargetGroup', '${AlbEventAlbTargetGrouphttpListener.TargetGroupFullName}', { stat: 'ts99', yAxis: 'right' }],
['AWS/ApplicationELB', 'LambdaInternalError', 'LoadBalancer', '${alb.LoadBalancerFullName}', 'TargetGroup', '${AlbEventAlbTargetGrouphttpListener.TargetGroupFullName}', { stat: 'P99', yAxis: 'left' }]
])

for (const widget of widgets) {
const props: MetricWidgetProperties = widget.properties as MetricWidgetProperties
t.ok((props.metrics?.length ?? 0) > 0)
t.equal(props.period, 300)
t.equal(props.view, 'timeSeries')
}

t.end()
})

t.end()
})
24 changes: 24 additions & 0 deletions core/dashboards/tests/dashboard-dynamodb.test.ts
@@ -1,6 +1,7 @@
import { merge } from 'lodash'
import { test } from 'tap'
import { type MetricWidgetProperties } from 'cloudwatch-dashboard-types'
import { type DynamoDB } from 'cloudform'

import { type ResourceType } from '../../cf-template'
import addDashboard from '../dashboard'
Expand Down Expand Up @@ -51,6 +52,29 @@ test('dashboard contains configured DynamoDB resources', (t) => {
t.end()
})

t.test('dashboards includes DynamoDB metrics without GSIs', (t) => {
const template = createTestCloudFormationTemplate()
delete ((template.Resources as ResourceType).dataTable as DynamoDB.Table).Properties.GlobalSecondaryIndexes
addDashboard(defaultConfig.dashboard, template)
const { dashboard } = getDashboardFromTemplate(template)

const widgets = getDashboardWidgetsByTitle(dashboard,
/ReadThrottleEvents Table /,
/ReadThrottleEvents GSI GSI1 in /,
/WriteThrottleEvents Table /,
/WriteThrottleEvents GSI GSI1 in /
)

const [
readThrottlesWidget, readThrottlesGsiWidget, writeThrottlesWidget, writeThrottlesGsiWidget
] = widgets
t.ok(readThrottlesWidget)
t.notOk(readThrottlesGsiWidget)
t.ok(writeThrottlesWidget)
t.notOk(writeThrottlesGsiWidget)
t.end()
})

t.test('service config overrides take precedence', (t) => {
const template = createTestCloudFormationTemplate()

Expand Down

0 comments on commit 971e40a

Please sign in to comment.