- System test framework can now assert specific response codes automatically
- Revised system test for issue #85 based on clarification from Ziad - Added system test to attempt admin action using a service token
This commit is contained in:
@@ -5,7 +5,7 @@ class HttpTestCase(unittest.TestCase):
|
||||
"""Performs generic HTTP request testing"""
|
||||
|
||||
def request(self, host='127.0.0.1', port=80, method='GET', path='/',
|
||||
headers={}, body=None, expect_exception=False,):
|
||||
headers={}, body=None, assert_status=None):
|
||||
"""Perform request and fetch httplib.HTTPResponse from the server"""
|
||||
|
||||
# Initialize a connection
|
||||
@@ -22,26 +22,26 @@ class HttpTestCase(unittest.TestCase):
|
||||
connection.close()
|
||||
|
||||
# Automatically assert HTTP status code
|
||||
if not expect_exception:
|
||||
self.assertSuccessfulResponse(response)
|
||||
if assert_status:
|
||||
self.assertResponseStatus(response, assert_status)
|
||||
else:
|
||||
self.assertExceptionalResponse(response)
|
||||
self.assertResponseSuccessful(response)
|
||||
|
||||
# Contains the response headers, body, etc
|
||||
return response
|
||||
|
||||
def assertSuccessfulResponse(self, response):
|
||||
|
||||
def assertResponseSuccessful(self, response):
|
||||
"""Asserts that a status code lies inside the 2xx range"""
|
||||
self.assertTrue(response.status >= 200 and response.status <= 299,
|
||||
'Status code %d is outside of the expected range (2xx) \n\n%s' %
|
||||
(response.status, response.body))
|
||||
|
||||
def assertExceptionalResponse(self, response):
|
||||
"""Asserts that a status code lies outside the 2xx range"""
|
||||
self.assertFalse(response.status >= 200 and response.status <= 299,
|
||||
'Status code %d is outside of the expected range (not 2xx)\n\n%s' %
|
||||
'Status code %d is outside of the expected range (2xx)\n\n%s' %
|
||||
(response.status, response.body))
|
||||
|
||||
def assertResponseStatus(self, response, assert_status):
|
||||
"""Asserts a specific status code on the response"""
|
||||
self.assertEqual(response.status, assert_status,
|
||||
'Status code %s is not %s, as expected)\n\n%s' %
|
||||
(response.status, assert_status, response.body))
|
||||
|
||||
class RestfulTestCase(HttpTestCase):
|
||||
"""Performs restful HTTP request testing"""
|
||||
|
||||
|
||||
@@ -18,6 +18,58 @@ class TestAdminAuthentication(KeystoneTestCase):
|
||||
self.assertTrue(r.json['auth']['token']['id'])
|
||||
self.assertTrue(r.json['auth']['token']['expires'])
|
||||
|
||||
class TestAdminAuthenticationNegative(KeystoneTestCase):
|
||||
"""Negative test admin-side user authentication"""
|
||||
|
||||
user_id = KeystoneTestCase._uuid()
|
||||
user_id2 = KeystoneTestCase._uuid()
|
||||
|
||||
def test_service_token_as_admin_token(self):
|
||||
"""Admin actions should fail for mere service tokens"""
|
||||
|
||||
# Admin create a user
|
||||
self.admin_request(method='PUT', path='/users',
|
||||
json={
|
||||
'user': {
|
||||
'id': self.user_id,
|
||||
'password': 'secrete',
|
||||
'email': self.user_id + '@openstack.org',
|
||||
'enabled': True,
|
||||
}
|
||||
})
|
||||
|
||||
# User authenticates to get a token
|
||||
r = self.service_request(method='POST', path='/tokens',
|
||||
json={
|
||||
'passwordCredentials': {
|
||||
'username': self.user_id,
|
||||
'password': 'secrete',
|
||||
}
|
||||
})
|
||||
self.service_token = r.json['auth']['token']['id']
|
||||
|
||||
# Prepare to use the service token as an admin token
|
||||
self.admin_token_backup = self.admin_token
|
||||
self.admin_token = self.service_token
|
||||
|
||||
# Try creating another user
|
||||
self.admin_request(method='PUT', path='/users', assert_status=401,
|
||||
json={
|
||||
'user': {
|
||||
'id': self.user_id2,
|
||||
'password': 'secrete',
|
||||
'email': self.user_id2 + '@openstack.org',
|
||||
'enabled': True,
|
||||
}
|
||||
})
|
||||
|
||||
def tearDown(self):
|
||||
# Restore our admin token so we can clean up
|
||||
self.admin_token = self.admin_token_backup
|
||||
|
||||
# Delete user
|
||||
self.admin_request(method='DELETE', path='/users/%s' % self.user_id)
|
||||
|
||||
class TestServiceAuthentication(KeystoneTestCase):
|
||||
"""Test service-side user authentication"""
|
||||
|
||||
@@ -32,7 +84,7 @@ class TestServiceAuthentication(KeystoneTestCase):
|
||||
'user': {
|
||||
'id': self.user_id,
|
||||
'password': 'secrete',
|
||||
'email': 'user@openstack.org',
|
||||
'email': self.user_id + '@openstack.org',
|
||||
'enabled': True,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -20,7 +20,7 @@ class TestIssue85(KeystoneTestCase):
|
||||
}
|
||||
})
|
||||
|
||||
# Create a user
|
||||
# Create a user for a specific tenant
|
||||
self.admin_request(method='PUT', path='/users',
|
||||
json={
|
||||
'user':{
|
||||
@@ -28,7 +28,7 @@ class TestIssue85(KeystoneTestCase):
|
||||
'password': 'secrete',
|
||||
'email': 'user@openstack.org',
|
||||
'enabled': True,
|
||||
'tenant_id': 'tenant',
|
||||
'tenantId': self.tenant_id
|
||||
}
|
||||
})
|
||||
|
||||
@@ -43,18 +43,20 @@ class TestIssue85(KeystoneTestCase):
|
||||
|
||||
def test_disabling_tenant_disables_token(self):
|
||||
"""Disabling a tenant should invalidate previously-issued tokens"""
|
||||
# Authenticate as user to get a token
|
||||
# Authenticate as user to get a token *for a specific tenant*
|
||||
r = self.service_request(method='POST', path='/tokens',
|
||||
json={
|
||||
'passwordCredentials': {
|
||||
'username': self.user_id,
|
||||
'password': 'secrete',
|
||||
'tenantId': self.tenant_id
|
||||
}
|
||||
})
|
||||
self.service_token = r.json['auth']['token']['id']
|
||||
|
||||
# Validate tenant token
|
||||
self.admin_request(path='/tokens/%s' % self.service_token)
|
||||
# Validate and check that token belongs to tenant
|
||||
self.admin_request(path='/tokens/%s?belongsTo=%s' %
|
||||
(self.service_token, self.tenant_id))
|
||||
|
||||
# Disable tenant
|
||||
r = self.admin_request(method='PUT',
|
||||
@@ -67,10 +69,11 @@ class TestIssue85(KeystoneTestCase):
|
||||
})
|
||||
self.assertEqual(r.json['tenant']['enabled'], False)
|
||||
|
||||
# Assert tenant token invalidated
|
||||
# Commented this out because it will fail this test
|
||||
# self.admin_request(path='/tokens/%s' % self.service_token,
|
||||
# expect_exception=True)
|
||||
# Assert that token belonging to disabled tenant is invalid
|
||||
r = self.admin_request(path='/tokens/%s?belongsTo=%s' %
|
||||
(self.service_token, self.tenant_id),
|
||||
assert_status=403)
|
||||
self.assertTrue(r.json['tenantDisabled'], 'Tenant is disabled')
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
@@ -56,7 +56,7 @@ class TestContentTypes(KeystoneTestCase):
|
||||
"""Content-Type should be honored even on 404 errors (Issue #13)"""
|
||||
_r = self.service_request(path='/completely-invalid-path',
|
||||
headers={'Accept': 'application/xml'},
|
||||
expect_exception=True)
|
||||
assert_status=404)
|
||||
|
||||
# Commenting this assertion out, as it currently fails
|
||||
# self.assertTrue('application/xml' in r.getheader('Content-Type'),
|
||||
|
||||
Reference in New Issue
Block a user