package alerts

import (
	"testing"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/cloudwatch"
	"github.com/aws/aws-sdk-go/service/cloudwatch/cloudwatchiface"
	"github.com/aws/aws-sdk-go/service/rds"
	"github.com/aws/aws-sdk-go/service/sns"
	"github.com/aws/aws-sdk-go/service/sns/snsiface"
	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"
)

type SNSMock struct {
	mock.Mock
	snsiface.SNSAPI
}

func (c SNSMock) ListTopics(input *sns.ListTopicsInput) (*sns.ListTopicsOutput, error) {
	retVal := c.Called(input)
	return retVal.Get(0).(*sns.ListTopicsOutput), retVal.Error(1)
}

func (c SNSMock) ListTopicsPages(input *sns.ListTopicsInput, fn func(p *sns.ListTopicsOutput, lastPage bool) (shouldContinue bool)) error {
	input.NextToken = nil

	for {
		resp, err := c.ListTopics(input)
		if err != nil {
			return err
		}

		if !fn(resp, resp.NextToken != nil) || resp.NextToken == nil {
			return nil
		}

		input.NextToken = resp.NextToken
	}
}

func (c CloudWatchMock) DescribeAlarms(input *cloudwatch.DescribeAlarmsInput) (*cloudwatch.DescribeAlarmsOutput, error) {
	retVal := c.Called(input)
	return retVal.Get(0).(*cloudwatch.DescribeAlarmsOutput), retVal.Error(1)
}

func (c CloudWatchMock) DescribeAlarmsPages(input *cloudwatch.DescribeAlarmsInput, fn func(p *cloudwatch.DescribeAlarmsOutput, lastPage bool) (shouldContinue bool)) error {
	input.NextToken = nil
	input.MaxRecords = aws.Int64(100)

	for {
		resp, err := c.DescribeAlarms(input)
		if err != nil {
			return err
		}

		if !fn(resp, resp.NextToken != nil) || resp.NextToken == nil {
			return nil
		}

		input.NextToken = resp.NextToken
	}
}

func (c CloudWatchMock) DeleteAlarms(input *cloudwatch.DeleteAlarmsInput) (*cloudwatch.DeleteAlarmsOutput, error) {
	retVal := c.Called(input)
	return retVal.Get(0).(*cloudwatch.DeleteAlarmsOutput), retVal.Error(1)
}

func (c CloudWatchMock) PutMetricAlarm(input *cloudwatch.PutMetricAlarmInput) (*cloudwatch.PutMetricAlarmOutput, error) {
	retVal := c.Called(input)
	return retVal.Get(0).(*cloudwatch.PutMetricAlarmOutput), retVal.Error(1)
}

type CloudWatchMock struct {
	mock.Mock
	cloudwatchiface.CloudWatchAPI
}

func getInstances() map[string]*rds.DBInstance {
	return map[string]*rds.DBInstance{
		"test-instance-1": makeInstance("test-instance-1", "db.t1.micro", 10, nil),
		"test-instance-2": makeInstance("test-instance-2", "db.r3.8xlarge", 250, aws.Int64(2500)),
	}
}

func getInstancePriorities() map[string]AlarmPriority {
	return map[string]AlarmPriority{
		"test-instance-1": VerboseAlarms,
		"test-instance-2": VerboseAlarms,
	}
}

func getAlarmInput(expectedAlertArn string, expectedAlarmName string, expectedAlarmDesc string, expectedIdentifier string,
	expectedComparisonOperator string, period int64, evaluationPeriods int64, metricName string, statistic *string, extendedStatistic *string,
	threshold float64) *cloudwatch.PutMetricAlarmInput {

	return &cloudwatch.PutMetricAlarmInput{
		ActionsEnabled: aws.Bool(true),
		AlarmActions: []*string{
			aws.String(expectedAlertArn),
		},
		AlarmDescription:   aws.String(expectedAlarmDesc),
		AlarmName:          aws.String(expectedAlarmName),
		ComparisonOperator: aws.String(expectedComparisonOperator),
		Dimensions: []*cloudwatch.Dimension{
			&cloudwatch.Dimension{
				Name:  aws.String("DBInstanceIdentifier"),
				Value: aws.String(expectedIdentifier),
			},
		},
		EvaluationPeriods: aws.Int64(evaluationPeriods),
		ExtendedStatistic: extendedStatistic,
		MetricName:        aws.String(metricName),
		Namespace:         aws.String("AWS/RDS"),
		OKActions: []*string{
			aws.String(expectedAlertArn),
		},
		Period:    aws.Int64(period),
		Statistic: statistic,
		Threshold: aws.Float64(threshold),
	}
}

func getAlarm(expectedAlertArn string, expectedAlarmName string, expectedAlarmDesc string, expectedIdentifier string,
	expectedComparisonOperator string, period int64, evaluationPeriods int64, metricName string, statistic *string, extendedStatistic *string,
	threshold float64) *cloudwatch.MetricAlarm {

	return &cloudwatch.MetricAlarm{
		ActionsEnabled: aws.Bool(true),
		AlarmActions: []*string{
			aws.String(expectedAlertArn),
		},
		AlarmDescription:   aws.String(expectedAlarmDesc),
		AlarmName:          aws.String(expectedAlarmName),
		ComparisonOperator: aws.String(expectedComparisonOperator),
		Dimensions: []*cloudwatch.Dimension{
			&cloudwatch.Dimension{
				Name:  aws.String("DBInstanceIdentifier"),
				Value: aws.String(expectedIdentifier),
			},
		},
		EvaluationPeriods: aws.Int64(evaluationPeriods),
		ExtendedStatistic: extendedStatistic,
		MetricName:        aws.String(metricName),
		Namespace:         aws.String("AWS/RDS"),
		OKActions: []*string{
			aws.String(expectedAlertArn),
		},
		Period:    aws.Int64(period),
		Statistic: statistic,
		Threshold: aws.Float64(threshold),
	}
}

func TestConfigureAlarmsNoTopic(t *testing.T) {
	instances := getInstances()
	instancePriorities := getInstancePriorities()

	snsClient := SNSMock{}
	snsClient.On("ListTopics", &sns.ListTopicsInput{}).Return(&sns.ListTopicsOutput{
		Topics: []*sns.Topic{},
	}, nil)

	cwClient := CloudWatchMock{}

	err := ConfigureAlarms(snsClient, cwClient, "data-eng", instancePriorities, instances)
	require.NotNil(t, err)
	require.Equal(t, "Could not find any ARN containing `:rds-buddy-data-eng-cloudwatch-alarms` - have the alerting artifacts been provisioned?", err.Error())

	snsClient.AssertExpectations(t)
	cwClient.AssertExpectations(t)
}

func TestConfigureAlarmsNoGoodTopic(t *testing.T) {
	instances := getInstances()
	instancePriorities := getInstancePriorities()

	snsClient := SNSMock{}
	snsClient.On("ListTopics", &sns.ListTopicsInput{}).Return(&sns.ListTopicsOutput{
		Topics: []*sns.Topic{
			&sns.Topic{
				TopicArn: aws.String("wow:rds-buddy-data-nope-cloudwatch-alarms:wrong"),
			},
			&sns.Topic{
				TopicArn: aws.String("alsowrong:rds-buddy-another-team-cloudwatch-alarms"),
			},
		},
	}, nil)

	cwClient := CloudWatchMock{}

	err := ConfigureAlarms(snsClient, cwClient, "data-eng", instancePriorities, instances)
	require.NotNil(t, err)
	require.Equal(t, "Could not find any ARN containing `:rds-buddy-data-eng-cloudwatch-alarms` - have the alerting artifacts been provisioned?", err.Error())

	snsClient.AssertExpectations(t)
	cwClient.AssertExpectations(t)
}

func TestConfigureAlarmsNoneExist(t *testing.T) {
	instances := getInstances()
	instancePriorities := getInstancePriorities()

	snsClient := SNSMock{}
	snsClient.On("ListTopics", &sns.ListTopicsInput{}).Return(&sns.ListTopicsOutput{
		Topics: []*sns.Topic{
			&sns.Topic{
				TopicArn: aws.String("wow:rds-buddy-data-eng-cloudwatch-alarms"),
			},
		},
	}, nil)

	cwClient := CloudWatchMock{}
	cwClient.On("DescribeAlarms", &cloudwatch.DescribeAlarmsInput{
		AlarmNamePrefix: aws.String("rds-buddy-data-eng"),
		MaxRecords:      aws.Int64(100),
	}).Return(&cloudwatch.DescribeAlarmsOutput{
		MetricAlarms: []*cloudwatch.MetricAlarm{},
	}, nil)

	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-1",
		"Over 80% CPU utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-1",
		"Over 5 minutes replica lag for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-1",
		"Over 80% connection utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(615)*(float64(4)/float64(150)))).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-1",
		"Over 80% read IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 24)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-1",
		"Over 80% write IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 24)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-1",
		"Less than 20% available RAM for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 123)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-1",
		"80% Queue Depth Saturation for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 4)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-1",
		"Over 200ms p99 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-1",
		"Over 75ms p90 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-1",
		"Over 200ms p99 ReadLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp90-test-instance-1",
		"Over 75ms p90 ReadLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p90"), 0.075)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)

	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-2",
		"Over 80% CPU utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-2",
		"Over 5 minutes replica lag for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-2",
		"Over 80% connection utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(244000)*(float64(4)/float64(150)))).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-2",
		"Over 80% read IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 2000)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-2",
		"Over 80% write IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 2000)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-2",
		"Less than 20% available RAM for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 48800)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-2",
		"80% Queue Depth Saturation for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 10)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-2",
		"Over 200ms p99 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-2",
		"Over 75ms p90 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-2",
		"Over 200ms p99 ReadLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp90-test-instance-2",
		"Over 75ms p90 ReadLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p90"), 0.075)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)

	err := ConfigureAlarms(snsClient, cwClient, "data-eng", instancePriorities, instances)
	require.Nil(t, err)

	snsClient.AssertExpectations(t)
	cwClient.AssertExpectations(t)
}

func TestConfigureAlarmsAllExist(t *testing.T) {
	instances := getInstances()
	instancePriorities := getInstancePriorities()

	snsClient := SNSMock{}
	snsClient.On("ListTopics", &sns.ListTopicsInput{}).Return(&sns.ListTopicsOutput{
		Topics: []*sns.Topic{
			&sns.Topic{
				TopicArn: aws.String("wow:rds-buddy-data-eng-cloudwatch-alarms"),
			},
		},
	}, nil)

	cwClient := CloudWatchMock{}
	cwClient.On("DescribeAlarms", &cloudwatch.DescribeAlarmsInput{
		AlarmNamePrefix: aws.String("rds-buddy-data-eng"),
		MaxRecords:      aws.Int64(100),
	}).Return(&cloudwatch.DescribeAlarmsOutput{
		MetricAlarms: []*cloudwatch.MetricAlarm{
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-1", "Over 80% CPU utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-1",
				"Over 5 minutes replica lag for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-1",
				"Over 80% connection utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(615)*(float64(4)/float64(150))),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-1",
				"Over 80% read IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 24),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-1",
				"Over 80% write IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 24),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-1",
				"Less than 20% available RAM for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 123),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-1",
				"80% Queue Depth Saturation for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 4),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-1",
				"Over 200ms p99 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-1",
				"Over 75ms p90 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-1",
				"Over 200ms p99 ReadLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp90-test-instance-1",
				"Over 75ms p90 ReadLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p90"), 0.075),

			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-2",
				"Over 80% CPU utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-2",
				"Over 5 minutes replica lag for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-2",
				"Over 80% connection utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(244000)*(float64(4)/float64(150))),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-2",
				"Over 80% read IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 2000),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-2",
				"Over 80% write IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 2000),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-2",
				"Less than 20% available RAM for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 48800),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-2",
				"80% Queue Depth Saturation for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 10),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-2",
				"Over 200ms p99 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-2",
				"Over 75ms p90 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-2",
				"Over 200ms p99 ReadLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp90-test-instance-2",
				"Over 75ms p90 ReadLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p90"), 0.075),
		},
	}, nil)

	err := ConfigureAlarms(snsClient, cwClient, "data-eng", instancePriorities, instances)
	require.Nil(t, err)

	snsClient.AssertExpectations(t)
	cwClient.AssertExpectations(t)
}

func TestConfigureExtraAlarmsExist(t *testing.T) {
	instances := getInstances()
	instancePriorities := getInstancePriorities()

	snsClient := SNSMock{}
	snsClient.On("ListTopics", &sns.ListTopicsInput{}).Return(&sns.ListTopicsOutput{
		Topics: []*sns.Topic{
			&sns.Topic{
				TopicArn: aws.String("wow:rds-buddy-data-eng-cloudwatch-alarms"),
			},
		},
	}, nil)

	cwClient := CloudWatchMock{}
	cwClient.On("DescribeAlarms", &cloudwatch.DescribeAlarmsInput{
		AlarmNamePrefix: aws.String("rds-buddy-data-eng"),
		MaxRecords:      aws.Int64(100),
	}).Return(&cloudwatch.DescribeAlarmsOutput{
		MetricAlarms: []*cloudwatch.MetricAlarm{
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-1", "Over 80% CPU utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-1",
				"Over 5 minutes replica lag for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-1",
				"Over 80% connection utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(615)*(float64(4)/float64(150))),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-1",
				"Over 80% read IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 24),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-1",
				"Over 80% write IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 24),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-1",
				"Less than 20% available RAM for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 123),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-1",
				"80% Queue Depth Saturation for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 4),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-1",
				"Over 200ms p99 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-1",
				"Over 75ms p90 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-1",
				"Over 200ms p99 ReadLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp90-test-instance-1",
				"Over 75ms p90 ReadLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p90"), 0.075),

			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-2",
				"Over 80% CPU utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-2",
				"Over 5 minutes replica lag for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-2",
				"Over 80% connection utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(244000)*(float64(4)/float64(150))),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-2",
				"Over 80% read IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 2000),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-2",
				"Over 80% write IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 2000),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-2",
				"Less than 20% available RAM for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 48800),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-2",
				"80% Queue Depth Saturation for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 10),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-2",
				"Over 200ms p99 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-2",
				"Over 75ms p90 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-2",
				"Over 200ms p99 ReadLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp90-test-instance-2",
				"Over 75ms p90 ReadLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p90"), 0.075),

			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-SomeMetric-test-instance-1",
				"Over 80% CPU utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "SomeMetric", aws.String("Average"), nil, 0.8),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-SomeOtherMetric-test-instance-1",
				"Over 80% CPU utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "SomeOtherMetric", aws.String("Average"), nil, 0.8),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-SomeMetric-test-instance-2",
				"Over 80% CPU utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "SomeMetric", aws.String("Average"), nil, 0.8),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-SomeOtherMetric-test-instance-2",
				"Over 80% CPU utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "SomeOtherMetric", aws.String("Average"), nil, 0.8),
		},
	}, nil)

	cwClient.On("DeleteAlarms", &cloudwatch.DeleteAlarmsInput{
		AlarmNames: []*string{
			aws.String("rds-buddy-data-eng-SomeMetric-test-instance-1"),
			aws.String("rds-buddy-data-eng-SomeOtherMetric-test-instance-1"),
		},
	}).Return(&cloudwatch.DeleteAlarmsOutput{}, nil)

	cwClient.On("DeleteAlarms", &cloudwatch.DeleteAlarmsInput{
		AlarmNames: []*string{
			aws.String("rds-buddy-data-eng-SomeMetric-test-instance-2"),
			aws.String("rds-buddy-data-eng-SomeOtherMetric-test-instance-2"),
		},
	}).Return(&cloudwatch.DeleteAlarmsOutput{}, nil)

	err := ConfigureAlarms(snsClient, cwClient, "data-eng", instancePriorities, instances)
	require.Nil(t, err)

	snsClient.AssertExpectations(t)
	cwClient.AssertExpectations(t)
}

func TestConfigureExtraHostsExist(t *testing.T) {
	instances := getInstances()
	instancePriorities := getInstancePriorities()

	snsClient := SNSMock{}
	snsClient.On("ListTopics", &sns.ListTopicsInput{}).Return(&sns.ListTopicsOutput{
		Topics: []*sns.Topic{
			&sns.Topic{
				TopicArn: aws.String("wow:rds-buddy-data-eng-cloudwatch-alarms"),
			},
		},
	}, nil)

	cwClient := CloudWatchMock{}
	cwClient.On("DescribeAlarms", &cloudwatch.DescribeAlarmsInput{
		AlarmNamePrefix: aws.String("rds-buddy-data-eng"),
		MaxRecords:      aws.Int64(100),
	}).Return(&cloudwatch.DescribeAlarmsOutput{
		MetricAlarms: []*cloudwatch.MetricAlarm{
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-1", "Over 80% CPU utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-1",
				"Over 5 minutes replica lag for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-1",
				"Over 80% connection utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(615)*(float64(4)/float64(150))),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-1",
				"Over 80% read IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 24),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-1",
				"Over 80% write IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 24),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-1",
				"Less than 20% available RAM for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 123),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-1",
				"80% Queue Depth Saturation for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 4),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-1",
				"Over 200ms p99 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-1",
				"Over 75ms p90 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-1",
				"Over 200ms p99 ReadLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp90-test-instance-1",
				"Over 75ms p90 ReadLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p90"), 0.075),

			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-2",
				"Over 80% CPU utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-2",
				"Over 5 minutes replica lag for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-2",
				"Over 80% connection utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(244000)*(float64(4)/float64(150))),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-2",
				"Over 80% read IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 2000),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-2",
				"Over 80% write IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 2000),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-2",
				"Less than 20% available RAM for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 48800),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-2",
				"80% Queue Depth Saturation for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 10),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-2",
				"Over 200ms p99 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-2",
				"Over 75ms p90 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-2",
				"Over 200ms p99 ReadLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp90-test-instance-2",
				"Over 75ms p90 ReadLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p90"), 0.075),

			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-3",
				"Over 80% CPU utilization for test-instance-3", "test-instance-3", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-3",
				"Over 5 minutes replica lag for test-instance-3", "test-instance-3", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-3",
				"Over 80% connection utilization for test-instance-3", "test-instance-3", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(244000)*(float64(4)/float64(150))),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-3",
				"Over 80% read IOPS utilization for test-instance-3", "test-instance-3", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 2000),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-3",
				"Over 80% write IOPS utilization for test-instance-3", "test-instance-3", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 2000),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-3",
				"Less than 20% available RAM for test-instance-3", "test-instance-3", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 48800),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-3",
				"80% Queue Depth Saturation for test-instance-3", "test-instance-3", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 10),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-3",
				"Over 200ms p99 WriteLatency for test-instance-3", "test-instance-3", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-3",
				"Over 75ms p90 WriteLatency for test-instance-3", "test-instance-3", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-3",
				"Over 200ms p99 ReadLatency for test-instance-3", "test-instance-3", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp90-test-instance-3",
				"Over 75ms p90 ReadLatency for test-instance-3", "test-instance-3", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p90"), 0.075),
		},
	}, nil)

	cwClient.On("DeleteAlarms", &cloudwatch.DeleteAlarmsInput{
		AlarmNames: []*string{
			aws.String("rds-buddy-data-eng-CPUUtilization-test-instance-3"),
			aws.String("rds-buddy-data-eng-DatabaseConnections-test-instance-3"),
			aws.String("rds-buddy-data-eng-DiskQueueDepth-test-instance-3"),
			aws.String("rds-buddy-data-eng-FreeableMemory-test-instance-3"),
			aws.String("rds-buddy-data-eng-ReadIOPS-test-instance-3"),
			aws.String("rds-buddy-data-eng-ReadLatencyp90-test-instance-3"),
			aws.String("rds-buddy-data-eng-ReadLatencyp99-test-instance-3"),
			aws.String("rds-buddy-data-eng-ReplicaLag-test-instance-3"),
			aws.String("rds-buddy-data-eng-WriteIOPS-test-instance-3"),
			aws.String("rds-buddy-data-eng-WriteLatencyp90-test-instance-3"),
			aws.String("rds-buddy-data-eng-WriteLatencyp99-test-instance-3"),
		},
	}).Return(&cloudwatch.DeleteAlarmsOutput{}, nil)

	err := ConfigureAlarms(snsClient, cwClient, "data-eng", instancePriorities, instances)
	require.Nil(t, err)

	snsClient.AssertExpectations(t)
	cwClient.AssertExpectations(t)
}

func TestConfigureAlarmsSomeExist(t *testing.T) {
	instances := getInstances()
	instancePriorities := getInstancePriorities()

	snsClient := SNSMock{}
	snsClient.On("ListTopics", &sns.ListTopicsInput{}).Return(&sns.ListTopicsOutput{
		Topics: []*sns.Topic{
			&sns.Topic{
				TopicArn: aws.String("wow:rds-buddy-data-eng-cloudwatch-alarms"),
			},
		},
	}, nil)

	cwClient := CloudWatchMock{}
	cwClient.On("DescribeAlarms", &cloudwatch.DescribeAlarmsInput{
		AlarmNamePrefix: aws.String("rds-buddy-data-eng"),
		MaxRecords:      aws.Int64(100),
	}).Return(&cloudwatch.DescribeAlarmsOutput{
		MetricAlarms: []*cloudwatch.MetricAlarm{
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-1", "Over 80% CPU utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-1",
				"Over 5 minutes replica lag for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-1",
				"Over 80% connection utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(615)*(float64(4)/float64(150))),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-1",
				"Over 80% read IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 24),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-1",
				"Over 80% write IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 24),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-1",
				"Less than 20% available RAM for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 123),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-1",
				"80% Queue Depth Saturation for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 4),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-1",
				"Over 200ms p99 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-1",
				"Over 75ms p90 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-1",
				"Over 200ms p99 ReadLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2),

			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-2",
				"Over 80% CPU utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-2",
				"Over 5 minutes replica lag for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-2",
				"Over 80% connection utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(244000)*(float64(4)/float64(150))),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-2",
				"Over 80% read IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 2000),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-2",
				"Over 80% write IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 2000),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-2",
				"Less than 20% available RAM for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 48800),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-2",
				"80% Queue Depth Saturation for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 10),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-2",
				"Over 200ms p99 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-2",
				"Over 75ms p90 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075),
			getAlarm("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-2",
				"Over 200ms p99 ReadLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2),
		},
	}, nil)

	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-1",
		"Over 80% CPU utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-1",
		"Over 5 minutes replica lag for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-1",
		"Over 80% connection utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(615)*(float64(4)/float64(150)))).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-1",
		"Over 80% read IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 24)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-1",
		"Over 80% write IOPS utilization for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 24)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-1",
		"Less than 20% available RAM for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 123)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-1",
		"80% Queue Depth Saturation for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 4)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-1",
		"Over 200ms p99 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-1",
		"Over 75ms p90 WriteLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-1",
		"Over 200ms p99 ReadLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp90-test-instance-1",
		"Over 75ms p90 ReadLatency for test-instance-1", "test-instance-1", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p90"), 0.075)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)

	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-CPUUtilization-test-instance-2",
		"Over 80% CPU utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 5, "CPUUtilization", aws.String("Average"), nil, 80)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReplicaLag-test-instance-2",
		"Over 5 minutes replica lag for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReplicaLag", aws.String("Average"), nil, 301)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DatabaseConnections-test-instance-2",
		"Over 80% connection utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "DatabaseConnections", aws.String("Average"), nil, float64(244000)*(float64(4)/float64(150)))).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadIOPS-test-instance-2",
		"Over 80% read IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "ReadIOPS", aws.String("Average"), nil, 2000)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteIOPS-test-instance-2",
		"Over 80% write IOPS utilization for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanThreshold, 60, 3, "WriteIOPS", aws.String("Average"), nil, 2000)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-FreeableMemory-test-instance-2",
		"Less than 20% available RAM for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorLessThanThreshold, 60, 3, "FreeableMemory", aws.String("Average"), nil, 48800)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-DiskQueueDepth-test-instance-2",
		"80% Queue Depth Saturation for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "DiskQueueDepth", aws.String("Average"), nil, 10)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp99-test-instance-2",
		"Over 200ms p99 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p99"), 0.2)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-WriteLatencyp90-test-instance-2",
		"Over 75ms p90 WriteLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "WriteLatency", nil, aws.String("p90"), 0.075)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp99-test-instance-2",
		"Over 200ms p99 ReadLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p99"), 0.2)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)
	cwClient.On("PutMetricAlarm", getAlarmInput("wow:rds-buddy-data-eng-cloudwatch-alarms", "rds-buddy-data-eng-ReadLatencyp90-test-instance-2",
		"Over 75ms p90 ReadLatency for test-instance-2", "test-instance-2", cloudwatch.ComparisonOperatorGreaterThanOrEqualToThreshold, 60, 3, "ReadLatency", nil, aws.String("p90"), 0.075)).
		Return(&cloudwatch.PutMetricAlarmOutput{}, nil)

	err := ConfigureAlarms(snsClient, cwClient, "data-eng", instancePriorities, instances)
	require.Nil(t, err)

	snsClient.AssertExpectations(t)
	cwClient.AssertExpectations(t)
}
