Consistent timestamp formatting for last_modified.

Fixes bug 798268.

Python datetime's isoformat() uses %Y-%m-%dT%H:%M:%S.%f format, but
the miliseconds part is not included when it's zero.

As consequence the compliant ISO 8601 format was not consistent
when performing a GET request over a container (listing objects info).

Change-Id: Ifed3f0adf3eaca47304c142615169bd3f1901631
This commit is contained in:
Juan J. Martinez 2012-02-02 11:54:15 +00:00
parent a196386ee6
commit bb3bfe1dbd
2 changed files with 49 additions and 8 deletions

View File

@ -326,6 +326,9 @@ class ContainerController(object):
name = simplejson.dumps(name)
created_at = datetime.utcfromtimestamp(
float(created_at)).isoformat()
# python isoformat() doesn't include msecs when zero
if len(created_at) < len("1970-01-01T00:00:00.000000"):
created_at += ".000000"
if content_type is None:
json_out.append('{"subdir":%s}' % name)
else:
@ -343,6 +346,9 @@ class ContainerController(object):
name = saxutils.escape(name)
created_at = datetime.utcfromtimestamp(
float(created_at)).isoformat()
# python isoformat() doesn't include msecs when zero
if len(created_at) < len("1970-01-01T00:00:00.000000"):
created_at += ".000000"
if content_type is None:
xml_output.append('<subdir name="%s"><name>%s</name>'
'</subdir>' % (name, name))

View File

@ -566,17 +566,17 @@ class TestContainerController(unittest.TestCase):
"hash":"x",
"bytes":0,
"content_type":"text/plain",
"last_modified":"1970-01-01T00:00:01"},
"last_modified":"1970-01-01T00:00:01.000000"},
{"name":"1",
"hash":"x",
"bytes":0,
"content_type":"text/plain",
"last_modified":"1970-01-01T00:00:01"},
"last_modified":"1970-01-01T00:00:01.000000"},
{"name":"2",
"hash":"x",
"bytes":0,
"content_type":"text/plain",
"last_modified":"1970-01-01T00:00:01"}]
"last_modified":"1970-01-01T00:00:01.000000"}]
req = Request.blank('/sda1/p/a/jsonc?format=json',
environ={'REQUEST_METHOD': 'GET'})
@ -644,6 +644,41 @@ class TestContainerController(unittest.TestCase):
self.assertEquals(resp.content_type, 'text/plain')
self.assertEquals(resp.body, plain_body)
def test_GET_json_last_modified(self):
# make a container
req = Request.blank('/sda1/p/a/jsonc', environ={'REQUEST_METHOD': 'PUT',
'HTTP_X_TIMESTAMP': '0'})
resp = self.controller.PUT(req)
for i, d in [(0, 1.5),
(1, 1.0),]:
req = Request.blank('/sda1/p/a/jsonc/%s'%i, environ=
{'REQUEST_METHOD': 'PUT',
'HTTP_X_TIMESTAMP': d,
'HTTP_X_CONTENT_TYPE': 'text/plain',
'HTTP_X_ETAG': 'x',
'HTTP_X_SIZE': 0})
resp = self.controller.PUT(req)
self.assertEquals(resp.status_int, 201)
# test format
# last_modified format must be uniform, even when there are not msecs
json_body = [{"name":"0",
"hash":"x",
"bytes":0,
"content_type":"text/plain",
"last_modified":"1970-01-01T00:00:01.500000"},
{"name":"1",
"hash":"x",
"bytes":0,
"content_type":"text/plain",
"last_modified":"1970-01-01T00:00:01.000000"},]
req = Request.blank('/sda1/p/a/jsonc?format=json',
environ={'REQUEST_METHOD': 'GET'})
resp = self.controller.GET(req)
self.assertEquals(resp.content_type, 'application/json')
self.assertEquals(eval(resp.body), json_body)
self.assertEquals(resp.charset, 'utf-8')
def test_GET_xml(self):
# make a container
req = Request.blank('/sda1/p/a/xmlc', environ={'REQUEST_METHOD': 'PUT',
@ -663,15 +698,15 @@ class TestContainerController(unittest.TestCase):
'<container name="xmlc">' \
'<object><name>0</name><hash>x</hash><bytes>0</bytes>' \
'<content_type>text/plain</content_type>' \
'<last_modified>1970-01-01T00:00:01' \
'<last_modified>1970-01-01T00:00:01.000000' \
'</last_modified></object>' \
'<object><name>1</name><hash>x</hash><bytes>0</bytes>' \
'<content_type>text/plain</content_type>' \
'<last_modified>1970-01-01T00:00:01' \
'<last_modified>1970-01-01T00:00:01.000000' \
'</last_modified></object>' \
'<object><name>2</name><hash>x</hash><bytes>0</bytes>' \
'<content_type>text/plain</content_type>' \
'<last_modified>1970-01-01T00:00:01' \
'<last_modified>1970-01-01T00:00:01.000000' \
'</last_modified></object>' \
'</container>'
# tests
@ -841,9 +876,9 @@ class TestContainerController(unittest.TestCase):
resp = self.controller.GET(req)
self.assertEquals(simplejson.loads(resp.body),
[{"name":"US/OK","hash":"x","bytes":0,"content_type":"text/plain",
"last_modified":"1970-01-01T00:00:01"},
"last_modified":"1970-01-01T00:00:01.000000"},
{"name":"US/TX","hash":"x","bytes":0,"content_type":"text/plain",
"last_modified":"1970-01-01T00:00:01"}])
"last_modified":"1970-01-01T00:00:01.000000"}])
def test_through_call(self):
inbuf = StringIO()