# # Copyright 2013 - Red Hat, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. # """ Unit tests for EC2 error responses. """ from lxml import etree from oslotest import base as test_base from ec2api import api as ec2 from ec2api import context from ec2api import wsgi class TestClientExceptionEC2(Exception): ec2_code = 'ClientException.Test' message = "Test Client Exception." code = 400 class TestServerExceptionEC2(Exception): ec2_code = 'ServerException.Test' message = "Test Server Exception." code = 500 class Ec2ErrorResponseTestCase(test_base.BaseTestCase): """Test EC2 error responses. This deals mostly with api/ec2/__init__.py code, especially the ec2_error_ex helper. """ def setUp(self): super(Ec2ErrorResponseTestCase, self).setUp() self.context = context.RequestContext('test_user_id', 'test_project_id') self.req = wsgi.Request.blank('/test') self.req.environ['ec2api.context'] = self.context def _validate_ec2_error(self, response, http_status, ec2_code, msg=None, unknown_msg=False): self.assertEqual(response.status_code, http_status, 'Expected HTTP status %s' % http_status) root_e = etree.XML(response.body) self.assertEqual(root_e.tag, 'Response', "Top element must be Response.") errors_e = root_e.find('Errors') self.assertEqual(len(errors_e), 1, "Expected exactly one Error element in Errors.") error_e = errors_e[0] self.assertEqual(error_e.tag, 'Error', "Expected Error element.") # Code code_e = error_e.find('Code') self.assertIsNotNone(code_e, "Code element must be present.") self.assertEqual(code_e.text, ec2_code) # Message if msg or unknown_msg: message_e = error_e.find('Message') self.assertIsNotNone(code_e, "Message element must be present.") if msg: self.assertEqual(message_e.text, msg) elif unknown_msg: self.assertEqual(message_e.text, "Unknown error occurred.", "Error message should be anonymous.") # RequestID requestid_e = root_e.find('RequestID') self.assertIsNotNone(requestid_e, 'RequestID element should be present.') self.assertEqual(requestid_e.text, self.context.request_id) def test_exception_ec2_4xx(self): """Test response to EC2 exception with code = 400.""" msg = "Test client failure." err = ec2.ec2_error_ex(TestClientExceptionEC2(msg), self.req) self._validate_ec2_error(err, TestClientExceptionEC2.code, TestClientExceptionEC2.ec2_code, msg) def test_exception_ec2_5xx(self): """Test response to EC2 exception with code = 500. Expected errors are treated as client ones even with 5xx code. """ msg = "Test client failure with 5xx error code." err = ec2.ec2_error_ex(TestServerExceptionEC2(msg), self.req) self._validate_ec2_error(err, 400, TestServerExceptionEC2.ec2_code, msg) def test_unexpected_exception_ec2_4xx(self): """Test response to unexpected EC2 exception with code = 400.""" msg = "Test unexpected client failure." err = ec2.ec2_error_ex(TestClientExceptionEC2(msg), self.req, unexpected=True) self._validate_ec2_error(err, TestClientExceptionEC2.code, TestClientExceptionEC2.ec2_code, msg) def test_unexpected_exception_ec2_5xx(self): """Test response to unexpected EC2 exception with code = 500. Server exception messages (with code >= 500 or without code) should be filtered as they might contain sensitive information. """ msg = "Test server failure." err = ec2.ec2_error_ex(TestServerExceptionEC2(msg), self.req, unexpected=True) self._validate_ec2_error(err, TestServerExceptionEC2.code, TestServerExceptionEC2.ec2_code, unknown_msg=True) def test_unexpected_exception_builtin(self): """Test response to builtin unexpected exception. Server exception messages (with code >= 500 or without code) should be filtered as they might contain sensitive information. """ msg = "Test server failure." err = ec2.ec2_error_ex(RuntimeError(msg), self.req, unexpected=True) self._validate_ec2_error(err, 500, 'RuntimeError', unknown_msg=True)