fix S3 last_modified. Closes #8

This commit is contained in:
Steve Pulec 2013-03-29 17:45:33 -04:00
parent 3882858639
commit b7c46ae7bf
3 changed files with 44 additions and 8 deletions

View File

@ -1,5 +1,4 @@
# from boto.s3.bucket import Bucket import datetime
# from boto.s3.key import Key
import md5 import md5
from moto.core import BaseBackend from moto.core import BaseBackend
@ -9,6 +8,7 @@ class FakeKey(object):
def __init__(self, name, value): def __init__(self, name, value):
self.name = name self.name = name
self.value = value self.value = value
self.last_modified = datetime.datetime.now()
@property @property
def etag(self): def etag(self):
@ -16,6 +16,24 @@ class FakeKey(object):
value_md5.update(self.value) value_md5.update(self.value)
return '"{0}"'.format(value_md5.hexdigest()) return '"{0}"'.format(value_md5.hexdigest())
@property
def last_modified_ISO8601(self):
return self.last_modified.strftime("%Y-%m-%dT%H:%M:%SZ")
@property
def last_modified_RFC1123(self):
# Different datetime formats depending on how the key is obtained
# https://github.com/boto/boto/issues/466
RFC1123 = '%a, %d %b %Y %H:%M:%S GMT'
return self.last_modified.strftime(RFC1123)
@property
def response_dict(self):
return {
'etag': self.etag,
'last-modified': self.last_modified_RFC1123,
}
@property @property
def size(self): def size(self):
return len(self.value) return len(self.value)

View File

@ -90,14 +90,14 @@ def key_response(uri_info, method, body, headers):
# empty string as part of closing the connection. # empty string as part of closing the connection.
new_key = s3_backend.set_key(bucket_name, key_name, body) new_key = s3_backend.set_key(bucket_name, key_name, body)
template = Template(S3_OBJECT_RESPONSE) template = Template(S3_OBJECT_RESPONSE)
return template.render(key=new_key), dict(etag=new_key.etag) return template.render(key=new_key), new_key.response_dict
key = s3_backend.get_key(bucket_name, key_name) key = s3_backend.get_key(bucket_name, key_name)
if key: if key:
return "", dict(etag=key.etag) return "", key.response_dict
elif method == 'HEAD': elif method == 'HEAD':
key = s3_backend.get_key(bucket_name, key_name) key = s3_backend.get_key(bucket_name, key_name)
if key: if key:
return S3_OBJECT_RESPONSE, dict(etag=key.etag) return S3_OBJECT_RESPONSE, key.response_dict
else: else:
return "", dict(status=404) return "", dict(status=404)
elif method == 'DELETE': elif method == 'DELETE':
@ -133,7 +133,7 @@ S3_BUCKET_GET_RESPONSE = """<?xml version="1.0" encoding="UTF-8"?>
{% for key in result_keys %} {% for key in result_keys %}
<Contents> <Contents>
<Key>{{ key.name }}</Key> <Key>{{ key.name }}</Key>
<LastModified>2006-01-01T12:00:00.000Z</LastModified> <LastModified>{{ key.last_modified_ISO8601 }}</LastModified>
<ETag>{{ key.etag }}</ETag> <ETag>{{ key.etag }}</ETag>
<Size>{{ key.size }}</Size> <Size>{{ key.size }}</Size>
<StorageClass>STANDARD</StorageClass> <StorageClass>STANDARD</StorageClass>
@ -190,13 +190,13 @@ S3_DELETE_OBJECT_SUCCESS = """<DeleteObjectResponse xmlns="http://s3.amazonaws.c
S3_OBJECT_RESPONSE = """<PutObjectResponse xmlns="http://s3.amazonaws.com/doc/2006-03-01"> S3_OBJECT_RESPONSE = """<PutObjectResponse xmlns="http://s3.amazonaws.com/doc/2006-03-01">
<PutObjectResponse> <PutObjectResponse>
<ETag>{{ key.etag }}</ETag> <ETag>{{ key.etag }}</ETag>
<LastModified>2006-03-01T12:00:00.183Z</LastModified> <LastModified>{{ key.last_modified_ISO8601 }}</LastModified>
</PutObjectResponse> </PutObjectResponse>
</PutObjectResponse>""" </PutObjectResponse>"""
S3_OBJECT_COPY_RESPONSE = """<CopyObjectResponse xmlns="http://doc.s3.amazonaws.com/2006-03-01"> S3_OBJECT_COPY_RESPONSE = """<CopyObjectResponse xmlns="http://doc.s3.amazonaws.com/2006-03-01">
<CopyObjectResponse> <CopyObjectResponse>
<ETag>{{ key.etag }}</ETag> <ETag>{{ key.etag }}</ETag>
<LastModified>2008-02-18T13:54:10.183Z</LastModified> <LastModified>{{ key.last_modified_ISO8601 }}</LastModified>
</CopyObjectResponse> </CopyObjectResponse>
</CopyObjectResponse>""" </CopyObjectResponse>"""

View File

@ -1,8 +1,10 @@
import datetime
import urllib2 import urllib2
import boto import boto
from boto.exception import S3ResponseError from boto.exception import S3ResponseError
from boto.s3.key import Key from boto.s3.key import Key
from freezegun import freeze_time
import requests import requests
import sure # flake8: noqa import sure # flake8: noqa
@ -90,6 +92,22 @@ def test_copy_key():
bucket.get_key("new-key").get_contents_as_string().should.equal("some value") bucket.get_key("new-key").get_contents_as_string().should.equal("some value")
@freeze_time("2012-01-01 12:00:00")
@mock_s3
def test_last_modified():
# See https://github.com/boto/boto/issues/466
conn = boto.connect_s3()
bucket = conn.create_bucket("foobar")
key = Key(bucket)
key.key = "the-key"
key.set_contents_from_string("some value")
rs = bucket.get_all_keys()
rs[0].last_modified.should.equal('2012-01-01T12:00:00Z')
bucket.get_key("the-key").last_modified.should.equal('Sun, 01 Jan 2012 12:00:00 GMT')
@mock_s3 @mock_s3
def test_get_all_keys(): def test_get_all_keys():
conn = boto.connect_s3('the_key', 'the_secret') conn = boto.connect_s3('the_key', 'the_secret')