)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":16312,"name":"Alfredo Moralejo","email":"amoralej@redhat.com","username":"amoralej"},"change_message_id":"2a1d59ab2c6a22592c103fea6a9adeaa10a0cd45","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"815d82ac_1d6f1f91","updated":"2026-07-03 12:19:24.000000000","message":"recheck","commit_id":"d048fe610ad94da5c03567b1f4681ff54ff03d9c"}],"watcher/tests/functional/base.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"e329964bdd7d0e557181feb60bc7e51ca4a196a9","unresolved":false,"context_lines":[{"line_number":220,"context_line":"        # 10b. Cinder emulator — install AFTER Nova so that the"},{"line_number":221,"context_line":"        #      real cinderclient overrides Nova\u0027s MagicMock."},{"line_number":222,"context_line":"        if use_cinder:"},{"line_number":223,"context_line":"            self.cinder_fixture \u003d self.useFixture("},{"line_number":224,"context_line":"                CinderFixture("},{"line_number":225,"context_line":"                    storage_nodes\u003dself._storage_nodes,"},{"line_number":226,"context_line":"                    pools\u003dself._pools,"}],"source_content_type":"text/x-python","patch_set":2,"id":"81a6a3f4_d1f91324","line":223,"updated":"2026-06-25 10:08:59.000000000","message":"WatcherEnvironment does not pass a snapshots parameter to CinderFixture, and WatcherFunctionalTestCase has no SNAPSHOTS class attribute. CinderFixture accepts snapshots and reload_topology passes them, but class-level snapshot topology is impossible since the fixture call omits snapshots.\n\n**Severity**: SUGGESTION | **Confidence**: 0.8\n\n**Benefit**: Adding snapshots passthrough (snapshots parameter to WatcherEnvironment.__init__, SNAPSHOTS class attribute, and snapshots\u003dself._snapshots in the CinderFixture call) provides symmetry with the other topology parameters and enables snapshot-based test scenarios at the class level.\n\n**Recommendation**:\nAdd a snapshots\u003dNone parameter to WatcherEnvironment.__init__, store it as self._snapshots, pass it to CinderFixture at line 224-229, and add SNAPSHOTS \u003d None to WatcherFunctionalTestCase. Also pass it through in the setUp method at line 339.","commit_id":"1d09e29ef617382119c6cfb50d18112f10e7f92b"}],"watcher/tests/functional/test_zone_migration.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"e329964bdd7d0e557181feb60bc7e51ca4a196a9","unresolved":false,"context_lines":[{"line_number":1096,"context_line":""},{"line_number":1097,"context_line":"        return details, ap"},{"line_number":1098,"context_line":""},{"line_number":1099,"context_line":"    def _assert_efficacy_indicators("},{"line_number":1100,"context_line":"        self,"},{"line_number":1101,"context_line":"        ap,"},{"line_number":1102,"context_line":"        planned_live\u003d0,"}],"source_content_type":"text/x-python","patch_set":2,"id":"72f19f71_cc7c6307","line":1099,"updated":"2026-06-25 10:08:59.000000000","message":"The _assert_efficacy_indicators method is duplicated between TestZoneMigration (line 251) and TestZoneMigrationScoped (line 1099). Both inherit from base.WatcherFunctionalTestCase, so the method could be added to the base class to eliminate the 37-line duplication.\n\n**Severity**: SUGGESTION | **Confidence**: 0.9\n\n**Benefit**: Moving this helper to WatcherFunctionalTestCase eliminates duplication, ensures a single source of truth for efficacy indicator assertions, and makes the method available to future functional test classes that test strategies with efficacy indicators.\n\n**Recommendation**:\nAdd _assert_efficacy_indicators to base.WatcherFunctionalTestCase and remove both copies. The method is generic enough (takes ap dict and expected counts) to serve all strategy tests.","commit_id":"1d09e29ef617382119c6cfb50d18112f10e7f92b"}],"watcher/tests/local_fixtures/cinder.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"e329964bdd7d0e557181feb60bc7e51ca4a196a9","unresolved":false,"context_lines":[{"line_number":216,"context_line":"            cinder_coll.CinderClusterDataModelCollector"},{"line_number":217,"context_line":"        )"},{"line_number":218,"context_line":"        if collector is not None:"},{"line_number":219,"context_line":"            collector._cluster_data_model \u003d None"}],"source_content_type":"text/x-python","patch_set":2,"id":"84e95aaa_bf10bbed","line":219,"updated":"2026-06-25 10:08:59.000000000","message":"The _invalidate_collector_model method directly sets collector._cluster_data_model \u003d None, bypassing the threading lock that the base collector class uses to protect this attribute. The base class provides set_cluster_data_model_as_stale() and a property setter for this purpose.\n\n**Severity**: SUGGESTION | **Confidence**: 0.8\n\n**Benefit**: Using the property setter or set_cluster_data_model_as_stale() ensures thread-safe cache invalidation, consistent with the collector\u0027s own synchronization design, and avoids relying on a private attribute name that could change.\n\n**Recommendation**:\nReplace collector._cluster_data_model \u003d None with collector.cluster_data_model \u003d None (uses the property setter with locking) or collector.set_cluster_data_model_as_stale().","commit_id":"1d09e29ef617382119c6cfb50d18112f10e7f92b"},{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"c56b1c838d6d7e643f0089b62e8b728d8ae22872","unresolved":false,"context_lines":[{"line_number":122,"context_line":""},{"line_number":123,"context_line":"        if any("},{"line_number":124,"context_line":"            x is not None"},{"line_number":125,"context_line":"            for x in ("},{"line_number":126,"context_line":"                self._storage_nodes,"},{"line_number":127,"context_line":"                self._pools,"},{"line_number":128,"context_line":"                self._volume_types,"}],"source_content_type":"text/x-python","patch_set":3,"id":"4399829f_29283cb8","line":125,"updated":"2026-07-02 20:03:22.000000000","message":"The setUp guard checks `any(x is not None for x in (storage_nodes, pools, volume_types, volumes))` but omits `self._snapshots`. A caller passing only snapshots\u003d... leaves the guard False, so load_topology is never called and snapshots are silently dropped.\n\n**Severity**: WARNING | **Confidence**: 0.9\n\n**Impact**: A test that constructs a CinderFixture with only snapshots (no storage_nodes/pools/volume_types/volumes) would silently get an empty emulator, leading to confusing test failures or false passes. The current zone_migration tests don\u0027t hit this path, but it is a latent footgun for future tests.\n\n**Suggestion**:\nAdd `self._snapshots` to the tuple inside the `any()` guard, or simplify by always calling `load_topology` (it already handles None values via `or []` defaults).","commit_id":"d048fe610ad94da5c03567b1f4681ff54ff03d9c"}],"watcher/tests/local_fixtures/nova_api_emulator.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"c56b1c838d6d7e643f0089b62e8b728d8ae22872","unresolved":false,"context_lines":[{"line_number":516,"context_line":"                    srv[\u0027status\u0027] \u003d \u0027VERIFY_RESIZE\u0027"},{"line_number":517,"context_line":"                return \u0027\u0027, 202"},{"line_number":518,"context_line":""},{"line_number":519,"context_line":"            if \u0027confirmResize\u0027 in body:"},{"line_number":520,"context_line":"                srv[\u0027status\u0027] \u003d srv.pop(\u0027_pre_resize_status\u0027, \u0027ACTIVE\u0027)"},{"line_number":521,"context_line":"                return \u0027\u0027, 204"},{"line_number":522,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"ccda6996_4292a684","line":519,"updated":"2026-07-02 20:03:22.000000000","message":"The internal bookkeeping key `_pre_resize_status` is stored directly on the server dict (`srv`), which is the same dict returned by GET /servers/{id} and GET /servers/detail. This internal field leaks into API responses, slightly diverging from real Nova which never returns such a key.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: The leaked key is visible to any code consuming server details via the emulator. While the SDK ignores unknown keys, the divergence could mask bugs in code that iterates server fields, and makes the emulator\u0027s responses less faithful to the real Nova API.\n\n**Suggestion**:\nTrack the pre-migration status in a separate side-channel dict (e.g. `self._pre_resize_status \u003d {}` keyed by server_id) instead of storing it on the server record, so it never appears in serialized API responses.","commit_id":"d048fe610ad94da5c03567b1f4681ff54ff03d9c"}]}
