internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: getmoto/moto

Issue:
KMS Decrypt response is missing KeyId
Self-explanatory.


Discussion:
KMS encrypt response is also missing KeyId

Resolving patch:
diff --git a/moto/kms/responses.py b/moto/kms/responses.py
--- a/moto/kms/responses.py
+++ b/moto/kms/responses.py
@@ -249,11 +249,11 @@ def encrypt(self):
         value = self.parameters.get("Plaintext")
         if isinstance(value, six.text_type):
             value = value.encode('utf-8')
-        return json.dumps({"CiphertextBlob": base64.b64encode(value).decode("utf-8")})
+        return json.dumps({"CiphertextBlob": base64.b64encode(value).decode("utf-8"), 'KeyId': 'key_id'})
 
     def decrypt(self):
         value = self.parameters.get("CiphertextBlob")
-        return json.dumps({"Plaintext": base64.b64decode(value).decode("utf-8")})
+        return json.dumps({"Plaintext": base64.b64decode(value).decode("utf-8"), 'KeyId': 'key_id'})
 
     def disable_key(self):
         key_id = self.parameters.get('KeyId')


Test patch:
diff --git a/tests/test_kms/test_kms.py b/tests/test_kms/test_kms.py
--- a/tests/test_kms/test_kms.py
+++ b/tests/test_kms/test_kms.py
@@ -171,6 +171,7 @@ def test_encrypt():
     conn = boto.kms.connect_to_region("us-west-2")
     response = conn.encrypt('key_id', 'encryptme'.encode('utf-8'))
     response['CiphertextBlob'].should.equal(b'ZW5jcnlwdG1l')
+    response['KeyId'].should.equal('key_id')
 
 
 @mock_kms_deprecated
@@ -178,6 +179,7 @@ def test_decrypt():
     conn = boto.kms.connect_to_region('us-west-2')
     response = conn.decrypt('ZW5jcnlwdG1l'.encode('utf-8'))
     response['Plaintext'].should.equal(b'encryptme')
+    response['KeyId'].should.equal('key_id')
 
 
 @mock_kms_deprecated
Repository: getmoto/moto

Issue:
DynamoDB2 Does not support DELETE on update_with_attribute_updates
If you use UpdateAttributes instead of UpdateExpressions, and try to DELETE from a set, it doesn't work and doesn't raise an exception. PR incoming.



Discussion:

Resolving patch:
diff --git a/moto/dynamodb2/models.py b/moto/dynamodb2/models.py
--- a/moto/dynamodb2/models.py
+++ b/moto/dynamodb2/models.py
@@ -294,6 +294,19 @@ def update_with_attribute_updates(self, attribute_updates):
                     # TODO: implement other data types
                     raise NotImplementedError(
                         'ADD not supported for %s' % ', '.join(update_action['Value'].keys()))
+            elif action == 'DELETE':
+                if set(update_action['Value'].keys()) == set(['SS']):
+                    existing = self.attrs.get(attribute_name, DynamoType({"SS": {}}))
+                    new_set = set(existing.value).difference(set(new_value))
+                    self.attrs[attribute_name] = DynamoType({
+                        "SS": list(new_set)
+                    })
+                else:
+                    raise NotImplementedError(
+                        'ADD not supported for %s' % ', '.join(update_action['Value'].keys()))
+            else:
+                raise NotImplementedError(
+                    '%s action not support for update_with_attribute_updates' % action)
 
 
 class StreamRecord(BaseModel):


Test patch:
diff --git a/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py b/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py
--- a/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py
+++ b/tests/test_dynamodb2/test_dynamodb_table_with_range_key.py
@@ -1344,6 +1344,34 @@ def test_update_item_add_value_string_set():
         'subject': '123',
     })
 
+@mock_dynamodb2
+def test_update_item_delete_value_string_set():
+    table = _create_table_with_range_key()
+
+    table.put_item(Item={
+        'forum_name': 'the-key',
+        'subject': '123',
+        'string_set': set(['str1', 'str2']),
+    })
+
+    item_key = {'forum_name': 'the-key', 'subject': '123'}
+    table.update_item(
+        Key=item_key,
+        AttributeUpdates={
+            'string_set': {
+                'Action': u'DELETE',
+                'Value': set(['str2']),
+            },
+        },
+    )
+
+    returned_item = dict((k, str(v) if isinstance(v, Decimal) else v)
+                         for k, v in table.get_item(Key=item_key)['Item'].items())
+    dict(returned_item).should.equal({
+        'string_set': set(['str1']),
+        'forum_name': 'the-key',
+        'subject': '123',
+    })
 
 @mock_dynamodb2
 def test_update_item_add_value_does_not_exist_is_created():
Repository: getmoto/moto

Issue:
IAM list_groups_for_user should return CreateDate
Hello, I am using moto version 1.3.8, boto3 1.9.161, and the iam function `list_groups_for_user` should return the CreateDate as [seen here](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/iam.html#IAM.Client.list_groups_for_user). 

Example Code missing the CreateDate in the response:
```python3
import boto3
import moto

@moto.mock_iam
def test_function():
    c = boto3.client('iam', region_name='us-east-1')
    c.create_group(Path='/', GroupName='TestGroup')
    c.create_user(UserName='TestUser')
    c.add_user_to_group(GroupName='TestGroup', UserName='TestUser')
    print(c.list_groups_for_user(UserName='TestUser'))

test_function()

{'Groups': [{'Path': '/', 'GroupName': 'TestGroup', 'GroupId': 'v9u2pby3t0xhhuiocj1c', 'Arn': 'arn:aws:iam::123456789012:group/TestGroup'}], 'IsTruncated': False, 'ResponseMetadata': {'RequestId': '7a62c49f-347e-4fc4-9331-6e8eEXAMPLE', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'amazon.com'}, 'RetryAttempts': 0}}
```


Discussion:

Resolving patch:
diff --git a/moto/iam/responses.py b/moto/iam/responses.py
--- a/moto/iam/responses.py
+++ b/moto/iam/responses.py
@@ -1349,6 +1349,7 @@ def untag_role(self):
             <GroupName>{{ group.name }}</GroupName>
             <GroupId>{{ group.id }}</GroupId>
             <Arn>{{ group.arn }}</Arn>
+            <CreateDate>{{ group.created_iso_8601 }}</CreateDate>
         </member>
         {% endfor %}
     </Groups>
@@ -1651,6 +1652,7 @@ def untag_role(self):
             <GroupName>{{ group.name }}</GroupName>
             <GroupId>{{ group.id }}</GroupId>
             <Arn>{{ group.arn }}</Arn>
+            <CreateDate>{{ group.created_iso_8601 }}</CreateDate>
         </member>
         {% endfor %}
     </Groups>


Test patch:
Repository: getmoto/moto

Issue:
RDS describe_db_instances missing InstanceCreateTime
Using `moto.mock_rds2()` and running the function `describe_db_instances()` I'm missing the `InstanceCreateTime` attribute from the returned response.


Discussion:
Thanks; setting as a feature request.

Resolving patch:
diff --git a/moto/rds2/models.py b/moto/rds2/models.py
--- a/moto/rds2/models.py
+++ b/moto/rds2/models.py
@@ -70,6 +70,7 @@ def __init__(self, **kwargs):
             self.port = Database.default_port(self.engine)
         self.db_instance_identifier = kwargs.get('db_instance_identifier')
         self.db_name = kwargs.get("db_name")
+        self.instance_create_time = iso_8601_datetime_with_milliseconds(datetime.datetime.now())
         self.publicly_accessible = kwargs.get("publicly_accessible")
         if self.publicly_accessible is None:
             self.publicly_accessible = True
@@ -148,6 +149,7 @@ def to_xml(self):
               <VpcSecurityGroups/>
               <DBInstanceIdentifier>{{ database.db_instance_identifier }}</DBInstanceIdentifier>
               <DbiResourceId>{{ database.dbi_resource_id }}</DbiResourceId>
+              <InstanceCreateTime>{{ database.instance_create_time }}</InstanceCreateTime>
               <PreferredBackupWindow>03:50-04:20</PreferredBackupWindow>
               <PreferredMaintenanceWindow>wed:06:38-wed:07:08</PreferredMaintenanceWindow>
               <ReadReplicaDBInstanceIdentifiers>
@@ -373,7 +375,7 @@ def to_json(self):
             "Address": "{{ database.address }}",
             "Port": "{{ database.port }}"
         },
-        "InstanceCreateTime": null,
+        "InstanceCreateTime": "{{ database.instance_create_time }}",
         "Iops": null,
         "ReadReplicaDBInstanceIdentifiers": [{%- for replica in database.replicas -%}
             {%- if not loop.first -%},{%- endif -%}


Test patch:
diff --git a/tests/test_rds2/test_rds2.py b/tests/test_rds2/test_rds2.py
--- a/tests/test_rds2/test_rds2.py
+++ b/tests/test_rds2/test_rds2.py
@@ -34,6 +34,7 @@ def test_create_database():
     db_instance['IAMDatabaseAuthenticationEnabled'].should.equal(False)
     db_instance['DbiResourceId'].should.contain("db-")
     db_instance['CopyTagsToSnapshot'].should.equal(False)
+    db_instance['InstanceCreateTime'].should.be.a("datetime.datetime")
 
 
 @mock_rds2
Repository: getmoto/moto

Issue:
DynamoDB query validation fails queries with leading newlines
This query:

```
q = """
            SET
            Metadata.subscription.event_history = list_append(
                if_not_exists(Metadata.subscription.event_history, :empty_list),
                :new_event_tuple),
            UpdatedOn = :timestamp,
            UpdatedBy = :appid
        """
```

works in DynamoDB, but not in Moto.  The relevant line in Moto that invalidates this query is https://github.com/spulec/moto/blob/c8b94b6e9fd170363a73d8804db33fb4c6bc4575/moto/dynamodb2/models.py#L137 resulting in the error `Mismatched operators and values in update expression`.

I worked around this by running `strip()` on the query before execution time (making the `parts` list length divisible by two again).  I think this list construction is newline-sensitive when it should not be.

This query is run via `update_item()`, and it is validated by the line referenced above; this should be a valid toy example.

Expected: this query to run and set the above nested list value.
Actual: the `Mismatched operators` error is thrown.
Versions of packages (all pip installed): `moto==1.3.8` `boto3==1.9.145` `botocore==1.12.145`



Discussion:
Good catch.

Do you think it should be enough for us to `.strip()` `update_expression` inside of `update`?
That'll probably do it, based on the test case I have - and it'll handle this whole issue the way I've phrased it.

I'm curious if there are other places where moto should be pre-processing the query in the same way as well.  I think this is the only place where moto does this particular test.

Resolving patch:
diff --git a/moto/dynamodb2/responses.py b/moto/dynamodb2/responses.py
--- a/moto/dynamodb2/responses.py
+++ b/moto/dynamodb2/responses.py
@@ -626,7 +626,7 @@ def update_item(self):
         name = self.body['TableName']
         key = self.body['Key']
         return_values = self.body.get('ReturnValues', 'NONE')
-        update_expression = self.body.get('UpdateExpression')
+        update_expression = self.body.get('UpdateExpression', '').strip()
         attribute_updates = self.body.get('AttributeUpdates')
         expression_attribute_names = self.body.get(
             'ExpressionAttributeNames', {})


Test patch:
Repository: getmoto/moto

Issue:
API Gateway generates invalid IDs
Generated IDs in API Gateway resources look like `A-Z601A-Z47201`. They contain `A-Z` instead of letters.


Discussion:

Resolving patch:
diff --git a/moto/apigateway/utils.py b/moto/apigateway/utils.py
--- a/moto/apigateway/utils.py
+++ b/moto/apigateway/utils.py
@@ -1,9 +1,10 @@
 from __future__ import unicode_literals
 import six
 import random
+import string
 
 
 def create_id():
     size = 10
-    chars = list(range(10)) + ['A-Z']
+    chars = list(range(10)) + list(string.ascii_lowercase)
     return ''.join(six.text_type(random.choice(chars)) for x in range(size))


Test patch:
Repository: getmoto/moto

Issue:
test_create_cluster_boto3 fails with timezones east of 0000
I get the following failure when running moto tests using `make test` on latest master:
```
F
======================================================================
FAIL: test_redshift.test_create_cluster_boto3
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/iiro/.local/share/virtualenvs/moto-5xIDD5E0/lib/python3.6/site-packages/nose/case.py", line 198, in runTest
    self.test(*self.arg)
  File "/home/iiro/Private/dev/moto/moto/core/models.py", line 84, in wrapper
    result = func(*args, **kwargs)
  File "/home/iiro/Private/dev/moto/tests/test_redshift/test_redshift.py", line 38, in test_create_cluster_boto3
    create_time.should.be.lower_than(datetime.datetime.now(create_time.tzinfo))
  File "/home/iiro/.local/share/virtualenvs/moto-5xIDD5E0/lib/python3.6/site-packages/sure/__init__.py", line 387, in wrapper
    raise AssertionError(e)
AssertionError: expected `2019-07-30 13:54:17.705000+00:00` to be lower than `2019-07-30 10:54:17.707495+00:00`
```
It seems to be due to timezones. `Cluster.__init__` takes current time in the local timezone and adds `Z` to the end to indicate UTC. In the test the current time is taken using the timezone from `ClusterCreateTime`.

The error can be recreated by changing the local timezone to UTC+N. The test passes with timeszones UTC and UTC-N.


Discussion:

Resolving patch:
diff --git a/moto/redshift/models.py b/moto/redshift/models.py
--- a/moto/redshift/models.py
+++ b/moto/redshift/models.py
@@ -78,7 +78,7 @@ def __init__(self, redshift_backend, cluster_identifier, node_type, master_usern
         super(Cluster, self).__init__(region_name, tags)
         self.redshift_backend = redshift_backend
         self.cluster_identifier = cluster_identifier
-        self.create_time = iso_8601_datetime_with_milliseconds(datetime.datetime.now())
+        self.create_time = iso_8601_datetime_with_milliseconds(datetime.datetime.utcnow())
         self.status = 'available'
         self.node_type = node_type
         self.master_username = master_username


Test patch:
diff --git a/tests/test_redshift/test_redshift.py b/tests/test_redshift/test_redshift.py
--- a/tests/test_redshift/test_redshift.py
+++ b/tests/test_redshift/test_redshift.py
@@ -36,6 +36,7 @@ def test_create_cluster_boto3():
     response['Cluster']['NodeType'].should.equal('ds2.xlarge')
     create_time = response['Cluster']['ClusterCreateTime']
     create_time.should.be.lower_than(datetime.datetime.now(create_time.tzinfo))
+    create_time.should.be.greater_than(datetime.datetime.now(create_time.tzinfo) - datetime.timedelta(minutes=1))
 
 
 @mock_redshift
Repository: getmoto/moto

Issue:
iot_data.update_thing_shadow should raise ConflictException, when specified shadow version  is not same as backend
## summary
Tthis document says,
>When you supply a version with an update request, the service rejects the request with an HTTP 409 conflict response code if the current version of the state document does not match the version supplied.

https://docs.aws.amazon.com/iot/latest/developerguide/using-device-shadows.html 	

But, moto will accept update request ,that has different shadow version

## moto and boto version
boto               2.49.0
boto3              1.9.215
moto               1.3.10


Discussion:

Resolving patch:
diff --git a/moto/iotdata/exceptions.py b/moto/iotdata/exceptions.py
--- a/moto/iotdata/exceptions.py
+++ b/moto/iotdata/exceptions.py
@@ -21,3 +21,11 @@ def __init__(self, message):
         super(InvalidRequestException, self).__init__(
             "InvalidRequestException", message
         )
+
+
+class ConflictException(IoTDataPlaneClientError):
+    def __init__(self, message):
+        self.code = 409
+        super(ConflictException, self).__init__(
+            "ConflictException", message
+        )
diff --git a/moto/iotdata/models.py b/moto/iotdata/models.py
--- a/moto/iotdata/models.py
+++ b/moto/iotdata/models.py
@@ -6,6 +6,7 @@
 from moto.core import BaseBackend, BaseModel
 from moto.iot import iot_backends
 from .exceptions import (
+    ConflictException,
     ResourceNotFoundException,
     InvalidRequestException
 )
@@ -161,6 +162,8 @@ def update_thing_shadow(self, thing_name, payload):
         if any(_ for _ in payload['state'].keys() if _ not in ['desired', 'reported']):
             raise InvalidRequestException('State contains an invalid node')
 
+        if 'version' in payload and thing.thing_shadow.version != payload['version']:
+                raise ConflictException('Version conflict')
         new_shadow = FakeShadow.create_from_previous_version(thing.thing_shadow, payload)
         thing.thing_shadow = new_shadow
         return thing.thing_shadow


Test patch:
diff --git a/tests/test_iotdata/test_iotdata.py b/tests/test_iotdata/test_iotdata.py
--- a/tests/test_iotdata/test_iotdata.py
+++ b/tests/test_iotdata/test_iotdata.py
@@ -86,6 +86,12 @@ def test_update():
     payload.should.have.key('version').which.should.equal(2)
     payload.should.have.key('timestamp')
 
+    raw_payload = b'{"state": {"desired": {"led": "on"}}, "version": 1}'
+    with assert_raises(ClientError) as ex:
+        client.update_thing_shadow(thingName=name, payload=raw_payload)
+    ex.exception.response['ResponseMetadata']['HTTPStatusCode'].should.equal(409)
+    ex.exception.response['Error']['Message'].should.equal('Version conflict')
+
 
 @mock_iotdata
 def test_publish():
Repository: getmoto/moto

Issue:
STS: Invalid xmlns in response from STS
I got error below, when trying to AssumeRole by AWS SDK (for PHP).
```
Error parsing XML: xmlns: 'https:\/\/sts.amazonaws.com\/doc\/ 2011-06-15\/' is not a valid URI
```



Discussion:

Resolving patch:
diff --git a/moto/sts/responses.py b/moto/sts/responses.py
--- a/moto/sts/responses.py
+++ b/moto/sts/responses.py
@@ -128,8 +128,7 @@ def get_caller_identity(self):
 </GetFederationTokenResponse>"""
 
 
-ASSUME_ROLE_RESPONSE = """<AssumeRoleResponse xmlns="https://sts.amazonaws.com/doc/
-2011-06-15/">
+ASSUME_ROLE_RESPONSE = """<AssumeRoleResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
   <AssumeRoleResult>
     <Credentials>
       <SessionToken>{{ role.session_token }}</SessionToken>


Test patch:
Repository: getmoto/moto

Issue:
Tags not in UsagePlan model - API Gateway
The `UsagePlan` model for api gateway doesn't currently support tags.


Discussion:
I believe I have a fix for this, so will add a PR soonish.

Resolving patch:
diff --git a/moto/apigateway/models.py b/moto/apigateway/models.py
--- a/moto/apigateway/models.py
+++ b/moto/apigateway/models.py
@@ -332,15 +332,16 @@ def _str2bool(self, v):
 
 class UsagePlan(BaseModel, dict):
 
-    def __init__(self, name=None, description=None, apiStages=[],
-                 throttle=None, quota=None):
+    def __init__(self, name=None, description=None, apiStages=None,
+                 throttle=None, quota=None, tags=None):
         super(UsagePlan, self).__init__()
         self['id'] = create_id()
         self['name'] = name
         self['description'] = description
-        self['apiStages'] = apiStages
+        self['apiStages'] = apiStages if apiStages else []
         self['throttle'] = throttle
         self['quota'] = quota
+        self['tags'] = tags
 
 
 class UsagePlanKey(BaseModel, dict):


Test patch:
diff --git a/tests/test_apigateway/test_apigateway.py b/tests/test_apigateway/test_apigateway.py
--- a/tests/test_apigateway/test_apigateway.py
+++ b/tests/test_apigateway/test_apigateway.py
@@ -1029,20 +1029,27 @@ def test_usage_plans():
     usage_plan['name'].should.equal(usage_plan_name)
     usage_plan['apiStages'].should.equal([])
 
-    usage_plan_name = 'TEST-PLAN-2'
-    usage_plan_description = 'Description'
-    usage_plan_quota = {'limit': 10, 'period': 'DAY', 'offset': 0}
-    usage_plan_throttle = {'rateLimit': 2, 'burstLimit': 1}
-    usage_plan_api_stages = [{'apiId': 'foo', 'stage': 'bar'}]
-    payload = {'name': usage_plan_name, 'description': usage_plan_description, 'quota': usage_plan_quota, 'throttle': usage_plan_throttle, 'apiStages': usage_plan_api_stages}
+    payload = {
+        'name': 'TEST-PLAN-2',
+        'description': 'Description',
+        'quota': {'limit': 10, 'period': 'DAY', 'offset': 0},
+        'throttle': {'rateLimit': 2, 'burstLimit': 1},
+        'apiStages': [{'apiId': 'foo', 'stage': 'bar'}],
+        'tags': {'tag_key': 'tag_value'},
+    }
     response = client.create_usage_plan(**payload)
     usage_plan_id = response['id']
     usage_plan = client.get_usage_plan(usagePlanId=usage_plan_id)
-    usage_plan['name'].should.equal(usage_plan_name)
-    usage_plan['description'].should.equal(usage_plan_description)
-    usage_plan['apiStages'].should.equal(usage_plan_api_stages)
-    usage_plan['throttle'].should.equal(usage_plan_throttle)
-    usage_plan['quota'].should.equal(usage_plan_quota)
+
+    # The payload should remain unchanged
+    for key, value in payload.items():
+        usage_plan.should.have.key(key).which.should.equal(value)
+
+    # Status code should be 200
+    usage_plan['ResponseMetadata'].should.have.key('HTTPStatusCode').which.should.equal(200)
+
+    # An Id should've been generated
+    usage_plan.should.have.key('id').which.should_not.be.none
 
     response = client.get_usage_plans()
     len(response['items']).should.equal(2)
Repository: getmoto/moto

Issue:
containerInstances argument to ECS DescribeContainerInstances cannot be empty
I looked and couldn't find this, so I'm reporting it here, but I'm happy to look into the solution and do a PR for it.

# Reproduction Steps

```
import boto3
ecs_client = boto3.client('ecs')
cluster_name = 'test-cluster'
ecs_client.create_cluster(clusterName=cluster_name)
print(ecs_client.describe_container_instances(cluster=cluster_name,containerInstances=[]))
```
# What I expect to happen

If I run the same code against the actual AWS SDK, I get the following exception:
```
InvalidParameterException: An error occurred (InvalidParameterException) when calling the DescribeContainerInstances operation: Container instance cannot be empty.
```

# What actually happens

If I run this with a `mock_ecs` like the following

```
import boto3

from moto import mock_ecs

with mock_ecs():
    ecs_client = boto3.client('ecs')
    cluster_name = 'test-cluster'
    ecs_client.create_cluster(clusterName=cluster_name)
    print(ecs_client.describe_container_instances(cluster=cluster_name,containerInstances=[]))
```
I get:

```
{'containerInstances': [], 'failures': [], 'ResponseMetadata': {'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'amazon.com'}, 'RetryAttempts': 0}}
```
Although this is a nicer answer, it isn't consistent with the AWS API, and therefore hides edge cases.

# Version

I tested this against the latest commit at the time of reporting: `31198c75b8011f067e8ebdc97c604f555d2e7c04`


Discussion:

Resolving patch:
diff --git a/moto/ecs/models.py b/moto/ecs/models.py
--- a/moto/ecs/models.py
+++ b/moto/ecs/models.py
@@ -790,6 +790,8 @@ def describe_container_instances(self, cluster_str, list_container_instance_ids)
         cluster_name = cluster_str.split('/')[-1]
         if cluster_name not in self.clusters:
             raise Exception("{0} is not a cluster".format(cluster_name))
+        if not list_container_instance_ids:
+            raise JsonRESTError('InvalidParameterException', 'Container instance cannot be empty')
         failures = []
         container_instance_objects = []
         for container_instance_id in list_container_instance_ids:


Test patch:
diff --git a/tests/test_ecs/test_ecs_boto3.py b/tests/test_ecs/test_ecs_boto3.py
--- a/tests/test_ecs/test_ecs_boto3.py
+++ b/tests/test_ecs/test_ecs_boto3.py
@@ -889,6 +889,12 @@ def test_describe_container_instances():
         instance.keys().should.contain('runningTasksCount')
         instance.keys().should.contain('pendingTasksCount')
 
+    with assert_raises(ClientError) as e:
+        ecs_client.describe_container_instances(
+            cluster=test_cluster_name,
+            containerInstances=[]
+        )
+
 
 @mock_ec2
 @mock_ecs