)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"524fd5113bff9426e9e5530fb5df16939c684ab0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"297d058f_0f6f28f8","updated":"2025-08-18 13:04:53.000000000","message":"I\u0027m sorry. I appreciate the time you\u0027ve invested in this, but functional tests that mess with service state have a bad habit of causing races. This is because our tests run in parallel, so stopping and starting a service can result in other tests failing if they run while the service is stopped. As a result, we have removed tests that did this for e.g. the compute service in the past. I would rather we don\u0027t add new ones now.","commit_id":"3feb01c4b601f01d286d36e57cdd4b209de51f12"},{"author":{"_account_id":38180,"name":"JIN YONG LEE","email":"ljy2855@gmail.com","username":"ljy2855"},"change_message_id":"c9f3fd4c6c3ae2b68d733f76f753c6a9419947d4","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":2,"id":"722beaaf_8a28071d","in_reply_to":"297d058f_0f6f28f8","updated":"2025-08-23 06:58:15.000000000","message":"Thanks for the context. I agree that functional tests which mutate service state can introduce races in our parallel tests run.\n\nTo align with that, I’ll drop the state-changing tests and keep only `volume service list`, `volume service set --enable`.","commit_id":"3feb01c4b601f01d286d36e57cdd4b209de51f12"},{"author":{"_account_id":38180,"name":"JIN YONG LEE","email":"ljy2855@gmail.com","username":"ljy2855"},"change_message_id":"03cd146282ec55d3ad212e23fdeebd66f00d1d68","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"897c3fdb_b7c82755","updated":"2025-09-30 08:50:37.000000000","message":"Thank you for your kind and detailed review, I fixed the test by referring to the review.","commit_id":"b4c0261d7739641b27c04f7f998e2a8ee7bbc06b"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"3ba8c3416943299b461751ea13e96d771ccfbe71","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"b3be1eb0_7e84420b","updated":"2025-11-12 12:43:36.000000000","message":"Two tiny nits left","commit_id":"25999d563be9f44919781437877c6f5279344c29"}],"openstackclient/tests/functional/volume/v3/test_service.py":[{"author":{"_account_id":35119,"name":"jihyun huh","email":"huhji.elha@gmail.com","username":"jhhuh"},"change_message_id":"c62041c3ca3c2f262a0feba5550978bc2c7d9c02","unresolved":true,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"class VolumeServiceTests(common.BaseVolumeTests):"},{"line_number":18,"context_line":"    \"\"\"Functional tests for \u0027openstack volume service set\u0027.\"\"\""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"    def test_service_list(self):"},{"line_number":21,"context_line":"        \"\"\"Verify listing works and host/service filters narrow results.\"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"aeceaf22_0c3ce5e3","line":18,"updated":"2025-08-23 06:13:27.000000000","message":"it may needs to change `openstack volume service set` to `openstack volume service`","commit_id":"44eb5efcab2281efed1bc029471cf77aaf01b13b"},{"author":{"_account_id":38180,"name":"JIN YONG LEE","email":"ljy2855@gmail.com","username":"ljy2855"},"change_message_id":"c22c59db7c13df309cdfa6d938384a7ec1915406","unresolved":false,"context_lines":[{"line_number":15,"context_line":""},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"class VolumeServiceTests(common.BaseVolumeTests):"},{"line_number":18,"context_line":"    \"\"\"Functional tests for \u0027openstack volume service set\u0027.\"\"\""},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"    def test_service_list(self):"},{"line_number":21,"context_line":"        \"\"\"Verify listing works and host/service filters narrow results.\"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"ab68d3a1_80ab5f76","line":18,"in_reply_to":"aeceaf22_0c3ce5e3","updated":"2025-08-23 07:38:46.000000000","message":"Done!!","commit_id":"44eb5efcab2281efed1bc029471cf77aaf01b13b"},{"author":{"_account_id":35119,"name":"jihyun huh","email":"huhji.elha@gmail.com","username":"jhhuh"},"change_message_id":"c62041c3ca3c2f262a0feba5550978bc2c7d9c02","unresolved":true,"context_lines":[{"line_number":130,"context_line":"        )"},{"line_number":131,"context_line":"        self.assertTrue(sorted_desc, \u0027No rows returned for descending sort\u0027)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def test_volume_service_set(self):"},{"line_number":134,"context_line":"        \"\"\"Test volume service set --enable\"\"\""},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"        # Get a service and host"}],"source_content_type":"text/x-python","patch_set":3,"id":"3ad6dd56_70a0cca0","line":133,"updated":"2025-08-23 06:13:27.000000000","message":"Could you combine two functional tests(test_volume_service_set and test_service_list) to one `test_volume_service`?\n\nyou can find reference from here: https://opendev.org/openstack/python-openstackclient/src/branch/master/openstackclient/tests/functional/identity/v3/test_access_rule.py","commit_id":"44eb5efcab2281efed1bc029471cf77aaf01b13b"},{"author":{"_account_id":38180,"name":"JIN YONG LEE","email":"ljy2855@gmail.com","username":"ljy2855"},"change_message_id":"c22c59db7c13df309cdfa6d938384a7ec1915406","unresolved":false,"context_lines":[{"line_number":130,"context_line":"        )"},{"line_number":131,"context_line":"        self.assertTrue(sorted_desc, \u0027No rows returned for descending sort\u0027)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def test_volume_service_set(self):"},{"line_number":134,"context_line":"        \"\"\"Test volume service set --enable\"\"\""},{"line_number":135,"context_line":""},{"line_number":136,"context_line":"        # Get a service and host"}],"source_content_type":"text/x-python","patch_set":3,"id":"3a01c735_cbe6f87a","line":133,"in_reply_to":"3ad6dd56_70a0cca0","updated":"2025-08-23 07:38:46.000000000","message":"Thanks for guides. I will combine tests by this reference","commit_id":"44eb5efcab2281efed1bc029471cf77aaf01b13b"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"bb0d4678f02d0cf16b5ad34185b408bfb967c8e8","unresolved":true,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"        # Pick one row for filter checks"},{"line_number":28,"context_line":"        row \u003d rows[0]"},{"line_number":29,"context_line":"        host \u003d row.get(\u0027Host\u0027) or row.get(\u0027host\u0027)"},{"line_number":30,"context_line":"        binary \u003d ("},{"line_number":31,"context_line":"            row.get(\u0027Binary\u0027)"},{"line_number":32,"context_line":"            or row.get(\u0027Service\u0027)"},{"line_number":33,"context_line":"            or row.get(\u0027binary\u0027)"},{"line_number":34,"context_line":"            or row.get(\u0027service\u0027)"},{"line_number":35,"context_line":"        )"},{"line_number":36,"context_line":"        self.assertIsNotNone(host)"},{"line_number":37,"context_line":"        self.assertIsNotNone(binary)"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"984672a3_7438ab7c","line":35,"range":{"start_line":29,"start_character":0,"end_line":35,"end_character":9},"updated":"2025-09-10 09:50:09.000000000","message":"We should know the name of these columns. Can you choose one and ideally use a direct access like `row[\u0027field\u0027]` so it fails with `KeyError` if missing. That way if the column names change then we\u0027ll need to update this test.","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":38180,"name":"JIN YONG LEE","email":"ljy2855@gmail.com","username":"ljy2855"},"change_message_id":"03cd146282ec55d3ad212e23fdeebd66f00d1d68","unresolved":false,"context_lines":[{"line_number":26,"context_line":""},{"line_number":27,"context_line":"        # Pick one row for filter checks"},{"line_number":28,"context_line":"        row \u003d rows[0]"},{"line_number":29,"context_line":"        host \u003d row.get(\u0027Host\u0027) or row.get(\u0027host\u0027)"},{"line_number":30,"context_line":"        binary \u003d ("},{"line_number":31,"context_line":"            row.get(\u0027Binary\u0027)"},{"line_number":32,"context_line":"            or row.get(\u0027Service\u0027)"},{"line_number":33,"context_line":"            or row.get(\u0027binary\u0027)"},{"line_number":34,"context_line":"            or row.get(\u0027service\u0027)"},{"line_number":35,"context_line":"        )"},{"line_number":36,"context_line":"        self.assertIsNotNone(host)"},{"line_number":37,"context_line":"        self.assertIsNotNone(binary)"},{"line_number":38,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"efb78df8_1a907ecf","line":35,"range":{"start_line":29,"start_character":0,"end_line":35,"end_character":9},"in_reply_to":"984672a3_7438ab7c","updated":"2025-09-30 08:50:37.000000000","message":"Done","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"bb0d4678f02d0cf16b5ad34185b408bfb967c8e8","unresolved":true,"context_lines":[{"line_number":42,"context_line":"            parse_output\u003dTrue,"},{"line_number":43,"context_line":"        )"},{"line_number":44,"context_line":"        self.assertTrue(filtered, \u0027filtered list is empty\u0027)"},{"line_number":45,"context_line":"        for r in filtered:"},{"line_number":46,"context_line":"            r_host \u003d r.get(\u0027Host\u0027) or r.get(\u0027host\u0027)"},{"line_number":47,"context_line":"            r_binary \u003d ("},{"line_number":48,"context_line":"                r.get(\u0027Binary\u0027)"},{"line_number":49,"context_line":"                or r.get(\u0027Service\u0027)"},{"line_number":50,"context_line":"                or r.get(\u0027binary\u0027)"},{"line_number":51,"context_line":"                or r.get(\u0027service\u0027)"},{"line_number":52,"context_line":"            )"},{"line_number":53,"context_line":"            # Some deployments may include extra whitespace; normalize"},{"line_number":54,"context_line":"            if r_host is not None:"},{"line_number":55,"context_line":"                r_host \u003d str(r_host).strip()"}],"source_content_type":"text/x-python","patch_set":4,"id":"010e4649_e6b36a05","line":52,"range":{"start_line":45,"start_character":26,"end_line":52,"end_character":13},"updated":"2025-09-10 09:50:09.000000000","message":"Same comment as above RE: field naming.","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":38180,"name":"JIN YONG LEE","email":"ljy2855@gmail.com","username":"ljy2855"},"change_message_id":"03cd146282ec55d3ad212e23fdeebd66f00d1d68","unresolved":false,"context_lines":[{"line_number":42,"context_line":"            parse_output\u003dTrue,"},{"line_number":43,"context_line":"        )"},{"line_number":44,"context_line":"        self.assertTrue(filtered, \u0027filtered list is empty\u0027)"},{"line_number":45,"context_line":"        for r in filtered:"},{"line_number":46,"context_line":"            r_host \u003d r.get(\u0027Host\u0027) or r.get(\u0027host\u0027)"},{"line_number":47,"context_line":"            r_binary \u003d ("},{"line_number":48,"context_line":"                r.get(\u0027Binary\u0027)"},{"line_number":49,"context_line":"                or r.get(\u0027Service\u0027)"},{"line_number":50,"context_line":"                or r.get(\u0027binary\u0027)"},{"line_number":51,"context_line":"                or r.get(\u0027service\u0027)"},{"line_number":52,"context_line":"            )"},{"line_number":53,"context_line":"            # Some deployments may include extra whitespace; normalize"},{"line_number":54,"context_line":"            if r_host is not None:"},{"line_number":55,"context_line":"                r_host \u003d str(r_host).strip()"}],"source_content_type":"text/x-python","patch_set":4,"id":"2670bb32_ccd3ada3","line":52,"range":{"start_line":45,"start_character":26,"end_line":52,"end_character":13},"in_reply_to":"010e4649_e6b36a05","updated":"2025-09-30 08:50:37.000000000","message":"Done","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"bb0d4678f02d0cf16b5ad34185b408bfb967c8e8","unresolved":true,"context_lines":[{"line_number":49,"context_line":"                or r.get(\u0027Service\u0027)"},{"line_number":50,"context_line":"                or r.get(\u0027binary\u0027)"},{"line_number":51,"context_line":"                or r.get(\u0027service\u0027)"},{"line_number":52,"context_line":"            )"},{"line_number":53,"context_line":"            # Some deployments may include extra whitespace; normalize"},{"line_number":54,"context_line":"            if r_host is not None:"},{"line_number":55,"context_line":"                r_host \u003d str(r_host).strip()"},{"line_number":56,"context_line":"            if host is not None:"},{"line_number":57,"context_line":"                host \u003d str(host).strip()"},{"line_number":58,"context_line":"            if r_binary is not None:"},{"line_number":59,"context_line":"                r_binary \u003d str(r_binary).strip()"},{"line_number":60,"context_line":"            if binary is not None:"},{"line_number":61,"context_line":"                binary \u003d str(binary).strip()"},{"line_number":62,"context_line":"            self.assertEqual(host, r_host)"},{"line_number":63,"context_line":"            self.assertEqual(binary, r_binary)"},{"line_number":64,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"1c42f6b8_54731777","line":61,"range":{"start_line":52,"start_character":13,"end_line":61,"end_character":44},"updated":"2025-09-10 09:50:09.000000000","message":"This feels like a bug. Where is the whitespace coming from? If it\u0027s the client then we should strip that whitespace before we print it. If it\u0027s the server then why doesn\u0027t the whitespace appear in both places? I would like to see all of this logic removed.","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":38180,"name":"JIN YONG LEE","email":"ljy2855@gmail.com","username":"ljy2855"},"change_message_id":"03cd146282ec55d3ad212e23fdeebd66f00d1d68","unresolved":false,"context_lines":[{"line_number":49,"context_line":"                or r.get(\u0027Service\u0027)"},{"line_number":50,"context_line":"                or r.get(\u0027binary\u0027)"},{"line_number":51,"context_line":"                or r.get(\u0027service\u0027)"},{"line_number":52,"context_line":"            )"},{"line_number":53,"context_line":"            # Some deployments may include extra whitespace; normalize"},{"line_number":54,"context_line":"            if r_host is not None:"},{"line_number":55,"context_line":"                r_host \u003d str(r_host).strip()"},{"line_number":56,"context_line":"            if host is not None:"},{"line_number":57,"context_line":"                host \u003d str(host).strip()"},{"line_number":58,"context_line":"            if r_binary is not None:"},{"line_number":59,"context_line":"                r_binary \u003d str(r_binary).strip()"},{"line_number":60,"context_line":"            if binary is not None:"},{"line_number":61,"context_line":"                binary \u003d str(binary).strip()"},{"line_number":62,"context_line":"            self.assertEqual(host, r_host)"},{"line_number":63,"context_line":"            self.assertEqual(binary, r_binary)"},{"line_number":64,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"df76e8f1_6141e0a8","line":61,"range":{"start_line":52,"start_character":13,"end_line":61,"end_character":44},"in_reply_to":"1c42f6b8_54731777","updated":"2025-09-30 08:50:37.000000000","message":"Thank you for the clear point. I will remove these logics","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"bb0d4678f02d0cf16b5ad34185b408bfb967c8e8","unresolved":true,"context_lines":[{"line_number":73,"context_line":"        self.assertTrue(long_rows, \u0027no rows returned for --long list\u0027)"},{"line_number":74,"context_line":"        # Ensure status field exists in some form"},{"line_number":75,"context_line":"        lr0 \u003d long_rows[0]"},{"line_number":76,"context_line":"        status \u003d lr0.get(\u0027Status\u0027) or lr0.get(\u0027status\u0027)"},{"line_number":77,"context_line":"        self.assertIsNotNone(status)"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        # Additional format and sorting checks"}],"source_content_type":"text/x-python","patch_set":4,"id":"62f6e8e9_b20e62c0","line":76,"updated":"2025-09-10 09:50:09.000000000","message":"Same comment","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":38180,"name":"JIN YONG LEE","email":"ljy2855@gmail.com","username":"ljy2855"},"change_message_id":"03cd146282ec55d3ad212e23fdeebd66f00d1d68","unresolved":false,"context_lines":[{"line_number":73,"context_line":"        self.assertTrue(long_rows, \u0027no rows returned for --long list\u0027)"},{"line_number":74,"context_line":"        # Ensure status field exists in some form"},{"line_number":75,"context_line":"        lr0 \u003d long_rows[0]"},{"line_number":76,"context_line":"        status \u003d lr0.get(\u0027Status\u0027) or lr0.get(\u0027status\u0027)"},{"line_number":77,"context_line":"        self.assertIsNotNone(status)"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        # Additional format and sorting checks"}],"source_content_type":"text/x-python","patch_set":4,"id":"6e12428e_5a4afc2e","line":76,"in_reply_to":"62f6e8e9_b20e62c0","updated":"2025-09-30 08:50:37.000000000","message":"Done","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"bb0d4678f02d0cf16b5ad34185b408bfb967c8e8","unresolved":true,"context_lines":[{"line_number":76,"context_line":"        status \u003d lr0.get(\u0027Status\u0027) or lr0.get(\u0027status\u0027)"},{"line_number":77,"context_line":"        self.assertIsNotNone(status)"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        # Additional format and sorting checks"},{"line_number":80,"context_line":"        json_output \u003d self.openstack("},{"line_number":81,"context_line":"            \u0027volume service list -f json\u0027, parse_output\u003dTrue"},{"line_number":82,"context_line":"        )"},{"line_number":83,"context_line":"        self.assertTrue(json_output, \u0027JSON output is empty\u0027)"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"        yaml_output \u003d self.openstack("},{"line_number":86,"context_line":"            \u0027volume service list -f yaml\u0027, parse_output\u003dTrue"},{"line_number":87,"context_line":"        )"},{"line_number":88,"context_line":"        self.assertTrue(yaml_output, \u0027YAML output is empty\u0027)"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        # Value-format output: expect one host per line, optionally with backend suffix"},{"line_number":91,"context_line":"        value_output_raw \u003d self.openstack("},{"line_number":92,"context_line":"            \u0027volume service list -f value -c Host\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f646db5_69d9dcea","line":89,"range":{"start_line":79,"start_character":8,"end_line":89,"end_character":1},"updated":"2025-09-10 09:50:09.000000000","message":"The `parse_output` option causes the `-f json` option to be appended to the end of the command. If you pass the same argument multiple times don\u0027t have `nargs` configured then `argparse` will only respect the last option. As such, these tests aren\u0027t doing anything: you\u0027ll always get JSON output and you\u0027ve already tested it above.\n\nCan you remove these lines","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":38180,"name":"JIN YONG LEE","email":"ljy2855@gmail.com","username":"ljy2855"},"change_message_id":"03cd146282ec55d3ad212e23fdeebd66f00d1d68","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        status \u003d lr0.get(\u0027Status\u0027) or lr0.get(\u0027status\u0027)"},{"line_number":77,"context_line":"        self.assertIsNotNone(status)"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        # Additional format and sorting checks"},{"line_number":80,"context_line":"        json_output \u003d self.openstack("},{"line_number":81,"context_line":"            \u0027volume service list -f json\u0027, parse_output\u003dTrue"},{"line_number":82,"context_line":"        )"},{"line_number":83,"context_line":"        self.assertTrue(json_output, \u0027JSON output is empty\u0027)"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"        yaml_output \u003d self.openstack("},{"line_number":86,"context_line":"            \u0027volume service list -f yaml\u0027, parse_output\u003dTrue"},{"line_number":87,"context_line":"        )"},{"line_number":88,"context_line":"        self.assertTrue(yaml_output, \u0027YAML output is empty\u0027)"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        # Value-format output: expect one host per line, optionally with backend suffix"},{"line_number":91,"context_line":"        value_output_raw \u003d self.openstack("},{"line_number":92,"context_line":"            \u0027volume service list -f value -c Host\u0027"}],"source_content_type":"text/x-python","patch_set":4,"id":"fb645d3c_75fe79f2","line":89,"range":{"start_line":79,"start_character":8,"end_line":89,"end_character":1},"in_reply_to":"5f646db5_69d9dcea","updated":"2025-09-30 08:50:37.000000000","message":"Done","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"bb0d4678f02d0cf16b5ad34185b408bfb967c8e8","unresolved":true,"context_lines":[{"line_number":87,"context_line":"        )"},{"line_number":88,"context_line":"        self.assertTrue(yaml_output, \u0027YAML output is empty\u0027)"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        # Value-format output: expect one host per line, optionally with backend suffix"},{"line_number":91,"context_line":"        value_output_raw \u003d self.openstack("},{"line_number":92,"context_line":"            \u0027volume service list -f value -c Host\u0027"},{"line_number":93,"context_line":"        )"},{"line_number":94,"context_line":"        value_lines \u003d ["},{"line_number":95,"context_line":"            ln.strip() for ln in value_output_raw.splitlines() if ln.strip()"},{"line_number":96,"context_line":"        ]"},{"line_number":97,"context_line":"        self.assertTrue(value_lines, \u0027Value output for Host is empty\u0027)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"        # Validate each line is a single token (no spaces)"},{"line_number":100,"context_line":"        for host_line in value_lines:"},{"line_number":101,"context_line":"            self.assertTrue(host_line, \u0027Host value should not be empty\u0027)"},{"line_number":102,"context_line":"            self.assertNotIn("},{"line_number":103,"context_line":"                \u0027 \u0027, host_line, \u0027Host value should not contain spaces\u0027"},{"line_number":104,"context_line":"            )"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        # Cross-check that value output corresponds exactly to JSON hosts"},{"line_number":107,"context_line":"        json_hosts \u003d {"},{"line_number":108,"context_line":"            str(row.get(\u0027Host\u0027) or row.get(\u0027host\u0027)).strip()"},{"line_number":109,"context_line":"            for row in rows"},{"line_number":110,"context_line":"            if (row.get(\u0027Host\u0027) or row.get(\u0027host\u0027))"},{"line_number":111,"context_line":"        }"},{"line_number":112,"context_line":"        self.assertTrue("},{"line_number":113,"context_line":"            any(h in json_hosts for h in value_lines),"},{"line_number":114,"context_line":"            \u0027Value output hosts do not correspond to JSON list hosts\u0027,"},{"line_number":115,"context_line":"        )"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        # NOTE: Set volume service could affect other tests."},{"line_number":118,"context_line":"        #       So we don\u0027t disable it here. Only test set --enable."}],"source_content_type":"text/x-python","patch_set":4,"id":"93a35a63_160b945e","line":115,"range":{"start_line":90,"start_character":8,"end_line":115,"end_character":9},"updated":"2025-09-10 09:50:09.000000000","message":"This is a test of common functionality that is not specific to the `volume service list` command. I don\u0027t think we should test common functionality (where do you stop?). Can you remove these lines also?","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":38180,"name":"JIN YONG LEE","email":"ljy2855@gmail.com","username":"ljy2855"},"change_message_id":"03cd146282ec55d3ad212e23fdeebd66f00d1d68","unresolved":false,"context_lines":[{"line_number":87,"context_line":"        )"},{"line_number":88,"context_line":"        self.assertTrue(yaml_output, \u0027YAML output is empty\u0027)"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        # Value-format output: expect one host per line, optionally with backend suffix"},{"line_number":91,"context_line":"        value_output_raw \u003d self.openstack("},{"line_number":92,"context_line":"            \u0027volume service list -f value -c Host\u0027"},{"line_number":93,"context_line":"        )"},{"line_number":94,"context_line":"        value_lines \u003d ["},{"line_number":95,"context_line":"            ln.strip() for ln in value_output_raw.splitlines() if ln.strip()"},{"line_number":96,"context_line":"        ]"},{"line_number":97,"context_line":"        self.assertTrue(value_lines, \u0027Value output for Host is empty\u0027)"},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"        # Validate each line is a single token (no spaces)"},{"line_number":100,"context_line":"        for host_line in value_lines:"},{"line_number":101,"context_line":"            self.assertTrue(host_line, \u0027Host value should not be empty\u0027)"},{"line_number":102,"context_line":"            self.assertNotIn("},{"line_number":103,"context_line":"                \u0027 \u0027, host_line, \u0027Host value should not contain spaces\u0027"},{"line_number":104,"context_line":"            )"},{"line_number":105,"context_line":""},{"line_number":106,"context_line":"        # Cross-check that value output corresponds exactly to JSON hosts"},{"line_number":107,"context_line":"        json_hosts \u003d {"},{"line_number":108,"context_line":"            str(row.get(\u0027Host\u0027) or row.get(\u0027host\u0027)).strip()"},{"line_number":109,"context_line":"            for row in rows"},{"line_number":110,"context_line":"            if (row.get(\u0027Host\u0027) or row.get(\u0027host\u0027))"},{"line_number":111,"context_line":"        }"},{"line_number":112,"context_line":"        self.assertTrue("},{"line_number":113,"context_line":"            any(h in json_hosts for h in value_lines),"},{"line_number":114,"context_line":"            \u0027Value output hosts do not correspond to JSON list hosts\u0027,"},{"line_number":115,"context_line":"        )"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        # NOTE: Set volume service could affect other tests."},{"line_number":118,"context_line":"        #       So we don\u0027t disable it here. Only test set --enable."}],"source_content_type":"text/x-python","patch_set":4,"id":"a7f19748_e71549d2","line":115,"range":{"start_line":90,"start_character":8,"end_line":115,"end_character":9},"in_reply_to":"93a35a63_160b945e","updated":"2025-09-30 08:50:37.000000000","message":"Done","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"bb0d4678f02d0cf16b5ad34185b408bfb967c8e8","unresolved":true,"context_lines":[{"line_number":114,"context_line":"            \u0027Value output hosts do not correspond to JSON list hosts\u0027,"},{"line_number":115,"context_line":"        )"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        # NOTE: Set volume service could affect other tests."},{"line_number":118,"context_line":"        #       So we don\u0027t disable it here. Only test set --enable."},{"line_number":119,"context_line":"        raw_output \u003d self.openstack("},{"line_number":120,"context_line":"            \u0027volume service set --enable \u0027 + host + \u0027 \u0027 + binary"},{"line_number":121,"context_line":"        )"},{"line_number":122,"context_line":"        self.assertEqual(\u0027\u0027, raw_output)"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        cmd_output \u003d self.openstack("},{"line_number":125,"context_line":"            \u0027volume service list --long\u0027,"},{"line_number":126,"context_line":"            parse_output\u003dTrue,"},{"line_number":127,"context_line":"        )"},{"line_number":128,"context_line":"        self.assertEqual(\u0027enabled\u0027, cmd_output[0][\u0027Status\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"a0d76385_8dd0bf33","line":128,"range":{"start_line":117,"start_character":8,"end_line":128,"end_character":60},"updated":"2025-09-10 09:50:09.000000000","message":"I\u0027m still slightly concerned about this. What about if the service is currently disabled? It seems unlikely but stranger things have happened. I would probably drop this too","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":38180,"name":"JIN YONG LEE","email":"ljy2855@gmail.com","username":"ljy2855"},"change_message_id":"03cd146282ec55d3ad212e23fdeebd66f00d1d68","unresolved":false,"context_lines":[{"line_number":114,"context_line":"            \u0027Value output hosts do not correspond to JSON list hosts\u0027,"},{"line_number":115,"context_line":"        )"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"        # NOTE: Set volume service could affect other tests."},{"line_number":118,"context_line":"        #       So we don\u0027t disable it here. Only test set --enable."},{"line_number":119,"context_line":"        raw_output \u003d self.openstack("},{"line_number":120,"context_line":"            \u0027volume service set --enable \u0027 + host + \u0027 \u0027 + binary"},{"line_number":121,"context_line":"        )"},{"line_number":122,"context_line":"        self.assertEqual(\u0027\u0027, raw_output)"},{"line_number":123,"context_line":""},{"line_number":124,"context_line":"        cmd_output \u003d self.openstack("},{"line_number":125,"context_line":"            \u0027volume service list --long\u0027,"},{"line_number":126,"context_line":"            parse_output\u003dTrue,"},{"line_number":127,"context_line":"        )"},{"line_number":128,"context_line":"        self.assertEqual(\u0027enabled\u0027, cmd_output[0][\u0027Status\u0027])"}],"source_content_type":"text/x-python","patch_set":4,"id":"d18ea897_e54c7ebd","line":128,"range":{"start_line":117,"start_character":8,"end_line":128,"end_character":60},"in_reply_to":"a0d76385_8dd0bf33","updated":"2025-09-30 08:50:37.000000000","message":"I agree about that. These logic could affect other tests. I will remove these lines.","commit_id":"3a1aca076346c245e01c7421b6e23bd25149e844"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"3ba8c3416943299b461751ea13e96d771ccfbe71","unresolved":true,"context_lines":[{"line_number":31,"context_line":"        self.assertIsNotNone(host)"},{"line_number":32,"context_line":"        self.assertIsNotNone(binary)"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"        host_filter \u003d str(host)"},{"line_number":35,"context_line":"        binary_filter \u003d str(binary)"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":"        # Filter by host+service should return matching entries only"},{"line_number":38,"context_line":"        filtered \u003d self.openstack("}],"source_content_type":"text/x-python","patch_set":6,"id":"5a6260e4_30140ba2","line":35,"range":{"start_line":34,"start_character":0,"end_line":35,"end_character":35},"updated":"2025-11-12 12:43:36.000000000","message":"These values should be strings already? Why do you need the casts? Can you just use `host` and `binary` directly below?","commit_id":"25999d563be9f44919781437877c6f5279344c29"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"3ba8c3416943299b461751ea13e96d771ccfbe71","unresolved":true,"context_lines":[{"line_number":55,"context_line":"            + binary_filter,"},{"line_number":56,"context_line":"            parse_output\u003dTrue,"},{"line_number":57,"context_line":"        )"},{"line_number":58,"context_line":"        self.assertTrue(long_rows, \u0027no rows returned for --long list\u0027)"},{"line_number":59,"context_line":"        # Ensure disabled reason column exists (value may be None)"},{"line_number":60,"context_line":"        lr0 \u003d long_rows[0]"},{"line_number":61,"context_line":"        self.assertIn(\u0027Disabled Reason\u0027, lr0)"}],"source_content_type":"text/x-python","patch_set":6,"id":"0d53d174_7fcb212e","line":58,"updated":"2025-11-12 12:43:36.000000000","message":"Can you instead assert that out length is `1` (we should only have one service with the given host and binary)\n\n```suggestion\n        self.assertEqual(1, len(long_rows))\n```","commit_id":"25999d563be9f44919781437877c6f5279344c29"}]}
