1# Licensed to the Apache Software Foundation (ASF) under one or more 2# contributor license agreements. See the NOTICE file distributed with 3# this work for additional information regarding copyright ownership. 4# The ASF licenses this file to You under the Apache License, Version 2.0 5# (the "License"); you may not use this file except in compliance with 6# the License. You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import sys 17 18from libcloud.test import unittest 19 20from libcloud.container.base import ContainerCluster, ContainerImage, Container 21from libcloud.container.drivers.ecs import ElasticContainerDriver 22from libcloud.container.utils.docker import RegistryClient 23 24from libcloud.utils.py3 import httplib 25from libcloud.test.secrets import CONTAINER_PARAMS_ECS 26from libcloud.test.file_fixtures import ContainerFileFixtures 27from libcloud.test import MockHttp 28 29 30class ElasticContainerDriverTestCase(unittest.TestCase): 31 32 def setUp(self): 33 ElasticContainerDriver.connectionCls.conn_class = ECSMockHttp 34 ECSMockHttp.type = None 35 ECSMockHttp.use_param = 'a' 36 ElasticContainerDriver.ecrConnectionClass.conn_class = ECSMockHttp 37 38 self.driver = ElasticContainerDriver(*CONTAINER_PARAMS_ECS) 39 40 def test_list_clusters(self): 41 clusters = self.driver.list_clusters() 42 self.assertEqual(len(clusters), 1) 43 self.assertEqual(clusters[0].id, 'arn:aws:ecs:us-east-1:012345678910:cluster/default') 44 self.assertEqual(clusters[0].name, 'default') 45 46 def test_create_cluster(self): 47 cluster = self.driver.create_cluster('my-cluster') 48 self.assertEqual(cluster.name, 'my-cluster') 49 50 def test_destroy_cluster(self): 51 self.assertTrue( 52 self.driver.destroy_cluster( 53 ContainerCluster( 54 id='arn:aws:ecs:us-east-1:012345678910:cluster/jim', 55 name='jim', 56 driver=self.driver))) 57 58 def test_list_containers(self): 59 containers = self.driver.list_containers() 60 self.assertEqual(len(containers), 1) 61 62 def test_list_containers_for_cluster(self): 63 cluster = self.driver.list_clusters()[0] 64 containers = self.driver.list_containers(cluster=cluster) 65 self.assertEqual(len(containers), 1) 66 67 def test_deploy_container(self): 68 container = self.driver.deploy_container( 69 name='jim', 70 image=ContainerImage( 71 id=None, 72 name='mysql', 73 path='mysql', 74 version=None, 75 driver=self.driver 76 ) 77 ) 78 self.assertEqual(container.id, 'arn:aws:ecs:ap-southeast-2:647433528374:container/e443d10f-dea3-481e-8a1e-966b9ad4e498') 79 80 def test_get_container(self): 81 container = self.driver.get_container( 82 'arn:aws:ecs:us-east-1:012345678910:container/76c980a8-2454-4a9c-acc4-9eb103117273' 83 ) 84 self.assertEqual(container.id, 'arn:aws:ecs:ap-southeast-2:647433528374:container/d56d4e2c-9804-42a7-9f2a-6029cb50d4a2') 85 self.assertEqual(container.name, 'simple-app') 86 self.assertEqual(container.image.name, 'simple-app') 87 88 def test_start_container(self): 89 container = self.driver.start_container( 90 Container( 91 id=None, 92 name=None, 93 image=None, 94 state=None, 95 ip_addresses=None, 96 driver=self.driver, 97 extra={ 98 'taskDefinitionArn': '' 99 } 100 ) 101 ) 102 self.assertFalse(container is None) 103 104 def test_stop_container(self): 105 container = self.driver.stop_container( 106 Container( 107 id=None, 108 name=None, 109 image=None, 110 state=None, 111 ip_addresses=None, 112 driver=self.driver, 113 extra={ 114 'taskArn': '12345', 115 'taskDefinitionArn': '123556' 116 } 117 ) 118 ) 119 self.assertFalse(container is None) 120 121 def test_restart_container(self): 122 container = self.driver.restart_container( 123 Container( 124 id=None, 125 name=None, 126 image=None, 127 state=None, 128 ip_addresses=None, 129 driver=self.driver, 130 extra={ 131 'taskArn': '12345', 132 'taskDefinitionArn': '123556' 133 } 134 ) 135 ) 136 self.assertFalse(container is None) 137 138 def test_list_images(self): 139 images = self.driver.list_images('my-images') 140 self.assertEqual(len(images), 1) 141 self.assertEqual(images[0].name, '647433528374.dkr.ecr.region.amazonaws.com/my-images:latest') 142 143 def test_ex_create_service(self): 144 cluster = self.driver.list_clusters()[0] 145 task_definition = self.driver.list_containers()[0].extra['taskDefinitionArn'] 146 service = self.driver.ex_create_service(cluster=cluster, 147 name='jim', 148 task_definition=task_definition) 149 self.assertEqual(service['serviceName'], 'test') 150 151 def test_ex_list_service_arns(self): 152 arns = self.driver.ex_list_service_arns() 153 self.assertEqual(len(arns), 2) 154 155 def test_ex_describe_service(self): 156 arn = self.driver.ex_list_service_arns()[0] 157 service = self.driver.ex_describe_service(arn) 158 self.assertEqual(service['serviceName'], 'test') 159 160 def test_ex_destroy_service(self): 161 arn = self.driver.ex_list_service_arns()[0] 162 service = self.driver.ex_destroy_service(arn) 163 self.assertEqual(service['status'], 'DRAINING') 164 165 def test_ex_get_registry_client(self): 166 client = self.driver.ex_get_registry_client('my-images') 167 self.assertIsInstance(client, RegistryClient) 168 169 170class ECSMockHttp(MockHttp): 171 fixtures = ContainerFileFixtures('ecs') 172 fixture_map = { 173 'DescribeClusters': 'describeclusters.json', 174 'CreateCluster': 'createcluster.json', 175 'DeleteCluster': 'deletecluster.json', 176 'DescribeTasks': 'describetasks.json', 177 'ListTasks': 'listtasks.json', 178 'ListClusters': 'listclusters.json', 179 'RegisterTaskDefinition': 'registertaskdefinition.json', 180 'RunTask': 'runtask.json', 181 'StopTask': 'stoptask.json', 182 'ListImages': 'listimages.json', 183 'DescribeRepositories': 'describerepositories.json', 184 'CreateService': 'createservice.json', 185 'ListServices': 'listservices.json', 186 'DescribeServices': 'describeservices.json', 187 'DeleteService': 'deleteservice.json', 188 'GetAuthorizationToken': 'getauthorizationtoken.json' 189 } 190 191 def root(self, method, url, body, headers): 192 target = headers['x-amz-target'] 193 194 # Workaround for host not being correctly set for the tests 195 if '%s' in self.host: 196 self.host = self.host % ('region') 197 198 if target is not None: 199 type = target.split('.')[-1] 200 if type is None or self.fixture_map.get(type) is None: 201 raise AssertionError('Unsupported request type %s' % (target)) 202 body = self.fixtures.load(self.fixture_map.get(type)) 203 else: 204 raise AssertionError('Unsupported method') 205 return (httplib.OK, body, {}, httplib.responses[httplib.OK]) 206 207if __name__ == '__main__': 208 sys.exit(unittest.main()) 209