diff --git a/swift/container/server.py b/swift/container/server.py index 0ac5c41aa3..dea558736f 100644 --- a/swift/container/server.py +++ b/swift/container/server.py @@ -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('%s' '' % (name, name)) diff --git a/test/unit/container/test_server.py b/test/unit/container/test_server.py index 64e8cb8ff3..b4c8df8cd5 100644 --- a/test/unit/container/test_server.py +++ b/test/unit/container/test_server.py @@ -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): '' \ '0x0' \ 'text/plain' \ - '1970-01-01T00:00:01' \ + '1970-01-01T00:00:01.000000' \ '' \ '1x0' \ 'text/plain' \ - '1970-01-01T00:00:01' \ + '1970-01-01T00:00:01.000000' \ '' \ '2x0' \ 'text/plain' \ - '1970-01-01T00:00:01' \ + '1970-01-01T00:00:01.000000' \ '' \ '' # 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()