)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a87da1a988a268292077c03aabe5edfbb9a3ade8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"cbad0d7a_746a5905","updated":"2025-02-03 19:00:22.000000000","message":"I\u0027m working on a patch that will require this change to the test infrastructure","commit_id":"35996f68b90486d8f0d8e7a3fbcdcbd4955a53d8"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7b957ba357f29a5972b60acaa50565451240853","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"7e0a85a9_86bb90df","updated":"2025-02-10 18:20:28.000000000","message":"this seems really helpful!\n\nI think we could reduce the test churn with some dynamic magic in `__iter__` but that\u0027s not obviously only helpful (esp now that Al\u0027s already done the cleanup!)","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bd2fd5ec5d65113b8055ae8feb55e7fd9b221ba5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"4ede281d_935c992d","updated":"2025-02-11 10:29:15.000000000","message":"follow up to modify encrypter tests https://review.opendev.org/c/openstack/swift/+/941228","commit_id":"f6fa84743fb4f15d2df946642c5804cbe630f627"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9fa8900931c38a4509b5a319ddd3453dd34963a9","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"ebf7014d_16a6459b","updated":"2025-02-11 16:37:57.000000000","message":"yeah headers_and_footers was silly; having FakeSwift manually stich together \"metadata\" as a union of headers/footers for tracking in the uploaded attribute that gets built during PUT/POST requests seems quite reasonable for that internal thing.","commit_id":"a740591883076c791944e40eed109a521ac38604"}],"test/unit/common/middleware/crypto/test_encrypter.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7b957ba357f29a5972b60acaa50565451240853","unresolved":true,"context_lines":[{"line_number":165,"context_line":"        self.assertEqual(exp_etag, base64.b64decode(parts[0]))"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"        # content-type is not encrypted"},{"line_number":168,"context_line":"        self.assertEqual(\u0027text/plain\u0027, actual_headers[\u0027Content-Type\u0027])"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"        # user meta is encrypted"},{"line_number":171,"context_line":"        self._verify_user_metadata("}],"source_content_type":"text/x-python","patch_set":3,"id":"ab8d6d3a_aac729f3","line":168,"updated":"2025-02-10 18:20:28.000000000","message":"this seems way better!","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bd2fd5ec5d65113b8055ae8feb55e7fd9b221ba5","unresolved":false,"context_lines":[{"line_number":165,"context_line":"        self.assertEqual(exp_etag, base64.b64decode(parts[0]))"},{"line_number":166,"context_line":""},{"line_number":167,"context_line":"        # content-type is not encrypted"},{"line_number":168,"context_line":"        self.assertEqual(\u0027text/plain\u0027, actual_headers[\u0027Content-Type\u0027])"},{"line_number":169,"context_line":""},{"line_number":170,"context_line":"        # user meta is encrypted"},{"line_number":171,"context_line":"        self._verify_user_metadata("}],"source_content_type":"text/x-python","patch_set":3,"id":"502b61ee_00cad421","line":168,"in_reply_to":"ab8d6d3a_aac729f3","updated":"2025-02-11 10:29:15.000000000","message":"Acknowledged","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7b957ba357f29a5972b60acaa50565451240853","unresolved":true,"context_lines":[{"line_number":206,"context_line":"        self.assertEqual(\u0027201 Created\u0027, resp.status)"},{"line_number":207,"context_line":"        self.assertEqual(plaintext_etag, resp.headers[\u0027Etag\u0027])"},{"line_number":208,"context_line":"        self.assertEqual(1, len(self.app.calls), self.app.calls)"},{"line_number":209,"context_line":"        self.assertEqual(\u0027PUT\u0027, self.app.calls[0][0])"},{"line_number":210,"context_line":"        req_hdrs \u003d self.app.headers[0]"},{"line_number":211,"context_line":"        actual_footers \u003d self.app.call_list[0].footers"},{"line_number":212,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"3326c478_203e7a87","line":209,"updated":"2025-02-10 18:20:28.000000000","message":"since this isn\u0027t `call_list` the second `[0]` is the method...\n\nI suppose the diff would have been longer; but:\n\n```\nassert 1 \u003d\u003d len(self.app.call_list)\ncall \u003d self.app.call_list[0]\nreq_hdrs \u003d call.headers\n```\n\nThen you don\u0027t even really \"need\":\n\n```\nactual_footers \u003d call.footers\n```","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bd2fd5ec5d65113b8055ae8feb55e7fd9b221ba5","unresolved":false,"context_lines":[{"line_number":206,"context_line":"        self.assertEqual(\u0027201 Created\u0027, resp.status)"},{"line_number":207,"context_line":"        self.assertEqual(plaintext_etag, resp.headers[\u0027Etag\u0027])"},{"line_number":208,"context_line":"        self.assertEqual(1, len(self.app.calls), self.app.calls)"},{"line_number":209,"context_line":"        self.assertEqual(\u0027PUT\u0027, self.app.calls[0][0])"},{"line_number":210,"context_line":"        req_hdrs \u003d self.app.headers[0]"},{"line_number":211,"context_line":"        actual_footers \u003d self.app.call_list[0].footers"},{"line_number":212,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"c821f2c0_c2003417","line":209,"in_reply_to":"3326c478_203e7a87","updated":"2025-02-11 10:29:15.000000000","message":"oh, yeah, let\u0027s use FakeSwiftCall attributes more explicitly.\n\nI think I can summon the energy for some more test bashing, but maybe I\u0027ll do it in a follow on patch to avoid churn here since I have a +2","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"}],"test/unit/common/middleware/helpers.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7b957ba357f29a5972b60acaa50565451240853","unresolved":true,"context_lines":[{"line_number":273,"context_line":"                footers \u003d HeaderKeyDict()"},{"line_number":274,"context_line":"                env[\u0027swift.callback.update_footers\u0027](footers)"},{"line_number":275,"context_line":"                req.headers.update(footers)"},{"line_number":276,"context_line":"                req_headers_copy.update(footers)"},{"line_number":277,"context_line":"            etag \u003d md5(req_body, usedforsecurity\u003dFalse).hexdigest()"},{"line_number":278,"context_line":"            headers.setdefault(\u0027Etag\u0027, etag)"},{"line_number":279,"context_line":"            headers.setdefault(\u0027Content-Length\u0027, len(req_body))"}],"source_content_type":"text/x-python","patch_set":3,"id":"7bc36f1f_5ca6e0a1","side":"PARENT","line":276,"updated":"2025-02-10 18:20:28.000000000","message":"this was definitely confusing","commit_id":"73201cc12dbd0a53bb83b0acf4ed432d5a1b3317"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bd2fd5ec5d65113b8055ae8feb55e7fd9b221ba5","unresolved":false,"context_lines":[{"line_number":273,"context_line":"                footers \u003d HeaderKeyDict()"},{"line_number":274,"context_line":"                env[\u0027swift.callback.update_footers\u0027](footers)"},{"line_number":275,"context_line":"                req.headers.update(footers)"},{"line_number":276,"context_line":"                req_headers_copy.update(footers)"},{"line_number":277,"context_line":"            etag \u003d md5(req_body, usedforsecurity\u003dFalse).hexdigest()"},{"line_number":278,"context_line":"            headers.setdefault(\u0027Etag\u0027, etag)"},{"line_number":279,"context_line":"            headers.setdefault(\u0027Content-Length\u0027, len(req_body))"}],"source_content_type":"text/x-python","patch_set":3,"id":"54bf55d5_2043cc35","side":"PARENT","line":276,"in_reply_to":"7bc36f1f_5ca6e0a1","updated":"2025-02-11 10:29:15.000000000","message":"Acknowledged","commit_id":"73201cc12dbd0a53bb83b0acf4ed432d5a1b3317"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7b957ba357f29a5972b60acaa50565451240853","unresolved":true,"context_lines":[{"line_number":52,"context_line":"        self.mark_closed(self.key)"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":""},{"line_number":55,"context_line":"class FakeSwiftCall(object):"},{"line_number":56,"context_line":"    def __init__(self, req, footers\u003dNone):"},{"line_number":57,"context_line":"        self.method \u003d req.method"},{"line_number":58,"context_line":"        path \u003d req.environ[\u0027PATH_INFO\u0027]"}],"source_content_type":"text/x-python","patch_set":3,"id":"a914d380_44fed163","line":55,"updated":"2025-02-10 18:20:28.000000000","message":"importantly this does not have a iter method; so callers can never try to unpack it by any length... \n\nmaybe we could allow dynamic iter?\n\n\n```\ndef calls_with_headers(self):\n    return [c._set_iter(\u0027method\u0027, \u0027status\u0027, \u0027headers\u0027) for c in self._calls]\n```\n\nwhere `_set_iter` returns self; and `__iter__` looks at the `_iter_vars`\n\n```\ndef __iter__(self):\n    if self._iter_vals:\n        return (getattr(self, v) for v in self._iter_vars)\n    raise TypeError(\u0027please use attribute access\u0027)\n```","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7b957ba357f29a5972b60acaa50565451240853","unresolved":true,"context_lines":[{"line_number":63,"context_line":"        self.footers \u003d footers or HeaderKeyDict()"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    @property"},{"line_number":66,"context_line":"    def headers_and_footers(self):"},{"line_number":67,"context_line":"        result \u003d dict(self.headers)"},{"line_number":68,"context_line":"        result.update(self.footers)"},{"line_number":69,"context_line":"        return result"}],"source_content_type":"text/x-python","patch_set":3,"id":"0191b411_f6151407","line":66,"updated":"2025-02-10 18:20:28.000000000","message":"lame!\n\nIf I\u0027m reading the diff you\u0027ve eliminated all the external-callers/tests that were previously expecting these values to be combined and AFAICT that\u0027s a great thing!\n\nCan we get rid of this or at least make it a private property?","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bd2fd5ec5d65113b8055ae8feb55e7fd9b221ba5","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        self.footers \u003d footers or HeaderKeyDict()"},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    @property"},{"line_number":66,"context_line":"    def headers_and_footers(self):"},{"line_number":67,"context_line":"        result \u003d dict(self.headers)"},{"line_number":68,"context_line":"        result.update(self.footers)"},{"line_number":69,"context_line":"        return result"}],"source_content_type":"text/x-python","patch_set":3,"id":"22094df2_83e7499f","line":66,"in_reply_to":"0191b411_f6151407","updated":"2025-02-11 10:29:15.000000000","message":"yes this is just called from FakeSwift, I guess it could be avoided","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7b957ba357f29a5972b60acaa50565451240853","unresolved":true,"context_lines":[{"line_number":288,"context_line":"            headers.setdefault(\u0027Content-Length\u0027, len(req_body))"},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"            # keep it for subsequent GET requests later"},{"line_number":291,"context_line":"            resp_headers \u003d call.headers_and_footers"},{"line_number":292,"context_line":"            if \"CONTENT_TYPE\" in env:"},{"line_number":293,"context_line":"                resp_headers[\u0027Content-Type\u0027] \u003d env[\"CONTENT_TYPE\"]"},{"line_number":294,"context_line":"            self.uploaded[env[\u0027PATH_INFO\u0027]] \u003d (resp_headers, req_body)"}],"source_content_type":"text/x-python","patch_set":3,"id":"d66f3cac_1e688b67","line":291,"updated":"2025-02-10 18:20:28.000000000","message":"oh maybe this is the clue; is someone actually sending content-type as a footer?","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bd2fd5ec5d65113b8055ae8feb55e7fd9b221ba5","unresolved":false,"context_lines":[{"line_number":288,"context_line":"            headers.setdefault(\u0027Content-Length\u0027, len(req_body))"},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"            # keep it for subsequent GET requests later"},{"line_number":291,"context_line":"            resp_headers \u003d call.headers_and_footers"},{"line_number":292,"context_line":"            if \"CONTENT_TYPE\" in env:"},{"line_number":293,"context_line":"                resp_headers[\u0027Content-Type\u0027] \u003d env[\"CONTENT_TYPE\"]"},{"line_number":294,"context_line":"            self.uploaded[env[\u0027PATH_INFO\u0027]] \u003d (resp_headers, req_body)"}],"source_content_type":"text/x-python","patch_set":3,"id":"14512d8d_c425ce95","line":291,"in_reply_to":"d66f3cac_1e688b67","updated":"2025-02-11 10:29:15.000000000","message":"FakeSwift persists all the headers and footers as metadata\n\nconfusingly its called ``resp_headers`` here and ``new_metadata`` at line 300","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7b957ba357f29a5972b60acaa50565451240853","unresolved":true,"context_lines":[{"line_number":397,"context_line":"        in ``call_list``."},{"line_number":398,"context_line":"        \"\"\""},{"line_number":399,"context_line":"        return [(call.method, call.path, call.headers)"},{"line_number":400,"context_line":"                for call in self._calls]"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"    @property"},{"line_number":403,"context_line":"    def call_count(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"39917f40_8fb5a448","line":400,"updated":"2025-02-10 18:20:28.000000000","message":"these all seem ok to maintain; but better if tests move in the direction of using `self.swift.call_list` and do any list-comprehension/attr-selection at the assert.","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bd2fd5ec5d65113b8055ae8feb55e7fd9b221ba5","unresolved":false,"context_lines":[{"line_number":397,"context_line":"        in ``call_list``."},{"line_number":398,"context_line":"        \"\"\""},{"line_number":399,"context_line":"        return [(call.method, call.path, call.headers)"},{"line_number":400,"context_line":"                for call in self._calls]"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":"    @property"},{"line_number":403,"context_line":"    def call_count(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"c5d8c6e5_3e1d40a6","line":400,"in_reply_to":"39917f40_8fb5a448","updated":"2025-02-11 10:29:15.000000000","message":"I agree, I just couldn\u0027t stomach changing all the existing tests, but I have now done more in test_encrypter at least","commit_id":"bb246e90a81256613481ed224e8f4e9a3836ec01"}],"test/unit/common/middleware/test_helpers.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"d7b957ba357f29a5972b60acaa50565451240853","unresolved":true,"context_lines":[{"line_number":530,"context_line":"        self.assertNotIn(\u0027Content-Range\u0027, resp.headers)"},{"line_number":531,"context_line":"        self.assertEqual(\u0027bytes\u003d0-2\u0027, req.headers.get(\u0027Range\u0027))"},{"line_number":532,"context_line":"        self.assertEqual(\u0027bytes\u003d0-2\u0027,"},{"line_number":533,"context_line":"                         swift.calls_with_headers[-1].headers.get(\u0027Range\u0027))"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"    def test_range_ignore_range_header_old_swift(self):"},{"line_number":536,"context_line":"        swift \u003d FakeSwift()"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa856184_09d4a2df","side":"PARENT","line":533,"updated":"2025-02-10 18:20:28.000000000","message":"right... cause this isn\u0027t a named tuple anymore; it\u0027s just a 3-tuple","commit_id":"73201cc12dbd0a53bb83b0acf4ed432d5a1b3317"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bd2fd5ec5d65113b8055ae8feb55e7fd9b221ba5","unresolved":false,"context_lines":[{"line_number":530,"context_line":"        self.assertNotIn(\u0027Content-Range\u0027, resp.headers)"},{"line_number":531,"context_line":"        self.assertEqual(\u0027bytes\u003d0-2\u0027, req.headers.get(\u0027Range\u0027))"},{"line_number":532,"context_line":"        self.assertEqual(\u0027bytes\u003d0-2\u0027,"},{"line_number":533,"context_line":"                         swift.calls_with_headers[-1].headers.get(\u0027Range\u0027))"},{"line_number":534,"context_line":""},{"line_number":535,"context_line":"    def test_range_ignore_range_header_old_swift(self):"},{"line_number":536,"context_line":"        swift \u003d FakeSwift()"}],"source_content_type":"text/x-python","patch_set":3,"id":"73dcd843_315cb451","side":"PARENT","line":533,"in_reply_to":"fa856184_09d4a2df","updated":"2025-02-11 10:29:15.000000000","message":"Acknowledged","commit_id":"73201cc12dbd0a53bb83b0acf4ed432d5a1b3317"}]}
