)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0662357f83fd56939165f9f18262681bd26d519f","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"this is a follow-up of 9fc1cc67d993cfa0afc46aaea2802e1c35445f77, fixing"},{"line_number":10,"context_line":"comments and finishing the left refactoring."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: If4048412c01c9d3ca341f7356908dd4221b40a28"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"9a68dd71_ec73dae5","line":11,"updated":"2016-01-21 15:01:03.000000000","message":"Cloud add: \n\n    Related-Bug: #1506473\n\nSince it contains context about 9fc1cc67d993cfa0afc46aaea2802e1c35445f77","commit_id":"b469688809430a36e93aaf025d797d8d8e1c47be"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2b6aa9de7edf98cd4dfe129c7e6f7c172c1d94a9","unresolved":false,"context_lines":[{"line_number":8,"context_line":""},{"line_number":9,"context_line":"this is a follow-up of 9fc1cc67d993cfa0afc46aaea2802e1c35445f77, fixing"},{"line_number":10,"context_line":"comments and finishing the left refactoring."},{"line_number":11,"context_line":""},{"line_number":12,"context_line":"Change-Id: If4048412c01c9d3ca341f7356908dd4221b40a28"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"7af24918_b4497f33","line":11,"updated":"2016-03-04 15:24:43.000000000","message":"Could add: \n\n    Related-Bug: #1506473\n\nSince it contains context about the patch.","commit_id":"b127a634a1b2674c42d9e0b7ff3b1d7a6c1f6ecb"}],"keystone/contrib/ec2/controllers.py":[{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"5edc4ad00df4f5e4ad4283cb0f6cbb1231d27054","unresolved":false,"context_lines":[{"line_number":47,"context_line":"from keystone import exception"},{"line_number":48,"context_line":"from keystone.i18n import _"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"CRED_TYPE_EC2 \u003d \u0027ec2\u0027"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"fa69d971_7000dd66","line":50,"updated":"2016-01-10 07:58:35.000000000","message":"unnecessary change?","commit_id":"02b68841c0b70cd1bec07898132424d044c0c1cc"},{"author":{"_account_id":19197,"name":"Tony Wang","inactive":true},"change_message_id":"f1c5012cce6021abb80288c4e596213eba6cefac","unresolved":false,"context_lines":[{"line_number":47,"context_line":"from keystone import exception"},{"line_number":48,"context_line":"from keystone.i18n import _"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"CRED_TYPE_EC2 \u003d \u0027ec2\u0027"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"fa69d971_f01a8dc5","line":50,"in_reply_to":"fa69d971_7000dd66","updated":"2016-01-10 08:35:36.000000000","message":"pointed out in the previous patch that two empty lines are needed after import\nhttp://docs.openstack.org/developer/hacking/#import-order-template","commit_id":"02b68841c0b70cd1bec07898132424d044c0c1cc"}],"keystone/tests/unit/rest.py":[{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"5edc4ad00df4f5e4ad4283cb0f6cbb1231d27054","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        \"\"\"Ensures that response headers appear as expected.\"\"\""},{"line_number":126,"context_line":"        self.assertIn(\u0027X-Auth-Token\u0027, response.headers.get(\u0027Vary\u0027))"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":129,"context_line":"        \"\"\"Verify that the error response is valid.\"\"\""},{"line_number":130,"context_line":"        resp \u003d r.result"},{"line_number":131,"context_line":"        self.assertIsNotNone(resp.get(\u0027error\u0027))"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa69d971_303ee528","line":128,"range":{"start_line":128,"start_character":4,"end_line":128,"end_character":42},"updated":"2016-01-10 07:58:35.000000000","message":"careful with this change, i think a lot of tests uses this function","commit_id":"02b68841c0b70cd1bec07898132424d044c0c1cc"},{"author":{"_account_id":19197,"name":"Tony Wang","inactive":true},"change_message_id":"f1c5012cce6021abb80288c4e596213eba6cefac","unresolved":false,"context_lines":[{"line_number":125,"context_line":"        \"\"\"Ensures that response headers appear as expected.\"\"\""},{"line_number":126,"context_line":"        self.assertIn(\u0027X-Auth-Token\u0027, response.headers.get(\u0027Vary\u0027))"},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":129,"context_line":"        \"\"\"Verify that the error response is valid.\"\"\""},{"line_number":130,"context_line":"        resp \u003d r.result"},{"line_number":131,"context_line":"        self.assertIsNotNone(resp.get(\u0027error\u0027))"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa69d971_90c8f123","line":128,"range":{"start_line":128,"start_character":4,"end_line":128,"end_character":42},"in_reply_to":"fa69d971_303ee528","updated":"2016-01-10 08:35:36.000000000","message":"I\u0027m aware of that. I checked all the usages, which either already checked expected_status, or in self.restful_request, that should not care the status code, but only if this is valid error response.\n\nso it\u0027s actually not necessary to check expected_status in this function, because it\u0027s already checked in self.request, then in app.request, which is handled by webtest","commit_id":"02b68841c0b70cd1bec07898132424d044c0c1cc"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"5edc4ad00df4f5e4ad4283cb0f6cbb1231d27054","unresolved":false,"context_lines":[{"line_number":128,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":129,"context_line":"        \"\"\"Verify that the error response is valid.\"\"\""},{"line_number":130,"context_line":"        resp \u003d r.result"},{"line_number":131,"context_line":"        self.assertIsNotNone(resp.get(\u0027error\u0027))"},{"line_number":132,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027code\u0027))"},{"line_number":133,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027title\u0027))"},{"line_number":134,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027message\u0027))"},{"line_number":135,"context_line":"        self.assertEqual(int(resp[\u0027error\u0027][\u0027code\u0027]), r.status_code)"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa69d971_5032795f","line":132,"range":{"start_line":131,"start_character":8,"end_line":132,"end_character":55},"updated":"2016-01-10 07:58:35.000000000","message":"i think these two are redundant, the code below will fail if these aren\u0027t passing, but not a big deal","commit_id":"02b68841c0b70cd1bec07898132424d044c0c1cc"},{"author":{"_account_id":19197,"name":"Tony Wang","inactive":true},"change_message_id":"f1c5012cce6021abb80288c4e596213eba6cefac","unresolved":false,"context_lines":[{"line_number":128,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":129,"context_line":"        \"\"\"Verify that the error response is valid.\"\"\""},{"line_number":130,"context_line":"        resp \u003d r.result"},{"line_number":131,"context_line":"        self.assertIsNotNone(resp.get(\u0027error\u0027))"},{"line_number":132,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027code\u0027))"},{"line_number":133,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027title\u0027))"},{"line_number":134,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027message\u0027))"},{"line_number":135,"context_line":"        self.assertEqual(int(resp[\u0027error\u0027][\u0027code\u0027]), r.status_code)"}],"source_content_type":"text/x-python","patch_set":1,"id":"fa69d971_b0cdf532","line":132,"range":{"start_line":131,"start_character":8,"end_line":132,"end_character":55},"in_reply_to":"fa69d971_5032795f","updated":"2016-01-10 08:35:36.000000000","message":"right, I did copy/paste. I\u0027ll remove this in next commit","commit_id":"02b68841c0b70cd1bec07898132424d044c0c1cc"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"5edc4ad00df4f5e4ad4283cb0f6cbb1231d27054","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027code\u0027))"},{"line_number":133,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027title\u0027))"},{"line_number":134,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027message\u0027))"},{"line_number":135,"context_line":"        self.assertEqual(int(resp[\u0027error\u0027][\u0027code\u0027]), r.status_code)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def _to_content_type(self, body, headers, content_type\u003dNone):"},{"line_number":138,"context_line":"        \"\"\"Attempt to encode JSON and XML automatically.\"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"fa69d971_70377d4d","line":135,"range":{"start_line":135,"start_character":8,"end_line":135,"end_character":67},"updated":"2016-01-10 07:58:35.000000000","message":"We are potentially losing coverage by removing the check against the actual code:\n\n\n  self.assertEqual(expected_status, r.status_code)\n\nwhere expected_status\u003dhttp_client.BAD_REQUEST","commit_id":"02b68841c0b70cd1bec07898132424d044c0c1cc"},{"author":{"_account_id":19197,"name":"Tony Wang","inactive":true},"change_message_id":"f1c5012cce6021abb80288c4e596213eba6cefac","unresolved":false,"context_lines":[{"line_number":132,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027code\u0027))"},{"line_number":133,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027title\u0027))"},{"line_number":134,"context_line":"        self.assertIsNotNone(resp[\u0027error\u0027].get(\u0027message\u0027))"},{"line_number":135,"context_line":"        self.assertEqual(int(resp[\u0027error\u0027][\u0027code\u0027]), r.status_code)"},{"line_number":136,"context_line":""},{"line_number":137,"context_line":"    def _to_content_type(self, body, headers, content_type\u003dNone):"},{"line_number":138,"context_line":"        \"\"\"Attempt to encode JSON and XML automatically.\"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"fa69d971_70ea1d76","line":135,"range":{"start_line":135,"start_character":8,"end_line":135,"end_character":67},"in_reply_to":"fa69d971_70377d4d","updated":"2016-01-10 08:35:36.000000000","message":"As mentioned above, r.status_code is checked in self.request, then in webtest, so this should not be a problem.\n\nThe problem I met is that a test posted something and the expected status is not 400, but `requestful_request` doesn\u0027t call assertValidErrorResponse with an `expected_status`, (also, test_v2, test_v3 override `assertValidErrorResponse`, losing `expected_status`).","commit_id":"02b68841c0b70cd1bec07898132424d044c0c1cc"}],"keystone/tests/unit/test_credential.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"3dd6f1c4c94eb90004f9d1ca558f7fb09bece95c","unresolved":false,"context_lines":[{"line_number":68,"context_line":"        self.assertEqual(1, len(cred_list))"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def test_ec2_cannot_list_non_ec2_credentials(self):"},{"line_number":71,"context_line":"        uri \u003d self._get_ec2_cred_uri()"},{"line_number":72,"context_line":"        non_ec2_cred \u003d unit.new_credential_ref("},{"line_number":73,"context_line":"            user_id\u003dself.user_id,"},{"line_number":74,"context_line":"            project_id\u003dself.project_id)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a68dd71_e5924357","line":71,"range":{"start_line":71,"start_character":8,"end_line":71,"end_character":38},"updated":"2016-01-20 18:29:36.000000000","message":"nit: move this down to where it is used on line 77","commit_id":"02b68841c0b70cd1bec07898132424d044c0c1cc"}],"keystone/tests/unit/test_v2.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2b6aa9de7edf98cd4dfe129c7e6f7c172c1d94a9","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    def assertValidError(self, error):"},{"line_number":36,"context_line":"        self.assertIsNotNone(error.get(\u0027code\u0027))"},{"line_number":37,"context_line":"        self.assertIsNotNone(error.get(\u0027title\u0027))"},{"line_number":38,"context_line":"        self.assertIsNotNone(error.get(\u0027message\u0027))"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    def assertValidVersion(self, version):"},{"line_number":41,"context_line":"        self.assertIsNotNone(version)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7af24918_9f1d6275","side":"PARENT","line":38,"updated":"2016-03-04 15:24:43.000000000","message":"Is this required for this patch?","commit_id":"ec5e5f1707f545dfce24cbd72ec7ad4a94414211"},{"author":{"_account_id":19197,"name":"Tony Wang","inactive":true},"change_message_id":"7660ed0517613409dab0b4d91b99caf3b55f49f2","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    def assertValidError(self, error):"},{"line_number":36,"context_line":"        self.assertIsNotNone(error.get(\u0027code\u0027))"},{"line_number":37,"context_line":"        self.assertIsNotNone(error.get(\u0027title\u0027))"},{"line_number":38,"context_line":"        self.assertIsNotNone(error.get(\u0027message\u0027))"},{"line_number":39,"context_line":""},{"line_number":40,"context_line":"    def assertValidVersion(self, version):"},{"line_number":41,"context_line":"        self.assertIsNotNone(version)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7af24918_42de5ddd","side":"PARENT","line":38,"in_reply_to":"7af24918_9f1d6275","updated":"2016-03-04 15:34:47.000000000","message":"This patch is to clean up the undesired code that `assertValidErrorResponse` from test_v2/test_v3 has different function signature with its parent\u0027s in rest.py","commit_id":"ec5e5f1707f545dfce24cbd72ec7ad4a94414211"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"2b6aa9de7edf98cd4dfe129c7e6f7c172c1d94a9","unresolved":false,"context_lines":[{"line_number":1017,"context_line":"    def assertValidErrorResponse(self, r):"},{"line_number":1018,"context_line":"        self.assertIsNotNone(r.result.get(\u0027error\u0027))"},{"line_number":1019,"context_line":"        self.assertValidError(r.result[\u0027error\u0027])"},{"line_number":1020,"context_line":"        self.assertEqual(r.result[\u0027error\u0027][\u0027code\u0027], r.status_code)"},{"line_number":1021,"context_line":""},{"line_number":1022,"context_line":"    def assertValidExtension(self, extension, expected):"},{"line_number":1023,"context_line":"        super(V2TestCase, self).assertValidExtension(extension)"}],"source_content_type":"text/x-python","patch_set":3,"id":"7af24918_1f0af225","side":"PARENT","line":1020,"updated":"2016-03-04 15:24:43.000000000","message":"Same comment here.","commit_id":"ec5e5f1707f545dfce24cbd72ec7ad4a94414211"}],"keystone/tests/unit/test_v3_credential.py":[{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"3dd6f1c4c94eb90004f9d1ca558f7fb09bece95c","unresolved":false,"context_lines":[{"line_number":443,"context_line":"        self.assertThat(r.result[\u0027links\u0027][\u0027self\u0027], matchers.EndsWith(uri))"},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"    def test_ec2_cannot_list_non_ec2_credentials(self):"},{"line_number":446,"context_line":"        uri \u003d self._get_ec2_cred_uri()"},{"line_number":447,"context_line":"        non_ec2_cred \u003d unit.new_credential_ref("},{"line_number":448,"context_line":"            user_id\u003dself.user_id,"},{"line_number":449,"context_line":"            project_id\u003dself.project_id)"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a68dd71_259e1b57","line":446,"range":{"start_line":446,"start_character":8,"end_line":446,"end_character":38},"updated":"2016-01-20 18:29:36.000000000","message":"nit: same comment as previous","commit_id":"02b68841c0b70cd1bec07898132424d044c0c1cc"},{"author":{"_account_id":5046,"name":"Lance Bragstad","email":"lbragstad@redhat.com","username":"ldbragst"},"change_message_id":"0662357f83fd56939165f9f18262681bd26d519f","unresolved":false,"context_lines":[{"line_number":442,"context_line":"        self.assertEqual(1, len(cred_list))"},{"line_number":443,"context_line":"        self.assertThat(r.result[\u0027links\u0027][\u0027self\u0027], matchers.EndsWith(uri))"},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"    def test_ec2_cannot_list_non_ec2_credentials(self):"},{"line_number":446,"context_line":"        non_ec2_cred \u003d unit.new_credential_ref("},{"line_number":447,"context_line":"            user_id\u003dself.user_id,"},{"line_number":448,"context_line":"            project_id\u003dself.project_id)"},{"line_number":449,"context_line":"        non_ec2_cred[\u0027type\u0027] \u003d uuid.uuid4().hex"},{"line_number":450,"context_line":"        self.credential_api.create_credential(non_ec2_cred[\u0027id\u0027], non_ec2_cred)"},{"line_number":451,"context_line":"        uri \u003d self._get_ec2_cred_uri()"},{"line_number":452,"context_line":"        r \u003d self.get(uri)"},{"line_number":453,"context_line":"        cred_list \u003d r.result[\u0027credentials\u0027]"},{"line_number":454,"context_line":"        # non-EC2 credentials are not returned."},{"line_number":455,"context_line":"        self.assertEqual(0, len(cred_list))"},{"line_number":456,"context_line":""},{"line_number":457,"context_line":"        # add an EC2 credential"},{"line_number":458,"context_line":"        self._get_ec2_cred()"},{"line_number":459,"context_line":"        r \u003d self.get(uri)"},{"line_number":460,"context_line":"        cred_list \u003d r.result[\u0027credentials\u0027]"},{"line_number":461,"context_line":"        self.assertEqual(1, len(cred_list))"},{"line_number":462,"context_line":""},{"line_number":463,"context_line":"    def test_ec2_delete_credential(self):"},{"line_number":464,"context_line":"        \"\"\"Test ec2 credential deletion.\"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_873559db","line":461,"range":{"start_line":445,"start_character":4,"end_line":461,"end_character":43},"updated":"2016-01-21 15:01:03.000000000","message":"This entire test shows a behavior that is already tested in test_credential.py, is there anyway we can consolidate the behavior and keep setUp specific stuff in a test class that inherits/tests the behavior?","commit_id":"b469688809430a36e93aaf025d797d8d8e1c47be"},{"author":{"_account_id":19197,"name":"Tony Wang","inactive":true},"change_message_id":"a8fcd6edaa5a13a2036119c1744deeabf43f2740","unresolved":false,"context_lines":[{"line_number":442,"context_line":"        self.assertEqual(1, len(cred_list))"},{"line_number":443,"context_line":"        self.assertThat(r.result[\u0027links\u0027][\u0027self\u0027], matchers.EndsWith(uri))"},{"line_number":444,"context_line":""},{"line_number":445,"context_line":"    def test_ec2_cannot_list_non_ec2_credentials(self):"},{"line_number":446,"context_line":"        non_ec2_cred \u003d unit.new_credential_ref("},{"line_number":447,"context_line":"            user_id\u003dself.user_id,"},{"line_number":448,"context_line":"            project_id\u003dself.project_id)"},{"line_number":449,"context_line":"        non_ec2_cred[\u0027type\u0027] \u003d uuid.uuid4().hex"},{"line_number":450,"context_line":"        self.credential_api.create_credential(non_ec2_cred[\u0027id\u0027], non_ec2_cred)"},{"line_number":451,"context_line":"        uri \u003d self._get_ec2_cred_uri()"},{"line_number":452,"context_line":"        r \u003d self.get(uri)"},{"line_number":453,"context_line":"        cred_list \u003d r.result[\u0027credentials\u0027]"},{"line_number":454,"context_line":"        # non-EC2 credentials are not returned."},{"line_number":455,"context_line":"        self.assertEqual(0, len(cred_list))"},{"line_number":456,"context_line":""},{"line_number":457,"context_line":"        # add an EC2 credential"},{"line_number":458,"context_line":"        self._get_ec2_cred()"},{"line_number":459,"context_line":"        r \u003d self.get(uri)"},{"line_number":460,"context_line":"        cred_list \u003d r.result[\u0027credentials\u0027]"},{"line_number":461,"context_line":"        self.assertEqual(1, len(cred_list))"},{"line_number":462,"context_line":""},{"line_number":463,"context_line":"    def test_ec2_delete_credential(self):"},{"line_number":464,"context_line":"        \"\"\"Test ec2 credential deletion.\"\"\""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a68dd71_a362acab","line":461,"range":{"start_line":445,"start_character":4,"end_line":461,"end_character":43},"in_reply_to":"9a68dd71_873559db","updated":"2016-01-22 06:19:14.000000000","message":"Right, but I\u0027m not sure how to do it decently. Maybe in another commit.","commit_id":"b469688809430a36e93aaf025d797d8d8e1c47be"}]}
