)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5577afb03fd85fae0964547b6914bfdbc6720ee5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"daa51f4a_808581dd","updated":"2026-04-13 20:09:33.000000000","message":"I considered a probe test using boto; but overwrite the marker object using internal client to force a x-timestamp in the future.  The problem is the only behavior to assert is the new error logging; which I think the unittest does more or less well enough.","commit_id":"20c7a5feea5b070842a88420b84c1aad55c63202"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f703ce2c2b7fa2b47d913fdb49168d765de264e1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"2616961f_e863edf2","updated":"2026-04-13 20:29:56.000000000","message":"I\u0027ll probably wait to see what Zuul says before I respin; thanks Tim!","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"dbcc9806ea21da9d687f7598cbcd74af9b9435ff","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"874acc0f_6c6dfd3d","updated":"2026-04-13 21:30:06.000000000","message":"i think i addressed the suggested improvements; but no rush to get it merged IMHO - we can carry it and see how much of this we actually see before we decide what needs to be done; it\u0027s going to be awhile before we can circle back to this with prod data.","commit_id":"ee32640464f47d4fe7be60316dd539376a35a1c2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bc6ebd51fea0673b9e8a0bdedd158d6d141640b8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"2f71e576_534bea4c","updated":"2026-04-14 09:46:06.000000000","message":"looks good: more insight, leveraging the existing pattern gets is proxy_logging and a statsd metric\n\nI agree with Matt that it\u0027d worth one more revision to clean up the stale debug comment","commit_id":"ee32640464f47d4fe7be60316dd539376a35a1c2"}],"swift/common/middleware/s3api/controllers/multi_upload.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5577afb03fd85fae0964547b6914bfdbc6720ee5","unresolved":true,"context_lines":[{"line_number":665,"context_line":"            # clock. The manifest PUT may succeed but the subsequent marker"},{"line_number":666,"context_line":"            # DELETE will fail, so don\u0027t attempt either."},{"line_number":667,"context_line":"            self.logger.error(\u0027Unable to Complete Multipart Upload \u0027"},{"line_number":668,"context_line":"                              \u0027because marker is %s newer\u0027 % marker_delta)"},{"line_number":669,"context_line":"            raise ServiceUnavailable(reason\u003d\u0027MPUClockSkew\u0027)"},{"line_number":670,"context_line":""},{"line_number":671,"context_line":"        headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"2175fbbf_2f4a4ba1","line":668,"updated":"2026-04-13 20:09:33.000000000","message":"with a diff like:\n\n```\ndiff --git a/swift/common/middleware/s3api/controllers/multi_upload.py b/swift/common/middleware/s3api/controllers/multi_upload.py\nindex 3264983275..583b32a9ac 100644\n--- a/swift/common/middleware/s3api/controllers/multi_upload.py\n+++ b/swift/common/middleware/s3api/controllers/multi_upload.py\n@@ -465,6 +465,7 @@ class UploadsController(Controller):\n \n         req.headers.pop(\u0027Etag\u0027, None)\n         req.headers.pop(\u0027Content-Md5\u0027, None)\n+        req.headers[\u0027X-Timestamp\u0027] \u003d Timestamp(time.time() + 10).normal\n \n         req.get_response(self.app, \u0027PUT\u0027, seg_container, obj, body\u003d\u0027\u0027)\n \n```\n\nI get logs like:\n\n```\nApr 13 19:55:44 saio proxy-server: Unable to Complete Multipart Upload because marker is 9.436590194702148 newer (txn: txc45179f162084d2d829e6-0069dd4a40) (client_ip: 127.0.0.1)\nApr 13 19:55:44 saio proxy-server: 127.0.0.1 127.0.0.1 13/Apr/2026/19/55/44 POST /s3test/mpu1%3FuploadId%3DOTUwZTA1MTktYTIwYi00Nzc2LTllZGUtODdiYzRkMDAxMWM4 HTTP/1.0 503 - Boto3/1.42.79%20md/Botocore%231.42.79%20ua/2.1%20os/linux%235.15.0-116-generic%20md/arch%23x86_64%20lang/python%233.10.12%20md/pyimpl%23CPython%20m/Z%2Cb%2CE%2Cn%2CN%20cfg/retry-mode%23standard%20Botocore/1.42.79 - - 193 - txc45179f162084d2d829e6-0069dd4a40 - 0.0080 - s3:err:ServiceUnavailable.MarkerClockSkew 1776110144.869607925 1776110144.877598763 - test:tester\n```\n\n... which I think is an improvement over master WRT to MTTD","commit_id":"20c7a5feea5b070842a88420b84c1aad55c63202"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"54e38a4c55290f0ea0f9fdadd47d73df916ed878","unresolved":true,"context_lines":[{"line_number":665,"context_line":"            # clock. The manifest PUT may succeed but the subsequent marker"},{"line_number":666,"context_line":"            # DELETE will fail, so don\u0027t attempt either."},{"line_number":667,"context_line":"            self.logger.error(\u0027Unable to Complete Multipart Upload \u0027"},{"line_number":668,"context_line":"                              \u0027because marker is %s newer\u0027 % marker_delta)"},{"line_number":669,"context_line":"            raise ServiceUnavailable(reason\u003d\u0027MPUClockSkew\u0027)"},{"line_number":670,"context_line":""},{"line_number":671,"context_line":"        headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"16d2ce85_414bb144","line":668,"in_reply_to":"2175fbbf_2f4a4ba1","updated":"2026-04-13 21:28:11.000000000","message":"```\nApr 13 20:56:36 saio proxy-server: Unable to Complete Multipart Upload, marker is 9.46134s newer (txn: tx538da45be53d4339bc33e-0069dd5884) (client_ip: 127.0.0.1)\nApr 13 20:56:36 saio proxy-server: 127.0.0.1 127.0.0.1 13/Apr/2026/20/56/36 POST /s3test/mpu1%3FuploadId%3DNzA0NDYyYWMtZTNjNS00ZmFjLWEyNmEtMGYwYmRiYjI2OWJm HTTP/1.0 503 - Boto3/1.42.79%20md/Botocore%231.42.79%20ua/2.1%20os/linux%235.15.0-116-generic%20md/arch%23x86_64%20lang/python%233.10.12%20md/pyimpl%23CPython%20m/b%2Cn%2CE%2CZ%2CN%20cfg/retry-mode%23standard%20Botocore/1.42.79 - - 193 - tx538da45be53d4339bc33e-0069dd5884 - 0.0075 - s3:err:ServiceUnavailable.mpu_clock_skew 1776113796.884513617 1776113796.892042160 - test:tester\n```\n\nnow with units on the delta, more descriptive unittests, and more consistent reason snake_case!","commit_id":"20c7a5feea5b070842a88420b84c1aad55c63202"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6fb9f81c7d7900b5d2423f293c064a69875d11fd","unresolved":true,"context_lines":[{"line_number":665,"context_line":"            # clock. The manifest PUT may succeed but the subsequent marker"},{"line_number":666,"context_line":"            # DELETE will fail, so don\u0027t attempt either."},{"line_number":667,"context_line":"            self.logger.error(\u0027Unable to Complete Multipart Upload \u0027"},{"line_number":668,"context_line":"                              \u0027because marker is %s newer\u0027 % marker_delta)"},{"line_number":669,"context_line":"            raise ServiceUnavailable(reason\u003d\u0027MPUClockSkew\u0027)"},{"line_number":670,"context_line":""},{"line_number":671,"context_line":"        headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"d3b3c2d5_3bd45b24","line":668,"range":{"start_line":668,"start_character":49,"end_line":668,"end_character":51},"updated":"2026-04-13 20:22:38.000000000","message":"Better as `%ss`, or even `%.5fs` -- IDK what it means to be 1.0001153945922852 newer.","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"dbcc9806ea21da9d687f7598cbcd74af9b9435ff","unresolved":false,"context_lines":[{"line_number":665,"context_line":"            # clock. The manifest PUT may succeed but the subsequent marker"},{"line_number":666,"context_line":"            # DELETE will fail, so don\u0027t attempt either."},{"line_number":667,"context_line":"            self.logger.error(\u0027Unable to Complete Multipart Upload \u0027"},{"line_number":668,"context_line":"                              \u0027because marker is %s newer\u0027 % marker_delta)"},{"line_number":669,"context_line":"            raise ServiceUnavailable(reason\u003d\u0027MPUClockSkew\u0027)"},{"line_number":670,"context_line":""},{"line_number":671,"context_line":"        headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"8dad668c_81d895c9","line":668,"range":{"start_line":668,"start_character":49,"end_line":668,"end_character":51},"in_reply_to":"49c40dd1_21aa6058","updated":"2026-04-13 21:30:06.000000000","message":"Acknowledged","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f703ce2c2b7fa2b47d913fdb49168d765de264e1","unresolved":true,"context_lines":[{"line_number":665,"context_line":"            # clock. The manifest PUT may succeed but the subsequent marker"},{"line_number":666,"context_line":"            # DELETE will fail, so don\u0027t attempt either."},{"line_number":667,"context_line":"            self.logger.error(\u0027Unable to Complete Multipart Upload \u0027"},{"line_number":668,"context_line":"                              \u0027because marker is %s newer\u0027 % marker_delta)"},{"line_number":669,"context_line":"            raise ServiceUnavailable(reason\u003d\u0027MPUClockSkew\u0027)"},{"line_number":670,"context_line":""},{"line_number":671,"context_line":"        headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"49c40dd1_21aa6058","line":668,"range":{"start_line":668,"start_character":49,"end_line":668,"end_character":51},"in_reply_to":"d3b3c2d5_3bd45b24","updated":"2026-04-13 20:29:56.000000000","message":"oh right, units are always good","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6fb9f81c7d7900b5d2423f293c064a69875d11fd","unresolved":true,"context_lines":[{"line_number":666,"context_line":"            # DELETE will fail, so don\u0027t attempt either."},{"line_number":667,"context_line":"            self.logger.error(\u0027Unable to Complete Multipart Upload \u0027"},{"line_number":668,"context_line":"                              \u0027because marker is %s newer\u0027 % marker_delta)"},{"line_number":669,"context_line":"            raise ServiceUnavailable(reason\u003d\u0027MPUClockSkew\u0027)"},{"line_number":670,"context_line":""},{"line_number":671,"context_line":"        headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027,"},{"line_number":672,"context_line":"                   sysmeta_header(\u0027object\u0027, \u0027upload-id\u0027): upload_id}"}],"source_content_type":"text/x-python","patch_set":2,"id":"ee049252_f21ffd17","line":669,"updated":"2026-04-13 20:22:38.000000000","message":"Will our user\u0027s clients even surface this? Or are we mainly doing this to get it into `log_info`?","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"54e38a4c55290f0ea0f9fdadd47d73df916ed878","unresolved":true,"context_lines":[{"line_number":666,"context_line":"            # DELETE will fail, so don\u0027t attempt either."},{"line_number":667,"context_line":"            self.logger.error(\u0027Unable to Complete Multipart Upload \u0027"},{"line_number":668,"context_line":"                              \u0027because marker is %s newer\u0027 % marker_delta)"},{"line_number":669,"context_line":"            raise ServiceUnavailable(reason\u003d\u0027MPUClockSkew\u0027)"},{"line_number":670,"context_line":""},{"line_number":671,"context_line":"        headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027,"},{"line_number":672,"context_line":"                   sysmeta_header(\u0027object\u0027, \u0027upload-id\u0027): upload_id}"}],"source_content_type":"text/x-python","patch_set":2,"id":"a0fde5e4_ad235956","line":669,"in_reply_to":"82815c99_dd572b4c","updated":"2026-04-13 21:28:11.000000000","message":"So the closest example of a legacy statsd like I could find looked like:\n\n```\n403.AccessDenied.invalid_header_auth\n```\n\nso I\u0027m going to go with `snake_case` for the reason","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bc6ebd51fea0673b9e8a0bdedd158d6d141640b8","unresolved":true,"context_lines":[{"line_number":666,"context_line":"            # DELETE will fail, so don\u0027t attempt either."},{"line_number":667,"context_line":"            self.logger.error(\u0027Unable to Complete Multipart Upload \u0027"},{"line_number":668,"context_line":"                              \u0027because marker is %s newer\u0027 % marker_delta)"},{"line_number":669,"context_line":"            raise ServiceUnavailable(reason\u003d\u0027MPUClockSkew\u0027)"},{"line_number":670,"context_line":""},{"line_number":671,"context_line":"        headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027,"},{"line_number":672,"context_line":"                   sysmeta_header(\u0027object\u0027, \u0027upload-id\u0027): upload_id}"}],"source_content_type":"text/x-python","patch_set":2,"id":"0b56b954_49638c2c","line":669,"in_reply_to":"a0fde5e4_ad235956","updated":"2026-04-14 09:46:06.000000000","message":"+1 ``snake_case`` is the norm for ``reason``:\nhttps://review.opendev.org/c/openstack/swift/+/921451/4/test/unit/common/middleware/s3api/test_s3api.py","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f703ce2c2b7fa2b47d913fdb49168d765de264e1","unresolved":true,"context_lines":[{"line_number":666,"context_line":"            # DELETE will fail, so don\u0027t attempt either."},{"line_number":667,"context_line":"            self.logger.error(\u0027Unable to Complete Multipart Upload \u0027"},{"line_number":668,"context_line":"                              \u0027because marker is %s newer\u0027 % marker_delta)"},{"line_number":669,"context_line":"            raise ServiceUnavailable(reason\u003d\u0027MPUClockSkew\u0027)"},{"line_number":670,"context_line":""},{"line_number":671,"context_line":"        headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027,"},{"line_number":672,"context_line":"                   sysmeta_header(\u0027object\u0027, \u0027upload-id\u0027): upload_id}"}],"source_content_type":"text/x-python","patch_set":2,"id":"82815c99_dd572b4c","line":669,"in_reply_to":"ee049252_f21ffd17","updated":"2026-04-13 20:29:56.000000000","message":"\u003e Will our user\u0027s clients even surface this\n\nno, and we need to be careful there - we don\u0027t want to disrupt the 503 retry\n\n\u003e mainly doing this to get it into log_info\n\n100% this","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bc6ebd51fea0673b9e8a0bdedd158d6d141640b8","unresolved":true,"context_lines":[{"line_number":658,"context_line":"        resp, is_marker \u003d _get_upload_info(req, self.app, upload_id)"},{"line_number":659,"context_line":"        marker_delta \u003d ("},{"line_number":660,"context_line":"            float(Timestamp(resp.sw_headers.get(\u0027X-Backend-Timestamp\u0027, \u00270\u0027)))"},{"line_number":661,"context_line":"            - float(Timestamp.now()))"},{"line_number":662,"context_line":"        # import pdb; pdb.set_trace()"},{"line_number":663,"context_line":"        if is_marker and marker_delta \u003e\u003d 0:"},{"line_number":664,"context_line":"            # Somehow the marker was created in the future w.r.t. this thread\u0027s"}],"source_content_type":"text/x-python","patch_set":3,"id":"b3cd8e5c_cdc95f0c","line":661,"range":{"start_line":661,"start_character":20,"end_line":661,"end_character":35},"updated":"2026-04-14 09:46:06.000000000","message":"note to self: this is going to conflict with the NormalTimestamp patch https://review.opendev.org/c/openstack/swift/+/968740/49/swift/common/middleware/s3api/controllers/multi_upload.py","commit_id":"ee32640464f47d4fe7be60316dd539376a35a1c2"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"346de81214d85a4842e786887a9dd38a57b95049","unresolved":false,"context_lines":[{"line_number":659,"context_line":"        marker_delta \u003d ("},{"line_number":660,"context_line":"            float(Timestamp(resp.sw_headers.get(\u0027X-Backend-Timestamp\u0027, \u00270\u0027)))"},{"line_number":661,"context_line":"            - float(Timestamp.now()))"},{"line_number":662,"context_line":"        # import pdb; pdb.set_trace()"},{"line_number":663,"context_line":"        if is_marker and marker_delta \u003e\u003d 0:"},{"line_number":664,"context_line":"            # Somehow the marker was created in the future w.r.t. this thread\u0027s"},{"line_number":665,"context_line":"            # clock. The manifest PUT may succeed but the subsequent marker"}],"source_content_type":"text/x-python","patch_set":3,"id":"394f3931_3829b157","line":662,"updated":"2026-04-14 01:36:16.000000000","message":"Probably don\u0027t need this anymore :P","commit_id":"ee32640464f47d4fe7be60316dd539376a35a1c2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bc6ebd51fea0673b9e8a0bdedd158d6d141640b8","unresolved":true,"context_lines":[{"line_number":665,"context_line":"            # clock. The manifest PUT may succeed but the subsequent marker"},{"line_number":666,"context_line":"            # DELETE will fail, so don\u0027t attempt either."},{"line_number":667,"context_line":"            self.logger.error(\u0027Unable to Complete Multipart Upload,\u0027"},{"line_number":668,"context_line":"                              \u0027 marker is %0.5fs newer\u0027, marker_delta)"},{"line_number":669,"context_line":"            raise ServiceUnavailable(reason\u003d\u0027mpu_clock_skew\u0027)"},{"line_number":670,"context_line":""},{"line_number":671,"context_line":"        headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"42360929_0fa46d20","line":668,"updated":"2026-04-14 09:46:06.000000000","message":"ok, this is exceptional so log it","commit_id":"ee32640464f47d4fe7be60316dd539376a35a1c2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bc6ebd51fea0673b9e8a0bdedd158d6d141640b8","unresolved":true,"context_lines":[{"line_number":666,"context_line":"            # DELETE will fail, so don\u0027t attempt either."},{"line_number":667,"context_line":"            self.logger.error(\u0027Unable to Complete Multipart Upload,\u0027"},{"line_number":668,"context_line":"                              \u0027 marker is %0.5fs newer\u0027, marker_delta)"},{"line_number":669,"context_line":"            raise ServiceUnavailable(reason\u003d\u0027mpu_clock_skew\u0027)"},{"line_number":670,"context_line":""},{"line_number":671,"context_line":"        headers \u003d {\u0027Accept\u0027: \u0027application/json\u0027,"},{"line_number":672,"context_line":"                   sysmeta_header(\u0027object\u0027, \u0027upload-id\u0027): upload_id}"}],"source_content_type":"text/x-python","patch_set":3,"id":"5c3f2b69_408cf5bc","line":669,"updated":"2026-04-14 09:46:06.000000000","message":"ok, this is sufficient to get more detail in the proxy logging and a statsd metric","commit_id":"ee32640464f47d4fe7be60316dd539376a35a1c2"}],"test/unit/common/middleware/s3api/test_multi_upload.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f703ce2c2b7fa2b47d913fdb49168d765de264e1","unresolved":true,"context_lines":[{"line_number":2076,"context_line":""},{"line_number":2077,"context_line":"        # marker created in the future"},{"line_number":2078,"context_line":"        with patch(\u0027swift.common.middleware.s3api.controllers.multi_upload.\u0027"},{"line_number":2079,"context_line":"                   \u0027Timestamp.now\u0027, return_value\u003dnow_timestamp):"},{"line_number":2080,"context_line":"            status, headers, body \u003d self.call_s3api(req)"},{"line_number":2081,"context_line":"        self.assertEqual(status.split()[0], \u0027503\u0027)"},{"line_number":2082,"context_line":"        self.assertEqual(\u0027ServiceUnavailable\u0027, self._get_error_code(body))"}],"source_content_type":"text/x-python","patch_set":2,"id":"8ef64435_d4dc1e50","line":2079,"updated":"2026-04-13 20:29:56.000000000","message":"we have `now_timestamp`, the log assertion probably could be tighter at the cost of basically re-implementing the math in the test.","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"dbcc9806ea21da9d687f7598cbcd74af9b9435ff","unresolved":false,"context_lines":[{"line_number":2076,"context_line":""},{"line_number":2077,"context_line":"        # marker created in the future"},{"line_number":2078,"context_line":"        with patch(\u0027swift.common.middleware.s3api.controllers.multi_upload.\u0027"},{"line_number":2079,"context_line":"                   \u0027Timestamp.now\u0027, return_value\u003dnow_timestamp):"},{"line_number":2080,"context_line":"            status, headers, body \u003d self.call_s3api(req)"},{"line_number":2081,"context_line":"        self.assertEqual(status.split()[0], \u0027503\u0027)"},{"line_number":2082,"context_line":"        self.assertEqual(\u0027ServiceUnavailable\u0027, self._get_error_code(body))"}],"source_content_type":"text/x-python","patch_set":2,"id":"35bc9829_8ac90ddc","line":2079,"in_reply_to":"8ef64435_d4dc1e50","updated":"2026-04-13 21:30:06.000000000","message":"Acknowledged","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6fb9f81c7d7900b5d2423f293c064a69875d11fd","unresolved":true,"context_lines":[{"line_number":2085,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket\u0027),"},{"line_number":2086,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket+segments/object/X\u0027)])"},{"line_number":2087,"context_line":"        self.assertEqual([\u0027s3:err:ServiceUnavailable.MPUClockSkew\u0027],"},{"line_number":2088,"context_line":"                         req.environ[\u0027swift.log_info\u0027])"},{"line_number":2089,"context_line":"        self.assertIn(\u0027because marker is \u0027,"},{"line_number":2090,"context_line":"                      self.logger.get_lines_for_level(\u0027error\u0027)[-1])"},{"line_number":2091,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"612ae1b3_f813fe2a","line":2088,"updated":"2026-04-13 20:22:38.000000000","message":"Do we also want to assert on the stats getting changed? Ref: https://github.com/openstack/swift/commit/f9af0b70","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"dbcc9806ea21da9d687f7598cbcd74af9b9435ff","unresolved":false,"context_lines":[{"line_number":2085,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket\u0027),"},{"line_number":2086,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket+segments/object/X\u0027)])"},{"line_number":2087,"context_line":"        self.assertEqual([\u0027s3:err:ServiceUnavailable.MPUClockSkew\u0027],"},{"line_number":2088,"context_line":"                         req.environ[\u0027swift.log_info\u0027])"},{"line_number":2089,"context_line":"        self.assertIn(\u0027because marker is \u0027,"},{"line_number":2090,"context_line":"                      self.logger.get_lines_for_level(\u0027error\u0027)[-1])"},{"line_number":2091,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"bdcd9b6f_47884c98","line":2088,"in_reply_to":"20118720_11830b61","updated":"2026-04-13 21:30:06.000000000","message":"Acknowledged","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"54e38a4c55290f0ea0f9fdadd47d73df916ed878","unresolved":true,"context_lines":[{"line_number":2085,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket\u0027),"},{"line_number":2086,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket+segments/object/X\u0027)])"},{"line_number":2087,"context_line":"        self.assertEqual([\u0027s3:err:ServiceUnavailable.MPUClockSkew\u0027],"},{"line_number":2088,"context_line":"                         req.environ[\u0027swift.log_info\u0027])"},{"line_number":2089,"context_line":"        self.assertIn(\u0027because marker is \u0027,"},{"line_number":2090,"context_line":"                      self.logger.get_lines_for_level(\u0027error\u0027)[-1])"},{"line_number":2091,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"20118720_11830b61","line":2088,"in_reply_to":"23b9233e_0f2f9706","updated":"2026-04-13 21:28:11.000000000","message":"i\u0027m not 100% those stats ARE proxy-logging related, looking more closely at the linked test diff it seems like some examples statsd assertions are in `test/unit/common/middleware/s3api/test_s3api.py`","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f703ce2c2b7fa2b47d913fdb49168d765de264e1","unresolved":true,"context_lines":[{"line_number":2085,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket\u0027),"},{"line_number":2086,"context_line":"            (\u0027HEAD\u0027, \u0027/v1/AUTH_test/bucket+segments/object/X\u0027)])"},{"line_number":2087,"context_line":"        self.assertEqual([\u0027s3:err:ServiceUnavailable.MPUClockSkew\u0027],"},{"line_number":2088,"context_line":"                         req.environ[\u0027swift.log_info\u0027])"},{"line_number":2089,"context_line":"        self.assertIn(\u0027because marker is \u0027,"},{"line_number":2090,"context_line":"                      self.logger.get_lines_for_level(\u0027error\u0027)[-1])"},{"line_number":2091,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"23b9233e_0f2f9706","line":2088,"in_reply_to":"612ae1b3_f813fe2a","updated":"2026-04-13 20:29:56.000000000","message":"ah, I didn\u0027t realize there was an implicit relationship with log_info and statsd - so that\u0027d be more of a proxy-logging diff?\n\nFWIW it\u0027ll probably be a can of worms to try and assert the legacy metrics w/o also modernizing it with labels.  For now I believe the log telemetry would be sufficient to sanity check if this even comes up very often.","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6fb9f81c7d7900b5d2423f293c064a69875d11fd","unresolved":true,"context_lines":[{"line_number":2087,"context_line":"        self.assertEqual([\u0027s3:err:ServiceUnavailable.MPUClockSkew\u0027],"},{"line_number":2088,"context_line":"                         req.environ[\u0027swift.log_info\u0027])"},{"line_number":2089,"context_line":"        self.assertIn(\u0027because marker is \u0027,"},{"line_number":2090,"context_line":"                      self.logger.get_lines_for_level(\u0027error\u0027)[-1])"},{"line_number":2091,"context_line":""},{"line_number":2092,"context_line":"    def test_object_multipart_upload_complete_marker_ts_now(self):"},{"line_number":2093,"context_line":"        marker_timestamp \u003d now_timestamp \u003d Timestamp.now()"}],"source_content_type":"text/x-python","patch_set":2,"id":"25436cae_948af90f","line":2090,"updated":"2026-04-13 20:22:38.000000000","message":"Seems better to mock out `Timestamp.now()` so we can `assertEqual` -- it\u0027ll reveal the current excess of precision.","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f703ce2c2b7fa2b47d913fdb49168d765de264e1","unresolved":true,"context_lines":[{"line_number":2087,"context_line":"        self.assertEqual([\u0027s3:err:ServiceUnavailable.MPUClockSkew\u0027],"},{"line_number":2088,"context_line":"                         req.environ[\u0027swift.log_info\u0027])"},{"line_number":2089,"context_line":"        self.assertIn(\u0027because marker is \u0027,"},{"line_number":2090,"context_line":"                      self.logger.get_lines_for_level(\u0027error\u0027)[-1])"},{"line_number":2091,"context_line":""},{"line_number":2092,"context_line":"    def test_object_multipart_upload_complete_marker_ts_now(self):"},{"line_number":2093,"context_line":"        marker_timestamp \u003d now_timestamp \u003d Timestamp.now()"}],"source_content_type":"text/x-python","patch_set":2,"id":"6f22872b_1d617901","line":2090,"in_reply_to":"25436cae_948af90f","updated":"2026-04-13 20:29:56.000000000","message":"i\u0027m not sure the extent it would \"revel\" it because `_do_test_object_multipart_upload_complete_marker_in_future` takes `marker_timestamp, now_timestamp` as params - I could move the log assertion to the various tests 💡","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"dbcc9806ea21da9d687f7598cbcd74af9b9435ff","unresolved":false,"context_lines":[{"line_number":2087,"context_line":"        self.assertEqual([\u0027s3:err:ServiceUnavailable.MPUClockSkew\u0027],"},{"line_number":2088,"context_line":"                         req.environ[\u0027swift.log_info\u0027])"},{"line_number":2089,"context_line":"        self.assertIn(\u0027because marker is \u0027,"},{"line_number":2090,"context_line":"                      self.logger.get_lines_for_level(\u0027error\u0027)[-1])"},{"line_number":2091,"context_line":""},{"line_number":2092,"context_line":"    def test_object_multipart_upload_complete_marker_ts_now(self):"},{"line_number":2093,"context_line":"        marker_timestamp \u003d now_timestamp \u003d Timestamp.now()"}],"source_content_type":"text/x-python","patch_set":2,"id":"bcd301b8_d4a24b30","line":2090,"in_reply_to":"6f22872b_1d617901","updated":"2026-04-13 21:30:06.000000000","message":"Acknowledged","commit_id":"b1f1f238e9890a38edd3f8c9c581765975a4c496"}]}
