)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Using mock_fixture.patch_mock_module() will enforce autospec\u003dTrue on all"},{"line_number":10,"context_line":"the mock.patch and similar calls. This will enforce signature checks on"},{"line_number":11,"context_line":"the mocked methods and functions, catching potential bugs missed by"},{"line_number":12,"context_line":"otherwise false positive unit tests."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: Icc4af149a63fac1c265e7006e188c2df8934d1cc"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"09a84f3b_6c123e25","line":11,"range":{"start_line":11,"start_character":34,"end_line":11,"end_character":57},"updated":"2026-06-28 23:57:45.000000000","message":"So did we catch any bugs!? I love catching bugs! But I can\u0027t tell which (if any) of the churn was supposed to be a bug.\n\nMaybe that\u0027s what the failing tests are about? Are those ones the remaining bugs?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Using mock_fixture.patch_mock_module() will enforce autospec\u003dTrue on all"},{"line_number":10,"context_line":"the mock.patch and similar calls. This will enforce signature checks on"},{"line_number":11,"context_line":"the mocked methods and functions, catching potential bugs missed by"},{"line_number":12,"context_line":"otherwise false positive unit tests."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: Icc4af149a63fac1c265e7006e188c2df8934d1cc"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"3b0845f7_0a166b7f","line":11,"range":{"start_line":11,"start_character":34,"end_line":11,"end_character":57},"in_reply_to":"09a84f3b_6c123e25","updated":"2026-07-08 13:02:46.000000000","message":"Hello, and thanks for the review.\n\nFor this project, it seems that no bugs were found. That is good, it basically means that all / most of the code is well tested / used, and any rough edges have been smoothed over over time.\n\n\nHowever, I can point out several bugs in other projects, where we did the same thing, using the oslotest mock fixture. Here are a few examples:\n\n- https://review.opendev.org/c/openstack/trove/+/994673/6/trove/extensions/mgmt/upgrade/models.py\n\t- the original call is incorrect. `guest_agent` returns `trove.guestagent.api.API` (as seen here, because manager\u003dNone: https://github.com/openstack/trove/blob/e9489ce73e2415ed277eb51ab45394f9247acc30/trove/common/clients.py#L81). If we look here (https://github.com/openstack/trove/blob/e9489ce73e2415ed277eb51ab45394f9247acc30/trove/guestagent/api.py#L396), you can see that `upgrade` only takes one argument, not 3.\n\n- https://review.opendev.org/c/openstack/cinder/+/994152/8/cinder/volume/drivers/netapp/dataontap/block_base.py\n\t- `_create_lun` and `_clone_lun` were missing the `qos_policy_group_is_adaptive` parameter that the `block_cmode` subclass passes. Not a \"bug\" per se, but still an interface mismatch, which can still be an issue (it happened to me once quite recently).\n\n- https://review.opendev.org/c/openstack/cinder/+/994152/8/cinder/volume/drivers/open_e/jovian_common/driver.py\n\t- the actual signature is `def _ensure_target_volume(self, id, vid, provider_auth, ro\u003dFalse):`, but `mode\u003d\u0027ro\u0027` is given instead.\n\n- https://review.opendev.org/c/openstack/cinder/+/994152/8/cinder/volume/drivers/remotefs.py\n\t- `_qemu_img_info` has the signature: `def _qemu_img_info(self, path: str, volume_name: str):`. Only one argument was being passed. There even was a comment: \"TODO: something is wrong here\"\n\nSo, instead of \"So did we catch any bugs!?\", the better question is: \"How come the bugs above even existed in the first place?\". Nonetheless, these issues have been caught by autospecs, rather than silently passing.\n\nBut the best usage of autospecs is as a canary for when things change (including for external libraries, interface changes would be caught if they are autospec\u0027d). From my personal experience, there were too many cases in which I had to fix things that could have been caught by an autospec (https://review.opendev.org/c/openstack/nova/+/461689, https://review.opendev.org/c/openstack/compute-hyperv/+/500130, https://review.opendev.org/c/openstack/compute-hyperv/+/498740, https://review.opendev.org/c/openstack/compute-hyperv/+/425625, https://review.opendev.org/c/openstack/os-win/+/253084), and since then, it prevented a few other cases, before having to send a PR upstream.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"dd52979c_80a89590","updated":"2026-06-28 23:57:45.000000000","message":"This was a surprisingly tricky change to review. There were a number of broad classes of changes made:\n\n- Swap `new\u003dlambda: x` for `return_value\u003dx`\n- Add `create\u003dTrue` when patching builtins\n- Stop creating `mock.MagicMock()`/`mock.Mock()` instances ourselves when we don\u0027t have to\n- Use `.return_value` rather than `()` when navigating to some deeply nested part of a mock\n- Stop mocking things twice (`get_swift_info` in s3api tests, `sharder.int_client` in sharder tests)\n- Use `side_effect` to raise exceptions rather than defining a new function\n- Swap `spec\u003dx` for `autospec\u003dx`\n\nand it wasn\u0027t clear to me which were strictly necessary.\n\nI\u0027m not necessarily opposed to (some? most? of) the changes, but we\u0027ll definitely need to fix the failing tests before we can do much with this. It\u0027s also rather odd that the number of failing unit tests changes depending on which version of Python we\u0027re using to run them (8 for py37, 37 for py314)...","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"46e8f7e7b73a0d8f499fa9483b0ffd205a1c3ed0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"23a68c72_69b0523e","in_reply_to":"1546ad04_c3f1ee6d","updated":"2026-07-08 20:36:29.000000000","message":"PS: the double mock issue is clearly seen as an anti-pattern / test bug in the upstream community: https://github.com/python/cpython/issues/87644","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"17f0e9ce7e2deae8335991c6de2956b779007f3d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"1546ad04_c3f1ee6d","in_reply_to":"dd52979c_80a89590","updated":"2026-07-08 13:15:56.000000000","message":"Hello,\n\nIndeed, there were quite a few changes:\n\n- `new` is not being used, that effectively disables autospec. Plus, using `return_value\u003dx` instead of `new\u003dlamda: x` yields the same result, and it\u0027s more idiomatic.\n- `create\u003dTrue` / `autospec\u003dFalse` when patching builtins: This is related to how the `mock` library works. If no autospec is given, `mock` will simply create a `mock.Mock` and `setattr` it into the module. If `autospec\u003dTrue`, it will try to `getattr` it first... but there is no such attribute in that module (let\u0027s say `open` or `input`), resulting in an `AttributeError`. That\u0027s because those are builtins. I\u0027d argue the `mock` module would address this issue and do as expected, but it doesn\u0027t.\n- `.return_value` because if you call the autospec\u0027d method, the expectation is for the call to *respect* the signature (e.g.: because you `()` without any arguments, and the original method has a few arguments, it will fail with a `TypeError` as expected), but on the test side, you typically navigate the object to do some assertions at some level.\n- Yep, the `mock` module raises `InvalidSpecError` in those cases, you can\u0027t autospec mocks / something that was already `mock.patched`.\n- `side_effect`: yes, that is also more idiomatic.\n- `autospec\u003dx` instead of `spec\u003dx` - `autospec` is stricter than `spec`. A `spec` will only check for an attribute\u0027s existence, and that\u0027s it. `autospec` will also ensure that the thing you call are actually callable, and that they are really being called with the right signature. There are some corner cases in which that is not perfect (e.g.: decorators injecting parameters).","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f29c4a6a007ac55ff1af77c20abe5c260499114b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"e84594e6_2ddac7ec","updated":"2026-07-10 17:21:36.000000000","message":"I\u0027ll see about getting some other cores to take a look, too.","commit_id":"3667131b75f19c427bce44763a85c7b7368d524c"}],"test-requirements.txt":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":9,"context_line":"pytest-subtests\u003e\u003d0.3.0  # MIT"},{"line_number":10,"context_line":"pytest-cov\u003e\u003d2.12.1  # MIT"},{"line_number":11,"context_line":"stestr\u003e\u003d2.0.0 # Apache-2.0"},{"line_number":12,"context_line":"oslotest\u003e\u003d3.2.0 # Apache-2.0"},{"line_number":13,"context_line":"python-swiftclient\u003e\u003d3.2.0"},{"line_number":14,"context_line":"python-keystoneclient\u003e\u003d3.19.0 # Apache-2.0"},{"line_number":15,"context_line":"boto\u003e\u003d2.32.1"}],"source_content_type":"text/plain","patch_set":3,"id":"fdc6103d_b25d618b","line":12,"updated":"2026-06-28 23:57:45.000000000","message":"OK, one new test requirement; it needs two transitive deps (`fixtures` and `testtools`), but `stestr` was already bringing those in.\n\nMinor annoyance for devs and their already-built envs, but probably tolerable. Gotta update `tools/playbooks/common/install_dependencies.yaml` though (or probe tests will continue to fail).","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":false,"context_lines":[{"line_number":9,"context_line":"pytest-subtests\u003e\u003d0.3.0  # MIT"},{"line_number":10,"context_line":"pytest-cov\u003e\u003d2.12.1  # MIT"},{"line_number":11,"context_line":"stestr\u003e\u003d2.0.0 # Apache-2.0"},{"line_number":12,"context_line":"oslotest\u003e\u003d3.2.0 # Apache-2.0"},{"line_number":13,"context_line":"python-swiftclient\u003e\u003d3.2.0"},{"line_number":14,"context_line":"python-keystoneclient\u003e\u003d3.19.0 # Apache-2.0"},{"line_number":15,"context_line":"boto\u003e\u003d2.32.1"}],"source_content_type":"text/plain","patch_set":3,"id":"e12539dc_62ecd0b2","line":12,"in_reply_to":"fdc6103d_b25d618b","updated":"2026-07-08 13:02:46.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"}],"test/unit/__init__.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":66,"context_line":"class BaseUnitTestCase(BaseTestCase):"},{"line_number":67,"context_line":"    def setUp(self):"},{"line_number":68,"context_line":"        super().setUp()"},{"line_number":69,"context_line":"        self.useFixture(mock_fixture.MockAutospecFixture())"},{"line_number":70,"context_line":"        self.ts_iter \u003d make_timestamp_iter()"},{"line_number":71,"context_line":"        self.normal_ts_iter \u003d make_normal_timestamp_iter()"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5ba1bcf3_1d8d9de9","line":69,"updated":"2026-06-28 23:57:45.000000000","message":"Should this be here, or in `BaseTestCase`? Why should we choose one vs. the other?\n\nAlso, is this the big win? Or is it the `mock_fixture.patch_mock_module()` import side-effect? I guess I should go read up on both of them...","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":66,"context_line":"class BaseUnitTestCase(BaseTestCase):"},{"line_number":67,"context_line":"    def setUp(self):"},{"line_number":68,"context_line":"        super().setUp()"},{"line_number":69,"context_line":"        self.useFixture(mock_fixture.MockAutospecFixture())"},{"line_number":70,"context_line":"        self.ts_iter \u003d make_timestamp_iter()"},{"line_number":71,"context_line":"        self.normal_ts_iter \u003d make_normal_timestamp_iter()"},{"line_number":72,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"2dbc4761_f495b311","line":69,"in_reply_to":"5ba1bcf3_1d8d9de9","updated":"2026-07-08 13:02:46.000000000","message":"`BaseTestCase` would be fine too. `BaseUnitTestCase` was chosen because unit tests typically use mocks / mock.patch, while functional tests not so much. We can move it to `BaseTestCase` if needed.\n\nThere are 2 different things being monkey patched. First of all, the change in `__init__.py` (`mock_fixture.patch_mock_module()`) - basically enforces `autospec\u003dTrue` on all `mock.patch`, `mock.patch.object`, `mock.patch.dict` calls. This needs to be done as early as possible (hence it is in `__init__.py`), otherwise the patcher doesn\u0027t work as intended (tests with `@mock.patch` / `@mock.patch.object` are \"initialized\" with `autospec\u003dNone`).\n\nMeanwhile, this fixture adds the `autospec\u003d` argument to `mock.Mock` and `mock.MagicMock`. It could be included in the `mock_fixture.patch_mock_module()` call, but the intent was to make them separate; you could use `mock_fixture.patch_mock_module()` without this.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"}],"test/unit/cli/test_manage_shard_ranges.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":1002,"context_line":"            with mock.patch(\u0027sys.stdout\u0027, out), \\"},{"line_number":1003,"context_line":"                    mock.patch(\u0027sys.stderr\u0027, err), \\"},{"line_number":1004,"context_line":"                    mock.patch(to_patch, side_effect\u003d[user_input],"},{"line_number":1005,"context_line":"                               create\u003dTrue):"},{"line_number":1006,"context_line":"                ret \u003d main([broker.db_file, \u0027replace\u0027, input_file])"},{"line_number":1007,"context_line":"            self.assertEqual(3, ret)"},{"line_number":1008,"context_line":"            expected \u003d [\u0027This will delete existing 10 shard ranges.\u0027]"}],"source_content_type":"text/x-python","patch_set":3,"id":"3d9ce32e_deedfacc","line":1005,"updated":"2026-06-28 23:57:45.000000000","message":"Hrm. So we\u0027re losing some of the improvements of newer versions of Python?\n\n\u003e *Changed in version 3.5*: If you are patching builtins in a module then you don’t need to pass `create\u003dTrue`, it will be added by default.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f29c4a6a007ac55ff1af77c20abe5c260499114b","unresolved":false,"context_lines":[{"line_number":1002,"context_line":"            with mock.patch(\u0027sys.stdout\u0027, out), \\"},{"line_number":1003,"context_line":"                    mock.patch(\u0027sys.stderr\u0027, err), \\"},{"line_number":1004,"context_line":"                    mock.patch(to_patch, side_effect\u003d[user_input],"},{"line_number":1005,"context_line":"                               create\u003dTrue):"},{"line_number":1006,"context_line":"                ret \u003d main([broker.db_file, \u0027replace\u0027, input_file])"},{"line_number":1007,"context_line":"            self.assertEqual(3, ret)"},{"line_number":1008,"context_line":"            expected \u003d [\u0027This will delete existing 10 shard ranges.\u0027]"}],"source_content_type":"text/x-python","patch_set":3,"id":"499cb176_5df4d4fe","line":1005,"in_reply_to":"3aeb0a93_36ba1d57","updated":"2026-07-10 17:21:36.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":1002,"context_line":"            with mock.patch(\u0027sys.stdout\u0027, out), \\"},{"line_number":1003,"context_line":"                    mock.patch(\u0027sys.stderr\u0027, err), \\"},{"line_number":1004,"context_line":"                    mock.patch(to_patch, side_effect\u003d[user_input],"},{"line_number":1005,"context_line":"                               create\u003dTrue):"},{"line_number":1006,"context_line":"                ret \u003d main([broker.db_file, \u0027replace\u0027, input_file])"},{"line_number":1007,"context_line":"            self.assertEqual(3, ret)"},{"line_number":1008,"context_line":"            expected \u003d [\u0027This will delete existing 10 shard ranges.\u0027]"}],"source_content_type":"text/x-python","patch_set":3,"id":"3aeb0a93_36ba1d57","line":1005,"in_reply_to":"3d9ce32e_deedfacc","updated":"2026-07-08 13:02:46.000000000","message":"When `autospec\u003dTrue`, `mock` will try to `getattr` the attribute being patched. However, `input` is a builtin, it will get an `AttributeError` when trying to get it for patching. `create\u003dTrue` effectively disables autospec. We could set `autospec\u003dFalse` instead (this is one of the exceptions in which we cannot autospec).","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"}],"test/unit/common/ring/test_ring.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":108,"context_line":"        rd.save(ring_fname)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        real_fh \u003d open(ring_fname, \u0027rb\u0027)"},{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"}],"source_content_type":"text/x-python","patch_set":3,"id":"dfb0e3bf_e1dedaca","line":111,"updated":"2026-06-28 23:57:45.000000000","message":"We can\u0027t just say\n```\nwith open(ring_fname, \u0027rb\u0027) as real_fh:\n    ...\n```\nand let the context manager handle clean up?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f29c4a6a007ac55ff1af77c20abe5c260499114b","unresolved":false,"context_lines":[{"line_number":108,"context_line":"        rd.save(ring_fname)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        real_fh \u003d open(ring_fname, \u0027rb\u0027)"},{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"}],"source_content_type":"text/x-python","patch_set":3,"id":"f8b95221_519a4b74","line":111,"in_reply_to":"39d95b74_b13f8f44","updated":"2026-07-10 17:21:36.000000000","message":"Acknowledged","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":108,"context_line":"        rd.save(ring_fname)"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        real_fh \u003d open(ring_fname, \u0027rb\u0027)"},{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"}],"source_content_type":"text/x-python","patch_set":3,"id":"39d95b74_b13f8f44","line":111,"in_reply_to":"dfb0e3bf_e1dedaca","updated":"2026-07-08 13:02:46.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"},{"line_number":115,"context_line":"            self.assertFalse(real_fh.closed)  # sanity"},{"line_number":116,"context_line":"            ring.RingData.load(ring_fname)"},{"line_number":117,"context_line":"            self.assertTrue(real_fh.closed)"}],"source_content_type":"text/x-python","patch_set":3,"id":"72b78ca9_6618965b","line":114,"updated":"2026-06-28 23:57:45.000000000","message":"How much of the `mock.mock_open` benefit remains once we do this? How much of it did we really *need*, given that we\u0027re subbing in an actual open return value?\n\nIf we want to use `mock.mock_open`, would it be better to do something like\n```\nwith open(ring_fname, \u0027rb\u0027) as fh:\n    mock_open \u003d mock.mock_open(read_data\u003dfh.read())\nwith mock.patch(\u0027swift.common.ring.io.open\u0027, mock_open):\n    ...\n```\nand then make assertions about whether `mock_open.close()` (and/or `mock_open.__exit__()`) have been called?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"},{"line_number":115,"context_line":"            self.assertFalse(real_fh.closed)  # sanity"},{"line_number":116,"context_line":"            ring.RingData.load(ring_fname)"},{"line_number":117,"context_line":"            self.assertTrue(real_fh.closed)"}],"source_content_type":"text/x-python","patch_set":3,"id":"ef4f59ef_df6698e3","line":114,"in_reply_to":"72b78ca9_6618965b","updated":"2026-07-08 13:02:46.000000000","message":"Fair enough.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f29c4a6a007ac55ff1af77c20abe5c260499114b","unresolved":false,"context_lines":[{"line_number":111,"context_line":"        self.addCleanup(real_fh.close)"},{"line_number":112,"context_line":"        with mock.patch(\u0027swift.common.ring.io.open\u0027,"},{"line_number":113,"context_line":"                        new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":114,"context_line":"            mock_open.return_value \u003d real_fh"},{"line_number":115,"context_line":"            self.assertFalse(real_fh.closed)  # sanity"},{"line_number":116,"context_line":"            ring.RingData.load(ring_fname)"},{"line_number":117,"context_line":"            self.assertTrue(real_fh.closed)"}],"source_content_type":"text/x-python","patch_set":3,"id":"b5c711a4_b3ab634a","line":114,"in_reply_to":"ef4f59ef_df6698e3","updated":"2026-07-10 17:21:36.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"f0a7f0a06c00c946518be745666c5a86a9321c48","unresolved":false,"context_lines":[{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        with open(ring_fname, \u0027rb\u0027) as real_fh, \\"},{"line_number":111,"context_line":"                mock.patch(\u0027swift.common.ring.io.open\u0027, autospec\u003dFalse,"},{"line_number":112,"context_line":"                          return_value\u003dreal_fh):"},{"line_number":113,"context_line":"            self.assertFalse(real_fh.closed)  # sanity"},{"line_number":114,"context_line":"            ring.RingData.load(ring_fname)"},{"line_number":115,"context_line":"            self.assertTrue(real_fh.closed)"}],"source_content_type":"text/x-python","patch_set":5,"id":"8c12aec8_f55c0c72","line":112,"updated":"2026-07-08 14:29:37.000000000","message":"pep8: E128 continuation line under-indented for visual indent","commit_id":"55a05708d02e1dba45459e61ed54463a7c2f0423"}],"test/unit/common/test_direct_client.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":91,"context_line":"    mocked \u003d kwargs.pop(\u0027mocked\u0027, \u0027swift.common.bufferedhttp.http_connect_raw\u0027)"},{"line_number":92,"context_line":"    fake_conn \u003d FakeConn(*args, **kwargs)"},{"line_number":93,"context_line":"    with mock.patch(mocked,"},{"line_number":94,"context_line":"                    side_effect\u003dfake_conn._update_raw_call_args):"},{"line_number":95,"context_line":"        yield fake_conn"},{"line_number":96,"context_line":""},{"line_number":97,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"10f4773e_361bf27c","line":94,"updated":"2026-06-28 23:57:45.000000000","message":"OK, this is some nice cleanup. 👍","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":5802,"context_line":"@mock.patch(\u0027swift.common.utils.open\u0027, new_callable\u003dmock.mock_open)"},{"line_number":5803,"context_line":"class TestGetPpid(unittest.TestCase):"},{"line_number":5804,"context_line":"    def test_happy_path(self, mock_open):"},{"line_number":5805,"context_line":"        mock_open.return_value.__enter__().read.return_value \u003d \\"},{"line_number":5806,"context_line":"            \u0027pid comm stat 456 see the procfs(5) man page for more info\\n\u0027"},{"line_number":5807,"context_line":"        self.assertEqual(utils.get_ppid(123), 456)"},{"line_number":5808,"context_line":"        self.assertIn(mock.call(\u0027/proc/123/stat\u0027), mock_open.mock_calls)"}],"source_content_type":"text/x-python","patch_set":3,"id":"1df1bd4e_bd20c9b0","line":5805,"range":{"start_line":5805,"start_character":31,"end_line":5805,"end_character":42},"updated":"2026-06-28 23:57:45.000000000","message":"We don\u0027t want/need to use `__enter__.return_value` to navigate here? I guess because it takes no args?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":false,"context_lines":[{"line_number":5802,"context_line":"@mock.patch(\u0027swift.common.utils.open\u0027, new_callable\u003dmock.mock_open)"},{"line_number":5803,"context_line":"class TestGetPpid(unittest.TestCase):"},{"line_number":5804,"context_line":"    def test_happy_path(self, mock_open):"},{"line_number":5805,"context_line":"        mock_open.return_value.__enter__().read.return_value \u003d \\"},{"line_number":5806,"context_line":"            \u0027pid comm stat 456 see the procfs(5) man page for more info\\n\u0027"},{"line_number":5807,"context_line":"        self.assertEqual(utils.get_ppid(123), 456)"},{"line_number":5808,"context_line":"        self.assertIn(mock.call(\u0027/proc/123/stat\u0027), mock_open.mock_calls)"}],"source_content_type":"text/x-python","patch_set":3,"id":"a6f50c66_ceff62b4","line":5805,"range":{"start_line":5805,"start_character":31,"end_line":5805,"end_character":42},"in_reply_to":"1df1bd4e_bd20c9b0","updated":"2026-07-08 13:02:46.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"}],"test/unit/container/test_server.py":[{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"0878d461b38749b91cda37a7b0d798f7f5b0cf6e","unresolved":false,"context_lines":[{"line_number":40,"context_line":"from swift.container import server as container_server"},{"line_number":41,"context_line":"from swift.common import constraints"},{"line_number":42,"context_line":"from swift.common.utils.timestamp import Timestamp"},{"line_number":43,"context_line":"from swift.common.utils import (mkdirs, public, replication,"},{"line_number":44,"context_line":"                                storage_directory, lock_parent_directory,"},{"line_number":45,"context_line":"                                ShardRange, RESERVED_STR, Namespace)"},{"line_number":46,"context_line":"from test.debug_logger import debug_logger"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a6dfd66_01917ff9","line":43,"updated":"2026-06-24 18:54:08.000000000","message":"pep8: F401 \u0027swift.common.utils.replication\u0027 imported but unused","commit_id":"443d9ee538bfe24c78585582ccc9371026319e24"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":39,"context_line":"import swift.container"},{"line_number":40,"context_line":"from swift.common import constraints"},{"line_number":41,"context_line":"from swift.common.utils.timestamp import Timestamp"},{"line_number":42,"context_line":"from swift.common.utils import (mkdirs, public, replication,"},{"line_number":43,"context_line":"                                storage_directory, lock_parent_directory,"},{"line_number":44,"context_line":"                                ShardRange, RESERVED_STR, Namespace)"},{"line_number":45,"context_line":"from test.debug_logger import debug_logger"}],"source_content_type":"text/x-python","patch_set":2,"id":"efa309ee_2ebe1140","line":42,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F401 \u0027swift.common.utils.replication\u0027 imported but unused","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        mkdirs(os.path.join(self.testdir, \u0027sda1\u0027))"},{"line_number":74,"context_line":"        mkdirs(os.path.join(self.testdir, \u0027sda1\u0027, \u0027tmp\u0027))"},{"line_number":75,"context_line":"        self.logger \u003d debug_logger()"},{"line_number":76,"context_line":"        self.controller \u003d container_server.ContainerController("},{"line_number":77,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027},"},{"line_number":78,"context_line":"            logger\u003dself.logger)"},{"line_number":79,"context_line":"        # some of the policy tests want at least two policies"}],"source_content_type":"text/x-python","patch_set":2,"id":"f60ba545_a89f39c8","line":76,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    def test_creation(self):"},{"line_number":117,"context_line":"        # later config should be extended to assert more config options"},{"line_number":118,"context_line":"        app \u003d container_server.ContainerController("},{"line_number":119,"context_line":"            {\u0027node_timeout\u0027: \u00273.5\u0027}, logger\u003dself.logger)"},{"line_number":120,"context_line":"        self.assertEqual(app.node_timeout, 3.5)"},{"line_number":121,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\u0027warning\u0027), [])"}],"source_content_type":"text/x-python","patch_set":2,"id":"1167caaa_c8dcdef8","line":118,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":376,"context_line":"        self.assertEqual(resp.status_int, 400)"},{"line_number":377,"context_line":""},{"line_number":378,"context_line":"    def test_OPTIONS(self):"},{"line_number":379,"context_line":"        server_handler \u003d container_server.ContainerController("},{"line_number":380,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027})"},{"line_number":381,"context_line":"        req \u003d Request.blank(\u0027/sda1/p/a/c/o\u0027, {\u0027REQUEST_METHOD\u0027: \u0027OPTIONS\u0027})"},{"line_number":382,"context_line":"        req.content_length \u003d 0"}],"source_content_type":"text/x-python","patch_set":2,"id":"f966ec4c_0a4d99ef","line":379,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":389,"context_line":""},{"line_number":390,"context_line":"    def test_insufficient_storage_mount_check_true(self):"},{"line_number":391,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027true\u0027}"},{"line_number":392,"context_line":"        container_controller \u003d container_server.ContainerController(conf)"},{"line_number":393,"context_line":"        self.assertTrue(container_controller.mount_check)"},{"line_number":394,"context_line":"        for method in container_controller.allowed_methods:"},{"line_number":395,"context_line":"            if method \u003d\u003d \u0027OPTIONS\u0027:"}],"source_content_type":"text/x-python","patch_set":2,"id":"2ab507ba_e077a3ec","line":392,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":416,"context_line":""},{"line_number":417,"context_line":"    def test_insufficient_storage_mount_check_false(self):"},{"line_number":418,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027}"},{"line_number":419,"context_line":"        container_controller \u003d container_server.ContainerController(conf)"},{"line_number":420,"context_line":"        self.assertFalse(container_controller.mount_check)"},{"line_number":421,"context_line":"        for method in container_controller.allowed_methods:"},{"line_number":422,"context_line":"            if method \u003d\u003d \u0027OPTIONS\u0027:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3ffb6ea6_8295f608","line":419,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":516,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir,"},{"line_number":517,"context_line":"                \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":518,"context_line":"                \u0027fallocate_reserve\u0027: \u00272%\u0027}"},{"line_number":519,"context_line":"        container_controller \u003d container_server.ContainerController(conf)"},{"line_number":520,"context_line":""},{"line_number":521,"context_line":"        req \u003d Request.blank("},{"line_number":522,"context_line":"            \u0027/sda1/p/a/c\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"e37f8938_6ac571f3","line":519,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":1196,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir,"},{"line_number":1197,"context_line":"                \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":1198,"context_line":"                \u0027fallocate_reserve\u0027: \u00272%\u0027}"},{"line_number":1199,"context_line":"        container_controller \u003d container_server.ContainerController(conf)"},{"line_number":1200,"context_line":""},{"line_number":1201,"context_line":"        req \u003d Request.blank("},{"line_number":1202,"context_line":"            \u0027/sda1/p/a/c\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"6335e7fe_dcc38299","line":1199,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":1231,"context_line":"        self.assertEqual(resp.status_int, 400)"},{"line_number":1232,"context_line":""},{"line_number":1233,"context_line":"    def test_POST_invalid_container_sync_to(self):"},{"line_number":1234,"context_line":"        self.controller \u003d container_server.ContainerController("},{"line_number":1235,"context_line":"            {\u0027devices\u0027: self.testdir})"},{"line_number":1236,"context_line":"        req \u003d Request.blank("},{"line_number":1237,"context_line":"            \u0027/sda-null/p/a/c\u0027, environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027POST\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"b8631c43_16190caa","line":1234,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":1618,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir,"},{"line_number":1619,"context_line":"                \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":1620,"context_line":"                \u0027fallocate_reserve\u0027: \u00272%\u0027}"},{"line_number":1621,"context_line":"        container_controller \u003d container_server.ContainerController(conf)"},{"line_number":1622,"context_line":""},{"line_number":1623,"context_line":"        req \u003d Request.blank("},{"line_number":1624,"context_line":"            \u0027/sda1/p/a/\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"302698db_f43d577e","line":1621,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":2034,"context_line":""},{"line_number":2035,"context_line":"        req \u003d Request.blank(path, method\u003d\u0027PUT\u0027,"},{"line_number":2036,"context_line":"                            headers\u003d{\u0027X-Timestamp\u0027: \u00274\u0027})"},{"line_number":2037,"context_line":"        with mock.patch.object(container_server.os.path, \u0027exists\u0027,"},{"line_number":2038,"context_line":"                               mock_exists):"},{"line_number":2039,"context_line":"            resp \u003d req.get_response(self.controller)"},{"line_number":2040,"context_line":"        # db was successfully created"}],"source_content_type":"text/x-python","patch_set":2,"id":"73ec7ef2_b3b4485f","line":2037,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6042,"context_line":"                     \u0027X-Account-Host\u0027: \u00271.2.3.4:5, 6.7.8.9:10\u0027,"},{"line_number":6043,"context_line":"                     \u0027X-Account-Device\u0027: \u0027sdb1, sdf1\u0027})"},{"line_number":6044,"context_line":""},{"line_number":6045,"context_line":"        orig_http_connect \u003d container_server.http_connect"},{"line_number":6046,"context_line":"        try:"},{"line_number":6047,"context_line":"            container_server.http_connect \u003d fake_http_connect"},{"line_number":6048,"context_line":"            req.get_response(self.controller)"}],"source_content_type":"text/x-python","patch_set":2,"id":"fa0ae853_1f6a2f03","line":6045,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6044,"context_line":""},{"line_number":6045,"context_line":"        orig_http_connect \u003d container_server.http_connect"},{"line_number":6046,"context_line":"        try:"},{"line_number":6047,"context_line":"            container_server.http_connect \u003d fake_http_connect"},{"line_number":6048,"context_line":"            req.get_response(self.controller)"},{"line_number":6049,"context_line":"        finally:"},{"line_number":6050,"context_line":"            container_server.http_connect \u003d orig_http_connect"}],"source_content_type":"text/x-python","patch_set":2,"id":"68518829_755292d1","line":6047,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6047,"context_line":"            container_server.http_connect \u003d fake_http_connect"},{"line_number":6048,"context_line":"            req.get_response(self.controller)"},{"line_number":6049,"context_line":"        finally:"},{"line_number":6050,"context_line":"            container_server.http_connect \u003d orig_http_connect"},{"line_number":6051,"context_line":""},{"line_number":6052,"context_line":"        http_connect_args.sort(key\u003doperator.itemgetter(\u0027ipaddr\u0027))"},{"line_number":6053,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"1af260df_9b84ef26","line":6050,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6091,"context_line":""},{"line_number":6092,"context_line":"    def test_serv_reserv(self):"},{"line_number":6093,"context_line":"        # Test replication_server flag was set from configuration file."},{"line_number":6094,"context_line":"        container_controller \u003d container_server.ContainerController"},{"line_number":6095,"context_line":"        conf \u003d {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027}"},{"line_number":6096,"context_line":"        self.assertTrue(container_controller(conf).replication_server)"},{"line_number":6097,"context_line":"        for val in [True, \u00271\u0027, \u0027True\u0027, \u0027true\u0027]:"}],"source_content_type":"text/x-python","patch_set":2,"id":"b31452ef_38aea27b","line":6094,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6118,"context_line":"        inbuf \u003d BytesIO()"},{"line_number":6119,"context_line":"        errbuf \u003d StringIO()"},{"line_number":6120,"context_line":"        outbuf \u003d StringIO()"},{"line_number":6121,"context_line":"        self.controller \u003d container_server.ContainerController("},{"line_number":6122,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":6123,"context_line":"             \u0027replication_server\u0027: \u0027false\u0027})"},{"line_number":6124,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"9dee13e3_ddacd6cc","line":6121,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6159,"context_line":"        inbuf \u003d BytesIO()"},{"line_number":6160,"context_line":"        errbuf \u003d StringIO()"},{"line_number":6161,"context_line":"        outbuf \u003d StringIO()"},{"line_number":6162,"context_line":"        self.controller \u003d container_server.ContainerController("},{"line_number":6163,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":6164,"context_line":"             \u0027replication_server\u0027: \u0027false\u0027})"},{"line_number":6165,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"87a24f24_38e25bb0","line":6162,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6197,"context_line":"        inbuf \u003d BytesIO()"},{"line_number":6198,"context_line":"        errbuf \u003d StringIO()"},{"line_number":6199,"context_line":"        outbuf \u003d StringIO()"},{"line_number":6200,"context_line":"        self.controller \u003d container_server.ContainerController("},{"line_number":6201,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":6202,"context_line":"             \u0027replication_server\u0027: \u0027true\u0027})"},{"line_number":6203,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"6e2a2f22_ba145fcb","line":6200,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"2f069dcb33e9967b0b9326d80f5cd7421b13a7ce","unresolved":false,"context_lines":[{"line_number":6231,"context_line":"        errbuf \u003d StringIO()"},{"line_number":6232,"context_line":"        outbuf \u003d StringIO()"},{"line_number":6233,"context_line":"        self.logger \u003d debug_logger(\u0027test\u0027)"},{"line_number":6234,"context_line":"        self.container_controller \u003d container_server.ContainerController("},{"line_number":6235,"context_line":"            {\u0027devices\u0027: self.testdir, \u0027mount_check\u0027: \u0027false\u0027,"},{"line_number":6236,"context_line":"             \u0027replication_server\u0027: \u0027false\u0027, \u0027log_requests\u0027: \u0027false\u0027},"},{"line_number":6237,"context_line":"            logger\u003dself.logger)"}],"source_content_type":"text/x-python","patch_set":2,"id":"125ec6c6_991be54c","line":6234,"updated":"2026-06-25 10:38:04.000000000","message":"pep8: F821 undefined name \u0027container_server\u0027","commit_id":"bc1c73beebf28cf2168e5d6dca7277dd61e401fe"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":6189,"context_line":"                  b\u0027allowed for this resource.\u003c/p\u003e\u003c/html\u003e\u0027]"},{"line_number":6190,"context_line":"        with mock.patch.object(self.controller, method) as mock_method:"},{"line_number":6191,"context_line":"            mock_method.replication \u003d True"},{"line_number":6192,"context_line":"            mock_method.publicly_accessible \u003d True"},{"line_number":6193,"context_line":"            response \u003d self.controller.__call__(env, start_response)"},{"line_number":6194,"context_line":"            self.assertEqual(response, answer)"},{"line_number":6195,"context_line":"            self.assertEqual(outbuf.getvalue()[:4], \u0027405 \u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"6f252b91_9f9eb1e0","line":6192,"updated":"2026-06-28 23:57:45.000000000","message":"Are we sure we really want to go reimplementing `@public` and `@replication` in tests?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":6189,"context_line":"                  b\u0027allowed for this resource.\u003c/p\u003e\u003c/html\u003e\u0027]"},{"line_number":6190,"context_line":"        with mock.patch.object(self.controller, method) as mock_method:"},{"line_number":6191,"context_line":"            mock_method.replication \u003d True"},{"line_number":6192,"context_line":"            mock_method.publicly_accessible \u003d True"},{"line_number":6193,"context_line":"            response \u003d self.controller.__call__(env, start_response)"},{"line_number":6194,"context_line":"            self.assertEqual(response, answer)"},{"line_number":6195,"context_line":"            self.assertEqual(outbuf.getvalue()[:4], \u0027405 \u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"b1927690_70a44d35","line":6192,"in_reply_to":"6f252b91_9f9eb1e0","updated":"2026-07-08 13:02:46.000000000","message":"Right, I\u0027ve updated those.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f29c4a6a007ac55ff1af77c20abe5c260499114b","unresolved":false,"context_lines":[{"line_number":6189,"context_line":"                  b\u0027allowed for this resource.\u003c/p\u003e\u003c/html\u003e\u0027]"},{"line_number":6190,"context_line":"        with mock.patch.object(self.controller, method) as mock_method:"},{"line_number":6191,"context_line":"            mock_method.replication \u003d True"},{"line_number":6192,"context_line":"            mock_method.publicly_accessible \u003d True"},{"line_number":6193,"context_line":"            response \u003d self.controller.__call__(env, start_response)"},{"line_number":6194,"context_line":"            self.assertEqual(response, answer)"},{"line_number":6195,"context_line":"            self.assertEqual(outbuf.getvalue()[:4], \u0027405 \u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"c8232608_2395748e","line":6192,"in_reply_to":"b1927690_70a44d35","updated":"2026-07-10 17:21:36.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":6258,"context_line":"               \u0027wsgi.multiprocess\u0027: False,"},{"line_number":6259,"context_line":"               \u0027wsgi.run_once\u0027: False}"},{"line_number":6260,"context_line":""},{"line_number":6261,"context_line":"        @public"},{"line_number":6262,"context_line":"        def mock_put_method(*args, **kwargs):"},{"line_number":6263,"context_line":"            raise Exception()"},{"line_number":6264,"context_line":""},{"line_number":6265,"context_line":"        with mock.patch.object(self.container_controller, method,"},{"line_number":6266,"context_line":"                               new\u003dmock_put_method):"},{"line_number":6267,"context_line":"            response \u003d self.container_controller.__call__(env, start_response)"},{"line_number":6268,"context_line":"            self.assertTrue(response[0].startswith("},{"line_number":6269,"context_line":"                b\u0027Traceback (most recent call last):\u0027))"}],"source_content_type":"text/x-python","patch_set":3,"id":"7779ca4b_b84aea34","line":6266,"range":{"start_line":6261,"start_character":0,"end_line":6266,"end_character":52},"updated":"2026-06-28 23:57:45.000000000","message":"I\u0027m a little surprised this didn\u0027t get rewritten, too.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":false,"context_lines":[{"line_number":6258,"context_line":"               \u0027wsgi.multiprocess\u0027: False,"},{"line_number":6259,"context_line":"               \u0027wsgi.run_once\u0027: False}"},{"line_number":6260,"context_line":""},{"line_number":6261,"context_line":"        @public"},{"line_number":6262,"context_line":"        def mock_put_method(*args, **kwargs):"},{"line_number":6263,"context_line":"            raise Exception()"},{"line_number":6264,"context_line":""},{"line_number":6265,"context_line":"        with mock.patch.object(self.container_controller, method,"},{"line_number":6266,"context_line":"                               new\u003dmock_put_method):"},{"line_number":6267,"context_line":"            response \u003d self.container_controller.__call__(env, start_response)"},{"line_number":6268,"context_line":"            self.assertTrue(response[0].startswith("},{"line_number":6269,"context_line":"                b\u0027Traceback (most recent call last):\u0027))"}],"source_content_type":"text/x-python","patch_set":3,"id":"ed5653f6_015bc5eb","line":6266,"range":{"start_line":6261,"start_character":0,"end_line":6266,"end_character":52},"in_reply_to":"7779ca4b_b84aea34","updated":"2026-07-08 13:02:46.000000000","message":"Done","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":22348,"name":"Zuul","username":"zuul","tags":["SERVICE_USER"]},"tag":"autogenerated:zuul:check","change_message_id":"44a244f799759404f24b99158930217356fa616f","unresolved":false,"context_lines":[{"line_number":6151,"context_line":"        method_res \u003d mock.MagicMock()"},{"line_number":6152,"context_line":"        with mock.patch.object(self.controller, method) as mock_method:"},{"line_number":6153,"context_line":"            mock_method.publicly_accessible \u003d True"},{"line_number":6154,"context_line":"            # Mock attributes are truthy by default; without this, allowed_methods"},{"line_number":6155,"context_line":"            # would treat PUT as a replication-only method and return 405."},{"line_number":6156,"context_line":"            mock_method.replication \u003d False"},{"line_number":6157,"context_line":"            mock_method.return_value.return_value \u003d method_res"}],"source_content_type":"text/x-python","patch_set":4,"id":"7a6ada9d_2a4b02e7","line":6154,"updated":"2026-07-08 11:17:02.000000000","message":"pep8: E501 line too long (82 \u003e 79 characters)","commit_id":"ca35b53f0a033f600ec9dcae3f8e6b4138b49dfb"}],"test/unit/obj/test_diskfile.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e399de7889e360a64d6289c7fdd22784aa4af562","unresolved":true,"context_lines":[{"line_number":1139,"context_line":"        with temptree([]) as tmpdir:"},{"line_number":1140,"context_line":"            os.makedirs(os.path.join(tmpdir, \"sdf\", \"objects\", \"1\", \"a\", \"b\"))"},{"line_number":1141,"context_line":"            with mock.patch(\u0027swift.obj.diskfile.open\u0027,"},{"line_number":1142,"context_line":"                            new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":1143,"context_line":"                # File does not exist yet - write expected"},{"line_number":1144,"context_line":"                update_auditor_status(tmpdir, None, [\u002742\u0027], \"ALL\")"},{"line_number":1145,"context_line":"                self.assertEqual(1, mock_open.call_count)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5a9a6b68_92339d8e","line":1142,"updated":"2026-06-28 23:57:45.000000000","message":"We don\u0027t need a `create\u003dTrue` on this one?","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"},{"author":{"_account_id":8213,"name":"Claudiu Belu","email":"cbelu@cloudbasesolutions.com","username":"claudiub"},"change_message_id":"4b9eab15adf5e7ef7e2663af6e9a54222c4d128e","unresolved":true,"context_lines":[{"line_number":1139,"context_line":"        with temptree([]) as tmpdir:"},{"line_number":1140,"context_line":"            os.makedirs(os.path.join(tmpdir, \"sdf\", \"objects\", \"1\", \"a\", \"b\"))"},{"line_number":1141,"context_line":"            with mock.patch(\u0027swift.obj.diskfile.open\u0027,"},{"line_number":1142,"context_line":"                            new_callable\u003dmock.mock_open) as mock_open:"},{"line_number":1143,"context_line":"                # File does not exist yet - write expected"},{"line_number":1144,"context_line":"                update_auditor_status(tmpdir, None, [\u002742\u0027], \"ALL\")"},{"line_number":1145,"context_line":"                self.assertEqual(1, mock_open.call_count)"}],"source_content_type":"text/x-python","patch_set":3,"id":"f7c23c1f_56a71273","line":1142,"in_reply_to":"5a9a6b68_92339d8e","updated":"2026-07-08 13:02:46.000000000","message":"For `open`, no. `mock.mock_open` create a very `open`-like mock, and it is the best way to mock `open`.","commit_id":"a40249331c6d0d967c8936d3844c64c4336b2d2b"}]}
