Merge "Stop using NoAuthMiddleware in tests"
This commit is contained in:
commit
efdc734832
|
@ -81,6 +81,14 @@ class InjectContext(wsgi.Middleware):
|
|||
class NovaKeystoneContext(wsgi.Middleware):
|
||||
"""Make a request context from keystone headers."""
|
||||
|
||||
@staticmethod
|
||||
def _create_context(env, **kwargs):
|
||||
"""Create a context from a request environ.
|
||||
|
||||
This exists to make test stubbing easier.
|
||||
"""
|
||||
return context.RequestContext.from_environ(env, **kwargs)
|
||||
|
||||
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
||||
def __call__(self, req):
|
||||
# Build a context, including the auth_token...
|
||||
|
@ -101,7 +109,7 @@ class NovaKeystoneContext(wsgi.Middleware):
|
|||
# middleware in newer versions.
|
||||
user_auth_plugin = req.environ.get('keystone.token_auth')
|
||||
|
||||
ctx = context.RequestContext.from_environ(
|
||||
ctx = self._create_context(
|
||||
req.environ,
|
||||
user_auth_plugin=user_auth_plugin,
|
||||
remote_address=remote_address,
|
||||
|
|
|
@ -955,18 +955,21 @@ class OSAPIFixture(fixtures.Fixture):
|
|||
"""
|
||||
|
||||
def __init__(self, api_version='v2',
|
||||
project_id='6f70656e737461636b20342065766572'):
|
||||
project_id='6f70656e737461636b20342065766572',
|
||||
use_project_id_in_urls=False):
|
||||
"""Constructor
|
||||
|
||||
:param api_version: the API version that we're interested in
|
||||
using. Currently this expects 'v2' or 'v2.1' as possible
|
||||
options.
|
||||
:param project_id: the project id to use on the API.
|
||||
|
||||
:param use_project_id_in_urls: If True, act like the "endpoint" in the
|
||||
"service catalog" has the legacy format including the project_id.
|
||||
"""
|
||||
super(OSAPIFixture, self).__init__()
|
||||
self.api_version = api_version
|
||||
self.project_id = project_id
|
||||
self.use_project_id_in_urls = use_project_id_in_urls
|
||||
|
||||
def setUp(self):
|
||||
super(OSAPIFixture, self).setUp()
|
||||
|
@ -982,6 +985,23 @@ class OSAPIFixture(fixtures.Fixture):
|
|||
}
|
||||
self.useFixture(ConfPatcher(**conf_overrides))
|
||||
|
||||
# Stub out authentication middleware
|
||||
# TODO(efried): Use keystonemiddleware.fixtures.AuthTokenFixture
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'keystonemiddleware.auth_token.filter_factory',
|
||||
return_value=lambda _app: _app))
|
||||
|
||||
# Stub out context middleware
|
||||
def fake_ctx(env, **kwargs):
|
||||
user_id = env['HTTP_X_AUTH_USER']
|
||||
project_id = env['HTTP_X_AUTH_PROJECT_ID']
|
||||
is_admin = user_id == 'admin'
|
||||
return context.RequestContext(
|
||||
user_id, project_id, is_admin=is_admin, **kwargs)
|
||||
|
||||
self.useFixture(fixtures.MonkeyPatch(
|
||||
'nova.api.auth.NovaKeystoneContext._create_context', fake_ctx))
|
||||
|
||||
# Turn off manipulation of socket_options in TCPKeepAliveAdapter
|
||||
# to keep wsgi-intercept happy. Replace it with the method
|
||||
# from its superclass.
|
||||
|
@ -999,12 +1019,15 @@ class OSAPIFixture(fixtures.Fixture):
|
|||
intercept.install_intercept()
|
||||
self.addCleanup(intercept.uninstall_intercept)
|
||||
|
||||
self.auth_url = 'http://%(host)s:%(port)s/%(api_version)s' % ({
|
||||
base_url = 'http://%(host)s:%(port)s/%(api_version)s' % ({
|
||||
'host': hostname, 'port': port, 'api_version': self.api_version})
|
||||
self.api = client.TestOpenStackClient('fake', 'fake', self.auth_url,
|
||||
self.project_id)
|
||||
if self.use_project_id_in_urls:
|
||||
base_url += '/' + self.project_id
|
||||
|
||||
self.api = client.TestOpenStackClient(
|
||||
'fake', base_url, project_id=self.project_id)
|
||||
self.admin_api = client.TestOpenStackClient(
|
||||
'admin', 'admin', self.auth_url, self.project_id)
|
||||
'admin', base_url, project_id=self.project_id)
|
||||
# Provide a way to access the wsgi application to tests using
|
||||
# the fixture.
|
||||
self.app = app
|
||||
|
|
|
@ -124,13 +124,10 @@ class TestOpenStackClient(object):
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, auth_user, auth_key, auth_url,
|
||||
project_id=None):
|
||||
def __init__(self, auth_user, base_url, project_id=None):
|
||||
super(TestOpenStackClient, self).__init__()
|
||||
self.auth_result = None
|
||||
self.auth_user = auth_user
|
||||
self.auth_key = auth_key
|
||||
self.auth_url = auth_url
|
||||
self.base_url = base_url
|
||||
if project_id is None:
|
||||
self.project_id = "6f70656e737461636b20342065766572"
|
||||
else:
|
||||
|
@ -144,49 +141,22 @@ class TestOpenStackClient(object):
|
|||
response = requests.request(method, url, data=body, headers=_headers)
|
||||
return response
|
||||
|
||||
def _authenticate(self, retry_count=0):
|
||||
if self.auth_result:
|
||||
return self.auth_result
|
||||
|
||||
auth_url = self.auth_url
|
||||
headers = {'X-Auth-User': self.auth_user,
|
||||
'X-Auth-Key': self.auth_key,
|
||||
'X-Auth-Project-Id': self.project_id}
|
||||
response = self.request(auth_url,
|
||||
headers=headers)
|
||||
|
||||
http_status = response.status_code
|
||||
LOG.debug("%(auth_url)s => code %(http_status)s",
|
||||
{'auth_url': auth_url,
|
||||
'http_status': http_status})
|
||||
|
||||
# NOTE(cdent): This is a workaround for an issue where the placement
|
||||
# API fixture may respond when a request was supposed to go to the
|
||||
# compute API fixture. Retry a few times, hoping to hit the right
|
||||
# fixture.
|
||||
if http_status == 401:
|
||||
if retry_count <= 3:
|
||||
return self._authenticate(retry_count=retry_count + 1)
|
||||
else:
|
||||
raise OpenStackApiAuthenticationException(response=response)
|
||||
|
||||
self.auth_result = response.headers
|
||||
return self.auth_result
|
||||
|
||||
def api_request(self, relative_uri, check_response_status=None,
|
||||
strip_version=False, **kwargs):
|
||||
auth_result = self._authenticate()
|
||||
|
||||
# NOTE(justinsb): httplib 'helpfully' converts headers to lower case
|
||||
base_uri = auth_result['x-server-management-url']
|
||||
base_uri = self.base_url
|
||||
if strip_version:
|
||||
# NOTE(vish): cut out version number and tenant_id
|
||||
base_uri = '/'.join(base_uri.split('/', 3)[:-1])
|
||||
# The base_uri is either http://%(host)s:%(port)s/%(api_version)s
|
||||
# or http://%(host)s:%(port)s/%(api_version)s/%(project_id)s
|
||||
# NOTE(efried): Using urlparse was not easier :)
|
||||
chunked = base_uri.split('/')
|
||||
base_uri = '/'.join(chunked[:3])
|
||||
# Restore the project ID if present
|
||||
if len(chunked) == 5:
|
||||
base_uri += '/' + chunked[-1]
|
||||
|
||||
full_uri = '%s/%s' % (base_uri, relative_uri)
|
||||
|
||||
headers = kwargs.setdefault('headers', {})
|
||||
headers['X-Auth-Token'] = auth_result['x-auth-token']
|
||||
if ('X-OpenStack-Nova-API-Version' in headers or
|
||||
'OpenStack-API-Version' in headers):
|
||||
raise Exception('Microversion should be set via '
|
||||
|
@ -195,6 +165,10 @@ class TestOpenStackClient(object):
|
|||
headers['X-OpenStack-Nova-API-Version'] = self.microversion
|
||||
headers['OpenStack-API-Version'] = 'compute %s' % self.microversion
|
||||
|
||||
headers.setdefault('X-Auth-User', self.auth_user)
|
||||
headers.setdefault('X-User-Id', self.auth_user)
|
||||
headers.setdefault('X-Auth-Project-Id', self.project_id)
|
||||
|
||||
response = self.request(full_uri, **kwargs)
|
||||
|
||||
http_status = response.status_code
|
||||
|
|
|
@ -62,6 +62,11 @@ class ApiSampleTestBaseV21(testscenarios.WithScenarios,
|
|||
# any additional fixtures needed for this scenario
|
||||
_additional_fixtures = []
|
||||
sample_dir = None
|
||||
# Include the project ID in request URLs by default. This is overridden
|
||||
# for certain `scenarios` and by certain subclasses.
|
||||
# Note that API sample tests also use this in substitutions to validate
|
||||
# that URLs in responses (e.g. location of a server just created) are
|
||||
# correctly constructed.
|
||||
_use_project_id = True
|
||||
# Availability zones for the API samples tests. Can be overridden by
|
||||
# sub-classes. If set, the AvailabilityZoneFilter is not used.
|
||||
|
|
|
@ -74,6 +74,7 @@ class SimpleTenantUsageV240Test(test_servers.ServersSampleBase):
|
|||
sample_dir = 'os-simple-tenant-usage'
|
||||
microversion = '2.40'
|
||||
scenarios = [('v2_40', {'api_major_version': 'v2.1'})]
|
||||
_use_project_id = False
|
||||
|
||||
def setUp(self):
|
||||
super(SimpleTenantUsageV240Test, self).setUp()
|
||||
|
|
|
@ -19,6 +19,7 @@ from nova.tests.functional.api_sample_tests import api_sample_base
|
|||
|
||||
class VersionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21):
|
||||
sample_dir = 'versions'
|
||||
_use_project_id = False
|
||||
# NOTE(gmann): Setting empty scenario for 'version' API testing
|
||||
# as those does not send request on particular endpoint and running
|
||||
# its tests alone is enough.
|
||||
|
|
|
@ -80,6 +80,9 @@ class _IntegratedTestBase(test.TestCase):
|
|||
# New tests should rely on Neutron and old ones migrated to use this since
|
||||
# nova-network is deprecated.
|
||||
USE_NEUTRON = True
|
||||
# This indicates whether to include the project ID in the URL for API
|
||||
# requests through OSAPIFixture. Overridden by subclasses.
|
||||
_use_project_id = False
|
||||
|
||||
def setUp(self):
|
||||
super(_IntegratedTestBase, self).setUp()
|
||||
|
@ -125,8 +128,11 @@ class _IntegratedTestBase(test.TestCase):
|
|||
self.scheduler = self._setup_scheduler_service()
|
||||
|
||||
self.compute = self._setup_compute_service()
|
||||
|
||||
self.api_fixture = self.useFixture(
|
||||
nova_fixtures.OSAPIFixture(self.api_major_version))
|
||||
nova_fixtures.OSAPIFixture(
|
||||
api_version=self.api_major_version,
|
||||
use_project_id_in_urls=self._use_project_id))
|
||||
|
||||
# if the class needs to run as admin, make the api endpoint
|
||||
# the admin, otherwise it's safer to run as non admin user.
|
||||
|
|
|
@ -41,6 +41,10 @@ class TestCORSMiddleware(api_sample_base.ApiSampleTestBaseV21):
|
|||
self._original_call_method = cfg.ConfigOpts.GroupAttr.__getattr__
|
||||
cfg.ConfigOpts.GroupAttr.__getattr__ = _mock_getattr
|
||||
|
||||
# With the project_id in the URL, we get the 300 'multiple choices'
|
||||
# response from nova.api.openstack.compute.versions.Versions.
|
||||
self.exp_version_status = 300 if self._use_project_id else 200
|
||||
|
||||
# Initialize the application after all the config overrides are in
|
||||
# place.
|
||||
super(TestCORSMiddleware, self).setUp()
|
||||
|
@ -103,7 +107,7 @@ class TestCORSMiddleware(api_sample_base.ApiSampleTestBaseV21):
|
|||
'Access-Control-Request-Method': 'GET'
|
||||
})
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.status_code, self.exp_version_status)
|
||||
self.assertIn('Access-Control-Allow-Origin', response.headers)
|
||||
self.assertEqual('http://valid.example.com',
|
||||
response.headers['Access-Control-Allow-Origin'])
|
||||
|
@ -116,5 +120,5 @@ class TestCORSMiddleware(api_sample_base.ApiSampleTestBaseV21):
|
|||
'Access-Control-Request-Method': 'GET'
|
||||
})
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.status_code, self.exp_version_status)
|
||||
self.assertNotIn('Access-Control-Allow-Origin', response.headers)
|
||||
|
|
|
@ -63,18 +63,15 @@ class TestRequestLogMiddleware(testtools.TestCase):
|
|||
api = self.useFixture(fixtures.OSAPIFixture()).api
|
||||
|
||||
resp = api.api_request('/', strip_version=True)
|
||||
log1 = ('INFO [nova.api.openstack.requestlog] 127.0.0.1 '
|
||||
'"GET /v2" status: 204 len: 0 microversion: - time:')
|
||||
self.assertIn(log1, self.stdlog.logger.output)
|
||||
|
||||
# the content length might vary, but the important part is
|
||||
# what we log is what we return to the user (which turns out
|
||||
# to excitingly not be the case with eventlet!)
|
||||
content_length = resp.headers['content-length']
|
||||
|
||||
log2 = ('INFO [nova.api.openstack.requestlog] 127.0.0.1 '
|
||||
log1 = ('INFO [nova.api.openstack.requestlog] 127.0.0.1 '
|
||||
'"GET /" status: 200 len: %s' % content_length)
|
||||
self.assertIn(log2, self.stdlog.logger.output)
|
||||
self.assertIn(log1, self.stdlog.logger.output)
|
||||
|
||||
@mock.patch('nova.api.openstack.requestlog.RequestLog._should_emit')
|
||||
def test_logs_mv(self, emit):
|
||||
|
|
|
@ -45,9 +45,6 @@ class ConfFixture(config_fixture.Config):
|
|||
self.conf.set_default('use_ipv6', True)
|
||||
self.conf.set_default('vlan_interface', 'eth0')
|
||||
|
||||
# api group
|
||||
self.conf.set_default('auth_strategy', 'noauth2', group='api')
|
||||
|
||||
# api_database group
|
||||
self.conf.set_default('connection', "sqlite://", group='api_database')
|
||||
self.conf.set_default('sqlite_synchronous', False,
|
||||
|
|
Loading…
Reference in New Issue