)]}'
{"swift/common/middleware/copy.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee69f84718f8071a294e8dbfb5fa36db6f060f11","unresolved":false,"context_lines":[{"line_number":474,"context_line":"        # Set data source, content length and etag for the PUT request"},{"line_number":475,"context_line":"        sink_req.environ[\u0027wsgi.input\u0027] \u003d FileLikeIter(source_resp.app_iter)"},{"line_number":476,"context_line":"        sink_req.content_length \u003d source_resp.content_length"},{"line_number":477,"context_line":"        if source_resp.status_int !\u003d HTTP_PARTIAL_CONTENT:"},{"line_number":478,"context_line":"            # have the content of the copied object verified against its Etag"},{"line_number":479,"context_line":"            # unless the request was for a Range in which case the response"},{"line_number":480,"context_line":"            # Etag may not match the content"}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_8f0b362b","line":477,"updated":"2016-06-02 16:25:31.000000000","message":"Maybe better to check for \u003d\u003d HTTP_OK?\n\nWe know it\u0027s in 1xx or 2xx or we would\u0027ve bailed already. The fact that this is a GET should rule out 1xx, 201, and 202. 200 and 206 we definitely know how we want to handle. And even zero-byte objects will respond 200 (rather than 204).\n\nThat leaves 203, 205, 207, 208, and 226. I don\u0027t think we ever send these, but if we did (or some third-party middleware did), I don\u0027t know that we should trust the etag coming out of it to match the MD5 of the content.","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7dc122a837cd55f72660fd94d1db458c0c7cdbab","unresolved":false,"context_lines":[{"line_number":474,"context_line":"        # Set data source, content length and etag for the PUT request"},{"line_number":475,"context_line":"        sink_req.environ[\u0027wsgi.input\u0027] \u003d FileLikeIter(source_resp.app_iter)"},{"line_number":476,"context_line":"        sink_req.content_length \u003d source_resp.content_length"},{"line_number":477,"context_line":"        if source_resp.status_int !\u003d HTTP_PARTIAL_CONTENT:"},{"line_number":478,"context_line":"            # have the content of the copied object verified against its Etag"},{"line_number":479,"context_line":"            # unless the request was for a Range in which case the response"},{"line_number":480,"context_line":"            # Etag may not match the content"}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_98818292","line":477,"in_reply_to":"9abb7d3a_8f0b362b","updated":"2016-06-03 15:14:15.000000000","message":"Done","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee69f84718f8071a294e8dbfb5fa36db6f060f11","unresolved":false,"context_lines":[{"line_number":478,"context_line":"            # have the content of the copied object verified against its Etag"},{"line_number":479,"context_line":"            # unless the request was for a Range in which case the response"},{"line_number":480,"context_line":"            # Etag may not match the content"},{"line_number":481,"context_line":"            sink_req.headers[\u0027Etag\u0027] \u003d source_resp.etag"},{"line_number":482,"context_line":""},{"line_number":483,"context_line":"        # We no longer need these headers"},{"line_number":484,"context_line":"        sink_req.headers.pop(\u0027X-Copy-From\u0027, None)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_4b81414d","line":481,"updated":"2016-06-02 16:25:31.000000000","message":"How will this work for large objects? Or rather, *will* it work for large objects?","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"},{"author":{"_account_id":9625,"name":"Thiago da Silva","email":"thiagodasilva@gmail.com","username":"thiago"},"change_message_id":"b8eb6f2b9ef2c218308d3d672d00138e6a9d8b7f","unresolved":false,"context_lines":[{"line_number":478,"context_line":"            # have the content of the copied object verified against its Etag"},{"line_number":479,"context_line":"            # unless the request was for a Range in which case the response"},{"line_number":480,"context_line":"            # Etag may not match the content"},{"line_number":481,"context_line":"            sink_req.headers[\u0027Etag\u0027] \u003d source_resp.etag"},{"line_number":482,"context_line":""},{"line_number":483,"context_line":"        # We no longer need these headers"},{"line_number":484,"context_line":"        sink_req.headers.pop(\u0027X-Copy-From\u0027, None)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_7a87a9d7","line":481,"in_reply_to":"9abb7d3a_4b81414d","updated":"2016-06-02 17:39:33.000000000","message":"looks like it doesn\u0027t work for large objects as func tests fail.\n\nHow about this: https://paste.fedoraproject.org/373832/48891041/","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7dc122a837cd55f72660fd94d1db458c0c7cdbab","unresolved":false,"context_lines":[{"line_number":478,"context_line":"            # have the content of the copied object verified against its Etag"},{"line_number":479,"context_line":"            # unless the request was for a Range in which case the response"},{"line_number":480,"context_line":"            # Etag may not match the content"},{"line_number":481,"context_line":"            sink_req.headers[\u0027Etag\u0027] \u003d source_resp.etag"},{"line_number":482,"context_line":""},{"line_number":483,"context_line":"        # We no longer need these headers"},{"line_number":484,"context_line":"        sink_req.headers.pop(\u0027X-Copy-From\u0027, None)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_3b35f0da","line":481,"in_reply_to":"9abb7d3a_7a87a9d7","updated":"2016-06-03 15:14:15.000000000","message":"thanks, Done, although I think DLO manifest copies can retain their etags (and they may have non-zero content so worth verifying the etag)","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"}],"test/functional/tests.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee69f84718f8071a294e8dbfb5fa36db6f060f11","unresolved":false,"context_lines":[{"line_number":1211,"context_line":"                else:"},{"line_number":1212,"context_line":"                    self.fail(\u0027Failed to find %s in listing\u0027 % dest_filename)"},{"line_number":1213,"context_line":""},{"line_number":1214,"context_line":"                self.assertEqual(1024, obj[\u0027bytes\u0027])"},{"line_number":1215,"context_line":"                self.assertEqual(file_item.etag, obj[\u0027hash\u0027])"},{"line_number":1216,"context_line":"                self.assertEqual(file_item.content_type, obj[\u0027content_type\u0027])"},{"line_number":1217,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_0bdbb91c","line":1214,"range":{"start_line":1214,"start_character":33,"end_line":1214,"end_character":37},"updated":"2016-06-02 16:25:31.000000000","message":"Maybe better as len(data)? Or file_item.size?","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7dc122a837cd55f72660fd94d1db458c0c7cdbab","unresolved":false,"context_lines":[{"line_number":1211,"context_line":"                else:"},{"line_number":1212,"context_line":"                    self.fail(\u0027Failed to find %s in listing\u0027 % dest_filename)"},{"line_number":1213,"context_line":""},{"line_number":1214,"context_line":"                self.assertEqual(1024, obj[\u0027bytes\u0027])"},{"line_number":1215,"context_line":"                self.assertEqual(file_item.etag, obj[\u0027hash\u0027])"},{"line_number":1216,"context_line":"                self.assertEqual(file_item.content_type, obj[\u0027content_type\u0027])"},{"line_number":1217,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_db2b0432","line":1214,"range":{"start_line":1214,"start_character":33,"end_line":1214,"end_character":37},"in_reply_to":"9abb7d3a_0bdbb91c","updated":"2016-06-03 15:14:15.000000000","message":"Done","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee69f84718f8071a294e8dbfb5fa36db6f060f11","unresolved":false,"context_lines":[{"line_number":1216,"context_line":"                self.assertEqual(file_item.content_type, obj[\u0027content_type\u0027])"},{"line_number":1217,"context_line":""},{"line_number":1218,"context_line":"                # verify copy object"},{"line_number":1219,"context_line":"                copy_file_item \u003d cont.file(dest_filename)"},{"line_number":1220,"context_line":"                self.assertEqual(data, copy_file_item.read())"},{"line_number":1221,"context_line":"                self.assertTrue(copy_file_item.initialize())"},{"line_number":1222,"context_line":"                self.assertEqual(metadata, copy_file_item.metadata)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_cbcd3188","line":1219,"range":{"start_line":1219,"start_character":16,"end_line":1219,"end_character":30},"updated":"2016-06-02 16:25:31.000000000","message":"Nice.","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee69f84718f8071a294e8dbfb5fa36db6f060f11","unresolved":false,"context_lines":[{"line_number":1227,"context_line":"        file_item \u003d self.env.container.file(source_filename)"},{"line_number":1228,"context_line":""},{"line_number":1229,"context_line":"        metadata \u003d {}"},{"line_number":1230,"context_line":"        for i in range(1):"},{"line_number":1231,"context_line":"            metadata[Utils.create_ascii_name()] \u003d Utils.create_name()"},{"line_number":1232,"context_line":""},{"line_number":1233,"context_line":"        data \u003d file_item.write_random(1024)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_0baa9919","line":1230,"updated":"2016-06-02 16:25:31.000000000","message":"I know this was copy/pasted, but it still feels silly.","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7dc122a837cd55f72660fd94d1db458c0c7cdbab","unresolved":false,"context_lines":[{"line_number":1227,"context_line":"        file_item \u003d self.env.container.file(source_filename)"},{"line_number":1228,"context_line":""},{"line_number":1229,"context_line":"        metadata \u003d {}"},{"line_number":1230,"context_line":"        for i in range(1):"},{"line_number":1231,"context_line":"            metadata[Utils.create_ascii_name()] \u003d Utils.create_name()"},{"line_number":1232,"context_line":""},{"line_number":1233,"context_line":"        data \u003d file_item.write_random(1024)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_3b90504e","line":1230,"in_reply_to":"9abb7d3a_0baa9919","updated":"2016-06-03 15:14:15.000000000","message":"Done","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee69f84718f8071a294e8dbfb5fa36db6f060f11","unresolved":false,"context_lines":[{"line_number":1238,"context_line":"        self.assertTrue(dest_cont.create())"},{"line_number":1239,"context_line":""},{"line_number":1240,"context_line":"        expected_body \u003d data[100:201]"},{"line_number":1241,"context_line":"        expected_etag \u003d hashlib.md5()"},{"line_number":1242,"context_line":"        expected_etag.update(expected_body)"},{"line_number":1243,"context_line":"        # copy both from within and across containers"},{"line_number":1244,"context_line":"        for cont in (self.env.container, dest_cont):"}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_0b58d955","line":1241,"updated":"2016-06-02 16:25:31.000000000","message":"nit: You could just say hashlib.md5(expected_body) and skip the next line.","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7dc122a837cd55f72660fd94d1db458c0c7cdbab","unresolved":false,"context_lines":[{"line_number":1238,"context_line":"        self.assertTrue(dest_cont.create())"},{"line_number":1239,"context_line":""},{"line_number":1240,"context_line":"        expected_body \u003d data[100:201]"},{"line_number":1241,"context_line":"        expected_etag \u003d hashlib.md5()"},{"line_number":1242,"context_line":"        expected_etag.update(expected_body)"},{"line_number":1243,"context_line":"        # copy both from within and across containers"},{"line_number":1244,"context_line":"        for cont in (self.env.container, dest_cont):"}],"source_content_type":"text/x-python","patch_set":1,"id":"9abb7d3a_fb0ec88a","line":1241,"in_reply_to":"9abb7d3a_0b58d955","updated":"2016-06-03 15:14:15.000000000","message":"yep, should have done that.","commit_id":"67be617880562d3c23e356e4068b5e1ba51fe5ad"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"441114253d67fb781952a10d46dfd93d4174a0e6","unresolved":false,"context_lines":[{"line_number":1193,"context_line":""},{"line_number":1194,"context_line":"        dest_cont \u003d self.env.account.container(Utils.create_name())"},{"line_number":1195,"context_line":"        self.assertTrue(dest_cont.create())"},{"line_number":1196,"context_line":""},{"line_number":1197,"context_line":"        # copy both from within and across containers"},{"line_number":1198,"context_line":"        for cont in (self.env.container, dest_cont):"},{"line_number":1199,"context_line":"            # copy both with and without initial slash"}],"source_content_type":"text/x-python","patch_set":5,"id":"dada55a8_61b0638c","line":1196,"updated":"2016-07-25 13:02:34.000000000","message":"This code looked very familiar and then it hit me that another change also improves this test: https://review.openstack.org/#/c/272724/11/test/functional/tests.py\n\nYou may want to consider making that patch dependent on this one.","commit_id":"e44ac6b3671784112fe8c996a4ec5b8c0eb5d327"},{"author":{"_account_id":12261,"name":"Mahati","email":"mahati.chamarthy@gmail.com","username":"Mahati"},"change_message_id":"683e155231e5f4c62b7a0ba5947d82a6bb695a3b","unresolved":false,"context_lines":[{"line_number":1260,"context_line":""},{"line_number":1261,"context_line":"                # verify copy object"},{"line_number":1262,"context_line":"                copy_file_item \u003d cont.file(dest_filename)"},{"line_number":1263,"context_line":"                self.assertEqual(expected_body, copy_file_item.read())"},{"line_number":1264,"context_line":"                self.assertTrue(copy_file_item.initialize())"},{"line_number":1265,"context_line":"                self.assertEqual(metadata, copy_file_item.metadata)"},{"line_number":1266,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"bacf61ea_22e689b4","line":1263,"updated":"2016-07-28 14:22:36.000000000","message":"Nice!","commit_id":"e44ac6b3671784112fe8c996a4ec5b8c0eb5d327"},{"author":{"_account_id":8542,"name":"Prashanth Pai","email":"ppai@redhat.com","username":"pai"},"change_message_id":"8416c09f2bb98285044fdedeb5179a53991dd2d6","unresolved":false,"context_lines":[{"line_number":1303,"context_line":"                for k in (\u0027Content-Disposition\u0027, \u0027Content-Encoding\u0027):"},{"line_number":1304,"context_line":"                    self.assertNotIn(k.lower(), resp_headers)"},{"line_number":1305,"context_line":""},{"line_number":1306,"context_line":"                # verify container listing for copy"},{"line_number":1307,"context_line":"                listing \u003d cont.files(parms\u003d{\u0027format\u0027: \u0027json\u0027})"},{"line_number":1308,"context_line":"                for obj in listing:"},{"line_number":1309,"context_line":"                    if obj[\u0027name\u0027] \u003d\u003d dest_filename:"}],"source_content_type":"text/x-python","patch_set":6,"id":"bacf61ea_76aa751a","line":1306,"range":{"start_line":1306,"start_character":47,"end_line":1306,"end_character":51},"updated":"2016-08-01 14:53:11.000000000","message":"This test is pretty long. You could put all the \u0027verify container listing for copy\u0027 code in a local method.","commit_id":"a49db4e6f4eaa8ec57abdc4cbc20eaefca5c8846"}],"test/unit/common/middleware/test_copy.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3784811ef05fab0f157a51d42a4f304f07b70db0","unresolved":false,"context_lines":[{"line_number":1356,"context_line":"        expected_puts \u003d POLICIES.default.ec_ndata + POLICIES.default.ec_nparity"},{"line_number":1357,"context_line":"        self.assertEqual(expected_puts, len(put_hdrs))"},{"line_number":1358,"context_line":"        for hdrs in put_hdrs:"},{"line_number":1359,"context_line":"            # etag should not be copied from source"},{"line_number":1360,"context_line":"            self.assertNotIn(\u0027etag\u0027, (h.lower() for h in hdrs))"},{"line_number":1361,"context_line":""},{"line_number":1362,"context_line":"    def test_COPY_with_invalid_ranges(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"dada55a8_4b2ad5e8","line":1359,"updated":"2016-07-22 17:24:07.000000000","message":"Would there have been an etag here if we didn\u0027t include the range? Since we\u0027re looking at the actual PUTs down to the object servers... for an EC policy... shouldn\u0027t the proxy-server be popping off etag and comparing locally?\n\nOn the other hand, I thought we were talking about making EC behave a little more like crypto, and have it send down an ETag in the footers regardless of whether the \"client\" (in this case, the copy middleware) included one in its headers. If we did that fix/enhancement, would we need to back out this test change?\n\nThe more I think about it, why do we care about EC-ness in this unit test? I thought the separation of concerns was one of the big benefits of pulling COPY out to middleware. Do we still need TestServerSideCopyMiddlewareWithEC at all?","commit_id":"e44ac6b3671784112fe8c996a4ec5b8c0eb5d327"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"fe034c47d70d2f9c8cc1da25289f6b1b54beb987","unresolved":false,"context_lines":[{"line_number":1356,"context_line":"        expected_puts \u003d POLICIES.default.ec_ndata + POLICIES.default.ec_nparity"},{"line_number":1357,"context_line":"        self.assertEqual(expected_puts, len(put_hdrs))"},{"line_number":1358,"context_line":"        for hdrs in put_hdrs:"},{"line_number":1359,"context_line":"            # etag should not be copied from source"},{"line_number":1360,"context_line":"            self.assertNotIn(\u0027etag\u0027, (h.lower() for h in hdrs))"},{"line_number":1361,"context_line":""},{"line_number":1362,"context_line":"    def test_COPY_with_invalid_ranges(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"bacf61ea_7d509832","line":1359,"in_reply_to":"dada55a8_4b2ad5e8","updated":"2016-08-01 14:08:06.000000000","message":"Hmmm, you\u0027re right in that EC strips off the ETag header from the PUT regardless of it being a Ranged copy or not, so really this test is verifying that EC behaviour, rather than the copy middleware behaviour. Indeed, if I regress copy middleware to copy Etag from a ranged response then this test still passes whereas test.unit.common.middleware.test_copy.TestServerSideCopyMiddleware#test_COPY_with_single_range fails.\n\nI guess the point of the test (as a whole) is to verify that EC object controller doesn\u0027t blow up when handling a range copy but I can\u0027t be sure in the absence of any comments.","commit_id":"e44ac6b3671784112fe8c996a4ec5b8c0eb5d327"}]}
