diff --git a/moto/cloudwatch/exceptions.py b/moto/cloudwatch/exceptions.py index c7bfa29b5..4196cc994 100644 --- a/moto/cloudwatch/exceptions.py +++ b/moto/cloudwatch/exceptions.py @@ -15,6 +15,13 @@ class InvalidParameterValue(RESTError): super().__init__(__class__.__name__, message) +class InvalidParameterCombination(RESTError): + code = 400 + + def __init__(self, message): + super().__init__(__class__.__name__, message) + + class ResourceNotFound(RESTError): code = 404 diff --git a/moto/cloudwatch/responses.py b/moto/cloudwatch/responses.py index 4c5fd265f..778e533bf 100644 --- a/moto/cloudwatch/responses.py +++ b/moto/cloudwatch/responses.py @@ -5,6 +5,7 @@ from dateutil.parser import parse as dtparse from moto.core.responses import BaseResponse from moto.core.utils import amzn_request_id from .models import cloudwatch_backends, MetricDataQuery, MetricStat, Metric, Dimension +from .exceptions import InvalidParameterCombination class CloudWatchResponse(BaseResponse): @@ -187,9 +188,8 @@ class CloudWatchResponse(BaseResponse): unit = self._get_param("Unit") extended_statistics = self._get_param("ExtendedStatistics") - # TODO: this should instead throw InvalidParameterCombination if not statistics and not extended_statistics: - raise NotImplementedError( + raise InvalidParameterCombination( "Must specify either Statistics or ExtendedStatistics" ) diff --git a/tests/test_cloudwatch/test_cloudwatch_boto3.py b/tests/test_cloudwatch/test_cloudwatch_boto3.py index 35f4db783..ebe0eb495 100644 --- a/tests/test_cloudwatch/test_cloudwatch_boto3.py +++ b/tests/test_cloudwatch/test_cloudwatch_boto3.py @@ -105,6 +105,31 @@ def test_get_metric_statistics(): datapoint["Sum"].should.equal(1.5) +@mock_cloudwatch +def test_get_metric_invalid_parameter_combination(): + conn = boto3.client("cloudwatch", region_name="us-east-1") + utc_now = datetime.now(tz=pytz.utc) + + conn.put_metric_data( + Namespace="tester", + MetricData=[dict(MetricName="metric", Value=1.5, Timestamp=utc_now)], + ) + + with pytest.raises(ClientError) as exc: + # make request without both statistics or extended statistics parameters + conn.get_metric_statistics( + Namespace="tester", + MetricName="metric", + StartTime=utc_now - timedelta(seconds=60), + EndTime=utc_now + timedelta(seconds=60), + Period=60, + ) + + err = exc.value.response["Error"] + err["Code"].should.equal("InvalidParameterCombination") + err["Message"].should.equal("Must specify either Statistics or ExtendedStatistics") + + @mock_cloudwatch def test_get_metric_statistics_dimensions(): conn = boto3.client("cloudwatch", region_name="us-east-1")