Documentation ¶
Index ¶
- Constants
- Variables
- func DiffJSON(t *testing.T, src []byte, dst []byte) error
- func GenTestSQSEvent() awsevents.SQSEvent
- func GetSlackMessageChannel() <-chan []byte
- func SendSlackMessage(rw http.ResponseWriter, r *http.Request)
- func SetS3ReceiveChannel(ch chan []byte, quit chan bool)
- type MockCWClient
- type MockPDClient
- type MockRetryer
- type MockS3Client
- type MockSSMClient
Constants ¶
const (
// SlackTokenSSMKey is a test SSM parameter store key
SlackTokenSSMKey = "/service/cw_alert_router/slack/app/oauth/auth_token"
)
Variables ¶
var ( // TestEventJSONFromSQS - a test event as seen from eventbridge -> SQS -> lambda TestEventJSONFromSQS = "" /* 1899-byte string literal not displayed */ // TestEventJSON provides a test cw alarm eventbridge event TestEventJSON = `` /* 1596-byte string literal not displayed */ TestSuppressPagerDuty = cw.AlarmEventDetail{ AlarmName: "arn:aws:cloudwatch:us-east-1:1234567890123:alarm:test-service-alarm-abcd", State: cw.AlarmState{ Value: "ALARM", Timestamp: "2022-09-29T22:10:04.692+0000", ReasonData: "{\\\"version\\\":\\\"1.0\\\",\\\"queryDate\\\":\\\"2022-09-29T22:10:04.689+0000\\\",\\\"startDate\\\":\\\"2022-09-29T21:40:00.000+0000\\\",\\\"statistic\\\":\\\"Sum\\\",\\\"period\\\":300,\\\"recentDatapoints\\\":[0.0,0.0,0.0,0.0,0.0,0.0],\\\"threshold\\\":0.0,\\\"evaluatedDatapoints\\\":[{\\\"timestamp\\\":\\\"2022-09-29T22:05:00.000+0000\\\",\\\"sampleCount\\\":5.0,\\\"value\\\":0.0},{\\\"timestamp\\\":\\\"2022-09-29T22:00:00.000+0000\\\",\\\"sampleCount\\\":5.0,\\\"value\\\":0.0},{\\\"timestamp\\\":\\\"2022-09-29T21:55:00.000+0000\\\",\\\"sampleCount\\\":5.0,\\\"value\\\":0.0},{\\\"timestamp\\\":\\\"2022-09-29T21:50:00.000+0000\\\",\\\"sampleCount\\\":5.0,\\\"value\\\":0.0},{\\\"timestamp\\\":\\\"2022-09-29T21:45:00.000+0000\\\",\\\"sampleCount\\\":5.0,\\\"value\\\":0.0},{\\\"timestamp\\\":\\\"2022-09-29T21:40:00.000+0000\\\",\\\"sampleCount\\\":5.0,\\\"value\\\":0.0}]}", Reason: "Threshold Crossed: 6 datapoints were less than or equal to the threshold (0.0). The most recent datapoints which crossed the threshold: [0.0 (29/09/22 22:05:00), 0.0 (29/09/22 22:00:00), 0.0 (29/09/22 21:55:00), 0.0 (29/09/22 21:50:00), 0.0 (29/09/22 21:45:00)].", }, PreviousState: cw.AlarmState{ Value: "OK", Timestamp: "2022-08-29T13:09:04.688+0000", ReasonData: "{\\\"version\\\":\\\"1.0\\\",\\\"queryDate\\\":\\\"2022-08-29T13:09:04.685+0000\\\",\\\"startDate\\\":\\\"2022-08-29T12:39:00.000+0000\\\",\\\"statistic\\\":\\\"Sum\\\",\\\"period\\\":300,\\\"recentDatapoints\\\":[0.0,0.0,0.0,0.0,0.0,9.0],\\\"threshold\\\":0.0,\\\"evaluatedDatapoints\\\":[{\\\"timestamp\\\":\\\"2022-08-29T13:04:00.000+0000\\\",\\\"sampleCount\\\":14.0,\\\"value\\\":9.0}]}", Reason: "Threshold Crossed: 1 datapoint [9.0 (29/08/22 13:04:00)] was not less than or equal to the threshold (0.0).", }, Tags: cw.AlarmTags{ "Env": "test", "alerts:suppress_pagerduty": "true", "service": "test-service", "owner": "test", }, Configuration: cw.AlarmConfiguration{ Metrics: []cw.AlarmMetric{ { ReturnData: true, ID: "76bafab0-8d7b-65d4-ad90-808e4af8f7dd", MetricStat: cw.AlarmMetricStat{ Stat: "Sum", Period: 300, Metric: cw.AlarmMetricDetail{ Namespace: "AWS/SQS", Name: "NumberOfEmptyReceives", Dimensions: map[string]string{ "QueueName": "testQueue.fifo", }, }, }, }, }, }, } // TestOKAlarm is just a test cloudwatch alarm used for various tests (in the OK state) TestOKAlarm = cw.AlarmEventDetail{ AlarmName: "test-service-alarm-abcd", State: cw.AlarmState{ Value: "OK", Timestamp: "2020-07-31T06:56:05.606+0000", ReasonData: "{\"version\":\"1.0\",\"queryDate\":\"2020-07-31T06:56:05.603+0000\",\"startDate\":\"2020-07-31T06:50:00.000+0000\",\"statistic\":\"Average\",\"period\":60,\"recentDatapoints\":[0.2872183414376726],\"threshold\":60.0}", Reason: "Threshold Crossed: 1 datapoint [0.2872183414376726 (31/07/20 06:50:00)] was not greater than the threshold (60.0).", }, PreviousState: cw.AlarmState{ Value: "INSUFFICIENT_DATA", Timestamp: "2020-07-31T06:52:05.601+0000", ReasonData: "{\"version\":\"1.0\",\"queryDate\":\"2020-07-31T06:52:05.598+0000\",\"statistic\":\"Average\",\"period\":60,\"recentDatapoints\":[],\"threshold\":60.0}", Reason: "Insufficient Data: 1 datapoint was unknown.", }, Configuration: cw.AlarmConfiguration{ Metrics: []cw.AlarmMetric{ { ReturnData: true, ID: "beb9cf5d-585d-3d43-179b-1e0898d8e237", MetricStat: cw.AlarmMetricStat{ Stat: "Average", Period: 60, Metric: cw.AlarmMetricDetail{ Namespace: "AWS/EC2", Name: "CPUUtilization", Dimensions: map[string]string{ "AutoScalingGroupName": "test-service", }, }, }, }, }, }, } // TestNoDataToOKAlarm is for testing with an alarm that just transitioned to OK from INSUFFICIENT_DATA TestNoDataToOKAlarm = cw.AlarmEventDetail{ AlarmName: "test-123-alarm-aabe21de-1236-4742-bf18-34b1c3b2682a", State: cw.AlarmState{ Value: "OK", Timestamp: "2020-11-11T06:56:05.606+0000", ReasonData: "{\"version\":\"1.0\",\"queryDate\":\"2020-11-11T06:56:05.603+0000\",\"startDate\":\"2020-11-11T06:50:00.000+0000\",\"statistic\":\"Average\",\"period\":60,\"recentDatapoints\":[0.2872183414376726],\"threshold\":60.0}", Reason: "Threshold Crossed: 1 datapoint [200.0 (11/11/20 06:50:00)] was greater than the threshold (60.0).", }, PreviousState: cw.AlarmState{ Value: "INSUFFICIENT_DATA", Timestamp: "2020-11-11T06:52:05.601+0000", ReasonData: "{\"version\":\"1.0\",\"queryDate\":\"2020-11-11T06:52:05.598+0000\",\"statistic\":\"Average\",\"period\":60,\"recentDatapoints\":[],\"threshold\":60.0}", Reason: "Insufficient Data: 1 datapoint was unknown.", }, Configuration: cw.AlarmConfiguration{ Metrics: []cw.AlarmMetric{ { ReturnData: true, ID: "1eb9cf5d-a85d-3d43-179c-1e0898d8e237", MetricStat: cw.AlarmMetricStat{ Stat: "Average", Period: 60, Metric: cw.AlarmMetricDetail{ Namespace: "AWS/EC2", Name: "CPUUtilization", Dimensions: map[string]string{ "AutoScalingGroupName": "test-123", }, }, }, }, }, }, } // TestTriggeredAlarm is just a test cloudwatch alarm used for various tests (in the OK state) TestTriggeredAlarm = cw.AlarmEventDetail{ AlarmName: "test-service-alarm-abcd", State: cw.AlarmState{ Value: "ALARM", Timestamp: "2020-07-31T06:56:05.606+0000", ReasonData: "{\"version\":\"1.0\",\"queryDate\":\"2020-07-31T06:56:05.603+0000\",\"startDate\":\"2020-07-31T06:50:00.000+0000\",\"statistic\":\"Average\",\"period\":60,\"recentDatapoints\":[0.2872183414376726],\"threshold\":60.0}", Reason: "Threshold Crossed: 1 datapoint [200.0 (31/07/20 06:50:00)] was greater than the threshold (60.0).", }, PreviousState: cw.AlarmState{ Value: "INSUFFICIENT_DATA", Timestamp: "2020-07-31T06:52:05.601+0000", ReasonData: "{\"version\":\"1.0\",\"queryDate\":\"2020-07-31T06:52:05.598+0000\",\"statistic\":\"Average\",\"period\":60,\"recentDatapoints\":[],\"threshold\":60.0}", Reason: "Insufficient Data: 1 datapoint was unknown.", }, Configuration: cw.AlarmConfiguration{ Metrics: []cw.AlarmMetric{ { ReturnData: true, ID: "beb9cf5d-585d-3d43-179b-1e0898d8e237", MetricStat: cw.AlarmMetricStat{ Stat: "Average", Period: 60, Metric: cw.AlarmMetricDetail{ Namespace: "AWS/EC2", Name: "CPUUtilization", Dimensions: map[string]string{ "AutoScalingGroupName": "test-service", }, }, }, }, }, }, } // ExpectedAlarmDetails is the parsed struct of the above JSON ExpectedAlarmDetails = cw.EventDetails{ Account: "1234567890123", Version: "0", Time: "2020-07-31T06:56:05Z", Source: "aws.cloudwatch", Resources: []string{ "arn:aws:cloudwatch:us-east-1:1234567890123:alarm:test-service-alarm-abcd", }, Region: "us-east-1", ID: "1ebd31a7-11e5-b52a-03e4-be4110b0f1e0", DetailType: "CloudWatch Alarm State Change", Detail: TestOKAlarm, } // TriggeredAlarmDetails is a sample CW alarm in ALARM state TriggeredAlarmDetails = cw.EventDetails{ Account: "1234567890123", Version: "0", Time: "2020-07-31T06:56:05Z", Source: "aws.cloudwatch", Resources: []string{ "arn:aws:cloudwatch:us-east-1:1234567890123:alarm:test-service-alarm-abcd", }, Region: "us-east-1", ID: "1ebd31a7-11e5-b52a-03e4-be4110b0f1e0", DetailType: "CloudWatch Alarm State Change", Detail: TestTriggeredAlarm, } // InsufficientDataToOKAlarmDetails is for testing insufficient data -> ok alarm InsufficientDataToOKAlarmDetails = cw.EventDetails{ Account: "1234567890123456", Version: "0", Time: "2020-11-11T06:56:05Z", Source: "aws.cloudwatch", Resources: []string{ "arn:aws:cloudwatch:us-east-1:1234567890123:alarm:test-service-alarm-abcd", }, Region: "us-east-1", ID: "1ebd31a7-11e5-b52a-03e4-be4110b0f1e0", DetailType: "CloudWatch Alarm State Change", Detail: TestNoDataToOKAlarm, } // SuppressPagerDutyTrue is for testing events with disabled PD alerts SuppressPagerDutyTrue = cw.EventDetails{ Account: "1234567890123", Version: "0", Time: "2022-09-29T22:10:04Z", Source: "aws.cloudwatch", Resources: []string{ "arn:aws:cloudwatch:us-east-1:1234567890123:alarm:test-service-alarm-abcd", }, Region: "us-east-1", ID: "0cd5bdb7-df8b-f066-50c5-cc06faac60c2", DetailType: "CloudWatch Alarm State Change", Detail: TestSuppressPagerDuty, } // GetMetricDataResponses provides some test GetMetricData api responses map key is the MetricDataQuery.Id GetMetricDataResponses = map[string]*cloudwatch.GetMetricDataOutput{ "m0": { MetricDataResults: []*cloudwatch.MetricDataResult{ { Id: aws.String("m0"), Timestamps: []*time.Time{ aws.Time(time.Date(2020, time.October, 30, 15, 0, 0, 0, time.UTC)), aws.Time(time.Date(2020, time.October, 30, 15, 5, 0, 0, time.UTC)), aws.Time(time.Date(2020, time.October, 30, 15, 10, 0, 0, time.UTC)), aws.Time(time.Date(2020, time.October, 30, 15, 15, 0, 0, time.UTC)), aws.Time(time.Date(2020, time.October, 30, 15, 20, 0, 0, time.UTC)), aws.Time(time.Date(2020, time.October, 30, 15, 25, 0, 0, time.UTC)), }, Values: []*float64{ aws.Float64(15.0), aws.Float64(3.0), aws.Float64(11.0), aws.Float64(9.0), aws.Float64(17.0), aws.Float64(15.0), }, }, }, }, } )
var ( // TestGetParametersByPathResponse defines some test responses for get parameters by path TestSSMGetParametersByPathResponse = map[string]*ssm.GetParametersByPathOutput{ "/service/cw_alert_router/pagerduty/routing_keys/shared_key": { Parameters: []*ssm.Parameter{ { Value: aws.String("shared-key-test-string"), }, }, }, "/service/cw_alert_router/pagerduty/routing_keys/test_service": { Parameters: []*ssm.Parameter{ { Value: aws.String("pagerduty-key-1"), }, }, }, } // TestGetParameterResponse defines some test reponses for get parameter TestSSMGetParameterResponse = map[string]*ssm.GetParameterOutput{ "/service/cw_alert_router/pagerduty/routing_keys/test_service": { Parameter: &ssm.Parameter{ Value: aws.String("pagerduty-key-1"), }, }, "/service/cw_alert_router/pagerduty/routing_keys/shared_key": { Parameter: &ssm.Parameter{ Value: aws.String("shared-key-test-string"), }, }, SlackTokenSSMKey: { Parameter: &ssm.Parameter{ Value: aws.String("abc123"), }, }, } )
Functions ¶
func GenTestSQSEvent ¶
func GetSlackMessageChannel ¶
func GetSlackMessageChannel() <-chan []byte
GetSlackMessageChannel allows hooking into the SendSlackMessage callback (to inspect messages)
func SendSlackMessage ¶
func SendSlackMessage(rw http.ResponseWriter, r *http.Request)
SendSlackMessage is for sending a test slack message (should have started a test server that listens to /chat.PostMessage - see slack_test.go)
func SetS3ReceiveChannel ¶
SetS3ReceiveChannel sets up a channel so we can tap into s3 object puts to just make sure we're writing what we think we are
Types ¶
type MockCWClient ¶
type MockCWClient struct {
cloudwatchiface.CloudWatchAPI
}
MockCWClient is a mock Cloudwatch client for testing
func (*MockCWClient) GetMetricData ¶
func (m *MockCWClient) GetMetricData(r *cloudwatch.GetMetricDataInput) (*cloudwatch.GetMetricDataOutput, error)
GetMetricData implements the same fn in cloudwatch
func (*MockCWClient) ListTagsForResource ¶
func (m *MockCWClient) ListTagsForResource(r *cloudwatch.ListTagsForResourceInput) (*cloudwatch.ListTagsForResourceOutput, error)
ListTagsForResource attempts to implement the list tags api call
type MockPDClient ¶
type MockPDClient struct{}
MockPDClient is a mock PagerDuty (our own) client
func (*MockPDClient) ManageEvent ¶
func (p *MockPDClient) ManageEvent(e pdapi.V2Event) (*pdapi.V2EventResponse, error)
ManageEvent - implement the same event from the pagerduty library
type MockRetryer ¶
type MockRetryer struct{}
MockRetryer is the request.Retryer to use in our fake requests
func (MockRetryer) MaxRetries ¶
func (mr MockRetryer) MaxRetries() int
MaxRetries implements said fn
func (MockRetryer) RetryRules ¶
func (mr MockRetryer) RetryRules(r *request.Request) time.Duration
RetryRules implements said fn
func (MockRetryer) ShouldRetry ¶
func (mr MockRetryer) ShouldRetry(r *request.Request) bool
ShouldRetry implements said fn
type MockS3Client ¶
MockS3Client is a mock S3 client for testing
func (*MockS3Client) GetObjectRequest ¶
func (m *MockS3Client) GetObjectRequest(req *s3.GetObjectInput) (*request.Request, *s3.GetObjectOutput)
GetObjectRequest implements that guy
func (*MockS3Client) PutObject ¶
func (m *MockS3Client) PutObject(req *s3.PutObjectInput) (*s3.PutObjectOutput, error)
PutObject implements the said function for the s3 client
type MockSSMClient ¶
MockSSMClient is a mock SSM client for testing
func (*MockSSMClient) GetParameter ¶
func (m *MockSSMClient) GetParameter(req *ssm.GetParameterInput) (*ssm.GetParameterOutput, error)
GetParameter implements the same function from ssm
func (*MockSSMClient) GetParametersByPath ¶
func (m *MockSSMClient) GetParametersByPath(req *ssm.GetParametersByPathInput) (*ssm.GetParametersByPathOutput, error)
GetParametersByPath implements the said function for the ssm client