)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71784d9354753c2ee9079f57b6b14b94c4c2c6bd","unresolved":true,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Proxy: Use shard-format for auto cont GETs and updating"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"With the first version of the get_namespaces patch to the container"},{"line_number":10,"context_line":"server allowing us to return namespace objects for container listings."},{"line_number":11,"context_line":"We should start using this new API in the proxy."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"acd40895_5011c5c1","line":9,"range":{"start_line":9,"start_character":9,"end_line":9,"end_character":22},"updated":"2023-09-28 15:53:49.000000000","message":"\"the first version of the get_namespaces patch to the container\nserver\"\n\nthis should be replaced a Related-Change reference","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2a73982e2aeb37c4de3aaccd988a4a94da3d7fe3","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Proxy: Use shard-format for auto cont GETs and updating"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"With the first version of the get_namespaces patch to the container"},{"line_number":10,"context_line":"server allowing us to return namespace objects for container listings."},{"line_number":11,"context_line":"We should start using this new API in the proxy."},{"line_number":12,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":9,"id":"c83df969_53f6db37","line":9,"range":{"start_line":9,"start_character":9,"end_line":9,"end_character":22},"in_reply_to":"acd40895_5011c5c1","updated":"2023-09-30 00:09:19.000000000","message":"Done","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     Jianjian Huo \u003cjhuo@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2023-10-31 11:56:40 -0700"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Proxy: Use shard-format for auto cont GETs and updating"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"With the Related-Change container servers can return a list Namespace"},{"line_number":10,"context_line":"objects in response to a GET request.  This patch modifies the proxy"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"0e14872e_fdaf55d3","line":7,"updated":"2023-11-01 00:22:45.000000000","message":"i read this as \"use format\u003dauto\", but really it\u0027s \"use format\u003dnamespace with type\u003dauto\"","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b6dbfa7f92aa86dc78a9c8d6bfc8076917c1e4f2","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Jianjian Huo \u003cjhuo@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2023-10-31 11:56:40 -0700"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Proxy: Use shard-format for auto cont GETs and updating"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"With the Related-Change container servers can return a list Namespace"},{"line_number":10,"context_line":"objects in response to a GET request.  This patch modifies the proxy"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"55999cea_ad516b61","line":7,"in_reply_to":"0e14872e_fdaf55d3","updated":"2024-01-11 10:45:45.000000000","message":"Done","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":15,"context_line":"In order to allow upgrades to clusters we can\u0027t just send"},{"line_number":16,"context_line":"\u0027X-Backend-Record-Type \u003d namespace\u0027, as old container servers won\u0027t"},{"line_number":17,"context_line":"know how to respond. Instead, proxies send a new header"},{"line_number":18,"context_line":"\u0027X-Backend-Record-Shard-Format \u003d namespace\u0027 along with the legacy"},{"line_number":19,"context_line":"\u0027X-Backend-Record-Type \u003d shard\u0027 header. Newer container servers will"},{"line_number":20,"context_line":"return namespaces while old container servers continue to return full"},{"line_number":21,"context_line":"shard ranges."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"4136d076_c5b690b4","line":18,"updated":"2023-11-01 00:22:45.000000000","message":"for me legacy has a connotation no longer the ideal or \"going away\" - but i think in this context it\u0027s just \"pre-existing\"; there\u0027s no intention of x-backend-record-shard-format \u003d namespace every being sent on it\u0027s own; it\u0027s just addative to the shard-type header.","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"12532e912d8cf1124c3469a52d36779d7413e475","unresolved":true,"context_lines":[{"line_number":15,"context_line":"In order to allow upgrades to clusters we can\u0027t just send"},{"line_number":16,"context_line":"\u0027X-Backend-Record-Type \u003d namespace\u0027, as old container servers won\u0027t"},{"line_number":17,"context_line":"know how to respond. Instead, proxies send a new header"},{"line_number":18,"context_line":"\u0027X-Backend-Record-Shard-Format \u003d namespace\u0027 along with the legacy"},{"line_number":19,"context_line":"\u0027X-Backend-Record-Type \u003d shard\u0027 header. Newer container servers will"},{"line_number":20,"context_line":"return namespaces while old container servers continue to return full"},{"line_number":21,"context_line":"shard ranges."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"c9d5cc32_82ce33bc","line":18,"in_reply_to":"4136d076_c5b690b4","updated":"2024-01-05 15:11:37.000000000","message":"agree\n\ns/legacy/existing/","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c521326e89be76bcba2dee0b72959fc102693801","unresolved":false,"context_lines":[{"line_number":15,"context_line":"In order to allow upgrades to clusters we can\u0027t just send"},{"line_number":16,"context_line":"\u0027X-Backend-Record-Type \u003d namespace\u0027, as old container servers won\u0027t"},{"line_number":17,"context_line":"know how to respond. Instead, proxies send a new header"},{"line_number":18,"context_line":"\u0027X-Backend-Record-Shard-Format \u003d namespace\u0027 along with the legacy"},{"line_number":19,"context_line":"\u0027X-Backend-Record-Type \u003d shard\u0027 header. Newer container servers will"},{"line_number":20,"context_line":"return namespaces while old container servers continue to return full"},{"line_number":21,"context_line":"shard ranges."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"fe69a25e_883b86fb","line":18,"in_reply_to":"c9d5cc32_82ce33bc","updated":"2024-01-06 01:49:39.000000000","message":"Acknowledged","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":21,"context_line":"shard ranges."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"Also, Ensure name/account/container are always consistent and always encode"},{"line_number":24,"context_line":"utf8 (py2)."},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Co-Authored-By: Jianjian Huo \u003cjhuo@nvidia.com\u003e"},{"line_number":27,"context_line":"Co-Authored-By: Alistair Coles \u003calistairncoles@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"a38d8c2e_05836469","line":24,"updated":"2023-11-01 00:22:45.000000000","message":"i think this is distracting me a little bit; maybe you had intended for it to be obvious/trivial but I\u0027m not sure if this is fixing something or just refactoring.","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b6dbfa7f92aa86dc78a9c8d6bfc8076917c1e4f2","unresolved":false,"context_lines":[{"line_number":21,"context_line":"shard ranges."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"Also, Ensure name/account/container are always consistent and always encode"},{"line_number":24,"context_line":"utf8 (py2)."},{"line_number":25,"context_line":""},{"line_number":26,"context_line":"Co-Authored-By: Jianjian Huo \u003cjhuo@nvidia.com\u003e"},{"line_number":27,"context_line":"Co-Authored-By: Alistair Coles \u003calistairncoles@gmail.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":17,"id":"6fe37ebd_1b05e123","line":24,"in_reply_to":"a38d8c2e_05836469","updated":"2024-01-11 10:45:45.000000000","message":"Done","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"12532e912d8cf1124c3469a52d36779d7413e475","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     Jianjian Huo \u003cjhuo@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2024-01-04 21:56:58 -0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Proxy: Use namespaces for container listing/updating GETs"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"With the Related-Change container servers can return a list Namespace"},{"line_number":10,"context_line":"objects in response to a GET request.  This patch modifies the proxy"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"4bac6495_1d85a12b","line":7,"range":{"start_line":7,"start_character":36,"end_line":7,"end_character":52},"updated":"2024-01-05 15:11:37.000000000","message":"it would be good to get the shard keyword in the subject line\n\nmaybe:\n\nProxy: Use namespaces when getting listing/updating shards","commit_id":"939ccc39d02129ac1549d93adf5872e9b531f30d"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c521326e89be76bcba2dee0b72959fc102693801","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Jianjian Huo \u003cjhuo@nvidia.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2024-01-04 21:56:58 -0800"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Proxy: Use namespaces for container listing/updating GETs"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"With the Related-Change container servers can return a list Namespace"},{"line_number":10,"context_line":"objects in response to a GET request.  This patch modifies the proxy"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"137432cd_3961d9e1","line":7,"range":{"start_line":7,"start_character":36,"end_line":7,"end_character":52},"in_reply_to":"4bac6495_1d85a12b","updated":"2024-01-06 01:49:39.000000000","message":"Acknowledged","commit_id":"939ccc39d02129ac1549d93adf5872e9b531f30d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"12532e912d8cf1124c3469a52d36779d7413e475","unresolved":true,"context_lines":[{"line_number":20,"context_line":"return namespaces, old container servers continue to return full"},{"line_number":21,"context_line":"shard ranges and they are parsed as Namespaces by the new proxy."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"The ObjectController would previously specify that the backend should"},{"line_number":24,"context_line":"return full format ShardRanges when asked for updating state shard"},{"line_number":25,"context_line":"ranges *with an includes parameter*. This isn\u0027t necessary with a"},{"line_number":26,"context_line":"modern backend which now supports the \u0027includes\u0027 parameter with"},{"line_number":27,"context_line":"\u0027namespace\u0027 format requests. This wasn\u0027t strictly necessary with a"},{"line_number":28,"context_line":"legacy backend, which would have returned full format ShardRanges"},{"line_number":29,"context_line":"anyway if an \u0027includes\u0027 parameter was sent."},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"The ContainerController._get_from_shards method needs a list of"},{"line_number":32,"context_line":"namespaces to build a sharded listing. It is currently passed a"},{"line_number":33,"context_line":"response which has a list of either namespaces or full shard range"},{"line_number":34,"context_line":"dicts, depending on what the backend server returned. The list of"},{"line_number":35,"context_line":"dicts is converted to a list of ShardRange objects. This is convenient"},{"line_number":36,"context_line":"because the ShardRange conveniently splits the namespace name into"},{"line_number":37,"context_line":"account and container parts, but it is also confusing given that the"},{"line_number":38,"context_line":"list will often be of namespace dicts."},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"This patch refactors _get_from_shards to clarify that it does not"},{"line_number":41,"context_line":"require ShardRange objects. The method is now passed a list of"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"62579f00_eb8bf94a","line":38,"range":{"start_line":23,"start_character":0,"end_line":38,"end_character":38},"updated":"2024-01-05 15:11:37.000000000","message":"these paragraphs seem to refer to the change between the two backend patches that have now been squashed into one. On master we *always* get shard ranges from the backend, with this patch we always get namespaces from a modern backend.\n\nI think that these paragraphs might just be deleted?","commit_id":"939ccc39d02129ac1549d93adf5872e9b531f30d"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c521326e89be76bcba2dee0b72959fc102693801","unresolved":false,"context_lines":[{"line_number":20,"context_line":"return namespaces, old container servers continue to return full"},{"line_number":21,"context_line":"shard ranges and they are parsed as Namespaces by the new proxy."},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"The ObjectController would previously specify that the backend should"},{"line_number":24,"context_line":"return full format ShardRanges when asked for updating state shard"},{"line_number":25,"context_line":"ranges *with an includes parameter*. This isn\u0027t necessary with a"},{"line_number":26,"context_line":"modern backend which now supports the \u0027includes\u0027 parameter with"},{"line_number":27,"context_line":"\u0027namespace\u0027 format requests. This wasn\u0027t strictly necessary with a"},{"line_number":28,"context_line":"legacy backend, which would have returned full format ShardRanges"},{"line_number":29,"context_line":"anyway if an \u0027includes\u0027 parameter was sent."},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"The ContainerController._get_from_shards method needs a list of"},{"line_number":32,"context_line":"namespaces to build a sharded listing. It is currently passed a"},{"line_number":33,"context_line":"response which has a list of either namespaces or full shard range"},{"line_number":34,"context_line":"dicts, depending on what the backend server returned. The list of"},{"line_number":35,"context_line":"dicts is converted to a list of ShardRange objects. This is convenient"},{"line_number":36,"context_line":"because the ShardRange conveniently splits the namespace name into"},{"line_number":37,"context_line":"account and container parts, but it is also confusing given that the"},{"line_number":38,"context_line":"list will often be of namespace dicts."},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"This patch refactors _get_from_shards to clarify that it does not"},{"line_number":41,"context_line":"require ShardRange objects. The method is now passed a list of"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":36,"id":"d429c59b_da9ae873","line":38,"range":{"start_line":23,"start_character":0,"end_line":38,"end_character":38},"in_reply_to":"62579f00_eb8bf94a","updated":"2024-01-06 01:49:39.000000000","message":"Acknowledged","commit_id":"939ccc39d02129ac1549d93adf5872e9b531f30d"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"05fbc74c6584fe06d64c0dd4b464ca823542bb1a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"68fa18b0_414fd3f7","updated":"2023-09-18 08:20:11.000000000","message":"Been reworking the container controller tests to test for both legecy container servers returning shardranges and returning namespaces. Not quite finished it yet.","commit_id":"f2753a1159d0403249f55af8cc889322ca9d5480"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f5280514b9dfe7c2242073e1609e7ae5f6378b72","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"79b4380a_16335c18","updated":"2023-09-18 08:31:53.000000000","message":"Still pulling more out of my other \"over\" attempt.","commit_id":"f2753a1159d0403249f55af8cc889322ca9d5480"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7054cbbae72bc97481b21ebc2187f66d5e32fac8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"8aca9154_3b6f3bf5","updated":"2023-09-19 06:28:16.000000000","message":"sign, unit tests all pass, now just need to debug the probe test failures.. on that now.","commit_id":"c1e148b4cf05c3cb262e14c5342a6c9ed8250cef"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71784d9354753c2ee9079f57b6b14b94c4c2c6bd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"5ab33ae9_da1c86b2","updated":"2023-09-28 15:53:49.000000000","message":"I have some reservations about the confusing naming/lack of clarity between when we\u0027re dealing with Namespaces vs ShardRanges, but I\u0027m sure that can be ironed out.\n\nFunctionally, I\u0027d advocate for making the exchange of headers between the proxy and backend symmetric:\n\nproxy sends\n\n```\nX-Backend-Record-Type: shard\nX-Backend-Shard-Format: namespace\n```\n\nold backend responds with\n\n```\nX-Backend-Record-Type: shard\n```\n\nnew backend responds with\n\n```\nX-Backend-Record-Type: shard\nX-Backend-Shard-Format: namespace\n```\n\nwhich would require a change in this and the parent patch.","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"0c995b1e9440be50c65fb870dff75163b67c4fe0","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":9,"id":"a1e6da3c_1200d2df","in_reply_to":"5ab33ae9_da1c86b2","updated":"2023-09-29 05:05:00.000000000","message":"I agree. For the new \"namespace\" format, new backend needs to send back \"X-Backend-Shard-Format: namespace\". But for new proxy talks to new backend for ShardRange format, I still want to keep it as same as old style:\n\nNew proxy sends: \n    X-Backend-Record-Type: shard\nNew backend responds with: \n    X-Backend-Record-Type: shard\n\nEssentially, \"X-Backend-Shard-Format: namespace\" is only add-on, lacking of this header indicates that proxy/backend asks for/sends back ShardRange, proxy-servers won\u0027t send \"X-Backend-Shard-Format: full\" anymore. Thus, it\u0027s more obvious to keep backend backward compatible when we keep modifying backend in future.","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2a73982e2aeb37c4de3aaccd988a4a94da3d7fe3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"b5e45130_17f821e2","in_reply_to":"a1e6da3c_1200d2df","updated":"2023-09-30 00:09:19.000000000","message":"per offline discussions, new backend will return both two headers for this case too.","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7847654d3c5c3d22730bbcc317fade233f2fc9bd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"8d3230ec_1bbf70ff","updated":"2023-09-29 18:05:40.000000000","message":"probe tests look ok\n\n```\nvagrant@vagrant:~/swift$ pytest test/probe/test_sharder.py::TestContainerSharding\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d test session starts \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\nplatform linux -- Python 3.8.10, pytest-7.2.1, pluggy-1.0.0 -- /usr/bin/python\ncachedir: .pytest_cache\nrootdir: /vagrant/swift, configfile: tox.ini\nplugins: cov-4.0.0\ncollected 18 items\n\ntest/probe/test_sharder.py::TestContainerSharding::test_async_pendings PASSED                                                                     [  5%]\ntest/probe/test_sharder.py::TestContainerSharding::test_delete_root_reclaim PASSED                                                                [ 11%]\ntest/probe/test_sharder.py::TestContainerSharding::test_listing_under_populated_replica PASSED                                                    [ 16%]\ntest/probe/test_sharder.py::TestContainerSharding::test_misplaced_object_movement PASSED                                                          [ 22%]\ntest/probe/test_sharder.py::TestContainerSharding::test_misplaced_object_movement_from_deleted_shard PASSED                                       [ 27%]\ntest/probe/test_sharder.py::TestContainerSharding::test_object_update_redirection PASSED                                                          [ 33%]\ntest/probe/test_sharder.py::TestContainerSharding::test_replication_to_empty_new_primary_from_sharding_old_primary PASSED                         [ 38%]\ntest/probe/test_sharder.py::TestContainerSharding::test_replication_to_sharded_container PASSED                                                   [ 44%]\ntest/probe/test_sharder.py::TestContainerSharding::test_replication_to_sharded_container_from_unsharded_old_primary PASSED                        [ 50%]\ntest/probe/test_sharder.py::TestContainerSharding::test_replication_to_sharding_container PASSED                                                  [ 55%]\ntest/probe/test_sharder.py::TestContainerSharding::test_sharded_account_updates PASSED                                                            [ 61%]\ntest/probe/test_sharder.py::TestContainerSharding::test_sharded_can_get_objects_different_policy PASSED                                           [ 66%]\ntest/probe/test_sharder.py::TestContainerSharding::test_sharded_can_get_objects_different_policy_reversed PASSED                                  [ 72%]\ntest/probe/test_sharder.py::TestContainerSharding::test_sharded_delete PASSED                                                                     [ 77%]\ntest/probe/test_sharder.py::TestContainerSharding::test_sharded_listing_no_replicators PASSED                                                     [ 83%]\ntest/probe/test_sharder.py::TestContainerSharding::test_sharded_listing_with_replicators PASSED                                                   [ 88%]\ntest/probe/test_sharder.py::TestContainerSharding::test_sharding_requires_sufficient_replication PASSED                                           [ 94%]\ntest/probe/test_sharder.py::TestContainerSharding::test_shrinking PASSED                                                                          [100%]\n\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d warnings summary \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\ntest/probe/test_sharder.py: 1525 warnings\n  /vagrant/python-swiftclient/swiftclient/client.py:449: DeprecationWarning: HTTPResponse.getheader() is deprecated and will be removed in urllib3 v2.1.0. Instead use HTTPResponse.headers.get(name, default).\n    return _decode_header(old_getheader(\n\n-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d 18 passed, 1525 warnings in 468.54s (0:07:48) \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n```","commit_id":"02405cb83d6d2a01a1c2ea65b7343a5087ae4c5c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a10c6485a1ca707650e22e8918aec52a7d9695ca","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"71c12454_201c4598","updated":"2023-10-02 14:35:17.000000000","message":"I\u0027m thinking that the Namespace name bug should probably be broken out into a separate patch rather then be a drive-by in this patch","commit_id":"7476f4bc3a86879a41495fa89445a2107a0779ba"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1789bba8cd72538246985f115d09d223572b199c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"611b6b03_df92bc0c","updated":"2023-10-02 18:19:03.000000000","message":"I have played with this and the parent patch in VSAIO, variously running proxy, sharder and container-server before and after upgrade, and all seems good.\n\nIMHO We should break out the Namespace.name bug fix before merging.","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"90a673a8ad489aafddd8b08d96078738fe630335","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"c8b58c9f_b5443371","updated":"2023-10-03 19:34:35.000000000","message":"I want to think a bit more about the `account`/`container`/`name` changes (I rather liked that you couldn\u0027t change `account` without impacting `name` and vice versa), but it all seems to make sense enough.","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"326cd0e40a65bf0c1f84c8933097441c47cbe6fc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"441e3a6e_e1fe8e62","updated":"2023-10-02 16:31:49.000000000","message":"recheck","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0d714ec1542d3d07f8c7a3e3877d207b7d29549b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"9d33cb57_905ee42a","updated":"2023-10-16 00:27:05.000000000","message":"OK, yeah adding the a/c to the namespace stuff does make it more brittle. And seems your follow up does fix the flakiness of setting account or container in a shardrange object and it properly updating the name. So i can totally get on board with that. best of both worlds.\n\nWhen it comes to using Namespace as a drop in replacement for shardranges, isn\u0027t quite as drop in, but not think it\u0027ll shake up the code too much!\n\nI\u0027ll squash it down.","commit_id":"2e59ddfe61acd61bbc109f6a68f17e144ada3924"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a9a3a0039b8d737bb1d23d2ad51a85996ba86bb6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"be07e4a4_b172406e","updated":"2023-10-13 17:07:53.000000000","message":"still looks OK to me, although I have reservations about making Namespaces have brittle name formats. See https://review.opendev.org/c/openstack/swift/+/898244 for why.","commit_id":"2e59ddfe61acd61bbc109f6a68f17e144ada3924"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"26aed7b82ae8dad6bc4d6b082fda24f6bc27f2c4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"95b4c809_1e93b40f","updated":"2023-10-16 19:11:44.000000000","message":"i find the OOP gymnastics a little confusing.  I like the suggestion to use Namespace objects if that\u0027s all the proxy needs (but didn\u0027t see a change in proxy.controllers.base in Al\u0027s follow-up; so I may be confused)","commit_id":"efb974f65df803d4fde17c2c4587fc3da562903b"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"721b7d1668a15214e7d806902e05c5ce5b4bf107","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"a5b013fa_b278c6d0","in_reply_to":"95b4c809_1e93b40f","updated":"2023-10-17 08:29:26.000000000","message":"Moving proxy to namespace objects is definitely on the cards. Al\u0027s follow up was to show the brittleness of the naming and why we it\u0027s useful to have namespaces take any name.\n\nThe moving to namespace objects will come as soon as the namespace api supports includes, marker, end_marker, etc.","commit_id":"efb974f65df803d4fde17c2c4587fc3da562903b"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d99c9ee863fc27154b53a70952c6f723d330ae6e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":17,"id":"6354514d_d92ef43b","updated":"2023-11-03 01:17:01.000000000","message":"I have split the Namespace name encoding py2 fix into this patch: https://review.opendev.org/c/openstack/swift/+/899993","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":17,"id":"92fc440a_5992157b","updated":"2023-11-01 00:22:45.000000000","message":"I think the testing approach here could potentially be a bit more targeted and thourough.\n\nI think the changes to proxy request headers AND ShardRange/Namespace class-hierarchy a bit much for one patch to grok all at once.  I totally missed the bit that makes it obvious they\u0027re related - we don\u0027t even *use* the Namespace class in the proxy and the sharder still requests record-format \u003d full?\n\n... but maybe this fine; i don\u0027t think we\u0027re carrying it yet","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"bfda870e1d34619807f038c09001f4f84a662e41","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":33,"id":"74468dab_511e76c2","updated":"2023-12-11 19:00:23.000000000","message":"recheck","commit_id":"c22a7946d1211d1d1ad20ae23c0c5a7cb870c3cd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"062f3e9de780753a4776468d255d05fd76f24bb8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":34,"id":"ed4faf72_0cd81d92","updated":"2024-01-04 12:11:59.000000000","message":"recheck \n\nbug https://bugs.launchpad.net/swift/+bug/2028175 intermittent probe test failure: test_reconciler_move_object_twice Edit","commit_id":"0f48c895d4afb63ef309cf30ea4655ff1672502a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"8e3992aaecf1c6722c63b956e8fd3252290cb5a2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":40,"id":"15927ac1_a37ba6e0","updated":"2024-01-08 12:02:21.000000000","message":"recheck","commit_id":"5d322113a3e118fbe66a4c811910afe3c22b1702"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"bbea5beccbae03541feadadc0f2dbf4691819a14","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":45,"id":"a47d0c75_7deefccd","updated":"2024-01-11 06:08:27.000000000","message":"Looking great to me. But I probably can\u0027t land it because I\u0027m an author.","commit_id":"e3bd775fafc62212750b2a366660f3055da50a2a"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"1c23f2bd238fb462074e5a9cbc92e66292b18631","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":46,"id":"085fc183_7676b43a","updated":"2024-01-12 03:34:08.000000000","message":"Great! I think this is ready to go! better we\u0027re already carrying it in prod and works great! Also it has a +1 from Jiianjian (well 2 days ago it did and it\u0027s only been rebased because of movement in the parent patch) which speaks bucket loads to me, he\u0027s been living and dreaming this namespace api 😊\n\nI\u0027m going to land this sucker! Great work team!","commit_id":"03b66c94f423f06cd6c16742a8ae2ea4bbccbd70"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5e5eb4e19096acf8651743f7a50222630c77a610","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":46,"id":"dcf0206e_22ccbc47","updated":"2024-01-12 14:36:16.000000000","message":"sorry i missed the last round on this one; seems like it worked out great!  love the new inheritence-based legacy test infra.","commit_id":"03b66c94f423f06cd6c16742a8ae2ea4bbccbd70"}],"swift/common/utils/__init__.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71784d9354753c2ee9079f57b6b14b94c4c2c6bd","unresolved":true,"context_lines":[{"line_number":4583,"context_line":"        self._upper \u003d Namespace.MAX"},{"line_number":4584,"context_line":"        self.lower \u003d lower"},{"line_number":4585,"context_line":"        self.upper \u003d upper"},{"line_number":4586,"context_line":"        self.name \u003d self._encode(name)"},{"line_number":4587,"context_line":""},{"line_number":4588,"context_line":"    def __iter__(self):"},{"line_number":4589,"context_line":"        yield \u0027name\u0027, str(self.name)"}],"source_content_type":"text/x-python","patch_set":9,"id":"a3b0ebad_1ad3d9d5","line":4586,"updated":"2023-09-28 15:53:49.000000000","message":"this seems significant but there\u0027s no matching test coverage added - what broke that needed this?","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2a73982e2aeb37c4de3aaccd988a4a94da3d7fe3","unresolved":false,"context_lines":[{"line_number":4583,"context_line":"        self._upper \u003d Namespace.MAX"},{"line_number":4584,"context_line":"        self.lower \u003d lower"},{"line_number":4585,"context_line":"        self.upper \u003d upper"},{"line_number":4586,"context_line":"        self.name \u003d self._encode(name)"},{"line_number":4587,"context_line":""},{"line_number":4588,"context_line":"    def __iter__(self):"},{"line_number":4589,"context_line":"        yield \u0027name\u0027, str(self.name)"}],"source_content_type":"text/x-python","patch_set":9,"id":"18324f19_bbbca24f","line":4586,"in_reply_to":"a3b0ebad_1ad3d9d5","updated":"2023-09-30 00:09:19.000000000","message":"it\u0027s this case: test/unit/proxy/controllers/test_container.py: TestContainerController.test_GET_sharded_container_no_memcache.\nNamespace\u0027s lower and upper were able to handle unicode names, but not name attribute, so I added self._encode(name) here. Also, added related test cases.","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a10c6485a1ca707650e22e8918aec52a7d9695ca","unresolved":true,"context_lines":[{"line_number":4583,"context_line":"        self._upper \u003d Namespace.MAX"},{"line_number":4584,"context_line":"        self.lower \u003d lower"},{"line_number":4585,"context_line":"        self.upper \u003d upper"},{"line_number":4586,"context_line":"        self.name \u003d self._encode(name)"},{"line_number":4587,"context_line":""},{"line_number":4588,"context_line":"    def __iter__(self):"},{"line_number":4589,"context_line":"        yield \u0027name\u0027, str(self.name)"}],"source_content_type":"text/x-python","patch_set":12,"id":"8bca84b1_cdbc07eb","line":4586,"updated":"2023-10-02 14:35:17.000000000","message":"this ought to be done via a property setter so that Namespace.name is encoded every time it is set, not just in the constructor","commit_id":"7476f4bc3a86879a41495fa89445a2107a0779ba"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1789bba8cd72538246985f115d09d223572b199c","unresolved":false,"context_lines":[{"line_number":4583,"context_line":"        self._upper \u003d Namespace.MAX"},{"line_number":4584,"context_line":"        self.lower \u003d lower"},{"line_number":4585,"context_line":"        self.upper \u003d upper"},{"line_number":4586,"context_line":"        self.name \u003d self._encode(name)"},{"line_number":4587,"context_line":""},{"line_number":4588,"context_line":"    def __iter__(self):"},{"line_number":4589,"context_line":"        yield \u0027name\u0027, str(self.name)"}],"source_content_type":"text/x-python","patch_set":12,"id":"2a25f570_832b3847","line":4586,"in_reply_to":"8bca84b1_cdbc07eb","updated":"2023-10-02 18:19:03.000000000","message":"Done","commit_id":"7476f4bc3a86879a41495fa89445a2107a0779ba"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ded64fafb800e6a79f835f524d4be423dc54b157","unresolved":false,"context_lines":[{"line_number":4583,"context_line":"        self._upper \u003d Namespace.MAX"},{"line_number":4584,"context_line":"        self.lower \u003d lower"},{"line_number":4585,"context_line":"        self.upper \u003d upper"},{"line_number":4586,"context_line":"        self.name \u003d self._encode(name)"},{"line_number":4587,"context_line":""},{"line_number":4588,"context_line":"    def __iter__(self):"},{"line_number":4589,"context_line":"        yield \u0027name\u0027, str(self.name)"}],"source_content_type":"text/x-python","patch_set":12,"id":"0b39b214_421b5a46","line":4586,"in_reply_to":"8bca84b1_cdbc07eb","updated":"2023-10-02 18:24:58.000000000","message":"good point, property setter is better. thanks!","commit_id":"7476f4bc3a86879a41495fa89445a2107a0779ba"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"90a673a8ad489aafddd8b08d96078738fe630335","unresolved":true,"context_lines":[{"line_number":4561,"context_line":"    :param upper: the upper bound of object names contained in the namespace;"},{"line_number":4562,"context_line":"        the upper bound *is* included in the namespace."},{"line_number":4563,"context_line":"    \"\"\""},{"line_number":4564,"context_line":"    __slots__ \u003d (\u0027_lower\u0027, \u0027_upper\u0027, \u0027_name\u0027)"},{"line_number":4565,"context_line":""},{"line_number":4566,"context_line":"    @functools.total_ordering"},{"line_number":4567,"context_line":"    class MaxBound(NamespaceOuterBound):"}],"source_content_type":"text/x-python","patch_set":13,"id":"3016833c_d5df322f","line":4564,"updated":"2023-10-03 19:34:35.000000000","message":"I wonder if it would be better to have `Namespace`s get `account`/`container` attrs -- do we ever anticipate using them outside of that sort of a context?","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a9a3a0039b8d737bb1d23d2ad51a85996ba86bb6","unresolved":true,"context_lines":[{"line_number":4561,"context_line":"    :param upper: the upper bound of object names contained in the namespace;"},{"line_number":4562,"context_line":"        the upper bound *is* included in the namespace."},{"line_number":4563,"context_line":"    \"\"\""},{"line_number":4564,"context_line":"    __slots__ \u003d (\u0027_lower\u0027, \u0027_upper\u0027, \u0027_name\u0027)"},{"line_number":4565,"context_line":""},{"line_number":4566,"context_line":"    @functools.total_ordering"},{"line_number":4567,"context_line":"    class MaxBound(NamespaceOuterBound):"}],"source_content_type":"text/x-python","patch_set":13,"id":"be1193ea_8ad3e76f","line":4564,"in_reply_to":"0de6f28d_af6888ed","updated":"2023-10-13 17:07:53.000000000","message":"I did intentionally not saddle Namespace with the requirement to be named a/c when breaking out the superclass. It\u0027s so brittle. \n\nWe already could use Namespaces with simpler names. For example:\n https://github.com/openstack/swift/blob/6d5301050847df1b09a3e548be7095e4b73a945c/swift/container/sharder.py#L1841-L1843\n\nhttps://github.com/openstack/swift/blob/6d5301050847df1b09a3e548be7095e4b73a945c/swift/container/sharder.py#L126-L157\n\nhttps://github.com/openstack/swift/blob/9063ea0ac72a4be3c3a4e099423458f25a9783db/swift/cli/manage_shard_ranges.py#L883-L895\n\nOn that topic (separate topic to this patch) I pushed https://review.opendev.org/c/openstack/swift/+/898244","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"1a0040df681f3abbc578aa3ea42bfcfac4da7947","unresolved":true,"context_lines":[{"line_number":4561,"context_line":"    :param upper: the upper bound of object names contained in the namespace;"},{"line_number":4562,"context_line":"        the upper bound *is* included in the namespace."},{"line_number":4563,"context_line":"    \"\"\""},{"line_number":4564,"context_line":"    __slots__ \u003d (\u0027_lower\u0027, \u0027_upper\u0027, \u0027_name\u0027)"},{"line_number":4565,"context_line":""},{"line_number":4566,"context_line":"    @functools.total_ordering"},{"line_number":4567,"context_line":"    class MaxBound(NamespaceOuterBound):"}],"source_content_type":"text/x-python","patch_set":13,"id":"0de6f28d_af6888ed","line":4564,"in_reply_to":"3016833c_d5df322f","updated":"2023-10-04 05:47:33.000000000","message":"If we want to start using namespaces more in the proxy. Ie. in most cases (outside the sharder using internal client) everything in the proxy only cares about lower, upper and the name. We currently reply on the account and container params of shard_ranges so to make Namespace objects drop in replacements I wouldn\u0027t be opposed to growing account container and name is just a setter/getter like we do in the sharder.\nIt\u0027s why my older patch had https://review.opendev.org/c/openstack/swift/+/892852/6/swift/common/utils/__init__.py#4442 \n\nAlternatively however, we could just split the name ourselves when we use it in the proxy.. and leave this as it is.","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d99c9ee863fc27154b53a70952c6f723d330ae6e","unresolved":true,"context_lines":[{"line_number":4561,"context_line":"    :param upper: the upper bound of object names contained in the namespace;"},{"line_number":4562,"context_line":"        the upper bound *is* included in the namespace."},{"line_number":4563,"context_line":"    \"\"\""},{"line_number":4564,"context_line":"    __slots__ \u003d (\u0027_lower\u0027, \u0027_upper\u0027, \u0027_name\u0027)"},{"line_number":4565,"context_line":""},{"line_number":4566,"context_line":"    @functools.total_ordering"},{"line_number":4567,"context_line":"    class MaxBound(NamespaceOuterBound):"}],"source_content_type":"text/x-python","patch_set":13,"id":"2d4808d0_4b7e51e3","line":4564,"in_reply_to":"9866cbea_37060142","updated":"2023-11-03 01:17:01.000000000","message":"Another reason I\u0027d like to keep the account/container stuff in ShardRange is for performance concerns. From previous benchmarking tests when we worked on shard range cache v2, the less variables Namespace object has, the better performance proxy will get when it needs looping over a list of ~12K those objects.","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":4561,"context_line":"    :param upper: the upper bound of object names contained in the namespace;"},{"line_number":4562,"context_line":"        the upper bound *is* included in the namespace."},{"line_number":4563,"context_line":"    \"\"\""},{"line_number":4564,"context_line":"    __slots__ \u003d (\u0027_lower\u0027, \u0027_upper\u0027, \u0027_name\u0027)"},{"line_number":4565,"context_line":""},{"line_number":4566,"context_line":"    @functools.total_ordering"},{"line_number":4567,"context_line":"    class MaxBound(NamespaceOuterBound):"}],"source_content_type":"text/x-python","patch_set":13,"id":"9866cbea_37060142","line":4564,"in_reply_to":"be1193ea_8ad3e76f","updated":"2023-11-01 00:22:45.000000000","message":"Ok, but those use-cases already pass \u0027a/c\u0027 as name, so they *could* be split into account/container.  It looks more like there\u0027s another use-case for a sortable bounds tuple that doesn\u0027t have a name at all?\n\n    ShardBound(lower, upper)\n    Namespace(\u0027a\u0027, \u0027c\u0027, lower, upper)\n    ShardRange(\u0027a\u0027, \u0027c\u0027, lower, upper, state, timestamp)\n    \nOnce you have a name it seems like that name is always in the form of a/c, correct?So I\u0027m not sure if there\u0027s a reason we\u0027re rejecting Tim\u0027s suggestion?","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"90a673a8ad489aafddd8b08d96078738fe630335","unresolved":false,"context_lines":[{"line_number":5059,"context_line":"                 reported\u003dFalse, tombstones\u003d-1, **kwargs):"},{"line_number":5060,"context_line":"        super(ShardRange, self).__init__(name\u003dname, lower\u003dlower, upper\u003dupper)"},{"line_number":5061,"context_line":"        self._timestamp \u003d self._meta_timestamp \u003d self._state_timestamp \u003d \\"},{"line_number":5062,"context_line":"            self._epoch \u003d None"},{"line_number":5063,"context_line":"        self._deleted \u003d False"},{"line_number":5064,"context_line":"        self._state \u003d None"},{"line_number":5065,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"390573df_b7813014","line":5062,"updated":"2023-10-03 19:34:35.000000000","message":"Hah! Oh jeeze... so prior to this, we would\n\n* take in `name` as an arg,\n* pass it to `super().__init__()`,\n* drop down to the `name` setter below,\n* sanity check the format, split it, and store it as `account`/`container`,\n* come back here and clear them both,\n* then call the setter *again*, so we can **really**\n* sanity check the format, split it, and store it as `account`/`container`.","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"90a673a8ad489aafddd8b08d96078738fe630335","unresolved":true,"context_lines":[{"line_number":5238,"context_line":"                \"Name must be of the form \u0027\u003caccount\u003e/\u003ccontainer\u003e\u0027, got %r\" %"},{"line_number":5239,"context_line":"                name)"},{"line_number":5240,"context_line":"        self._name \u003d name"},{"line_number":5241,"context_line":"        self.account, self.container \u003d name.split(\u0027/\u0027)"},{"line_number":5242,"context_line":""},{"line_number":5243,"context_line":"    @property"},{"line_number":5244,"context_line":"    def timestamp(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"8087abf9_939aa3d1","line":5241,"updated":"2023-10-03 19:34:35.000000000","message":"Hmm... so now we can have `account`/`container` diverge from `name`... but only once you\u0027ve already instantiated the `ShardRange`, and only by using a particular order of operations; i.e.,\n```\nsr \u003d ShardRange(...)\nsr.name \u003d \u0027foo/bar\u0027\nsr.container \u003d \u0027baz\u0027\n```\nwill result in that divergence, while\n```\nsr \u003d ShardRange(...)\nsr.container \u003d \u0027baz\u0027\nsr.name \u003d \u0027foo/bar\u0027\n```\nwill not. I wonder, in that former case, what gets written down in the DB if we go to save a split-brain shard range like that? My bet would be that `name` is used, and the different `container` wouldn\u0027t round-trip when you read it back.\n\nI don\u0027t think we really manipulate `account`/`container` like that, though, so it\u0027s probably all moot.","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"66bbcea7e52f1a311d685db87c4016194cf879b7","unresolved":false,"context_lines":[{"line_number":5238,"context_line":"                \"Name must be of the form \u0027\u003caccount\u003e/\u003ccontainer\u003e\u0027, got %r\" %"},{"line_number":5239,"context_line":"                name)"},{"line_number":5240,"context_line":"        self._name \u003d name"},{"line_number":5241,"context_line":"        self.account, self.container \u003d name.split(\u0027/\u0027)"},{"line_number":5242,"context_line":""},{"line_number":5243,"context_line":"    @property"},{"line_number":5244,"context_line":"    def timestamp(self):"}],"source_content_type":"text/x-python","patch_set":13,"id":"71bb3461_23f7ddbc","line":5241,"in_reply_to":"8087abf9_939aa3d1","updated":"2023-10-13 10:10:44.000000000","message":"I just moved account/container up into namespace. It tidies this all up in my opinion.","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a9a3a0039b8d737bb1d23d2ad51a85996ba86bb6","unresolved":true,"context_lines":[{"line_number":4586,"context_line":"    def __init__(self, name, lower, upper):"},{"line_number":4587,"context_line":"        self._lower \u003d Namespace.MIN"},{"line_number":4588,"context_line":"        self._upper \u003d Namespace.MAX"},{"line_number":4589,"context_line":"        self.account \u003d self.container \u003d None"},{"line_number":4590,"context_line":"        self.lower \u003d lower"},{"line_number":4591,"context_line":"        self.upper \u003d upper"},{"line_number":4592,"context_line":"        self.name \u003d name"}],"source_content_type":"text/x-python","patch_set":14,"id":"23ac2908_a3ce89b2","line":4589,"updated":"2023-10-13 17:07:53.000000000","message":"I\u0027d really prefer Namespaces not to be saddled with the brittle requirement that a name is a/c.\n\nAlso, shouldn\u0027t we be ensuring account and container are encoded (py2) when they are set? just like name is.\n\nHow about this solution, keeping the account/container stuff  in ShardRange https://review.opendev.org/c/openstack/swift/+/898243 ?","commit_id":"2e59ddfe61acd61bbc109f6a68f17e144ada3924"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"4f6801698e911242b941035947715a156625d376","unresolved":true,"context_lines":[{"line_number":4586,"context_line":"    def __init__(self, name, lower, upper):"},{"line_number":4587,"context_line":"        self._lower \u003d Namespace.MIN"},{"line_number":4588,"context_line":"        self._upper \u003d Namespace.MAX"},{"line_number":4589,"context_line":"        self.account \u003d self.container \u003d None"},{"line_number":4590,"context_line":"        self.lower \u003d lower"},{"line_number":4591,"context_line":"        self.upper \u003d upper"},{"line_number":4592,"context_line":"        self.name \u003d name"}],"source_content_type":"text/x-python","patch_set":14,"id":"67e60ebe_740aec8a","line":4589,"in_reply_to":"23ac2908_a3ce89b2","updated":"2023-10-13 19:30:01.000000000","message":"I would prefer to keep the account/container stuff in ShardRange too, mainly for performance concerns. From previous benchmarking tests in general, the less object variables, the better performance when looping over list of those objects.","commit_id":"2e59ddfe61acd61bbc109f6a68f17e144ada3924"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"824ebca9ca91b06d1a8ca6afc6ee9b11b58db768","unresolved":false,"context_lines":[{"line_number":4586,"context_line":"    def __init__(self, name, lower, upper):"},{"line_number":4587,"context_line":"        self._lower \u003d Namespace.MIN"},{"line_number":4588,"context_line":"        self._upper \u003d Namespace.MAX"},{"line_number":4589,"context_line":"        self.account \u003d self.container \u003d None"},{"line_number":4590,"context_line":"        self.lower \u003d lower"},{"line_number":4591,"context_line":"        self.upper \u003d upper"},{"line_number":4592,"context_line":"        self.name \u003d name"}],"source_content_type":"text/x-python","patch_set":14,"id":"068ab6e7_3cad721a","line":4589,"in_reply_to":"67e60ebe_740aec8a","updated":"2023-10-16 00:28:54.000000000","message":"Ack","commit_id":"2e59ddfe61acd61bbc109f6a68f17e144ada3924"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a9a3a0039b8d737bb1d23d2ad51a85996ba86bb6","unresolved":true,"context_lines":[{"line_number":4664,"context_line":""},{"line_number":4665,"context_line":"    @property"},{"line_number":4666,"context_line":"    def name(self):"},{"line_number":4667,"context_line":"        return \u0027%s/%s\u0027 % (self.account, self.container)"},{"line_number":4668,"context_line":""},{"line_number":4669,"context_line":"    @name.setter"},{"line_number":4670,"context_line":"    def name(self, path):"}],"source_content_type":"text/x-python","patch_set":14,"id":"8edbc27e_5f25e464","line":4667,"updated":"2023-10-13 17:07:53.000000000","message":"this is the fix needed w.r.t. patchset 13","commit_id":"2e59ddfe61acd61bbc109f6a68f17e144ada3924"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d8751f1359c8d218a4da427b2fafffc544a2efdb","unresolved":false,"context_lines":[{"line_number":4664,"context_line":""},{"line_number":4665,"context_line":"    @property"},{"line_number":4666,"context_line":"    def name(self):"},{"line_number":4667,"context_line":"        return \u0027%s/%s\u0027 % (self.account, self.container)"},{"line_number":4668,"context_line":""},{"line_number":4669,"context_line":"    @name.setter"},{"line_number":4670,"context_line":"    def name(self, path):"}],"source_content_type":"text/x-python","patch_set":14,"id":"ace7dc8d_3a12d545","line":4667,"in_reply_to":"8edbc27e_5f25e464","updated":"2023-10-16 10:06:21.000000000","message":"Done","commit_id":"2e59ddfe61acd61bbc109f6a68f17e144ada3924"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"26aed7b82ae8dad6bc4d6b082fda24f6bc27f2c4","unresolved":true,"context_lines":[{"line_number":5059,"context_line":"        self._deleted \u003d False"},{"line_number":5060,"context_line":"        self._state \u003d None"},{"line_number":5061,"context_line":""},{"line_number":5062,"context_line":"        self.name \u003d name"},{"line_number":5063,"context_line":"        self.timestamp \u003d timestamp"},{"line_number":5064,"context_line":"        self.deleted \u003d deleted"},{"line_number":5065,"context_line":"        self.object_count \u003d object_count"}],"source_content_type":"text/x-python","patch_set":15,"id":"94a2190a_297d9340","side":"PARENT","line":5062,"updated":"2023-10-16 19:11:44.000000000","message":"ok, so the super call into `__init__` actually takes care of calling the name propety setter on *this* class?","commit_id":"e8052b259584a1587d53670bb9c800fcd4b912f3"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d99c9ee863fc27154b53a70952c6f723d330ae6e","unresolved":false,"context_lines":[{"line_number":5059,"context_line":"        self._deleted \u003d False"},{"line_number":5060,"context_line":"        self._state \u003d None"},{"line_number":5061,"context_line":""},{"line_number":5062,"context_line":"        self.name \u003d name"},{"line_number":5063,"context_line":"        self.timestamp \u003d timestamp"},{"line_number":5064,"context_line":"        self.deleted \u003d deleted"},{"line_number":5065,"context_line":"        self.object_count \u003d object_count"}],"source_content_type":"text/x-python","patch_set":15,"id":"1f11293d_053507aa","side":"PARENT","line":5062,"in_reply_to":"94a2190a_297d9340","updated":"2023-11-03 01:17:01.000000000","message":"yes, the instantiation of Namespace will call the name property setter of child class, as demonstrated in test case: https://review.opendev.org/c/openstack/swift/+/899993/1/test/unit/common/test_utils.py#8083","commit_id":"e8052b259584a1587d53670bb9c800fcd4b912f3"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"26aed7b82ae8dad6bc4d6b082fda24f6bc27f2c4","unresolved":true,"context_lines":[{"line_number":5258,"context_line":"            raise ValueError("},{"line_number":5259,"context_line":"                \"Name must be of the form \u0027\u003caccount\u003e/\u003ccontainer\u003e\u0027, got %r\" %"},{"line_number":5260,"context_line":"                name)"},{"line_number":5261,"context_line":"        self._account, self._container \u003d name.split(\u0027/\u0027)"},{"line_number":5262,"context_line":""},{"line_number":5263,"context_line":"    @property"},{"line_number":5264,"context_line":"    def timestamp(self):"}],"source_content_type":"text/x-python","patch_set":15,"id":"a8e8ccef_8020a1d3","line":5261,"updated":"2023-10-16 19:11:44.000000000","message":"it\u0027s not clear to me exactly how all this churn is related to dropping `self.name \u003d name` in `__init__` - but i have to assume _encode is idempotent.","commit_id":"efb974f65df803d4fde17c2c4587fc3da562903b"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d99c9ee863fc27154b53a70952c6f723d330ae6e","unresolved":false,"context_lines":[{"line_number":5258,"context_line":"            raise ValueError("},{"line_number":5259,"context_line":"                \"Name must be of the form \u0027\u003caccount\u003e/\u003ccontainer\u003e\u0027, got %r\" %"},{"line_number":5260,"context_line":"                name)"},{"line_number":5261,"context_line":"        self._account, self._container \u003d name.split(\u0027/\u0027)"},{"line_number":5262,"context_line":""},{"line_number":5263,"context_line":"    @property"},{"line_number":5264,"context_line":"    def timestamp(self):"}],"source_content_type":"text/x-python","patch_set":15,"id":"6c10eb85_cf89f997","line":5261,"in_reply_to":"a8e8ccef_8020a1d3","updated":"2023-11-03 01:17:01.000000000","message":"Those are fixes to account/container setters to encode value in py2, in additional to Namespace ``name`` fix.","commit_id":"efb974f65df803d4fde17c2c4587fc3da562903b"}],"swift/container/sharder.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f5280514b9dfe7c2242073e1609e7ae5f6378b72","unresolved":true,"context_lines":[{"line_number":1156,"context_line":"        params \u003d params or {}"},{"line_number":1157,"context_line":"        params.setdefault(\u0027format\u0027, \u0027json\u0027)"},{"line_number":1158,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":1159,"context_line":"                   \u0027X-Backend-Record-Shard-Format\u0027: \u0027full\u0027,"},{"line_number":1160,"context_line":"                   \u0027X-Backend-Override-Deleted\u0027: \u0027true\u0027,"},{"line_number":1161,"context_line":"                   \u0027X-Backend-Include-Deleted\u0027: str(include_deleted)}"},{"line_number":1162,"context_line":"        if newest:"}],"source_content_type":"text/x-python","patch_set":1,"id":"c90fe50e_b506cf9a","line":1159,"updated":"2023-09-18 08:31:53.000000000","message":"Better to be explicit with what we want, so we don\u0027t get some edge case bug.","commit_id":"f2753a1159d0403249f55af8cc889322ca9d5480"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ccd698c7b2d81ee57fb4dcffd89df7eb64aeb9b3","unresolved":false,"context_lines":[{"line_number":1156,"context_line":"        params \u003d params or {}"},{"line_number":1157,"context_line":"        params.setdefault(\u0027format\u0027, \u0027json\u0027)"},{"line_number":1158,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":1159,"context_line":"                   \u0027X-Backend-Record-Shard-Format\u0027: \u0027full\u0027,"},{"line_number":1160,"context_line":"                   \u0027X-Backend-Override-Deleted\u0027: \u0027true\u0027,"},{"line_number":1161,"context_line":"                   \u0027X-Backend-Include-Deleted\u0027: str(include_deleted)}"},{"line_number":1162,"context_line":"        if newest:"}],"source_content_type":"text/x-python","patch_set":1,"id":"1c756bb9_6d55e31b","line":1159,"in_reply_to":"c90fe50e_b506cf9a","updated":"2023-09-21 21:14:48.000000000","message":"Ack","commit_id":"f2753a1159d0403249f55af8cc889322ca9d5480"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71784d9354753c2ee9079f57b6b14b94c4c2c6bd","unresolved":true,"context_lines":[{"line_number":1156,"context_line":"        params \u003d params or {}"},{"line_number":1157,"context_line":"        params.setdefault(\u0027format\u0027, \u0027json\u0027)"},{"line_number":1158,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":1159,"context_line":"                   \u0027X-Backend-Record-Shard-Format\u0027: \u0027full\u0027,"},{"line_number":1160,"context_line":"                   \u0027X-Backend-Override-Deleted\u0027: \u0027true\u0027,"},{"line_number":1161,"context_line":"                   \u0027X-Backend-Include-Deleted\u0027: str(include_deleted)}"},{"line_number":1162,"context_line":"        if newest:"}],"source_content_type":"text/x-python","patch_set":9,"id":"6ed5010c_b848a154","line":1159,"updated":"2023-09-28 15:53:49.000000000","message":"the old container server always returns full, correct? because the sharder is not necessarily upgrade at the same time as the container server or proxy.","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2a73982e2aeb37c4de3aaccd988a4a94da3d7fe3","unresolved":false,"context_lines":[{"line_number":1156,"context_line":"        params \u003d params or {}"},{"line_number":1157,"context_line":"        params.setdefault(\u0027format\u0027, \u0027json\u0027)"},{"line_number":1158,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":1159,"context_line":"                   \u0027X-Backend-Record-Shard-Format\u0027: \u0027full\u0027,"},{"line_number":1160,"context_line":"                   \u0027X-Backend-Override-Deleted\u0027: \u0027true\u0027,"},{"line_number":1161,"context_line":"                   \u0027X-Backend-Include-Deleted\u0027: str(include_deleted)}"},{"line_number":1162,"context_line":"        if newest:"}],"source_content_type":"text/x-python","patch_set":9,"id":"39092657_1813892b","line":1159,"in_reply_to":"6ed5010c_b848a154","updated":"2023-09-30 00:09:19.000000000","message":"Ack","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1789bba8cd72538246985f115d09d223572b199c","unresolved":true,"context_lines":[{"line_number":1156,"context_line":"        params \u003d params or {}"},{"line_number":1157,"context_line":"        params.setdefault(\u0027format\u0027, \u0027json\u0027)"},{"line_number":1158,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":1159,"context_line":"                   \u0027X-Backend-Record-Shard-Format\u0027: \u0027full\u0027,"},{"line_number":1160,"context_line":"                   \u0027X-Backend-Override-Deleted\u0027: \u0027true\u0027,"},{"line_number":1161,"context_line":"                   \u0027X-Backend-Include-Deleted\u0027: str(include_deleted)}"},{"line_number":1162,"context_line":"        if newest:"}],"source_content_type":"text/x-python","patch_set":13,"id":"7e0b8150_336c18d8","line":1159,"updated":"2023-10-02 18:19:03.000000000","message":"ok, this seems to be the only place that the sharder makes a container GET request","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a9a3a0039b8d737bb1d23d2ad51a85996ba86bb6","unresolved":false,"context_lines":[{"line_number":1156,"context_line":"        params \u003d params or {}"},{"line_number":1157,"context_line":"        params.setdefault(\u0027format\u0027, \u0027json\u0027)"},{"line_number":1158,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":1159,"context_line":"                   \u0027X-Backend-Record-Shard-Format\u0027: \u0027full\u0027,"},{"line_number":1160,"context_line":"                   \u0027X-Backend-Override-Deleted\u0027: \u0027true\u0027,"},{"line_number":1161,"context_line":"                   \u0027X-Backend-Include-Deleted\u0027: str(include_deleted)}"},{"line_number":1162,"context_line":"        if newest:"}],"source_content_type":"text/x-python","patch_set":13,"id":"eba81215_86ae8482","line":1159,"in_reply_to":"7e0b8150_336c18d8","updated":"2023-10-13 17:07:53.000000000","message":"Ack","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":1179,"context_line":"        params \u003d params or {}"},{"line_number":1180,"context_line":"        params.setdefault(\u0027format\u0027, \u0027json\u0027)"},{"line_number":1181,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":1182,"context_line":"                   \u0027X-Backend-Record-Shard-Format\u0027: \u0027full\u0027,"},{"line_number":1183,"context_line":"                   \u0027X-Backend-Override-Deleted\u0027: \u0027true\u0027,"},{"line_number":1184,"context_line":"                   \u0027X-Backend-Include-Deleted\u0027: str(include_deleted)}"},{"line_number":1185,"context_line":"        if newest:"}],"source_content_type":"text/x-python","patch_set":17,"id":"6dd21fdf_1e4c197f","line":1182,"updated":"2023-11-01 00:22:45.000000000","message":"nice and explicit!","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a4e9c34eef2afee5a89bbc4cb388d0eda8f024f4","unresolved":false,"context_lines":[{"line_number":1179,"context_line":"        params \u003d params or {}"},{"line_number":1180,"context_line":"        params.setdefault(\u0027format\u0027, \u0027json\u0027)"},{"line_number":1181,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":1182,"context_line":"                   \u0027X-Backend-Record-Shard-Format\u0027: \u0027full\u0027,"},{"line_number":1183,"context_line":"                   \u0027X-Backend-Override-Deleted\u0027: \u0027true\u0027,"},{"line_number":1184,"context_line":"                   \u0027X-Backend-Include-Deleted\u0027: str(include_deleted)}"},{"line_number":1185,"context_line":"        if newest:"}],"source_content_type":"text/x-python","patch_set":17,"id":"5cf4e56f_3f6933d3","line":1182,"in_reply_to":"6dd21fdf_1e4c197f","updated":"2023-11-21 12:04:27.000000000","message":"Acknowledged","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"}],"swift/proxy/controllers/base.py":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f5280514b9dfe7c2242073e1609e7ae5f6378b72","unresolved":true,"context_lines":[{"line_number":2430,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2431,"context_line":"            # this line can be removed as soon as the container server"},{"line_number":2432,"context_line":"            # supports get_namespaces api supports includes."},{"line_number":2433,"context_line":"            headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":2434,"context_line":"        if states:"},{"line_number":2435,"context_line":"            params[\u0027states\u0027] \u003d states"},{"line_number":2436,"context_line":"        listing, response \u003d self._get_container_listing("}],"source_content_type":"text/x-python","patch_set":1,"id":"832c7d58_b60d3b9d","line":2433,"updated":"2023-09-18 08:31:53.000000000","message":"This \"should\" mean obj PUT container updates that take the no memcache path to still ask for shardranges, as they pass in the includes. Once the container-server get-namespace API grows the includes we should just need to remove this line.","commit_id":"f2753a1159d0403249f55af8cc889322ca9d5480"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ccd698c7b2d81ee57fb4dcffd89df7eb64aeb9b3","unresolved":false,"context_lines":[{"line_number":2430,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2431,"context_line":"            # this line can be removed as soon as the container server"},{"line_number":2432,"context_line":"            # supports get_namespaces api supports includes."},{"line_number":2433,"context_line":"            headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":2434,"context_line":"        if states:"},{"line_number":2435,"context_line":"            params[\u0027states\u0027] \u003d states"},{"line_number":2436,"context_line":"        listing, response \u003d self._get_container_listing("}],"source_content_type":"text/x-python","patch_set":1,"id":"66d9d4e3_a5ec63cf","line":2433,"in_reply_to":"832c7d58_b60d3b9d","updated":"2023-09-21 21:14:48.000000000","message":"Ack","commit_id":"f2753a1159d0403249f55af8cc889322ca9d5480"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71784d9354753c2ee9079f57b6b14b94c4c2c6bd","unresolved":true,"context_lines":[{"line_number":2398,"context_line":"            return None"},{"line_number":2399,"context_line":""},{"line_number":2400,"context_line":"        record_type \u003d response.headers.get(\u0027x-backend-record-type\u0027)"},{"line_number":2401,"context_line":"        if record_type not in (\u0027shard\u0027, \u0027namespace\u0027):"},{"line_number":2402,"context_line":"            err \u003d \u0027unexpected record type %r\u0027 % record_type"},{"line_number":2403,"context_line":"            self.logger.error(\"Failed to get shard ranges from %s: %s\","},{"line_number":2404,"context_line":"                              req.path_qs, err)"}],"source_content_type":"text/x-python","patch_set":9,"id":"2c7f94a1_af3d1613","line":2401,"updated":"2023-09-28 15:53:49.000000000","message":"We ask for record_type \u003d \u0027shard\u0027, but server returns record_type \u003d \u0027namespace\u0027? I think it would be much more intuitive is server returned record_type \u003d shard and (if upgraded) shard_format\u003dnamespace.\n\ni.e. let\u0027s preserve the symmetry of headers proxy-\u003ebackend and backend-\u003eproxy","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7847654d3c5c3d22730bbcc317fade233f2fc9bd","unresolved":false,"context_lines":[{"line_number":2398,"context_line":"            return None"},{"line_number":2399,"context_line":""},{"line_number":2400,"context_line":"        record_type \u003d response.headers.get(\u0027x-backend-record-type\u0027)"},{"line_number":2401,"context_line":"        if record_type not in (\u0027shard\u0027, \u0027namespace\u0027):"},{"line_number":2402,"context_line":"            err \u003d \u0027unexpected record type %r\u0027 % record_type"},{"line_number":2403,"context_line":"            self.logger.error(\"Failed to get shard ranges from %s: %s\","},{"line_number":2404,"context_line":"                              req.path_qs, err)"}],"source_content_type":"text/x-python","patch_set":9,"id":"8f62c9cf_d8294767","line":2401,"in_reply_to":"2c7f94a1_af3d1613","updated":"2023-09-29 18:05:40.000000000","message":"Done","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71784d9354753c2ee9079f57b6b14b94c4c2c6bd","unresolved":true,"context_lines":[{"line_number":2409,"context_line":"            # namespaces only has \u0027name\u0027, \u0027lower\u0027 and \u0027upper\u0027 keys. We"},{"line_number":2410,"context_line":"            # therefore cannot use ShardRange.from_dict(). So forced to use"},{"line_number":2411,"context_line":"            # the constructor"},{"line_number":2412,"context_line":"            return [ShardRange(**data) for data in listing]"},{"line_number":2413,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2414,"context_line":"            self.logger.error("},{"line_number":2415,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","}],"source_content_type":"text/x-python","patch_set":9,"id":"41bed168_17482e0c","line":2412,"updated":"2023-09-28 15:53:49.000000000","message":"why are we still constructing ShardRanges when we know they may not (after upgrade) be completely populated? It seems risky that this method is still pretending to return ShardRanges.\n\nFor clarity, I think we should rename all the methods that are now going to return namespaces e.g. _parse_shard_ranges, _get_shard_ranges","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1789bba8cd72538246985f115d09d223572b199c","unresolved":true,"context_lines":[{"line_number":2409,"context_line":"            # namespaces only has \u0027name\u0027, \u0027lower\u0027 and \u0027upper\u0027 keys. We"},{"line_number":2410,"context_line":"            # therefore cannot use ShardRange.from_dict(). So forced to use"},{"line_number":2411,"context_line":"            # the constructor"},{"line_number":2412,"context_line":"            return [ShardRange(**data) for data in listing]"},{"line_number":2413,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2414,"context_line":"            self.logger.error("},{"line_number":2415,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","}],"source_content_type":"text/x-python","patch_set":9,"id":"47841933_ee9e5165","line":2412,"in_reply_to":"41bed168_17482e0c","updated":"2023-10-02 18:19:03.000000000","message":"both the object updating and container listing use this method to process response body from backend, so upgraded proxy is OK to receive only namespaces or shard ranges","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ded64fafb800e6a79f835f524d4be423dc54b157","unresolved":false,"context_lines":[{"line_number":2409,"context_line":"            # namespaces only has \u0027name\u0027, \u0027lower\u0027 and \u0027upper\u0027 keys. We"},{"line_number":2410,"context_line":"            # therefore cannot use ShardRange.from_dict(). So forced to use"},{"line_number":2411,"context_line":"            # the constructor"},{"line_number":2412,"context_line":"            return [ShardRange(**data) for data in listing]"},{"line_number":2413,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2414,"context_line":"            self.logger.error("},{"line_number":2415,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","}],"source_content_type":"text/x-python","patch_set":9,"id":"9c1cd1f9_7dd54503","line":2412,"in_reply_to":"47841933_ee9e5165","updated":"2023-10-02 18:24:58.000000000","message":"Ack","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71784d9354753c2ee9079f57b6b14b94c4c2c6bd","unresolved":true,"context_lines":[{"line_number":2436,"context_line":"        params.pop(\u0027limit\u0027, None)"},{"line_number":2437,"context_line":"        params[\u0027format\u0027] \u003d \u0027json\u0027"},{"line_number":2438,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":2439,"context_line":"                   \u0027X-Backend-Record-Shard-Format\u0027: \u0027namespace\u0027}"},{"line_number":2440,"context_line":"        if includes:"},{"line_number":2441,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2442,"context_line":"            # this line can be removed as soon as the container server"}],"source_content_type":"text/x-python","patch_set":9,"id":"3330e48e_bed759eb","line":2439,"range":{"start_line":2439,"start_character":19,"end_line":2439,"end_character":63},"updated":"2023-09-28 15:53:49.000000000","message":"maybe just add an else at line 2445 rather than setting the key the resetting the key","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7847654d3c5c3d22730bbcc317fade233f2fc9bd","unresolved":false,"context_lines":[{"line_number":2436,"context_line":"        params.pop(\u0027limit\u0027, None)"},{"line_number":2437,"context_line":"        params[\u0027format\u0027] \u003d \u0027json\u0027"},{"line_number":2438,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":2439,"context_line":"                   \u0027X-Backend-Record-Shard-Format\u0027: \u0027namespace\u0027}"},{"line_number":2440,"context_line":"        if includes:"},{"line_number":2441,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2442,"context_line":"            # this line can be removed as soon as the container server"}],"source_content_type":"text/x-python","patch_set":9,"id":"d0783247_38452741","line":2439,"range":{"start_line":2439,"start_character":19,"end_line":2439,"end_character":63},"in_reply_to":"3330e48e_bed759eb","updated":"2023-09-29 18:05:40.000000000","message":"on the other hand, I can see that this does highlight the ancticipation that the backend support will one day support includes for namespaces","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71784d9354753c2ee9079f57b6b14b94c4c2c6bd","unresolved":true,"context_lines":[{"line_number":2440,"context_line":"        if includes:"},{"line_number":2441,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2442,"context_line":"            # this line can be removed as soon as the container server"},{"line_number":2443,"context_line":"            # supports get_namespaces api supports includes."},{"line_number":2444,"context_line":"            headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":2445,"context_line":"        if states:"},{"line_number":2446,"context_line":"            params[\u0027states\u0027] \u003d states"}],"source_content_type":"text/x-python","patch_set":9,"id":"6409d8cf_8c14adf6","line":2443,"range":{"start_line":2443,"start_character":42,"end_line":2443,"end_character":50},"updated":"2023-09-28 15:53:49.000000000","message":"nit: there\u0027s one too many supports in this sentence :)","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2a73982e2aeb37c4de3aaccd988a4a94da3d7fe3","unresolved":false,"context_lines":[{"line_number":2440,"context_line":"        if includes:"},{"line_number":2441,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2442,"context_line":"            # this line can be removed as soon as the container server"},{"line_number":2443,"context_line":"            # supports get_namespaces api supports includes."},{"line_number":2444,"context_line":"            headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":2445,"context_line":"        if states:"},{"line_number":2446,"context_line":"            params[\u0027states\u0027] \u003d states"}],"source_content_type":"text/x-python","patch_set":9,"id":"b5f756ea_92c730e2","line":2443,"range":{"start_line":2443,"start_character":42,"end_line":2443,"end_character":50},"in_reply_to":"6409d8cf_8c14adf6","updated":"2023-09-30 00:09:19.000000000","message":"Done","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71784d9354753c2ee9079f57b6b14b94c4c2c6bd","unresolved":true,"context_lines":[{"line_number":2441,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2442,"context_line":"            # this line can be removed as soon as the container server"},{"line_number":2443,"context_line":"            # supports get_namespaces api supports includes."},{"line_number":2444,"context_line":"            headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":2445,"context_line":"        if states:"},{"line_number":2446,"context_line":"            params[\u0027states\u0027] \u003d states"},{"line_number":2447,"context_line":"        listing, response \u003d self._get_container_listing("}],"source_content_type":"text/x-python","patch_set":9,"id":"493c1a44_e8c513ca","line":2444,"updated":"2023-09-28 15:53:49.000000000","message":"oh, so this method may or may not return full ShardRanges? that\u0027s confusing...","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ded64fafb800e6a79f835f524d4be423dc54b157","unresolved":false,"context_lines":[{"line_number":2441,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2442,"context_line":"            # this line can be removed as soon as the container server"},{"line_number":2443,"context_line":"            # supports get_namespaces api supports includes."},{"line_number":2444,"context_line":"            headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":2445,"context_line":"        if states:"},{"line_number":2446,"context_line":"            params[\u0027states\u0027] \u003d states"},{"line_number":2447,"context_line":"        listing, response \u003d self._get_container_listing("}],"source_content_type":"text/x-python","patch_set":9,"id":"726725a2_a4c615dc","line":2444,"in_reply_to":"0c1ea166_f7d761ab","updated":"2023-10-02 18:24:58.000000000","message":"Ack","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2a73982e2aeb37c4de3aaccd988a4a94da3d7fe3","unresolved":true,"context_lines":[{"line_number":2441,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2442,"context_line":"            # this line can be removed as soon as the container server"},{"line_number":2443,"context_line":"            # supports get_namespaces api supports includes."},{"line_number":2444,"context_line":"            headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":2445,"context_line":"        if states:"},{"line_number":2446,"context_line":"            params[\u0027states\u0027] \u003d states"},{"line_number":2447,"context_line":"        listing, response \u003d self._get_container_listing("}],"source_content_type":"text/x-python","patch_set":9,"id":"fe7422f5_336b9da6","line":2444,"in_reply_to":"493c1a44_e8c513ca","updated":"2023-09-30 00:09:19.000000000","message":"yeah, this line will be removed after backend get_namespaces supports \u0027includes\u0027. And we can rename _parse_shard_ranges and _get_shard_ranges at that step too.","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1789bba8cd72538246985f115d09d223572b199c","unresolved":true,"context_lines":[{"line_number":2441,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2442,"context_line":"            # this line can be removed as soon as the container server"},{"line_number":2443,"context_line":"            # supports get_namespaces api supports includes."},{"line_number":2444,"context_line":"            headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":2445,"context_line":"        if states:"},{"line_number":2446,"context_line":"            params[\u0027states\u0027] \u003d states"},{"line_number":2447,"context_line":"        listing, response \u003d self._get_container_listing("}],"source_content_type":"text/x-python","patch_set":9,"id":"0c1ea166_f7d761ab","line":2444,"in_reply_to":"fe7422f5_336b9da6","updated":"2023-10-02 18:19:03.000000000","message":"ok. note also: \"belt-and-braces\": backend will revert to format\u003dfull if it receives the includes param, so not-yet-upgraded proxy works with new backend and will still receive full shard ranges.","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1789bba8cd72538246985f115d09d223572b199c","unresolved":true,"context_lines":[{"line_number":2403,"context_line":""},{"line_number":2404,"context_line":"        try:"},{"line_number":2405,"context_line":"            return [ShardRange.from_dict(shard_range)"},{"line_number":2406,"context_line":"                    for shard_range in listing]"},{"line_number":2407,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2408,"context_line":"            self.logger.error("},{"line_number":2409,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","}],"source_content_type":"text/x-python","patch_set":13,"id":"357a2926_50b4639c","side":"PARENT","line":2406,"updated":"2023-10-02 18:19:03.000000000","message":"this is where an old proxy will blow up if the backend sends only namespaces - so backend MUST only send namespaces if the proxy explicitly requests them (which it does)","commit_id":"4bfbf4ae0835c433c2f7a24eb493407dd2a51783"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ded64fafb800e6a79f835f524d4be423dc54b157","unresolved":false,"context_lines":[{"line_number":2403,"context_line":""},{"line_number":2404,"context_line":"        try:"},{"line_number":2405,"context_line":"            return [ShardRange.from_dict(shard_range)"},{"line_number":2406,"context_line":"                    for shard_range in listing]"},{"line_number":2407,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2408,"context_line":"            self.logger.error("},{"line_number":2409,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","}],"source_content_type":"text/x-python","patch_set":13,"id":"ba72da49_0bcd9ed8","side":"PARENT","line":2406,"in_reply_to":"357a2926_50b4639c","updated":"2023-10-02 18:24:58.000000000","message":"Ack","commit_id":"4bfbf4ae0835c433c2f7a24eb493407dd2a51783"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"90a673a8ad489aafddd8b08d96078738fe630335","unresolved":true,"context_lines":[{"line_number":2406,"context_line":"            # dicts; namespaces only has \u0027name\u0027, \u0027lower\u0027 and \u0027upper\u0027 keys. We"},{"line_number":2407,"context_line":"            # therefore cannot use ShardRange.from_dict(). So forced to use the"},{"line_number":2408,"context_line":"            # constructor"},{"line_number":2409,"context_line":"            return [ShardRange(**data) for data in listing]"},{"line_number":2410,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2411,"context_line":"            self.logger.error("},{"line_number":2412,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","}],"source_content_type":"text/x-python","patch_set":13,"id":"78110612_f20c2cee","line":2409,"updated":"2023-10-03 19:34:35.000000000","message":"Do we actually *need* `ShardRange`s here in the proxy? Would it be better for us to be instantiating `Namespace`s instead, and rename this `_parse_namespaces`?","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":2406,"context_line":"            # dicts; namespaces only has \u0027name\u0027, \u0027lower\u0027 and \u0027upper\u0027 keys. We"},{"line_number":2407,"context_line":"            # therefore cannot use ShardRange.from_dict(). So forced to use the"},{"line_number":2408,"context_line":"            # constructor"},{"line_number":2409,"context_line":"            return [ShardRange(**data) for data in listing]"},{"line_number":2410,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2411,"context_line":"            self.logger.error("},{"line_number":2412,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","}],"source_content_type":"text/x-python","patch_set":13,"id":"c40c6038_750f1137","line":2409,"in_reply_to":"0ba26cc0_f9692cee","updated":"2023-11-01 00:22:45.000000000","message":"oh crap, i was going to test this and then got distracted\n\nit seems like it\u0027s related in some deep way to the proxy app sometimes returning a response to the client from *cache* (!?)\n\nI5fc696625d69d1ee9218ee2a508a1b9be6cf9685\n\n... which I guess is ok because the only client that actually gets this cached responses is either somehow it\u0027s own self when fetching shard ranges for object_update/container_listing or maybe internal client for something something sharder.\n\nI think at this point it would be nice if a InternalClient GET /a/c x-backend-record-type: shard request would always go to the backend and client facing object_updater/container_listing requests were somehow less \"recursive; but maybe the short term answer is \"here we should inspect the response and build what we have\" i.e. _parse_shard_resp","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0960193ee40acfa6ca82f4b52491e058a151bac4","unresolved":false,"context_lines":[{"line_number":2406,"context_line":"            # dicts; namespaces only has \u0027name\u0027, \u0027lower\u0027 and \u0027upper\u0027 keys. We"},{"line_number":2407,"context_line":"            # therefore cannot use ShardRange.from_dict(). So forced to use the"},{"line_number":2408,"context_line":"            # constructor"},{"line_number":2409,"context_line":"            return [ShardRange(**data) for data in listing]"},{"line_number":2410,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2411,"context_line":"            self.logger.error("},{"line_number":2412,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","}],"source_content_type":"text/x-python","patch_set":13,"id":"d102ada4_6b43c516","line":2409,"in_reply_to":"473362a9_921a97c9","updated":"2024-01-08 15:09:42.000000000","message":"Done","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"45473c69a61994b4c3c1791beaaa603da8ee27dc","unresolved":true,"context_lines":[{"line_number":2406,"context_line":"            # dicts; namespaces only has \u0027name\u0027, \u0027lower\u0027 and \u0027upper\u0027 keys. We"},{"line_number":2407,"context_line":"            # therefore cannot use ShardRange.from_dict(). So forced to use the"},{"line_number":2408,"context_line":"            # constructor"},{"line_number":2409,"context_line":"            return [ShardRange(**data) for data in listing]"},{"line_number":2410,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2411,"context_line":"            self.logger.error("},{"line_number":2412,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","}],"source_content_type":"text/x-python","patch_set":13,"id":"0ba26cc0_f9692cee","line":2409,"in_reply_to":"51248d0a_d8bb0ef8","updated":"2023-10-16 03:03:58.000000000","message":"it\u0027s still possible to return ShardRanges objects, either old ones or from the internal client from the sharder. Hmm, although maybe in the latter we can force it to bypass the cache, ie don\u0027t go down that path and just go straight to get_or_head_base, we\u0027d bypass this function all together. :hmm:","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"66bbcea7e52f1a311d685db87c4016194cf879b7","unresolved":true,"context_lines":[{"line_number":2406,"context_line":"            # dicts; namespaces only has \u0027name\u0027, \u0027lower\u0027 and \u0027upper\u0027 keys. We"},{"line_number":2407,"context_line":"            # therefore cannot use ShardRange.from_dict(). So forced to use the"},{"line_number":2408,"context_line":"            # constructor"},{"line_number":2409,"context_line":"            return [ShardRange(**data) for data in listing]"},{"line_number":2410,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2411,"context_line":"            self.logger.error("},{"line_number":2412,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","}],"source_content_type":"text/x-python","patch_set":13,"id":"51248d0a_d8bb0ef8","line":2409,"in_reply_to":"78110612_f20c2cee","updated":"2023-10-13 10:10:44.000000000","message":"Yes this! That is exactly what my other version did. But we decided to break it up into 2 steps. Once we get includes support I plan to write the second 1/2 of this patch that will basically use namespaces in the proxy, because they\u0027re lighter and only then turn to full shardrange objects for the sharder, via the internalclient interface.\n\nBut I\u0027m saving for the naming and refactoring when we can fully use Namespace objects basically as a drop in (ie marker, end_marker, reverse, includes support). Adding the account and container to the namepsace object (that the next patchset does) also goes a long way into allow us to drop in replace ShardRanges.","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a4e9c34eef2afee5a89bbc4cb388d0eda8f024f4","unresolved":true,"context_lines":[{"line_number":2406,"context_line":"            # dicts; namespaces only has \u0027name\u0027, \u0027lower\u0027 and \u0027upper\u0027 keys. We"},{"line_number":2407,"context_line":"            # therefore cannot use ShardRange.from_dict(). So forced to use the"},{"line_number":2408,"context_line":"            # constructor"},{"line_number":2409,"context_line":"            return [ShardRange(**data) for data in listing]"},{"line_number":2410,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2411,"context_line":"            self.logger.error("},{"line_number":2412,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","}],"source_content_type":"text/x-python","patch_set":13,"id":"473362a9_921a97c9","line":2409,"in_reply_to":"c40c6038_750f1137","updated":"2023-11-21 12:04:27.000000000","message":"Tim\u0027s point is dealt with in the follow on patch https://review.opendev.org/c/openstack/swift/+/900350/13/swift/proxy/controllers/base.py#2473\n\nClay\u0027s point is (IIUC) dealt with by https://review.opendev.org/c/openstack/swift/+/901335/ i.e. clean separation of GETs explicitly for shard ranges (e.g. from sharder IC) vs recursive GETs to build object listings - in that patch the proxy only parses namespaces when the proxy needs to use them.","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"90a673a8ad489aafddd8b08d96078738fe630335","unresolved":true,"context_lines":[{"line_number":2438,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2439,"context_line":"            # this line can be removed as soon as the container server"},{"line_number":2440,"context_line":"            # supports get_namespaces api with \u0027includes\u0027."},{"line_number":2441,"context_line":"            headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":2442,"context_line":"        if states:"},{"line_number":2443,"context_line":"            params[\u0027states\u0027] \u003d states"},{"line_number":2444,"context_line":"        listing, response \u003d self._get_container_listing("}],"source_content_type":"text/x-python","patch_set":13,"id":"8065855f_5ae7edc7","line":2441,"updated":"2023-10-03 19:34:35.000000000","message":"Good call -- alternatively, we could have something like\n```\nheaders \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027}\nif includes:\n    params[\u0027includes\u0027] \u003d str_to_wsgi(includes)\nelse:\n    headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027namespace\u0027\n```\n\\*shrug\\*","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"66bbcea7e52f1a311d685db87c4016194cf879b7","unresolved":false,"context_lines":[{"line_number":2438,"context_line":"            params[\u0027includes\u0027] \u003d str_to_wsgi(includes)"},{"line_number":2439,"context_line":"            # this line can be removed as soon as the container server"},{"line_number":2440,"context_line":"            # supports get_namespaces api with \u0027includes\u0027."},{"line_number":2441,"context_line":"            headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":2442,"context_line":"        if states:"},{"line_number":2443,"context_line":"            params[\u0027states\u0027] \u003d states"},{"line_number":2444,"context_line":"        listing, response \u003d self._get_container_listing("}],"source_content_type":"text/x-python","patch_set":13,"id":"3f8c4285_42e5da02","line":2441,"in_reply_to":"8065855f_5ae7edc7","updated":"2023-10-13 10:10:44.000000000","message":"yeah, totally. Just thought better to be explicit","commit_id":"0440b0c2f3cf1badbccca454600ab08df8c47232"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":2361,"context_line":"            return None"},{"line_number":2362,"context_line":""},{"line_number":2363,"context_line":"    def _get_container_listing(self, req, account, container, headers\u003dNone,"},{"line_number":2364,"context_line":"                               params\u003dNone):"},{"line_number":2365,"context_line":"        \"\"\""},{"line_number":2366,"context_line":"        Fetch container listing from given `account/container`."},{"line_number":2367,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"30b7ac4d_e5bcc3e8","line":2364,"updated":"2023-11-01 00:22:45.000000000","message":"this is the main entry point for controller.container when it\u0027s fetching listings form shards; controller.object also gets here by way of _get_shard_ranges when container_info tells it the object is sharded.","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a4e9c34eef2afee5a89bbc4cb388d0eda8f024f4","unresolved":false,"context_lines":[{"line_number":2361,"context_line":"            return None"},{"line_number":2362,"context_line":""},{"line_number":2363,"context_line":"    def _get_container_listing(self, req, account, container, headers\u003dNone,"},{"line_number":2364,"context_line":"                               params\u003dNone):"},{"line_number":2365,"context_line":"        \"\"\""},{"line_number":2366,"context_line":"        Fetch container listing from given `account/container`."},{"line_number":2367,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"23b72436_d86fd2bc","line":2364,"in_reply_to":"30b7ac4d_e5bcc3e8","updated":"2023-11-21 12:04:27.000000000","message":"Acknowledged","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":2386,"context_line":"        subreq.params \u003d params"},{"line_number":2387,"context_line":"        self.logger.debug("},{"line_number":2388,"context_line":"            \u0027Get listing from %s %s\u0027 % (subreq.path_qs, headers))"},{"line_number":2389,"context_line":"        response \u003d self.app.handle_request(subreq)"},{"line_number":2390,"context_line":"        data \u003d self._parse_listing_response(req, response)"},{"line_number":2391,"context_line":"        return data, response"},{"line_number":2392,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"39681d7d_7e4d20ee","line":2389,"updated":"2023-11-01 00:22:45.000000000","message":"this is what makes me call this routing \"recursive\" - we\u0027re in a [Object|Container]Controller but then we punt all the way back up to the app - which might make up it\u0027s response from cache.","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a4e9c34eef2afee5a89bbc4cb388d0eda8f024f4","unresolved":false,"context_lines":[{"line_number":2386,"context_line":"        subreq.params \u003d params"},{"line_number":2387,"context_line":"        self.logger.debug("},{"line_number":2388,"context_line":"            \u0027Get listing from %s %s\u0027 % (subreq.path_qs, headers))"},{"line_number":2389,"context_line":"        response \u003d self.app.handle_request(subreq)"},{"line_number":2390,"context_line":"        data \u003d self._parse_listing_response(req, response)"},{"line_number":2391,"context_line":"        return data, response"},{"line_number":2392,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"6f182b93_e4ff3482","line":2389,"in_reply_to":"39681d7d_7e4d20ee","updated":"2023-11-21 12:04:27.000000000","message":"Acknowledged","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":2410,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2411,"context_line":"            self.logger.error("},{"line_number":2412,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","},{"line_number":2413,"context_line":"                req.path_qs, err)"},{"line_number":2414,"context_line":"            return None"},{"line_number":2415,"context_line":""},{"line_number":2416,"context_line":"    def _get_shard_ranges("}],"source_content_type":"text/x-python","patch_set":17,"id":"aea02a93_3ffe3934","line":2413,"updated":"2023-11-01 00:22:45.000000000","message":"it seems there\u0027s a number of things that can go wrong with parsing (Value, Type, Key) - but actually the repr(err) might not be that helpful (we probably can\u0027t log all the contents of listing)","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a4e9c34eef2afee5a89bbc4cb388d0eda8f024f4","unresolved":false,"context_lines":[{"line_number":2410,"context_line":"        except (ValueError, TypeError, KeyError) as err:"},{"line_number":2411,"context_line":"            self.logger.error("},{"line_number":2412,"context_line":"                \"Failed to get shard ranges from %s: invalid data: %r\","},{"line_number":2413,"context_line":"                req.path_qs, err)"},{"line_number":2414,"context_line":"            return None"},{"line_number":2415,"context_line":""},{"line_number":2416,"context_line":"    def _get_shard_ranges("}],"source_content_type":"text/x-python","patch_set":17,"id":"38f5b1dc_c4798d6c","line":2413,"in_reply_to":"aea02a93_3ffe3934","updated":"2023-11-21 12:04:27.000000000","message":"Acknowledged","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"}],"swift/proxy/controllers/container.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7534082519b2bbd0982414a3bac92c65dc67ed52","unresolved":false,"context_lines":[{"line_number":489,"context_line":"        # Ideally we would construct Namespace objects here, but later we use"},{"line_number":490,"context_line":"        # the ShardRange account and container properties to access parsed"},{"line_number":491,"context_line":"        # parts of the name."},{"line_number":492,"context_line":"        shard_ranges \u003d [ShardRange(**data) for data in json.loads(resp.body)]"},{"line_number":493,"context_line":"        self.logger.debug(\u0027GET listing from %s shards for: %s\u0027,"},{"line_number":494,"context_line":"                          len(shard_ranges), req.path_qs)"},{"line_number":495,"context_line":"        if not shard_ranges:"}],"source_content_type":"text/x-python","patch_set":3,"id":"048a2f47_916a5a85","line":492,"updated":"2023-09-18 22:42:49.000000000","message":"it\u0027s already using \"ShardRange(**data)\", so this could handle both ShardRange and Namespace as well.","commit_id":"58f0527f3f06cb445f7fb7748bb1fb8c0078e1e3"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"eb81a128cc3188911311b3f2b8353d59693563e6","unresolved":true,"context_lines":[{"line_number":104,"context_line":"        # these, yet.. once it does we can remove this."},{"line_number":105,"context_line":"        if \u0027marker\u0027 in req.params or \u0027end_marker\u0027 in req.params or \\"},{"line_number":106,"context_line":"                \u0027includes\u0027 in req.params or \u0027reverse\u0027 in req.params:"},{"line_number":107,"context_line":"            req.headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":108,"context_line":"        part \u003d self.app.container_ring.get_part("},{"line_number":109,"context_line":"            self.account_name, self.container_name)"},{"line_number":110,"context_line":"        concurrency \u003d self.app.container_ring.replica_count \\"}],"source_content_type":"text/x-python","patch_set":6,"id":"0a93118b_73865471","line":107,"updated":"2023-09-20 06:41:54.000000000","message":"I don\u0027t like this, but leaving it in for now as it means probe tests will pass. Just randomally hacked this while debugging the probe tests.\n\nThe probe tests fail because the container get_namespaces API doesn\u0027t support reverse, but added the other params it also doesn\u0027t support.\n\n@jianjian, reverse might be another we need to add to your follow up patch.","commit_id":"71bb6bec31ea87c18d52ed9dcb384b07ba6e742b"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"8d2c4eca93460556e260e2c9e412eb5904b6c41a","unresolved":false,"context_lines":[{"line_number":104,"context_line":"        # these, yet.. once it does we can remove this."},{"line_number":105,"context_line":"        if \u0027marker\u0027 in req.params or \u0027end_marker\u0027 in req.params or \\"},{"line_number":106,"context_line":"                \u0027includes\u0027 in req.params or \u0027reverse\u0027 in req.params:"},{"line_number":107,"context_line":"            req.headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027full\u0027"},{"line_number":108,"context_line":"        part \u003d self.app.container_ring.get_part("},{"line_number":109,"context_line":"            self.account_name, self.container_name)"},{"line_number":110,"context_line":"        concurrency \u003d self.app.container_ring.replica_count \\"}],"source_content_type":"text/x-python","patch_set":6,"id":"9572073d_a48906d9","line":107,"in_reply_to":"0a93118b_73865471","updated":"2023-09-21 05:08:01.000000000","message":"I updated get namespace patch to not support \"reverse\" explicitly, then we should be able to pass those failed probe tests.","commit_id":"71bb6bec31ea87c18d52ed9dcb384b07ba6e742b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71784d9354753c2ee9079f57b6b14b94c4c2c6bd","unresolved":true,"context_lines":[{"line_number":384,"context_line":"        if not record_type:"},{"line_number":385,"context_line":"            record_type \u003d \u0027auto\u0027"},{"line_number":386,"context_line":"            req.headers[\u0027X-Backend-Record-Type\u0027] \u003d \u0027auto\u0027"},{"line_number":387,"context_line":"            # The sharder explicitly uses a record_type, so a normal listing"},{"line_number":388,"context_line":"            # should attempt to return namespaces where possible, so set the"},{"line_number":389,"context_line":"            # shard-format incase we end up talking to a sharding/sharded"},{"line_number":390,"context_line":"            # container."},{"line_number":391,"context_line":"            req.headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027namespace\u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"29ea5024_8e91e909","line":388,"range":{"start_line":387,"start_character":57,"end_line":388,"end_character":64},"updated":"2023-09-28 15:53:49.000000000","message":"this comment confused me: a \"normal listing\" returns  objects, but the proxy needs to discover of the backend is sharded and be prepared to transform a list of namespace to a list of objects\n\nBut, I think maybe what\u0027s important to convey here is that if the API caller didn\u0027t explicitly specify record-type then the proxy is going to request namespaces, because that\u0027s what the proxy wants.","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7847654d3c5c3d22730bbcc317fade233f2fc9bd","unresolved":false,"context_lines":[{"line_number":384,"context_line":"        if not record_type:"},{"line_number":385,"context_line":"            record_type \u003d \u0027auto\u0027"},{"line_number":386,"context_line":"            req.headers[\u0027X-Backend-Record-Type\u0027] \u003d \u0027auto\u0027"},{"line_number":387,"context_line":"            # The sharder explicitly uses a record_type, so a normal listing"},{"line_number":388,"context_line":"            # should attempt to return namespaces where possible, so set the"},{"line_number":389,"context_line":"            # shard-format incase we end up talking to a sharding/sharded"},{"line_number":390,"context_line":"            # container."},{"line_number":391,"context_line":"            req.headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027namespace\u0027"}],"source_content_type":"text/x-python","patch_set":9,"id":"4a8cb644_03a25075","line":388,"range":{"start_line":387,"start_character":57,"end_line":388,"end_character":64},"in_reply_to":"29ea5024_8e91e909","updated":"2023-09-29 18:05:40.000000000","message":"Done","commit_id":"3d99b2b73c246d4ce07fa99a75bf42b6c7293ca1"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":291,"context_line":"            ns_bound_list \u003d self._store_shard_ranges_in_cache(req, resp)"},{"line_number":292,"context_line":"            if ns_bound_list:"},{"line_number":293,"context_line":"                resp.body \u003d self._make_namespaces_response_body("},{"line_number":294,"context_line":"                    req, ns_bound_list)"},{"line_number":295,"context_line":"        return resp"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"    def _record_shard_listing_cache_metrics("}],"source_content_type":"text/x-python","patch_set":17,"id":"52b03821_1c27f23a","line":294,"updated":"2023-11-01 00:22:45.000000000","message":"so here storing in cache is a side-effect of recieving a full shard range listing\n\nbut presumably regardless of record-format\u003dshard or record-format\u003dnamesapce we only always cache the minimal namespace objects\n\nI\u0027m less clear why we manipulate the resp.body","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a4e9c34eef2afee5a89bbc4cb388d0eda8f024f4","unresolved":false,"context_lines":[{"line_number":291,"context_line":"            ns_bound_list \u003d self._store_shard_ranges_in_cache(req, resp)"},{"line_number":292,"context_line":"            if ns_bound_list:"},{"line_number":293,"context_line":"                resp.body \u003d self._make_namespaces_response_body("},{"line_number":294,"context_line":"                    req, ns_bound_list)"},{"line_number":295,"context_line":"        return resp"},{"line_number":296,"context_line":""},{"line_number":297,"context_line":"    def _record_shard_listing_cache_metrics("}],"source_content_type":"text/x-python","patch_set":17,"id":"48900592_8a846c2b","line":294,"in_reply_to":"52b03821_1c27f23a","updated":"2023-11-21 12:04:27.000000000","message":"\u003e I\u0027m less clear why we manipulate the resp.body\n\ndealt with in 901335: proxy: only use listing shards cache for \u0027auto\u0027 listings | https://review.opendev.org/c/openstack/swift/+/901335 - that patch stops re-writing the response body, once we have a list of namespaces from cache or backend it is just passed to _get_from_shards","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":392,"context_line":"            # ranges (e.g. the sharder) would have set X-Backend-Record-Type."},{"line_number":393,"context_line":"            record_type \u003d \u0027auto\u0027"},{"line_number":394,"context_line":"            req.headers[\u0027X-Backend-Record-Type\u0027] \u003d \u0027auto\u0027"},{"line_number":395,"context_line":"            req.headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027namespace\u0027"},{"line_number":396,"context_line":"            params[\u0027states\u0027] \u003d \u0027listing\u0027"},{"line_number":397,"context_line":"        req.params \u003d params"},{"line_number":398,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"98f68b7c_cc3d3115","line":395,"updated":"2023-11-01 00:22:45.000000000","message":"presumably this new header has no effect on _GET_using_cache.  Hopefully all the places already not setting record-type were expecting record-type\u003dauto responses and will be fine with record-type\u003dnamespace","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a4e9c34eef2afee5a89bbc4cb388d0eda8f024f4","unresolved":false,"context_lines":[{"line_number":392,"context_line":"            # ranges (e.g. the sharder) would have set X-Backend-Record-Type."},{"line_number":393,"context_line":"            record_type \u003d \u0027auto\u0027"},{"line_number":394,"context_line":"            req.headers[\u0027X-Backend-Record-Type\u0027] \u003d \u0027auto\u0027"},{"line_number":395,"context_line":"            req.headers[\u0027X-Backend-Record-Shard-Format\u0027] \u003d \u0027namespace\u0027"},{"line_number":396,"context_line":"            params[\u0027states\u0027] \u003d \u0027listing\u0027"},{"line_number":397,"context_line":"        req.params \u003d params"},{"line_number":398,"context_line":""}],"source_content_type":"text/x-python","patch_set":17,"id":"d3751d1d_e82f01b6","line":395,"in_reply_to":"98f68b7c_cc3d3115","updated":"2023-11-21 12:04:27.000000000","message":"it does affect _GET_using_cache, because that method may end up fetching shards from the backend and will now ask for namespace format.\n\nAny call not specifying a record type should get back objects, the format is only relevant to the proxy fetching shards to build the object listing.\n\nAll much clearer in 901335: proxy: only use listing shards cache for \u0027auto\u0027 listings | https://review.opendev.org/c/openstack/swift/+/901335","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0960193ee40acfa6ca82f4b52491e058a151bac4","unresolved":true,"context_lines":[{"line_number":376,"context_line":"                    self.logger.info("},{"line_number":377,"context_line":"                        \u0027Caching updating shards for %s (%d shards)\u0027,"},{"line_number":378,"context_line":"                        cache_key, len(namespaces))"},{"line_number":379,"context_line":"            update_shard_ns \u003d find_namespace(obj, namespaces or [])"},{"line_number":380,"context_line":"        record_cache_op_metrics("},{"line_number":381,"context_line":"            self.logger, self.server_type.lower(), \u0027shard_updating\u0027,"},{"line_number":382,"context_line":"            get_cache_state, response)"}],"source_content_type":"text/x-python","patch_set":40,"id":"6ea6c112_626b421f","line":379,"updated":"2024-01-08 15:09:42.000000000","message":"I think there may have been a comment on the now-squashed-in patch about using ns_bound_list.get_namespace here rather than find_namespace. It would at least result in more consistent code.","commit_id":"5d322113a3e118fbe66a4c811910afe3c22b1702"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"b8d0f20d59a6b772420f331e3665afc0135cb0df","unresolved":false,"context_lines":[{"line_number":376,"context_line":"                    self.logger.info("},{"line_number":377,"context_line":"                        \u0027Caching updating shards for %s (%d shards)\u0027,"},{"line_number":378,"context_line":"                        cache_key, len(namespaces))"},{"line_number":379,"context_line":"            update_shard_ns \u003d find_namespace(obj, namespaces or [])"},{"line_number":380,"context_line":"        record_cache_op_metrics("},{"line_number":381,"context_line":"            self.logger, self.server_type.lower(), \u0027shard_updating\u0027,"},{"line_number":382,"context_line":"            get_cache_state, response)"}],"source_content_type":"text/x-python","patch_set":40,"id":"bfca9f80_be1d16c3","line":379,"in_reply_to":"6ea6c112_626b421f","updated":"2024-01-09 05:42:46.000000000","message":"Yes! ``ns_bound_list.get_namespace`` is also faster than ``find_namespace``, nice change.","commit_id":"5d322113a3e118fbe66a4c811910afe3c22b1702"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f869ec9474eef008226b943cc2cbd8d181c65ed","unresolved":true,"context_lines":[{"line_number":344,"context_line":"        :return: an instance of :class:`swift.common.utils.Namespace`,"},{"line_number":345,"context_line":"            or None if the update should go back to the root"},{"line_number":346,"context_line":"        \"\"\""},{"line_number":347,"context_line":"        if not self.app.recheck_updating_shard_ranges:"},{"line_number":348,"context_line":"            # caching is disabled"},{"line_number":349,"context_line":"            return self._get_update_shard_caching_disabled("},{"line_number":350,"context_line":"                req, account, container, obj)"}],"source_content_type":"text/x-python","patch_set":43,"id":"0e6e018b_5727882a","line":347,"updated":"2024-01-09 15:24:22.000000000","message":"off-topic: (existing behaviour-\u003e fix in follow up) we\u0027re not checking that memcache is available here, so if recheck_updating_shard_ranges\u003e0 but there\u0027s no memcache we still fetch all namespaces.\n\nfix here https://review.opendev.org/c/openstack/swift/+/905112","commit_id":"61a31e676dd3ba559e9a9f4b59472cc52a73df12"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b6dbfa7f92aa86dc78a9c8d6bfc8076917c1e4f2","unresolved":false,"context_lines":[{"line_number":344,"context_line":"        :return: an instance of :class:`swift.common.utils.Namespace`,"},{"line_number":345,"context_line":"            or None if the update should go back to the root"},{"line_number":346,"context_line":"        \"\"\""},{"line_number":347,"context_line":"        if not self.app.recheck_updating_shard_ranges:"},{"line_number":348,"context_line":"            # caching is disabled"},{"line_number":349,"context_line":"            return self._get_update_shard_caching_disabled("},{"line_number":350,"context_line":"                req, account, container, obj)"}],"source_content_type":"text/x-python","patch_set":43,"id":"d4a05259_9905d1a7","line":347,"in_reply_to":"0e6e018b_5727882a","updated":"2024-01-11 10:45:45.000000000","message":"Acknowledged","commit_id":"61a31e676dd3ba559e9a9f4b59472cc52a73df12"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a10c6485a1ca707650e22e8918aec52a7d9695ca","unresolved":true,"context_lines":[{"line_number":7477,"context_line":"            self.assertEqual(namespaces[i].name,"},{"line_number":7478,"context_line":"                             \u0027.shards_a/c_%s\u0027 % bounds[i][1])"},{"line_number":7479,"context_line":"            self.assertEqual(namespaces[i].lower_str, bounds[i][0])"},{"line_number":7480,"context_line":"            self.assertEqual(namespaces[i].upper_str, bounds[i][1])"},{"line_number":7481,"context_line":""},{"line_number":7482,"context_line":"    def test_entire_namespace(self):"},{"line_number":7483,"context_line":"        # test entire range (no boundaries)"}],"source_content_type":"text/x-python","patch_set":12,"id":"6f758c45_5137fd28","line":7480,"updated":"2023-10-02 14:35:17.000000000","message":"so this seems to have been an existing bug? but I haven\u0027t been able to provoke it on master - perhaps because Namespaces are only ever instantiated using the properties of a ShardRange??? i.e. in practice we\u0027ve always created a ShardRange, and therefore encoded the name, before creating a Namespace from the encoded name.","commit_id":"7476f4bc3a86879a41495fa89445a2107a0779ba"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ded64fafb800e6a79f835f524d4be423dc54b157","unresolved":false,"context_lines":[{"line_number":7477,"context_line":"            self.assertEqual(namespaces[i].name,"},{"line_number":7478,"context_line":"                             \u0027.shards_a/c_%s\u0027 % bounds[i][1])"},{"line_number":7479,"context_line":"            self.assertEqual(namespaces[i].lower_str, bounds[i][0])"},{"line_number":7480,"context_line":"            self.assertEqual(namespaces[i].upper_str, bounds[i][1])"},{"line_number":7481,"context_line":""},{"line_number":7482,"context_line":"    def test_entire_namespace(self):"},{"line_number":7483,"context_line":"        # test entire range (no boundaries)"}],"source_content_type":"text/x-python","patch_set":12,"id":"a00cb36c_3e71876d","line":7480,"in_reply_to":"6f758c45_5137fd28","updated":"2023-10-02 18:24:58.000000000","message":"For cases other than creating a Namespace from ShardRange encoded names, we encode those names before we use them to create Namespace objects. See:\nhttps://github.com/NVIDIA/swift/blob/master/swift/proxy/controllers/container.py#L177\nhttps://github.com/NVIDIA/swift/blob/master/swift/proxy/controllers/obj.py#L320\nI won\u0027t call it a bug, since even upstream users won\u0027t run into it? it will only show up with this new patch, so I feel it\u0027s okay to include it within this patch.","commit_id":"7476f4bc3a86879a41495fa89445a2107a0779ba"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":7488,"context_line":"            exp_bounds \u003d bounds"},{"line_number":7489,"context_line":"        for i in range(len(exp_bounds)):"},{"line_number":7490,"context_line":"            self.assertEqual(namespaces[i].name,"},{"line_number":7491,"context_line":"                             \u0027.shards_a/c_%s\u0027 % exp_bounds[i][1])"},{"line_number":7492,"context_line":"            self.assertEqual(namespaces[i].lower_str, exp_bounds[i][0])"},{"line_number":7493,"context_line":""},{"line_number":7494,"context_line":"            self.assertEqual(namespaces[i].upper_str, exp_bounds[i][1])"}],"source_content_type":"text/x-python","patch_set":17,"id":"aeefb645_3b344985","line":7491,"updated":"2023-11-01 00:22:45.000000000","message":"these tests don\u0027t really make it obvious that Namespace shouldn\u0027t have account/container attributes.","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"}],"test/unit/container/test_sharder.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":6336,"context_line":"                        sharder, \u0027int_client\u0027) as mock_swift:"},{"line_number":6337,"context_line":"                mock_response \u003d mock.MagicMock()"},{"line_number":6338,"context_line":"                mock_response.headers \u003d {\u0027x-backend-record-type\u0027:"},{"line_number":6339,"context_line":"                                         \u0027shard\u0027}"},{"line_number":6340,"context_line":"                shard_ranges.sort(key\u003dShardRange.sort_key)"},{"line_number":6341,"context_line":"                mock_response.body \u003d json.dumps("},{"line_number":6342,"context_line":"                    [dict(sr) for sr in shard_ranges])"}],"source_content_type":"text/x-python","patch_set":17,"id":"bc5a282f_c783ff88","line":6339,"updated":"2023-11-01 00:22:45.000000000","message":"we could maybe add an explict record-format here too","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"65e5029e2abf4abc5f7d463a399551755bfae14a","unresolved":false,"context_lines":[{"line_number":6336,"context_line":"                        sharder, \u0027int_client\u0027) as mock_swift:"},{"line_number":6337,"context_line":"                mock_response \u003d mock.MagicMock()"},{"line_number":6338,"context_line":"                mock_response.headers \u003d {\u0027x-backend-record-type\u0027:"},{"line_number":6339,"context_line":"                                         \u0027shard\u0027}"},{"line_number":6340,"context_line":"                shard_ranges.sort(key\u003dShardRange.sort_key)"},{"line_number":6341,"context_line":"                mock_response.body \u003d json.dumps("},{"line_number":6342,"context_line":"                    [dict(sr) for sr in shard_ranges])"}],"source_content_type":"text/x-python","patch_set":17,"id":"ba32c0c7_dbee5f31","line":6339,"in_reply_to":"bc5a282f_c783ff88","updated":"2023-11-14 04:24:12.000000000","message":"Done","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"}],"test/unit/proxy/controllers/test_base.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":1478,"context_line":"        base \u003d Controller(self.app)"},{"line_number":1479,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c\u0027, method\u003d\u0027GET\u0027)"},{"line_number":1480,"context_line":"        resp_headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":1481,"context_line":"                        \u0027X-Backend-Record-Shard-Format\u0027: \u0027namespace\u0027}"},{"line_number":1482,"context_line":"        with mocked_http_conn("},{"line_number":1483,"context_line":"            200, 200,"},{"line_number":1484,"context_line":"            body_iter\u003diter([b\u0027\u0027, json.dumps(shard_ranges).encode(\u0027ascii\u0027)]),"}],"source_content_type":"text/x-python","patch_set":17,"id":"d978c4eb_88a92409","line":1481,"updated":"2023-11-01 00:22:45.000000000","message":"isn\u0027t it weird that our headers say we\u0027re returning namespaces but the body is returning full ShardRange dicts?","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":1583,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, method\u003d\u0027PUT\u0027)"},{"line_number":1584,"context_line":"        # empty response"},{"line_number":1585,"context_line":"        headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":1586,"context_line":"                   \u0027X-Backend-Record-Shard-Format\u0027: \u0027namespace\u0027}"},{"line_number":1587,"context_line":"        with mocked_http_conn(200, 200, body_iter\u003diter([b\u0027\u0027, body]),"},{"line_number":1588,"context_line":"                              headers\u003dheaders):"},{"line_number":1589,"context_line":"            actual, resp \u003d base._get_shard_ranges(req, \u0027a\u0027, \u0027c\u0027, \u00271_test\u0027)"}],"source_content_type":"text/x-python","patch_set":17,"id":"108436f0_cebc171f","line":1586,"updated":"2023-11-01 00:22:45.000000000","message":"maybe it would be better to pass in \"shard_ranges\" and then have a helper that \"creates_response\" which can either be a Namespace or ShardRange response.","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":1612,"context_line":"        body \u003d json.dumps([{}]).encode(\u0027ascii\u0027)"},{"line_number":1613,"context_line":"        error_lines \u003d self._check_get_shard_ranges_bad_data(body)"},{"line_number":1614,"context_line":"        self.assertIn(\u0027Failed to get shard ranges\u0027, error_lines[0])"},{"line_number":1615,"context_line":"        self.assertIn(\u0027TypeError\u0027, error_lines[0])"},{"line_number":1616,"context_line":"        self.assertFalse(error_lines[1:])"},{"line_number":1617,"context_line":""},{"line_number":1618,"context_line":"    def test_get_shard_ranges_invalid_shard_range(self):"}],"source_content_type":"text/x-python","patch_set":17,"id":"aca8babb_6333f982","line":1615,"updated":"2023-11-01 00:22:45.000000000","message":"```\nFailed to get shard ranges from /v1/a/c/o: invalid data: TypeError(\"__init__() missing 1 required positional argument: \\\u0027name\\\u0027\")\n```\n\nthe _check_bad_data helper is actually verifying that mocked response status is 200 with the invalid shard_range translated to a None; which i guess is fine with callers to get_shard_ranges","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"}],"test/unit/proxy/controllers/test_container.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"52b5136e32abe3fb7141f9f0030dc4b5da1186af","unresolved":true,"context_lines":[{"line_number":3750,"context_line":"        self._assert_responses(\u0027POST\u0027, POST_TEST_CASES)"},{"line_number":3751,"context_line":""},{"line_number":3752,"context_line":""},{"line_number":3753,"context_line":"@patch_policies([StoragePolicy(0, \u0027zero\u0027, True, object_ring\u003dFakeRing())])"},{"line_number":3754,"context_line":"class TestContainerControllerReturnShardRanges(TestContainerController):"},{"line_number":3755,"context_line":"    RESP_RECORD_TYPE \u003d \u0027shard\u0027"},{"line_number":3756,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"593912e3_c8875e0c","line":3753,"updated":"2023-09-21 21:16:31.000000000","message":"still need add test cases to verify that proxy will be able to handle that Namespace queries come back and return ShardRange.","commit_id":"d452dbdc59dd99b9f477d200969f451ebb99f156"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"12ea84bf73ad21d05487a6fc794e45c044909a55","unresolved":false,"context_lines":[{"line_number":3750,"context_line":"        self._assert_responses(\u0027POST\u0027, POST_TEST_CASES)"},{"line_number":3751,"context_line":""},{"line_number":3752,"context_line":""},{"line_number":3753,"context_line":"@patch_policies([StoragePolicy(0, \u0027zero\u0027, True, object_ring\u003dFakeRing())])"},{"line_number":3754,"context_line":"class TestContainerControllerReturnShardRanges(TestContainerController):"},{"line_number":3755,"context_line":"    RESP_RECORD_TYPE \u003d \u0027shard\u0027"},{"line_number":3756,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"dbe681b0_b6c48ed1","line":3753,"in_reply_to":"593912e3_c8875e0c","updated":"2023-09-27 22:41:53.000000000","message":"The new TestContainerControllerReturnShardRanges inherited from TestContainerController, so it will test all the current test cases in TestContainerController with shard range returned. Those are backward compatibility tests which simulate proxy queries Namespaces to older version container server and then gets ShardRange returned. very neat!!","commit_id":"d452dbdc59dd99b9f477d200969f451ebb99f156"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":517,"context_line":"            request.environ[\u0027swift.cache\u0027] \u003d FakeMemcache()"},{"line_number":518,"context_line":""},{"line_number":519,"context_line":"        with mocked_http_conn("},{"line_number":520,"context_line":"                *codes, body_iter\u003dbodies, headers\u003dexp_headers) as fake_conn:"},{"line_number":521,"context_line":"            resp \u003d request.get_response(self.app)"},{"line_number":522,"context_line":"        for backend_req in fake_conn.requests:"},{"line_number":523,"context_line":"            self.assertEqual(request.headers[\u0027X-Trans-Id\u0027],"}],"source_content_type":"text/x-python","patch_set":17,"id":"6345f4ce_9cca3a36","line":520,"updated":"2023-11-01 00:22:45.000000000","message":"only ~15 methods use this helper; and it seems to largely overlap with the methods already patched.","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"10a5f4153f9de4a9d0bada9ea6dfcb797383c5c5","unresolved":false,"context_lines":[{"line_number":517,"context_line":"            request.environ[\u0027swift.cache\u0027] \u003d FakeMemcache()"},{"line_number":518,"context_line":""},{"line_number":519,"context_line":"        with mocked_http_conn("},{"line_number":520,"context_line":"                *codes, body_iter\u003dbodies, headers\u003dexp_headers) as fake_conn:"},{"line_number":521,"context_line":"            resp \u003d request.get_response(self.app)"},{"line_number":522,"context_line":"        for backend_req in fake_conn.requests:"},{"line_number":523,"context_line":"            self.assertEqual(request.headers[\u0027X-Trans-Id\u0027],"}],"source_content_type":"text/x-python","patch_set":17,"id":"839a4d7d_cc87d514","line":520,"in_reply_to":"6345f4ce_9cca3a36","updated":"2023-12-11 14:44:03.000000000","message":"Done","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":587,"context_line":"            for lower, upper in bounds]"},{"line_number":588,"context_line":"        ns_dicts \u003d [dict(ns) for ns in namespaces]"},{"line_number":589,"context_line":"        ns_objs \u003d [self._make_shard_objects(ns) for ns in namespaces]"},{"line_number":590,"context_line":"        return namespaces, ns_dicts, ns_objs"},{"line_number":591,"context_line":""},{"line_number":592,"context_line":"    def test_GET_sharded_container_no_memcache(self):"},{"line_number":593,"context_line":"        # Don\u0027t worry, ShardRange._encode takes care of unicode/bytes issues"}],"source_content_type":"text/x-python","patch_set":17,"id":"f31411d4_01ea6c9d","line":590,"updated":"2023-11-01 00:22:45.000000000","message":"I love me some test setup helpers!  nice!","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a4e9c34eef2afee5a89bbc4cb388d0eda8f024f4","unresolved":false,"context_lines":[{"line_number":587,"context_line":"            for lower, upper in bounds]"},{"line_number":588,"context_line":"        ns_dicts \u003d [dict(ns) for ns in namespaces]"},{"line_number":589,"context_line":"        ns_objs \u003d [self._make_shard_objects(ns) for ns in namespaces]"},{"line_number":590,"context_line":"        return namespaces, ns_dicts, ns_objs"},{"line_number":591,"context_line":""},{"line_number":592,"context_line":"    def test_GET_sharded_container_no_memcache(self):"},{"line_number":593,"context_line":"        # Don\u0027t worry, ShardRange._encode takes care of unicode/bytes issues"}],"source_content_type":"text/x-python","patch_set":17,"id":"8bc81b46_ec851745","line":590,"in_reply_to":"f31411d4_01ea6c9d","updated":"2023-11-21 12:04:27.000000000","message":"Acknowledged","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":2663,"context_line":"        resp_hdrs \u003d dict(self.root_resp_hdrs)"},{"line_number":2664,"context_line":"        resp_hdrs.update(resp_extra_hdrs)"},{"line_number":2665,"context_line":"        resp_status \u003d [resp_status] * num_resp"},{"line_number":2666,"context_line":"        with mocked_http_conn("},{"line_number":2667,"context_line":"                *resp_status, body_iter\u003d[resp_body] * num_resp,"},{"line_number":2668,"context_line":"                headers\u003d[resp_hdrs] * num_resp) as fake_conn:"},{"line_number":2669,"context_line":"            resp \u003d req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":17,"id":"7e3250ce_eba01057","line":2666,"updated":"2023-11-01 00:22:45.000000000","message":"there\u0027s a different set of *mostly* shard related tests that use this setup:\n\n```\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_objects_makes_no_cache_lookup True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_404_response True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_bad_response_body True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_recheck_listing_shard_ranges True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_when_include_deleted_shards True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_when_requesting_updating_shards True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_write_for_incomplete_listing True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_write_for_non_sharded_states True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_write_for_object_listing True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_write_with_cached_container_info True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_memcache_available True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_read_from_cache_error True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_write_to_cache True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_write_to_cache_with_x_newest True\n```","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":2663,"context_line":"        resp_hdrs \u003d dict(self.root_resp_hdrs)"},{"line_number":2664,"context_line":"        resp_hdrs.update(resp_extra_hdrs)"},{"line_number":2665,"context_line":"        resp_status \u003d [resp_status] * num_resp"},{"line_number":2666,"context_line":"        with mocked_http_conn("},{"line_number":2667,"context_line":"                *resp_status, body_iter\u003d[resp_body] * num_resp,"},{"line_number":2668,"context_line":"                headers\u003d[resp_hdrs] * num_resp) as fake_conn:"},{"line_number":2669,"context_line":"            resp \u003d req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":17,"id":"48791130_61b33d23","line":2666,"updated":"2023-11-01 00:22:45.000000000","message":"~","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"10a5f4153f9de4a9d0bada9ea6dfcb797383c5c5","unresolved":false,"context_lines":[{"line_number":2663,"context_line":"        resp_hdrs \u003d dict(self.root_resp_hdrs)"},{"line_number":2664,"context_line":"        resp_hdrs.update(resp_extra_hdrs)"},{"line_number":2665,"context_line":"        resp_status \u003d [resp_status] * num_resp"},{"line_number":2666,"context_line":"        with mocked_http_conn("},{"line_number":2667,"context_line":"                *resp_status, body_iter\u003d[resp_body] * num_resp,"},{"line_number":2668,"context_line":"                headers\u003d[resp_hdrs] * num_resp) as fake_conn:"},{"line_number":2669,"context_line":"            resp \u003d req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":17,"id":"3ff23666_a9ba64c1","line":2666,"in_reply_to":"48791130_61b33d23","updated":"2023-12-11 14:44:03.000000000","message":"Done","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"10a5f4153f9de4a9d0bada9ea6dfcb797383c5c5","unresolved":false,"context_lines":[{"line_number":2663,"context_line":"        resp_hdrs \u003d dict(self.root_resp_hdrs)"},{"line_number":2664,"context_line":"        resp_hdrs.update(resp_extra_hdrs)"},{"line_number":2665,"context_line":"        resp_status \u003d [resp_status] * num_resp"},{"line_number":2666,"context_line":"        with mocked_http_conn("},{"line_number":2667,"context_line":"                *resp_status, body_iter\u003d[resp_body] * num_resp,"},{"line_number":2668,"context_line":"                headers\u003d[resp_hdrs] * num_resp) as fake_conn:"},{"line_number":2669,"context_line":"            resp \u003d req.get_response(self.app)"}],"source_content_type":"text/x-python","patch_set":17,"id":"ebcc612a_1fee8ef8","line":2666,"in_reply_to":"7e3250ce_eba01057","updated":"2023-12-11 14:44:03.000000000","message":"Done","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0e18409bbfb34cfc1f6d414e88f5819cce7f0368","unresolved":true,"context_lines":[{"line_number":3792,"context_line":"        sr_dicts \u003d [dict(sr, last_modified\u003dsr.timestamp.isoformat)"},{"line_number":3793,"context_line":"                    for sr in shard_ranges]"},{"line_number":3794,"context_line":"        sr_objs \u003d [self._make_shard_objects(sr) for sr in shard_ranges]"},{"line_number":3795,"context_line":"        return shard_ranges, sr_dicts, sr_objs"},{"line_number":3796,"context_line":""},{"line_number":3797,"context_line":""},{"line_number":3798,"context_line":"if __name__ \u003d\u003d \u0027__main__\u0027:"}],"source_content_type":"text/x-python","patch_set":17,"id":"c6c4c67c_cd2f97fe","line":3795,"updated":"2023-11-01 00:22:45.000000000","message":"ohh... I see.\n\nOnly 18/49 tests in this TestCase use create_server_response_data - the same that blow up w/o RESP_SHARD_FORMAT_HEADERS:\n\n```\n(vagrant-swift-all-in-one) clayg@banana:~/Workspace/vagrant-swift-all-in-one/swift$ git diff\ndiff --git a/test/unit/proxy/controllers/test_container.py b/test/unit/proxy/controllers/test_container.py\nindex 9004a6c2b..d1cdc08b8 100644\n--- a/test/unit/proxy/controllers/test_container.py\n+++ b/test/unit/proxy/controllers/test_container.py\n@@ -47,7 +47,7 @@ from test.unit.proxy.test_server import node_error_count\n \n @patch_policies([StoragePolicy(0, \u0027zero\u0027, True, object_ring\u003dFakeRing())])\n class TestContainerController(TestRingBase):\n-    RESP_SHARD_FORMAT_HEADERS \u003d {\u0027X-Backend-Record-Shard-Format\u0027: \u0027namespace\u0027}\n+    # RESP_SHARD_FORMAT_HEADERS \u003d {\u0027X-Backend-Record-Shard-Format\u0027: \u0027namespace\u0027}\n \n     CONTAINER_REPLICAS \u003d 3\n \n@@ -89,6 +89,11 @@ class TestContainerController(TestRingBase):\n         self.app.get_controller \u003d wrapped_get_controller\n         self.ts_iter \u003d make_timestamp_iter()\n \n+    def tearDown(self):\n+        with open(\u0027test.audit\u0027, \u0027a\u0027) as f:\n+            f.write(\u0027%s %s\\n\u0027 % (self.id(), getattr(\n+                self, \u0027has_used_crate_sr_response_data\u0027, False)))\n+\n     def _make_callback_func(self, context):\n         def callback(ipaddr, port, device, partition, method, path,\n                      headers\u003dNone, query_string\u003dNone, ssl\u003dFalse):\n@@ -579,6 +584,7 @@ class TestContainerController(TestRingBase):\n         self.assertEqual(headers_to_container_info(info_hdrs), info)\n \n     def create_server_response_data(self, bounds, states\u003dNone, remove_char\u003d\u0027\u0027):\n+        self.has_used_crate_sr_response_data \u003d True\n         if not isinstance(bounds[0], (list, tuple)):\n             bounds \u003d [(l, u) for l, u in zip(bounds[:-1], bounds[1:])]\n         namespaces \u003d [\n```\n\nI think you should pull out the tests you want to double-run into their own testcase:\n\n```\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_bad_requests False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_objects_makes_no_cache_lookup False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_404_response False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_bad_response_body False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_recheck_listing_shard_ranges False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_when_include_deleted_shards False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_when_requesting_updating_shards False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_write_for_incomplete_listing False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_write_for_non_sharded_states False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_write_for_object_listing False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_cache_write_with_cached_container_info False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_no_memcache_available False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_read_from_cache False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_read_from_cache_error False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_write_to_cache False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_shard_ranges_write_to_cache_with_x_newest False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_empty_shard True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_gap_in_shards_memcache True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_gap_in_shards_no_memcache True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_mix_ok_and_unavailable_shards True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_mixed_policies_error True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_no_memcache True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_overlapping_shards True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_shard_errors True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_shard_redirects_between_shards True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_shard_redirects_to_root True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_sharding_shard True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_sharding_shard_mixed_policies True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_with_deleted_shard True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_with_delimiter True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_with_delimiter_and_reverse True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_with_memcache True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharded_container_with_mix_ok_and_deleted_shard True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_GET_sharding_container_gap_in_shards_memcache True\ntest.unit.proxy.controllers.test_container.TestContainerController.test_cache_clearing False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_container_cache_cleared_after_PUT False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_container_info_got_cached False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_get_from_shards_add_root_spi False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_handoff_has_deleted_database False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_node_errors False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_reseller_admin False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_response_code_for_DELETE False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_response_code_for_POST False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_response_code_for_PUT False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_response_codes_for_GET False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_swift_owner False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_sys_meta_headers_POST False\ntest.unit.proxy.controllers.test_container.TestContainerController.test_sys_meta_headers_PUT False\n```\n\nI don\u0027t think we should run tests twice with the exact some arguments; also some of the sharded tests maybe *should* run with both ShardRange and Namespace responses (e.g. test_GET_shard_ranges); but they don\u0027t because of some difference in test-setup/stub-response mocking?","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a4e9c34eef2afee5a89bbc4cb388d0eda8f024f4","unresolved":false,"context_lines":[{"line_number":3792,"context_line":"        sr_dicts \u003d [dict(sr, last_modified\u003dsr.timestamp.isoformat)"},{"line_number":3793,"context_line":"                    for sr in shard_ranges]"},{"line_number":3794,"context_line":"        sr_objs \u003d [self._make_shard_objects(sr) for sr in shard_ranges]"},{"line_number":3795,"context_line":"        return shard_ranges, sr_dicts, sr_objs"},{"line_number":3796,"context_line":""},{"line_number":3797,"context_line":""},{"line_number":3798,"context_line":"if __name__ \u003d\u003d \u0027__main__\u0027:"}],"source_content_type":"text/x-python","patch_set":17,"id":"2b3c9ff9_3da88f21","line":3795,"in_reply_to":"c6c4c67c_cd2f97fe","updated":"2023-11-21 12:04:27.000000000","message":"Done","commit_id":"2065dfd7081c1dbcae6497294a7fb1636875db73"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"10a5f4153f9de4a9d0bada9ea6dfcb797383c5c5","unresolved":true,"context_lines":[{"line_number":3703,"context_line":"        do_test(\u0027POST\u0027, 204, self.CONTAINER_REPLICAS)"},{"line_number":3704,"context_line":"        do_test(\u0027PUT\u0027, 202, self.CONTAINER_REPLICAS)"},{"line_number":3705,"context_line":""},{"line_number":3706,"context_line":"    def test_GET_bad_requests(self):"},{"line_number":3707,"context_line":"        # verify that the proxy controller enforces checks on request params"},{"line_number":3708,"context_line":"        req \u003d Request.blank("},{"line_number":3709,"context_line":"            \u0027/v1/a/c?limit\u003d%d\u0027 % (CONTAINER_LISTING_LIMIT + 1))"}],"source_content_type":"text/x-python","patch_set":32,"id":"7fd1d431_975e2ac5","side":"PARENT","line":3706,"updated":"2023-12-11 14:44:03.000000000","message":"With new test subclasses being added, this needed to move up in the file to remain with the \u0027generic\u0027 tests in TestContainerController","commit_id":"cf2bad8e97c2b6fa3efa22913f81b06c5ff2e6e9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"062f3e9de780753a4776468d255d05fd76f24bb8","unresolved":false,"context_lines":[{"line_number":3703,"context_line":"        do_test(\u0027POST\u0027, 204, self.CONTAINER_REPLICAS)"},{"line_number":3704,"context_line":"        do_test(\u0027PUT\u0027, 202, self.CONTAINER_REPLICAS)"},{"line_number":3705,"context_line":""},{"line_number":3706,"context_line":"    def test_GET_bad_requests(self):"},{"line_number":3707,"context_line":"        # verify that the proxy controller enforces checks on request params"},{"line_number":3708,"context_line":"        req \u003d Request.blank("},{"line_number":3709,"context_line":"            \u0027/v1/a/c?limit\u003d%d\u0027 % (CONTAINER_LISTING_LIMIT + 1))"}],"source_content_type":"text/x-python","patch_set":32,"id":"56d37603_82e81893","side":"PARENT","line":3706,"in_reply_to":"7fd1d431_975e2ac5","updated":"2024-01-04 12:11:59.000000000","message":"Acknowledged","commit_id":"cf2bad8e97c2b6fa3efa22913f81b06c5ff2e6e9"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5e5eb4e19096acf8651743f7a50222630c77a610","unresolved":true,"context_lines":[{"line_number":493,"context_line":"        self.assertEqual(400, req.get_response(self.app).status_int)"},{"line_number":494,"context_line":""},{"line_number":495,"context_line":""},{"line_number":496,"context_line":"class TestGetShardedContainer(BaseTestContainerController):"},{"line_number":497,"context_line":"    RESP_SHARD_FORMAT_HEADERS \u003d {\u0027X-Backend-Record-Shard-Format\u0027: \u0027namespace\u0027}"},{"line_number":498,"context_line":""},{"line_number":499,"context_line":"    def setUp(self):"}],"source_content_type":"text/x-python","patch_set":46,"id":"ab1a59ce_ad5852d4","line":496,"updated":"2024-01-12 14:36:16.000000000","message":"wow, it seems like this test file was surprisingly well organized; this was a clean split of the existing tests in un/sharded tests","commit_id":"03b66c94f423f06cd6c16742a8ae2ea4bbccbd70"}],"test/unit/proxy/controllers/test_obj.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"b8d0f20d59a6b772420f331e3665afc0135cb0df","unresolved":false,"context_lines":[{"line_number":7264,"context_line":"            \u0027%d_upper\u0027 % i, object_count\u003di, bytes_used\u003d1024 * i,"},{"line_number":7265,"context_line":"            meta_timestamp\u003dnext(ts_iter))"},{"line_number":7266,"context_line":"            for i in range(3)]"},{"line_number":7267,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, method\u003d\u0027PUT\u0027)"},{"line_number":7268,"context_line":"        body, resp_headers \u003d self._create_response_data(shard_ranges)"},{"line_number":7269,"context_line":"        with mocked_http_conn("},{"line_number":7270,"context_line":"                200, 200, body_iter\u003diter([b\u0027\u0027, body]),"}],"source_content_type":"text/x-python","patch_set":40,"id":"1d94be4e_144d629a","line":7267,"updated":"2024-01-09 05:42:46.000000000","message":"yeah, no memcache was passed into Request.","commit_id":"5d322113a3e118fbe66a4c811910afe3c22b1702"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0960193ee40acfa6ca82f4b52491e058a151bac4","unresolved":true,"context_lines":[{"line_number":7291,"context_line":"        exp_dicts \u003d [dict(name\u003dsr.name, lower\u003dsr.lower, upper\u003dsr.upper)"},{"line_number":7292,"context_line":"                     for sr in shard_ranges]"},{"line_number":7293,"context_line":"        self.assertEqual(exp_dicts, [dict(sr) for sr in actual])"},{"line_number":7294,"context_line":"        self.assertFalse(self.app.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":7295,"context_line":""},{"line_number":7296,"context_line":"    def test_get_namespaces_for_object_put(self):"},{"line_number":7297,"context_line":"        # verify case when specific shard is returned"}],"source_content_type":"text/x-python","patch_set":40,"id":"9acf227a_b1f5d7e9","line":7294,"updated":"2024-01-08 15:09:42.000000000","message":"these tests are not giving any coverage of reading and writing from/too cache","commit_id":"5d322113a3e118fbe66a4c811910afe3c22b1702"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"b8d0f20d59a6b772420f331e3665afc0135cb0df","unresolved":false,"context_lines":[{"line_number":7291,"context_line":"        exp_dicts \u003d [dict(name\u003dsr.name, lower\u003dsr.lower, upper\u003dsr.upper)"},{"line_number":7292,"context_line":"                     for sr in shard_ranges]"},{"line_number":7293,"context_line":"        self.assertEqual(exp_dicts, [dict(sr) for sr in actual])"},{"line_number":7294,"context_line":"        self.assertFalse(self.app.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":7295,"context_line":""},{"line_number":7296,"context_line":"    def test_get_namespaces_for_object_put(self):"},{"line_number":7297,"context_line":"        # verify case when specific shard is returned"}],"source_content_type":"text/x-python","patch_set":40,"id":"e0a98600_e963ba2d","line":7294,"in_reply_to":"9acf227a_b1f5d7e9","updated":"2024-01-09 05:42:46.000000000","message":"Acknowledged","commit_id":"5d322113a3e118fbe66a4c811910afe3c22b1702"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"b8d0f20d59a6b772420f331e3665afc0135cb0df","unresolved":false,"context_lines":[{"line_number":7259,"context_line":"            meta_timestamp\u003dnext(ts_iter))"},{"line_number":7260,"context_line":"            for i in range(3)]"},{"line_number":7261,"context_line":""},{"line_number":7262,"context_line":"    def _create_response_data(self, namespaces, includes\u003dNone):"},{"line_number":7263,"context_line":"        resp_headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027shard\u0027,"},{"line_number":7264,"context_line":"                        \u0027X-Backend-Record-Shard-Format\u0027: \u0027namespace\u0027}"},{"line_number":7265,"context_line":"        namespaces \u003d [Namespace(sr.name, sr.lower, sr.upper)"}],"source_content_type":"text/x-python","patch_set":42,"id":"856d2754_d906106e","line":7262,"updated":"2024-01-09 05:42:46.000000000","message":"nit: s/namespaces/shards to be consistent","commit_id":"0204e5cf3540c94fb49ef35b416a5f14dd5d1e84"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"b8d0f20d59a6b772420f331e3665afc0135cb0df","unresolved":false,"context_lines":[{"line_number":7319,"context_line":"        self.assertEqual(exp_ns, actual)"},{"line_number":7320,"context_line":"        self.assertFalse(self.app.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":7321,"context_line":""},{"line_number":7322,"context_line":"    def test_get_update_shard_cache_disabled(self):"},{"line_number":7323,"context_line":"        # verify case when single shard is returned"},{"line_number":7324,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, method\u003d\u0027PUT\u0027,"},{"line_number":7325,"context_line":"                            environ\u003d{\u0027swift.cache\u0027: self.memcache})"}],"source_content_type":"text/x-python","patch_set":42,"id":"b69419f5_4ebeaa21","line":7322,"updated":"2024-01-09 05:42:46.000000000","message":"this case is not the case with memcache disable, I will add one.","commit_id":"0204e5cf3540c94fb49ef35b416a5f14dd5d1e84"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f869ec9474eef008226b943cc2cbd8d181c65ed","unresolved":false,"context_lines":[{"line_number":7319,"context_line":"        self.assertEqual(exp_ns, actual)"},{"line_number":7320,"context_line":"        self.assertFalse(self.app.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":7321,"context_line":""},{"line_number":7322,"context_line":"    def test_get_update_shard_cache_disabled(self):"},{"line_number":7323,"context_line":"        # verify case when single shard is returned"},{"line_number":7324,"context_line":"        req \u003d Request.blank(\u0027/v1/a/c/o\u0027, method\u003d\u0027PUT\u0027,"},{"line_number":7325,"context_line":"                            environ\u003d{\u0027swift.cache\u0027: self.memcache})"}],"source_content_type":"text/x-python","patch_set":42,"id":"32e06354_3f96b7ea","line":7322,"in_reply_to":"b69419f5_4ebeaa21","updated":"2024-01-09 15:24:22.000000000","message":"thanks!\n\nI may change the test name - worth noting that \"single shard\" is a consequence of recheck_updating_shard_ranges being zero (i.e. memcache is available but shard caching is disabled)","commit_id":"0204e5cf3540c94fb49ef35b416a5f14dd5d1e84"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3f869ec9474eef008226b943cc2cbd8d181c65ed","unresolved":true,"context_lines":[{"line_number":7371,"context_line":"        self.assertEqual(\u0027a/c\u0027, captured[1][\u0027path\u0027][7:])"},{"line_number":7372,"context_line":"        params \u003d sorted(captured[1][\u0027qs\u0027].split(\u0027\u0026\u0027))"},{"line_number":7373,"context_line":"        self.assertEqual("},{"line_number":7374,"context_line":"            [\u0027format\u003djson\u0027, \u0027states\u003dupdating\u0027], params)"},{"line_number":7375,"context_line":"        captured_hdrs \u003d captured[1][\u0027headers\u0027]"},{"line_number":7376,"context_line":"        self.assertEqual(\u0027shard\u0027, captured_hdrs.get(\u0027X-Backend-Record-Type\u0027))"},{"line_number":7377,"context_line":"        self.assertEqual(\u0027namespace\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"c2e221e1_3c0754aa","line":7374,"updated":"2024-01-09 15:24:22.000000000","message":"hmmm, so we fetch *all* the namespaces despite there being no memcache available - that doesn\u0027t make sense, but it\u0027s existing behavior, and swift without memcache isn\u0027t typical, so let\u0027s address it in a follow up.","commit_id":"61a31e676dd3ba559e9a9f4b59472cc52a73df12"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"79eb423e4c81edcfae9f418c20e0f0ec0808508e","unresolved":false,"context_lines":[{"line_number":7371,"context_line":"        self.assertEqual(\u0027a/c\u0027, captured[1][\u0027path\u0027][7:])"},{"line_number":7372,"context_line":"        params \u003d sorted(captured[1][\u0027qs\u0027].split(\u0027\u0026\u0027))"},{"line_number":7373,"context_line":"        self.assertEqual("},{"line_number":7374,"context_line":"            [\u0027format\u003djson\u0027, \u0027states\u003dupdating\u0027], params)"},{"line_number":7375,"context_line":"        captured_hdrs \u003d captured[1][\u0027headers\u0027]"},{"line_number":7376,"context_line":"        self.assertEqual(\u0027shard\u0027, captured_hdrs.get(\u0027X-Backend-Record-Type\u0027))"},{"line_number":7377,"context_line":"        self.assertEqual(\u0027namespace\u0027,"}],"source_content_type":"text/x-python","patch_set":43,"id":"94822267_c83d1a9f","line":7374,"in_reply_to":"c2e221e1_3c0754aa","updated":"2024-01-09 20:42:10.000000000","message":"Acknowledged","commit_id":"61a31e676dd3ba559e9a9f4b59472cc52a73df12"}]}
