| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | import json | 
					
						
							| 
									
										
										
										
											2017-07-25 17:54:05 -04:00
										 |  |  | from datetime import datetime | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | import pytest | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  | from freezegun import freeze_time | 
					
						
							|  |  |  | import os | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  | import re | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  | import sure  # noqa # pylint: disable=unused-import | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | import boto3 | 
					
						
							| 
									
										
										
										
											2021-01-31 04:21:24 -08:00
										 |  |  | from botocore.exceptions import ClientError | 
					
						
							| 
									
										
										
										
											2017-07-25 17:54:05 -04:00
										 |  |  | from dateutil.tz import tzlocal | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | from moto import mock_ecr | 
					
						
							| 
									
										
										
										
											2020-10-06 07:54:49 +02:00
										 |  |  | from unittest import SkipTest | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-08-13 09:49:43 +00:00
										 |  |  | from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-16 10:22:43 -08:00
										 |  |  | from tests.test_ecr.test_ecr_helpers import ( | 
					
						
							|  |  |  |     _create_image_manifest, | 
					
						
							|  |  |  |     _create_image_manifest_list, | 
					
						
							|  |  |  | ) | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_create_repository(): | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     # given | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     repo = response["repository"] | 
					
						
							|  |  |  |     repo["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     repo["repositoryArn"].should.equal( | 
					
						
							|  |  |  |         f"arn:aws:ecr:us-east-1:{ACCOUNT_ID}:repository/{repo_name}" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     repo["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     repo["repositoryUri"].should.equal( | 
					
						
							|  |  |  |         f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/{repo_name}" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     repo["createdAt"].should.be.a(datetime) | 
					
						
							|  |  |  |     repo["imageTagMutability"].should.equal("MUTABLE") | 
					
						
							|  |  |  |     repo["imageScanningConfiguration"].should.equal({"scanOnPush": False}) | 
					
						
							|  |  |  |     repo["encryptionConfiguration"].should.equal({"encryptionType": "AES256"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_create_repository_with_non_default_config(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     kms_key = f"arn:aws:kms:{region_name}:{ACCOUNT_ID}:key/51d81fab-b138-4bd2-8a09-07fd6d37224d" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.create_repository( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         imageTagMutability="IMMUTABLE", | 
					
						
							|  |  |  |         imageScanningConfiguration={"scanOnPush": True}, | 
					
						
							|  |  |  |         encryptionConfiguration={"encryptionType": "KMS", "kmsKey": kms_key}, | 
					
						
							|  |  |  |         tags=[{"Key": "key-1", "Value": "value-1"}], | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     repo = response["repository"] | 
					
						
							|  |  |  |     repo["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     repo["repositoryArn"].should.equal( | 
					
						
							|  |  |  |         f"arn:aws:ecr:{region_name}:{ACCOUNT_ID}:repository/{repo_name}" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     repo["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     repo["repositoryUri"].should.equal( | 
					
						
							|  |  |  |         f"{ACCOUNT_ID}.dkr.ecr.{region_name}.amazonaws.com/{repo_name}" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     repo["createdAt"].should.be.a(datetime) | 
					
						
							|  |  |  |     repo["imageTagMutability"].should.equal("IMMUTABLE") | 
					
						
							|  |  |  |     repo["imageScanningConfiguration"].should.equal({"scanOnPush": True}) | 
					
						
							|  |  |  |     repo["encryptionConfiguration"].should.equal( | 
					
						
							|  |  |  |         {"encryptionType": "KMS", "kmsKey": kms_key} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-01-06 21:05:23 -01:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_create_repository_in_different_account(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when passing in a custom registry ID | 
					
						
							|  |  |  |     response = client.create_repository( | 
					
						
							|  |  |  |         registryId="222222222222", repositoryName=repo_name | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then we should persist this ID | 
					
						
							|  |  |  |     repo = response["repository"] | 
					
						
							|  |  |  |     repo.should.have.key("registryId").equals("222222222222") | 
					
						
							|  |  |  |     repo.should.have.key("repositoryArn").equals( | 
					
						
							|  |  |  |         "arn:aws:ecr:us-east-1:222222222222:repository/test-repo" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then this repo should be returned with the correct ID | 
					
						
							|  |  |  |     repo = client.describe_repositories()["repositories"][0] | 
					
						
							|  |  |  |     repo.should.have.key("registryId").equals("222222222222") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then we can search for repos with this ID | 
					
						
							|  |  |  |     response = client.describe_repositories(registryId="222222222222") | 
					
						
							|  |  |  |     response.should.have.key("repositories").length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then this repo is not found when searching for a different ID | 
					
						
							|  |  |  |     response = client.describe_repositories(registryId=ACCOUNT_ID) | 
					
						
							|  |  |  |     response.should.have.key("repositories").length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_create_repository_with_aws_managed_kms(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     repo = client.create_repository( | 
					
						
							|  |  |  |         repositoryName=repo_name, encryptionConfiguration={"encryptionType": "KMS"} | 
					
						
							|  |  |  |     )["repository"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     repo["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     repo["encryptionConfiguration"]["encryptionType"].should.equal("KMS") | 
					
						
							|  |  |  |     repo["encryptionConfiguration"]["kmsKey"].should.match( | 
					
						
							|  |  |  |         r"arn:aws:kms:eu-central-1:[0-9]{12}:key/[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[ab89][a-f0-9]{3}-[a-f0-9]{12}$" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_create_repository_error_already_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("CreateRepository") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryAlreadyExistsException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' already exists " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_repositories(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository0") | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |     response = client.describe_repositories() | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     len(response["repositories"]).should.equal(2) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 15:21:11 -08:00
										 |  |  |     repository_arns = [ | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |         f"arn:aws:ecr:us-east-1:{ACCOUNT_ID}:repository/test_repository1", | 
					
						
							|  |  |  |         f"arn:aws:ecr:us-east-1:{ACCOUNT_ID}:repository/test_repository0", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     sorted( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         [ | 
					
						
							|  |  |  |             response["repositories"][0]["repositoryArn"], | 
					
						
							|  |  |  |             response["repositories"][1]["repositoryArn"], | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     ).should.equal(sorted(repository_arns)) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 15:21:11 -08:00
										 |  |  |     repository_uris = [ | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |         f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/test_repository1", | 
					
						
							|  |  |  |         f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/test_repository0", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     sorted( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         [ | 
					
						
							|  |  |  |             response["repositories"][0]["repositoryUri"], | 
					
						
							|  |  |  |             response["repositories"][1]["repositoryUri"], | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     ).should.equal(sorted(repository_uris)) | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_repositories_1(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository0") | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     response = client.describe_repositories(registryId=ACCOUNT_ID) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     len(response["repositories"]).should.equal(2) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 15:21:11 -08:00
										 |  |  |     repository_arns = [ | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |         f"arn:aws:ecr:us-east-1:{ACCOUNT_ID}:repository/test_repository1", | 
					
						
							|  |  |  |         f"arn:aws:ecr:us-east-1:{ACCOUNT_ID}:repository/test_repository0", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     sorted( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         [ | 
					
						
							|  |  |  |             response["repositories"][0]["repositoryArn"], | 
					
						
							|  |  |  |             response["repositories"][1]["repositoryArn"], | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     ).should.equal(sorted(repository_arns)) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-20 15:21:11 -08:00
										 |  |  |     repository_uris = [ | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |         f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/test_repository1", | 
					
						
							|  |  |  |         f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/test_repository0", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     sorted( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         [ | 
					
						
							|  |  |  |             response["repositories"][0]["repositoryUri"], | 
					
						
							|  |  |  |             response["repositories"][1]["repositoryUri"], | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     ).should.equal(sorted(repository_uris)) | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_repositories_2(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository0") | 
					
						
							|  |  |  |     response = client.describe_repositories(registryId="109876543210") | 
					
						
							|  |  |  |     len(response["repositories"]).should.equal(0) | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_repositories_3(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository0") | 
					
						
							|  |  |  |     response = client.describe_repositories(repositoryNames=["test_repository1"]) | 
					
						
							|  |  |  |     len(response["repositories"]).should.equal(1) | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     repository_arn = f"arn:aws:ecr:us-east-1:{ACCOUNT_ID}:repository/test_repository1" | 
					
						
							| 
									
										
										
										
											2020-01-20 15:21:11 -08:00
										 |  |  |     response["repositories"][0]["repositoryArn"].should.equal(repository_arn) | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     repository_uri = f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/test_repository1" | 
					
						
							| 
									
										
										
										
											2020-01-20 15:21:11 -08:00
										 |  |  |     response["repositories"][0]["repositoryUri"].should.equal(repository_uri) | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 15:32:32 -04:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_repositories_with_image(): | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     # given | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     client.put_image( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							| 
									
										
										
										
											2017-06-20 15:32:32 -04:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="latest", | 
					
						
							| 
									
										
										
										
											2017-06-20 15:32:32 -04:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     # when | 
					
						
							|  |  |  |     response = client.describe_repositories(repositoryNames=[repo_name]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["repositories"].should.have.length_of(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     repo = response["repositories"][0] | 
					
						
							|  |  |  |     repo["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     repo["repositoryArn"].should.equal( | 
					
						
							|  |  |  |         f"arn:aws:ecr:us-east-1:{ACCOUNT_ID}:repository/{repo_name}" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     repo["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     repo["repositoryUri"].should.equal( | 
					
						
							|  |  |  |         f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/{repo_name}" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     repo["createdAt"].should.be.a(datetime) | 
					
						
							|  |  |  |     repo["imageScanningConfiguration"].should.equal({"scanOnPush": False}) | 
					
						
							|  |  |  |     repo["imageTagMutability"].should.equal("MUTABLE") | 
					
						
							|  |  |  |     repo["encryptionConfiguration"].should.equal({"encryptionType": "AES256"}) | 
					
						
							| 
									
										
										
										
											2017-06-20 15:32:32 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_repository(): | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     # given | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.delete_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     repo = response["repository"] | 
					
						
							|  |  |  |     repo["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     repo["repositoryArn"].should.equal( | 
					
						
							|  |  |  |         f"arn:aws:ecr:us-east-1:{ACCOUNT_ID}:repository/{repo_name}" | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     repo["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     repo["repositoryUri"].should.equal( | 
					
						
							|  |  |  |         f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/{repo_name}" | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     repo["createdAt"].should.be.a(datetime) | 
					
						
							|  |  |  |     repo["imageTagMutability"].should.equal("MUTABLE") | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     response = client.describe_repositories() | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     response["repositories"].should.have.length_of(0) | 
					
						
							| 
									
										
										
										
											2017-05-22 22:50:39 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-12 14:08:28 +09:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_repository_with_force(): | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     client.put_image( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							|  |  |  |         imageTag="latest", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.delete_repository(repositoryName=repo_name, force=True) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     repo = response["repository"] | 
					
						
							|  |  |  |     repo["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     repo["repositoryArn"].should.equal( | 
					
						
							|  |  |  |         f"arn:aws:ecr:us-east-1:{ACCOUNT_ID}:repository/{repo_name}" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     repo["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     repo["repositoryUri"].should.equal( | 
					
						
							|  |  |  |         f"{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com/{repo_name}" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     repo["createdAt"].should.be.a(datetime) | 
					
						
							|  |  |  |     repo["imageTagMutability"].should.equal("MUTABLE") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.describe_repositories() | 
					
						
							|  |  |  |     response["repositories"].should.have.length_of(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_image(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2017-06-20 15:32:32 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |     response = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="latest", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response["image"]["imageId"]["imageTag"].should.equal("latest") | 
					
						
							|  |  |  |     response["image"]["imageId"]["imageDigest"].should.contain("sha") | 
					
						
							|  |  |  |     response["image"]["repositoryName"].should.equal("test_repository") | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     response["image"]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-16 10:22:43 -08:00
										 |  |  | @mock_ecr() | 
					
						
							|  |  |  | def test_put_manifest_list(): | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     manifest_list = _create_image_manifest_list() | 
					
						
							|  |  |  |     for image_manifest in manifest_list["image_manifests"]: | 
					
						
							|  |  |  |         _ = client.put_image( | 
					
						
							|  |  |  |             repositoryName="test_repository", | 
					
						
							|  |  |  |             imageManifest=json.dumps(image_manifest), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.put_image( | 
					
						
							|  |  |  |         repositoryName="test_repository", | 
					
						
							|  |  |  |         imageManifest=json.dumps(manifest_list["manifest_list"]), | 
					
						
							|  |  |  |         imageTag="multiArch", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response["image"]["imageId"]["imageTag"].should.equal("multiArch") | 
					
						
							|  |  |  |     response["image"]["imageId"]["imageDigest"].should.contain("sha") | 
					
						
							|  |  |  |     response["image"]["repositoryName"].should.equal("test_repository") | 
					
						
							|  |  |  |     response["image"]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["image"].should.have.key("imageManifest") | 
					
						
							|  |  |  |     image_manifest = json.loads(response["image"]["imageManifest"]) | 
					
						
							|  |  |  |     image_manifest.should.have.key("mediaType") | 
					
						
							|  |  |  |     image_manifest.should.have.key("manifests") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_image_with_push_date(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     if os.environ.get("TEST_SERVER_MODE", "false").lower() == "true": | 
					
						
							|  |  |  |         raise SkipTest("Cant manipulate time in server mode") | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     with freeze_time("2018-08-28 00:00:00"): | 
					
						
							| 
									
										
										
										
											2021-10-30 06:00:40 -04:00
										 |  |  |         image1_date = datetime.now(tzlocal()) | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  |         _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  |             imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2022-10-15 09:50:42 +00:00
										 |  |  |             imageTag="first", | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     with freeze_time("2019-05-31 00:00:00"): | 
					
						
							| 
									
										
										
										
											2021-10-30 06:00:40 -04:00
										 |  |  |         image2_date = datetime.now(tzlocal()) | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  |         _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  |             imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2022-10-15 09:50:42 +00:00
										 |  |  |             imageTag="second", | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     describe_response = client.describe_images(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(describe_response["imageDetails"]).should.be(list) | 
					
						
							|  |  |  |     len(describe_response["imageDetails"]).should.be(2) | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     set( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             describe_response["imageDetails"][0]["imagePushedAt"], | 
					
						
							|  |  |  |             describe_response["imageDetails"][1]["imagePushedAt"], | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ).should.equal(set([image1_date, image2_date])) | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_image_with_multiple_tags(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  |     manifest = _create_image_manifest() | 
					
						
							|  |  |  |     response = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  |         imageManifest=json.dumps(manifest), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="v1", | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response["image"]["imageId"]["imageTag"].should.equal("v1") | 
					
						
							|  |  |  |     response["image"]["imageId"]["imageDigest"].should.contain("sha") | 
					
						
							|  |  |  |     response["image"]["repositoryName"].should.equal("test_repository") | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     response["image"]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     response1 = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  |         imageManifest=json.dumps(manifest), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="latest", | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response1["image"]["imageId"]["imageTag"].should.equal("latest") | 
					
						
							|  |  |  |     response1["image"]["imageId"]["imageDigest"].should.contain("sha") | 
					
						
							|  |  |  |     response1["image"]["repositoryName"].should.equal("test_repository") | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     response1["image"]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response2 = client.describe_images(repositoryName="test_repository") | 
					
						
							|  |  |  |     type(response2["imageDetails"]).should.be(list) | 
					
						
							|  |  |  |     len(response2["imageDetails"]).should.be(1) | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response2["imageDetails"][0]["imageDigest"].should.contain("sha") | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     response2["imageDetails"][0]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							| 
									
										
										
										
											2018-06-14 09:07:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response2["imageDetails"][0]["repositoryName"].should.equal("test_repository") | 
					
						
							| 
									
										
										
										
											2018-06-14 09:07:09 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     len(response2["imageDetails"][0]["imageTags"]).should.be(2) | 
					
						
							|  |  |  |     response2["imageDetails"][0]["imageTags"].should.be.equal(["v1", "latest"]) | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-06 08:34:10 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-15 09:50:42 +00:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_multiple_images_with_same_tag(): | 
					
						
							|  |  |  |     repo_name = "testrepo" | 
					
						
							|  |  |  |     image_tag = "my-tag" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client = boto3.client("ecr", "us-east-1") | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     image_1 = client.put_image( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         imageTag=image_tag, | 
					
						
							|  |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							|  |  |  |     )["image"]["imageId"]["imageDigest"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # We should overwrite the first image | 
					
						
							|  |  |  |     image_2 = client.put_image( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         imageTag=image_tag, | 
					
						
							|  |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							|  |  |  |     )["image"]["imageId"]["imageDigest"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     assert image_1 != image_2 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     images = client.describe_images(repositoryName=repo_name)["imageDetails"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     images.should.have.length_of(1) | 
					
						
							|  |  |  |     images[0]["imageDigest"].should.equal(image_2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Image with different tags are allowed | 
					
						
							|  |  |  |     image_3 = client.put_image( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         imageTag="different-tag", | 
					
						
							|  |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							|  |  |  |     )["image"]["imageId"]["imageDigest"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     images = client.describe_images(repositoryName=repo_name)["imageDetails"] | 
					
						
							|  |  |  |     images.should.have.length_of(2) | 
					
						
							|  |  |  |     set([img["imageDigest"] for img in images]).should.equal({image_2, image_3}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_list_images(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository_1") | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     _ = client.create_repository(repositoryName="test_repository_2") | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository_1", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="latest", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository_1", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="v1", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository_1", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="v2", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository_2", | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="oldest", | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response = client.list_images(repositoryName="test_repository_1") | 
					
						
							|  |  |  |     type(response["imageIds"]).should.be(list) | 
					
						
							|  |  |  |     len(response["imageIds"]).should.be(3) | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-05 15:10:23 +01:00
										 |  |  |     for image in response["imageIds"]: | 
					
						
							|  |  |  |         image["imageDigest"].should.contain("sha") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     image_tags = ["latest", "v1", "v2"] | 
					
						
							|  |  |  |     set( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             response["imageIds"][0]["imageTag"], | 
					
						
							|  |  |  |             response["imageIds"][1]["imageTag"], | 
					
						
							|  |  |  |             response["imageIds"][2]["imageTag"], | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ).should.equal(set(image_tags)) | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response = client.list_images(repositoryName="test_repository_2") | 
					
						
							|  |  |  |     type(response["imageIds"]).should.be(list) | 
					
						
							|  |  |  |     len(response["imageIds"]).should.be(1) | 
					
						
							|  |  |  |     response["imageIds"][0]["imageTag"].should.equal("oldest") | 
					
						
							| 
									
										
										
										
											2020-11-05 15:10:23 +01:00
										 |  |  |     response["imageIds"][0]["imageDigest"].should.contain("sha") | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-25 12:34:10 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_list_images_from_repository_that_doesnt_exist(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository_1") | 
					
						
							| 
									
										
										
										
											2018-06-25 12:34:10 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # non existing repo | 
					
						
							|  |  |  |     error_msg = re.compile( | 
					
						
							|  |  |  |         r".*The repository with name 'repo-that-doesnt-exist' does not exist in the registry with id '123'.*", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         re.MULTILINE, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-06-25 12:34:10 -04:00
										 |  |  |     client.list_images.when.called_with( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="repo-that-doesnt-exist", registryId="123" | 
					
						
							| 
									
										
										
										
											2018-06-25 12:34:10 -04:00
										 |  |  |     ).should.throw(Exception, error_msg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # repo does not exist in specified registry | 
					
						
							|  |  |  |     error_msg = re.compile( | 
					
						
							|  |  |  |         r".*The repository with name 'test_repository_1' does not exist in the registry with id '222'.*", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         re.MULTILINE, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2018-06-25 12:34:10 -04:00
										 |  |  |     client.list_images.when.called_with( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository_1", registryId="222" | 
					
						
							| 
									
										
										
										
											2018-06-25 12:34:10 -04:00
										 |  |  |     ).should.throw(Exception, error_msg) | 
					
						
							| 
									
										
										
										
											2017-05-22 21:57:14 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_images(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							|  |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2018-06-13 16:14:18 +02:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="latest", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="v1", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="v2", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-16 10:22:43 -08:00
										 |  |  |     manifest_list = _create_image_manifest_list() | 
					
						
							|  |  |  |     for image_manifest in manifest_list["image_manifests"]: | 
					
						
							|  |  |  |         _ = client.put_image( | 
					
						
							|  |  |  |             repositoryName="test_repository", | 
					
						
							|  |  |  |             imageManifest=json.dumps(image_manifest), | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							|  |  |  |         repositoryName="test_repository", | 
					
						
							|  |  |  |         imageManifest=json.dumps(manifest_list["manifest_list"]), | 
					
						
							|  |  |  |         imageTag="multiArch", | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response = client.describe_images(repositoryName="test_repository") | 
					
						
							|  |  |  |     type(response["imageDetails"]).should.be(list) | 
					
						
							| 
									
										
										
										
											2022-12-16 10:22:43 -08:00
										 |  |  |     len(response["imageDetails"]).should.be(7) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response["imageDetails"][0]["imageManifestMediaType"].should.contain( | 
					
						
							|  |  |  |         "distribution.manifest.v2+json" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response["imageDetails"][1]["imageManifestMediaType"].should.contain( | 
					
						
							|  |  |  |         "distribution.manifest.v2+json" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response["imageDetails"][2]["imageManifestMediaType"].should.contain( | 
					
						
							|  |  |  |         "distribution.manifest.v2+json" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response["imageDetails"][3]["imageManifestMediaType"].should.contain( | 
					
						
							|  |  |  |         "distribution.manifest.v2+json" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response["imageDetails"][4]["imageManifestMediaType"].should.contain( | 
					
						
							|  |  |  |         "distribution.manifest.v2+json" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response["imageDetails"][5]["imageManifestMediaType"].should.contain( | 
					
						
							|  |  |  |         "distribution.manifest.v2+json" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response["imageDetails"][6]["imageManifestMediaType"].should.contain( | 
					
						
							|  |  |  |         "distribution.manifest.list.v2+json" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     response["imageDetails"][0]["imageDigest"].should.contain("sha") | 
					
						
							|  |  |  |     response["imageDetails"][1]["imageDigest"].should.contain("sha") | 
					
						
							|  |  |  |     response["imageDetails"][2]["imageDigest"].should.contain("sha") | 
					
						
							|  |  |  |     response["imageDetails"][3]["imageDigest"].should.contain("sha") | 
					
						
							| 
									
										
										
										
											2022-12-16 10:22:43 -08:00
										 |  |  |     response["imageDetails"][4]["imageDigest"].should.contain("sha") | 
					
						
							|  |  |  |     response["imageDetails"][5]["imageDigest"].should.contain("sha") | 
					
						
							|  |  |  |     response["imageDetails"][6]["imageDigest"].should.contain("sha") | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     response["imageDetails"][0]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["imageDetails"][1]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["imageDetails"][2]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["imageDetails"][3]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							| 
									
										
										
										
											2022-12-16 10:22:43 -08:00
										 |  |  |     response["imageDetails"][4]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["imageDetails"][5]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["imageDetails"][6]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     response["imageDetails"][0]["repositoryName"].should.equal("test_repository") | 
					
						
							|  |  |  |     response["imageDetails"][1]["repositoryName"].should.equal("test_repository") | 
					
						
							|  |  |  |     response["imageDetails"][2]["repositoryName"].should.equal("test_repository") | 
					
						
							|  |  |  |     response["imageDetails"][3]["repositoryName"].should.equal("test_repository") | 
					
						
							| 
									
										
										
										
											2022-12-16 10:22:43 -08:00
										 |  |  |     response["imageDetails"][4]["repositoryName"].should.equal("test_repository") | 
					
						
							|  |  |  |     response["imageDetails"][5]["repositoryName"].should.equal("test_repository") | 
					
						
							|  |  |  |     response["imageDetails"][6]["repositoryName"].should.equal("test_repository") | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     response["imageDetails"][0].should_not.have.key("imageTags") | 
					
						
							| 
									
										
										
										
											2022-12-16 10:22:43 -08:00
										 |  |  |     response["imageDetails"][4].should_not.have.key("imageTags") | 
					
						
							|  |  |  |     response["imageDetails"][5].should_not.have.key("imageTags") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     len(response["imageDetails"][1]["imageTags"]).should.be(1) | 
					
						
							|  |  |  |     len(response["imageDetails"][2]["imageTags"]).should.be(1) | 
					
						
							|  |  |  |     len(response["imageDetails"][3]["imageTags"]).should.be(1) | 
					
						
							| 
									
										
										
										
											2022-12-16 10:22:43 -08:00
										 |  |  |     len(response["imageDetails"][6]["imageTags"]).should.be(1) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |     image_tags = ["latest", "v1", "v2"] | 
					
						
							|  |  |  |     set( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             response["imageDetails"][1]["imageTags"][0], | 
					
						
							|  |  |  |             response["imageDetails"][2]["imageTags"][0], | 
					
						
							|  |  |  |             response["imageDetails"][3]["imageTags"][0], | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ).should.equal(set(image_tags)) | 
					
						
							| 
									
										
										
										
											2017-05-22 15:52:17 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-16 10:22:43 -08:00
										 |  |  |     response["imageDetails"][6].should_not.have.key("imageSizeInBytes") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response["imageDetails"][0]["imageSizeInBytes"].should.be.greater_than(0) | 
					
						
							|  |  |  |     response["imageDetails"][1]["imageSizeInBytes"].should.be.greater_than(0) | 
					
						
							|  |  |  |     response["imageDetails"][2]["imageSizeInBytes"].should.be.greater_than(0) | 
					
						
							|  |  |  |     response["imageDetails"][3]["imageSizeInBytes"].should.be.greater_than(0) | 
					
						
							|  |  |  |     response["imageDetails"][4]["imageSizeInBytes"].should.be.greater_than(0) | 
					
						
							|  |  |  |     response["imageDetails"][5]["imageSizeInBytes"].should.be.greater_than(0) | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_images_by_tag(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     tag_map = {} | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     for tag in ["latest", "v1", "v2"]: | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  |         put_response = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  |             imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             imageTag=tag, | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         tag_map[tag] = put_response["image"] | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for tag, put_response in tag_map.items(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         response = client.describe_images( | 
					
						
							|  |  |  |             repositoryName="test_repository", imageIds=[{"imageTag": tag}] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         len(response["imageDetails"]).should.be(1) | 
					
						
							|  |  |  |         image_detail = response["imageDetails"][0] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |         image_detail["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         image_detail["repositoryName"].should.equal("test_repository") | 
					
						
							|  |  |  |         image_detail["imageTags"].should.equal([put_response["imageId"]["imageTag"]]) | 
					
						
							|  |  |  |         image_detail["imageDigest"].should.equal(put_response["imageId"]["imageDigest"]) | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_images_tags_should_not_contain_empty_tag1(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     manifest = _create_image_manifest() | 
					
						
							|  |  |  |     client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", imageManifest=json.dumps(manifest) | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     tags = ["v1", "v2", "latest"] | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  |     for tag in tags: | 
					
						
							|  |  |  |         client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  |             imageManifest=json.dumps(manifest), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             imageTag=tag, | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response = client.describe_images( | 
					
						
							|  |  |  |         repositoryName="test_repository", imageIds=[{"imageTag": tag}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     len(response["imageDetails"]).should.be(1) | 
					
						
							|  |  |  |     image_detail = response["imageDetails"][0] | 
					
						
							|  |  |  |     len(image_detail["imageTags"]).should.equal(3) | 
					
						
							|  |  |  |     image_detail["imageTags"].should.be.equal(tags) | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_images_tags_should_not_contain_empty_tag2(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  |     manifest = _create_image_manifest() | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     tags = ["v1", "v2"] | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  |     for tag in tags: | 
					
						
							|  |  |  |         client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  |             imageManifest=json.dumps(manifest), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             imageTag=tag, | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", imageManifest=json.dumps(manifest) | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  |         imageManifest=json.dumps(manifest), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="latest", | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response = client.describe_images( | 
					
						
							|  |  |  |         repositoryName="test_repository", imageIds=[{"imageTag": tag}] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     len(response["imageDetails"]).should.be(1) | 
					
						
							|  |  |  |     image_detail = response["imageDetails"][0] | 
					
						
							|  |  |  |     len(image_detail["imageTags"]).should.equal(3) | 
					
						
							|  |  |  |     image_detail["imageTags"].should.be.equal(["v1", "v2", "latest"]) | 
					
						
							| 
									
										
										
										
											2018-06-14 09:53:11 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_repository_that_doesnt_exist(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     error_msg = re.compile( | 
					
						
							|  |  |  |         r".*The repository with name 'repo-that-doesnt-exist' does not exist in the registry with id '123'.*", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         re.MULTILINE, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  |     client.describe_repositories.when.called_with( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryNames=["repo-that-doesnt-exist"], registryId="123" | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  |     ).should.throw(ClientError, error_msg) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_image_that_doesnt_exist(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     error_msg1 = re.compile( | 
					
						
							|  |  |  |         r".*The image with imageId {imageDigest:'null', imageTag:'testtag'} does not exist within " | 
					
						
							| 
									
										
										
										
											2021-08-12 14:06:21 +09:00
										 |  |  |         r"the repository with name 'test_repository' in the registry with id '123456789012'.*", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         re.MULTILINE, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     client.describe_images.when.called_with( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							|  |  |  |         imageIds=[{"imageTag": "testtag"}], | 
					
						
							| 
									
										
										
										
											2021-08-12 14:06:21 +09:00
										 |  |  |         registryId=ACCOUNT_ID, | 
					
						
							| 
									
										
										
										
											2020-03-08 20:56:21 +01:00
										 |  |  |     ).should.throw(client.exceptions.ImageNotFoundException, error_msg1) | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     error_msg2 = re.compile( | 
					
						
							| 
									
										
										
										
											2021-08-12 14:06:21 +09:00
										 |  |  |         r".*The repository with name 'repo-that-doesnt-exist' does not exist in the registry with id '123456789012'.*", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         re.MULTILINE, | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  |     client.describe_images.when.called_with( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="repo-that-doesnt-exist", | 
					
						
							|  |  |  |         imageIds=[{"imageTag": "testtag"}], | 
					
						
							| 
									
										
										
										
											2021-08-12 14:06:21 +09:00
										 |  |  |         registryId=ACCOUNT_ID, | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  |     ).should.throw(ClientError, error_msg2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_repository_that_doesnt_exist(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     repo_name = "repo-that-doesnt-exist" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.delete_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("DeleteRepository") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_repository_error_not_empty(): | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     client.put_image( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							|  |  |  |         imageTag="latest", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.delete_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("DeleteRepository") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotEmptyException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' " | 
					
						
							|  |  |  |         f"in registry with id '{ACCOUNT_ID}' " | 
					
						
							|  |  |  |         "cannot be deleted because it still contains images" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-08-10 19:33:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_images_by_digest(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     tags = ["latest", "v1", "v2"] | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  |     digest_map = {} | 
					
						
							|  |  |  |     for tag in tags: | 
					
						
							|  |  |  |         put_response = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  |             imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             imageTag=tag, | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  |         ) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         digest_map[put_response["image"]["imageId"]["imageDigest"]] = put_response[ | 
					
						
							|  |  |  |             "image" | 
					
						
							|  |  |  |         ] | 
					
						
							| 
									
										
										
										
											2017-06-20 16:22:34 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     for digest, put_response in digest_map.items(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         response = client.describe_images( | 
					
						
							|  |  |  |             repositoryName="test_repository", imageIds=[{"imageDigest": digest}] | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         len(response["imageDetails"]).should.be(1) | 
					
						
							|  |  |  |         image_detail = response["imageDetails"][0] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |         image_detail["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         image_detail["repositoryName"].should.equal("test_repository") | 
					
						
							|  |  |  |         image_detail["imageTags"].should.equal([put_response["imageId"]["imageTag"]]) | 
					
						
							|  |  |  |         image_detail["imageDigest"].should.equal(digest) | 
					
						
							| 
									
										
										
										
											2017-07-25 17:54:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_get_authorization_token_assume_region(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							| 
									
										
										
										
											2017-07-25 17:54:05 -04:00
										 |  |  |     auth_token_response = client.get_authorization_token() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     auth_token_response.should.contain("authorizationData") | 
					
						
							|  |  |  |     auth_token_response.should.contain("ResponseMetadata") | 
					
						
							|  |  |  |     auth_token_response["authorizationData"].should.equal( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             { | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |                 "authorizationToken": "QVdTOjEyMzQ1Njc4OTAxMi1hdXRoLXRva2Vu", | 
					
						
							|  |  |  |                 "proxyEndpoint": f"https://{ACCOUNT_ID}.dkr.ecr.us-east-1.amazonaws.com", | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |                 "expiresAt": datetime(2015, 1, 1, tzinfo=tzlocal()), | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-07-25 17:54:05 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_get_authorization_token_explicit_regions(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     auth_token_response = client.get_authorization_token( | 
					
						
							|  |  |  |         registryIds=["10987654321", "878787878787"] | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-07-25 17:54:05 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     auth_token_response.should.contain("authorizationData") | 
					
						
							|  |  |  |     auth_token_response.should.contain("ResponseMetadata") | 
					
						
							|  |  |  |     auth_token_response["authorizationData"].should.equal( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "authorizationToken": "QVdTOjEwOTg3NjU0MzIxLWF1dGgtdG9rZW4=", | 
					
						
							|  |  |  |                 "proxyEndpoint": "https://10987654321.dkr.ecr.us-east-1.amazonaws.com", | 
					
						
							|  |  |  |                 "expiresAt": datetime(2015, 1, 1, tzinfo=tzlocal()), | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "authorizationToken": "QVdTOjg3ODc4Nzg3ODc4Ny1hdXRoLXRva2Vu", | 
					
						
							|  |  |  |                 "proxyEndpoint": "https://878787878787.dkr.ecr.us-east-1.amazonaws.com", | 
					
						
							|  |  |  |                 "expiresAt": datetime(2015, 1, 1, tzinfo=tzlocal()), | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_batch_get_image(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="latest", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="v1", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="v2", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.batch_get_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", imageIds=[{"imageTag": "v2"}] | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(response["images"]).should.be(list) | 
					
						
							|  |  |  |     len(response["images"]).should.be(1) | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response["images"][0]["imageManifest"].should.contain( | 
					
						
							|  |  |  |         "vnd.docker.distribution.manifest.v2+json" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     response["images"][0]["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response["images"][0]["repositoryName"].should.equal("test_repository") | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     response["images"][0]["imageId"]["imageTag"].should.equal("v2") | 
					
						
							|  |  |  |     response["images"][0]["imageId"]["imageDigest"].should.contain("sha") | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(response["failures"]).should.be(list) | 
					
						
							|  |  |  |     len(response["failures"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_batch_get_image_that_doesnt_exist(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     _ = client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="latest", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="v1", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     _ = client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="v2", | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.batch_get_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", imageIds=[{"imageTag": "v5"}] | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(response["images"]).should.be(list) | 
					
						
							|  |  |  |     len(response["images"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(response["failures"]).should.be(list) | 
					
						
							|  |  |  |     len(response["failures"]).should.be(1) | 
					
						
							|  |  |  |     response["failures"][0]["failureReason"].should.equal("Requested image not found") | 
					
						
							|  |  |  |     response["failures"][0]["failureCode"].should.equal("ImageNotFound") | 
					
						
							|  |  |  |     response["failures"][0]["imageId"]["imageTag"].should.equal("v5") | 
					
						
							| 
									
										
										
										
											2017-12-30 20:39:23 -06:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_batch_delete_image_by_tag(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     manifest = _create_image_manifest() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     tags = ["v1", "v1.0", "latest"] | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     for tag in tags: | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  |         client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |             imageManifest=json.dumps(manifest), | 
					
						
							|  |  |  |             imageTag=tag, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     describe_response1 = client.describe_images(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     batch_delete_response = client.batch_delete_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         registryId="012345678910", | 
					
						
							|  |  |  |         repositoryName="test_repository", | 
					
						
							|  |  |  |         imageIds=[{"imageTag": "latest"}], | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     describe_response2 = client.describe_images(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(describe_response1["imageDetails"][0]["imageTags"]).should.be(list) | 
					
						
							|  |  |  |     len(describe_response1["imageDetails"][0]["imageTags"]).should.be(3) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(describe_response2["imageDetails"][0]["imageTags"]).should.be(list) | 
					
						
							|  |  |  |     len(describe_response2["imageDetails"][0]["imageTags"]).should.be(2) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["imageIds"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["imageIds"]).should.be(1) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     batch_delete_response["imageIds"][0]["imageTag"].should.equal("latest") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["failures"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["failures"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_batch_delete_image_delete_last_tag(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         imageTag="v1", | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     describe_response1 = client.describe_images(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     batch_delete_response = client.batch_delete_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         registryId="012345678910", | 
					
						
							|  |  |  |         repositoryName="test_repository", | 
					
						
							|  |  |  |         imageIds=[{"imageTag": "v1"}], | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     describe_response2 = client.describe_images(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(describe_response1["imageDetails"][0]["imageTags"]).should.be(list) | 
					
						
							|  |  |  |     len(describe_response1["imageDetails"][0]["imageTags"]).should.be(1) | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(describe_response2["imageDetails"]).should.be(list) | 
					
						
							|  |  |  |     len(describe_response2["imageDetails"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["imageIds"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["imageIds"]).should.be(1) | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     batch_delete_response["imageIds"][0]["imageTag"].should.equal("v1") | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["failures"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["failures"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_batch_delete_image_with_nonexistent_tag(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     manifest = _create_image_manifest() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     tags = ["v1", "v1.0", "latest"] | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     for tag in tags: | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  |         client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |             imageManifest=json.dumps(manifest), | 
					
						
							|  |  |  |             imageTag=tag, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     describe_response = client.describe_images(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     missing_tag = "missing-tag" | 
					
						
							|  |  |  |     batch_delete_response = client.batch_delete_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         registryId="012345678910", | 
					
						
							|  |  |  |         repositoryName="test_repository", | 
					
						
							|  |  |  |         imageIds=[{"imageTag": missing_tag}], | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(describe_response["imageDetails"][0]["imageTags"]).should.be(list) | 
					
						
							|  |  |  |     len(describe_response["imageDetails"][0]["imageTags"]).should.be(3) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["imageIds"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["imageIds"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     batch_delete_response["failures"][0]["imageId"]["imageTag"].should.equal( | 
					
						
							|  |  |  |         missing_tag | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     batch_delete_response["failures"][0]["failureCode"].should.equal("ImageNotFound") | 
					
						
							|  |  |  |     batch_delete_response["failures"][0]["failureReason"].should.equal( | 
					
						
							|  |  |  |         "Requested image not found" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["failures"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["failures"]).should.be(1) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_batch_delete_image_by_digest(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     manifest = _create_image_manifest() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     tags = ["v1", "v2", "latest"] | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     for tag in tags: | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  |         client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |             imageManifest=json.dumps(manifest), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             imageTag=tag, | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     describe_response = client.describe_images(repositoryName="test_repository") | 
					
						
							|  |  |  |     image_digest = describe_response["imageDetails"][0]["imageDigest"] | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     batch_delete_response = client.batch_delete_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         registryId="012345678910", | 
					
						
							|  |  |  |         repositoryName="test_repository", | 
					
						
							|  |  |  |         imageIds=[{"imageDigest": image_digest}], | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     describe_response = client.describe_images(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(describe_response["imageDetails"]).should.be(list) | 
					
						
							|  |  |  |     len(describe_response["imageDetails"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["imageIds"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["imageIds"]).should.be(3) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     batch_delete_response["imageIds"][0]["imageDigest"].should.equal(image_digest) | 
					
						
							|  |  |  |     batch_delete_response["imageIds"][1]["imageDigest"].should.equal(image_digest) | 
					
						
							|  |  |  |     batch_delete_response["imageIds"][2]["imageDigest"].should.equal(image_digest) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     set( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             batch_delete_response["imageIds"][0]["imageTag"], | 
					
						
							|  |  |  |             batch_delete_response["imageIds"][1]["imageTag"], | 
					
						
							|  |  |  |             batch_delete_response["imageIds"][2]["imageTag"], | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ).should.equal(set(tags)) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["failures"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["failures"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_batch_delete_image_with_invalid_digest(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     manifest = _create_image_manifest() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     tags = ["v1", "v2", "latest"] | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     for tag in tags: | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  |         client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |             imageManifest=json.dumps(manifest), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             imageTag=tag, | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     invalid_image_digest = "sha256:invalid-digest" | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     batch_delete_response = client.batch_delete_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         registryId="012345678910", | 
					
						
							|  |  |  |         repositoryName="test_repository", | 
					
						
							|  |  |  |         imageIds=[{"imageDigest": invalid_image_digest}], | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["imageIds"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["imageIds"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["failures"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["failures"]).should.be(1) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     batch_delete_response["failures"][0]["imageId"]["imageDigest"].should.equal( | 
					
						
							|  |  |  |         invalid_image_digest | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     batch_delete_response["failures"][0]["failureCode"].should.equal( | 
					
						
							|  |  |  |         "InvalidImageDigest" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     batch_delete_response["failures"][0]["failureReason"].should.equal( | 
					
						
							|  |  |  |         "Invalid request parameters: image digest should satisfy the regex '[a-zA-Z0-9-_+.]+:[a-fA-F0-9]+'" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_batch_delete_image_with_missing_parameters(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     batch_delete_response = client.batch_delete_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         registryId="012345678910", repositoryName="test_repository", imageIds=[{}] | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["imageIds"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["imageIds"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["failures"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["failures"]).should.be(1) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     batch_delete_response["failures"][0]["failureCode"].should.equal( | 
					
						
							|  |  |  |         "MissingDigestAndTag" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     batch_delete_response["failures"][0]["failureReason"].should.equal( | 
					
						
							|  |  |  |         "Invalid request parameters: both tag and digest cannot be null" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_batch_delete_image_with_matching_digest_and_tag(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     manifest = _create_image_manifest() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     tags = ["v1", "v1.0", "latest"] | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     for tag in tags: | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  |         client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |             imageManifest=json.dumps(manifest), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             imageTag=tag, | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     describe_response = client.describe_images(repositoryName="test_repository") | 
					
						
							|  |  |  |     image_digest = describe_response["imageDetails"][0]["imageDigest"] | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     batch_delete_response = client.batch_delete_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         registryId="012345678910", | 
					
						
							|  |  |  |         repositoryName="test_repository", | 
					
						
							|  |  |  |         imageIds=[{"imageDigest": image_digest, "imageTag": "v1"}], | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     describe_response = client.describe_images(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(describe_response["imageDetails"]).should.be(list) | 
					
						
							|  |  |  |     len(describe_response["imageDetails"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["imageIds"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["imageIds"]).should.be(3) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     batch_delete_response["imageIds"][0]["imageDigest"].should.equal(image_digest) | 
					
						
							|  |  |  |     batch_delete_response["imageIds"][1]["imageDigest"].should.equal(image_digest) | 
					
						
							|  |  |  |     batch_delete_response["imageIds"][2]["imageDigest"].should.equal(image_digest) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     set( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             batch_delete_response["imageIds"][0]["imageTag"], | 
					
						
							|  |  |  |             batch_delete_response["imageIds"][1]["imageTag"], | 
					
						
							|  |  |  |             batch_delete_response["imageIds"][2]["imageTag"], | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ).should.equal(set(tags)) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["failures"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["failures"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_batch_delete_image_with_mismatched_digest_and_tag(): | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     client.create_repository(repositoryName="test_repository") | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     manifest = _create_image_manifest() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     tags = ["v1", "latest"] | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     for tag in tags: | 
					
						
							| 
									
										
										
										
											2019-06-17 13:41:35 -04:00
										 |  |  |         client.put_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             repositoryName="test_repository", | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |             imageManifest=json.dumps(manifest), | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |             imageTag=tag, | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     describe_response = client.describe_images(repositoryName="test_repository") | 
					
						
							|  |  |  |     image_digest = describe_response["imageDetails"][0]["imageDigest"] | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |     batch_delete_response = client.batch_delete_image( | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |         registryId="012345678910", | 
					
						
							|  |  |  |         repositoryName="test_repository", | 
					
						
							|  |  |  |         imageIds=[{"imageDigest": image_digest, "imageTag": "v2"}], | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["imageIds"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["imageIds"]).should.be(0) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     type(batch_delete_response["failures"]).should.be(list) | 
					
						
							|  |  |  |     len(batch_delete_response["failures"]).should.be(1) | 
					
						
							| 
									
										
										
										
											2019-05-30 13:16:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-31 08:44:26 -07:00
										 |  |  |     batch_delete_response["failures"][0]["imageId"]["imageDigest"].should.equal( | 
					
						
							|  |  |  |         image_digest | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     batch_delete_response["failures"][0]["imageId"]["imageTag"].should.equal("v2") | 
					
						
							|  |  |  |     batch_delete_response["failures"][0]["failureCode"].should.equal("ImageNotFound") | 
					
						
							|  |  |  |     batch_delete_response["failures"][0]["failureReason"].should.equal( | 
					
						
							|  |  |  |         "Requested image not found" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-25 14:11:54 -01:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_batch_image_with_multiple_images(): | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="us-east-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Populate mock repo with images | 
					
						
							|  |  |  |     for i in range(10): | 
					
						
							|  |  |  |         client.put_image( | 
					
						
							| 
									
										
										
										
											2022-11-23 05:16:33 -08:00
										 |  |  |             repositoryName=repo_name, | 
					
						
							|  |  |  |             imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							|  |  |  |             imageTag=f"tag{i}", | 
					
						
							| 
									
										
										
										
											2022-03-25 14:11:54 -01:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Pull down image digests for each image in the mock repo | 
					
						
							|  |  |  |     repo_images = client.describe_images(repositoryName=repo_name)["imageDetails"] | 
					
						
							|  |  |  |     image_digests = [{"imageDigest": image["imageDigest"]} for image in repo_images] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Pick a couple of images to delete | 
					
						
							|  |  |  |     images_to_delete = image_digests[5:7] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Delete the images | 
					
						
							|  |  |  |     response = client.batch_delete_image( | 
					
						
							|  |  |  |         repositoryName=repo_name, imageIds=images_to_delete | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response["imageIds"].should.have.length_of(2) | 
					
						
							|  |  |  |     response["failures"].should.equal([]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # Verify other images still exist | 
					
						
							|  |  |  |     repo_images = client.describe_images(repositoryName=repo_name)["imageDetails"] | 
					
						
							|  |  |  |     image_tags = [img["imageTags"][0] for img in repo_images] | 
					
						
							|  |  |  |     image_tags.should.equal( | 
					
						
							|  |  |  |         ["tag0", "tag1", "tag2", "tag3", "tag4", "tag7", "tag8", "tag9"] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_list_tags_for_resource(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     arn = client.create_repository( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         repositoryName=repo_name, tags=[{"Key": "key-1", "Value": "value-1"}] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     )["repository"]["repositoryArn"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     tags = client.list_tags_for_resource(resourceArn=arn)["tags"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     tags.should.equal([{"Key": "key-1", "Value": "value-1"}]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_list_tags_for_resource_error_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.list_tags_for_resource( | 
					
						
							|  |  |  |             resourceArn=f"arn:aws:ecr:{region_name}:{ACCOUNT_ID}:repository/{repo_name}" | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("ListTagsForResource") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-05 22:23:11 +09:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_list_tags_for_resource_error_invalid_param(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         client.list_tags_for_resource(resourceArn="invalid") | 
					
						
							| 
									
										
										
										
											2021-08-05 22:23:11 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("ListTagsForResource") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("InvalidParameterException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Invalid parameter at 'resourceArn' failed to satisfy constraint: " | 
					
						
							|  |  |  |         "'Invalid ARN'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_tag_resource(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     arn = client.create_repository( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         repositoryName=repo_name, tags=[{"Key": "key-1", "Value": "value-1"}] | 
					
						
							| 
									
										
										
										
											2021-08-04 00:21:15 +09:00
										 |  |  |     )["repository"]["repositoryArn"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     client.tag_resource(resourceArn=arn, tags=[{"Key": "key-2", "Value": "value-2"}]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     tags = client.list_tags_for_resource(resourceArn=arn)["tags"] | 
					
						
							|  |  |  |     sorted(tags, key=lambda i: i["Key"]).should.equal( | 
					
						
							|  |  |  |         sorted( | 
					
						
							|  |  |  |             [ | 
					
						
							|  |  |  |                 {"Key": "key-1", "Value": "value-1"}, | 
					
						
							|  |  |  |                 {"Key": "key-2", "Value": "value-2"}, | 
					
						
							|  |  |  |             ], | 
					
						
							|  |  |  |             key=lambda i: i["Key"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_tag_resource_error_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.tag_resource( | 
					
						
							|  |  |  |             resourceArn=f"arn:aws:ecr:{region_name}:{ACCOUNT_ID}:repository/{repo_name}", | 
					
						
							|  |  |  |             tags=[{"Key": "key-1", "Value": "value-2"}], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("TagResource") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_untag_resource(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     arn = client.create_repository( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         tags=[ | 
					
						
							|  |  |  |             {"Key": "key-1", "Value": "value-1"}, | 
					
						
							|  |  |  |             {"Key": "key-2", "Value": "value-2"}, | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     )["repository"]["repositoryArn"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     client.untag_resource(resourceArn=arn, tagKeys=["key-1"]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     tags = client.list_tags_for_resource(resourceArn=arn)["tags"] | 
					
						
							|  |  |  |     tags.should.equal([{"Key": "key-2", "Value": "value-2"}]) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_untag_resource_error_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.untag_resource( | 
					
						
							|  |  |  |             resourceArn=f"arn:aws:ecr:{region_name}:{ACCOUNT_ID}:repository/{repo_name}", | 
					
						
							|  |  |  |             tagKeys=["key-1"], | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("UntagResource") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-05 22:23:11 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_image_tag_mutability(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.describe_repositories(repositoryNames=[repo_name]) | 
					
						
							|  |  |  |     response["repositories"][0]["imageTagMutability"].should.equal("MUTABLE") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.put_image_tag_mutability( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         repositoryName=repo_name, imageTagMutability="IMMUTABLE" | 
					
						
							| 
									
										
										
										
											2021-08-05 22:23:11 +09:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["imageTagMutability"].should.equal("IMMUTABLE") | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.describe_repositories(repositoryNames=[repo_name]) | 
					
						
							|  |  |  |     response["repositories"][0]["imageTagMutability"].should.equal("IMMUTABLE") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_image_tag_mutability_error_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.put_image_tag_mutability( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |             repositoryName=repo_name, imageTagMutability="IMMUTABLE" | 
					
						
							| 
									
										
										
										
											2021-08-05 22:23:11 +09:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("PutImageTagMutability") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_image_tag_mutability_error_invalid_param(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.put_image_tag_mutability( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |             repositoryName=repo_name, imageTagMutability="invalid" | 
					
						
							| 
									
										
										
										
											2021-08-05 22:23:11 +09:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("PutImageTagMutability") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("InvalidParameterException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Invalid parameter at 'imageTagMutability' failed to satisfy constraint: " | 
					
						
							|  |  |  |         "'Member must satisfy enum value set: [IMMUTABLE, MUTABLE]'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_image_scanning_configuration(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.describe_repositories(repositoryNames=[repo_name]) | 
					
						
							|  |  |  |     response["repositories"][0]["imageScanningConfiguration"].should.equal( | 
					
						
							|  |  |  |         {"scanOnPush": False} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.put_image_scanning_configuration( | 
					
						
							|  |  |  |         repositoryName=repo_name, imageScanningConfiguration={"scanOnPush": True} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["imageScanningConfiguration"].should.equal({"scanOnPush": True}) | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     response = client.describe_repositories(repositoryNames=[repo_name]) | 
					
						
							|  |  |  |     response["repositories"][0]["imageScanningConfiguration"].should.equal( | 
					
						
							|  |  |  |         {"scanOnPush": True} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_image_scanning_configuration_error_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.put_image_scanning_configuration( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |             repositoryName=repo_name, imageScanningConfiguration={"scanOnPush": True} | 
					
						
							| 
									
										
										
										
											2021-08-05 22:23:11 +09:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("PutImageScanningConfiguration") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-07 16:48:28 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_set_repository_policy(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "Version": "2012-10-17", | 
					
						
							|  |  |  |         "Statement": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Sid": "root", | 
					
						
							|  |  |  |                 "Effect": "Allow", | 
					
						
							|  |  |  |                 "Principal": {"AWS": f"arn:aws:iam::{ACCOUNT_ID}:root"}, | 
					
						
							|  |  |  |                 "Action": ["ecr:DescribeImages"], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.set_repository_policy( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         repositoryName=repo_name, policyText=json.dumps(policy) | 
					
						
							| 
									
										
										
										
											2021-08-07 16:48:28 +09:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     json.loads(response["policyText"]).should.equal(policy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_set_repository_policy_error_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "Version": "2012-10-17", | 
					
						
							|  |  |  |         "Statement": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Sid": "root", | 
					
						
							|  |  |  |                 "Effect": "Allow", | 
					
						
							|  |  |  |                 "Principal": {"AWS": f"arn:aws:iam::{ACCOUNT_ID}:root"}, | 
					
						
							|  |  |  |                 "Action": ["ecr:DescribeImages"], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.set_repository_policy( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |             repositoryName=repo_name, policyText=json.dumps(policy) | 
					
						
							| 
									
										
										
										
											2021-08-07 16:48:28 +09:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("SetRepositoryPolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_set_repository_policy_error_invalid_param(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "Version": "2012-10-17", | 
					
						
							|  |  |  |         "Statement": [{"Effect": "Allow"}], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.set_repository_policy( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |             repositoryName=repo_name, policyText=json.dumps(policy) | 
					
						
							| 
									
										
										
										
											2021-08-07 16:48:28 +09:00
										 |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("SetRepositoryPolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("InvalidParameterException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Invalid parameter at 'PolicyText' failed to satisfy constraint: " | 
					
						
							|  |  |  |         "'Invalid repository policy provided'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_get_repository_policy(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "Version": "2012-10-17", | 
					
						
							|  |  |  |         "Statement": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Sid": "root", | 
					
						
							|  |  |  |                 "Effect": "Allow", | 
					
						
							|  |  |  |                 "Principal": {"AWS": f"arn:aws:iam::{ACCOUNT_ID}:root"}, | 
					
						
							|  |  |  |                 "Action": ["ecr:DescribeImages"], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     client.set_repository_policy( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         repositoryName=repo_name, policyText=json.dumps(policy) | 
					
						
							| 
									
										
										
										
											2021-08-07 16:48:28 +09:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.get_repository_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     json.loads(response["policyText"]).should.equal(policy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_get_repository_policy_error_repo_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.get_repository_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("GetRepositoryPolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_get_repository_policy_error_policy_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.get_repository_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("GetRepositoryPolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryPolicyNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Repository policy does not exist " | 
					
						
							|  |  |  |         f"for the repository with name '{repo_name}' " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_repository_policy(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "Version": "2012-10-17", | 
					
						
							|  |  |  |         "Statement": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Sid": "root", | 
					
						
							|  |  |  |                 "Effect": "Allow", | 
					
						
							|  |  |  |                 "Principal": {"AWS": f"arn:aws:iam::{ACCOUNT_ID}:root"}, | 
					
						
							|  |  |  |                 "Action": ["ecr:DescribeImages"], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     client.set_repository_policy( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         repositoryName=repo_name, policyText=json.dumps(policy) | 
					
						
							| 
									
										
										
										
											2021-08-07 16:48:28 +09:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.delete_repository_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     json.loads(response["policyText"]).should.equal(policy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.get_repository_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     e.value.response["Error"]["Code"].should.contain( | 
					
						
							|  |  |  |         "RepositoryPolicyNotFoundException" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_repository_policy_error_repo_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.delete_repository_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("DeleteRepositoryPolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_repository_policy_error_policy_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.delete_repository_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("DeleteRepositoryPolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryPolicyNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Repository policy does not exist " | 
					
						
							|  |  |  |         f"for the repository with name '{repo_name}' " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-09 22:55:29 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_lifecycle_policy(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "rules": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "rulePriority": 1, | 
					
						
							|  |  |  |                 "description": "test policy", | 
					
						
							|  |  |  |                 "selection": { | 
					
						
							|  |  |  |                     "tagStatus": "untagged", | 
					
						
							|  |  |  |                     "countType": "imageCountMoreThan", | 
					
						
							|  |  |  |                     "countNumber": 30, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 "action": {"type": "expire"}, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.put_lifecycle_policy( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         repositoryName=repo_name, lifecyclePolicyText=json.dumps(policy) | 
					
						
							| 
									
										
										
										
											2021-08-09 22:55:29 +09:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     json.loads(response["lifecyclePolicyText"]).should.equal(policy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_lifecycle_policy_error_repo_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "rules": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "rulePriority": 1, | 
					
						
							|  |  |  |                 "description": "test policy", | 
					
						
							|  |  |  |                 "selection": { | 
					
						
							|  |  |  |                     "tagStatus": "untagged", | 
					
						
							|  |  |  |                     "countType": "imageCountMoreThan", | 
					
						
							|  |  |  |                     "countNumber": 30, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 "action": {"type": "expire"}, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.put_lifecycle_policy( | 
					
						
							|  |  |  |             repositoryName=repo_name, lifecyclePolicyText=json.dumps(policy) | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("PutLifecyclePolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_get_lifecycle_policy(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "rules": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "rulePriority": 1, | 
					
						
							|  |  |  |                 "description": "test policy", | 
					
						
							|  |  |  |                 "selection": { | 
					
						
							|  |  |  |                     "tagStatus": "untagged", | 
					
						
							|  |  |  |                     "countType": "imageCountMoreThan", | 
					
						
							|  |  |  |                     "countNumber": 30, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 "action": {"type": "expire"}, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     client.put_lifecycle_policy( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         repositoryName=repo_name, lifecyclePolicyText=json.dumps(policy) | 
					
						
							| 
									
										
										
										
											2021-08-09 22:55:29 +09:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.get_lifecycle_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     json.loads(response["lifecyclePolicyText"]).should.equal(policy) | 
					
						
							|  |  |  |     response["lastEvaluatedAt"].should.be.a(datetime) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_get_lifecycle_policy_error_repo_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.get_lifecycle_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("GetLifecyclePolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_get_lifecycle_policy_error_policy_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.get_lifecycle_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("GetLifecyclePolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("LifecyclePolicyNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Lifecycle policy does not exist " | 
					
						
							|  |  |  |         f"for the repository with name '{repo_name}' " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_lifecycle_policy(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "rules": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "rulePriority": 1, | 
					
						
							|  |  |  |                 "description": "test policy", | 
					
						
							|  |  |  |                 "selection": { | 
					
						
							|  |  |  |                     "tagStatus": "untagged", | 
					
						
							|  |  |  |                     "countType": "imageCountMoreThan", | 
					
						
							|  |  |  |                     "countNumber": 30, | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 "action": {"type": "expire"}, | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     client.put_lifecycle_policy( | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         repositoryName=repo_name, lifecyclePolicyText=json.dumps(policy) | 
					
						
							| 
									
										
										
										
											2021-08-09 22:55:29 +09:00
										 |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.delete_lifecycle_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     json.loads(response["lifecyclePolicyText"]).should.equal(policy) | 
					
						
							|  |  |  |     response["lastEvaluatedAt"].should.be.a(datetime) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.get_lifecycle_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     e.value.response["Error"]["Code"].should.contain("LifecyclePolicyNotFoundException") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_lifecycle_policy_error_repo_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.delete_lifecycle_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("DeleteLifecyclePolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_lifecycle_policy_error_policy_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.delete_lifecycle_policy(repositoryName=repo_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("DeleteLifecyclePolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("LifecyclePolicyNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Lifecycle policy does not exist " | 
					
						
							|  |  |  |         f"for the repository with name '{repo_name}' " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-11 21:18:12 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							| 
									
										
										
										
											2022-05-19 11:08:02 +00:00
										 |  |  | @pytest.mark.parametrize( | 
					
						
							|  |  |  |     "actions", | 
					
						
							|  |  |  |     ["ecr:CreateRepository", ["ecr:CreateRepository", "ecr:ReplicateImage"]], | 
					
						
							|  |  |  |     ids=["single-action", "multiple-actions"], | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | def test_put_registry_policy(actions): | 
					
						
							| 
									
										
										
										
											2021-08-11 21:18:12 +09:00
										 |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "Version": "2012-10-17", | 
					
						
							|  |  |  |         "Statement": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Effect": "Allow", | 
					
						
							|  |  |  |                 "Principal": { | 
					
						
							|  |  |  |                     "AWS": ["arn:aws:iam::111111111111:root", "222222222222"] | 
					
						
							|  |  |  |                 }, | 
					
						
							| 
									
										
										
										
											2022-05-19 11:08:02 +00:00
										 |  |  |                 "Action": actions, | 
					
						
							| 
									
										
										
										
											2021-08-11 21:18:12 +09:00
										 |  |  |                 "Resource": "*", | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.put_registry_policy(policyText=json.dumps(policy)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     json.loads(response["policyText"]).should.equal(policy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_registry_policy_error_invalid_action(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "Version": "2012-10-17", | 
					
						
							|  |  |  |         "Statement": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Effect": "Allow", | 
					
						
							|  |  |  |                 "Principal": {"AWS": "arn:aws:iam::111111111111:root"}, | 
					
						
							|  |  |  |                 "Action": [ | 
					
						
							|  |  |  |                     "ecr:CreateRepository", | 
					
						
							|  |  |  |                     "ecr:ReplicateImage", | 
					
						
							|  |  |  |                     "ecr:DescribeRepositories", | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |                 "Resource": "*", | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.put_registry_policy(policyText=json.dumps(policy)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("PutRegistryPolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("InvalidParameterException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Invalid parameter at 'PolicyText' failed to satisfy constraint: " | 
					
						
							|  |  |  |         "'Invalid registry policy provided'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_get_registry_policy(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "Version": "2012-10-17", | 
					
						
							|  |  |  |         "Statement": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Effect": "Allow", | 
					
						
							|  |  |  |                 "Principal": { | 
					
						
							|  |  |  |                     "AWS": ["arn:aws:iam::111111111111:root", "222222222222"] | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 "Action": ["ecr:CreateRepository", "ecr:ReplicateImage"], | 
					
						
							|  |  |  |                 "Resource": "*", | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     client.put_registry_policy(policyText=json.dumps(policy)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.get_registry_policy() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     json.loads(response["policyText"]).should.equal(policy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_get_registry_policy_error_policy_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.get_registry_policy() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("GetRegistryPolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RegistryPolicyNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"Registry policy does not exist in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_registry_policy(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     policy = { | 
					
						
							|  |  |  |         "Version": "2012-10-17", | 
					
						
							|  |  |  |         "Statement": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "Effect": "Allow", | 
					
						
							|  |  |  |                 "Principal": { | 
					
						
							|  |  |  |                     "AWS": ["arn:aws:iam::111111111111:root", "222222222222"] | 
					
						
							|  |  |  |                 }, | 
					
						
							|  |  |  |                 "Action": ["ecr:CreateRepository", "ecr:ReplicateImage"], | 
					
						
							|  |  |  |                 "Resource": "*", | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ], | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     client.put_registry_policy(policyText=json.dumps(policy)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.delete_registry_policy() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     json.loads(response["policyText"]).should.equal(policy) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.get_registry_policy() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     e.value.response["Error"]["Code"].should.contain("RegistryPolicyNotFoundException") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_delete_registry_policy_error_policy_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.delete_registry_policy() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("DeleteRegistryPolicy") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RegistryPolicyNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"Registry policy does not exist in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-12 14:06:21 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_start_image_scan(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     image_tag = "latest" | 
					
						
							|  |  |  |     image_digest = client.put_image( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							|  |  |  |         imageTag="latest", | 
					
						
							|  |  |  |     )["image"]["imageId"]["imageDigest"] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.start_image_scan( | 
					
						
							|  |  |  |         repositoryName=repo_name, imageId={"imageTag": image_tag} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     response["imageId"].should.equal( | 
					
						
							|  |  |  |         {"imageDigest": image_digest, "imageTag": image_tag} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response["imageScanStatus"].should.equal({"status": "IN_PROGRESS"}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_start_image_scan_error_repo_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.start_image_scan( | 
					
						
							|  |  |  |             repositoryName=repo_name, imageId={"imageTag": "latest"} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("StartImageScan") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_start_image_scan_error_image_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     image_tag = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.start_image_scan( | 
					
						
							|  |  |  |             repositoryName=repo_name, imageId={"imageTag": image_tag} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("StartImageScan") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("ImageNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The image with imageId {{imageDigest:'null', imageTag:'{image_tag}'}} does not exist " | 
					
						
							|  |  |  |         f"within the repository with name '{repo_name}' " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_start_image_scan_error_image_tag_digest_mismatch(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     image_digest = client.put_image( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							|  |  |  |         imageTag="latest", | 
					
						
							|  |  |  |     )["image"]["imageId"]["imageDigest"] | 
					
						
							|  |  |  |     image_tag = "not-latest" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.start_image_scan( | 
					
						
							|  |  |  |             repositoryName=repo_name, | 
					
						
							|  |  |  |             imageId={"imageTag": image_tag, "imageDigest": image_digest}, | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("StartImageScan") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("ImageNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The image with imageId {{imageDigest:'{image_digest}', imageTag:'{image_tag}'}} does not exist " | 
					
						
							|  |  |  |         f"within the repository with name '{repo_name}' " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_start_image_scan_error_daily_limit(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     image_tag = "latest" | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  |     client.put_image( | 
					
						
							| 
									
										
										
										
											2021-08-12 14:06:21 +09:00
										 |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							|  |  |  |         imageTag="latest", | 
					
						
							| 
									
										
										
										
											2021-10-18 19:44:29 +00:00
										 |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-12 14:06:21 +09:00
										 |  |  |     client.start_image_scan(repositoryName=repo_name, imageId={"imageTag": image_tag}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.start_image_scan( | 
					
						
							|  |  |  |             repositoryName=repo_name, imageId={"imageTag": image_tag} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("StartImageScan") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("LimitExceededException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "The scan quota per image has been exceeded. Wait and try again." | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_image_scan_findings(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     image_tag = "latest" | 
					
						
							|  |  |  |     image_digest = client.put_image( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							|  |  |  |         imageTag="latest", | 
					
						
							|  |  |  |     )["image"]["imageId"]["imageDigest"] | 
					
						
							|  |  |  |     client.start_image_scan(repositoryName=repo_name, imageId={"imageTag": image_tag}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.describe_image_scan_findings( | 
					
						
							|  |  |  |         repositoryName=repo_name, imageId={"imageTag": image_tag} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["repositoryName"].should.equal(repo_name) | 
					
						
							|  |  |  |     response["imageId"].should.equal( | 
					
						
							|  |  |  |         {"imageDigest": image_digest, "imageTag": image_tag} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     response["imageScanStatus"].should.equal( | 
					
						
							|  |  |  |         {"status": "COMPLETE", "description": "The scan was completed successfully."} | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     scan_findings = response["imageScanFindings"] | 
					
						
							|  |  |  |     scan_findings["imageScanCompletedAt"].should.be.a(datetime) | 
					
						
							|  |  |  |     scan_findings["vulnerabilitySourceUpdatedAt"].should.be.a(datetime) | 
					
						
							|  |  |  |     scan_findings["findings"].should.equal( | 
					
						
							|  |  |  |         [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "name": "CVE-9999-9999", | 
					
						
							|  |  |  |                 "uri": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-9999-9999", | 
					
						
							|  |  |  |                 "severity": "HIGH", | 
					
						
							|  |  |  |                 "attributes": [ | 
					
						
							|  |  |  |                     {"key": "package_version", "value": "9.9.9"}, | 
					
						
							|  |  |  |                     {"key": "package_name", "value": "moto_fake"}, | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |                     {"key": "CVSS2_VECTOR", "value": "AV:N/AC:L/Au:N/C:P/I:P/A:P"}, | 
					
						
							| 
									
										
										
										
											2021-08-12 14:06:21 +09:00
										 |  |  |                     {"key": "CVSS2_SCORE", "value": "7.5"}, | 
					
						
							|  |  |  |                 ], | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  |     scan_findings["findingSeverityCounts"].should.equal({"HIGH": 1}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_image_scan_findings_error_repo_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     repo_name = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.describe_image_scan_findings( | 
					
						
							|  |  |  |             repositoryName=repo_name, imageId={"imageTag": "latest"} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("DescribeImageScanFindings") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("RepositoryNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The repository with name '{repo_name}' does not exist " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_image_scan_findings_error_image_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     image_tag = "not-exists" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.describe_image_scan_findings( | 
					
						
							|  |  |  |             repositoryName=repo_name, imageId={"imageTag": image_tag} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("DescribeImageScanFindings") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("ImageNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"The image with imageId {{imageDigest:'null', imageTag:'{image_tag}'}} does not exist " | 
					
						
							|  |  |  |         f"within the repository with name '{repo_name}' " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_image_scan_findings_error_scan_not_exists(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     repo_name = "test-repo" | 
					
						
							|  |  |  |     client.create_repository(repositoryName=repo_name) | 
					
						
							|  |  |  |     image_tag = "latest" | 
					
						
							|  |  |  |     client.put_image( | 
					
						
							|  |  |  |         repositoryName=repo_name, | 
					
						
							|  |  |  |         imageManifest=json.dumps(_create_image_manifest()), | 
					
						
							|  |  |  |         imageTag=image_tag, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.describe_image_scan_findings( | 
					
						
							|  |  |  |             repositoryName=repo_name, imageId={"imageTag": image_tag} | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("DescribeImageScanFindings") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("ScanNotFoundException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         f"Image scan does not exist for the image with '{{imageDigest:'null', imageTag:'{image_tag}'}}' " | 
					
						
							|  |  |  |         f"in the repository with name '{repo_name}' " | 
					
						
							|  |  |  |         f"in the registry with id '{ACCOUNT_ID}'" | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2021-08-15 00:15:56 +09:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_replication_configuration(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     config = { | 
					
						
							| 
									
										
										
										
											2022-03-10 13:39:59 -01:00
										 |  |  |         "rules": [{"destinations": [{"region": "eu-west-1", "registryId": ACCOUNT_ID}]}] | 
					
						
							| 
									
										
										
										
											2021-08-15 00:15:56 +09:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.put_replication_configuration(replicationConfiguration=config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["replicationConfiguration"].should.equal(config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_replication_configuration_error_feature_disabled(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     config = { | 
					
						
							|  |  |  |         "rules": [ | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "destinations": [ | 
					
						
							|  |  |  |                     {"region": "eu-central-1", "registryId": "111111111111"}, | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 "destinations": [ | 
					
						
							|  |  |  |                     {"region": "eu-central-1", "registryId": "222222222222"}, | 
					
						
							|  |  |  |                 ] | 
					
						
							|  |  |  |             }, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.put_replication_configuration(replicationConfiguration=config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("PutReplicationConfiguration") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("ValidationException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal("This feature is disabled") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_put_replication_configuration_error_same_source(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     region_name = "eu-central-1" | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name=region_name) | 
					
						
							|  |  |  |     config = { | 
					
						
							|  |  |  |         "rules": [ | 
					
						
							|  |  |  |             {"destinations": [{"region": region_name, "registryId": ACCOUNT_ID}]}, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     with pytest.raises(ClientError) as e: | 
					
						
							|  |  |  |         client.put_replication_configuration(replicationConfiguration=config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     ex = e.value | 
					
						
							|  |  |  |     ex.operation_name.should.equal("PutReplicationConfiguration") | 
					
						
							|  |  |  |     ex.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400) | 
					
						
							|  |  |  |     ex.response["Error"]["Code"].should.contain("InvalidParameterException") | 
					
						
							|  |  |  |     ex.response["Error"]["Message"].should.equal( | 
					
						
							|  |  |  |         "Invalid parameter at 'replicationConfiguration' failed to satisfy constraint: " | 
					
						
							|  |  |  |         "'Replication destination cannot be the same as the source registry'" | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_registry(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.describe_registry() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["registryId"].should.equal(ACCOUNT_ID) | 
					
						
							|  |  |  |     response["replicationConfiguration"].should.equal({"rules": []}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @mock_ecr | 
					
						
							|  |  |  | def test_describe_registry_after_update(): | 
					
						
							|  |  |  |     # given | 
					
						
							|  |  |  |     client = boto3.client("ecr", region_name="eu-central-1") | 
					
						
							|  |  |  |     config = { | 
					
						
							|  |  |  |         "rules": [ | 
					
						
							|  |  |  |             {"destinations": [{"region": "eu-west-1", "registryId": ACCOUNT_ID}]}, | 
					
						
							|  |  |  |         ] | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     client.put_replication_configuration(replicationConfiguration=config) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # when | 
					
						
							|  |  |  |     response = client.describe_registry() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # then | 
					
						
							|  |  |  |     response["replicationConfiguration"].should.equal(config) |