)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"72ecd3940d703f060d0731434f31da776d57beb9","unresolved":true,"context_lines":[{"line_number":14,"context_line":"clears task_state) and finish_evacuation (which updates instance.host)."},{"line_number":15,"context_line":"When the periodic fires in this window, the evacuating instance\u0027s"},{"line_number":16,"context_line":"pinned CPUs are not accounted for, and the next rebuild_claim assigns"},{"line_number":17,"context_line":"the same pCPUs to another instance."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"Related-Bug: #2162835"},{"line_number":20,"context_line":"Assisted-By: Claude-Code opus 4.6"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"551a64a1_6afaabe2","line":17,"updated":"2026-08-19 14:01:37.000000000","message":"just by looking at the baseline code it seems that the intention is that the migration context is still holding the allocation between _update_instance_after_spawn and finish_evacuation. So the periodic should see the allocation via the migration context.\n\nhaving and empty task state but not having the instance.host set is alone a big gap regardless of the periodic as it would allow another action to be executed on this instance and that will see no host.","commit_id":"73893494d2d2b4809d6b7faf00cc126d80386de6"},{"author":{"_account_id":16207,"name":"ribaudr","display_name":"uggla","email":"rene.ribaud@gmail.com","username":"uggla","status":"Red Hat"},"change_message_id":"025add57dd5f1071ad9f6264a1346627ea437c5e","unresolved":false,"context_lines":[{"line_number":14,"context_line":"clears task_state) and finish_evacuation (which updates instance.host)."},{"line_number":15,"context_line":"When the periodic fires in this window, the evacuating instance\u0027s"},{"line_number":16,"context_line":"pinned CPUs are not accounted for, and the next rebuild_claim assigns"},{"line_number":17,"context_line":"the same pCPUs to another instance."},{"line_number":18,"context_line":""},{"line_number":19,"context_line":"Related-Bug: #2162835"},{"line_number":20,"context_line":"Assisted-By: Claude-Code opus 4.6"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"68fcec55_c783168e","line":17,"in_reply_to":"551a64a1_6afaabe2","updated":"2026-09-04 13:09:48.000000000","message":"Acknowledged","commit_id":"73893494d2d2b4809d6b7faf00cc126d80386de6"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"72ecd3940d703f060d0731434f31da776d57beb9","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"a568e7a9_b6b544de","updated":"2026-08-19 14:01:37.000000000","message":"It seems a valid bug reproduction. Thanks. I suggested making the injection of the periodics run cleaner.","commit_id":"73893494d2d2b4809d6b7faf00cc126d80386de6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"abc6f84e61dd64127c05268b6ff2bb90d41110d8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"75f0a48f_a83c00e3","updated":"2026-09-09 13:41:33.000000000","message":"Looks a lot better now. I have a handful of smaller suggestion inline that worth a respin.","commit_id":"1f129651c4969f338b437c282529127f7372addc"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"684cbf569e05fba40219979fbf58ca2110903534","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"eeb5fa5b_ec4456c8","updated":"2026-09-28 10:01:36.000000000","message":"looks good","commit_id":"c0973db1f853948e60a067b3a05fdfc3f4633c21"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"30917d8e1677cc9eada20b963d9b28168f81a1a1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"86114518_2313e55c","updated":"2026-09-28 10:01:46.000000000","message":"recheck threading hang","commit_id":"c0973db1f853948e60a067b3a05fdfc3f4633c21"}],"nova/tests/functional/regressions/test_bug_2162835.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"72ecd3940d703f060d0731434f31da776d57beb9","unresolved":true,"context_lines":[{"line_number":111,"context_line":"                    self.host_mappings[\u0027host2\u0027].cell_mapping,"},{"line_number":112,"context_line":"                ) as cctxt:"},{"line_number":113,"context_line":"                    self.computes[\u0027host2\u0027].manager.\\"},{"line_number":114,"context_line":"                        update_available_resource(cctxt)"},{"line_number":115,"context_line":"            return original_finish(instance, node, migration)"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        with mock.patch.object(rt, \u0027finish_evacuation\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"305d819f_6252e670","line":114,"updated":"2026-08-19 14:01:37.000000000","message":"This is a bit invasive as periodics are never called from that specific place of the code so the state of the locks grabbed by the process might not be realistic to a periodic starting to run.\n\nWe can stop the mock_finish() with a threading.Event. And then trigger the periodic from the test case, and then set the event to allow the mock_finish to continue. We even have some helpers to trigger the periodic from the test code.`self._run_periodics()`. This will be a little cleaner. \n\n(you probably need two events one to signal that finish is entered and therefore periodics can start, and another that signals from the test to the finish to continue after the periodics)\n\n(also you need to split the _evacuate_server call to two 1] triggering the action 2] periodic stuff 3] waiting for the evacution to finish. And for that to work you need to switch this test to be a \"proper\" parallel test via CAST_AS_CALL disabled)","commit_id":"73893494d2d2b4809d6b7faf00cc126d80386de6"},{"author":{"_account_id":16207,"name":"ribaudr","display_name":"uggla","email":"rene.ribaud@gmail.com","username":"uggla","status":"Red Hat"},"change_message_id":"025add57dd5f1071ad9f6264a1346627ea437c5e","unresolved":true,"context_lines":[{"line_number":111,"context_line":"                    self.host_mappings[\u0027host2\u0027].cell_mapping,"},{"line_number":112,"context_line":"                ) as cctxt:"},{"line_number":113,"context_line":"                    self.computes[\u0027host2\u0027].manager.\\"},{"line_number":114,"context_line":"                        update_available_resource(cctxt)"},{"line_number":115,"context_line":"            return original_finish(instance, node, migration)"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        with mock.patch.object(rt, \u0027finish_evacuation\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"a4d1533a_c32c6c6e","line":114,"in_reply_to":"305d819f_6252e670","updated":"2026-09-04 13:09:48.000000000","message":"The test now uses the pattern entered/proceed events on finish_evacuation, the periodic is triggered from the test thread via self._run_periodics(), and CAST_AS_CALL \u003d False makes the evacuate truly async.\n\nI hope it is the direction you expected.","commit_id":"73893494d2d2b4809d6b7faf00cc126d80386de6"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"abc6f84e61dd64127c05268b6ff2bb90d41110d8","unresolved":false,"context_lines":[{"line_number":43,"context_line":"    \"\"\""},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    ADMIN_API \u003d True"},{"line_number":46,"context_line":"    CAST_AS_CALL \u003d False"},{"line_number":47,"context_line":"    microversion \u003d \u0027latest\u0027"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def setUp(self):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9439bf3d_60be5995","line":46,"updated":"2026-09-09 13:41:33.000000000","message":"+100\nCAST_AS_CALL was a pretty nasty shortcut applied in functional test. I would disable it by default if I could.","commit_id":"1f129651c4969f338b437c282529127f7372addc"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"abc6f84e61dd64127c05268b6ff2bb90d41110d8","unresolved":true,"context_lines":[{"line_number":101,"context_line":"        # - proceed: the test signals finish_evacuation to continue"},{"line_number":102,"context_line":"        #   after the periodic has run."},{"line_number":103,"context_line":"        entered \u003d threading.Event()"},{"line_number":104,"context_line":"        proceed \u003d threading.Event()"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        rt \u003d self.computes[\u0027host2\u0027].manager.rt"},{"line_number":107,"context_line":"        original_finish \u003d rt.finish_evacuation"}],"source_content_type":"text/x-python","patch_set":2,"id":"eafd1c40_09538ee5","line":104,"updated":"2026-09-09 13:41:33.000000000","message":"any time you are using events in tests to create some synchronization points it is a good idea to do self.addCleanup(\u003cevent\u003e.set) immediately after the creation. This avoids a set of issues when a test case start failing for an unrelated error but the event.wait() prevents the test case to clearly terminate after that unrelated fault and it hangs.","commit_id":"1f129651c4969f338b437c282529127f7372addc"},{"author":{"_account_id":16207,"name":"ribaudr","display_name":"uggla","email":"rene.ribaud@gmail.com","username":"uggla","status":"Red Hat"},"change_message_id":"3bfd47f4af84d7e07df6366bc1b589cc11cb0099","unresolved":false,"context_lines":[{"line_number":101,"context_line":"        # - proceed: the test signals finish_evacuation to continue"},{"line_number":102,"context_line":"        #   after the periodic has run."},{"line_number":103,"context_line":"        entered \u003d threading.Event()"},{"line_number":104,"context_line":"        proceed \u003d threading.Event()"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        rt \u003d self.computes[\u0027host2\u0027].manager.rt"},{"line_number":107,"context_line":"        original_finish \u003d rt.finish_evacuation"}],"source_content_type":"text/x-python","patch_set":2,"id":"815fc827_1b598577","line":104,"in_reply_to":"eafd1c40_09538ee5","updated":"2026-09-16 15:48:52.000000000","message":"Done","commit_id":"1f129651c4969f338b437c282529127f7372addc"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"abc6f84e61dd64127c05268b6ff2bb90d41110d8","unresolved":true,"context_lines":[{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        rt \u003d self.computes[\u0027host2\u0027].manager.rt"},{"line_number":107,"context_line":"        original_finish \u003d rt.finish_evacuation"},{"line_number":108,"context_line":"        should_block \u003d [True]"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        def blocking_finish(instance, node, migration):"},{"line_number":111,"context_line":"            if should_block[0]:"}],"source_content_type":"text/x-python","patch_set":2,"id":"69e0d2f1_aa746caa","line":108,"updated":"2026-09-09 13:41:33.000000000","message":"wondering if we really need should_block now. I think without it the first run will wait for proceed to be set, but the second run will see proceed to be already set and passing through without waiting. So I think without the conditional we get the same behavior just because of the events.","commit_id":"1f129651c4969f338b437c282529127f7372addc"},{"author":{"_account_id":16207,"name":"ribaudr","display_name":"uggla","email":"rene.ribaud@gmail.com","username":"uggla","status":"Red Hat"},"change_message_id":"3bfd47f4af84d7e07df6366bc1b589cc11cb0099","unresolved":false,"context_lines":[{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        rt \u003d self.computes[\u0027host2\u0027].manager.rt"},{"line_number":107,"context_line":"        original_finish \u003d rt.finish_evacuation"},{"line_number":108,"context_line":"        should_block \u003d [True]"},{"line_number":109,"context_line":""},{"line_number":110,"context_line":"        def blocking_finish(instance, node, migration):"},{"line_number":111,"context_line":"            if should_block[0]:"}],"source_content_type":"text/x-python","patch_set":2,"id":"724194f3_dcc21c52","line":108,"in_reply_to":"69e0d2f1_aa746caa","updated":"2026-09-16 15:48:52.000000000","message":"Done","commit_id":"1f129651c4969f338b437c282529127f7372addc"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"abc6f84e61dd64127c05268b6ff2bb90d41110d8","unresolved":true,"context_lines":[{"line_number":124,"context_line":"        #    i.e. _update_instance_after_spawn has already run and"},{"line_number":125,"context_line":"        #    task_state is cleared."},{"line_number":126,"context_line":"        self.assertTrue("},{"line_number":127,"context_line":"            entered.wait(timeout\u003d60),"},{"line_number":128,"context_line":"            \"Timed out waiting for finish_evacuation to be entered\")"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"        # 3) Run the periodic task from the test thread. This resets"}],"source_content_type":"text/x-python","patch_set":2,"id":"d36f79bc_6c59b72d","line":127,"updated":"2026-09-09 13:41:33.000000000","message":"I like the way out timeout\u003d60, but I think it still make sense (and easier to remember pattern) to add self.addCleanup(entered.set) right at the creation of the event.","commit_id":"1f129651c4969f338b437c282529127f7372addc"},{"author":{"_account_id":16207,"name":"ribaudr","display_name":"uggla","email":"rene.ribaud@gmail.com","username":"uggla","status":"Red Hat"},"change_message_id":"3bfd47f4af84d7e07df6366bc1b589cc11cb0099","unresolved":false,"context_lines":[{"line_number":124,"context_line":"        #    i.e. _update_instance_after_spawn has already run and"},{"line_number":125,"context_line":"        #    task_state is cleared."},{"line_number":126,"context_line":"        self.assertTrue("},{"line_number":127,"context_line":"            entered.wait(timeout\u003d60),"},{"line_number":128,"context_line":"            \"Timed out waiting for finish_evacuation to be entered\")"},{"line_number":129,"context_line":""},{"line_number":130,"context_line":"        # 3) Run the periodic task from the test thread. This resets"}],"source_content_type":"text/x-python","patch_set":2,"id":"1a2a0b19_24156ce5","line":127,"in_reply_to":"d36f79bc_6c59b72d","updated":"2026-09-16 15:48:52.000000000","message":"Done","commit_id":"1f129651c4969f338b437c282529127f7372addc"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"abc6f84e61dd64127c05268b6ff2bb90d41110d8","unresolved":false,"context_lines":[{"line_number":131,"context_line":"        #    host2\u0027s pinned_cpus because:"},{"line_number":132,"context_line":"        #    - instance.host still \u003d host1 (not counted)"},{"line_number":133,"context_line":"        #    - migration is skipped (task_state\u003dNone)"},{"line_number":134,"context_line":"        self._run_periodics()"},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"        # 4) Allow finish_evacuation to proceed"},{"line_number":137,"context_line":"        proceed.set()"}],"source_content_type":"text/x-python","patch_set":2,"id":"ffb8f432_ec477f7e","line":134,"updated":"2026-09-09 13:41:33.000000000","message":"yepp this is a lot more realistic now.","commit_id":"1f129651c4969f338b437c282529127f7372addc"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"abc6f84e61dd64127c05268b6ff2bb90d41110d8","unresolved":false,"context_lines":[{"line_number":141,"context_line":"        server_a \u003d self._wait_for_server_parameter("},{"line_number":142,"context_line":"            server_a, {"},{"line_number":143,"context_line":"                \u0027OS-EXT-SRV-ATTR:host\u0027: \u0027host2\u0027,"},{"line_number":144,"context_line":"                \u0027status\u0027: \u0027SHUTOFF\u0027,"},{"line_number":145,"context_line":"            })"},{"line_number":146,"context_line":""},{"line_number":147,"context_line":"        # Evacuate server_b normally (blocking_finish passes through)."}],"source_content_type":"text/x-python","patch_set":2,"id":"939927b2_62300628","line":144,"updated":"2026-09-09 13:41:33.000000000","message":"yepp, latest microversion will stop the instance on the target node.","commit_id":"1f129651c4969f338b437c282529127f7372addc"}]}
