)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":32171,"name":"Girish Chilukuri","email":"girish.chilukuri@ibm.com","username":"GirishChilukuri"},"change_message_id":"e4618fb6bd29df1b6589e591e5d71ec3dbc5aac9","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"APIs like quotas, volume type access etc require project"},{"line_number":10,"context_line":"validation. Currently the method to validate it exists in"},{"line_number":11,"context_line":"default types code. moving it to api_utils will allow other"},{"line_number":12,"context_line":"APIs to also reuse it."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I20f8e500f583eb85f24a4c36f344c11c7face06c"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"9ee8cf3b_2c266ba3","line":11,"range":{"start_line":11,"start_character":0,"end_line":11,"end_character":13},"updated":"2021-03-01 11:43:04.000000000","message":"I think \"default types\" should be \"default_types\", since the \"_validate_project_and_authorize\" method file name was default_types.py.","commit_id":"0a6f071177b47cdca9015b4ce0ec46a8b1e85b00"},{"author":{"_account_id":32171,"name":"Girish Chilukuri","email":"girish.chilukuri@ibm.com","username":"GirishChilukuri"},"change_message_id":"e4618fb6bd29df1b6589e591e5d71ec3dbc5aac9","unresolved":true,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"APIs like quotas, volume type access etc require project"},{"line_number":10,"context_line":"validation. Currently the method to validate it exists in"},{"line_number":11,"context_line":"default types code. moving it to api_utils will allow other"},{"line_number":12,"context_line":"APIs to also reuse it."},{"line_number":13,"context_line":""},{"line_number":14,"context_line":"Change-Id: I20f8e500f583eb85f24a4c36f344c11c7face06c"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":5,"id":"395bf159_8931aaa7","line":11,"range":{"start_line":11,"start_character":14,"end_line":11,"end_character":26},"updated":"2021-03-01 11:43:04.000000000","message":"we need to change either \u0027.\u0027 to \u0027,\u0027 or making \u0027m\u0027 capital","commit_id":"0a6f071177b47cdca9015b4ce0ec46a8b1e85b00"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"040c51fb86a4aeb157c4c2a5c4088f378d2bf596","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     Rajat Dhasmana \u003crajatdhasmana@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2021-03-05 17:01:53 -0500"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Refactor: move project validation to api_utils"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"APIs like quotas, volume type access etc require project"},{"line_number":10,"context_line":"validation. Currently the method to validate it exists in"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"c2a0dfb5_428b57fa","line":7,"range":{"start_line":7,"start_character":37,"end_line":7,"end_character":46},"updated":"2021-03-10 11:36:26.000000000","message":"unrelated rant you should ignore: I would prefer if we had just named it \"utils\" instead when it was first created.\n\nI know that we are doing this in other places, like with volume_utils, but in my opinion is not the proper approach.\n\nIf a utils.py file is in the api directory, the the namespace \"cinder.api.utils\" clearly specifies the kind of utils it is, and having it as \"cinder.api.api_utils\" seem redundant.\n\nThis is how we currently name other files such as \"api.py\", \"manager.py\", and \"rpcapi.py\" in backup, volume, and scheduler.","commit_id":"f0894c8a78ce3e85754686a51c3298c9815f20ff"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"59268b0fa1db7a210ad135e17c39e0397de57074","unresolved":true,"context_lines":[{"line_number":4,"context_line":"Commit:     Rajat Dhasmana \u003crajatdhasmana@gmail.com\u003e"},{"line_number":5,"context_line":"CommitDate: 2021-03-05 17:01:53 -0500"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Refactor: move project validation to api_utils"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"APIs like quotas, volume type access etc require project"},{"line_number":10,"context_line":"validation. Currently the method to validate it exists in"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"2a9277fe_58d6d8c5","line":7,"range":{"start_line":7,"start_character":37,"end_line":7,"end_character":46},"in_reply_to":"c2a0dfb5_428b57fa","updated":"2021-03-17 07:33:08.000000000","message":"+1","commit_id":"f0894c8a78ce3e85754686a51c3298c9815f20ff"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"040c51fb86a4aeb157c4c2a5c4088f378d2bf596","unresolved":true,"context_lines":[{"line_number":5,"context_line":"CommitDate: 2021-03-05 17:01:53 -0500"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Refactor: move project validation to api_utils"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"APIs like quotas, volume type access etc require project"},{"line_number":10,"context_line":"validation. Currently the method to validate it exists in"},{"line_number":11,"context_line":"default types code. moving it to api_utils will allow other"},{"line_number":12,"context_line":"APIs to also reuse it."},{"line_number":13,"context_line":"Also moving/renaming methods from quota_utils to api_utils"},{"line_number":14,"context_line":"since those not used by quota anymore."},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"cb0363a7_cd4d79a3","line":12,"range":{"start_line":8,"start_character":0,"end_line":12,"end_character":22},"updated":"2021-03-10 11:36:26.000000000","message":"nit: If I\u0027m understanding this correctly, a rephrasing of this paragraph could help better transmit the reason for this refactor.\n\nMaybe start saying that we currently only validate the existence of a project on the default types code so that we cannot set it for non existing projects, but there are other places where we would benefit from having this validation, such as setting quotas.\n\nI believe thhere was a bug related to that, so we should add the appropriate \"Related-Bug\" footer.","commit_id":"f0894c8a78ce3e85754686a51c3298c9815f20ff"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"59268b0fa1db7a210ad135e17c39e0397de57074","unresolved":false,"context_lines":[{"line_number":5,"context_line":"CommitDate: 2021-03-05 17:01:53 -0500"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"Refactor: move project validation to api_utils"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"APIs like quotas, volume type access etc require project"},{"line_number":10,"context_line":"validation. Currently the method to validate it exists in"},{"line_number":11,"context_line":"default types code. moving it to api_utils will allow other"},{"line_number":12,"context_line":"APIs to also reuse it."},{"line_number":13,"context_line":"Also moving/renaming methods from quota_utils to api_utils"},{"line_number":14,"context_line":"since those not used by quota anymore."},{"line_number":15,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":10,"id":"b03c2f80_90335632","line":12,"range":{"start_line":8,"start_character":0,"end_line":12,"end_character":22},"in_reply_to":"cb0363a7_cd4d79a3","updated":"2021-03-17 07:33:08.000000000","message":"Done","commit_id":"f0894c8a78ce3e85754686a51c3298c9815f20ff"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"322b87711b6be908cab85541f40828cfdaf6e718","unresolved":true,"context_lines":[{"line_number":15,"context_line":"to api_utils."},{"line_number":16,"context_line":"This patch also modifies the method get_project_hierarchy to get_project"},{"line_number":17,"context_line":"and removes related hierarchy tests since with the removal of nested quota"},{"line_number":18,"context_line":"driver we don\u0027t require the hierarchy properties anymore."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Related-Bug: #1638804"},{"line_number":21,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":12,"id":"df246682_22cf99f8","line":18,"updated":"2021-03-17 11:19:40.000000000","message":"nit: Commit message lines should be wrapped at 72 characters, as mentioned in the docs: https://wiki.openstack.org/wiki/GitCommitMessages","commit_id":"1f00a144376bf78bf2e83b1c118fb66cfafa405b"}],"cinder/api/contrib/volume_type_access.py":[{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"96f735385d123bce762a4b039e13ee10d25e9d00","unresolved":false,"context_lines":[{"line_number":100,"context_line":"    @validation.schema(volume_type_access.add_project_access)"},{"line_number":101,"context_line":"    def _addProjectAccess(self, req, id, body):"},{"line_number":102,"context_line":"        context \u003d req.environ[\u0027cinder.context\u0027]"},{"line_number":103,"context_line":"        project \u003d body[\u0027addProjectAccess\u0027][\u0027project\u0027]"},{"line_number":104,"context_line":"        utils.validate_project_and_authorize(context, project,"},{"line_number":105,"context_line":"                                             policy.ADD_PROJECT_POLICY)"},{"line_number":106,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9f560f44_87f35673","line":103,"updated":"2020-09-21 15:17:42.000000000","message":"I think that in an ideal world, in order to not change the error we return if the project is not in the body and they are not authorized we should catch any exception that happens here and raise it after the authorization.\n\nI don\u0027t really have a strong feeling about it though.","commit_id":"9cfe95a6584fc556bd8053d2c11ffd0c413d686a"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"96f735385d123bce762a4b039e13ee10d25e9d00","unresolved":false,"context_lines":[{"line_number":115,"context_line":"    @validation.schema(volume_type_access.remove_project_access)"},{"line_number":116,"context_line":"    def _removeProjectAccess(self, req, id, body):"},{"line_number":117,"context_line":"        context \u003d req.environ[\u0027cinder.context\u0027]"},{"line_number":118,"context_line":"        project \u003d body[\u0027removeProjectAccess\u0027][\u0027project\u0027]"},{"line_number":119,"context_line":"        utils.validate_project_and_authorize(context, project,"},{"line_number":120,"context_line":"                                             policy.REMOVE_PROJECT_POLICY)"},{"line_number":121,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"9f560f44_c7e9ce7f","line":118,"updated":"2020-09-21 15:17:42.000000000","message":"ditto","commit_id":"9cfe95a6584fc556bd8053d2c11ffd0c413d686a"}],"cinder/tests/unit/test_quota_utils.py":[{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"040c51fb86a4aeb157c4c2a5c4088f378d2bf596","unresolved":true,"context_lines":[{"line_number":113,"context_line":"            self.context, self.context.project_id)"},{"line_number":114,"context_line":"        self.assertEqual(expected_project.__dict__, project.__dict__)"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    @mock.patch(\u0027keystoneclient.client.Client\u0027)"},{"line_number":117,"context_line":"    def test_get_project_keystoneclient_v3_with_subtree(self, ksclient_class):"},{"line_number":118,"context_line":"        keystoneclient \u003d ksclient_class.return_value"},{"line_number":119,"context_line":"        keystoneclient.version \u003d \u0027v3\u0027"},{"line_number":120,"context_line":"        returned_project \u003d self.FakeProject(self.context.project_id, \u0027bar\u0027)"},{"line_number":121,"context_line":"        subtree_dict \u003d {\u0027baz\u0027: {\u0027quux\u0027: None}}"},{"line_number":122,"context_line":"        returned_project.subtree \u003d subtree_dict"},{"line_number":123,"context_line":"        keystoneclient.projects.get.return_value \u003d returned_project"},{"line_number":124,"context_line":"        expected_project \u003d quota_utils.GenericProjectInfo("},{"line_number":125,"context_line":"            self.context.project_id, \u0027v3\u0027, \u0027bar\u0027, subtree_dict,"},{"line_number":126,"context_line":"            domain_id\u003d\u0027default\u0027)"},{"line_number":127,"context_line":"        project \u003d quota_utils.get_project_hierarchy("},{"line_number":128,"context_line":"            self.context, self.context.project_id, subtree_as_ids\u003dTrue)"},{"line_number":129,"context_line":"        keystoneclient.projects.get.assert_called_once_with("},{"line_number":130,"context_line":"            self.context.project_id, parents_as_ids\u003dFalse, subtree_as_ids\u003dTrue)"},{"line_number":131,"context_line":"        self.assertEqual(expected_project.__dict__, project.__dict__)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def _setup_mock_ksclient(self, mock_client, version\u003d\u0027v3\u0027,"},{"line_number":134,"context_line":"                             subtree\u003dNone, parents\u003dNone):"},{"line_number":135,"context_line":"        keystoneclient \u003d mock_client.return_value"}],"source_content_type":"text/x-python","patch_set":10,"id":"ed8d61f0_72db39aa","side":"PARENT","line":132,"range":{"start_line":116,"start_character":0,"end_line":132,"end_character":0},"updated":"2021-03-10 11:36:26.000000000","message":"-1: Why are we removing this test?","commit_id":"babafa435c95720a07470e520f6486cd9cdd5acd"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"59268b0fa1db7a210ad135e17c39e0397de57074","unresolved":true,"context_lines":[{"line_number":113,"context_line":"            self.context, self.context.project_id)"},{"line_number":114,"context_line":"        self.assertEqual(expected_project.__dict__, project.__dict__)"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    @mock.patch(\u0027keystoneclient.client.Client\u0027)"},{"line_number":117,"context_line":"    def test_get_project_keystoneclient_v3_with_subtree(self, ksclient_class):"},{"line_number":118,"context_line":"        keystoneclient \u003d ksclient_class.return_value"},{"line_number":119,"context_line":"        keystoneclient.version \u003d \u0027v3\u0027"},{"line_number":120,"context_line":"        returned_project \u003d self.FakeProject(self.context.project_id, \u0027bar\u0027)"},{"line_number":121,"context_line":"        subtree_dict \u003d {\u0027baz\u0027: {\u0027quux\u0027: None}}"},{"line_number":122,"context_line":"        returned_project.subtree \u003d subtree_dict"},{"line_number":123,"context_line":"        keystoneclient.projects.get.return_value \u003d returned_project"},{"line_number":124,"context_line":"        expected_project \u003d quota_utils.GenericProjectInfo("},{"line_number":125,"context_line":"            self.context.project_id, \u0027v3\u0027, \u0027bar\u0027, subtree_dict,"},{"line_number":126,"context_line":"            domain_id\u003d\u0027default\u0027)"},{"line_number":127,"context_line":"        project \u003d quota_utils.get_project_hierarchy("},{"line_number":128,"context_line":"            self.context, self.context.project_id, subtree_as_ids\u003dTrue)"},{"line_number":129,"context_line":"        keystoneclient.projects.get.assert_called_once_with("},{"line_number":130,"context_line":"            self.context.project_id, parents_as_ids\u003dFalse, subtree_as_ids\u003dTrue)"},{"line_number":131,"context_line":"        self.assertEqual(expected_project.__dict__, project.__dict__)"},{"line_number":132,"context_line":""},{"line_number":133,"context_line":"    def _setup_mock_ksclient(self, mock_client, version\u003d\u0027v3\u0027,"},{"line_number":134,"context_line":"                             subtree\u003dNone, parents\u003dNone):"},{"line_number":135,"context_line":"        keystoneclient \u003d mock_client.return_value"}],"source_content_type":"text/x-python","patch_set":10,"id":"dbb9c4c6_bd35c0ca","side":"PARENT","line":132,"range":{"start_line":116,"start_character":0,"end_line":132,"end_character":0},"in_reply_to":"ed8d61f0_72db39aa","updated":"2021-03-17 07:33:08.000000000","message":"I\u0027ve updated the get_project_hierarchy method to get_project that only fetches project details without the hierarchy. Since the hierarchy was used in nested quota driver (which we\u0027ve removed) it makes sense to just validate project for current APIs. I will update the commit msg to reflect it.","commit_id":"babafa435c95720a07470e520f6486cd9cdd5acd"},{"author":{"_account_id":9535,"name":"Gorka Eguileor","email":"geguileo@redhat.com","username":"Gorka"},"change_message_id":"040c51fb86a4aeb157c4c2a5c4088f378d2bf596","unresolved":true,"context_lines":[{"line_number":151,"context_line":"        self.assertIsNone(project.parent_id)"},{"line_number":152,"context_line":"        self.assertIsNone(project.parents)"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"    @mock.patch(\u0027keystoneclient.client.Client\u0027)"},{"line_number":155,"context_line":"    def test__filter_domain_id_from_parents_domain_as_grandparent("},{"line_number":156,"context_line":"            self, mock_client):"},{"line_number":157,"context_line":"        # Test with a child project (domain is more than a parent)"},{"line_number":158,"context_line":"        self._setup_mock_ksclient(mock_client,"},{"line_number":159,"context_line":"                                  parents\u003d{\u0027bar\u0027: {\u0027default\u0027: None}})"},{"line_number":160,"context_line":"        project \u003d quota_utils.get_project_hierarchy("},{"line_number":161,"context_line":"            self.context, self.context.project_id, parents_as_ids\u003dTrue)"},{"line_number":162,"context_line":"        self.assertEqual(\u0027bar\u0027, project.parent_id)"},{"line_number":163,"context_line":"        self.assertEqual({\u0027bar\u0027: None}, project.parents)"},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"    @mock.patch(\u0027keystoneclient.client.Client\u0027)"},{"line_number":166,"context_line":"    def test__filter_domain_id_from_parents_no_domain_in_parents("},{"line_number":167,"context_line":"            self, mock_client):"},{"line_number":168,"context_line":"        # Test that if top most parent is not a domain (to simulate an older"},{"line_number":169,"context_line":"        # keystone version) nothing gets removed from the tree"},{"line_number":170,"context_line":"        parents \u003d {\u0027bar\u0027: {\u0027foo\u0027: None}}"},{"line_number":171,"context_line":"        self._setup_mock_ksclient(mock_client, parents\u003dparents)"},{"line_number":172,"context_line":"        project \u003d quota_utils.get_project_hierarchy("},{"line_number":173,"context_line":"            self.context, self.context.project_id, parents_as_ids\u003dTrue)"},{"line_number":174,"context_line":"        self.assertEqual(\u0027bar\u0027, project.parent_id)"},{"line_number":175,"context_line":"        self.assertEqual(parents, project.parents)"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    @mock.patch(\u0027keystoneclient.client.Client\u0027)"},{"line_number":178,"context_line":"    def test__filter_domain_id_from_parents_no_parents("},{"line_number":179,"context_line":"            self, mock_client):"},{"line_number":180,"context_line":"        # Test that if top no parents are present (to simulate an older"},{"line_number":181,"context_line":"        # keystone version) things don\u0027t blow up"},{"line_number":182,"context_line":"        self._setup_mock_ksclient(mock_client)"},{"line_number":183,"context_line":"        project \u003d quota_utils.get_project_hierarchy("},{"line_number":184,"context_line":"            self.context, self.context.project_id, parents_as_ids\u003dTrue)"},{"line_number":185,"context_line":"        self.assertIsNone(project.parent_id)"},{"line_number":186,"context_line":"        self.assertIsNone(project.parents)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def _process_reserve_over_quota(self, overs, usages, quotas,"},{"line_number":189,"context_line":"                                    expected_ex,"}],"source_content_type":"text/x-python","patch_set":10,"id":"21538d2d_b327966c","side":"PARENT","line":186,"range":{"start_line":154,"start_character":0,"end_line":186,"end_character":42},"updated":"2021-03-10 11:36:26.000000000","message":"-1: Why are we removing these tests?","commit_id":"babafa435c95720a07470e520f6486cd9cdd5acd"},{"author":{"_account_id":27615,"name":"Rajat Dhasmana","email":"rajatdhasmana@gmail.com","username":"whoami-rajat"},"change_message_id":"59268b0fa1db7a210ad135e17c39e0397de57074","unresolved":true,"context_lines":[{"line_number":151,"context_line":"        self.assertIsNone(project.parent_id)"},{"line_number":152,"context_line":"        self.assertIsNone(project.parents)"},{"line_number":153,"context_line":""},{"line_number":154,"context_line":"    @mock.patch(\u0027keystoneclient.client.Client\u0027)"},{"line_number":155,"context_line":"    def test__filter_domain_id_from_parents_domain_as_grandparent("},{"line_number":156,"context_line":"            self, mock_client):"},{"line_number":157,"context_line":"        # Test with a child project (domain is more than a parent)"},{"line_number":158,"context_line":"        self._setup_mock_ksclient(mock_client,"},{"line_number":159,"context_line":"                                  parents\u003d{\u0027bar\u0027: {\u0027default\u0027: None}})"},{"line_number":160,"context_line":"        project \u003d quota_utils.get_project_hierarchy("},{"line_number":161,"context_line":"            self.context, self.context.project_id, parents_as_ids\u003dTrue)"},{"line_number":162,"context_line":"        self.assertEqual(\u0027bar\u0027, project.parent_id)"},{"line_number":163,"context_line":"        self.assertEqual({\u0027bar\u0027: None}, project.parents)"},{"line_number":164,"context_line":""},{"line_number":165,"context_line":"    @mock.patch(\u0027keystoneclient.client.Client\u0027)"},{"line_number":166,"context_line":"    def test__filter_domain_id_from_parents_no_domain_in_parents("},{"line_number":167,"context_line":"            self, mock_client):"},{"line_number":168,"context_line":"        # Test that if top most parent is not a domain (to simulate an older"},{"line_number":169,"context_line":"        # keystone version) nothing gets removed from the tree"},{"line_number":170,"context_line":"        parents \u003d {\u0027bar\u0027: {\u0027foo\u0027: None}}"},{"line_number":171,"context_line":"        self._setup_mock_ksclient(mock_client, parents\u003dparents)"},{"line_number":172,"context_line":"        project \u003d quota_utils.get_project_hierarchy("},{"line_number":173,"context_line":"            self.context, self.context.project_id, parents_as_ids\u003dTrue)"},{"line_number":174,"context_line":"        self.assertEqual(\u0027bar\u0027, project.parent_id)"},{"line_number":175,"context_line":"        self.assertEqual(parents, project.parents)"},{"line_number":176,"context_line":""},{"line_number":177,"context_line":"    @mock.patch(\u0027keystoneclient.client.Client\u0027)"},{"line_number":178,"context_line":"    def test__filter_domain_id_from_parents_no_parents("},{"line_number":179,"context_line":"            self, mock_client):"},{"line_number":180,"context_line":"        # Test that if top no parents are present (to simulate an older"},{"line_number":181,"context_line":"        # keystone version) things don\u0027t blow up"},{"line_number":182,"context_line":"        self._setup_mock_ksclient(mock_client)"},{"line_number":183,"context_line":"        project \u003d quota_utils.get_project_hierarchy("},{"line_number":184,"context_line":"            self.context, self.context.project_id, parents_as_ids\u003dTrue)"},{"line_number":185,"context_line":"        self.assertIsNone(project.parent_id)"},{"line_number":186,"context_line":"        self.assertIsNone(project.parents)"},{"line_number":187,"context_line":""},{"line_number":188,"context_line":"    def _process_reserve_over_quota(self, overs, usages, quotas,"},{"line_number":189,"context_line":"                                    expected_ex,"}],"source_content_type":"text/x-python","patch_set":10,"id":"fdb5bf45_6823d28f","side":"PARENT","line":186,"range":{"start_line":154,"start_character":0,"end_line":186,"end_character":42},"in_reply_to":"21538d2d_b327966c","updated":"2021-03-17 07:33:08.000000000","message":"same","commit_id":"babafa435c95720a07470e520f6486cd9cdd5acd"}]}
