text: from __future__ import unicode_literals
  from datetime import datetime
  
  from copy import deepcopy
  
  from botocore.exceptions import ClientError
  import boto3
  import sure  # noqa
  import json
  from moto.ec2 import utils as ec2_utils
  from uuid import UUID
  
  from moto import mock_cloudformation, mock_elbv2
  from moto import mock_ecs
  from moto import mock_ec2
  from nose.tools import assert_raises
  
  
  @mock_ecs
  def test_create_cluster():
      client = boto3.client('ecs', region_name='us-east-1')
      response = client.create_cluster(
          clusterName='test_ecs_cluster'
      )
      response['cluster']['clusterName'].should.equal('test_ecs_cluster')
      response['cluster']['clusterArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster')
      response['cluster']['status'].should.equal('ACTIVE')
      response['cluster']['registeredContainerInstancesCount'].should.equal(0)
      response['cluster']['runningTasksCount'].should.equal(0)
      response['cluster']['pendingTasksCount'].should.equal(0)
      response['cluster']['activeServicesCount'].should.equal(0)
  
  
  @mock_ecs
  def test_list_clusters():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.create_cluster(
          clusterName='test_cluster0'
      )
      _ = client.create_cluster(
          clusterName='test_cluster1'
      )
      response = client.list_clusters()
      response['clusterArns'].should.contain(
          'arn:aws:ecs:us-east-1:012345678910:cluster/test_cluster0')
      response['clusterArns'].should.contain(
          'arn:aws:ecs:us-east-1:012345678910:cluster/test_cluster1')
  
  
  @mock_ecs
  def test_describe_clusters():
      client = boto3.client('ecs', region_name='us-east-1')
      response = client.describe_clusters(clusters=["some-cluster"])
      response['failures'].should.contain({
          'arn': 'arn:aws:ecs:us-east-1:012345678910:cluster/some-cluster',
          'reason': 'MISSING'
      })
  
  @mock_ecs
  def test_delete_cluster():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.create_cluster(
          clusterName='test_ecs_cluster'
      )
      response = client.delete_cluster(cluster='test_ecs_cluster')
      response['cluster']['clusterName'].should.equal('test_ecs_cluster')
      response['cluster']['clusterArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster')
      response['cluster']['status'].should.equal('ACTIVE')
      response['cluster']['registeredContainerInstancesCount'].should.equal(0)
      response['cluster']['runningTasksCount'].should.equal(0)
      response['cluster']['pendingTasksCount'].should.equal(0)
      response['cluster']['activeServicesCount'].should.equal(0)
  
      response = client.list_clusters()
      len(response['clusterArns']).should.equal(0)
  
  
  @mock_ecs
  def test_register_task_definition():
      client = boto3.client('ecs', region_name='us-east-1')
      response = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ],
          tags=[
              {'key': 'createdBy', 'value': 'moto-unittest'},
              {'key': 'foo', 'value': 'bar'},
          ]
      )
      type(response['taskDefinition']).should.be(dict)
      response['taskDefinition']['revision'].should.equal(1)
      response['taskDefinition']['taskDefinitionArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')
      response['taskDefinition']['containerDefinitions'][
          0]['name'].should.equal('hello_world')
      response['taskDefinition']['containerDefinitions'][0][
          'image'].should.equal('docker/hello-world:latest')
      response['taskDefinition']['containerDefinitions'][
          0]['cpu'].should.equal(1024)
      response['taskDefinition']['containerDefinitions'][
          0]['memory'].should.equal(400)
      response['taskDefinition']['containerDefinitions'][
          0]['essential'].should.equal(True)
      response['taskDefinition']['containerDefinitions'][0][
          'environment'][0]['name'].should.equal('AWS_ACCESS_KEY_ID')
      response['taskDefinition']['containerDefinitions'][0][
          'environment'][0]['value'].should.equal('SOME_ACCESS_KEY')
      response['taskDefinition']['containerDefinitions'][0][
          'logConfiguration']['logDriver'].should.equal('json-file')
  
  
  @mock_ecs
  def test_list_task_definitions():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world2',
                  'image': 'docker/hello-world2:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY2'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      response = client.list_task_definitions()
      len(response['taskDefinitionArns']).should.equal(2)
      response['taskDefinitionArns'][0].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')
      response['taskDefinitionArns'][1].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:2')
  
  
  @mock_ecs
  def test_describe_task_definition():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world2',
                  'image': 'docker/hello-world2:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY2'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world3',
                  'image': 'docker/hello-world3:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY3'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      response = client.describe_task_definition(taskDefinition='test_ecs_task')
      response['taskDefinition']['taskDefinitionArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:3')
  
      response = client.describe_task_definition(
          taskDefinition='test_ecs_task:2')
      response['taskDefinition']['taskDefinitionArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:2')
  
  
  @mock_ecs
  def test_deregister_task_definition():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      response = client.deregister_task_definition(
          taskDefinition='test_ecs_task:1'
      )
      type(response['taskDefinition']).should.be(dict)
      response['taskDefinition']['taskDefinitionArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')
      response['taskDefinition']['containerDefinitions'][
          0]['name'].should.equal('hello_world')
      response['taskDefinition']['containerDefinitions'][0][
          'image'].should.equal('docker/hello-world:latest')
      response['taskDefinition']['containerDefinitions'][
          0]['cpu'].should.equal(1024)
      response['taskDefinition']['containerDefinitions'][
          0]['memory'].should.equal(400)
      response['taskDefinition']['containerDefinitions'][
          0]['essential'].should.equal(True)
      response['taskDefinition']['containerDefinitions'][0][
          'environment'][0]['name'].should.equal('AWS_ACCESS_KEY_ID')
      response['taskDefinition']['containerDefinitions'][0][
          'environment'][0]['value'].should.equal('SOME_ACCESS_KEY')
      response['taskDefinition']['containerDefinitions'][0][
          'logConfiguration']['logDriver'].should.equal('json-file')
  
  
  @mock_ecs
  def test_create_service():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.create_cluster(
          clusterName='test_ecs_cluster'
      )
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      response = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service',
          taskDefinition='test_ecs_task',
          desiredCount=2
      )
      response['service']['clusterArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster')
      response['service']['desiredCount'].should.equal(2)
      len(response['service']['events']).should.equal(0)
      len(response['service']['loadBalancers']).should.equal(0)
      response['service']['pendingCount'].should.equal(0)
      response['service']['runningCount'].should.equal(0)
      response['service']['serviceArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service')
      response['service']['serviceName'].should.equal('test_ecs_service')
      response['service']['status'].should.equal('ACTIVE')
      response['service']['taskDefinition'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')
      response['service']['schedulingStrategy'].should.equal('REPLICA')
  
  @mock_ecs
  def test_create_service_scheduling_strategy():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.create_cluster(
          clusterName='test_ecs_cluster'
      )
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      response = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service',
          taskDefinition='test_ecs_task',
          desiredCount=2,
          schedulingStrategy='DAEMON',
      )
      response['service']['clusterArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster')
      response['service']['desiredCount'].should.equal(2)
      len(response['service']['events']).should.equal(0)
      len(response['service']['loadBalancers']).should.equal(0)
      response['service']['pendingCount'].should.equal(0)
      response['service']['runningCount'].should.equal(0)
      response['service']['serviceArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service')
      response['service']['serviceName'].should.equal('test_ecs_service')
      response['service']['status'].should.equal('ACTIVE')
      response['service']['taskDefinition'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')
      response['service']['schedulingStrategy'].should.equal('DAEMON')
  
  
  @mock_ecs
  def test_list_services():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.create_cluster(
          clusterName='test_ecs_cluster'
      )
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      _ = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service1',
          taskDefinition='test_ecs_task',
          schedulingStrategy='REPLICA',
          desiredCount=2
      )
      _ = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service2',
          taskDefinition='test_ecs_task',
          schedulingStrategy='DAEMON',
          desiredCount=2
      )
      unfiltered_response = client.list_services(
          cluster='test_ecs_cluster'
      )
      len(unfiltered_response['serviceArns']).should.equal(2)
      unfiltered_response['serviceArns'][0].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service1')
      unfiltered_response['serviceArns'][1].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service2')
  
      filtered_response = client.list_services(
          cluster='test_ecs_cluster',
          schedulingStrategy='REPLICA'
      )
      len(filtered_response['serviceArns']).should.equal(1)
      filtered_response['serviceArns'][0].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service1')
  
  @mock_ecs
  def test_describe_services():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.create_cluster(
          clusterName='test_ecs_cluster'
      )
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      _ = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service1',
          taskDefinition='test_ecs_task',
          desiredCount=2
      )
      _ = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service2',
          taskDefinition='test_ecs_task',
          desiredCount=2
      )
      _ = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service3',
          taskDefinition='test_ecs_task',
          desiredCount=2
      )
      response = client.describe_services(
          cluster='test_ecs_cluster',
          services=['test_ecs_service1',
                    'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service2']
      )
      len(response['services']).should.equal(2)
      response['services'][0]['serviceArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service1')
      response['services'][0]['serviceName'].should.equal('test_ecs_service1')
      response['services'][1]['serviceArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service2')
      response['services'][1]['serviceName'].should.equal('test_ecs_service2')
  
      response['services'][0]['deployments'][0]['desiredCount'].should.equal(2)
      response['services'][0]['deployments'][0]['pendingCount'].should.equal(2)
      response['services'][0]['deployments'][0]['runningCount'].should.equal(0)
      response['services'][0]['deployments'][0]['status'].should.equal('PRIMARY')
      (datetime.now() - response['services'][0]['deployments'][0]["createdAt"].replace(tzinfo=None)).seconds.should.be.within(0, 10)
      (datetime.now() - response['services'][0]['deployments'][0]["updatedAt"].replace(tzinfo=None)).seconds.should.be.within(0, 10)
  
  
  @mock_ecs
  def test_describe_services_scheduling_strategy():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.create_cluster(
          clusterName='test_ecs_cluster'
      )
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      _ = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service1',
          taskDefinition='test_ecs_task',
          desiredCount=2
      )
      _ = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service2',
          taskDefinition='test_ecs_task',
          desiredCount=2,
          schedulingStrategy='DAEMON'
      )
      _ = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service3',
          taskDefinition='test_ecs_task',
          desiredCount=2
      )
      response = client.describe_services(
          cluster='test_ecs_cluster',
          services=['test_ecs_service1',
                    'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service2',
                    'test_ecs_service3']
      )
      len(response['services']).should.equal(3)
      response['services'][0]['serviceArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service1')
      response['services'][0]['serviceName'].should.equal('test_ecs_service1')
      response['services'][1]['serviceArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service2')
      response['services'][1]['serviceName'].should.equal('test_ecs_service2')
  
      response['services'][0]['deployments'][0]['desiredCount'].should.equal(2)
      response['services'][0]['deployments'][0]['pendingCount'].should.equal(2)
      response['services'][0]['deployments'][0]['runningCount'].should.equal(0)
      response['services'][0]['deployments'][0]['status'].should.equal('PRIMARY')
  
      response['services'][0]['schedulingStrategy'].should.equal('REPLICA')
      response['services'][1]['schedulingStrategy'].should.equal('DAEMON')
      response['services'][2]['schedulingStrategy'].should.equal('REPLICA')
  
  
  @mock_ecs
  def test_update_service():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.create_cluster(
          clusterName='test_ecs_cluster'
      )
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      response = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service',
          taskDefinition='test_ecs_task',
          desiredCount=2
      )
      response['service']['desiredCount'].should.equal(2)
  
      response = client.update_service(
          cluster='test_ecs_cluster',
          service='test_ecs_service',
          taskDefinition='test_ecs_task',
          desiredCount=0
      )
      response['service']['desiredCount'].should.equal(0)
      response['service']['schedulingStrategy'].should.equal('REPLICA')
  
  
  @mock_ecs
  def test_update_missing_service():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.create_cluster(
          clusterName='test_ecs_cluster'
      )
  
      client.update_service.when.called_with(
          cluster='test_ecs_cluster',
          service='test_ecs_service',
          taskDefinition='test_ecs_task',
          desiredCount=0
      ).should.throw(ClientError)
  
  
  @mock_ecs
  def test_delete_service():
      client = boto3.client('ecs', region_name='us-east-1')
      _ = client.create_cluster(
          clusterName='test_ecs_cluster'
      )
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      _ = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service',
          taskDefinition='test_ecs_task',
          desiredCount=2
      )
      _ = client.update_service(
          cluster='test_ecs_cluster',
          service='test_ecs_service',
          desiredCount=0
      )
      response = client.delete_service(
          cluster='test_ecs_cluster',
          service='test_ecs_service'
      )
      response['service']['clusterArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster')
      response['service']['desiredCount'].should.equal(0)
      len(response['service']['events']).should.equal(0)
      len(response['service']['loadBalancers']).should.equal(0)
      response['service']['pendingCount'].should.equal(0)
      response['service']['runningCount'].should.equal(0)
      response['service']['serviceArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service')
      response['service']['serviceName'].should.equal('test_ecs_service')
      response['service']['status'].should.equal('ACTIVE')
      response['service']['schedulingStrategy'].should.equal('REPLICA')
      response['service']['taskDefinition'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')
  
  
  @mock_ecs
  def test_update_non_existant_service():
      client = boto3.client('ecs', region_name='us-east-1')
      try:
          client.update_service(
              cluster="my-clustet",
              service="my-service",
              desiredCount=0,
          )
      except ClientError as exc:
          error_code = exc.response['Error']['Code']
          error_code.should.equal('ServiceNotFoundException')
      else:
          raise Exception("Didn't raise ClientError")
  
  
  @mock_ec2
  @mock_ecs
  def test_register_container_instance():
      ecs_client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = ecs_client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      response = ecs_client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      response['containerInstance'][
          'ec2InstanceId'].should.equal(test_instance.id)
      full_arn = response['containerInstance']['containerInstanceArn']
      arn_part = full_arn.split('/')
      arn_part[0].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:container-instance')
      arn_part[1].should.equal(str(UUID(arn_part[1])))
      response['containerInstance']['status'].should.equal('ACTIVE')
      len(response['containerInstance']['registeredResources']).should.equal(4)
      len(response['containerInstance']['remainingResources']).should.equal(4)
      response['containerInstance']['agentConnected'].should.equal(True)
      response['containerInstance']['versionInfo'][
          'agentVersion'].should.equal('1.0.0')
      response['containerInstance']['versionInfo'][
          'agentHash'].should.equal('4023248')
      response['containerInstance']['versionInfo'][
          'dockerVersion'].should.equal('DockerVersion: 1.5.0')
  
  
  @mock_ec2
  @mock_ecs
  def test_deregister_container_instance():
      ecs_client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = ecs_client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      response = ecs_client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
      container_instance_id = response['containerInstance']['containerInstanceArn']
      response = ecs_client.deregister_container_instance(
          cluster=test_cluster_name,
          containerInstance=container_instance_id
      )
      container_instances_response = ecs_client.list_container_instances(
          cluster=test_cluster_name
      )
      len(container_instances_response['containerInstanceArns']).should.equal(0)
  
      response = ecs_client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
      container_instance_id = response['containerInstance']['containerInstanceArn']
      _ = ecs_client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
  
      response = ecs_client.start_task(
          cluster='test_ecs_cluster',
          taskDefinition='test_ecs_task',
          overrides={},
          containerInstances=[container_instance_id],
          startedBy='moto'
      )
      with assert_raises(Exception) as e:
          ecs_client.deregister_container_instance(
              cluster=test_cluster_name,
              containerInstance=container_instance_id
          ).should.have.raised(Exception)
      container_instances_response = ecs_client.list_container_instances(
          cluster=test_cluster_name
      )
      len(container_instances_response['containerInstanceArns']).should.equal(1)
      ecs_client.deregister_container_instance(
          cluster=test_cluster_name,
          containerInstance=container_instance_id,
          force=True
      )
      container_instances_response = ecs_client.list_container_instances(
          cluster=test_cluster_name
      )
      len(container_instances_response['containerInstanceArns']).should.equal(0)
  
  
  @mock_ec2
  @mock_ecs
  def test_list_container_instances():
      ecs_client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
      _ = ecs_client.create_cluster(
          clusterName=test_cluster_name
      )
  
      instance_to_create = 3
      test_instance_arns = []
      for i in range(0, instance_to_create):
          test_instance = ec2.create_instances(
              ImageId="ami-1234abcd",
              MinCount=1,
              MaxCount=1,
          )[0]
  
          instance_id_document = json.dumps(
              ec2_utils.generate_instance_identity_document(test_instance)
          )
  
          response = ecs_client.register_container_instance(
              cluster=test_cluster_name,
              instanceIdentityDocument=instance_id_document)
  
          test_instance_arns.append(response['containerInstance'][
                                        'containerInstanceArn'])
  
      response = ecs_client.list_container_instances(cluster=test_cluster_name)
  
      len(response['containerInstanceArns']).should.equal(instance_to_create)
      for arn in test_instance_arns:
          response['containerInstanceArns'].should.contain(arn)
  
  
  @mock_ec2
  @mock_ecs
  def test_describe_container_instances():
      ecs_client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
      _ = ecs_client.create_cluster(
          clusterName=test_cluster_name
      )
  
      instance_to_create = 3
      test_instance_arns = []
      for i in range(0, instance_to_create):
          test_instance = ec2.create_instances(
              ImageId="ami-1234abcd",
              MinCount=1,
              MaxCount=1,
          )[0]
  
          instance_id_document = json.dumps(
              ec2_utils.generate_instance_identity_document(test_instance)
          )
  
          response = ecs_client.register_container_instance(
              cluster=test_cluster_name,
              instanceIdentityDocument=instance_id_document)
  
          test_instance_arns.append(response['containerInstance'][
                                        'containerInstanceArn'])
  
      test_instance_ids = list(
          map((lambda x: x.split('/')[1]), test_instance_arns))
      response = ecs_client.describe_container_instances(
          cluster=test_cluster_name, containerInstances=test_instance_ids)
      len(response['failures']).should.equal(0)
      len(response['containerInstances']).should.equal(instance_to_create)
      response_arns = [ci['containerInstanceArn']
                       for ci in response['containerInstances']]
      for arn in test_instance_arns:
          response_arns.should.contain(arn)
      for instance in response['containerInstances']:
          instance.keys().should.contain('runningTasksCount')
          instance.keys().should.contain('pendingTasksCount')
  
  
  @mock_ec2
  @mock_ecs
  def test_update_container_instances_state():
      ecs_client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
      _ = ecs_client.create_cluster(
          clusterName=test_cluster_name
      )
  
      instance_to_create = 3
      test_instance_arns = []
      for i in range(0, instance_to_create):
          test_instance = ec2.create_instances(
              ImageId="ami-1234abcd",
              MinCount=1,
              MaxCount=1,
          )[0]
  
          instance_id_document = json.dumps(
              ec2_utils.generate_instance_identity_document(test_instance)
          )
  
          response = ecs_client.register_container_instance(
              cluster=test_cluster_name,
              instanceIdentityDocument=instance_id_document)
  
          test_instance_arns.append(response['containerInstance']['containerInstanceArn'])
  
      test_instance_ids = list(map((lambda x: x.split('/')[1]), test_instance_arns))
      response = ecs_client.update_container_instances_state(cluster=test_cluster_name,
                                                             containerInstances=test_instance_ids,
                                                             status='DRAINING')
      len(response['failures']).should.equal(0)
      len(response['containerInstances']).should.equal(instance_to_create)
      response_statuses = [ci['status'] for ci in response['containerInstances']]
      for status in response_statuses:
          status.should.equal('DRAINING')
      response = ecs_client.update_container_instances_state(cluster=test_cluster_name,
                                                             containerInstances=test_instance_ids,
                                                             status='DRAINING')
      len(response['failures']).should.equal(0)
      len(response['containerInstances']).should.equal(instance_to_create)
      response_statuses = [ci['status'] for ci in response['containerInstances']]
      for status in response_statuses:
          status.should.equal('DRAINING')
      response = ecs_client.update_container_instances_state(cluster=test_cluster_name,
                                                             containerInstances=test_instance_ids,
                                                             status='ACTIVE')
      len(response['failures']).should.equal(0)
      len(response['containerInstances']).should.equal(instance_to_create)
      response_statuses = [ci['status'] for ci in response['containerInstances']]
      for status in response_statuses:
          status.should.equal('ACTIVE')
      ecs_client.update_container_instances_state.when.called_with(cluster=test_cluster_name,
                                                                   containerInstances=test_instance_ids,
                                                                   status='test_status').should.throw(Exception)
  
  
  @mock_ec2
  @mock_ecs
  def test_update_container_instances_state_by_arn():
      ecs_client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
      _ = ecs_client.create_cluster(
          clusterName=test_cluster_name
      )
  
      instance_to_create = 3
      test_instance_arns = []
      for i in range(0, instance_to_create):
          test_instance = ec2.create_instances(
              ImageId="ami-1234abcd",
              MinCount=1,
              MaxCount=1,
          )[0]
  
          instance_id_document = json.dumps(
              ec2_utils.generate_instance_identity_document(test_instance)
          )
  
          response = ecs_client.register_container_instance(
              cluster=test_cluster_name,
              instanceIdentityDocument=instance_id_document)
  
          test_instance_arns.append(response['containerInstance']['containerInstanceArn'])
  
      response = ecs_client.update_container_instances_state(cluster=test_cluster_name,
                                                             containerInstances=test_instance_arns,
                                                             status='DRAINING')
      len(response['failures']).should.equal(0)
      len(response['containerInstances']).should.equal(instance_to_create)
      response_statuses = [ci['status'] for ci in response['containerInstances']]
      for status in response_statuses:
          status.should.equal('DRAINING')
      response = ecs_client.update_container_instances_state(cluster=test_cluster_name,
                                                             containerInstances=test_instance_arns,
                                                             status='DRAINING')
      len(response['failures']).should.equal(0)
      len(response['containerInstances']).should.equal(instance_to_create)
      response_statuses = [ci['status'] for ci in response['containerInstances']]
      for status in response_statuses:
          status.should.equal('DRAINING')
      response = ecs_client.update_container_instances_state(cluster=test_cluster_name,
                                                             containerInstances=test_instance_arns,
                                                             status='ACTIVE')
      len(response['failures']).should.equal(0)
      len(response['containerInstances']).should.equal(instance_to_create)
      response_statuses = [ci['status'] for ci in response['containerInstances']]
      for status in response_statuses:
          status.should.equal('ACTIVE')
      ecs_client.update_container_instances_state.when.called_with(cluster=test_cluster_name,
                                                                   containerInstances=test_instance_arns,
                                                                   status='test_status').should.throw(Exception)
  
  
  @mock_ec2
  @mock_ecs
  def test_run_task():
      client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      response = client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      response = client.run_task(
          cluster='test_ecs_cluster',
          overrides={},
          taskDefinition='test_ecs_task',
          count=2,
          startedBy='moto'
      )
      len(response['tasks']).should.equal(2)
      response['tasks'][0]['taskArn'].should.contain(
          'arn:aws:ecs:us-east-1:012345678910:task/')
      response['tasks'][0]['clusterArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster')
      response['tasks'][0]['taskDefinitionArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')
      response['tasks'][0]['containerInstanceArn'].should.contain(
          'arn:aws:ecs:us-east-1:012345678910:container-instance/')
      response['tasks'][0]['overrides'].should.equal({})
      response['tasks'][0]['lastStatus'].should.equal("RUNNING")
      response['tasks'][0]['desiredStatus'].should.equal("RUNNING")
      response['tasks'][0]['startedBy'].should.equal("moto")
      response['tasks'][0]['stoppedReason'].should.equal("")
  
  
  @mock_ec2
  @mock_ecs
  def test_start_task():
      client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      response = client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      container_instances = client.list_container_instances(
          cluster=test_cluster_name)
      container_instance_id = container_instances[
          'containerInstanceArns'][0].split('/')[-1]
  
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
  
      response = client.start_task(
          cluster='test_ecs_cluster',
          taskDefinition='test_ecs_task',
          overrides={},
          containerInstances=[container_instance_id],
          startedBy='moto'
      )
  
      len(response['tasks']).should.equal(1)
      response['tasks'][0]['taskArn'].should.contain(
          'arn:aws:ecs:us-east-1:012345678910:task/')
      response['tasks'][0]['clusterArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster')
      response['tasks'][0]['taskDefinitionArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')
      response['tasks'][0]['containerInstanceArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:container-instance/{0}'.format(container_instance_id))
      response['tasks'][0]['overrides'].should.equal({})
      response['tasks'][0]['lastStatus'].should.equal("RUNNING")
      response['tasks'][0]['desiredStatus'].should.equal("RUNNING")
      response['tasks'][0]['startedBy'].should.equal("moto")
      response['tasks'][0]['stoppedReason'].should.equal("")
  
  
  @mock_ec2
  @mock_ecs
  def test_list_tasks():
      client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      _ = client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      container_instances = client.list_container_instances(
          cluster=test_cluster_name)
      container_instance_id = container_instances[
          'containerInstanceArns'][0].split('/')[-1]
  
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
  
      _ = client.start_task(
          cluster='test_ecs_cluster',
          taskDefinition='test_ecs_task',
          overrides={},
          containerInstances=[container_instance_id],
          startedBy='foo'
      )
  
      _ = client.start_task(
          cluster='test_ecs_cluster',
          taskDefinition='test_ecs_task',
          overrides={},
          containerInstances=[container_instance_id],
          startedBy='bar'
      )
  
      assert len(client.list_tasks()['taskArns']).should.equal(2)
      assert len(client.list_tasks(cluster='test_ecs_cluster')
                 ['taskArns']).should.equal(2)
      assert len(client.list_tasks(startedBy='foo')['taskArns']).should.equal(1)
  
  
  @mock_ec2
  @mock_ecs
  def test_describe_tasks():
      client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      response = client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      tasks_arns = [
          task['taskArn'] for task in client.run_task(
              cluster='test_ecs_cluster',
              overrides={},
              taskDefinition='test_ecs_task',
              count=2,
              startedBy='moto'
          )['tasks']
      ]
      response = client.describe_tasks(
          cluster='test_ecs_cluster',
          tasks=tasks_arns
      )
  
      len(response['tasks']).should.equal(2)
      set([response['tasks'][0]['taskArn'], response['tasks']
      [1]['taskArn']]).should.equal(set(tasks_arns))
  
      # Test we can pass task ids instead of ARNs
      response = client.describe_tasks(
          cluster='test_ecs_cluster',
          tasks=[tasks_arns[0].split("/")[-1]]
      )
      len(response['tasks']).should.equal(1)
  
  
  @mock_ecs
  def describe_task_definition():
      client = boto3.client('ecs', region_name='us-east-1')
      container_definition = {
          'name': 'hello_world',
          'image': 'docker/hello-world:latest',
          'cpu': 1024,
          'memory': 400,
          'essential': True,
          'environment': [{
              'name': 'AWS_ACCESS_KEY_ID',
              'value': 'SOME_ACCESS_KEY'
          }],
          'logConfiguration': {'logDriver': 'json-file'}
      }
      task_definition = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[container_definition]
      )
      family = task_definition['family']
      task = client.describe_task_definition(taskDefinition=family)
      task['containerDefinitions'][0].should.equal(container_definition)
      task['taskDefinitionArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task2:1')
      task['volumes'].should.equal([])
  
  
  @mock_ec2
  @mock_ecs
  def test_stop_task():
      client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      _ = client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      run_response = client.run_task(
          cluster='test_ecs_cluster',
          overrides={},
          taskDefinition='test_ecs_task',
          count=1,
          startedBy='moto'
      )
      stop_response = client.stop_task(
          cluster='test_ecs_cluster',
          task=run_response['tasks'][0].get('taskArn'),
          reason='moto testing'
      )
  
      stop_response['task']['taskArn'].should.equal(
          run_response['tasks'][0].get('taskArn'))
      stop_response['task']['lastStatus'].should.equal('STOPPED')
      stop_response['task']['desiredStatus'].should.equal('STOPPED')
      stop_response['task']['stoppedReason'].should.equal('moto testing')
  
  
  @mock_ec2
  @mock_ecs
  def test_resource_reservation_and_release():
      client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      _ = client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'},
                  'portMappings': [
                      {
                          'hostPort': 80,
                          'containerPort': 8080
                      }
                  ]
              }
          ]
      )
      run_response = client.run_task(
          cluster='test_ecs_cluster',
          overrides={},
          taskDefinition='test_ecs_task',
          count=1,
          startedBy='moto'
      )
      container_instance_arn = run_response['tasks'][0].get('containerInstanceArn')
      container_instance_description = client.describe_container_instances(
          cluster='test_ecs_cluster',
          containerInstances=[container_instance_arn]
      )['containerInstances'][0]
      remaining_resources, registered_resources = _fetch_container_instance_resources(
          container_instance_description)
      remaining_resources['CPU'].should.equal(registered_resources['CPU'] - 1024)
      remaining_resources['MEMORY'].should.equal(registered_resources['MEMORY'] - 400)
      registered_resources['PORTS'].append('80')
      remaining_resources['PORTS'].should.equal(registered_resources['PORTS'])
      container_instance_description['runningTasksCount'].should.equal(1)
      client.stop_task(
          cluster='test_ecs_cluster',
          task=run_response['tasks'][0].get('taskArn'),
          reason='moto testing'
      )
      container_instance_description = client.describe_container_instances(
          cluster='test_ecs_cluster',
          containerInstances=[container_instance_arn]
      )['containerInstances'][0]
      remaining_resources, registered_resources = _fetch_container_instance_resources(
          container_instance_description)
      remaining_resources['CPU'].should.equal(registered_resources['CPU'])
      remaining_resources['MEMORY'].should.equal(registered_resources['MEMORY'])
      remaining_resources['PORTS'].should.equal(registered_resources['PORTS'])
      container_instance_description['runningTasksCount'].should.equal(0)
  
  @mock_ec2
  @mock_ecs
  def test_resource_reservation_and_release_memory_reservation():
      client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      _ = client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'memoryReservation': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'},
                  'portMappings': [
                      {
                          'containerPort': 8080
                      }
                  ]
              }
          ]
      )
      run_response = client.run_task(
          cluster='test_ecs_cluster',
          overrides={},
          taskDefinition='test_ecs_task',
          count=1,
          startedBy='moto'
      )
      container_instance_arn = run_response['tasks'][0].get('containerInstanceArn')
      container_instance_description = client.describe_container_instances(
          cluster='test_ecs_cluster',
          containerInstances=[container_instance_arn]
      )['containerInstances'][0]
      remaining_resources, registered_resources = _fetch_container_instance_resources(container_instance_description)
      remaining_resources['CPU'].should.equal(registered_resources['CPU'])
      remaining_resources['MEMORY'].should.equal(registered_resources['MEMORY'] - 400)
      remaining_resources['PORTS'].should.equal(registered_resources['PORTS'])
      container_instance_description['runningTasksCount'].should.equal(1)
      client.stop_task(
          cluster='test_ecs_cluster',
          task=run_response['tasks'][0].get('taskArn'),
          reason='moto testing'
      )
      container_instance_description = client.describe_container_instances(
          cluster='test_ecs_cluster',
          containerInstances=[container_instance_arn]
      )['containerInstances'][0]
      remaining_resources, registered_resources = _fetch_container_instance_resources(container_instance_description)
      remaining_resources['CPU'].should.equal(registered_resources['CPU'])
      remaining_resources['MEMORY'].should.equal(registered_resources['MEMORY'])
      remaining_resources['PORTS'].should.equal(registered_resources['PORTS'])
      container_instance_description['runningTasksCount'].should.equal(0)
  
  
  
  @mock_ecs
  @mock_cloudformation
  def test_create_cluster_through_cloudformation():
      template = {
          "AWSTemplateFormatVersion": "2010-09-09",
          "Description": "ECS Cluster Test CloudFormation",
          "Resources": {
              "testCluster": {
                  "Type": "AWS::ECS::Cluster",
                  "Properties": {
                      "ClusterName": "testcluster"
                  }
              }
          }
      }
      template_json = json.dumps(template)
  
      ecs_conn = boto3.client('ecs', region_name='us-west-1')
      resp = ecs_conn.list_clusters()
      len(resp['clusterArns']).should.equal(0)
  
      cfn_conn = boto3.client('cloudformation', region_name='us-west-1')
      cfn_conn.create_stack(
          StackName="test_stack",
          TemplateBody=template_json,
      )
  
      resp = ecs_conn.list_clusters()
      len(resp['clusterArns']).should.equal(1)
  
  
  @mock_ecs
  @mock_cloudformation
  def test_create_cluster_through_cloudformation_no_name():
      # cloudformation should create a cluster name for you if you do not provide it
      # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-cluster.html#cfn-ecs-cluster-clustername
      template = {
          "AWSTemplateFormatVersion": "2010-09-09",
          "Description": "ECS Cluster Test CloudFormation",
          "Resources": {
              "testCluster": {
                  "Type": "AWS::ECS::Cluster",
              }
          }
      }
      template_json = json.dumps(template)
      cfn_conn = boto3.client('cloudformation', region_name='us-west-1')
      cfn_conn.create_stack(
          StackName="test_stack",
          TemplateBody=template_json,
      )
  
      ecs_conn = boto3.client('ecs', region_name='us-west-1')
      resp = ecs_conn.list_clusters()
      len(resp['clusterArns']).should.equal(1)
  
  
  @mock_ecs
  @mock_cloudformation
  def test_update_cluster_name_through_cloudformation_should_trigger_a_replacement():
      template1 = {
          "AWSTemplateFormatVersion": "2010-09-09",
          "Description": "ECS Cluster Test CloudFormation",
          "Resources": {
              "testCluster": {
                  "Type": "AWS::ECS::Cluster",
                  "Properties": {
                      "ClusterName": "testcluster1"
                  }
              }
          }
      }
      template2 = deepcopy(template1)
      template2['Resources']['testCluster'][
          'Properties']['ClusterName'] = 'testcluster2'
      template1_json = json.dumps(template1)
      cfn_conn = boto3.client('cloudformation', region_name='us-west-1')
      stack_resp = cfn_conn.create_stack(
          StackName="test_stack",
          TemplateBody=template1_json,
      )
  
      template2_json = json.dumps(template2)
      cfn_conn.update_stack(
          StackName=stack_resp['StackId'],
          TemplateBody=template2_json
      )
      ecs_conn = boto3.client('ecs', region_name='us-west-1')
      resp = ecs_conn.list_clusters()
      len(resp['clusterArns']).should.equal(1)
      resp['clusterArns'][0].endswith('testcluster2').should.be.true
  
  
  @mock_ecs
  @mock_cloudformation
  def test_create_task_definition_through_cloudformation():
      template = {
          "AWSTemplateFormatVersion": "2010-09-09",
          "Description": "ECS Cluster Test CloudFormation",
          "Resources": {
              "testTaskDefinition": {
                  "Type": "AWS::ECS::TaskDefinition",
                  "Properties": {
                      "ContainerDefinitions": [
                          {
                              "Name": "ecs-sample",
                              "Image": "amazon/amazon-ecs-sample",
                              "Cpu": "200",
                              "Memory": "500",
                              "Essential": "true"
                          }
                      ],
                      "Volumes": [],
                  }
              }
          }
      }
      template_json = json.dumps(template)
      cfn_conn = boto3.client('cloudformation', region_name='us-west-1')
      stack_name = 'test_stack'
      cfn_conn.create_stack(
          StackName=stack_name,
          TemplateBody=template_json,
      )
  
      ecs_conn = boto3.client('ecs', region_name='us-west-1')
      resp = ecs_conn.list_task_definitions()
      len(resp['taskDefinitionArns']).should.equal(1)
      task_definition_arn = resp['taskDefinitionArns'][0]
  
      task_definition_details = cfn_conn.describe_stack_resource(
          StackName=stack_name,LogicalResourceId='testTaskDefinition')['StackResourceDetail']
      task_definition_details['PhysicalResourceId'].should.equal(task_definition_arn)
  
  @mock_ec2
  @mock_ecs
  def test_task_definitions_unable_to_be_placed():
      client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      response = client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 5000,
                  'memory': 40000,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      response = client.run_task(
          cluster='test_ecs_cluster',
          overrides={},
          taskDefinition='test_ecs_task',
          count=2,
          startedBy='moto'
      )
      len(response['tasks']).should.equal(0)
  
  
  @mock_ec2
  @mock_ecs
  def test_task_definitions_with_port_clash():
      client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      response = client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      _ = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 256,
                  'memory': 512,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'},
                  'portMappings': [
                      {
                          'hostPort': 80,
                          'containerPort': 8080
                      }
                  ]
              }
          ]
      )
      response = client.run_task(
          cluster='test_ecs_cluster',
          overrides={},
          taskDefinition='test_ecs_task',
          count=2,
          startedBy='moto'
      )
      len(response['tasks']).should.equal(1)
      response['tasks'][0]['taskArn'].should.contain(
          'arn:aws:ecs:us-east-1:012345678910:task/')
      response['tasks'][0]['clusterArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster')
      response['tasks'][0]['taskDefinitionArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')
      response['tasks'][0]['containerInstanceArn'].should.contain(
          'arn:aws:ecs:us-east-1:012345678910:container-instance/')
      response['tasks'][0]['overrides'].should.equal({})
      response['tasks'][0]['lastStatus'].should.equal("RUNNING")
      response['tasks'][0]['desiredStatus'].should.equal("RUNNING")
      response['tasks'][0]['startedBy'].should.equal("moto")
      response['tasks'][0]['stoppedReason'].should.equal("")
  
  
  @mock_ecs
  @mock_cloudformation
  def test_update_task_definition_family_through_cloudformation_should_trigger_a_replacement():
      template1 = {
          "AWSTemplateFormatVersion": "2010-09-09",
          "Description": "ECS Cluster Test CloudFormation",
          "Resources": {
              "testTaskDefinition": {
                  "Type": "AWS::ECS::TaskDefinition",
                  "Properties": {
                      "Family": "testTaskDefinition1",
                      "ContainerDefinitions": [
                          {
                              "Name": "ecs-sample",
                              "Image": "amazon/amazon-ecs-sample",
                              "Cpu": "200",
                              "Memory": "500",
                              "Essential": "true"
                          }
                      ],
                      "Volumes": [],
                  }
              }
          }
      }
      template1_json = json.dumps(template1)
      cfn_conn = boto3.client('cloudformation', region_name='us-west-1')
      cfn_conn.create_stack(
          StackName="test_stack",
          TemplateBody=template1_json,
      )
  
      template2 = deepcopy(template1)
      template2['Resources']['testTaskDefinition'][
          'Properties']['Family'] = 'testTaskDefinition2'
      template2_json = json.dumps(template2)
      cfn_conn.update_stack(
          StackName="test_stack",
          TemplateBody=template2_json,
      )
  
      ecs_conn = boto3.client('ecs', region_name='us-west-1')
      resp = ecs_conn.list_task_definitions(familyPrefix='testTaskDefinition')
      len(resp['taskDefinitionArns']).should.equal(1)
      resp['taskDefinitionArns'][0].endswith(
          'testTaskDefinition2:1').should.be.true
  
  
  @mock_ecs
  @mock_cloudformation
  def test_create_service_through_cloudformation():
      template = {
          "AWSTemplateFormatVersion": "2010-09-09",
          "Description": "ECS Cluster Test CloudFormation",
          "Resources": {
              "testCluster": {
                  "Type": "AWS::ECS::Cluster",
                  "Properties": {
                      "ClusterName": "testcluster"
                  }
              },
              "testTaskDefinition": {
                  "Type": "AWS::ECS::TaskDefinition",
                  "Properties": {
                      "ContainerDefinitions": [
                          {
                              "Name": "ecs-sample",
                              "Image": "amazon/amazon-ecs-sample",
                              "Cpu": "200",
                              "Memory": "500",
                              "Essential": "true"
                          }
                      ],
                      "Volumes": [],
                  }
              },
              "testService": {
                  "Type": "AWS::ECS::Service",
                  "Properties": {
                      "Cluster": {"Ref": "testCluster"},
                      "DesiredCount": 10,
                      "TaskDefinition": {"Ref": "testTaskDefinition"},
                  }
              }
          }
      }
      template_json = json.dumps(template)
      cfn_conn = boto3.client('cloudformation', region_name='us-west-1')
      cfn_conn.create_stack(
          StackName="test_stack",
          TemplateBody=template_json,
      )
  
      ecs_conn = boto3.client('ecs', region_name='us-west-1')
      resp = ecs_conn.list_services(cluster='testcluster')
      len(resp['serviceArns']).should.equal(1)
  
  
  @mock_ecs
  @mock_cloudformation
  def test_update_service_through_cloudformation_should_trigger_replacement():
      template1 = {
          "AWSTemplateFormatVersion": "2010-09-09",
          "Description": "ECS Cluster Test CloudFormation",
          "Resources": {
              "testCluster": {
                  "Type": "AWS::ECS::Cluster",
                  "Properties": {
                      "ClusterName": "testcluster"
                  }
              },
              "testTaskDefinition": {
                  "Type": "AWS::ECS::TaskDefinition",
                  "Properties": {
                      "ContainerDefinitions": [
                          {
                              "Name": "ecs-sample",
                              "Image": "amazon/amazon-ecs-sample",
                              "Cpu": "200",
                              "Memory": "500",
                              "Essential": "true"
                          }
                      ],
                      "Volumes": [],
                  }
              },
              "testService": {
                  "Type": "AWS::ECS::Service",
                  "Properties": {
                      "Cluster": {"Ref": "testCluster"},
                      "TaskDefinition": {"Ref": "testTaskDefinition"},
                      "DesiredCount": 10,
                  }
              }
          }
      }
      template_json1 = json.dumps(template1)
      cfn_conn = boto3.client('cloudformation', region_name='us-west-1')
      cfn_conn.create_stack(
          StackName="test_stack",
          TemplateBody=template_json1,
      )
      template2 = deepcopy(template1)
      template2['Resources']['testService']['Properties']['DesiredCount'] = 5
      template2_json = json.dumps(template2)
      cfn_conn.update_stack(
          StackName="test_stack",
          TemplateBody=template2_json,
      )
  
      ecs_conn = boto3.client('ecs', region_name='us-west-1')
      resp = ecs_conn.list_services(cluster='testcluster')
      len(resp['serviceArns']).should.equal(1)
  
  
  @mock_ec2
  @mock_ecs
  def test_attributes():
      # Combined put, list delete attributes into the same test due to the amount of setup
      ecs_client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      _ = ecs_client.create_cluster(
          clusterName=test_cluster_name
      )
  
      instances = []
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
      instances.append(test_instance)
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      response = ecs_client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      response['containerInstance'][
          'ec2InstanceId'].should.equal(test_instance.id)
      full_arn1 = response['containerInstance']['containerInstanceArn']
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
      instances.append(test_instance)
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      response = ecs_client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      response['containerInstance'][
          'ec2InstanceId'].should.equal(test_instance.id)
      full_arn2 = response['containerInstance']['containerInstanceArn']
      partial_arn2 = full_arn2.rsplit('/', 1)[-1]
  
      full_arn2.should_not.equal(full_arn1)  # uuid1 isnt unique enough when the pc is fast ;-)
  
      # Ok set instance 1 with 1 attribute, instance 2 with another, and all of them with a 3rd.
      ecs_client.put_attributes(
          cluster=test_cluster_name,
          attributes=[
              {'name': 'env', 'value': 'prod'},
              {'name': 'attr1', 'value': 'instance1', 'targetId': full_arn1},
              {'name': 'attr1', 'value': 'instance2', 'targetId': partial_arn2,
               'targetType': 'container-instance'}
          ]
      )
  
      resp = ecs_client.list_attributes(
          cluster=test_cluster_name,
          targetType='container-instance'
      )
      attrs = resp['attributes']
  
      NUM_CUSTOM_ATTRIBUTES = 4  # 2 specific to individual machines and 1 global, going to both machines (2 + 1*2)
      NUM_DEFAULT_ATTRIBUTES = 4
      len(attrs).should.equal(NUM_CUSTOM_ATTRIBUTES + (NUM_DEFAULT_ATTRIBUTES * len(instances)))
  
      # Tests that the attrs have been set properly
      len(list(filter(lambda item: item['name'] == 'env', attrs))).should.equal(2)
      len(list(
          filter(lambda item: item['name'] == 'attr1' and item['value'] == 'instance1', attrs))).should.equal(1)
  
      ecs_client.delete_attributes(
          cluster=test_cluster_name,
          attributes=[
              {'name': 'attr1', 'value': 'instance2', 'targetId': partial_arn2,
               'targetType': 'container-instance'}
          ]
      )
      NUM_CUSTOM_ATTRIBUTES -= 1
  
      resp = ecs_client.list_attributes(
          cluster=test_cluster_name,
          targetType='container-instance'
      )
      attrs = resp['attributes']
      len(attrs).should.equal(NUM_CUSTOM_ATTRIBUTES + (NUM_DEFAULT_ATTRIBUTES * len(instances)))
  
  
  @mock_ecs
  def test_poll_endpoint():
      # Combined put, list delete attributes into the same test due to the amount of setup
      ecs_client = boto3.client('ecs', region_name='us-east-1')
  
      # Just a placeholder until someone actually wants useless data, just testing it doesnt raise an exception
      resp = ecs_client.discover_poll_endpoint(cluster='blah', containerInstance='blah')
      resp.should.contain('endpoint')
      resp.should.contain('telemetryEndpoint')
  
  
  @mock_ecs
  def test_list_task_definition_families():
      client = boto3.client('ecs', region_name='us-east-1')
      client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      client.register_task_definition(
          family='alt_test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
  
      resp1 = client.list_task_definition_families()
      resp2 = client.list_task_definition_families(familyPrefix='alt')
  
      len(resp1['families']).should.equal(2)
      len(resp2['families']).should.equal(1)
  
  
  @mock_ec2
  @mock_ecs
  def test_default_container_instance_attributes():
      ecs_client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      # Create cluster and EC2 instance
      _ = ecs_client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      # Register container instance
      response = ecs_client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      response['containerInstance'][
          'ec2InstanceId'].should.equal(test_instance.id)
      full_arn = response['containerInstance']['containerInstanceArn']
      container_instance_id = full_arn.rsplit('/', 1)[-1]
  
      default_attributes = response['containerInstance']['attributes']
      assert len(default_attributes) == 4
      expected_result = [
          {'name': 'ecs.availability-zone', 'value': test_instance.placement['AvailabilityZone']},
          {'name': 'ecs.ami-id', 'value': test_instance.image_id},
          {'name': 'ecs.instance-type', 'value': test_instance.instance_type},
          {'name': 'ecs.os-type', 'value': test_instance.platform or 'linux'}
      ]
      assert sorted(default_attributes, key=lambda item: item['name']) == sorted(expected_result,
                                                                                 key=lambda item: item['name'])
  
  
  @mock_ec2
  @mock_ecs
  def test_describe_container_instances_with_attributes():
      ecs_client = boto3.client('ecs', region_name='us-east-1')
      ec2 = boto3.resource('ec2', region_name='us-east-1')
  
      test_cluster_name = 'test_ecs_cluster'
  
      # Create cluster and EC2 instance
      _ = ecs_client.create_cluster(
          clusterName=test_cluster_name
      )
  
      test_instance = ec2.create_instances(
          ImageId="ami-1234abcd",
          MinCount=1,
          MaxCount=1,
      )[0]
  
      instance_id_document = json.dumps(
          ec2_utils.generate_instance_identity_document(test_instance)
      )
  
      # Register container instance
      response = ecs_client.register_container_instance(
          cluster=test_cluster_name,
          instanceIdentityDocument=instance_id_document
      )
  
      response['containerInstance'][
          'ec2InstanceId'].should.equal(test_instance.id)
      full_arn = response['containerInstance']['containerInstanceArn']
      container_instance_id = full_arn.rsplit('/', 1)[-1]
      default_attributes = response['containerInstance']['attributes']
  
      # Set attributes on container instance, one without a value
      attributes = [
          {'name': 'env', 'value': 'prod'},
          {'name': 'attr1', 'value': 'instance1', 'targetId': container_instance_id,
           'targetType': 'container-instance'},
          {'name': 'attr_without_value'}
      ]
      ecs_client.put_attributes(
          cluster=test_cluster_name,
          attributes=attributes
      )
  
      # Describe container instance, should have attributes previously set
      described_instance = ecs_client.describe_container_instances(cluster=test_cluster_name,
                                                                   containerInstances=[container_instance_id])
  
      assert len(described_instance['containerInstances']) == 1
      assert isinstance(described_instance['containerInstances'][0]['attributes'], list)
  
      # Remove additional info passed to put_attributes
      cleaned_attributes = []
      for attribute in attributes:
          attribute.pop('targetId', None)
          attribute.pop('targetType', None)
          cleaned_attributes.append(attribute)
      described_attributes = sorted(described_instance['containerInstances'][0]['attributes'],
                                    key=lambda item: item['name'])
      expected_attributes = sorted(default_attributes + cleaned_attributes, key=lambda item: item['name'])
      assert described_attributes == expected_attributes
  
  
  def _fetch_container_instance_resources(container_instance_description):
      remaining_resources = {}
      registered_resources = {}
      remaining_resources_list = container_instance_description['remainingResources']
      registered_resources_list = container_instance_description['registeredResources']
      remaining_resources['CPU'] = [x['integerValue'] for x in remaining_resources_list if x['name'] == 'CPU'][
          0]
      remaining_resources['MEMORY'] = \
      [x['integerValue'] for x in remaining_resources_list if x['name'] == 'MEMORY'][0]
      remaining_resources['PORTS'] = \
      [x['stringSetValue'] for x in remaining_resources_list if x['name'] == 'PORTS'][0]
      registered_resources['CPU'] = \
      [x['integerValue'] for x in registered_resources_list if x['name'] == 'CPU'][0]
      registered_resources['MEMORY'] = \
      [x['integerValue'] for x in registered_resources_list if x['name'] == 'MEMORY'][0]
      registered_resources['PORTS'] = \
      [x['stringSetValue'] for x in registered_resources_list if x['name'] == 'PORTS'][0]
      return remaining_resources, registered_resources
  
  
  @mock_ecs
  def test_create_service_load_balancing():
      client = boto3.client('ecs', region_name='us-east-1')
      client.create_cluster(
          clusterName='test_ecs_cluster'
      )
      client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ]
      )
      response = client.create_service(
          cluster='test_ecs_cluster',
          serviceName='test_ecs_service',
          taskDefinition='test_ecs_task',
          desiredCount=2,
          loadBalancers=[
              {
                  'targetGroupArn': 'test_target_group_arn',
                  'loadBalancerName': 'test_load_balancer_name',
                  'containerName': 'test_container_name',
                  'containerPort': 123
              }
          ]
      )
      response['service']['clusterArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:cluster/test_ecs_cluster')
      response['service']['desiredCount'].should.equal(2)
      len(response['service']['events']).should.equal(0)
      len(response['service']['loadBalancers']).should.equal(1)
      response['service']['loadBalancers'][0]['targetGroupArn'].should.equal(
          'test_target_group_arn')
      response['service']['loadBalancers'][0]['loadBalancerName'].should.equal(
          'test_load_balancer_name')
      response['service']['loadBalancers'][0]['containerName'].should.equal(
          'test_container_name')
      response['service']['loadBalancers'][0]['containerPort'].should.equal(123)
      response['service']['pendingCount'].should.equal(0)
      response['service']['runningCount'].should.equal(0)
      response['service']['serviceArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:service/test_ecs_service')
      response['service']['serviceName'].should.equal('test_ecs_service')
      response['service']['status'].should.equal('ACTIVE')
      response['service']['taskDefinition'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')
  
  
  @mock_ecs
  def test_list_tags_for_resource():
      client = boto3.client('ecs', region_name='us-east-1')
      response = client.register_task_definition(
          family='test_ecs_task',
          containerDefinitions=[
              {
                  'name': 'hello_world',
                  'image': 'docker/hello-world:latest',
                  'cpu': 1024,
                  'memory': 400,
                  'essential': True,
                  'environment': [{
                      'name': 'AWS_ACCESS_KEY_ID',
                      'value': 'SOME_ACCESS_KEY'
                  }],
                  'logConfiguration': {'logDriver': 'json-file'}
              }
          ],
          tags=[
              {'key': 'createdBy', 'value': 'moto-unittest'},
              {'key': 'foo', 'value': 'bar'},
          ]
      )
      type(response['taskDefinition']).should.be(dict)
      response['taskDefinition']['revision'].should.equal(1)
      response['taskDefinition']['taskDefinitionArn'].should.equal(
          'arn:aws:ecs:us-east-1:012345678910:task-definition/test_ecs_task:1')
  
      task_definition_arn = response['taskDefinition']['taskDefinitionArn']
      response = client.list_tags_for_resource(resourceArn=task_definition_arn)
  
      type(response['tags']).should.be(list)
      response['tags'].should.equal([
          {'key': 'createdBy', 'value': 'moto-unittest'},
          {'key': 'foo', 'value': 'bar'},
      ])
  
  
  @mock_ecs
  def test_list_tags_for_resource_unknown():
      client = boto3.client('ecs', region_name='us-east-1')
      task_definition_arn = 'arn:aws:ecs:us-east-1:012345678910:task-definition/unknown:1'
      try:
          client.list_tags_for_resource(resourceArn=task_definition_arn)
      except ClientError as err:
          err.response['Error']['Code'].should.equal('ClientException')
  