)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":true,"context_lines":[{"line_number":15,"context_line":"is to use the timestamp iterator helper available via"},{"line_number":16,"context_line":"BaseUnitTestCase.ts_iter and BaseUnitTestCase.ts(). This patch adopts"},{"line_number":17,"context_line":"this pattern, but there is still further work required to make all"},{"line_number":18,"context_line":"tests use the pattern consistently."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Change-Id: I2b6cee7e7a189294d4e28b7cb2aadadd10a11c2d"},{"line_number":21,"context_line":"Signed-off-by: Alistair Coles \u003calistairncoles@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":7,"id":"457229b5_bc115335","line":18,"updated":"2026-02-18 23:39:52.000000000","message":"\u003e retires the use of normalize_timestamp in tests\n\u003e further work required\n\nit seems like this change removes ALL usage of `normalize_timestamp` in tests? [1] Is this \"further work\" comment just referring to ad-hoc usage of `make_timestamp_iter` vs `BaseUnitTestCase`?\n\n1. outside of *explicit* testing in `test.unit.common.utils.test_timestamp` - which is reasonable given the function is still used by `obj.server`","commit_id":"810478eed645cc896511fd20245a9fe43bc0a276"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"421e544956df605e64342cb2e23ce219e5e28d93","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"2db9f7f3_9915d382","updated":"2026-02-11 18:05:15.000000000","message":"recheck\n\nPretty sure those errors are transient. At the very least, they\u0027re not to do with us.","commit_id":"9caa17685df58d29e13f3a0d89f7a3a7ad0f9044"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4139b406e2dff6e0e60dc09343c65c0507198800","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"c8946267_28758c88","updated":"2026-02-16 04:16:26.000000000","message":"I problably only have NITs so happy to change my vote if no one agrees 😊","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"824cf44d_62c98008","updated":"2026-02-18 23:39:52.000000000","message":"all the `test.unit.obj` usage of `self.ts().internal` as opposed to `normlize_timestamp` is a massive and obvious win.\n\nthe usage of `self.ts().internal` in account/container/common.db initialize is reasonably \"concerning\" since AFAIK we are NOT planning on *actually* making the proxy send extended transaction timestamps for account/container PUT/DELETE *yet* - BUT I\u0027m comfortable with it b/c I believe that the code does and should handle that case properly AND want to eventually make sure that we CAN add transaction jitter to those proxy requests... eventually (so validating support in the backend is a necessary and useful first step)\n\ncommit message is good - I think it\u0027s trying to warn that we don\u0027t use `BaseTestCase` *everywhere* yet and some places probably still use `make_timestamp_iter` directly BUT nevertheless it\u0027s a REALLY GOOD AND USEFUL cleanup to get rid of `normalize_timestamp` when we already know that the object-server SHOULD be handling internal Timestamp offset/hexpart correctly and consistently in all code paths (so using normal timestamps was just a cheat anyway)\n\nfor the few places that this change removed `normalize_timestamp` and replaced it with `Timestamp(\u003csome_value\u003e)` instead of `self.ts()` (for ease of direct non-invasive translation) I think 1) that\u0027s perfectly fine 2) actually still better - even granting that eventually in some of these places we might want to audit the creation of explicit `Timestamp` instances in backend unittests to question if they would be \"more accurate\" using a new `extended\u003dTrue` kwarg.  i.e. the *difference* between `Timestamp(\u003csome_value\u003e)` and `self.ts()` is IMHO *mainly* that `self.ts()` will get extended\u003dTrue transaction timestamps *automatically* is a subsequent change, where as explicit `Timestamp` creation will need to add it on purpose when necessary.  So it\u0027s basically the same problem we have now with the use of `normalize_timestamp` in the object-server except with a much restricted fail closed scope.\n\nZuul is happy and this has been looked at multiple times by multiple core reviewers - I think that\u0027s a plenty high bar for a test only change that\u0027s blocking a critical bug fix.  Everything here seems in order to me, so if I missed something it was probably subtle and we can always fix it later.","commit_id":"810478eed645cc896511fd20245a9fe43bc0a276"}],"test/functional/__init__.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4139b406e2dff6e0e60dc09343c65c0507198800","unresolved":true,"context_lines":[{"line_number":695,"context_line":""},{"line_number":696,"context_line":"    # Create accounts \"test\" and \"test2\""},{"line_number":697,"context_line":"    def create_account(act):"},{"line_number":698,"context_line":"        ts \u003d utils.Timestamp.now().internal"},{"line_number":699,"context_line":"        account_ring \u003d Ring(_testdir, ring_name\u003d\u0027account\u0027)"},{"line_number":700,"context_line":"        partition, nodes \u003d account_ring.get_nodes(act)"},{"line_number":701,"context_line":"        for node in nodes:"}],"source_content_type":"text/x-python","patch_set":4,"id":"47de0f22_232f84ea","line":698,"updated":"2026-02-16 04:16:26.000000000","message":"Should probably be:\n```\nutils.timestamp.Timestamp...\n```\n\nSo people can get used to using the real util location of the Timestamp class.","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":false,"context_lines":[{"line_number":695,"context_line":""},{"line_number":696,"context_line":"    # Create accounts \"test\" and \"test2\""},{"line_number":697,"context_line":"    def create_account(act):"},{"line_number":698,"context_line":"        ts \u003d utils.Timestamp.now().internal"},{"line_number":699,"context_line":"        account_ring \u003d Ring(_testdir, ring_name\u003d\u0027account\u0027)"},{"line_number":700,"context_line":"        partition, nodes \u003d account_ring.get_nodes(act)"},{"line_number":701,"context_line":"        for node in nodes:"}],"source_content_type":"text/x-python","patch_set":4,"id":"b951fbb9_93c82538","line":698,"in_reply_to":"47de0f22_232f84ea","updated":"2026-02-18 14:16:19.000000000","message":"Done","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[{"line_number":51,"context_line":"# test.functional namespace."},{"line_number":52,"context_line":"from test.unit import skip_if_no_xattrs as real_skip_if_no_xattrs"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"from swift.common import constraints, utils, ring, storage_policy"},{"line_number":55,"context_line":"from swift.common.ring import Ring"},{"line_number":56,"context_line":"from swift.common.http_protocol import SwiftHttpProtocol"},{"line_number":57,"context_line":"from swift.common.wsgi import loadapp"}],"source_content_type":"text/x-python","patch_set":7,"id":"8b288a0c_b259c017","line":54,"updated":"2026-02-18 23:39:52.000000000","message":"the imports from `swift.common` are *not* organized very well IMHO","commit_id":"810478eed645cc896511fd20245a9fe43bc0a276"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[{"line_number":55,"context_line":"from swift.common.ring import Ring"},{"line_number":56,"context_line":"from swift.common.http_protocol import SwiftHttpProtocol"},{"line_number":57,"context_line":"from swift.common.wsgi import loadapp"},{"line_number":58,"context_line":"from swift.common.utils import config_true_value, split_path"},{"line_number":59,"context_line":"from swift.account import server as account_server"},{"line_number":60,"context_line":"from swift.container import server as container_server"},{"line_number":61,"context_line":"from swift.obj import server as object_server, mem_server as mem_object_server"}],"source_content_type":"text/x-python","patch_set":7,"id":"4c952a58_bc270f81","line":58,"updated":"2026-02-18 23:39:52.000000000","message":"See L43 😞","commit_id":"810478eed645cc896511fd20245a9fe43bc0a276"}],"test/unit/__init__.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":true,"context_lines":[{"line_number":73,"context_line":""},{"line_number":74,"context_line":"        :return: an instance of Timestamp"},{"line_number":75,"context_line":"        \"\"\""},{"line_number":76,"context_line":"        return next(self.ts_iter)"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"# try not to import this module from swift"}],"source_content_type":"text/x-python","patch_set":7,"id":"b9497743_eb73198f","line":76,"updated":"2026-02-18 23:39:52.000000000","message":"FWIW looking around the corner I\u0027ve seen that `make_timestamp_iter` will eventually produce extended\u003dTrue transaction timestamps\n\nSo in the cases where we\u0027ve `s/normalize_timestamp(1)/self.ts()/` we should be expecting those tests to pickup jitter in a subsequent patch even if we\u0027re not sending jitter from the real proxy.","commit_id":"810478eed645cc896511fd20245a9fe43bc0a276"}],"test/unit/account/test_reaper.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4139b406e2dff6e0e60dc09343c65c0507198800","unresolved":true,"context_lines":[{"line_number":26,"context_line":"from swift.account import reaper"},{"line_number":27,"context_line":"from swift.account.backend import DATADIR"},{"line_number":28,"context_line":"from swift.common.exceptions import ClientException"},{"line_number":29,"context_line":"from swift.common.utils import Timestamp"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"from test import unit"},{"line_number":32,"context_line":"from test.debug_logger import debug_logger"}],"source_content_type":"text/x-python","patch_set":4,"id":"315dddf4_d2f3e8e7","line":29,"updated":"2026-02-16 04:16:26.000000000","message":"Here too, or am I being to pedantic?","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":false,"context_lines":[{"line_number":26,"context_line":"from swift.account import reaper"},{"line_number":27,"context_line":"from swift.account.backend import DATADIR"},{"line_number":28,"context_line":"from swift.common.exceptions import ClientException"},{"line_number":29,"context_line":"from swift.common.utils import Timestamp"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"from test import unit"},{"line_number":32,"context_line":"from test.debug_logger import debug_logger"}],"source_content_type":"text/x-python","patch_set":4,"id":"1fc5bfd1_dfb03c45","line":29,"in_reply_to":"315dddf4_d2f3e8e7","updated":"2026-02-18 14:16:19.000000000","message":"Done","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":true,"context_lines":[{"line_number":267,"context_line":"            # account\u0027s name to do the reaping."},{"line_number":268,"context_line":"            b.info[\u0027delete_timestamp\u0027] \u003d Timestamp(89).internal"},{"line_number":269,"context_line":"            self.assertRaises(KeyError, r.reap_account, b, 0, None)"},{"line_number":270,"context_line":"            b.info[\u0027delete_timestamp\u0027] \u003d Timestamp(1).internal"},{"line_number":271,"context_line":"            self.assertRaises(KeyError, r.reap_account, b, 0, None)"},{"line_number":272,"context_line":"        finally:"},{"line_number":273,"context_line":"            reaper.time \u003d time_orig"}],"source_content_type":"text/x-python","patch_set":7,"id":"0a7e4c78_16eae348","line":270,"updated":"2026-02-18 23:39:52.000000000","message":"oic, sometimes the main difference is `Ts(\u003cint\u003e).normal` vs `Ts(\u003cint\u003e).internal`\n\npresumably even after we add transaction timestamps with the extended hex part creating a `Timestamp` instance directly will NOT include jitter.","commit_id":"810478eed645cc896511fd20245a9fe43bc0a276"}],"test/unit/account/test_replicator.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":true,"context_lines":[{"line_number":33,"context_line":"    def test_sync(self):"},{"line_number":34,"context_line":"        broker \u003d self._get_broker(\u0027a\u0027, node_index\u003d0)"},{"line_number":35,"context_line":"        put_timestamp \u003d self.ts().internal"},{"line_number":36,"context_line":"        broker.initialize(put_timestamp)"},{"line_number":37,"context_line":"        # \"replicate\" to same database"},{"line_number":38,"context_line":"        daemon \u003d replicator.AccountReplicator({})"},{"line_number":39,"context_line":"        part, node \u003d self._get_broker_part_node(broker)"}],"source_content_type":"text/x-python","patch_set":7,"id":"ce49c90d_e94731c2","line":36,"updated":"2026-02-18 23:39:52.000000000","message":"N.B. we\u0027re presumably already committed to the db broker API being willing to accept timestamp strings with hexpart - and the API seems to allow it e.g.\n\n```\n        if not put_timestamp:\n            put_timestamp \u003d Timestamp.zero().internal\n```\n^ from common.db\n\n```\n        if put_timestamp is None:\n            put_timestamp \u003d Timestamp.zero().internal\n```\n^ from container.backend\n\n```\n        conn.execute(\"\"\"\n            INSERT INTO container_info (account, container, created_at, id,\n                put_timestamp, status_changed_at, storage_policy_index)\n            VALUES (?, ?, ?, ?, ?, ?, ?);\n        \"\"\", (self.account, self.container, Timestamp.now().internal,\n              self._new_db_id(), put_timestamp, put_timestamp,\n              storage_policy_index))\n```\n\nit *should* already be the case that anywhere we evaluate \"the string stored in the put_timestamps column\" we\u0027re treating it as a `Timestamp(put_timestamp_str)` ... so it *should* be fine to add jitter to this test\n\n... in fact we\u0027d previously concluded that we\u0027ll *gain* confidence in our testing and the ability to add transaction-timestamps to database creation/update by starting with introducing extended transaction timestamps in unittests!\n\ni.e. if we have to update all the tests - update in the direction of where we want to GO instead of some interim transitional state that will require updating them all again to be consistent with a future reality.","commit_id":"810478eed645cc896511fd20245a9fe43bc0a276"}],"test/unit/account/test_server.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"83a941bf362fdeb64df72a00cadef4d47e99f91c","unresolved":true,"context_lines":[{"line_number":183,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":184,"context_line":"        self.assertEqual(resp.status_int, 204)"},{"line_number":185,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027DELETE\u0027,"},{"line_number":186,"context_line":"                                                  \u0027HTTP_X_TIMESTAMP\u0027: \u00271\u0027})"},{"line_number":187,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":188,"context_line":"        self.assertEqual(resp.status_int, 204)"},{"line_number":189,"context_line":"        self.assertEqual(resp.headers[\u0027X-Account-Status\u0027], \u0027Deleted\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"4fe19353_06de5d28","line":186,"updated":"2026-02-17 21:37:45.000000000","message":"If we\u0027re switching to `self.ts()` above, should we here, too?","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":false,"context_lines":[{"line_number":183,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":184,"context_line":"        self.assertEqual(resp.status_int, 204)"},{"line_number":185,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027DELETE\u0027,"},{"line_number":186,"context_line":"                                                  \u0027HTTP_X_TIMESTAMP\u0027: \u00271\u0027})"},{"line_number":187,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":188,"context_line":"        self.assertEqual(resp.status_int, 204)"},{"line_number":189,"context_line":"        self.assertEqual(resp.headers[\u0027X-Account-Status\u0027], \u0027Deleted\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"c8fff8bc_beae55fd","line":186,"in_reply_to":"4fe19353_06de5d28","updated":"2026-02-18 14:16:19.000000000","message":"Done","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"83a941bf362fdeb64df72a00cadef4d47e99f91c","unresolved":true,"context_lines":[{"line_number":438,"context_line":"                     \u0027X-DELETE-Timestamp\u0027: ts.internal,"},{"line_number":439,"context_line":"                     \u0027X-Object-Count\u0027: \u00271\u0027,"},{"line_number":440,"context_line":"                     \u0027X-Bytes-Used\u0027: \u00271\u0027,"},{"line_number":441,"context_line":"                     \u0027X-Timestamp\u0027: ts.internal})"},{"line_number":442,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":443,"context_line":"        self.assertEqual(resp.status_int, 404)"},{"line_number":444,"context_line":"        self.assertNotIn(\u0027X-Account-Status\u0027, resp.headers)"}],"source_content_type":"text/x-python","patch_set":6,"id":"4b2cdc41_5dd2bd02","line":441,"updated":"2026-02-17 21:37:45.000000000","message":"Huh. This *is* a  funny test, isn\u0027t it... I wonder if this sort of situation ever comes up in practice...","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":false,"context_lines":[{"line_number":438,"context_line":"                     \u0027X-DELETE-Timestamp\u0027: ts.internal,"},{"line_number":439,"context_line":"                     \u0027X-Object-Count\u0027: \u00271\u0027,"},{"line_number":440,"context_line":"                     \u0027X-Bytes-Used\u0027: \u00271\u0027,"},{"line_number":441,"context_line":"                     \u0027X-Timestamp\u0027: ts.internal})"},{"line_number":442,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":443,"context_line":"        self.assertEqual(resp.status_int, 404)"},{"line_number":444,"context_line":"        self.assertNotIn(\u0027X-Account-Status\u0027, resp.headers)"}],"source_content_type":"text/x-python","patch_set":6,"id":"a3061e8b_8d239c89","line":441,"in_reply_to":"4b2cdc41_5dd2bd02","updated":"2026-02-18 14:16:19.000000000","message":"Acknowledged","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"83a941bf362fdeb64df72a00cadef4d47e99f91c","unresolved":true,"context_lines":[{"line_number":523,"context_line":"    def test_PUT_after_DELETE(self):"},{"line_number":524,"context_line":"        ts_delete, ts_put \u003d self.ts(), self.ts()"},{"line_number":525,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":526,"context_line":"                            headers\u003d{\u0027X-Timestamp\u0027: ts_delete.internal})"},{"line_number":527,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":528,"context_line":"        self.assertEqual(resp.status_int, 201)"},{"line_number":529,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027DELETE\u0027},"}],"source_content_type":"text/x-python","patch_set":6,"id":"baadf468_3946fec1","line":526,"updated":"2026-02-17 21:37:45.000000000","message":"Wait, what? We `PUT` at `ts_delete`? And **then** we `DELETE` at *the exact same time*??\n\nI mean, I get that this was a pre-existing test, but it\u0027s still weird... I want to know what we actually *want* to be testing here, \u0027cause I\u0027m not sure the test as-written makes a ton of sense.","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[{"line_number":523,"context_line":"    def test_PUT_after_DELETE(self):"},{"line_number":524,"context_line":"        ts_delete, ts_put \u003d self.ts(), self.ts()"},{"line_number":525,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":526,"context_line":"                            headers\u003d{\u0027X-Timestamp\u0027: ts_delete.internal})"},{"line_number":527,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":528,"context_line":"        self.assertEqual(resp.status_int, 201)"},{"line_number":529,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027DELETE\u0027},"}],"source_content_type":"text/x-python","patch_set":6,"id":"fa8cf419_0d3210f0","line":526,"in_reply_to":"4136ef27_cd04f752","updated":"2026-02-18 23:39:52.000000000","message":"I might hypothesize from the name \"PUT_after_DELETE\" that the first PUT here (at `normalize_timestamp(1)`) was added as an after thought?\n\nOTOH, it\u0027s a very old test - and may have had some implicit understanding towards the precedence of the delete and put timestamps:\n\n```\n        return status \u003d\u003d \u0027DELETED\u0027 or zero_like(container_count) and (\n            Timestamp(delete_timestamp) \u003e Timestamp(put_timestamp))\n```\n\n... but I don\u0027t *see* any assert about the \"state\" of the database after delete_timestamp \u003d\u003d put_timestamp","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":true,"context_lines":[{"line_number":523,"context_line":"    def test_PUT_after_DELETE(self):"},{"line_number":524,"context_line":"        ts_delete, ts_put \u003d self.ts(), self.ts()"},{"line_number":525,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":526,"context_line":"                            headers\u003d{\u0027X-Timestamp\u0027: ts_delete.internal})"},{"line_number":527,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":528,"context_line":"        self.assertEqual(resp.status_int, 201)"},{"line_number":529,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027DELETE\u0027},"}],"source_content_type":"text/x-python","patch_set":6,"id":"4136ef27_cd04f752","line":526,"in_reply_to":"baadf468_3946fec1","updated":"2026-02-18 14:16:19.000000000","message":"ack, my re-naming was unfortunate, I\u0027ll make the vars more abstract, or get rid of them even.\n\nAFAICT the test is targeting for the second PUT the 403. It\u0027s possibly just a curiosity that the DELETE timestamp equals the PUT. I can fix it to appear more realistic?","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"83a941bf362fdeb64df72a00cadef4d47e99f91c","unresolved":true,"context_lines":[{"line_number":614,"context_line":"        # Send other"},{"line_number":615,"context_line":"        req \u003d Request.blank("},{"line_number":616,"context_line":"            \u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":617,"context_line":"            headers\u003d{\u0027X-Timestamp\u0027: self.ts().internal,"},{"line_number":618,"context_line":"                     \u0027X-Will-Not-Be-Saved\u0027: b\u0027\\xff\u0027})"},{"line_number":619,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":620,"context_line":"        self.assertEqual(resp.status_int, 202)"}],"source_content_type":"text/x-python","patch_set":6,"id":"149580ae_bc5d8bd6","line":617,"updated":"2026-02-17 21:37:45.000000000","message":"Minor change in behavior: previously we tested with a single timestamp, but now we keep it moving. Shouldn\u0027t really matter, though, as nothing gets written down until this last request.","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":true,"context_lines":[{"line_number":614,"context_line":"        # Send other"},{"line_number":615,"context_line":"        req \u003d Request.blank("},{"line_number":616,"context_line":"            \u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":617,"context_line":"            headers\u003d{\u0027X-Timestamp\u0027: self.ts().internal,"},{"line_number":618,"context_line":"                     \u0027X-Will-Not-Be-Saved\u0027: b\u0027\\xff\u0027})"},{"line_number":619,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":620,"context_line":"        self.assertEqual(resp.status_int, 202)"}],"source_content_type":"text/x-python","patch_set":6,"id":"e89ea229_db34d448","line":617,"in_reply_to":"149580ae_bc5d8bd6","updated":"2026-02-18 14:16:19.000000000","message":"I\u0027ll make it like the next test i.e. use a single\n\n``ts_str \u003d self.ts().internal``","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[{"line_number":614,"context_line":"        # Send other"},{"line_number":615,"context_line":"        req \u003d Request.blank("},{"line_number":616,"context_line":"            \u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":617,"context_line":"            headers\u003d{\u0027X-Timestamp\u0027: self.ts().internal,"},{"line_number":618,"context_line":"                     \u0027X-Will-Not-Be-Saved\u0027: b\u0027\\xff\u0027})"},{"line_number":619,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":620,"context_line":"        self.assertEqual(resp.status_int, 202)"}],"source_content_type":"text/x-python","patch_set":6,"id":"f8d958fe_c1f36ddc","line":617,"in_reply_to":"e89ea229_db34d448","updated":"2026-02-18 23:39:52.000000000","message":"Done","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"83a941bf362fdeb64df72a00cadef4d47e99f91c","unresolved":true,"context_lines":[{"line_number":1075,"context_line":"                                     \u0027X-Object-Count\u0027: \u00273\u0027,"},{"line_number":1076,"context_line":"                                     \u0027X-Bytes-Used\u0027: \u00274\u0027,"},{"line_number":1077,"context_line":"                                     \u0027X-Timestamp\u0027: self.ts().internal})"},{"line_number":1078,"context_line":"        req.get_response(self.controller)"},{"line_number":1079,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027GET\u0027})"},{"line_number":1080,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":1081,"context_line":"        self.assertEqual(resp.status_int, 200)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7cb7d311_1e66c62c","line":1078,"updated":"2026-02-17 21:37:45.000000000","message":"Interesting that we make **no** assertions on any of the PUT responses...","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"83a941bf362fdeb64df72a00cadef4d47e99f91c","unresolved":true,"context_lines":[{"line_number":1136,"context_line":"                                     \u0027X-Timestamp\u0027: timestamps[0].internal})"},{"line_number":1137,"context_line":"        req.get_response(self.controller)"},{"line_number":1138,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a/c2\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":1139,"context_line":"                            headers\u003d{\u0027X-Put-Timestamp\u0027: timestamps[3].internal,"},{"line_number":1140,"context_line":"                                     \u0027X-Delete-Timestamp\u0027: \u00270\u0027,"},{"line_number":1141,"context_line":"                                     \u0027X-Object-Count\u0027: \u00273\u0027,"},{"line_number":1142,"context_line":"                                     \u0027X-Bytes-Used\u0027: \u00274\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"52db869c_18ae5072","line":1139,"updated":"2026-02-17 21:37:45.000000000","message":"Not `timestamps[4].internal`?","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":true,"context_lines":[{"line_number":1136,"context_line":"                                     \u0027X-Timestamp\u0027: timestamps[0].internal})"},{"line_number":1137,"context_line":"        req.get_response(self.controller)"},{"line_number":1138,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a/c2\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":1139,"context_line":"                            headers\u003d{\u0027X-Put-Timestamp\u0027: timestamps[3].internal,"},{"line_number":1140,"context_line":"                                     \u0027X-Delete-Timestamp\u0027: \u00270\u0027,"},{"line_number":1141,"context_line":"                                     \u0027X-Object-Count\u0027: \u00273\u0027,"},{"line_number":1142,"context_line":"                                     \u0027X-Bytes-Used\u0027: \u00274\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"b57c7bac_5b04cbd6","line":1139,"in_reply_to":"52db869c_18ae5072","updated":"2026-02-18 14:16:19.000000000","message":"good catch\n\nAlso, I made the diff on this test more than necessary, will revert some","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[{"line_number":1136,"context_line":"                                     \u0027X-Timestamp\u0027: timestamps[0].internal})"},{"line_number":1137,"context_line":"        req.get_response(self.controller)"},{"line_number":1138,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a/c2\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":1139,"context_line":"                            headers\u003d{\u0027X-Put-Timestamp\u0027: timestamps[3].internal,"},{"line_number":1140,"context_line":"                                     \u0027X-Delete-Timestamp\u0027: \u00270\u0027,"},{"line_number":1141,"context_line":"                                     \u0027X-Object-Count\u0027: \u00273\u0027,"},{"line_number":1142,"context_line":"                                     \u0027X-Bytes-Used\u0027: \u00274\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"ec8328c6_37f0753c","line":1139,"in_reply_to":"b57c7bac_5b04cbd6","updated":"2026-02-18 23:39:52.000000000","message":"Done","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[{"line_number":533,"context_line":"                            headers\u003d{\u0027X-Timestamp\u0027: normalize_timestamp(2)})"},{"line_number":534,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":535,"context_line":"        self.assertEqual(resp.status_int, 403)"},{"line_number":536,"context_line":"        self.assertEqual(resp.body, b\u0027Recently deleted\u0027)"},{"line_number":537,"context_line":"        self.assertEqual(resp.headers[\u0027X-Account-Status\u0027], \u0027Deleted\u0027)"},{"line_number":538,"context_line":""},{"line_number":539,"context_line":"    def test_create_reserved_namespace_account(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"c5f97b5a_13e7b198","side":"PARENT","line":536,"updated":"2026-02-18 23:39:52.000000000","message":"accounts really do have an interesting API","commit_id":"2c980ac94682e8baed89c7f3c3b5af824514e8c3"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[{"line_number":613,"context_line":"        # Send other"},{"line_number":614,"context_line":"        req \u003d Request.blank("},{"line_number":615,"context_line":"            \u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":616,"context_line":"            headers\u003d{\u0027X-Timestamp\u0027: normalize_timestamp(1),"},{"line_number":617,"context_line":"                     \u0027X-Will-Not-Be-Saved\u0027: b\u0027\\xff\u0027})"},{"line_number":618,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":619,"context_line":"        self.assertEqual(resp.status_int, 202)"}],"source_content_type":"text/x-python","patch_set":7,"id":"4fa663d1_2b586582","side":"PARENT","line":616,"updated":"2026-02-18 23:39:52.000000000","message":"honestly these tests re-using timestamps make them kind of sus\n\nbut b/c the first two return 400 it\u0027s *maybe* \"ok\" in that there\u0027s not really any state/data that\u0027s being confused.  Perhaps there is even a subtle validation that the 400s aren\u0027t storing anything b/c the same timestamp still works in the 202 case - but that\u0027s a pretty round about way to assert the behavior if that\u0027s what we\u0027re trying to do.\n\nI think the earlier version of this change that used repeated calls to self.ts() was probably an improvement - but also not obviously necessary or what this change was really \"about\" - so keeping behavior inline with original wonkyness seems justifiable.","commit_id":"2c980ac94682e8baed89c7f3c3b5af824514e8c3"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[{"line_number":534,"context_line":"        self.assertEqual(resp.status_int, 204)"},{"line_number":535,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":536,"context_line":"                            headers\u003d{\u0027X-Timestamp\u0027: self.ts().internal})"},{"line_number":537,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":538,"context_line":"        self.assertEqual(resp.status_int, 403)"},{"line_number":539,"context_line":"        self.assertEqual(resp.body, b\u0027Recently deleted\u0027)"},{"line_number":540,"context_line":"        self.assertEqual(resp.headers[\u0027X-Account-Status\u0027], \u0027Deleted\u0027)"}],"source_content_type":"text/x-python","patch_set":7,"id":"4049664d_e853255c","line":537,"updated":"2026-02-18 23:39:52.000000000","message":"I think using `self.ts()` consistently in order makes more sense than than naming/re-use of timestamps in nearly ALL tests.  It\u0027s a great pattern and I\u0027m quite happy to see it used more often.","commit_id":"810478eed645cc896511fd20245a9fe43bc0a276"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[{"line_number":717,"context_line":"        # Remove metadata header (by setting it to empty)"},{"line_number":718,"context_line":"        req \u003d Request.blank("},{"line_number":719,"context_line":"            \u0027/sda1/p/a\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027PUT\u0027},"},{"line_number":720,"context_line":"            headers\u003d{\u0027X-Timestamp\u0027: timestamps[3].internal,"},{"line_number":721,"context_line":"                     \u0027X-Account-Meta-Test\u0027: \u0027\u0027})"},{"line_number":722,"context_line":"        resp \u003d req.get_response(self.controller)"},{"line_number":723,"context_line":"        self.assertEqual(resp.status_int, 202)"}],"source_content_type":"text/x-python","patch_set":7,"id":"d24ec586_721ef811","line":720,"updated":"2026-02-18 23:39:52.000000000","message":"the `normal(x)` \u003d\u003e `ts[x-1]` 0-index is subtle - but looks correct to me.","commit_id":"810478eed645cc896511fd20245a9fe43bc0a276"}],"test/unit/common/test_db.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4139b406e2dff6e0e60dc09343c65c0507198800","unresolved":true,"context_lines":[{"line_number":751,"context_line":"                          broker.initialize, ts_str)"},{"line_number":752,"context_line":""},{"line_number":753,"context_line":"    def test_delete_db(self):"},{"line_number":754,"context_line":"        timestamps \u003d [next(self.ts) for _ in range(3)]"},{"line_number":755,"context_line":"        meta \u003d {\u0027foo\u0027: [\u0027bar\u0027, timestamps[0].internal]}"},{"line_number":756,"context_line":""},{"line_number":757,"context_line":"        def init_stub(conn, put_timestamp, **kwargs):"}],"source_content_type":"text/x-python","patch_set":4,"id":"80c6b006_291120e0","line":754,"range":{"start_line":754,"start_character":27,"end_line":754,"end_character":34},"updated":"2026-02-16 04:16:26.000000000","message":"self.ts or self.ts_iter?\nself.ts is next(self.ts_iter) and doesn\u0027t this make more sense to either we:\n\n```\n [self.ts for _ in range(3)]\n```\nor\n```\n [next(self.ts_iter) for _ in range(3)]\n```\n\n\nOH!! BaseUnitTestCase makes self.ts a class level function that calls self.ts_iter, where in test_db self.ts is an iter.. so they behave differently.. that\u0027s annoyingly confusing. Maybe we should be using BaseUnitTestCase for _ALL_ classes going forward.. but not a blocker for this patch... So you\u0027ll have to stick with `next(self.ts)`.\n\nMaybe I\u0027ll just write a quick follow up to fix the test file. (https://review.opendev.org/c/openstack/swift/+/976890)","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":false,"context_lines":[{"line_number":751,"context_line":"                          broker.initialize, ts_str)"},{"line_number":752,"context_line":""},{"line_number":753,"context_line":"    def test_delete_db(self):"},{"line_number":754,"context_line":"        timestamps \u003d [next(self.ts) for _ in range(3)]"},{"line_number":755,"context_line":"        meta \u003d {\u0027foo\u0027: [\u0027bar\u0027, timestamps[0].internal]}"},{"line_number":756,"context_line":""},{"line_number":757,"context_line":"        def init_stub(conn, put_timestamp, **kwargs):"}],"source_content_type":"text/x-python","patch_set":4,"id":"ba2a83fa_33e9240e","line":754,"range":{"start_line":754,"start_character":27,"end_line":754,"end_character":34},"in_reply_to":"80c6b006_291120e0","updated":"2026-02-18 14:16:19.000000000","message":"done in follow on patch","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"83a941bf362fdeb64df72a00cadef4d47e99f91c","unresolved":true,"context_lines":[{"line_number":1456,"context_line":"                      - MAX_META_VALUE_LENGTH):"},{"line_number":1457,"context_line":"            size +\u003d 4 + MAX_META_VALUE_LENGTH"},{"line_number":1458,"context_line":"            metadata[\u0027X-Account-Meta-%04d\u0027 % x] \u003d (metadata_value,"},{"line_number":1459,"context_line":"                                                   next(self.ts).internal)"},{"line_number":1460,"context_line":"            x +\u003d 1"},{"line_number":1461,"context_line":"        if MAX_META_OVERALL_SIZE - size \u003e 1:"},{"line_number":1462,"context_line":"            metadata[\u0027X-Account-Meta-k\u0027] \u003d ("}],"source_content_type":"text/x-python","patch_set":6,"id":"ad298d54_8f455c12","line":1459,"updated":"2026-02-17 21:37:45.000000000","message":"Did we mean to smear all this meta out across time? Eh, I suppose it probably doesn\u0027t matter.","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[{"line_number":1456,"context_line":"                      - MAX_META_VALUE_LENGTH):"},{"line_number":1457,"context_line":"            size +\u003d 4 + MAX_META_VALUE_LENGTH"},{"line_number":1458,"context_line":"            metadata[\u0027X-Account-Meta-%04d\u0027 % x] \u003d (metadata_value,"},{"line_number":1459,"context_line":"                                                   next(self.ts).internal)"},{"line_number":1460,"context_line":"            x +\u003d 1"},{"line_number":1461,"context_line":"        if MAX_META_OVERALL_SIZE - size \u003e 1:"},{"line_number":1462,"context_line":"            metadata[\u0027X-Account-Meta-k\u0027] \u003d ("}],"source_content_type":"text/x-python","patch_set":6,"id":"1bea9716_1e0dd079","line":1459,"in_reply_to":"58b77a23_c5ec7934","updated":"2026-02-18 23:39:52.000000000","message":"\u003e Eh, I suppose it probably doesn\u0027t matter\n\nI think in a lot of cases where it doesn\u0027t matter the more realistic approach is an improvement.  One of the advantages of ts_iter is that it makes a reasonable approximation of time moving forward easy.\n\nI\u0027ve been burned at least a couple times in swift unitests where the assertion on a sequence of events made *no sense* and the cause seemed to be the author accidentally re-using a timestamp such that some mutation wasn\u0027t applied correctly/consistently.\n\nIn the rare cases where we\u0027re actually testing \"out of order\" updates on purpose I think ts_iter again helps with:\n\n```\nt0_put \u003d self.ts()\nt1_put \u003d self.ts()\n# use t1 *first*\nPUT w/ t1\n# use t0 *after*\nPUT w/ t0 # ignored!!\n```\n\nHoever in this case it\u0027s not obvious the test wasn\u0027t actually trying to simulate a single large POST with a bunch of metadata vs a series of POSTs with increasingly large metadata.","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":true,"context_lines":[{"line_number":1456,"context_line":"                      - MAX_META_VALUE_LENGTH):"},{"line_number":1457,"context_line":"            size +\u003d 4 + MAX_META_VALUE_LENGTH"},{"line_number":1458,"context_line":"            metadata[\u0027X-Account-Meta-%04d\u0027 % x] \u003d (metadata_value,"},{"line_number":1459,"context_line":"                                                   next(self.ts).internal)"},{"line_number":1460,"context_line":"            x +\u003d 1"},{"line_number":1461,"context_line":"        if MAX_META_OVERALL_SIZE - size \u003e 1:"},{"line_number":1462,"context_line":"            metadata[\u0027X-Account-Meta-k\u0027] \u003d ("}],"source_content_type":"text/x-python","patch_set":6,"id":"58b77a23_c5ec7934","line":1459,"in_reply_to":"ad298d54_8f455c12","updated":"2026-02-18 14:16:19.000000000","message":"good catch\n\nAlso in a few other places, will fix","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"83a941bf362fdeb64df72a00cadef4d47e99f91c","unresolved":true,"context_lines":[{"line_number":1473,"context_line":"                      - MAX_META_VALUE_LENGTH):"},{"line_number":1474,"context_line":"            size +\u003d 4 + MAX_META_VALUE_LENGTH"},{"line_number":1475,"context_line":"            metadata[\u0027X-Account-Meta-%04d\u0027 % x] \u003d (metadata_value,"},{"line_number":1476,"context_line":"                                                   next(self.ts).internal)"},{"line_number":1477,"context_line":"            x +\u003d 1"},{"line_number":1478,"context_line":"        if MAX_META_OVERALL_SIZE - size \u003e 1:"},{"line_number":1479,"context_line":"            metadata[\u0027X-Account-Meta-k\u0027] \u003d ("}],"source_content_type":"text/x-python","patch_set":6,"id":"38b82723_c676ee11","line":1476,"updated":"2026-02-17 21:37:45.000000000","message":"Here, too.","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":false,"context_lines":[{"line_number":1473,"context_line":"                      - MAX_META_VALUE_LENGTH):"},{"line_number":1474,"context_line":"            size +\u003d 4 + MAX_META_VALUE_LENGTH"},{"line_number":1475,"context_line":"            metadata[\u0027X-Account-Meta-%04d\u0027 % x] \u003d (metadata_value,"},{"line_number":1476,"context_line":"                                                   next(self.ts).internal)"},{"line_number":1477,"context_line":"            x +\u003d 1"},{"line_number":1478,"context_line":"        if MAX_META_OVERALL_SIZE - size \u003e 1:"},{"line_number":1479,"context_line":"            metadata[\u0027X-Account-Meta-k\u0027] \u003d ("}],"source_content_type":"text/x-python","patch_set":6,"id":"3f540e97_aa030a32","line":1476,"in_reply_to":"2befde68_12bedc5a","updated":"2026-02-18 23:39:52.000000000","message":"Done","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":true,"context_lines":[{"line_number":1473,"context_line":"                      - MAX_META_VALUE_LENGTH):"},{"line_number":1474,"context_line":"            size +\u003d 4 + MAX_META_VALUE_LENGTH"},{"line_number":1475,"context_line":"            metadata[\u0027X-Account-Meta-%04d\u0027 % x] \u003d (metadata_value,"},{"line_number":1476,"context_line":"                                                   next(self.ts).internal)"},{"line_number":1477,"context_line":"            x +\u003d 1"},{"line_number":1478,"context_line":"        if MAX_META_OVERALL_SIZE - size \u003e 1:"},{"line_number":1479,"context_line":"            metadata[\u0027X-Account-Meta-k\u0027] \u003d ("}],"source_content_type":"text/x-python","patch_set":6,"id":"2befde68_12bedc5a","line":1476,"in_reply_to":"38b82723_c676ee11","updated":"2026-02-18 14:16:19.000000000","message":"Done","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"}],"test/unit/common/test_db_replicator.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":true,"context_lines":[{"line_number":2493,"context_line":"        # create a super old broker and delete it!"},{"line_number":2494,"context_line":"        forever_ago \u003d time.time() - daemon.reclaim_age"},{"line_number":2495,"context_line":"        put_timestamp \u003d Timestamp(forever_ago - 2).internal"},{"line_number":2496,"context_line":"        delete_timestamp \u003d Timestamp(forever_ago - 1).internal"},{"line_number":2497,"context_line":"        broker.initialize(put_timestamp)"},{"line_number":2498,"context_line":"        broker.delete_db(delete_timestamp)"},{"line_number":2499,"context_line":"        # if we have a container broker make sure it\u0027s reported"}],"source_content_type":"text/x-python","patch_set":7,"id":"b0318e4b_6ef39fca","line":2496,"updated":"2026-02-18 23:39:52.000000000","message":"the eventual difference between explicitly creating a `Timestamp(time())` w/o `extended\u003dTrue` and the expected change in behavior when `self.ts()` grows an implicit `extended\u003dTrue` by default ...\n\n... doesn\u0027t really make our situation any worse.\n\nIf we ever do need to audit the db_replicator tests b/c we\u0027ve started sending extended transaction timestamps to account/container db create/delete requests - we can *just* grep for `Timestamp` and add `extended\u003dTrue` all the places we\u0027ve already ported to `self.ts` will just be that much ahead of the curve.","commit_id":"810478eed645cc896511fd20245a9fe43bc0a276"}],"test/unit/common/utils/test_timestamp.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"83a941bf362fdeb64df72a00cadef4d47e99f91c","unresolved":true,"context_lines":[{"line_number":94,"context_line":"            # timestamp instance can also compare to string or float"},{"line_number":95,"context_line":"            self.assertEqual(ts, expected)"},{"line_number":96,"context_line":"            self.assertEqual(ts, float(expected))"},{"line_number":97,"context_line":"            self.assertEqual(ts, timestamp.normalize_timestamp(expected))"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"    def test_isoformat(self):"},{"line_number":100,"context_line":"        expected \u003d \u00272014-06-10T22:47:32.054580\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"dbcc94a8_df60cbd0","line":97,"updated":"2026-02-17 21:37:45.000000000","message":"OK, I guess this usage can probably stay...","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"83a941bf362fdeb64df72a00cadef4d47e99f91c","unresolved":true,"context_lines":[{"line_number":204,"context_line":"            self.assertEqual(timestamp.Timestamp(1402437380.581859).internal,"},{"line_number":205,"context_line":"                             \u00271402437380.58186\u0027)"},{"line_number":206,"context_line":"            self.assertEqual(timestamp.Timestamp(0).internal,"},{"line_number":207,"context_line":"                             timestamp.normalize_timestamp(0))"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    def test_no_force_internal_with_offset(self):"},{"line_number":210,"context_line":"        \"\"\"Test that internal always includes the offset if significant\"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"fb208709_2c3c133b","line":207,"updated":"2026-02-17 21:37:45.000000000","message":"I wonder if we should drop this. Or maybe add a\n```\n        self.assertEqual(timestamp.normalize_timestamp(0),\n                         \"0000000000.00000\")\n```\nto `test_normalize_timestamp` *then* drop it...","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":false,"context_lines":[{"line_number":204,"context_line":"            self.assertEqual(timestamp.Timestamp(1402437380.581859).internal,"},{"line_number":205,"context_line":"                             \u00271402437380.58186\u0027)"},{"line_number":206,"context_line":"            self.assertEqual(timestamp.Timestamp(0).internal,"},{"line_number":207,"context_line":"                             timestamp.normalize_timestamp(0))"},{"line_number":208,"context_line":""},{"line_number":209,"context_line":"    def test_no_force_internal_with_offset(self):"},{"line_number":210,"context_line":"        \"\"\"Test that internal always includes the offset if significant\"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"510a822c_5a0aa756","line":207,"in_reply_to":"fb208709_2c3c133b","updated":"2026-02-18 14:16:19.000000000","message":"Done","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"83a941bf362fdeb64df72a00cadef4d47e99f91c","unresolved":true,"context_lines":[{"line_number":942,"context_line":"        self.assertEqual(timestamp.normalize_timestamp(1253327593),"},{"line_number":943,"context_line":"                         \"1253327593.00000\")"},{"line_number":944,"context_line":"        self.assertEqual(timestamp.normalize_timestamp("},{"line_number":945,"context_line":"            timestamp.Timestamp(1253327593, offset\u003d0xabcdef)),"},{"line_number":946,"context_line":"            \"1253327593.00000\")"},{"line_number":947,"context_line":"        self.assertRaises(ValueError, timestamp.normalize_timestamp, \u0027\u0027)"},{"line_number":948,"context_line":"        self.assertRaises(ValueError, timestamp.normalize_timestamp, \u0027abc\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"ae01a886_f8650fd2","line":945,"updated":"2026-02-17 21:37:45.000000000","message":"Do we ever actually pass a `Timestamp` to `normalize_timestamp`? I thought we only ever pass strings from headers... Should there be a `.internal` in here?","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":true,"context_lines":[{"line_number":942,"context_line":"        self.assertEqual(timestamp.normalize_timestamp(1253327593),"},{"line_number":943,"context_line":"                         \"1253327593.00000\")"},{"line_number":944,"context_line":"        self.assertEqual(timestamp.normalize_timestamp("},{"line_number":945,"context_line":"            timestamp.Timestamp(1253327593, offset\u003d0xabcdef)),"},{"line_number":946,"context_line":"            \"1253327593.00000\")"},{"line_number":947,"context_line":"        self.assertRaises(ValueError, timestamp.normalize_timestamp, \u0027\u0027)"},{"line_number":948,"context_line":"        self.assertRaises(ValueError, timestamp.normalize_timestamp, \u0027abc\u0027)"}],"source_content_type":"text/x-python","patch_set":6,"id":"ab11643b_4f30c0c7","line":945,"in_reply_to":"ae01a886_f8650fd2","updated":"2026-02-18 14:16:19.000000000","message":"\u003e Do we ever actually pass a Timestamp to normalize_timestamp?\n\nNo. In fact normalize_timestamp is only used by object server, and I propose to remove that: https://review.opendev.org/c/openstack/swift/+/976533\n\n\u003e Should there be a .internal in here?\n\nDone","commit_id":"361dd1f5f2a205b848974d71ba5b204ea77c28c4"}],"test/unit/obj/common.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4139b406e2dff6e0e60dc09343c65c0507198800","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        \"\"\""},{"line_number":77,"context_line":"        Timestamps - forever."},{"line_number":78,"context_line":"        \"\"\""},{"line_number":79,"context_line":"        return next(self._ts_iter)"},{"line_number":80,"context_line":""},{"line_number":81,"context_line":"    def _make_diskfile(self, device\u003d\u0027dev\u0027, partition\u003d\u00279\u0027,"},{"line_number":82,"context_line":"                       account\u003d\u0027a\u0027, container\u003d\u0027c\u0027, obj\u003d\u0027o\u0027, body\u003db\u0027test\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"c3e30188_6dcb8f18","side":"PARENT","line":79,"updated":"2026-02-16 04:16:26.000000000","message":"nice","commit_id":"1964da5195e0d4fe96e89e98d418d1ded010a9ad"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f75f31da4c23314e0ee55bba13c8191b3ce099b4","unresolved":true,"context_lines":[{"line_number":74,"context_line":""},{"line_number":75,"context_line":"    def ts(self):"},{"line_number":76,"context_line":"        \"\"\""},{"line_number":77,"context_line":"        Timestamps - forever."},{"line_number":78,"context_line":"        \"\"\""},{"line_number":79,"context_line":"        return next(self._ts_iter)"},{"line_number":80,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"68209057_2d34f16c","side":"PARENT","line":77,"updated":"2026-02-18 23:39:52.000000000","message":"hahah - i love me a silly doc string RIP","commit_id":"2c980ac94682e8baed89c7f3c3b5af824514e8c3"}],"test/unit/obj/test_server.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4139b406e2dff6e0e60dc09343c65c0507198800","unresolved":true,"context_lines":[{"line_number":8263,"context_line":"        req \u003d Request.blank("},{"line_number":8264,"context_line":"            \u0027/sda1/p/a/c/o\u0027,"},{"line_number":8265,"context_line":"            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027DELETE\u0027},"},{"line_number":8266,"context_line":"            headers\u003d{\u0027X-Timestamp\u0027: Timestamp(ts, delta\u003d-95 * 1e5).internal,"},{"line_number":8267,"context_line":"                     \u0027X-If-Delete-At\u0027: str(int(ts))})"},{"line_number":8268,"context_line":"        resp \u003d req.get_response(self.object_controller)"},{"line_number":8269,"context_line":"        self.assertEqual(resp.status_int, 412)"}],"source_content_type":"text/x-python","patch_set":4,"id":"0ce197c0_07fd8b98","line":8266,"range":{"start_line":8266,"start_character":57,"end_line":8266,"end_character":65},"updated":"2026-02-16 04:16:26.000000000","message":"There have been a bunch of these, I do wonder if it\u0027s getting to the point we might want to throw in a `secs_to_deca_micro(seconds)` helper or something?","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4139b406e2dff6e0e60dc09343c65c0507198800","unresolved":true,"context_lines":[{"line_number":8355,"context_line":"        )])"},{"line_number":8356,"context_line":""},{"line_number":8357,"context_line":"        timestamp3 \u003d self.ts()"},{"line_number":8358,"context_line":"        delete_at_timestamp2 \u003d str(int(self.ts()) + 2000)"},{"line_number":8359,"context_line":"        req \u003d Request.blank("},{"line_number":8360,"context_line":"            \u0027/sda1/p/a/c/o\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027},"},{"line_number":8361,"context_line":"            headers\u003d{\u0027X-Timestamp\u0027: timestamp3.internal,"}],"source_content_type":"text/x-python","patch_set":4,"id":"9729dc86_1509fe59","line":8358,"updated":"2026-02-16 04:16:26.000000000","message":"There are a bunch of these `delete_at_timestamp` from a Timstamp class now, do we need a converter.. although I guess int() is a good one, or maybe float 😊\n\nSo meh, this is probably fine.","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":false,"context_lines":[{"line_number":8859,"context_line":"        proxy_ts_put \u003d self.ts()"},{"line_number":8860,"context_line":"        proxy_ts_post \u003d self.ts()"},{"line_number":8861,"context_line":"        delete_at_time \u003d int(proxy_ts_put) + 50"},{"line_number":8862,"context_line":"        obj_server_put_time \u003d float(proxy_ts_put) + 1100"},{"line_number":8863,"context_line":"        obj_server_post_time \u003d float(proxy_ts_put) + 1101"},{"line_number":8864,"context_line":""},{"line_number":8865,"context_line":"        # test setup: make an object for us to POST to"}],"source_content_type":"text/x-python","patch_set":4,"id":"005bd5f8_54cb386b","line":8862,"range":{"start_line":8862,"start_character":52,"end_line":8862,"end_character":56},"updated":"2026-02-18 14:16:19.000000000","message":"should be 100 to preserve original deltas\n\nand 101 on next line","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4139b406e2dff6e0e60dc09343c65c0507198800","unresolved":true,"context_lines":[{"line_number":8860,"context_line":"        proxy_ts_post \u003d self.ts()"},{"line_number":8861,"context_line":"        delete_at_time \u003d int(proxy_ts_put) + 50"},{"line_number":8862,"context_line":"        obj_server_put_time \u003d float(proxy_ts_put) + 1100"},{"line_number":8863,"context_line":"        obj_server_post_time \u003d float(proxy_ts_put) + 1101"},{"line_number":8864,"context_line":""},{"line_number":8865,"context_line":"        # test setup: make an object for us to POST to"},{"line_number":8866,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":4,"id":"229fac03_ed52ec75","line":8863,"updated":"2026-02-16 04:16:26.000000000","message":"Haha, yeah just like this.. I guess we do have agood helper method ;)","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"30b37c02c53b976e7b610c6679314795b84ed8a1","unresolved":false,"context_lines":[{"line_number":8860,"context_line":"        proxy_ts_post \u003d self.ts()"},{"line_number":8861,"context_line":"        delete_at_time \u003d int(proxy_ts_put) + 50"},{"line_number":8862,"context_line":"        obj_server_put_time \u003d float(proxy_ts_put) + 1100"},{"line_number":8863,"context_line":"        obj_server_post_time \u003d float(proxy_ts_put) + 1101"},{"line_number":8864,"context_line":""},{"line_number":8865,"context_line":"        # test setup: make an object for us to POST to"},{"line_number":8866,"context_line":"        req \u003d Request.blank("}],"source_content_type":"text/x-python","patch_set":4,"id":"925775cc_7785c89e","line":8863,"in_reply_to":"229fac03_ed52ec75","updated":"2026-02-18 14:16:19.000000000","message":"Acknowledged","commit_id":"2fe96d6988f58f737565db44fe1ce6679a902567"}]}
