diff --git a/.bumpversion.cfg b/.bumpversion.cfg deleted file mode 100644 index 479af4af8..000000000 --- a/.bumpversion.cfg +++ /dev/null @@ -1,7 +0,0 @@ -[bumpversion] -current_version = 1.3.4 - -[bumpversion:file:setup.py] - -[bumpversion:file:moto/__init__.py] - diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 06c0f5142..667ef3d9e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -170,8 +170,8 @@ jobs: - name: Start MotoServer run: | python setup.py sdist - docker run --rm -t --name motoserver -e TEST_SERVER_MODE=true -e AWS_SECRET_ACCESS_KEY=server_secret -e AWS_ACCESS_KEY_ID=server_key -v `pwd`:/moto -p 5000:5000 -v /var/run/docker.sock:/var/run/docker.sock python:3.7-buster /moto/travis_moto_server.sh & - python wait_for.py + docker run --rm -t --name motoserver -e TEST_SERVER_MODE=true -e AWS_SECRET_ACCESS_KEY=server_secret -e AWS_ACCESS_KEY_ID=server_key -v `pwd`:/moto -p 5000:5000 -v /var/run/docker.sock:/var/run/docker.sock python:3.7-buster /moto/scripts/ci_moto_server.sh & + python scripts/ci_wait_for_server.py - name: Get pip cache dir id: pip-cache run: | @@ -290,8 +290,8 @@ jobs: - name: Start MotoServer run: | python setup.py sdist - docker run --rm -t --name motoserver -e TEST_SERVER_MODE=true -e MOTO_PORT=4566 -e AWS_SECRET_ACCESS_KEY=server_secret -e AWS_ACCESS_KEY_ID=server_key -v `pwd`:/moto -p 4566:4566 -v /var/run/docker.sock:/var/run/docker.sock python:3.7-buster /moto/travis_moto_server.sh & - MOTO_PORT=4566 python wait_for.py + docker run --rm -t --name motoserver -e TEST_SERVER_MODE=true -e MOTO_PORT=4566 -e AWS_SECRET_ACCESS_KEY=server_secret -e AWS_ACCESS_KEY_ID=server_key -v `pwd`:/moto -p 4566:4566 -v /var/run/docker.sock:/var/run/docker.sock python:3.7-buster /moto/scripts/ci_moto_server.sh & + MOTO_PORT=4566 python scripts/ci_wait_for_server.py # Poor man's parallelization # Running them sequentially takes to much time # And using the build in parallel-argument does not help with reducing runtime diff --git a/CHANGELOG.md b/CHANGELOG.md index 312344a41..6894a904e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,44 @@ Moto Changelog =================== +2.2.17 +------ + New Services: + * CloudFront: + * create_distribution() + * delete_distribution() + * get_distribution() + * list_distributions() + + New Methods: + * Autoscaling: + * describe_tags() + * CloudFormation: + * get_stack_policy() + * set_stack_policy() + * DynamoDB: + * restore_table_to_point_in_time() + * Glue: + * delete_database() + * list_jobs() + * IAM: + * update_group() + * Route53 Resolver: + * associate_resolver_rule() + * create_resolver_rule() + * delete_resolver_rule() + * disassociate_resolver_rule() + * get_resolver_rule() + * get_resolver_rule_association() + * list_resolver_rules() + * list_resolver_rule_associations() + + Miscellaneous: + * Batch: register_job_definition() now supports the timeout-parameter + * Batch: submit_job() now supports the timeout-parameter + * EC2: describe_network_interfaces() now supports the `attachment.instance-id` filter + + 2.2.16 ------ New Services: diff --git a/IMPLEMENTATION_COVERAGE.md b/IMPLEMENTATION_COVERAGE.md index 3faa202e5..dfe047a81 100644 --- a/IMPLEMENTATION_COVERAGE.md +++ b/IMPLEMENTATION_COVERAGE.md @@ -204,7 +204,7 @@ ## autoscaling
-45% implemented +47% implemented - [X] attach_instances - [X] attach_load_balancer_target_groups @@ -241,7 +241,7 @@ - [ ] describe_scaling_activities - [ ] describe_scaling_process_types - [ ] describe_scheduled_actions -- [ ] describe_tags +- [X] describe_tags - [ ] describe_termination_policy_types - [ ] describe_warm_pool - [X] detach_instances @@ -329,7 +329,7 @@ ## cloudformation
-27% implemented +30% implemented - [ ] activate_type - [ ] batch_describe_type_configurations @@ -364,7 +364,7 @@ - [ ] detect_stack_set_drift - [ ] estimate_template_cost - [X] execute_change_set -- [ ] get_stack_policy +- [X] get_stack_policy - [ ] get_template - [ ] get_template_summary - [ ] import_stacks_to_stack_set @@ -385,7 +385,7 @@ - [ ] register_publisher - [ ] register_type - [ ] rollback_stack -- [ ] set_stack_policy +- [X] set_stack_policy - [ ] set_type_configuration - [ ] set_type_default_version - [ ] signal_resource @@ -1119,7 +1119,7 @@ ## dynamodb
-56% implemented +58% implemented - [ ] batch_execute_statement - [X] batch_get_item @@ -1157,7 +1157,7 @@ - [X] put_item - [X] query - [X] restore_table_from_backup -- [ ] restore_table_to_point_in_time +- [X] restore_table_to_point_in_time - [X] scan - [X] tag_resource - [X] transact_get_items @@ -1579,6 +1579,7 @@ - [ ] modify_launch_template - [X] modify_managed_prefix_list - [X] modify_network_interface_attribute +- [ ] modify_private_dns_name_options - [ ] modify_reserved_instances - [ ] modify_security_group_rules - [ ] modify_snapshot_attribute @@ -2149,11 +2150,14 @@ ## forecast
-14% implemented +11% implemented +- [ ] create_auto_predictor - [ ] create_dataset - [X] create_dataset_group - [ ] create_dataset_import_job +- [ ] create_explainability +- [ ] create_explainability_export - [ ] create_forecast - [ ] create_forecast_export_job - [ ] create_predictor @@ -2161,14 +2165,19 @@ - [ ] delete_dataset - [X] delete_dataset_group - [ ] delete_dataset_import_job +- [ ] delete_explainability +- [ ] delete_explainability_export - [ ] delete_forecast - [ ] delete_forecast_export_job - [ ] delete_predictor - [ ] delete_predictor_backtest_export_job - [ ] delete_resource_tree +- [ ] describe_auto_predictor - [ ] describe_dataset - [X] describe_dataset_group - [ ] describe_dataset_import_job +- [ ] describe_explainability +- [ ] describe_explainability_export - [ ] describe_forecast - [ ] describe_forecast_export_job - [ ] describe_predictor @@ -2177,6 +2186,8 @@ - [X] list_dataset_groups - [ ] list_dataset_import_jobs - [ ] list_datasets +- [ ] list_explainabilities +- [ ] list_explainability_exports - [ ] list_forecast_export_jobs - [ ] list_forecasts - [ ] list_predictor_backtest_export_jobs @@ -2229,7 +2240,7 @@ ## glue
-8% implemented +9% implemented - [ ] batch_create_partition - [ ] batch_delete_connection @@ -2271,7 +2282,7 @@ - [ ] delete_column_statistics_for_table - [ ] delete_connection - [X] delete_crawler -- [ ] delete_database +- [X] delete_database - [ ] delete_dev_endpoint - [ ] delete_job - [ ] delete_ml_transform @@ -2346,7 +2357,7 @@ - [ ] list_blueprints - [ ] list_crawlers - [ ] list_dev_endpoints -- [ ] list_jobs +- [X] list_jobs - [ ] list_ml_transforms - [ ] list_registries - [ ] list_schema_versions @@ -2547,7 +2558,7 @@ - [X] update_access_key - [X] update_account_password_policy - [ ] update_assume_role_policy -- [ ] update_group +- [X] update_group - [X] update_login_profile - [ ] update_open_id_connect_provider_thumbprint - [X] update_role @@ -2565,7 +2576,7 @@ ## iot
-28% implemented +27% implemented - [ ] accept_certificate_transfer - [ ] add_thing_to_billing_group @@ -2664,6 +2675,7 @@ - [X] describe_job - [X] describe_job_execution - [ ] describe_job_template +- [ ] describe_managed_job_template - [ ] describe_mitigation_action - [ ] describe_provisioning_template - [ ] describe_provisioning_template_version @@ -2720,6 +2732,7 @@ - [X] list_job_executions_for_thing - [ ] list_job_templates - [X] list_jobs +- [ ] list_managed_job_templates - [ ] list_mitigation_actions - [ ] list_ota_updates - [ ] list_outgoing_certificates @@ -3544,6 +3557,7 @@ - [ ] promote_read_replica - [ ] promote_read_replica_db_cluster - [ ] purchase_reserved_db_instances_offering +- [ ] reboot_db_cluster - [X] reboot_db_instance - [ ] register_db_proxy_targets - [ ] remove_from_global_cluster @@ -3573,7 +3587,7 @@ ## redshift
-24% implemented +23% implemented - [ ] accept_reserved_node_exchange - [ ] add_partner @@ -3644,6 +3658,7 @@ - [ ] describe_node_configuration_options - [ ] describe_orderable_cluster_options - [ ] describe_partners +- [ ] describe_reserved_node_exchange_status - [ ] describe_reserved_node_offerings - [ ] describe_reserved_nodes - [ ] describe_resize @@ -3660,6 +3675,7 @@ - [ ] enable_logging - [X] enable_snapshot_copy - [X] get_cluster_credentials +- [ ] get_reserved_node_exchange_configuration_options - [ ] get_reserved_node_exchange_offerings - [ ] modify_aqua_configuration - [ ] modify_authentication_profile @@ -3801,7 +3817,7 @@ ## route53resolver
-27% implemented +26% implemented - [ ] associate_firewall_rule_group - [ ] associate_resolver_endpoint_ip_address @@ -4911,6 +4927,7 @@ - meteringmarketplace - mgh - mgn +- migration-hub-refactor-spaces - migrationhub-config - migrationhubstrategy - mobile diff --git a/docs/docs/services/autoscaling.rst b/docs/docs/services/autoscaling.rst index 3d9077543..88cc4000f 100644 --- a/docs/docs/services/autoscaling.rst +++ b/docs/docs/services/autoscaling.rst @@ -60,7 +60,12 @@ autoscaling - [ ] describe_scaling_activities - [ ] describe_scaling_process_types - [ ] describe_scheduled_actions -- [ ] describe_tags +- [X] describe_tags + + Pagination is not yet implemented. + Only the `auto-scaling-group` and `propagate-at-launch` filters are implemented. + + - [ ] describe_termination_policy_types - [ ] describe_warm_pool - [X] detach_instances diff --git a/docs/docs/services/cloudformation.rst b/docs/docs/services/cloudformation.rst index 8fe7ea161..ce4b4c818 100644 --- a/docs/docs/services/cloudformation.rst +++ b/docs/docs/services/cloudformation.rst @@ -58,7 +58,7 @@ cloudformation - [ ] detect_stack_set_drift - [ ] estimate_template_cost - [X] execute_change_set -- [ ] get_stack_policy +- [X] get_stack_policy - [ ] get_template - [ ] get_template_summary - [ ] import_stacks_to_stack_set @@ -79,7 +79,11 @@ cloudformation - [ ] register_publisher - [ ] register_type - [ ] rollback_stack -- [ ] set_stack_policy +- [X] set_stack_policy + + Note that Moto does no validation/parsing/enforcement of this policy - we simply persist it. + + - [ ] set_type_configuration - [ ] set_type_default_version - [ ] signal_resource diff --git a/docs/docs/services/dynamodb.rst b/docs/docs/services/dynamodb.rst index 0122b9799..8ba29812c 100644 --- a/docs/docs/services/dynamodb.rst +++ b/docs/docs/services/dynamodb.rst @@ -62,6 +62,11 @@ dynamodb - [X] query - [X] restore_table_from_backup - [X] restore_table_to_point_in_time + + Currently this only accepts the source and target table elements, and will + copy all items from the source without respect to other arguments. + + - [X] scan - [X] tag_resource - [X] transact_get_items diff --git a/docs/docs/services/ec2.rst b/docs/docs/services/ec2.rst index 9850931a4..8ac0a4876 100644 --- a/docs/docs/services/ec2.rst +++ b/docs/docs/services/ec2.rst @@ -428,6 +428,7 @@ ec2 - [ ] modify_launch_template - [X] modify_managed_prefix_list - [X] modify_network_interface_attribute +- [ ] modify_private_dns_name_options - [ ] modify_reserved_instances - [ ] modify_security_group_rules - [ ] modify_snapshot_attribute diff --git a/docs/docs/services/forecast.rst b/docs/docs/services/forecast.rst index 36f35a65b..c8423e321 100644 --- a/docs/docs/services/forecast.rst +++ b/docs/docs/services/forecast.rst @@ -25,9 +25,12 @@ forecast |start-h3| Implemented features for this service |end-h3| +- [ ] create_auto_predictor - [ ] create_dataset - [X] create_dataset_group - [ ] create_dataset_import_job +- [ ] create_explainability +- [ ] create_explainability_export - [ ] create_forecast - [ ] create_forecast_export_job - [ ] create_predictor @@ -35,14 +38,19 @@ forecast - [ ] delete_dataset - [X] delete_dataset_group - [ ] delete_dataset_import_job +- [ ] delete_explainability +- [ ] delete_explainability_export - [ ] delete_forecast - [ ] delete_forecast_export_job - [ ] delete_predictor - [ ] delete_predictor_backtest_export_job - [ ] delete_resource_tree +- [ ] describe_auto_predictor - [ ] describe_dataset - [X] describe_dataset_group - [ ] describe_dataset_import_job +- [ ] describe_explainability +- [ ] describe_explainability_export - [ ] describe_forecast - [ ] describe_forecast_export_job - [ ] describe_predictor @@ -51,6 +59,8 @@ forecast - [X] list_dataset_groups - [ ] list_dataset_import_jobs - [ ] list_datasets +- [ ] list_explainabilities +- [ ] list_explainability_exports - [ ] list_forecast_export_jobs - [ ] list_forecasts - [ ] list_predictor_backtest_export_jobs diff --git a/docs/docs/services/glue.rst b/docs/docs/services/glue.rst index fd13054ce..fdd19d0d0 100644 --- a/docs/docs/services/glue.rst +++ b/docs/docs/services/glue.rst @@ -65,7 +65,7 @@ glue - [ ] delete_column_statistics_for_table - [ ] delete_connection - [X] delete_crawler -- [ ] delete_database +- [X] delete_database - [ ] delete_dev_endpoint - [ ] delete_job - [ ] delete_ml_transform @@ -140,7 +140,7 @@ glue - [ ] list_blueprints - [ ] list_crawlers - [ ] list_dev_endpoints -- [ ] list_jobs +- [X] list_jobs - [ ] list_ml_transforms - [ ] list_registries - [ ] list_schema_versions diff --git a/docs/docs/services/iam.rst b/docs/docs/services/iam.rst index 4e8b6b8ae..01fecd7e8 100644 --- a/docs/docs/services/iam.rst +++ b/docs/docs/services/iam.rst @@ -173,7 +173,7 @@ iam - [X] update_access_key - [X] update_account_password_policy - [ ] update_assume_role_policy -- [ ] update_group +- [X] update_group - [X] update_login_profile - [ ] update_open_id_connect_provider_thumbprint - [X] update_role diff --git a/docs/docs/services/iot.rst b/docs/docs/services/iot.rst index ae2045d17..9d46d9a42 100644 --- a/docs/docs/services/iot.rst +++ b/docs/docs/services/iot.rst @@ -122,6 +122,7 @@ iot - [X] describe_job - [X] describe_job_execution - [ ] describe_job_template +- [ ] describe_managed_job_template - [ ] describe_mitigation_action - [ ] describe_provisioning_template - [ ] describe_provisioning_template_version @@ -178,6 +179,7 @@ iot - [X] list_job_executions_for_thing - [ ] list_job_templates - [X] list_jobs +- [ ] list_managed_job_templates - [ ] list_mitigation_actions - [ ] list_ota_updates - [ ] list_outgoing_certificates diff --git a/docs/docs/services/rds.rst b/docs/docs/services/rds.rst index 25b73695c..bc507f9cb 100644 --- a/docs/docs/services/rds.rst +++ b/docs/docs/services/rds.rst @@ -140,6 +140,7 @@ rds - [ ] promote_read_replica - [ ] promote_read_replica_db_cluster - [ ] purchase_reserved_db_instances_offering +- [ ] reboot_db_cluster - [X] reboot_db_instance - [ ] register_db_proxy_targets - [ ] remove_from_global_cluster diff --git a/docs/docs/services/redshift.rst b/docs/docs/services/redshift.rst index 7d5427b68..eee47b452 100644 --- a/docs/docs/services/redshift.rst +++ b/docs/docs/services/redshift.rst @@ -94,6 +94,7 @@ redshift - [ ] describe_node_configuration_options - [ ] describe_orderable_cluster_options - [ ] describe_partners +- [ ] describe_reserved_node_exchange_status - [ ] describe_reserved_node_offerings - [ ] describe_reserved_nodes - [ ] describe_resize @@ -110,6 +111,7 @@ redshift - [ ] enable_logging - [X] enable_snapshot_copy - [X] get_cluster_credentials +- [ ] get_reserved_node_exchange_configuration_options - [ ] get_reserved_node_exchange_offerings - [ ] modify_aqua_configuration - [ ] modify_authentication_profile diff --git a/docs/docs/services/route53resolver.rst b/docs/docs/services/route53resolver.rst index 3f5cf23c9..030f45695 100644 --- a/docs/docs/services/route53resolver.rst +++ b/docs/docs/services/route53resolver.rst @@ -31,6 +31,8 @@ route53resolver - [ ] associate_resolver_endpoint_ip_address - [ ] associate_resolver_query_log_config - [X] associate_resolver_rule + Return description for a newly created resolver rule association. + - [ ] create_firewall_domain_list - [ ] create_firewall_rule - [ ] create_firewall_rule_group @@ -39,10 +41,12 @@ route53resolver NOTE: IPv6 IPs are currently not being filtered when calculating the create_resolver_endpoint() IpAddresses. - + - [ ] create_resolver_query_log_config - [X] create_resolver_rule + Return description for a newly created resolver rule. + - [ ] delete_firewall_domain_list - [ ] delete_firewall_rule - [ ] delete_firewall_rule_group @@ -51,10 +55,14 @@ route53resolver - [ ] delete_resolver_query_log_config - [X] delete_resolver_rule + Delete a resolver rule. + - [ ] disassociate_firewall_rule_group - [ ] disassociate_resolver_endpoint_ip_address - [ ] disassociate_resolver_query_log_config - [X] disassociate_resolver_rule + Removes association between a resolver rule and a VPC. + - [ ] get_firewall_config - [ ] get_firewall_domain_list - [ ] get_firewall_rule_group @@ -69,7 +77,11 @@ route53resolver - [ ] get_resolver_query_log_config_association - [ ] get_resolver_query_log_config_policy - [X] get_resolver_rule + Return info for specified resolver rule. + - [X] get_resolver_rule_association + Return info for specified resolver rule association. + - [ ] get_resolver_rule_policy - [ ] import_firewall_domains - [ ] list_firewall_configs @@ -89,7 +101,11 @@ route53resolver - [ ] list_resolver_query_log_config_associations - [ ] list_resolver_query_log_configs - [X] list_resolver_rule_associations + List all resolver rule associations, using filters if specified. + - [X] list_resolver_rules + List all resolver rules, using filters if specified. + - [X] list_tags_for_resource List all tags for the given resource. diff --git a/moto/dynamodb2/models/__init__.py b/moto/dynamodb2/models/__init__.py index c1576db7a..8c7895118 100644 --- a/moto/dynamodb2/models/__init__.py +++ b/moto/dynamodb2/models/__init__.py @@ -1730,12 +1730,12 @@ class DynamoDBBackend(BaseBackend): self.tables[target_table_name] = new_table return new_table - """ - Currently this only accepts the source and target table elements, and will - copy all items from the source without respect to other arguments. - """ - def restore_table_to_point_in_time(self, target_table_name, source_table_name): + """ + Currently this only accepts the source and target table elements, and will + copy all items from the source without respect to other arguments. + """ + source = self.get_table(source_table_name) if source is None: raise KeyError() diff --git a/moto/iam/models.py b/moto/iam/models.py index 8dba263a6..23c8ff5d9 100644 --- a/moto/iam/models.py +++ b/moto/iam/models.py @@ -2075,14 +2075,11 @@ class IAMBackend(BaseBackend): return group def get_group(self, group_name, marker=None, max_items=None): - group = None try: - group = self.groups[group_name] + return self.groups[group_name] except KeyError: raise IAMNotFoundException("Group {0} not found".format(group_name)) - return group - def list_groups(self): return self.groups.values() @@ -2122,11 +2119,11 @@ class IAMBackend(BaseBackend): "The group with name {0} cannot be found.".format(group_name) ) - def update_group(self, group_name, new_group_name, new_path="/"): + def update_group(self, group_name, new_group_name, new_path): if new_group_name: if new_group_name in self.groups: raise IAMConflictException( - "Group {0} already exists".format(new_group_name) + message="Group {0} already exists".format(new_group_name) ) try: group = self.groups[group_name] diff --git a/moto/iam/responses.py b/moto/iam/responses.py index ec009e463..3846e3ae5 100644 --- a/moto/iam/responses.py +++ b/moto/iam/responses.py @@ -507,7 +507,7 @@ class IamResponse(BaseResponse): def update_group(self): group_name = self._get_param("GroupName") new_group_name = self._get_param("NewGroupName") - new_path = self._get_param("NewPath", "/") + new_path = self._get_param("NewPath") iam_backend.update_group(group_name, new_group_name, new_path) template = self.response_template(GENERIC_EMPTY_TEMPLATE) return template.render(name="UpdateGroup") diff --git a/moto/server.py b/moto/server.py index 612476016..397ba1cdd 100644 --- a/moto/server.py +++ b/moto/server.py @@ -317,7 +317,7 @@ def create_backend_app(service): def signal_handler(reset_server_port, signum, frame): if reset_server_port: - del os.environ["MOTO_SERVER_PORT"] + del os.environ["MOTO_PORT"] sys.exit(0) @@ -335,7 +335,11 @@ def main(argv=sys.argv[1:]): "-H", "--host", type=str, help="Which host to bind", default="127.0.0.1" ) parser.add_argument( - "-p", "--port", type=int, help="Port number to use for connection", default=5000 + "-p", + "--port", + type=int, + help="Port number to use for connection", + default=int(os.environ.get("MOTO_PORT", 5000)), ) parser.add_argument( "-r", @@ -361,9 +365,9 @@ def main(argv=sys.argv[1:]): args = parser.parse_args(argv) reset_server_port = False - if "MOTO_SERVER_PORT" not in os.environ: + if "MOTO_PORT" not in os.environ: reset_server_port = True - os.environ["MOTO_SERVER_PORT"] = f"{args.port}" + os.environ["MOTO_PORT"] = f"{args.port}" try: signal.signal(signal.SIGINT, partial(signal_handler, reset_server_port)) diff --git a/moto/settings.py b/moto/settings.py index 6a73631ad..aee2c58b5 100644 --- a/moto/settings.py +++ b/moto/settings.py @@ -47,7 +47,7 @@ def ecs_new_arn_format(): def moto_server_port(): - return os.environ.get("MOTO_SERVER_PORT") or "5000" + return os.environ.get("MOTO_PORT") or "5000" def moto_server_host(): diff --git a/scripts/ci_moto_server.sh b/scripts/ci_moto_server.sh new file mode 100755 index 000000000..35e38602a --- /dev/null +++ b/scripts/ci_moto_server.sh @@ -0,0 +1,5 @@ +#!/usr/bin/env bash + +set -e +pip install $(ls /moto/dist/moto*.gz)[server,all] +moto_server -H 0.0.0.0 > /moto/server_output.log 2>&1 diff --git a/wait_for.py b/scripts/ci_wait_for_server.py similarity index 56% rename from wait_for.py rename to scripts/ci_wait_for_server.py index ac2945eef..471afbda6 100755 --- a/wait_for.py +++ b/scripts/ci_wait_for_server.py @@ -1,21 +1,11 @@ import os import time -try: - # py2 - import urllib2 as urllib - from urllib2 import URLError - import socket - import httplib +import urllib.request as urllib +from urllib.error import URLError +import socket - EXCEPTIONS = (URLError, socket.error, httplib.BadStatusLine) -except ImportError: - # py3 - import urllib.request as urllib - from urllib.error import URLError - import socket - - EXCEPTIONS = (URLError, socket.timeout, ConnectionResetError) +EXCEPTIONS = (URLError, socket.timeout, ConnectionResetError) start_ts = time.time() diff --git a/setup.cfg b/setup.cfg index 1b0084197..c68650e2f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,6 +8,10 @@ markers = [coverage:run] relative_files = True +[flake8] +ignore = W503,W605,E128,E501,E203,E266,E501,E231 +exclude = moto/packages,dist + [pylint.'MESSAGES CONTROL'] disable = W,C,R,E # Check we have any tests with duplicate names (causing them to be skipped) diff --git a/tests/test_iam/test_iam_groups.py b/tests/test_iam/test_iam_groups.py index 077c93920..f13af8980 100644 --- a/tests/test_iam/test_iam_groups.py +++ b/tests/test_iam/test_iam_groups.py @@ -355,3 +355,73 @@ def test_delete_unknown_group(): err.value.response["Error"]["Message"].should.equal( "The group with name unknown-group cannot be found." ) + + +@mock_iam +def test_update_group_name(): + conn = boto3.client("iam", region_name="us-east-1") + conn.create_group(GroupName="my-group") + initial_group = conn.get_group(GroupName="my-group")["Group"] + + conn.update_group(GroupName="my-group", NewGroupName="new-group") + + # The old group-name should no longer exist + with pytest.raises(ClientError) as exc: + conn.get_group(GroupName="my-group") + exc.value.response["Error"]["Code"].should.equal("NoSuchEntity") + + result = conn.get_group(GroupName="new-group")["Group"] + result["Path"].should.equal("/") + result["GroupName"].should.equal("new-group") + result["GroupId"].should.equal(initial_group["GroupId"]) + result["Arn"].should.match(":group/new-group") + + +@mock_iam +def test_update_group_name_that_has_a_path(): + conn = boto3.client("iam", region_name="us-east-1") + conn.create_group(GroupName="my-group", Path="/path") + + conn.update_group(GroupName="my-group", NewGroupName="new-group") + + # Verify the path hasn't changed + new = conn.get_group(GroupName="new-group")["Group"] + new["Path"].should.equal("/path") + + +@mock_iam +def test_update_group_path(): + conn = boto3.client("iam", region_name="us-east-1") + conn.create_group(GroupName="my-group", Path="/path") + + conn.update_group( + GroupName="my-group", NewGroupName="new-group", NewPath="/new-path" + ) + + # Verify the path has changed + new = conn.get_group(GroupName="new-group")["Group"] + new["Path"].should.equal("/new-path") + + +@mock_iam +def test_update_group_that_does_not_exist(): + conn = boto3.client("iam", region_name="us-east-1") + + with pytest.raises(ClientError) as exc: + conn.update_group(GroupName="nonexisting", NewGroupName="..") + err = exc.value.response["Error"] + err["Code"].should.equal("NoSuchEntity") + err["Message"].should.equal("The group with name nonexisting cannot be found.") + + +@mock_iam +def test_update_group_with_existing_name(): + conn = boto3.client("iam", region_name="us-east-1") + conn.create_group(GroupName="existing1") + conn.create_group(GroupName="existing2") + + with pytest.raises(ClientError) as exc: + conn.update_group(GroupName="existing1", NewGroupName="existing2") + err = exc.value.response["Error"] + err["Code"].should.equal("Conflict") + err["Message"].should.equal("Group existing2 already exists") diff --git a/tox.ini b/tox.ini deleted file mode 100644 index f77df29b3..000000000 --- a/tox.ini +++ /dev/null @@ -1,19 +0,0 @@ -[tox] -envlist = py27, py36, py37 - -[testenv] -setenv = - BOTO_CONFIG=/dev/null - AWS_SECRET_ACCESS_KEY=foobar_secret - AWS_ACCESS_KEY_ID=foobar_key - AWS_DEFAULT_REGION=us-east-1 -deps = - -r{toxinidir}/requirements.txt - -r{toxinidir}/requirements-dev.txt -commands = - {envpython} setup.py test - pytest -v {posargs} - -[flake8] -ignore = W503,W605,E128,E501,E203,E266,E501,E231 -exclude = moto/packages,dist diff --git a/travis_moto_server.sh b/travis_moto_server.sh deleted file mode 100755 index 6f6d29a21..000000000 --- a/travis_moto_server.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env bash - -export MOTO_PORT=${MOTO_PORT:-5000} - -set -e -pip install $(ls /moto/dist/moto*.gz)[server,all] -moto_server -H 0.0.0.0 -p ${MOTO_PORT} > /moto/server_output.log 2>&1