Add unit tests
Added unit tests and tidy up calls to initialise Keystone client. Closes-Bug: 1628491 Change-Id: I14ea09539e5781ded75bcfa47108f10e27c816df
This commit is contained in:
parent
c2ccf415c5
commit
f9100ec85d
|
@ -65,15 +65,24 @@ class TempestAdminAdapter(adapters.OpenStackRelationAdapter):
|
|||
"""Collection keystone information from keystone relation"""
|
||||
return self.relation.credentials()
|
||||
|
||||
def init_keystone_client(self):
|
||||
"""Initialise keystone client"""
|
||||
if self.kc:
|
||||
return
|
||||
self.keystone_auth_url = '{}://{}:{}/v2.0'.format(
|
||||
@property
|
||||
def ks_client(self):
|
||||
if not self.kc:
|
||||
self.init_keystone_client()
|
||||
return self.kc
|
||||
|
||||
@property
|
||||
def keystone_auth_url(self):
|
||||
return '{}://{}:{}/v2.0'.format(
|
||||
'http',
|
||||
self.keystone_info['service_hostname'],
|
||||
self.keystone_info['service_port']
|
||||
)
|
||||
|
||||
def init_keystone_client(self):
|
||||
"""Initialise keystone client"""
|
||||
if self.kc:
|
||||
return
|
||||
auth = {
|
||||
'username': self.keystone_info['service_username'],
|
||||
'password': self.keystone_info['service_password'],
|
||||
|
@ -92,14 +101,15 @@ class TempestAdminAdapter(adapters.OpenStackRelationAdapter):
|
|||
|
||||
@returns {'access_token' token1, 'secret_token': token2}
|
||||
"""
|
||||
self.init_keystone_client()
|
||||
if not self.kc:
|
||||
if not self.ks_client:
|
||||
return {}
|
||||
current_creds = self.kc.ec2.list(self.kc.user_id)
|
||||
current_creds = self.ks_client.ec2.list(self.ks_client.user_id)
|
||||
if current_creds:
|
||||
creds = current_creds[0]
|
||||
else:
|
||||
creds = self.kc.ec2.create(self.kc.user_id, self.kc.tenant_id)
|
||||
creds = self.ks_client.ec2.create(
|
||||
self.ks_client.user_id,
|
||||
self.ks_client.tenant_id)
|
||||
return {'access_token': creds.access, 'secret_token': creds.secret}
|
||||
|
||||
@property
|
||||
|
@ -108,14 +118,13 @@ class TempestAdminAdapter(adapters.OpenStackRelationAdapter):
|
|||
|
||||
@returns {'image_id' id1, 'image_alt_id': id2}
|
||||
"""
|
||||
self.init_keystone_client()
|
||||
image_info = {}
|
||||
try:
|
||||
glance_endpoint = self.kc.service_catalog.url_for(
|
||||
glance_endpoint = self.ks_client.service_catalog.url_for(
|
||||
service_type='image',
|
||||
endpoint_type='publicURL')
|
||||
glance_client = glanceclient.Client(
|
||||
'2', glance_endpoint, token=self.kc.auth_token)
|
||||
'2', glance_endpoint, token=self.ks_client.auth_token)
|
||||
for image in glance_client.images.list():
|
||||
if self.uconfig.get('glance-image-name') == image.name:
|
||||
image_info['image_id'] = image.id
|
||||
|
@ -138,15 +147,14 @@ class TempestAdminAdapter(adapters.OpenStackRelationAdapter):
|
|||
|
||||
@returns {'public_network_id' id1, 'router_id': id2}
|
||||
"""
|
||||
self.init_keystone_client()
|
||||
network_info = {}
|
||||
try:
|
||||
neutron_ep = self.kc.service_catalog.url_for(
|
||||
neutron_ep = self.ks_client.service_catalog.url_for(
|
||||
service_type='network',
|
||||
endpoint_type='publicURL')
|
||||
neutron_client = neutronclient.Client(
|
||||
endpoint_url=neutron_ep,
|
||||
token=self.kc.auth_token)
|
||||
token=self.ks_client.auth_token)
|
||||
routers = neutron_client.list_routers(
|
||||
name=self.uconfig['router-name'])
|
||||
if len(routers['routers']) == 0:
|
||||
|
@ -178,10 +186,9 @@ class TempestAdminAdapter(adapters.OpenStackRelationAdapter):
|
|||
|
||||
@returns {'flavor_id' id1, 'flavor_alt_id': id2}
|
||||
"""
|
||||
self.init_keystone_client()
|
||||
compute_info = {}
|
||||
try:
|
||||
nova_ep = self.kc.service_catalog.url_for(
|
||||
nova_ep = self.ks_client.service_catalog.url_for(
|
||||
service_type='compute',
|
||||
endpoint_type='publicURL'
|
||||
)
|
||||
|
@ -210,8 +217,9 @@ class TempestAdminAdapter(adapters.OpenStackRelationAdapter):
|
|||
|
||||
@returns [svc1, svc2, ...]: List of registered services
|
||||
"""
|
||||
self.init_keystone_client()
|
||||
services = [svc.name for svc in self.kc.services.list() if svc.enabled]
|
||||
services = [svc.name
|
||||
for svc in self.ks_client.services.list()
|
||||
if svc.enabled]
|
||||
return services
|
||||
|
||||
@property
|
||||
|
@ -338,7 +346,7 @@ class TempestCharm(charm.OpenStackCharm):
|
|||
env['https_proxy'] = conf['https-proxy']
|
||||
cmd = ['tox', '-e', tox_target]
|
||||
f = open(logfile, "w")
|
||||
subprocess.call(cmd, cwd=run_dir, stdout=f, stderr=f)
|
||||
subprocess.call(cmd, cwd=run_dir, stdout=f, stderr=f, env=env)
|
||||
|
||||
def get_tempest_files(self, branch_name):
|
||||
"""Prepare tempest files and directories
|
||||
|
@ -357,7 +365,7 @@ class TempestCharm(charm.OpenStackCharm):
|
|||
@return dict: Dictonary of summary data
|
||||
"""
|
||||
summary = {}
|
||||
with open(logfile) as tempest_log:
|
||||
with open(logfile, 'r') as tempest_log:
|
||||
summary_line = False
|
||||
for line in tempest_log:
|
||||
if line.strip() == "Totals":
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
# Unit test requirements
|
||||
flake8>=2.2.4,<=2.4.1
|
||||
# Lint and unit test requirements
|
||||
flake8
|
||||
os-testr>=0.4.1
|
||||
charms.reactive
|
||||
mock>=1.2
|
||||
coverage>=3.6
|
||||
git+https://github.com/openstack/charms.openstack#egg=charms.openstack
|
||||
requests
|
||||
python-glanceclient
|
||||
python-neutronclient
|
||||
python-novaclient
|
||||
git+https://github.com/openstack/charms.openstack.git#egg=charms-openstack
|
||||
|
|
|
@ -1,5 +1,46 @@
|
|||
# By design, this unit_tests dir is outside the src charm (layer),
|
||||
# and it will not be included in the resultant built charm asset.
|
||||
# Copyright 2016 Canonical Ltd
|
||||
#
|
||||
# Include unit tests here which are intended to be executable
|
||||
# from the source charm but not the built charm.
|
||||
# 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 sys
|
||||
import mock
|
||||
|
||||
sys.path.append('src')
|
||||
sys.path.append('src/lib')
|
||||
|
||||
# Mock out charmhelpers so that we can test without it.
|
||||
# also stops sideeffects from occuring.
|
||||
charmhelpers = mock.MagicMock()
|
||||
apt_pkg = mock.MagicMock()
|
||||
sys.modules['apt_pkg'] = apt_pkg
|
||||
sys.modules['charmhelpers'] = charmhelpers
|
||||
sys.modules['charmhelpers.core'] = charmhelpers.core
|
||||
sys.modules['charmhelpers.core.decorators'] = charmhelpers.core.decorators
|
||||
sys.modules['charmhelpers.core.hookenv'] = charmhelpers.core.hookenv
|
||||
sys.modules['charmhelpers.core.host'] = charmhelpers.core.host
|
||||
sys.modules['charmhelpers.core.unitdata'] = charmhelpers.core.unitdata
|
||||
sys.modules['charmhelpers.core.templating'] = charmhelpers.core.templating
|
||||
sys.modules['charmhelpers.contrib'] = charmhelpers.contrib
|
||||
sys.modules['charmhelpers.contrib.openstack'] = charmhelpers.contrib.openstack
|
||||
sys.modules['charmhelpers.contrib.openstack.utils'] = (
|
||||
charmhelpers.contrib.openstack.utils)
|
||||
sys.modules['charmhelpers.contrib.openstack.templating'] = (
|
||||
charmhelpers.contrib.openstack.templating)
|
||||
sys.modules['charmhelpers.contrib.network'] = charmhelpers.contrib.network
|
||||
sys.modules['charmhelpers.contrib.network.ip'] = (
|
||||
charmhelpers.contrib.network.ip)
|
||||
sys.modules['charmhelpers.fetch'] = charmhelpers.fetch
|
||||
sys.modules['charmhelpers.cli'] = charmhelpers.cli
|
||||
sys.modules['charmhelpers.contrib.hahelpers'] = charmhelpers.contrib.hahelpers
|
||||
sys.modules['charmhelpers.contrib.hahelpers.cluster'] = (
|
||||
charmhelpers.contrib.hahelpers.cluster)
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
TEMPEST_OUT = """
|
||||
======
|
||||
Totals
|
||||
======
|
||||
Ran: 62 tests in 64.8226 sec.
|
||||
- Passed: 21
|
||||
- Skipped: 41
|
||||
- Expected Fail: 0
|
||||
- Unexpected Success: 0
|
||||
- Failed: 0
|
||||
Sum of execute time for each test: 13.7436 sec.
|
||||
|
||||
==============
|
||||
Worker Balance
|
||||
==============
|
||||
- Worker 0 (62 tests) => 0:00:59.719541
|
||||
___________________________________ summary
|
||||
____________________________________
|
||||
smoke: commands succeeded
|
||||
congratulations :)
|
||||
"""
|
|
@ -0,0 +1,358 @@
|
|||
# Copyright 2016 Canonical Ltd
|
||||
#
|
||||
# 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.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
import io
|
||||
import mock
|
||||
|
||||
import charms_openstack.test_utils as test_utils
|
||||
import charm.openstack.tempest as tempest
|
||||
import unit_tests.tempest_output
|
||||
|
||||
|
||||
class Helper(test_utils.PatchHelper):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.patch_release(tempest.TempestCharm.release)
|
||||
|
||||
|
||||
class TestTempestAdminAdapter(test_utils.PatchHelper):
|
||||
|
||||
def test_init(self):
|
||||
self.patch_object(tempest.hookenv, 'config')
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'init_keystone_client')
|
||||
self.patch_object(
|
||||
tempest.adapters.OpenStackRelationAdapter, '__init__')
|
||||
tempest.TempestAdminAdapter('rel2')
|
||||
self.init_keystone_client.assert_called_once_with()
|
||||
self.__init__.assert_called_once_with('rel2')
|
||||
|
||||
def test_init_keystone_client(self):
|
||||
ks_info = {
|
||||
'service_hostname': 'kshost',
|
||||
'service_port': '5001',
|
||||
'service_username': 'user1',
|
||||
'service_password': 'pass1',
|
||||
'service_tenant_name': 'svc',
|
||||
'service_region': 'reg1'}
|
||||
self.patch_object(tempest.keystoneclient.client, 'Client')
|
||||
self.patch_object(tempest.hookenv, 'config')
|
||||
self.patch_object(
|
||||
tempest.adapters.OpenStackRelationAdapter, '__init__')
|
||||
self.patch_object(
|
||||
tempest.TempestAdminAdapter,
|
||||
'keystone_info',
|
||||
new=ks_info)
|
||||
a = tempest.TempestAdminAdapter('rel2')
|
||||
a.init_keystone_client()
|
||||
self.Client.assert_called_once_with(
|
||||
auth_url='http://kshost:5001/v2.0',
|
||||
password='pass1',
|
||||
region_name='reg1',
|
||||
tenant_name='svc',
|
||||
username='user1')
|
||||
|
||||
def test_ec2_creds(self):
|
||||
self.patch_object(tempest.hookenv, 'config')
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'init_keystone_client')
|
||||
self.patch_object(
|
||||
tempest.adapters.OpenStackRelationAdapter, '__init__')
|
||||
kc = mock.MagicMock()
|
||||
creds = mock.MagicMock()
|
||||
creds.access = 'ac2'
|
||||
creds.secret = 'st2'
|
||||
kc.user_id = 'bob'
|
||||
kc.ec2.list = lambda x: [creds]
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'ks_client', new=kc)
|
||||
a = tempest.TempestAdminAdapter('rel2')
|
||||
self.assertEqual(a.ec2_creds, {'access_token': 'ac2',
|
||||
'secret_token': 'st2'})
|
||||
|
||||
def test_image_info(self):
|
||||
self.patch_object(tempest.hookenv, 'config')
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'init_keystone_client')
|
||||
self.patch_object(
|
||||
tempest.adapters.OpenStackRelationAdapter, '__init__')
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'ks_client')
|
||||
self.patch_object(tempest.glanceclient, 'Client')
|
||||
self.config.return_value = {
|
||||
'glance-image-name': 'img1',
|
||||
'glance-alt-image-name': 'altimg',
|
||||
}
|
||||
kc = mock.MagicMock()
|
||||
kc.service_catalog.url_for = \
|
||||
lambda service_type=None, endpoint_type=None: 'http://glance'
|
||||
self.ks_client.return_value = kc
|
||||
img1 = mock.MagicMock()
|
||||
img1.name = 'img1'
|
||||
img1.id = 'img1_id'
|
||||
img2 = mock.MagicMock()
|
||||
img2.name = 'img2'
|
||||
img2.id = 'img2_id'
|
||||
gc = mock.MagicMock()
|
||||
gc.images.list = lambda: [img1, img2]
|
||||
self.Client.return_value = gc
|
||||
a = tempest.TempestAdminAdapter('rel2')
|
||||
self.assertEqual(a.image_info, {'image_id': 'img1_id'})
|
||||
|
||||
def test_network_info(self):
|
||||
self.patch_object(tempest.hookenv, 'config')
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'init_keystone_client')
|
||||
self.patch_object(
|
||||
tempest.adapters.OpenStackRelationAdapter, '__init__')
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'ks_client')
|
||||
self.patch_object(tempest.neutronclient, 'Client')
|
||||
router1 = {'id': '16'}
|
||||
net1 = {'id': 'pubnet1'}
|
||||
kc = mock.MagicMock()
|
||||
kc.service_catalog.url_for = \
|
||||
lambda service_type=None, endpoint_type=None: 'http://neutron'
|
||||
self.ks_client.return_value = kc
|
||||
self.config.return_value = {
|
||||
'router-name': 'route1',
|
||||
'network-name': 'net1'}
|
||||
nc = mock.MagicMock()
|
||||
nc.list_routers = lambda name=None: {'routers': [router1]}
|
||||
nc.list_networks = lambda name=None: {'networks': [net1]}
|
||||
self.Client.return_value = nc
|
||||
a = tempest.TempestAdminAdapter('rel2')
|
||||
self.assertEqual(
|
||||
a.network_info,
|
||||
{'public_network_id': 'pubnet1', 'router_id': '16'})
|
||||
|
||||
def test_compute_info(self):
|
||||
self.patch_object(tempest.hookenv, 'config')
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'init_keystone_client')
|
||||
self.patch_object(
|
||||
tempest.adapters.OpenStackRelationAdapter, '__init__')
|
||||
ki = {
|
||||
'service_username': 'user',
|
||||
'service_password': 'pass',
|
||||
'service_tenant_name': 'ten',
|
||||
}
|
||||
self.patch_object(
|
||||
tempest.TempestAdminAdapter,
|
||||
'keystone_info',
|
||||
new=ki)
|
||||
self.patch_object(
|
||||
tempest.TempestAdminAdapter,
|
||||
'keystone_auth_url',
|
||||
new='auth_url')
|
||||
self.config.return_value = {
|
||||
'flavor-name': 'm3.huuge'}
|
||||
kc = mock.MagicMock()
|
||||
kc.service_catalog.url_for = \
|
||||
lambda service_type=None, endpoint_type=None: 'http://nova:999/bob'
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'ks_client', new=kc)
|
||||
self.patch_object(tempest.novaclient.client, 'Client')
|
||||
_flavor1 = mock.MagicMock()
|
||||
_flavor1.name = 'm3.huuge'
|
||||
_flavor1.id = 'id1'
|
||||
nc = mock.MagicMock()
|
||||
nc.flavors.list = lambda: [_flavor1]
|
||||
self.Client.return_value = nc
|
||||
a = tempest.TempestAdminAdapter('rel2')
|
||||
self.assertEqual(
|
||||
a.compute_info,
|
||||
{
|
||||
'flavor_id': 'id1',
|
||||
'nova_base': 'http://nova',
|
||||
'nova_endpoint': 'http://nova:999/bob'})
|
||||
|
||||
def test_get_present_services(self):
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'init_keystone_client')
|
||||
self.patch_object(
|
||||
tempest.adapters.OpenStackRelationAdapter, '__init__')
|
||||
kc = mock.MagicMock()
|
||||
svc1 = mock.Mock()
|
||||
svc2 = mock.Mock()
|
||||
svc3 = mock.Mock()
|
||||
svc1.name = 'compute'
|
||||
svc1.enabled = True
|
||||
svc2.name = 'image'
|
||||
svc2.enabled = False
|
||||
svc3.name = 'network'
|
||||
svc3.enabled = True
|
||||
svcs = [svc1, svc2, svc3]
|
||||
kc.services.list = lambda: svcs
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'ks_client', new=kc)
|
||||
a = tempest.TempestAdminAdapter('rel2')
|
||||
self.assertEqual(
|
||||
a.get_present_services(),
|
||||
['compute', 'network'])
|
||||
|
||||
def test_service_info(self):
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'init_keystone_client')
|
||||
self.patch_object(
|
||||
tempest.adapters.OpenStackRelationAdapter, '__init__')
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'get_present_services')
|
||||
self.get_present_services.return_value = ['cinder', 'glance']
|
||||
self.patch_object(tempest.hookenv, 'action_get')
|
||||
self.action_get.return_value = {
|
||||
'service-whitelist': 'swift glance'}
|
||||
a = tempest.TempestAdminAdapter('rel2')
|
||||
self.assertEqual(
|
||||
a.service_info,
|
||||
{
|
||||
'ceilometer': 'false',
|
||||
'cinder': 'false',
|
||||
'glance': 'true',
|
||||
'heat': 'false',
|
||||
'horizon': 'false',
|
||||
'ironic': 'false',
|
||||
'neutron': 'false',
|
||||
'nova': 'false',
|
||||
'sahara': 'false',
|
||||
'swift': 'true',
|
||||
'trove': 'false',
|
||||
'zaqar': 'false',
|
||||
'neutron': 'false'})
|
||||
|
||||
def test_service_info_auto(self):
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'init_keystone_client')
|
||||
self.patch_object(
|
||||
tempest.adapters.OpenStackRelationAdapter, '__init__')
|
||||
self.patch_object(tempest.TempestAdminAdapter, 'get_present_services')
|
||||
self.get_present_services.return_value = ['cinder', 'glance']
|
||||
self.patch_object(tempest.hookenv, 'action_get')
|
||||
self.action_get.return_value = {
|
||||
'service-whitelist': 'auto'}
|
||||
a = tempest.TempestAdminAdapter('rel2')
|
||||
self.assertEqual(
|
||||
a.service_info,
|
||||
{
|
||||
'ceilometer': 'false',
|
||||
'cinder': 'true',
|
||||
'glance': 'true',
|
||||
'heat': 'false',
|
||||
'horizon': 'false',
|
||||
'ironic': 'false',
|
||||
'neutron': 'false',
|
||||
'nova': 'false',
|
||||
'sahara': 'false',
|
||||
'swift': 'false',
|
||||
'trove': 'false',
|
||||
'zaqar': 'false',
|
||||
'neutron': 'false'})
|
||||
|
||||
|
||||
class TestTempestCharm(Helper):
|
||||
|
||||
def test_setup_directories(self):
|
||||
self.patch_object(tempest.os.path, 'exists')
|
||||
self.patch_object(tempest.os, 'mkdir')
|
||||
self.exists.return_value = False
|
||||
c = tempest.TempestCharm()
|
||||
c.setup_directories()
|
||||
calls = [
|
||||
mock.call('/var/lib/tempest'),
|
||||
mock.call('/var/lib/tempest/logs')
|
||||
]
|
||||
self.mkdir.assert_has_calls(calls)
|
||||
|
||||
def test_setup_git(self):
|
||||
self.patch_object(tempest.hookenv, 'config')
|
||||
self.patch_object(tempest.os.path, 'exists')
|
||||
self.patch_object(tempest.os, 'symlink')
|
||||
self.patch_object(tempest.fetch, 'install_remote')
|
||||
self.config.return_value = {'tempest-source': 'git_url'}
|
||||
self.exists.return_value = False
|
||||
c = tempest.TempestCharm()
|
||||
c.setup_git('git_branch', 'git_dir')
|
||||
self.install_remote.assert_called_once_with(
|
||||
'git_url',
|
||||
branch='git_branch',
|
||||
depth='1',
|
||||
dest='git_dir')
|
||||
self.symlink.assert_called_once_with(
|
||||
'/var/lib/tempest/tempest.conf',
|
||||
'git_dir/tempest/etc/tempest.conf')
|
||||
|
||||
def test_setup_git_noop(self):
|
||||
self.patch_object(tempest.hookenv, 'config')
|
||||
self.patch_object(tempest.os.path, 'exists')
|
||||
self.config.return_value = {'tempest-source': 'git_url'}
|
||||
self.patch_object(tempest.os, 'symlink')
|
||||
self.patch_object(tempest.fetch, 'install_remote')
|
||||
self.exists.return_value = True
|
||||
c = tempest.TempestCharm()
|
||||
c.setup_git('git_branch', 'git_dir')
|
||||
self.assertFalse(self.install_remote.called)
|
||||
self.assertFalse(self.symlink.called)
|
||||
|
||||
def test_execute_tox(self):
|
||||
# XXX env seems unused
|
||||
self.patch_object(tempest.hookenv, 'config')
|
||||
self.patch_object(tempest.os.environ, 'copy')
|
||||
self.patch_object(tempest.subprocess, 'call')
|
||||
os_env = mock.MagicMock()
|
||||
self.copy.return_value = os_env
|
||||
self.config.return_value = {
|
||||
'http-proxy': 'http://proxy',
|
||||
'https-proxy': 'https://proxy',
|
||||
}
|
||||
with mock.patch("builtins.open", return_value="fhandle"):
|
||||
c = tempest.TempestCharm()
|
||||
c.execute_tox('/tmp/run', '/tmp/t.log', 'py38')
|
||||
self.call.assert_called_with(
|
||||
['tox', '-e', 'py38'],
|
||||
cwd='/tmp/run',
|
||||
stderr='fhandle',
|
||||
stdout='fhandle',
|
||||
env=os_env)
|
||||
|
||||
def test_get_tempest_files(self):
|
||||
self.patch_object(tempest.time, 'strftime')
|
||||
self.strftime.return_value = 'teatime'
|
||||
c = tempest.TempestCharm()
|
||||
self.assertEqual(
|
||||
c.get_tempest_files('br1'),
|
||||
('/var/lib/tempest/tempest-br1',
|
||||
'/var/lib/tempest/logs/run_teatime.log',
|
||||
'/var/lib/tempest/tempest-br1/tempest'))
|
||||
|
||||
def test_parse_tempest_log(self):
|
||||
_log_contents = io.StringIO(unit_tests.tempest_output.TEMPEST_OUT)
|
||||
expect = {
|
||||
'expected-fail': '0',
|
||||
'failed': '0',
|
||||
'passed': '21',
|
||||
'skipped': '41',
|
||||
'unexpected-success': '0'}
|
||||
with mock.patch("builtins.open", return_value=_log_contents):
|
||||
c = tempest.TempestCharm()
|
||||
self.assertEqual(c.parse_tempest_log("logfile"), expect)
|
||||
|
||||
def test_run_test(self):
|
||||
self.patch_object(tempest.hookenv, 'action_set')
|
||||
self.patch_object(tempest.hookenv, 'action_get')
|
||||
self.action_get.return_value = {
|
||||
'branch': 'br1'}
|
||||
self.patch_object(tempest.TempestCharm, 'get_tempest_files')
|
||||
self.patch_object(tempest.TempestCharm, 'setup_directories')
|
||||
self.patch_object(tempest.TempestCharm, 'setup_git')
|
||||
self.patch_object(tempest.TempestCharm, 'execute_tox')
|
||||
self.patch_object(tempest.TempestCharm, 'parse_tempest_log')
|
||||
self.get_tempest_files.return_value = (
|
||||
'git_dir1',
|
||||
'/var/log/t.log',
|
||||
'/var/tempest/run')
|
||||
self.parse_tempest_log.return_value = {'run_info': 'OK'}
|
||||
c = tempest.TempestCharm()
|
||||
c.run_test('py39')
|
||||
self.action_set.assert_called_once_with(
|
||||
{'run_info': 'OK', 'tempest-logfile': '/var/log/t.log'})
|
|
@ -1,13 +0,0 @@
|
|||
import unittest
|
||||
|
||||
|
||||
class TestNoOp(unittest.TestCase):
|
||||
"""Placeholder - Write Me!"""
|
||||
# XXX (beisner): with the charm.openstack vs lib/charm/openstack/tempest
|
||||
# module namespace collision, and with the hard requirement to have some
|
||||
# sort of unit test passing, here is a temporary inert noop test. After
|
||||
# charms_openstack module is completed, and this tempest charm is
|
||||
# refactored to use it, revisit this and add actual unit tests.
|
||||
def test_noop(self):
|
||||
"""Test Nothing"""
|
||||
pass
|
|
@ -0,0 +1,34 @@
|
|||
# Copyright 2016 Canonical Ltd
|
||||
#
|
||||
# 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.
|
||||
|
||||
from __future__ import absolute_import
|
||||
from __future__ import print_function
|
||||
|
||||
import reactive.tempest_handlers as handlers
|
||||
import charms_openstack.test_utils as test_utils
|
||||
|
||||
|
||||
class TestRegisteredHooks(test_utils.TestRegisteredHooks):
|
||||
|
||||
def test_hooks(self):
|
||||
defaults = []
|
||||
hook_set = {
|
||||
'when': {
|
||||
'install_packages': ('charm.installed',),
|
||||
'assess_status': ('charm.installed',),
|
||||
}
|
||||
}
|
||||
# test that the hooks were registered via the
|
||||
# reactive.barbican_handlers
|
||||
self.registered_hooks_test_helper(handlers, hook_set, defaults)
|
Loading…
Reference in New Issue