def test_authenticate_tenant_propagates_auth_errors(self): """ authenticate_tenant propagates errors from authenticate_user. """ self.impersonate_user.side_effect = lambda *a, **k: fail( UpstreamError(Failure(APIError(401, '4')), 'identity', 'o')) self.authenticate_user.side_effect = lambda *a, **kw: fail( UpstreamError(Failure(APIError(500, '500')), 'identity', 'o')) f = self.failureResultOf(self.ia.authenticate_tenant(111111), UpstreamError) self.assertEqual(f.value.reason.value.code, 500)
def wrap_failure(failure): new_f = _unwrap_first(failure) if new_f.check(APIError): raise UpstreamError(new_f, system, message, new_f.value.url) if new_f.check(ConnectionRefusedError, UpstreamError): # allowing UpstreamError too, since the traceback will be too short # and this gives us a sort of diagnosis stack raise UpstreamError(new_f, system, message) return failure
def test_authenticate_tenant_retries_getting_endpoints_for_the_impersonation_token( self): """ authenticate_tenant fetches all the endpoints for the impersonation and retries with new authentication token if it gets 401 """ self.endpoints_for_token.side_effect = [ fail(UpstreamError(Failure(APIError(401, '')), 'identity', 'o')), succeed({'endpoints': [{ 'name': 'anEndpoint', 'type': 'anType' }]}) ] self.successResultOf(self.ia.authenticate_tenant(111111, log=self.log)) self.endpoints_for_token.assert_has_calls([ mock.call(self.admin_url, None, 'impersonation_token', log=self.log), mock.call(self.admin_url, 'auth-token', 'impersonation_token', log=self.log) ]) self.authenticate_user.assert_called_once_with(self.url, self.user, self.password, log=self.log) self.log.msg.assert_called_once_with( 'Getting new identity admin token')
def test_non_apierror(self): """ Any error other than APIError in UpstreamError is propogated """ d = retry_on_unauth( lambda: fail(UpstreamError(Failure(ValueError('a')), 'identity', 'o')), self.auth) f = self.failureResultOf(d, UpstreamError) f.value.reason.trap(ValueError)
def test_non_apierror(self): """ Wraps any other error and has message and details accordingly """ err = UpstreamError(Failure(ValueError('heh')), 'identity', 'stuff', 'xkcd.com') self.assertEqual(str(err), 'identity error: heh (stuff)') self.assertEqual(err.details, { 'system': 'identity', 'operation': 'stuff', 'url': 'xkcd.com'})
def test_500_error(self): """ Any error other than 401 is propogated """ d = retry_on_unauth( lambda: fail(UpstreamError(Failure(APIError(500, 'a')), 'identity', 'o')), self.auth) f = self.failureResultOf(d, UpstreamError) f.value.reason.trap(APIError) self.assertEqual(f.value.reason.value.code, 500)
def test_authenticate_tenant_propagates_endpoint_list_errors(self): """ authenticate_tenant propagates errors from endpoints_for_token """ self.endpoints_for_token.side_effect = lambda *a, **kw: fail( UpstreamError(Failure(APIError(500, '500')), 'identity', 'o')) f = self.failureResultOf(self.ia.authenticate_tenant(111111), UpstreamError) self.assertEqual(f.value.reason.value.code, 500)
def test_authenticate_tenant_propagates_user_list_errors(self): """ authenticate_tenant propagates errors from user_for_tenant """ self.authenticate_user.side_effect = lambda *a, **kw: fail( UpstreamError(Failure(APIError(500, '500')), 'identity', 'o')) f = self.failureResultOf(self.st.authenticate_tenant('111111'), UpstreamError) self.assertEqual(f.value.reason.value.code, 500)
def test_auth_error_propogates(self): """ `auth()` errors are propogated """ auth = mock.Mock(spec=[], return_value=fail(ValueError('a'))) func = mock.Mock(side_effect=[ fail(UpstreamError(Failure(APIError(401, '401')), 'identity', 'o')), succeed('r')]) d = retry_on_unauth(func, auth) self.failureResultOf(d, ValueError) auth.assert_called_once_with()
def test_auth_error(self): """ Calls auth() followed by func() again if initial func() returns 401 """ auth = mock.Mock(spec=[], return_value=succeed('a')) func = mock.Mock(side_effect=[ fail(UpstreamError(Failure(APIError(401, '401')), 'identity', 'o')), succeed('r')]) d = retry_on_unauth(func, auth) self.assertEqual(self.successResultOf(d), 'r') auth.assert_called_once_with()
def test_apierror_identity(self): """ Wraps APIError from identity and parses error body accordingly """ body = json.dumps({"identityFault": {"message": "ba"}}) apie = APIError(410, body, {}) err = UpstreamError(Failure(apie), 'identity', 'stuff', 'xkcd.com') self.assertEqual(str(err), 'identity error: 410 - ba (stuff)') self.assertEqual(err.details, { 'system': 'identity', 'operation': 'stuff', 'url': 'xkcd.com', 'message': 'ba', 'code': 410, 'body': body, 'headers': {}})
def test_apierror_clb(self): """ Wraps APIError from clb and parses error body accordingly """ body = json.dumps({"message": "b"}) apie = APIError(403, body, {'h1': 2}) err = UpstreamError(Failure(apie), 'clb', 'remove', 'xkcd.com') self.assertEqual(str(err), 'clb error: 403 - b (remove)') self.assertEqual(err.details, { 'system': 'clb', 'operation': 'remove', 'url': 'xkcd.com', 'message': 'b', 'code': 403, 'body': body, 'headers': {'h1': 2}})
def test_apierror_nova(self): """ Wraps APIError from nova and parses error body accordingly """ body = json.dumps({"computeFault": {"message": "b"}}) apie = APIError(404, body, {}) err = UpstreamError(Failure(apie), 'nova', 'add', 'xkcd.com') self.assertEqual(str(err), 'nova error: 404 - b (add)') self.assertEqual(err.details, { 'system': 'nova', 'operation': 'add', 'url': 'xkcd.com', 'message': 'b', 'code': 404, 'body': body, 'headers': {}})
def test_apierror_unparsed(self): """ Wraps APIError from identity and uses default string if unable to parse error body """ body = json.dumps({"identityFault": {"m": "ba"}}) apie = APIError(410, body, {}) err = UpstreamError(Failure(apie), 'identity', 'stuff', 'xkcd.com') self.assertEqual( str(err), 'identity error: 410 - Could not parse API error body (stuff)') self.assertEqual(err.details, { 'system': 'identity', 'operation': 'stuff', 'url': 'xkcd.com', 'message': 'Could not parse API error body', 'code': 410, 'body': body, 'headers': {}})
def test_authenticate_tenant_retries_impersonates_first_user(self): """ authenticate_tenant impersonates again with new auth if initial impersonation fails with 401 """ self.impersonate_user.side_effect = [ fail(UpstreamError(Failure(APIError(401, '')), 'identity', 'o')), succeed({'access': { 'token': { 'id': 'impersonation_token' } }}) ] self.successResultOf(self.ia.authenticate_tenant(111111, self.log)) self.impersonate_user.assert_has_calls([ mock.call(self.admin_url, None, 'test_user', log=self.log), mock.call(self.admin_url, 'auth-token', 'test_user', log=self.log) ]) self.authenticate_user.assert_called_once_with(self.url, self.user, self.password, log=self.log) self.log.msg.assert_called_once_with( 'Getting new identity admin token')