)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"b884fd25312c4ceaa911405483cf941af920d6c9","unresolved":true,"context_lines":[{"line_number":12,"context_line":"sequence, whatever ran before in the same worker breaks the initial"},{"line_number":13,"context_line":"assertNotIn() of these tests (observed on the buildd: mdev_nvidia-11"},{"line_number":14,"context_line":"and neutron_physnet_foo already present in CONF), and the tests\u0027"},{"line_number":15,"context_line":"own registration leaks into everything running after them."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Run the tests against a private ConfigOpts instead: they stay"},{"line_number":18,"context_line":"hermetic regardless of what ran before, they keep verifying exactly"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"158f029b_f73dbecb","line":15,"updated":"2026-10-27 16:26:38.000000000","message":"do you have a traceback or test order that actully cause a test to fail\nor is this specultive based on inspecting the code wihtouh know we use\na dedicated cofnig fidture that is metn to handel all cofnig option unregistration for us.","commit_id":"b380f4048f23bcd38c1711cc0e0c664be125074a"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"bd37b1c84622f49354d618d50ce1d3cb6c863e23","unresolved":false,"context_lines":[{"line_number":12,"context_line":"sequence, whatever ran before in the same worker breaks the initial"},{"line_number":13,"context_line":"assertNotIn() of these tests (observed on the buildd: mdev_nvidia-11"},{"line_number":14,"context_line":"and neutron_physnet_foo already present in CONF), and the tests\u0027"},{"line_number":15,"context_line":"own registration leaks into everything running after them."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Run the tests against a private ConfigOpts instead: they stay"},{"line_number":18,"context_line":"hermetic regardless of what ran before, they keep verifying exactly"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"9433f41e_76f569b9","line":15,"in_reply_to":"158f029b_f73dbecb","updated":"2026-11-06 08:57:18.000000000","message":"Done","commit_id":"b380f4048f23bcd38c1711cc0e0c664be125074a"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"bd37b1c84622f49354d618d50ce1d3cb6c863e23","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"3d03fd40_114d62d3","updated":"2026-11-06 08:57:18.000000000","message":"FYI, here\u0027s the traceback that I am trying to fix:\n\nin test_neutron:\n\nFAIL: nova.tests.unit.conf.test_neutron.NeutronConfTestCase.test_register_dynamic_opts\nTraceback (most recent call last):\n  File \"/build/nova-I8vCKM/nova-34.0.0/nova/tests/unit/conf/test_neutron.py\", line 27, in test_register_dynamic_opts\n    self.assertNotIn(\u0027neutron_physnet_foo\u0027, CONF)\n  File \"/usr/lib/python3/dist-packages/testtools/testcase.py\", line 562, in assertNotIn\n    self.assertThat(haystack, matcher, message)\n  File \"/usr/lib/python3/dist-packages/testtools/testcase.py\", line 704, in assertThat\n    raise mismatch_error\ntesttools.matchers._impl.MismatchError: \u003coslo_config.cfg.ConfigOpts object at 0x7f6e71c0dbe0\u003e matches Contains(\u0027neutron_physnet_foo\u0027)\n\nin test_devices:\n\nFAIL: nova.tests.unit.conf.test_devices.DevicesConfTestCase.test_register_dynamic_opts\nTraceback (most recent call last):\n  File \"/build/nova-I8vCKM/nova-34.0.0/nova/tests/unit/conf/test_devices.py\", line 26, in test_register_dynamic_opts\n    self.assertNotIn(\u0027mdev_nvidia-11\u0027, CONF)\n  File \"/usr/lib/python3/dist-packages/testtools/testcase.py\", line 562, in assertNotIn\n    self.assertThat(haystack, matcher, message)\n  File \"/usr/lib/python3/dist-packages/testtools/testcase.py\", line 704, in assertThat\n    raise mismatch_error\ntesttools.matchers._impl.MismatchError: \u003coslo_config.cfg.ConfigOpts object at 0x7f394be11be0\u003e matches Contains(\u0027mdev_nvidia-11\u0027)\n\nThey both share a specific order to be triggered:\n\nRun first LibvirtConnTestCase.test_get_host_numa_topology that calls nova.conf.neutron.register_dynamic_opts(CONF).","commit_id":"b380f4048f23bcd38c1711cc0e0c664be125074a"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"0754f2a553a0846178f5c72403409ff4aaece737","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"ddfd5b0b_41c38577","updated":"2026-10-28 08:40:59.000000000","message":"Thanks for the review.\n\nFYI, this bug is not speculative; I have experienced it, in a deterministic way, while building the Hibiscus package for Debian, and a two-test pair that fails on Nova master branch, proving that it passes with this patch.\n\nThe failure when building the Debian package in unstable (Hibiscus, so 34.0.0):\nFAIL: nova.tests.unit.conf.test_neutron.NeutronConfTestCase.test_register_dynamic_opts\n...\nMismatchError: \u003coslo_config.cfg.ConfigOpts object\u003e matches Contains(\u0027neutron_physnet_foo\u0027)\nand the mdev twin in the same run: Contains(\u0027mdev_nvidia-11\u0027) against conf.test_devices.test_register_dynamic_opts.\n\nHere\u0027s the test order in my run: the test LibvirtConnTestCase.test_get_host_numa_topology ran before, which calls nova.conf.neutron.register_dynamic_opts(CONF) directly. 300+ tests later the test suite runs conf.test_neutron.test_register_dynamic_opts, and the build got the issue. So I tried replaying just those two tests in one process, in that order, on Nova master branch, to reproduce the failure. With this patch, it passes.\n\nThe config fixture you\u0027re suggesting, unless I missunderstood your suggestion, will unfortunately not fix things: the ConfFixture wraps the global CONF, its cleanup unregisters only the options that were registered through the fixture itself (Config._registered_config_opts) and then calls ConfigOpts.reset(). Neither touches groups/options registered at runtime by product code.\n\nHere\u0027s a minimal repro outside nova\u0027s tests that is probably easier to understand:\n\nconf \u003d cfg.ConfigOpts()\nconf.register_group(devices_group)\nconf.register_opts(mdev_opts, group\u003ddevices_group)\nconf.set_override(\u0027enabled_mdev_types\u0027, [\u0027nvidia-11\u0027], group\u003d\u0027devices\u0027)\nnova.conf.devices.register_dynamic_opts(conf)\nassert \u0027mdev_nvidia-11\u0027 in conf   # True\nconf.reset()\nassert \u0027mdev_nvidia-11\u0027 in conf   # True — the group survives the fixture cleanup\n\nThe suggested self.config_fixture \u003d self.useFixture(ConfFixture(CONF)) + CONF \u003d self.config_fixture.conf would still wrap the same global CONF object, so the groups would survive that too.\n\nSince test_get_host_numa_topology registers the dynamic opts straight into the global CONF and nothing ever unregisters them, every later test in that worker that assumes a pristine CONF sees them. This patch keeps the two conf tests hermetic in both directions: they can\u0027t be broken by earlier registrations, and their own registration can\u0027t leak into later tests.\n\nI can do in another way if you can suggest something else. For example, having tests that call register_dynamic_opts() clean up and the enf of the tests. But given the groups survive reset(), a fresh ConfigOpts seemed the most self-contained way to make these tests robust.","commit_id":"b380f4048f23bcd38c1711cc0e0c664be125074a"}],"nova/tests/unit/conf/test_devices.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"b884fd25312c4ceaa911405483cf941af920d6c9","unresolved":true,"context_lines":[{"line_number":18,"context_line":"class DevicesConfTestCase(test.NoDBTestCase):"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"    def test_register_dynamic_opts(self):"},{"line_number":21,"context_line":"        # Use a private ConfigOpts: the dynamic opts are registered"},{"line_number":22,"context_line":"        # against whatever CONF is passed in and nothing ever"},{"line_number":23,"context_line":"        # unregisters them. Other tests may have registered mdev opts"},{"line_number":24,"context_line":"        # before us in the same worker (the dynamic stestr scheduler"},{"line_number":25,"context_line":"        # runs hundreds of groups per worker), which would break the"},{"line_number":26,"context_line":"        # asserts below, and our own registration would leak into the"},{"line_number":27,"context_line":"        # tests running after us."},{"line_number":28,"context_line":"        conf \u003d cfg.ConfigOpts()"},{"line_number":29,"context_line":"        nova.conf.devices.register_opts(conf)"},{"line_number":30,"context_line":"        conf.set_override(\u0027enabled_mdev_types\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"dafb53b1_a28257f2","line":27,"range":{"start_line":21,"start_character":7,"end_line":27,"end_character":33},"updated":"2026-10-27 16:26:38.000000000","message":"we use a config fixtgure in the base class so that you dont need too\ncreate serepat econfig otpions liek this. in tests.\n\nhttps://github.com/openstack/nova/blob/master/nova/tests/fixtures/conf.py#L26-L83\n\nit inherits form the fixture provide by oslo config\n\nhttps://github.com/openstack/oslo.config/blob/master/oslo_config/fixture.py#L25\n\nso before each test we create a new config object\n\nand it does call unregstionr after each test via cleanup\n\nhttps://github.com/openstack/oslo.config/blob/master/oslo_config/fixture.py#L47\n\nso this shoudl not be needed.\n\n\nif we were to change it then i woudl be more enclided to update\nhttps://github.com/openstack/nova/blob/master/nova/test.py#L238\n`self.useFixture(nova_fixtures.ConfFixture(CONF))`\nto  `self.config_fixture \u003d  self.useFixture(nova_fixtures.ConfFixture(CONF))`\n\nthen here remove CONF \u003d nova.conf.CONF\n\nand in thie test defien\n\nCONF \u003d self.config_fixture.conf","commit_id":"b380f4048f23bcd38c1711cc0e0c664be125074a"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"bd37b1c84622f49354d618d50ce1d3cb6c863e23","unresolved":false,"context_lines":[{"line_number":18,"context_line":"class DevicesConfTestCase(test.NoDBTestCase):"},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"    def test_register_dynamic_opts(self):"},{"line_number":21,"context_line":"        # Use a private ConfigOpts: the dynamic opts are registered"},{"line_number":22,"context_line":"        # against whatever CONF is passed in and nothing ever"},{"line_number":23,"context_line":"        # unregisters them. Other tests may have registered mdev opts"},{"line_number":24,"context_line":"        # before us in the same worker (the dynamic stestr scheduler"},{"line_number":25,"context_line":"        # runs hundreds of groups per worker), which would break the"},{"line_number":26,"context_line":"        # asserts below, and our own registration would leak into the"},{"line_number":27,"context_line":"        # tests running after us."},{"line_number":28,"context_line":"        conf \u003d cfg.ConfigOpts()"},{"line_number":29,"context_line":"        nova.conf.devices.register_opts(conf)"},{"line_number":30,"context_line":"        conf.set_override(\u0027enabled_mdev_types\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"4929eddc_b5f30ecf","line":27,"range":{"start_line":21,"start_character":7,"end_line":27,"end_character":33},"in_reply_to":"dafb53b1_a28257f2","updated":"2026-11-06 08:57:18.000000000","message":"Done","commit_id":"b380f4048f23bcd38c1711cc0e0c664be125074a"}],"nova/tests/unit/conf/test_neutron.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"b884fd25312c4ceaa911405483cf941af920d6c9","unresolved":true,"context_lines":[{"line_number":20,"context_line":"class NeutronConfTestCase(test.NoDBTestCase):"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"    def test_register_dynamic_opts(self):"},{"line_number":23,"context_line":"        # Use a private ConfigOpts: the dynamic opts are registered"},{"line_number":24,"context_line":"        # against whatever CONF is passed in and nothing ever"},{"line_number":25,"context_line":"        # unregisters them. Other tests may have registered physnet"},{"line_number":26,"context_line":"        # opts before us in the same worker (the dynamic stestr"},{"line_number":27,"context_line":"        # scheduler runs hundreds of groups per worker), which would"},{"line_number":28,"context_line":"        # break the asserts below, and our own registration would leak"},{"line_number":29,"context_line":"        # into the tests running after us."},{"line_number":30,"context_line":"        conf \u003d cfg.ConfigOpts()"},{"line_number":31,"context_line":"        conf.register_group(nova.conf.neutron.neutron_group)"},{"line_number":32,"context_line":"        conf.register_opts(nova.conf.neutron.ALL_OPTS,"}],"source_content_type":"text/x-python","patch_set":1,"id":"1a5782dc_3a9542a0","line":29,"range":{"start_line":23,"start_character":8,"end_line":29,"end_character":42},"updated":"2026-10-27 16:26:38.000000000","message":"again the config fixture shoudl be handelign this for us so im not sure this is correct.","commit_id":"b380f4048f23bcd38c1711cc0e0c664be125074a"},{"author":{"_account_id":6476,"name":"Thomas Goirand","email":"thomas@goirand.fr","username":"thomas-goirand"},"change_message_id":"bd37b1c84622f49354d618d50ce1d3cb6c863e23","unresolved":false,"context_lines":[{"line_number":20,"context_line":"class NeutronConfTestCase(test.NoDBTestCase):"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"    def test_register_dynamic_opts(self):"},{"line_number":23,"context_line":"        # Use a private ConfigOpts: the dynamic opts are registered"},{"line_number":24,"context_line":"        # against whatever CONF is passed in and nothing ever"},{"line_number":25,"context_line":"        # unregisters them. Other tests may have registered physnet"},{"line_number":26,"context_line":"        # opts before us in the same worker (the dynamic stestr"},{"line_number":27,"context_line":"        # scheduler runs hundreds of groups per worker), which would"},{"line_number":28,"context_line":"        # break the asserts below, and our own registration would leak"},{"line_number":29,"context_line":"        # into the tests running after us."},{"line_number":30,"context_line":"        conf \u003d cfg.ConfigOpts()"},{"line_number":31,"context_line":"        conf.register_group(nova.conf.neutron.neutron_group)"},{"line_number":32,"context_line":"        conf.register_opts(nova.conf.neutron.ALL_OPTS,"}],"source_content_type":"text/x-python","patch_set":1,"id":"9695d230_05820df9","line":29,"range":{"start_line":23,"start_character":8,"end_line":29,"end_character":42},"in_reply_to":"1a5782dc_3a9542a0","updated":"2026-11-06 08:57:18.000000000","message":"Done","commit_id":"b380f4048f23bcd38c1711cc0e0c664be125074a"}]}
