Use testtools as the base testcase class.

As a step towards parallelizing the test runs, use testtools as the
base unittest test case class. In this patch, it has caused us to catch
places where setUp and tearDown were not being chained properly.
Additionally, we get to remove our custom skip decorators and a few
backported assert calls.

Part of blueprint grizzly-testtools

Change-Id: Ia2025e1b7191b65130b85b30ce6239d5c431c8ba
This commit is contained in:
Monty Taylor
2012-10-25 11:06:13 -07:00
parent 316d8b73e7
commit c14bb9a677
12 changed files with 35 additions and 149 deletions

View File

@@ -25,12 +25,12 @@ inline callbacks.
import functools
import sys
import unittest
import uuid
import mox
import nose.plugins.skip
import stubout
import testtools
from nova import flags
from nova.openstack.common import cfg
@@ -56,68 +56,11 @@ FLAGS.register_opts(test_opts)
LOG = logging.getLogger(__name__)
class skip_test(object):
"""Decorator that skips a test."""
# TODO(tr3buchet): remember forever what comstud did here
def __init__(self, msg):
self.message = msg
def __call__(self, func):
@functools.wraps(func)
def _skipper(*args, **kw):
"""Wrapped skipper function."""
raise nose.SkipTest(self.message)
return _skipper
class skip_if(object):
"""Decorator that skips a test if condition is true."""
def __init__(self, condition, msg):
self.condition = condition
self.message = msg
def __call__(self, func):
@functools.wraps(func)
def _skipper(*args, **kw):
"""Wrapped skipper function."""
if self.condition:
raise nose.SkipTest(self.message)
func(*args, **kw)
return _skipper
class skip_unless(object):
"""Decorator that skips a test if condition is not true."""
def __init__(self, condition, msg):
self.condition = condition
self.message = msg
def __call__(self, func):
@functools.wraps(func)
def _skipper(*args, **kw):
"""Wrapped skipper function."""
if not self.condition:
raise nose.SkipTest(self.message)
func(*args, **kw)
return _skipper
def skip_if_fake(func):
"""Decorator that skips a test if running in fake mode."""
def _skipper(*args, **kw):
"""Wrapped skipper function."""
if FLAGS.fake_tests:
raise unittest.SkipTest('Test cannot be run in fake mode')
else:
return func(*args, **kw)
return _skipper
class TestingException(Exception):
pass
class TestCase(unittest.TestCase):
class TestCase(testtools.TestCase):
"""Test case base class for all unit tests."""
def setUp(self):
@@ -272,7 +215,8 @@ class TestCase(unittest.TestCase):
def assertSubDictMatch(self, sub_dict, super_dict):
"""Assert a sub_dict is subset of super_dict."""
self.assertTrue(set(sub_dict.keys()).issubset(set(super_dict.keys())))
self.assertEqual(True,
set(sub_dict.keys()).issubset(set(super_dict.keys())))
for k, sub_value in sub_dict.items():
super_value = super_dict[k]
if isinstance(sub_value, dict):
@@ -281,30 +225,3 @@ class TestCase(unittest.TestCase):
continue
else:
self.assertEqual(sub_value, super_value)
def assertIn(self, a, b, *args, **kwargs):
"""Python < v2.7 compatibility. Assert 'a' in 'b'"""
try:
f = super(TestCase, self).assertIn
except AttributeError:
self.assertTrue(a in b, *args, **kwargs)
else:
f(a, b, *args, **kwargs)
def assertNotIn(self, a, b, *args, **kwargs):
"""Python < v2.7 compatibility. Assert 'a' NOT in 'b'"""
try:
f = super(TestCase, self).assertNotIn
except AttributeError:
self.assertFalse(a in b, *args, **kwargs)
else:
f(a, b, *args, **kwargs)
def assertIsInstance(self, a, b, *args, **kwargs):
"""Python < v2.7 compatibility. Assert 'a' is Instance of 'b'"""
try:
f = super(TestCase, self).assertIsInstance
except AttributeError:
self.assertTrue(isinstance(a, b), *args, **kwargs)
else:
f(a, b, *args, **kwargs)

View File

@@ -31,7 +31,7 @@ class FakeImageServiceTestCase(test.TestCase):
self.context = context.get_admin_context()
def tearDown(self):
super(FakeImageServiceTestCase, self).setUp()
super(FakeImageServiceTestCase, self).tearDown()
nova.tests.image.fake.FakeImageService_reset()
def test_detail(self):

View File

@@ -61,7 +61,9 @@ networks = [{'id': 0,
'vlan': None,
'host': HOST,
'project_id': 'fake_project',
'vpn_public_address': '192.168.0.2'},
'vpn_public_address': '192.168.0.2',
'vpn_public_port': '22',
'vpn_private_address': '10.0.0.2'},
{'id': 1,
'uuid': 'bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb',
'label': 'test1',
@@ -81,7 +83,9 @@ networks = [{'id': 0,
'vlan': None,
'host': HOST,
'project_id': 'fake_project',
'vpn_public_address': '192.168.1.2'}]
'vpn_public_address': '192.168.1.2',
'vpn_public_port': '22',
'vpn_private_address': '10.0.0.2'}]
fixed_ips = [{'id': 0,
'network_id': FAKEUUID,

View File

@@ -226,6 +226,7 @@ class TestQuantumv2(test.TestCase):
self.mox.VerifyAll()
finally:
FLAGS.reset()
super(TestQuantumv2, self).tearDown()
def _verify_nw_info(self, nw_inf, index=0):
id_suffix = index + 1

View File

@@ -431,7 +431,7 @@ class ApiEc2TestCase(test.TestCase):
group.authorize(*args)
except boto_exc.EC2ResponseError as e:
self.assertEqual(e.status, 400, 'Expected status to be 400')
self.assertIn(message, e.error_message, e.error_message)
self.assertIn(message, e.error_message)
else:
raise self.failureException, 'EC2ResponseError not raised'

View File

@@ -217,11 +217,12 @@ class TestMigrations(test.TestCase):
if _is_mysql_avail(user="openstack_cifail"):
self.fail("Shouldn't have connected")
@test.skip_unless(_have_mysql(), "mysql not available")
def test_mysql_innodb(self):
"""
Test that table creation on mysql only builds InnoDB tables
"""
if not _have_mysql():
self.skipTest("mysql not available")
# add this to the global lists to make reset work with it, it's removed
# automaticaly in tearDown so no need to clean it up here.
connect_string = _mysql_get_connect_string()

View File

@@ -63,9 +63,9 @@ class RootwrapTestCase(test.TestCase):
self.assertEqual(env.get('FLAGFILE'), 'A')
self.assertEqual(env.get('NETWORK_ID'), 'foobar')
@test.skip_if(not os.path.exists("/proc/%d" % os.getpid()),
"Test requires /proc filesystem (procfs)")
def test_KillFilter(self):
if not os.path.exists("/proc/%d" % os.getpid()):
self.skipTest("Test requires /proc filesystem (procfs)")
p = subprocess.Popen(["cat"], stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)

View File

@@ -1,47 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
#
# 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 nova import test
class ExampleSkipTestCase(test.TestCase):
test_counter = 0
@test.skip_test("Example usage of @test.skip_test()")
def test_skip_test_example(self):
self.fail("skip_test failed to work properly.")
@test.skip_if(True, "Example usage of @test.skip_if()")
def test_skip_if_example(self):
self.fail("skip_if failed to work properly.")
@test.skip_unless(False, "Example usage of @test.skip_unless()")
def test_skip_unless_example(self):
self.fail("skip_unless failed to work properly.")
@test.skip_if(False, "This test case should never be skipped.")
def test_001_increase_test_counter(self):
ExampleSkipTestCase.test_counter += 1
@test.skip_unless(True, "This test case should never be skipped.")
def test_002_increase_test_counter(self):
ExampleSkipTestCase.test_counter += 1
def test_003_verify_test_counter(self):
self.assertEquals(ExampleSkipTestCase.test_counter, 2,
"Tests were not skipped appropriately")

View File

@@ -16,11 +16,11 @@
# under the License.
import os
import platform
from nova import exception
from nova import flags
from nova import test
from nova import tests
from nova import utils
from nova.virt.disk import api as disk_api
from nova.virt import driver
@@ -166,27 +166,31 @@ class TestVirtDiskPaths(test.TestCase):
self.stubs.Set(utils, 'execute', nonroot_execute)
@test.skip_unless(platform.mac_ver()[0] == '', "Unable to test on OSX")
def test_check_safe_path(self):
if tests.utils.is_osx():
self.skipTest("Unable to test on OSX")
ret = disk_api._join_and_check_path_within_fs('/foo', 'etc',
'something.conf')
self.assertEquals(ret, '/foo/etc/something.conf')
@test.skip_unless(platform.mac_ver()[0] == '', "Unable to test on OSX")
def test_check_unsafe_path(self):
if tests.utils.is_osx():
self.skipTest("Unable to test on OSX")
self.assertRaises(exception.Invalid,
disk_api._join_and_check_path_within_fs,
'/foo', 'etc/../../../something.conf')
@test.skip_unless(platform.mac_ver()[0] == '', "Unable to test on OSX")
def test_inject_files_with_bad_path(self):
if tests.utils.is_osx():
self.skipTest("Unable to test on OSX")
self.assertRaises(exception.Invalid,
disk_api._inject_file_into_fs,
'/tmp', '/etc/../../../../etc/passwd',
'hax')
@test.skip_unless(platform.mac_ver()[0] == '', "Unable to test on OSX")
def test_inject_metadata(self):
if tests.utils.is_osx():
self.skipTest("Unable to test on OSX")
with utils.tempdir() as tmpdir:
meta_objs = [{"key": "foo", "value": "bar"}]
metadata = {"foo": "bar"}

View File

@@ -537,8 +537,7 @@ class LibvirtConnTestCase(_VirtDriverTestCase):
self.flags(libvirt_wait_soft_reboot_seconds=0)
self.test_reboot()
@test.skip_test("Test nothing, but this method "
"needed to override superclass.")
def test_migrate_disk_and_power_off(self):
# there is lack of fake stuff to execute this method. so pass.
pass
self.skipTest("Test nothing, but this method"
" needed to override superclass.")

View File

@@ -14,6 +14,8 @@
# License for the specific language governing permissions and limitations
#
import platform
import nova.context
import nova.db
import nova.flags
@@ -95,3 +97,7 @@ def get_test_network_info(count=1):
{'ip': fake_ip_2},
{'ip': fake_ip_3}]
return [(network, mapping) for x in xrange(0, count)]
def is_osx():
return platform.mac_ver()[0] != ''

View File

@@ -4,6 +4,7 @@ distribute>=0.6.24
coverage
mox==0.5.3
nose
testtools
openstack.nose_plugin>=0.7
nosehtmloutput
pep8==1.2