)]}'
{"watcher_dashboard/content/goals/tests.py":[{"robot_id":"zuul","robot_run_id":"52d173e4ae07477bb64c4c109121313d","url":"https://zuul.teim.app/t/main/buildset/52d173e4ae07477bb64c4c109121313d","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":"da8c4bf7bcff36800d305aa8561178a7317d31c2","patch_set":4,"id":"b644e09f_f6871f83","line":41,"updated":"2026-04-04 01:33:48.000000000","message":"The logger name strings are hardcoded in each test method (e.g., \u0027watcher_dashboard.content.goals.views\u0027). These could drift out of sync if the module is renamed or reorganised.\n\n**Severity**: SUGGESTION | **Confidence**: 0.6\n\n**Benefit**: Using a constant or importing the logger name from the views module would prevent duplication and keep the test tightly coupled to the actual module path.\n\n**Recommendation**:\nOptionally define a module-level constant like LOGGER_NAME \u003d \u0027watcher_dashboard.content.goals.views\u0027 or extract it from views.LOG. This is a minor improvement and not blocking.","commit_id":"40f34ec36476dfcc1ba82ad388b2eea6f702c1af"},{"robot_id":"zuul","robot_run_id":"759bea021bf146fab80c797459a83aa7","url":"https://zuul.teim.app/t/main/buildset/759bea021bf146fab80c797459a83aa7","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":"c72d9d4d412cecab6aa53a4bc9d3fc6d6dd209e1","patch_set":5,"id":"ce433264_bcbba6c4","line":41,"updated":"2026-04-30 18:12:05.000000000","message":"The logger variable name is repeated identically in each test method (e.g. logger \u003d \u0027watcher_dashboard.content.goals.views\u0027). Extracting it to a module-level constant or class attribute would reduce duplication.\n\n**Severity**: SUGGESTION | **Confidence**: 0.8\n\n**Benefit**: Reduces copy-paste errors and makes it easier to update logger names if modules are refactored.\n\n**Recommendation**:\nAdd a module-level constant, e.g. VIEWS_LOGGER \u003d \u0027watcher_dashboard.content.goals.views\u0027, and reference it in all assertLogs() calls. Apply the same pattern to audit_templates/tests.py and strategies/tests.py.","commit_id":"4500afca10c9d2cc257715c07f8209188b81eaa3"}],"watcher_dashboard/test/local_fixtures/logging_fixture.py":[{"robot_id":"zuul","robot_run_id":"52d173e4ae07477bb64c4c109121313d","url":"https://zuul.teim.app/t/main/buildset/52d173e4ae07477bb64c4c109121313d","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":"da8c4bf7bcff36800d305aa8561178a7317d31c2","patch_set":4,"id":"61bd702d_179c22b3","line":31,"updated":"2026-04-04 01:33:48.000000000","message":"NullHandler.handle() calls self.format(record) but emit() is a no-op. The Python logging documentation states that handle() checks conditions and then calls emit(). Overriding both handle() and emit() creates an unusual pattern where handle() does formatting work that emit() would normally do, but emit() silently discards it.\n\n**Severity**: WARNING | **Confidence**: 0.7\n\n**Impact**: The fixture works correctly for its intended purpose (catching format errors at DEBUG level), but the split between handle() and emit() is non-obvious and may confuse future maintainers who expect standard Handler behaviour.\n\n**Suggestion**:\nConsider adding a brief comment explaining why both handle() and emit() are overridden, or simplify to only override emit() with the format check inline.","commit_id":"40f34ec36476dfcc1ba82ad388b2eea6f702c1af"},{"robot_id":"zuul","robot_run_id":"52d173e4ae07477bb64c4c109121313d","url":"https://zuul.teim.app/t/main/buildset/52d173e4ae07477bb64c4c109121313d","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":"da8c4bf7bcff36800d305aa8561178a7317d31c2","patch_set":4,"id":"8c38e2d4_2a1e0960","line":61,"updated":"2026-04-04 01:33:48.000000000","message":"The logging fixture captures logs into a StringIO stream but the stream is never exposed or asserted against. Tests using assertLogs() for their own purposes bypass this stream. The fixture\u0027s main value is preventing log noise and testing format strings, which is useful infrastructure.\n\n**Severity**: SUGGESTION | **Confidence**: 0.6\n\n**Benefit**: Exposing the stream via the fixture would enable future tests to assert on log output without needing assertLogs(), providing a more flexible testing approach.\n\n**Recommendation**:\nConsider attaching the StringIO stream to the testcase object (e.g., self.log_output \u003d stream) so individual tests can inspect it if needed. Low priority.","commit_id":"40f34ec36476dfcc1ba82ad388b2eea6f702c1af"}],"watcher_dashboard/test/settings.py":[{"robot_id":"zuul","robot_run_id":"1543ce085cdc4b95bc77263e73052903","url":"https://zuul.teim.app/t/main/buildset/1543ce085cdc4b95bc77263e73052903","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":"94e639bda3e078c3da9819e81720c39dbc7b77c5","patch_set":1,"id":"cc926d1f_64644f5d","line":20,"updated":"2026-02-28 12:35:42.000000000","message":"Consider adding noqa comments for the intentionally set root logger level in test/settings.py\n\n**Severity**: SUGGESTION | **Confidence**: 0.7\n\n**Benefit**: Improves code maintainability by documenting that setting the root logger level to ERROR is intentional for test isolation purposes, preventing future maintainers from accidentally reverting it.\n\n**Recommendation**:\nAdd a comment \u0027# noqa: LOG001\u0027 or similar annotation to indicate this is an intentional deviation from normal logging practices for test purposes. Alternatively, add a docstring or block comment explaining the test isolation rationale.","commit_id":"59986f0e10bac8ede2df3956da66e425215ad116"},{"robot_id":"zuul","robot_run_id":"81d7609ab4df4e00ba400efffcebe1f9","url":"https://zuul.teim.app/t/main/buildset/81d7609ab4df4e00ba400efffcebe1f9","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":"306a1c17a856991b68f258646a015d360fc379a4","patch_set":3,"id":"190414a3_9181b35a","line":20,"updated":"2026-03-30 15:16:05.000000000","message":"Setting the root logger level to ERROR in test/settings.py may suppress legitimate WARNING-level log output from the application under test, including from watcher-dashboard\u0027s own LOG.warning() calls during error-path tests\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: Tests that verify WARNING-level log emission (e.g., deprecation warnings from watcher-dashboard code) would silently pass even if the warning is not emitted, because assertLogs(\u0027logger\u0027, level\u003d\u0027WARNING\u0027) would not see output suppressed at the root logger\n\n**Suggestion**:\nConsider using a more targeted suppression approach, such as warnings.filterwarnings(\u0027ignore\u0027, message\u003d\u0027.*default_dashboard is DEPRECATED.*\u0027) or configuring only the specific logger that emits the noise (e.g., logging.getLogger(\u0027openstack_dashboard\u0027).setLevel(logging.ERROR)) instead of the root logger. This would preserve WARNING-level output from the application under test.","commit_id":"00020b5fc9ea109f638b3270129bdbb9c4b4b128"},{"robot_id":"zuul","robot_run_id":"52d173e4ae07477bb64c4c109121313d","url":"https://zuul.teim.app/t/main/buildset/52d173e4ae07477bb64c4c109121313d","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":"da8c4bf7bcff36800d305aa8561178a7317d31c2","patch_set":4,"id":"fe435e0a_c6786319","line":19,"updated":"2026-04-04 01:33:48.000000000","message":"The warnings.filterwarnings() call in test/settings.py uses a broad regex pattern \u0027.*default_dashboard.*\u0027 which could suppress other legitimate warnings containing \u0027default_dashboard\u0027 in the message.\n\n**Severity**: WARNING | **Confidence**: 0.7\n\n**Impact**: If a different warning with \u0027default_dashboard\u0027 in its message appears during testing, it would also be silently suppressed, potentially hiding real issues.\n\n**Suggestion**:\nConsider narrowing the regex pattern to more closely match the specific deprecation warning, or add a comment noting the exact warning class and source that this is intended to suppress.","commit_id":"40f34ec36476dfcc1ba82ad388b2eea6f702c1af"}],"watcher_dashboard/tests/local_fixtures/logging_fixture.py":[{"robot_id":"zuul","robot_run_id":"759bea021bf146fab80c797459a83aa7","url":"https://zuul.teim.app/t/main/buildset/759bea021bf146fab80c797459a83aa7","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":"c72d9d4d412cecab6aa53a4bc9d3fc6d6dd209e1","patch_set":5,"id":"2d5d7a01_00f99f7c","line":15,"updated":"2026-04-30 18:12:05.000000000","message":"The logging fixture docstring references watcher.tests.fixtures.watcher but the module is new to watcher-dashboard. The reference may confuse future contributors unfamiliar with the Watcher server codebase.\n\n**Severity**: SUGGESTION | **Confidence**: 0.7\n\n**Benefit**: Clearer provenance documentation helps contributors understand the design rationale and find the upstream source.\n\n**Recommendation**:\nConsider adding a comment or brief note clarifying that the adaptation is from the python-watcher (server) project\u0027s StandardLogging fixture, with a URL to the source if available, so contributors can track divergence.","commit_id":"4500afca10c9d2cc257715c07f8209188b81eaa3"},{"robot_id":"zuul","robot_run_id":"759bea021bf146fab80c797459a83aa7","url":"https://zuul.teim.app/t/main/buildset/759bea021bf146fab80c797459a83aa7","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":"c72d9d4d412cecab6aa53a4bc9d3fc6d6dd209e1","patch_set":5,"id":"d32752b5_1c37e82e","line":43,"updated":"2026-04-30 18:12:05.000000000","message":"The logging fixture NullHandler.createLock() sets self.lock \u003d None instead of using threading.Lock(). Python\u0027s logging.Handler.acquire() calls self.lock.acquire() when lock is not None, but setting it to None skips locking entirely, which relies on undocumented internal behaviour.\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: In single-threaded test execution this is harmless, but if any test spawns threads that log, the missing lock could cause interleaved output or race conditions. Relying on CPython internals makes the fixture fragile across Python versions.\n\n**Suggestion**:\nReplace createLock override with a pass (keep the default threading.Lock) or remove the method entirely. The NullHandler.emit is already a no-op, so there is no performance benefit from skipping the lock.","commit_id":"4500afca10c9d2cc257715c07f8209188b81eaa3"},{"robot_id":"zuul","robot_run_id":"759bea021bf146fab80c797459a83aa7","url":"https://zuul.teim.app/t/main/buildset/759bea021bf146fab80c797459a83aa7","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":"c72d9d4d412cecab6aa53a4bc9d3fc6d6dd209e1","patch_set":5,"id":"e8e1148b_b417bb0a","line":76,"updated":"2026-04-30 18:12:05.000000000","message":"setup_standard_logging() captures the root logger state and restores it in _restore(), but if a test adds its own handlers to the root logger during execution, those handlers will persist after teardown because _restore only removes main_handler and extra_handlers.\n\n**Severity**: WARNING | **Confidence**: 0.7\n\n**Impact**: Handler leaks between tests could cause duplicate log output or test ordering dependencies. The risk is low because most tests do not modify root handlers, but the fixture\u0027s contract (full isolation) is not fully met.\n\n**Suggestion**:\nIn _restore(), remove all handlers from root before restoring saved_handlers, e.g.: for h in list(root.handlers): root.removeHandler(h). This ensures a clean slate before re-adding the original handlers.","commit_id":"4500afca10c9d2cc257715c07f8209188b81eaa3"}],"watcher_dashboard/tests/settings.py":[{"robot_id":"zuul","robot_run_id":"759bea021bf146fab80c797459a83aa7","url":"https://zuul.teim.app/t/main/buildset/759bea021bf146fab80c797459a83aa7","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":"c72d9d4d412cecab6aa53a4bc9d3fc6d6dd209e1","patch_set":5,"id":"14217eaf_8a56de6b","line":19,"updated":"2026-04-30 18:12:05.000000000","message":"The warnings.filterwarnings() call in settings.py uses a broad message regex that could silence legitimate deprecation warnings from other sources mentioning \u0027default_dashboard\u0027.\n\n**Severity**: SUGGESTION | **Confidence**: 0.7\n\n**Benefit**: Narrower filtering reduces the risk of masking genuine deprecation issues from other libraries.\n\n**Recommendation**:\nConsider adding module\u003d parameter to the filterwarnings call, e.g. module\u003dopenstack_dashboard.enabled, to restrict the suppression to the specific source module.","commit_id":"4500afca10c9d2cc257715c07f8209188b81eaa3"}]}
