vmware-nsx/vmware_nsx/tests/unit/nsxlib/v3/nsxlib_testcase.py
Shih-Hao Li ce75aa97d9 NSXv3: Fix typo in URI while setting GW for router
Fixes NSX v3 router integration to not pass along sub-URI
in API calls to the backend.

This patch also includes updates to the NSX v3 mock API
session handling to ensure mocked clients handle their
appropriate sub URIs.

Closes-Bug: #1510279
Change-Id: Ib90071a68572d5b18db896ea38b91e5beaeca88a
2015-11-02 21:14:52 +00:00

191 lines
7.1 KiB
Python

# Copyright (c) 2015 VMware, 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.
#
import contextlib
import mock
import types
import unittest
from oslo_config import cfg
from oslo_utils import uuidutils
from vmware_nsx.nsxlib.v3 import client as nsx_client
from vmware_nsx.tests.unit.nsx_v3 import mocks
NSX_USER = 'admin'
NSX_PASSWORD = 'default'
NSX_MANAGER = '1.2.3.4'
NSX_INSECURE = True
NSX_CERT = '/opt/stack/certs/nsx.pem'
V3_CLIENT_PKG = 'vmware_nsx.nsxlib.v3.client'
BRIDGE_FNS = ['create_resource', 'delete_resource',
'update_resource', 'get_resource']
class NsxLibTestCase(unittest.TestCase):
def setUp(self, *args, **kwargs):
super(NsxLibTestCase, self).setUp()
cfg.CONF.set_override('nsx_user', NSX_USER)
cfg.CONF.set_override('nsx_password', NSX_PASSWORD)
cfg.CONF.set_override('default_tz_uuid',
uuidutils.generate_uuid())
cfg.CONF.set_override('nsx_controllers', ['11.9.8.7', '11.9.8.77'])
cfg.CONF.set_override('nsx_user', NSX_USER, 'nsx_v3')
cfg.CONF.set_override('nsx_password', NSX_PASSWORD, 'nsx_v3')
cfg.CONF.set_override('nsx_manager', NSX_MANAGER, 'nsx_v3')
cfg.CONF.set_override('insecure', NSX_INSECURE, 'nsx_v3')
cfg.CONF.set_override('ca_file', NSX_CERT, 'nsx_v3')
# print diffs when assert comparisons fail
self.maxDiff = None
# NOTE(boden): a lot of the hackery and magic below can be removed
# once we move all v3 rest function calls to OO based on rest resource
class NsxClientTestCase(NsxLibTestCase):
class MockBridge(object):
def __init__(self, api_client):
self._client = api_client
def get_resource(self, resource):
return nsx_client.get_resource(
resource, client=self._client)
def create_resource(self, resource, data):
return nsx_client.create_resource(
resource, data, client=self._client)
def delete_resource(self, resource):
return nsx_client.delete_resource(
resource, client=self._client)
def update_resource(self, resource, data):
return nsx_client.create_resource(
resource, data, client=self._client)
def new_client(
self, clazz, host_ip=NSX_MANAGER,
user_name=NSX_USER,
password=NSX_PASSWORD,
insecure=NSX_INSECURE,
url_prefix=None,
default_headers=None,
cert_file=NSX_CERT):
return clazz(host_ip=host_ip, user_name=user_name,
password=password, insecure=insecure,
url_prefix=url_prefix, default_headers=default_headers,
cert_file=cert_file)
@contextlib.contextmanager
def mocked_client(self, client, mock_validate=True):
session = client._session
with mock.patch.object(session, 'get') as _get:
with mock.patch.object(session, 'post') as _post:
with mock.patch.object(session, 'delete') as _delete:
with mock.patch.object(session, 'put') as _put:
rep = {
'get': _get,
'put': _put,
'delete': _delete,
'post': _post
}
if mock_validate:
with mock.patch.object(client, '_validate_result'):
yield rep
else:
yield rep
@contextlib.contextmanager
def mocked_resource(self, resource, mock_validate=True):
with self.mocked_client(resource._client,
mock_validate=mock_validate) as _client:
yield _client
@contextlib.contextmanager
def mocked_client_bridge(self, client, module, attr, mock_validate=True):
mocked_bridge = NsxClientTestCase.MockBridge(client)
mocked_bridge.JSONRESTClient = nsx_client.JSONRESTClient
with self.mocked_client(client, mock_validate=mock_validate) as mocked:
with mock.patch.object(module, attr, new=mocked_bridge):
yield mocked
@classmethod
def patch_client_module(cls, in_module, fn_map):
mock_client = mock.Mock()
for name, clazz in in_module.__dict__.items():
if (isinstance(clazz, types.ModuleType) and
clazz.__name__ == V3_CLIENT_PKG):
for fn_name in BRIDGE_FNS:
mock_call = fn_map.get(fn_name, getattr(mocks, fn_name))
setattr(mock_client, fn_name, mock_call)
for fn_name, fn_call in fn_map.items():
if fn_name not in BRIDGE_FNS:
setattr(mock_client, fn_name, fn_call)
return mock.patch.object(in_module, name, new=mock_client)
return None
@classmethod
def mocked_session_module(cls, in_module, with_client,
mock_session=None):
mock_session = mock_session or mocks.MockRequestSessionApi()
with_client._session = mock_session
def _call_client(fn_name):
def _client(*args, **kwargs):
client_fn = getattr(nsx_client, fn_name)
kwargs['client'] = with_client
return client_fn(*args, **kwargs)
return _client
def _proxy_new_client_for(client):
new_client_fn = client.new_client_for
def _new_client_for(*uri_segs):
new_client = new_client_fn(*uri_segs)
new_client._session = mock_session
new_client.new_client_for = _proxy_new_client_for(new_client)
return new_client
return _new_client_for
def _proxy_init(class_name):
client_init = getattr(nsx_client, class_name)
def _init_client(*args, **kwargs):
if (not args and not kwargs and
with_client.__class__.__name__ == class_name):
return with_client
client = client_init(*args, **kwargs)
client._session = mock_session
return client
return _init_client
fn_map = {}
for fn in BRIDGE_FNS:
fn_map[fn] = _call_client(fn)
fn_map['NSX3Client'] = _proxy_init('NSX3Client')
fn_map['JSONRESTClient'] = _proxy_init('JSONRESTClient')
fn_map['RESTClient'] = _proxy_init('RESTClient')
with_client.new_client_for = _proxy_new_client_for(with_client)
return cls.patch_client_module(in_module, fn_map)