Best Python code snippet using localstack_python
test_register_service.py
Source:test_register_service.py
1import sys2import json3import datetime4import unittest5from contextlib import ExitStack6from unittest import mock7from unittest.mock import MagicMock8import mimesis9from deploy2ecscli.app import App10class TestRegisterService(unittest.TestCase):11 DEFAULT_YAML = """12 integration:13 images:14 task_definitions: 15 services:16 - name: example_application17 cluster: ecs-cluster18 task_family: example_application19 template: ./config/application.yaml20 bind_variables:21 - name: ACCOUNT_ID22 value: 9999999923 before_deploy:24 tasks:25 - task_family: migrate26 cluster: ecs-cluster27 template: ./config/migrate.yaml28 """29 TEMPLATE_SERVICE_YAML = """30 cluster: !Ref CLUSTER_NAME31 serviceName: !Ref SERVICE_NAME32 taskDefinition: !Ref TASK_DEFINITION_ARN33 loadBalancers:34 - containerPort: 8035 containerName: nginx36 targetGroupArn: !Ref TARGET_GROUP_ARN37 desiredCount: 238 launchType: FARGATE39 platformVersion: LATEST40 deploymentConfiguration:41 minimumHealthyPercent: 10042 maximumPercent: 20043 networkConfiguration:44 awsvpcConfiguration:45 securityGroups: !Split46 - ","47 - !Ref SECURITY_GROUPS48 subnets: !Split49 - ","50 - !Ref SUBNETS51 assignPublicIp: ENABLED52 healthCheckGracePeriodSeconds: 053 schedulingStrategy: REPLICA54 enableECSManagedTags: false55 tags:56 - key: JSON_COMMIT_HASH57 value: !Ref JSON_COMMIT_HASH58 """59 TEMPLATE_ONETIME_TASK_YAML = """60 cluster: !Ref CLUSTER_NAME61 taskDefinition: !Ref TASK_DEFINITION_ARN62 launchType: FARGATE63 platformVersion: LATEST64 networkConfiguration:65 awsvpcConfiguration:66 securityGroups: !Split67 - ","68 - !Ref SECURITY_GROUPS69 subnets: !Split70 - ","71 - !Ref SUBNETS72 assignPublicIp: ENABLED73 """74 TEMPLATE_MAPPING = {75 './config/application.yaml': TEMPLATE_SERVICE_YAML,76 './config/migrate.yaml': TEMPLATE_ONETIME_TASK_YAML77 }78 RESPONSE_SERVICES_TEMPLATE = """{79 "services": [80 {81 "serviceArn": "arn:aws:ecs:REGION:ACCOUNT_ID:service/ecs-cluster/example_application",82 "serviceName": "example_application",83 "clusterArn": "arn:aws:ecs:REGION:ACCOUNT_ID:cluster/ecs-cluster",84 "loadBalancers": [85 {86 "targetGroupArn": "arn:aws:elasticloadbalancing:REGION:ACCOUNT_ID:targetgroup/ecs-cluster/xxxxXXXXxxxxXXXX",87 "containerName": "nginx",88 "containerPort": 8089 }90 ],91 "serviceRegistries": [],92 "status": "{{status}}",93 "desiredCount": 2,94 "runningCount": 2,95 "pendingCount": 0,96 "launchType": "FARGATE",97 "platformVersion": "LATEST",98 "taskDefinition": "arn:aws:ecs:REGION:ACCOUNT_ID:task-definition/example_application:{{revision}}",99 "deploymentConfiguration": {100 "maximumPercent": 200,101 "minimumHealthyPercent": 100102 },103 "deployments": [104 {105 "id": "ecs-svc/9999999999999999999",106 "status": "PRIMARY",107 "taskDefinition": "arn:aws:ecs:REGION:ACCOUNT_ID:task-definition/example_application:{{revision}}",108 "desiredCount": 2,109 "pendingCount": 0,110 "runningCount": 2,111 "createdAt": "2019-10-25T20:41:04.312000+09:00",112 "updatedAt": "2019-10-25T20:44:57.843000+09:00",113 "launchType": "FARGATE",114 "platformVersion": "1.3.0",115 "networkConfiguration": {116 "awsvpcConfiguration": {117 "subnets": [118 "subnet-xxxxxxx1",119 "subnet-xxxxxxx2",120 "subnet-xxxxxxx3"121 ],122 "securityGroups": [123 "sg-xxxxxxxx"124 ],125 "assignPublicIp": "ENABLED"126 }127 }128 }129 ],130 "roleArn": "arn:aws:iam::ACCOUNT_ID:role/aws-service-role/ecs.amazonaws.com/AWSServiceRoleForECS",131 "createdAt": "2019-10-24T13:30:06.215000+09:00",132 "placementConstraints": [],133 "placementStrategy": [],134 "networkConfiguration": {135 "awsvpcConfiguration": {136 "subnets": [137 "subnet-xxxxxxx1",138 "subnet-xxxxxxx2",139 "subnet-xxxxxxx3"140 ],141 "securityGroups": [142 "sg-xxxxxxxx"143 ],144 "assignPublicIp": "ENABLED"145 }146 },147 "healthCheckGracePeriodSeconds": 0,148 "schedulingStrategy": "REPLICA",149 "enableECSManagedTags": false,150 "propagateTags": "NONE",151 "tags": [152 {153 "key": "JSON_COMMIT_HASH",154 "value": "{{json_commit_hash}}"155 }156 ]157 }158 ],159 "failures": [],160 "ResponseMetadata": {161 "RequestId": "8022c17e-9865-43dc-80bd-f87eaa11e7bc",162 "HTTPStatusCode": 200,163 "HTTPHeaders": {164 "x-amzn-requestid": "8022c17e-9865-43dc-80bd-f87eaa11e7bc",165 "content-type": "application/x-amz-json-1.1",166 "content-length": "20872",167 "date": "Wed, 30 Oct 2019 11:57:06 GMT"168 },169 "RetryAttempts": 0170 }171 }172 """173 RESPONSE_TASK_DEFINITION_TEMPLATE = """{174 "taskDefinition": {175 "taskDefinitionArn": "arn:aws:ecs:REGION:ACCOUNT_ID:task-definition/example_application:{{revision}}",176 "containerDefinitions": [177 {178 "name": "nginx",179 "image": "ACCOUNT_ID.dkr.ecr.REGION.amazonaws.com/example_application/nginx:1",180 "cpu": 0,181 "portMappings": [182 {183 "containerPort": 80,184 "hostPort": 80,185 "protocol": "tcp"186 }187 ],188 "essential": true,189 "mountPoints": [],190 "volumesFrom": [191 {192 "sourceContainer": "app",193 "readOnly": true194 }195 ],196 "dependsOn": [197 {198 "containerName": "app",199 "condition": "HEALTHY"200 }201 ],202 "logConfiguration": {203 "logDriver": "awslogs",204 "options": {205 "awslogs-group": "/ecs/example_application",206 "awslogs-region": "REGION",207 "awslogs-stream-prefix": "ecs"208 }209 },210 "healthCheck": {211 "command": [212 "CMD-SHELL",213 "wget -q -O /dev/null http://localhost/healthcheck || exit 1"214 ],215 "interval": 5,216 "timeout": 5,217 "retries": 5,218 "startPeriod": 10219 }220 },221 {222 "name": "app",223 "image": "ACCOUNT_ID.dkr.ecr.REGION.amazonaws.com/example_application/app:1",224 "cpu": 0,225 "memoryReservation": 500,226 "portMappings": [],227 "essential": true,228 "mountPoints": [],229 "volumesFrom": [],230 "logConfiguration": {231 "logDriver": "awslogs",232 "options": {233 "awslogs-group": "/ecs/example_application",234 "awslogs-region": "REGION",235 "awslogs-stream-prefix": "ecs"236 }237 },238 "healthCheck": {239 "command": [240 "CMD-SHELL",241 "ls /var/run/app/puma.sock || exit 1"242 ],243 "interval": 5,244 "timeout": 5,245 "retries": 5,246 "startPeriod": 10247 }248 }249 ],250 "family": "example_application",251 "taskRoleArn": "arn:aws:iam::ACCOUNT_ID:role/ecsTaskExecutionRole",252 "executionRoleArn": "arn:aws:iam::ACCOUNT_ID:role/ecsTaskExecutionRole",253 "networkMode": "awsvpc",254 "revision": 1,255 "volumes": [],256 "status": "ACTIVE",257 "placementConstraints": [],258 "compatibilities": [259 "EC2",260 "FARGATE"261 ],262 "requiresCompatibilities": [263 "FARGATE"264 ],265 "cpu": "512",266 "memory": "1024"267 },268 "tags": [269 {270 "key": "JSON_COMMIT_HASH",271 "value": "{{json_commit_hash}}"272 }273 ],274 "ResponseMetadata": {275 "RequestId": "1c418748-b05f-4d3d-88df-0dcf5d414c03",276 "HTTPStatusCode": 200,277 "HTTPHeaders": {278 "x-amzn-requestid": "1c418748-b05f-4d3d-88df-0dcf5d414c03",279 "content-type": "application/x-amz-json-1.1",280 "content-length": "2877",281 "date": "Wed, 30 Oct 2019 12:15:52 GMT"282 },283 "RetryAttempts": 0284 }285 }286 """287 def __subprocer_run(self, command):288 if command.startswith('git rev-parse --is-inside-work-tree'):289 return MagicMock(returncode=0, stdout=b'true')290 if command.startswith('git --no-pager name-rev --name-only HEAD'):291 return MagicMock(returncode=0, stdout=b'integration')292 if command.startswith('git --no-pager log -n 1 --pretty=oneline'):293 stdout = '{0} {1}'294 stdout = stdout.format(295 mimesis.Cryptographic().token_hex(),296 mimesis.Text().sentence())297 return MagicMock(returncode=0, stdout=stdout.encode('utf8'))298 if command.startswith('git --no-pager log -n 1'):299 stdout = '{0} {1}'300 stdout = stdout.format(301 mimesis.Cryptographic().token_hex(),302 mimesis.Text().sentence())303 return MagicMock(returncode=0, stdout=stdout.encode('utf8'))304 return MagicMock(returncode=127, stderr=b'command not found')305 def test_when_service_inactive(self):306 with ExitStack() as stack:307 params = [308 'deploy2ecs',309 'register-service',310 '--config', mimesis.File().file_name(),311 '-q'312 ]313 stack.enter_context(mock.patch.object(sys, 'argv', params))314 describe_services = \315 self.RESPONSE_SERVICES_TEMPLATE \316 .replace('{', '{{') \317 .replace('}', '}}') \318 .replace('{{{{', '{') \319 .replace('}}}}', '}') \320 .format(321 status='INACTIVE',322 revision=100,323 json_commit_hash=mimesis.Cryptographic().token_hex()324 )325 describe_services = json.loads(describe_services)326 mock_aws = stack.enter_context(mock.patch('boto3.client'))327 mock_aws = mock_aws.return_value328 mock_aws.describe_services.return_value = \329 describe_services330 mock_aws.describe_tasks.return_value = {331 'tasks': [332 {333 'taskArn': mimesis.Cryptographic.token_hex(),334 'lastStatus': 'STOPPED',335 'containers': [336 {'name': mimesis.File().file_name(), 'exitCode': 0}337 ]338 }339 ],340 'failures': []341 }342 mock_aws.de343 mock_subprocer = \344 stack.enter_context(mock.patch('subprocess.run'))345 mock_subprocer.side_effect = \346 lambda x, **_: self.__subprocer_run(x)347 stack.enter_context(mock.patch(348 'deploy2ecscli.app.open', mock.mock_open(read_data=self.DEFAULT_YAML)))349 config_open = MagicMock()350 config_open.side_effect = \351 lambda x: mock.mock_open(352 read_data=(self.TEMPLATE_MAPPING[x]))\353 .return_value354 stack.enter_context(mock.patch(355 'deploy2ecscli.config.open', config_open))356 App().run()357 mock_aws.run_task.assert_called()358 mock_aws.create_service.assert_called()359 mock_aws.update_service.assert_not_called()360 mock_aws.tag_resource.assert_not_called()361 def test_when_unmatch_task_definition_revision(self):362 with ExitStack() as stack:363 params = [364 'deploy2ecs',365 'register-service',366 '--config', mimesis.File().file_name(),367 '-q'368 ]369 stack.enter_context(mock.patch.object(sys, 'argv', params))370 describe_task_definition = \371 self.RESPONSE_TASK_DEFINITION_TEMPLATE \372 .replace('{', '{{') \373 .replace('}', '}}') \374 .replace('{{{{', '{') \375 .replace('}}}}', '}') \376 .format(377 revision=101,378 json_commit_hash=mimesis.Cryptographic().token_hex()379 )380 describe_task_definition = json.loads(describe_task_definition)381 describe_services = \382 self.RESPONSE_SERVICES_TEMPLATE \383 .replace('{', '{{') \384 .replace('}', '}}') \385 .replace('{{{{', '{') \386 .replace('}}}}', '}') \387 .format(388 status='ACTIVE',389 revision=100,390 json_commit_hash=mimesis.Cryptographic().token_hex()391 )392 describe_services = json.loads(describe_services)393 mock_aws = stack.enter_context(mock.patch('boto3.client'))394 mock_aws = mock_aws.return_value395 mock_aws.describe_services.return_value = \396 describe_services397 mock_aws.describe_task_definition.return_value = \398 describe_task_definition399 mock_aws.describe_tasks.return_value = {400 'tasks': [401 {402 'taskArn': mimesis.Cryptographic.token_hex(),403 'lastStatus': 'STOPPED',404 'containers': [405 {'name': mimesis.File().file_name(), 'exitCode': 0}406 ]407 }408 ],409 'failures': []410 }411 mock_subprocer = \412 stack.enter_context(mock.patch('subprocess.run'))413 mock_subprocer.side_effect = \414 lambda x, **_: self.__subprocer_run(x)415 stack.enter_context(mock.patch(416 'deploy2ecscli.app.open', mock.mock_open(read_data=self.DEFAULT_YAML)))417 config_open = MagicMock()418 config_open.side_effect = \419 lambda x: mock.mock_open(420 read_data=(self.TEMPLATE_MAPPING[x]))\421 .return_value422 stack.enter_context(mock.patch(423 'deploy2ecscli.config.open', config_open))424 App().run()425 mock_aws.run_task.assert_called()426 mock_aws.create_service.assert_not_called()427 mock_aws.update_service.assert_called()428 mock_aws.tag_resource.assert_called()429 def test_when_json_commit_hash_empty(self):430 with ExitStack() as stack:431 params = [432 'deploy2ecs',433 'register-service',434 '--config', mimesis.File().file_name(),435 '-q'436 ]437 stack.enter_context(mock.patch.object(sys, 'argv', params))438 describe_task_definition = \439 self.RESPONSE_TASK_DEFINITION_TEMPLATE \440 .replace('{', '{{') \441 .replace('}', '}}') \442 .replace('{{{{', '{') \443 .replace('}}}}', '}') \444 .format(445 revision=100,446 json_commit_hash=mimesis.Cryptographic().token_hex()447 )448 describe_task_definition = json.loads(describe_task_definition)449 describe_services = \450 self.RESPONSE_SERVICES_TEMPLATE \451 .replace('{', '{{') \452 .replace('}', '}}') \453 .replace('{{{{', '{') \454 .replace('}}}}', '}') \455 .format(456 status='ACTIVE',457 revision=100,458 json_commit_hash='')459 describe_services = json.loads(describe_services)460 mock_aws = stack.enter_context(mock.patch('boto3.client'))461 mock_aws = mock_aws.return_value462 mock_aws.describe_services.return_value = \463 describe_services464 mock_aws.describe_task_definition.return_value = \465 describe_task_definition466 mock_aws.run_task.return_value = {467 'tasks': [468 {469 'taskArn': mimesis.Cryptographic.token_hex(),470 'lastStatus': 'STOPPED',471 'containers': [472 {'name': mimesis.File().file_name(), 'exitCode': 0}473 ]474 }475 ],476 'failures': []477 }478 mock_aws.describe_tasks.return_value = {479 'tasks': [480 {481 'taskArn': mimesis.Cryptographic.token_hex(),482 'lastStatus': 'STOPPED',483 'containers': [484 {'name': mimesis.File().file_name(), 'exitCode': 0}485 ]486 }487 ],488 'failures': []489 }490 mock_subprocer = \491 stack.enter_context(mock.patch('subprocess.run'))492 mock_subprocer.side_effect = \493 lambda x, **_: self.__subprocer_run(x)494 stack.enter_context(mock.patch(495 'deploy2ecscli.app.open', mock.mock_open(read_data=self.DEFAULT_YAML)))496 config_open = MagicMock()497 config_open.side_effect = \498 lambda x: mock.mock_open(499 read_data=(self.TEMPLATE_MAPPING[x]))\500 .return_value501 stack.enter_context(mock.patch(502 'deploy2ecscli.config.open', config_open))503 App().run()504 mock_aws.run_task.assert_called()505 mock_aws.create_service.assert_not_called()506 mock_aws.update_service.assert_called()507 mock_aws.tag_resource.assert_called()508 def test_when_unmatch_json_commit_hash(self):509 with ExitStack() as stack:510 params = [511 'deploy2ecs',512 'register-service',513 '--config', mimesis.File().file_name(),514 '-q'515 ]516 stack.enter_context(mock.patch.object(sys, 'argv', params))517 describe_task_definition = \518 self.RESPONSE_TASK_DEFINITION_TEMPLATE \519 .replace('{', '{{') \520 .replace('}', '}}') \521 .replace('{{{{', '{') \522 .replace('}}}}', '}') \523 .format(524 revision=100,525 json_commit_hash=mimesis.Cryptographic().token_hex()526 )527 describe_task_definition = json.loads(describe_task_definition)528 describe_services = \529 self.RESPONSE_SERVICES_TEMPLATE \530 .replace('{', '{{') \531 .replace('}', '}}') \532 .replace('{{{{', '{') \533 .replace('}}}}', '}') \534 .format(535 status='ACTIVE',536 revision=100,537 json_commit_hash=mimesis.Cryptographic().token_hex()538 )539 describe_services = json.loads(describe_services)540 mock_aws = stack.enter_context(mock.patch('boto3.client'))541 mock_aws = mock_aws.return_value542 mock_aws.describe_services.return_value = \543 describe_services544 mock_aws.describe_task_definition.return_value = \545 describe_task_definition546 mock_aws.run_task.return_value = {547 'tasks': [548 {549 'taskArn': mimesis.Cryptographic.token_hex(),550 'lastStatus': 'STOPPED',551 'containers': [552 {'name': mimesis.File().file_name(), 'exitCode': 0}553 ]554 }555 ],556 'failures': []557 }558 mock_aws.describe_tasks.return_value = {559 'tasks': [560 {561 'taskArn': mimesis.Cryptographic.token_hex(),562 'lastStatus': 'STOPPED',563 'containers': [564 {'name': mimesis.File().file_name(), 'exitCode': 0}565 ]566 }567 ],568 'failures': []569 }570 mock_subprocer = \571 stack.enter_context(mock.patch('subprocess.run'))572 mock_subprocer.side_effect = \573 lambda x, **_: self.__subprocer_run(x)574 stack.enter_context(mock.patch(575 'deploy2ecscli.app.open', mock.mock_open(read_data=self.DEFAULT_YAML)))576 config_open = MagicMock()577 config_open.side_effect = \578 lambda x: mock.mock_open(579 read_data=(self.TEMPLATE_MAPPING[x]))\580 .return_value581 stack.enter_context(mock.patch(582 'deploy2ecscli.config.open', config_open))583 App().run()584 mock_aws.run_task.assert_called()585 mock_aws.create_service.assert_not_called()586 mock_aws.update_service.assert_called()...
ecs_utils_test.py
Source:ecs_utils_test.py
1"""Test case for ecs_utils."""2import copy3import datetime4import unittest5from unittest import TestCase6from unittest.mock import patch7import scripts.ecs_utils as ecs_utils8# speed up the polling9ecs_utils.SLEEP_TIME_S = 010# note: we override time.time()11POLL_S = 1012GOOD_SERVICE = {13 'services': [{14 'serviceName': 'service-foo',15 'runningCount': 2,16 'desiredCount': 2,17 'deployments': [{18 'runningCount': 2,19 'desiredCount': 2,20 'status': 'PRIMARY',21 'rolloutState': 'COMPLETED',22 'createdAt': datetime.time()23 }]24 }]25}26INPROGRESS_SERVICE = copy.deepcopy(GOOD_SERVICE)27INPROGRESS_SERVICE['services'][0]['deployments'][0]['rolloutState'] = 'IN_PROGRESS'28BAD_SERVICE = copy.deepcopy(GOOD_SERVICE)29BAD_SERVICE['services'][0]['deployments'][0]['status'] = 'BAD'30BAD_SERVICE['services'][0]['deployments'][0]['rolloutState'] = 'BAD'31BAD_SERVICE['services'][0]['runningCount'] = 132INACTIVE_SERVICE = copy.deepcopy(GOOD_SERVICE)33INACTIVE_SERVICE['services'][0]['desiredCount'] = 034INACTIVE_SERVICE['services'][0]['runningCount'] = 0 35BAD_TASKS = {'tasks': [36 {'healthStatus': 'HEALTHY', 'taskArn': 'foo'},37 {'healthStatus': 'UNHEALTHY', 'taskArn': 'bar'}38]}39GOOD_TASKS = {'tasks': [40 {'healthStatus': 'HEALTHY', 'taskArn': 'foo'},41 {'healthStatus': 'HEALTHY', 'taskArn': 'bar'}42]}43TASKS = {44 'taskArns': ['foo', 'bar'],45 'nextoken': None46}47EMPTY_TASKS = copy.deepcopy(TASKS)48EMPTY_TASKS['taskArns'] = []49class EcsTestCase(TestCase):50 """Test the ecs utils module."""51 def setUp(self):52 # time will advance by 1sec every polling iteration53 self.patcher = patch('time.time')54 self.mock_time = self.patcher.start()55 self.mock_time.side_effect = list(range(100))56 self.addCleanup(self.patcher.stop)57 @patch('boto3.client')58 def test_poll_cluster_positive(self, mock_boto):59 mock_client = mock_boto.return_value60 mock_client.describe_services.return_value = GOOD_SERVICE61 mock_client.list_tasks.return_value = TASKS62 mock_client.describe_tasks.return_value = GOOD_TASKS63 ecs_utils.poll_cluster_state(mock_client, 'cluster-foo', ['service-foo'], POLL_S)64 @patch('boto3.client')65 def test_poll_cluster_new_arn(self, mock_boto):66 mock_client = mock_boto.return_value67 mock_client.describe_services.return_value = GOOD_SERVICE68 mock_client.list_tasks.return_value = TASKS69 mock_client.describe_tasks.return_value = GOOD_TASKS70 ecs_utils.poll_cluster_state(mock_client, 'cluster-foo', ['cluster-foo/service-foo'], POLL_S)71 @patch('boto3.client')72 def test_poll_cluster_matching_cluster_and_service_name(self, mock_boto):73 mock_client = mock_boto.return_value74 mock_client.describe_services.return_value = GOOD_SERVICE75 mock_client.list_tasks.return_value = TASKS76 mock_client.describe_tasks.return_value = GOOD_TASKS77 ecs_utils.poll_cluster_state(mock_client, 'service-foo', ['service-foo'], POLL_S)78 @patch('boto3.client')79 def test_poll_cluster_with_inactive_service(self, mock_boto):80 mock_client = mock_boto.return_value81 mock_client.describe_services.return_value = INACTIVE_SERVICE82 mock_client.list_tasks.return_value = EMPTY_TASKS83 mock_client.describe_tasks.side_effect = Exception('Tasks cannot be empty.')84 ecs_utils.poll_cluster_state(mock_client, 'cluster-foo', ['service-foo'], POLL_S)85 @patch('scripts.ecs_utils.print_events')86 @patch('boto3.client')87 def test_poll_cluster_timeout(self, mock_boto, mock_print_events):88 mock_client = mock_boto.return_value89 mock_client.describe_services.return_value = BAD_SERVICE90 with self.assertRaises(ecs_utils.TimeoutException):91 ecs_utils.poll_cluster_state(mock_client, 'cluster-foo', ['service-foo'], POLL_S)92 @patch('scripts.ecs_utils.print_events')93 @patch('boto3.client')94 def test_poll_cluster_bad_tasks(self, mock_boto, mock_print_events):95 mock_client = mock_boto.return_value96 mock_client.describe_services.return_value = GOOD_SERVICE97 mock_client.list_tasks.return_value = TASKS98 mock_client.describe_tasks.return_value = BAD_TASKS99 with self.assertRaises(ecs_utils.TimeoutException):100 ecs_utils.poll_cluster_state(mock_client, 'cluster-foo', ['service-foo'], POLL_S)101 @patch('scripts.ecs_utils.print_events')102 @patch('boto3.client')103 def test_poll_deployment_positive(self, mock_boto, mock_print_events):104 mock_client = mock_boto.return_value105 mock_client.describe_services.return_value = GOOD_SERVICE106 mock_client.list_tasks.return_value = TASKS107 mock_client.describe_tasks.side_effect = [BAD_TASKS, GOOD_TASKS]108 ecs_utils.poll_deployment_state(mock_client, 'cluster-foo', 'service-foo', POLL_S)109 @patch('scripts.ecs_utils.print_events')110 @patch('boto3.client')111 def test_poll_deployment_in_progres_timeout(self, mock_boto, mock_print_events):112 mock_client = mock_boto.return_value113 mock_client.describe_services.return_value = INPROGRESS_SERVICE114 with self.assertRaises(ecs_utils.TimeoutException):115 ecs_utils.poll_deployment_state(mock_client, 'cluster-foo', ['service-foo'], POLL_S)116 @patch('scripts.ecs_utils.print_events')117 @patch('boto3.client')118 def test_poll_deployment_bad_deploy(self, mock_boto, mock_print_events):119 mock_client = mock_boto.return_value120 mock_client.describe_services.return_value = BAD_SERVICE121 mock_client.list_tasks.return_value = TASKS122 with self.assertRaises(ecs_utils.TimeoutException):123 ecs_utils.poll_deployment_state(mock_client, 'cluster-foo', 'service-foo', POLL_S)124 @patch('scripts.ecs_utils.print_events')125 @patch('boto3.client')126 def test_poll_deployment_bad_tasks(self, mock_boto, mock_print_events):127 mock_client = mock_boto.return_value128 mock_client.describe_services.return_value = GOOD_SERVICE129 mock_client.list_tasks.return_value = TASKS130 mock_client.describe_tasks.side_effect = [BAD_TASKS] * 50131 with self.assertRaises(ecs_utils.TimeoutException):...
test_ecs_probes.py
Source:test_ecs_probes.py
1from unittest.mock import MagicMock, patch2import pytest3from chaoslib.exceptions import FailedActivity4from chaosaws.ecs.probes import (5 are_all_desired_tasks_running,6 describe_cluster,7 describe_service,8 describe_tasks,9 service_is_deploying,10)11@patch("chaosaws.ecs.probes.aws_client", autospec=True)12def test_ecs_service_is_not_deploying(aws_client):13 client = MagicMock()14 client.describe_services = MagicMock(15 return_value={"services": [{"deployments": [{"status": "PRIMARY"}]}]}16 )17 aws_client.return_value = client18 cluster = "ecs-cluster"19 service = "ecs-service"20 response = service_is_deploying(cluster, service)21 client.describe_services.assert_called_with(cluster=cluster, services=[service])22 assert response is False23@patch("chaosaws.ecs.probes.aws_client", autospec=True)24def test_ecs_service_is_deploying(aws_client):25 client = MagicMock()26 client.describe_services = MagicMock(27 return_value={28 "services": [{"deployments": [{"status": "PRIMARY"}, {"status": "ACTIVE"}]}]29 }30 )31 aws_client.return_value = client32 cluster = "ecs-cluster"33 service = "ecs-service"34 response = service_is_deploying(cluster, service)35 client.describe_services.assert_called_with(cluster=cluster, services=[service])36 assert response is True37@patch("chaosaws.ecs.probes.aws_client", autospec=True)38def test_error_checking_ecs_service_is_not_deploying(aws_client):39 client = MagicMock()40 client.describe_services = MagicMock(41 return_value={42 "services": [],43 "failures": [{"reason": "some_reason", "arn": "some_arn"}],44 }45 )46 aws_client.return_value = client47 cluster = "ecs-cluster"48 service = "ecs-service"49 with pytest.raises(FailedActivity) as exceptionInfo:50 service_is_deploying(cluster, service)51 client.describe_services.assert_called_with(cluster=cluster, services=[service])52 assert "Error retrieving service data from AWS" in str(exceptionInfo.value)53@patch("chaosaws.ecs.probes.aws_client", autospec=True)54def test_are_all_tasks_running_true(aws_client):55 client = MagicMock()56 client.describe_services = MagicMock(57 return_value={58 "services": [59 {60 "serviceName": "MyGenericService",61 "desiredCount": 3,62 "runningCount": 3,63 }64 ]65 }66 )67 aws_client.return_value = client68 cluster = "ecs-cluster"69 service = "MyGenericService"70 response = are_all_desired_tasks_running(cluster, service)71 client.describe_services.assert_called_with(cluster=cluster, services=[service])72 assert response73@patch("chaosaws.ecs.probes.aws_client", autospec=True)74def test_are_all_tasks_running_false(aws_client):75 client = MagicMock()76 client.describe_services = MagicMock(77 return_value={78 "services": [79 {80 "serviceName": "MyGenericService",81 "desiredCount": 3,82 "runningCount": 2,83 }84 ]85 }86 )87 aws_client.return_value = client88 cluster = "ecs-cluster"89 service = "MyGenericService"90 response = are_all_desired_tasks_running(cluster, service)91 client.describe_services.assert_called_with(cluster=cluster, services=[service])92 assert not response93@patch("chaosaws.ecs.probes.aws_client", autospec=True)94def test_are_all_tasks_running_exception(aws_client):95 client = MagicMock()96 client.describe_services = MagicMock(return_value={"services": []})97 aws_client.return_value = client98 cluster = "ecs-cluster"99 service = "MyGenericService"100 with pytest.raises(FailedActivity) as e:101 are_all_desired_tasks_running(cluster, service)102 client.describe_services.assert_called_with(cluster=cluster, services=[service])103 assert "Error retrieving service data from AWS" in str(e.value)104@patch("chaosaws.ecs.probes.aws_client", autospec=True)105def test_describe_clusters(aws_client):106 client = MagicMock()107 aws_client.return_value = client108 client.describe_clusters.return_value = {109 "clusters": [110 {111 "clusterArn": "arn:aws:ecs:region:012345678910:cluster/MyCluster",112 "clusterName": "MyCluster",113 "status": "ACTIVE",114 }115 ]116 }117 response = describe_cluster(cluster="MyCluster")118 client.describe_clusters.assert_called_with(clusters=["MyCluster"])119 assert response["clusters"][0]["clusterName"] == "MyCluster"120@patch("chaosaws.ecs.probes.aws_client", autospec=True)121def test_describe_service(aws_client):122 client = MagicMock()123 aws_client.return_value = client124 client.describe_services.return_value = {125 "services": [126 {127 "clusterArn": "arn:aws:ecs:region:012345678910:cluster/MyCluster",128 "serviceArn": "arn:aws:ecs:region:012345678910:service/MyService",129 "serviceName": "MyService",130 "status": "ACTIVE",131 }132 ]133 }134 response = describe_service(cluster="MyCluster", service="MyService")135 client.describe_services.assert_called_with(136 cluster="MyCluster", services=["MyService"]137 )138 assert response["services"][0]["serviceName"] == "MyService"139@patch("chaosaws.ecs.probes.aws_client", autospec=True)140def test_describe_tasks(aws_client):141 client = MagicMock()142 aws_client.return_value = client143 client.get_paginator.return_value.paginate.return_value = [144 {"taskArns": ["arn:aws:ecs:region:012345678910:task/MyCluster/123456789"]}145 ]146 client.describe_tasks.return_value = {147 "tasks": [148 {149 "clusterArn": "arn:aws:ecs:region:012345678910:cluster/" "MyCluster",150 "taskArn": "arn:aws:ecs:region:012345678910:task/MyCluster/"151 "123456789",152 "version": 22,153 }154 ]155 }156 response = describe_tasks(cluster="MyCluster")157 client.get_paginator.return_value.paginate.assert_called_with(cluster="MyCluster")158 client.describe_tasks.assert_called_with(159 cluster="MyCluster",160 tasks=["arn:aws:ecs:region:012345678910:task/MyCluster/123456789"],161 )...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!