diff --git a/moto/ecr/models.py b/moto/ecr/models.py index 552643fad..9ff37b7d6 100644 --- a/moto/ecr/models.py +++ b/moto/ecr/models.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import hashlib import re from copy import copy +from datetime import datetime from random import random from botocore.exceptions import ParamValidationError @@ -106,7 +107,7 @@ class Image(BaseObject): self.repository = repository self.registry_id = registry_id self.image_digest = digest - self.image_pushed_at = None + self.image_pushed_at = str(datetime.utcnow().isoformat()) def _create_digest(self): image_contents = 'docker_image{0}'.format(int(random() * 10 ** 6)) @@ -158,7 +159,7 @@ class Image(BaseObject): response_object['repositoryName'] = self.repository response_object['registryId'] = self.registry_id response_object['imageSizeInBytes'] = self.image_size_in_bytes - response_object['imagePushedAt'] = '2017-05-09' + response_object['imagePushedAt'] = self.image_pushed_at return {k: v for k, v in response_object.items() if v is not None and v != []} @property diff --git a/setup.py b/setup.py index bcc4db4d9..bc53ff6bb 100755 --- a/setup.py +++ b/setup.py @@ -24,6 +24,7 @@ install_requires = [ "boto3>=1.9.86", "botocore>=1.12.86", "cryptography>=2.3.0", + "datetime", "requests>=2.5", "xmltodict", "six>1.9", diff --git a/tests/test_ecr/test_ecr_boto3.py b/tests/test_ecr/test_ecr_boto3.py index ff845e4b1..221eba842 100644 --- a/tests/test_ecr/test_ecr_boto3.py +++ b/tests/test_ecr/test_ecr_boto3.py @@ -3,6 +3,8 @@ from __future__ import unicode_literals import hashlib import json from datetime import datetime +from freezegun import freeze_time +import os from random import random import re @@ -13,6 +15,7 @@ from botocore.exceptions import ClientError, ParamValidationError from dateutil.tz import tzlocal from moto import mock_ecr +from nose import SkipTest def _create_image_digest(contents=None): @@ -198,6 +201,42 @@ def test_put_image(): response['image']['repositoryName'].should.equal('test_repository') response['image']['registryId'].should.equal('012345678910') + +@mock_ecr +def test_put_image_with_push_date(): + if os.environ.get('TEST_SERVER_MODE', 'false').lower() == 'true': + raise SkipTest('Cant manipulate time in server mode') + + client = boto3.client('ecr', region_name='us-east-1') + _ = client.create_repository( + repositoryName='test_repository' + ) + + with freeze_time('2018-08-28 00:00:00'): + image1_date = datetime.now() + _ = client.put_image( + repositoryName='test_repository', + imageManifest=json.dumps(_create_image_manifest()), + imageTag='latest' + ) + + with freeze_time('2019-05-31 00:00:00'): + image2_date = datetime.now() + _ = client.put_image( + repositoryName='test_repository', + imageManifest=json.dumps(_create_image_manifest()), + imageTag='latest' + ) + + describe_response = client.describe_images(repositoryName='test_repository') + + type(describe_response['imageDetails']).should.be(list) + len(describe_response['imageDetails']).should.be(2) + + set([describe_response['imageDetails'][0]['imagePushedAt'], + describe_response['imageDetails'][1]['imagePushedAt']]).should.equal(set([image1_date, image2_date])) + + @mock_ecr def test_put_image_with_multiple_tags(): client = boto3.client('ecr', region_name='us-east-1') @@ -240,6 +279,7 @@ def test_put_image_with_multiple_tags(): len(response2['imageDetails'][0]['imageTags']).should.be(2) response2['imageDetails'][0]['imageTags'].should.be.equal(['v1', 'latest']) + @mock_ecr def test_list_images(): client = boto3.client('ecr', region_name='us-east-1')