vmware-nsx/vmware_nsx/tests/unit/nsxlib/v3/nsxlib_testcase.py
Boden R eac5453721 refactor NSX v3 UTs
this patch contains a major refactor of the nsx v3 tests
which have nsx rest api calls in their execution stack.
in particular it removes the global module level patching
that's current done as this type of global patching has
intermittent failures when testr runs tests in parallel.
these failures become more prevalent when the psec
code + tests are added. thus this patch is needed for
the psec drop I have.

NB: as noted in the code, most of the module level
patching / mocking magic can go away once we move
the current functional logic to a rest resource model.

Change-Id: Idec72c464a4a2771f089b840aae129d42816a35f
2015-10-01 10:46:51 -06:00

156 lines
5.8 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 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('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
fn_map = {}
for fn in BRIDGE_FNS:
fn_map[fn] = _call_client(fn)
fn_map['NSX3Client'] = nsx_client.NSX3Client
return cls.patch_client_module(in_module, fn_map)