Replace custom tearDown with fixtures and cleanup.

testtools.addCleanup is a more resilient way to perform cleanup activities,
as it will continue to clean things up even if there are unforseen problems.

Specifically, replace custom management of tempdirs with fixtures.TempDir
and replace tearDown methods that can be easily replaced with calls to
addCleanup in the setUp method. There are at least two temp dir creations that
did not have a corresponding cleanup in this patch, which is another reason
for using useFixture(fixtures.TempDir) instead of calls to mkdtemp.

Part of blueprint grizzly-testtools.

Change-Id: I4eb548010612bd5a8d30e8e2304fa66d3d5ffb7c
This commit is contained in:
Monty Taylor 2013-01-05 21:18:17 -05:00
parent 3de221b9db
commit 43f8697696
14 changed files with 113 additions and 188 deletions

View File

@ -33,6 +33,7 @@ import socket
import time
import urlparse
import fixtures
from sqlalchemy import create_engine
from glance.common import utils
@ -457,7 +458,7 @@ class FunctionalTest(test_utils.BaseTestCase):
def setUp(self):
super(FunctionalTest, self).setUp()
self.test_id, self.test_dir = test_utils.get_isolated_test_env()
self.test_dir = self.useFixture(fixtures.TempDir()).path
self.api_protocol = 'http'
self.api_port = get_unused_port()
@ -776,12 +777,6 @@ class FunctionalTest(test_utils.BaseTestCase):
self.stop_server(self.registry_server, 'Registry server')
self.stop_server(self.scrubber_daemon, 'Scrubber daemon')
# If all went well, then just remove the test directory.
# We only want to check the logs and stuff if something
# went wrong...
if os.path.exists(self.test_dir):
shutil.rmtree(self.test_dir)
self._reset_database(self.registry_server.sql_connection)
def run_sql_cmd(self, sql):

View File

@ -20,7 +20,8 @@ Functional tests for the File store interface
import os
import os.path
import shutil
import fixtures
import testtools
import glance.openstack.common.cfg
@ -37,7 +38,7 @@ class TestFilesystemStore(store_tests.BaseTestCase, testtools.TestCase):
def setUp(self):
super(TestFilesystemStore, self).setUp()
_, self.tmp_dir = glance.tests.utils.get_isolated_test_env()
self.tmp_dir = self.useFixture(fixtures.TempDir()).path
self.store_dir = os.path.join(self.tmp_dir, 'images')
os.mkdir(self.store_dir)
@ -50,10 +51,6 @@ class TestFilesystemStore(store_tests.BaseTestCase, testtools.TestCase):
glance.openstack.common.cfg.CONF(default_config_files=[config_file],
args=[])
def tearDown(self):
shutil.rmtree(self.tmp_dir)
super(TestFilesystemStore, self).tearDown()
def get_store(self, **kwargs):
store = glance.store.filesystem.Store(context=kwargs.get('context'))
store.configure()

View File

@ -21,9 +21,10 @@ import os
import signal
import socket
import sys
import tempfile
import time
import fixtures
from glance.tests import functional
from glance.tests.utils import skip_if_disabled
@ -90,7 +91,7 @@ class TestGlanceControl(functional.FunctionalTest):
"""
if os.getuid() is 0:
self.skipTest("User root can always create directories")
parent = tempfile.mkdtemp()
parent = self.useFixture(fixtures.TempDir()).path
os.chmod(parent, 0)
pid_file = os.path.join(parent, 'pids', 'api.pid')
self._do_test_fallback_pidfile(pid_file)
@ -103,7 +104,7 @@ class TestGlanceControl(functional.FunctionalTest):
"""
if os.getuid() is 0:
self.skipTest("User root can always write inside directories")
parent = tempfile.mkdtemp()
parent = self.useFixture(fixtures.TempDir()).path
os.chmod(parent, 0)
pid_file = os.path.join(parent, 'api.pid')
self._do_test_fallback_pidfile(pid_file)

View File

@ -19,6 +19,7 @@ import json
import os
import shutil
import fixtures
import stubout
from glance.openstack.common import cfg
@ -38,11 +39,7 @@ class StoreClearingUnitTest(test_utils.BaseTestCase):
# Ensure stores + locations cleared
location.SCHEME_TO_CLS_MAP = {}
store.create_stores()
def tearDown(self):
super(StoreClearingUnitTest, self).tearDown()
# Ensure stores + locations cleared
location.SCHEME_TO_CLS_MAP = {}
self.addCleanup(setattr, location, 'SCHEME_TO_CLS_MAP', dict())
class IsolatedUnitTest(StoreClearingUnitTest):
@ -53,7 +50,8 @@ class IsolatedUnitTest(StoreClearingUnitTest):
"""
def setUp(self):
self.test_id, self.test_dir = test_utils.get_isolated_test_env()
super(IsolatedUnitTest, self).setUp()
self.test_dir = self.useFixture(fixtures.TempDir()).path
self.stubs = stubout.StubOutForTesting()
policy_file = self._copy_data_file('policy.json', self.test_dir)
self.config(sql_connection='sqlite://',
@ -62,8 +60,8 @@ class IsolatedUnitTest(StoreClearingUnitTest):
default_store='filesystem',
filesystem_store_datadir=os.path.join(self.test_dir),
policy_file=policy_file)
super(IsolatedUnitTest, self).setUp()
stubs.stub_out_registry_and_store_server(self.stubs, self.test_dir)
self.addCleanup(self.stubs.UnsetAll)
def _copy_data_file(self, file_name, dst_dir):
src_file_name = os.path.join('glance/tests/etc', file_name)
@ -75,9 +73,3 @@ class IsolatedUnitTest(StoreClearingUnitTest):
fap = open(CONF.policy_file, 'w')
fap.write(json.dumps(rules))
fap.close()
def tearDown(self):
super(IsolatedUnitTest, self).tearDown()
self.stubs.UnsetAll()
if os.path.exists(self.test_dir):
shutil.rmtree(self.test_dir)

View File

@ -120,10 +120,7 @@ class TestKeystoneAuthPlugin(utils.BaseTestCase):
def setUp(self):
super(TestKeystoneAuthPlugin, self).setUp()
self.stubs = stubout.StubOutForTesting()
def tearDown(self):
super(TestKeystoneAuthPlugin, self).tearDown()
self.stubs.UnsetAll()
self.addCleanup(self.stubs.UnsetAll)
def test_required_creds(self):
"""

View File

@ -137,10 +137,7 @@ class TestCacheMiddlewareProcessRequest(testtools.TestCase):
def setUp(self):
super(TestCacheMiddlewareProcessRequest, self).setUp()
self.stubs = stubout.StubOutForTesting()
def tearDown(self):
super(TestCacheMiddlewareProcessRequest, self).tearDown()
self.stubs.UnsetAll()
self.addCleanup(self.stubs.UnsetAll)
def test_v1_deleted_image_fetch(self):
"""

View File

@ -17,8 +17,8 @@
import os.path
import shutil
import tempfile
import fixtures
import stubout
from glance.api.middleware import context
@ -31,10 +31,7 @@ class TestPasteApp(test_utils.BaseTestCase):
def setUp(self):
super(TestPasteApp, self).setUp()
self.stubs = stubout.StubOutForTesting()
def tearDown(self):
super(TestPasteApp, self).tearDown()
self.stubs.UnsetAll()
self.addCleanup(self.stubs.UnsetAll)
def _do_test_load_paste_app(self,
expected_app_type,
@ -58,24 +55,22 @@ class TestPasteApp(test_utils.BaseTestCase):
config_file=paste_config_file,
group='paste_deploy')
temp_file = os.path.join(tempfile.mkdtemp(), 'testcfg.conf')
temp_dir = self.useFixture(fixtures.TempDir()).path
temp_file = os.path.join(temp_dir, 'testcfg.conf')
try:
_writeto(temp_file, '[DEFAULT]\n')
_writeto(temp_file, '[DEFAULT]\n')
config.parse_args(['--config-file', temp_file])
config.parse_args(['--config-file', temp_file])
paste_to = temp_file.replace('.conf', '-paste.ini')
if not paste_config_file and make_paste_file:
paste_from = os.path.join(os.getcwd(),
'etc/glance-registry-paste.ini')
_appendto(paste_from, paste_to, paste_append)
paste_to = temp_file.replace('.conf', '-paste.ini')
if not paste_config_file and make_paste_file:
paste_from = os.path.join(os.getcwd(),
'etc/glance-registry-paste.ini')
_appendto(paste_from, paste_to, paste_append)
app = config.load_paste_app('glance-registry')
app = config.load_paste_app('glance-registry')
self.assertEquals(expected_app_type, type(app))
finally:
shutil.rmtree(os.path.dirname(temp_file))
self.assertEquals(expected_app_type, type(app))
def test_load_paste_app(self):
expected_middleware = context.UnauthenticatedContextMiddleware

View File

@ -18,13 +18,13 @@ import copy
import imp
import json
import os
import shutil
import StringIO
import sys
import tempfile
import UserDict
import uuid
import fixtures
from glance.tests import utils as test_utils
@ -333,7 +333,7 @@ class ReplicationCommandsTestCase(test_utils.BaseTestCase):
self.assertEqual(output, 'Total size is 400 bytes across 2 images')
def test_replication_dump(self):
tempdir = tempfile.mkdtemp()
tempdir = self.useFixture(fixtures.TempDir()).path
options = UserDict.UserDict()
options.chunksize = 4096
@ -342,39 +342,36 @@ class ReplicationCommandsTestCase(test_utils.BaseTestCase):
args = ['localhost:9292', tempdir]
orig_img_service = glance_replicator.get_image_service
try:
glance_replicator.get_image_service = get_image_service
glance_replicator.replication_dump(options, args)
self.addCleanup(setattr, glance_replicator,
'get_image_service', orig_img_service)
glance_replicator.get_image_service = get_image_service
glance_replicator.replication_dump(options, args)
for active in ['5dcddce0-cba5-4f18-9cf4-9853c7b207a6',
'37ff82db-afca-48c7-ae0b-ddc7cf83e3db']:
imgfile = os.path.join(tempdir, active)
self.assertTrue(os.path.exists(imgfile))
self.assertTrue(os.path.exists('%s.img' % imgfile))
for active in ['5dcddce0-cba5-4f18-9cf4-9853c7b207a6',
'37ff82db-afca-48c7-ae0b-ddc7cf83e3db']:
imgfile = os.path.join(tempdir, active)
self.assertTrue(os.path.exists(imgfile))
self.assertTrue(os.path.exists('%s.img' % imgfile))
with open(imgfile) as f:
d = json.loads(f.read())
self.assertTrue('status' in d)
self.assertTrue('id' in d)
self.assertTrue('size' in d)
with open(imgfile) as f:
d = json.loads(f.read())
self.assertTrue('status' in d)
self.assertTrue('id' in d)
self.assertTrue('size' in d)
for inactive in ['f4da1d2a-40e8-4710-b3aa-0222a4cc887b']:
imgfile = os.path.join(tempdir, inactive)
self.assertTrue(os.path.exists(imgfile))
self.assertFalse(os.path.exists('%s.img' % imgfile))
for inactive in ['f4da1d2a-40e8-4710-b3aa-0222a4cc887b']:
imgfile = os.path.join(tempdir, inactive)
self.assertTrue(os.path.exists(imgfile))
self.assertFalse(os.path.exists('%s.img' % imgfile))
with open(imgfile) as f:
d = json.loads(f.read())
self.assertTrue('status' in d)
self.assertTrue('id' in d)
self.assertTrue('size' in d)
finally:
glance_replicator.get_image_service = orig_img_service
shutil.rmtree(tempdir)
with open(imgfile) as f:
d = json.loads(f.read())
self.assertTrue('status' in d)
self.assertTrue('id' in d)
self.assertTrue('size' in d)
def test_replication_load(self):
tempdir = tempfile.mkdtemp()
tempdir = self.useFixture(fixtures.TempDir()).path
def write_image(img, data):
imgfile = os.path.join(tempdir, img['id'])
@ -385,56 +382,52 @@ class ReplicationCommandsTestCase(test_utils.BaseTestCase):
with open('%s.img' % imgfile, 'w') as f:
f.write(data)
for img in FAKEIMAGES:
cimg = copy.copy(img)
# We need at least one image where the stashed metadata on disk
# is newer than what the fake has
if cimg['id'] == '5dcddce0-cba5-4f18-9cf4-9853c7b207a6':
cimg['extra'] = 'thisissomeextra'
# This is an image where the metadata change should be ignored
if cimg['id'] == 'f4da1d2a-40e8-4710-b3aa-0222a4cc887b':
cimg['dontrepl'] = 'thisisyetmoreextra'
write_image(cimg, 'kjdhfkjshdfkjhsdkfd')
# And an image which isn't on the destination at all
new_id = str(uuid.uuid4())
cimg['id'] = new_id
write_image(cimg, 'dskjfhskjhfkfdhksjdhf')
# And an image which isn't on the destination, but lacks image
# data
new_id_missing_data = str(uuid.uuid4())
cimg['id'] = new_id_missing_data
write_image(cimg, None)
# A file which should be ignored
badfile = os.path.join(tempdir, 'kjdfhf')
with open(badfile, 'w') as f:
f.write(json.dumps([1, 2, 3, 4, 5]))
# Finally, we're ready to test
options = UserDict.UserDict()
options.dontreplicate = 'dontrepl dontreplabsent'
options.slavetoken = 'slavetoken'
args = ['localhost:9292', tempdir]
orig_img_service = glance_replicator.get_image_service
try:
for img in FAKEIMAGES:
cimg = copy.copy(img)
# We need at least one image where the stashed metadata on disk
# is newer than what the fake has
if cimg['id'] == '5dcddce0-cba5-4f18-9cf4-9853c7b207a6':
cimg['extra'] = 'thisissomeextra'
# This is an image where the metadata change should be ignored
if cimg['id'] == 'f4da1d2a-40e8-4710-b3aa-0222a4cc887b':
cimg['dontrepl'] = 'thisisyetmoreextra'
write_image(cimg, 'kjdhfkjshdfkjhsdkfd')
# And an image which isn't on the destination at all
new_id = str(uuid.uuid4())
cimg['id'] = new_id
write_image(cimg, 'dskjfhskjhfkfdhksjdhf')
# And an image which isn't on the destination, but lacks image
# data
new_id_missing_data = str(uuid.uuid4())
cimg['id'] = new_id_missing_data
write_image(cimg, None)
# A file which should be ignored
badfile = os.path.join(tempdir, 'kjdfhf')
with open(badfile, 'w') as f:
f.write(json.dumps([1, 2, 3, 4, 5]))
# Finally, we're ready to test
options = UserDict.UserDict()
options.dontreplicate = 'dontrepl dontreplabsent'
options.slavetoken = 'slavetoken'
args = ['localhost:9292', tempdir]
orig_img_service = glance_replicator.get_image_service
try:
glance_replicator.get_image_service = get_image_service
updated = glance_replicator.replication_load(options, args)
finally:
glance_replicator.get_image_service = orig_img_service
self.assertTrue('5dcddce0-cba5-4f18-9cf4-9853c7b207a6' in updated)
self.assertFalse('f4da1d2a-40e8-4710-b3aa-0222a4cc887b' in updated)
self.assertTrue(new_id in updated)
self.assertFalse(new_id_missing_data in updated)
glance_replicator.get_image_service = get_image_service
updated = glance_replicator.replication_load(options, args)
finally:
shutil.rmtree(tempdir)
glance_replicator.get_image_service = orig_img_service
self.assertTrue('5dcddce0-cba5-4f18-9cf4-9853c7b207a6' in updated)
self.assertFalse('f4da1d2a-40e8-4710-b3aa-0222a4cc887b' in updated)
self.assertTrue(new_id in updated)
self.assertFalse(new_id_missing_data in updated)
def test_replication_livecopy(self):
options = UserDict.UserDict()

View File

@ -22,6 +22,7 @@ import random
import shutil
import StringIO
import fixtures
import stubout
from glance.common import exception
@ -418,9 +419,7 @@ class TestImageCacheXattr(test_utils.BaseTestCase,
if getattr(self, 'disable', False):
return
self.cache_dir = os.path.join("/", "tmp", "test.cache.%d" %
random.randint(0, 1000000))
utils.safe_mkdirs(self.cache_dir)
self.cache_dir = self.useFixture(fixtures.TempDir()).path
if not getattr(self, 'inited', False):
try:
@ -444,11 +443,6 @@ class TestImageCacheXattr(test_utils.BaseTestCase,
self.disabled_message = ("filesystem does not support xattr")
return
def tearDown(self):
super(TestImageCacheXattr, self).tearDown()
if os.path.exists(self.cache_dir):
shutil.rmtree(self.cache_dir)
class TestImageCacheSqlite(test_utils.BaseTestCase,
ImageCacheTestCase):
@ -476,18 +470,12 @@ class TestImageCacheSqlite(test_utils.BaseTestCase,
self.inited = True
self.disabled = False
self.cache_dir = os.path.join("/", "tmp", "test.cache.%d" %
random.randint(0, 1000000))
self.cache_dir = self.useFixture(fixtures.TempDir()).path
self.config(image_cache_dir=self.cache_dir,
image_cache_driver='sqlite',
image_cache_max_size=1024 * 5)
self.cache = image_cache.ImageCache()
def tearDown(self):
super(TestImageCacheSqlite, self).tearDown()
if os.path.exists(self.cache_dir):
shutil.rmtree(self.cache_dir)
class TestImageCacheNoDep(test_utils.BaseTestCase):
@ -501,10 +489,7 @@ class TestImageCacheNoDep(test_utils.BaseTestCase):
self.stubs = stubout.StubOutForTesting()
self.stubs.Set(image_cache.ImageCache, 'init_driver', init_driver)
def tearDown(self):
super(TestImageCacheNoDep, self).tearDown()
self.stubs.UnsetAll()
self.addCleanup(self.stubs.UnsetAll)
def test_get_caching_iter_when_write_fails(self):

View File

@ -165,11 +165,7 @@ class TestStore(base.StoreClearingUnitTest):
self.stubs = stubout.StubOutForTesting()
stub_out_s3(self.stubs)
self.store = Store()
def tearDown(self):
"""Clear the test environment"""
super(TestStore, self).tearDown()
self.stubs.UnsetAll()
self.addCleanup(self.stubs.UnsetAll)
def test_get(self):
"""Test a "normal" retrieval of an image in chunks"""

View File

@ -658,11 +658,7 @@ class TestStoreAuthV1(base.StoreClearingUnitTest, SwiftTests):
self.stubs = stubout.StubOutForTesting()
stub_out_swiftclient(self.stubs, conf['swift_store_auth_version'])
self.store = Store()
def tearDown(self):
"""Clear the test environment"""
super(TestStoreAuthV1, self).tearDown()
self.stubs.UnsetAll()
self.addCleanup(self.stubs.UnsetAll)
class TestStoreAuthV2(TestStoreAuthV1):

View File

@ -60,6 +60,10 @@ class TestRegistryDb(test_utils.BaseTestCase):
self.orig_engine = db_api._ENGINE
self.orig_connection = db_api._CONNECTION
self.orig_maker = db_api._MAKER
self.addCleanup(self.stubs.UnsetAll)
self.addCleanup(setattr, db_api, '_ENGINE', self.orig_engine)
self.addCleanup(setattr, db_api, '_CONNECTION', self.orig_connection)
self.addCleanup(setattr, db_api, '_MAKER', self.orig_maker)
def test_bad_sql_connection(self):
"""
@ -98,14 +102,6 @@ class TestRegistryDb(test_utils.BaseTestCase):
self.assertTrue(exc_raised)
self.assertTrue(self.log_written)
def tearDown(self):
"""Clear the test environment"""
super(TestRegistryDb, self).tearDown()
db_api._ENGINE = self.orig_engine
db_api._CONNECTION = self.orig_connection
db_api._MAKER = self.orig_maker
self.stubs.UnsetAll()
class TestRegistryAPI(base.IsolatedUnitTest):
def setUp(self):

View File

@ -36,19 +36,6 @@ from glance.openstack.common import cfg
CONF = cfg.CONF
def get_isolated_test_env():
"""
Returns a tuple of (test_id, test_dir) that is unique
for an isolated test environment. Also ensure the test_dir
is created.
"""
test_id = random.randint(0, 100000)
test_tmp_dir = os.getenv('GLANCE_TEST_TMP_DIR', '/tmp')
test_dir = os.path.join(test_tmp_dir, "test.%d" % test_id)
utils.safe_mkdirs(test_dir)
return test_id, test_dir
class BaseTestCase(testtools.TestCase):
def setUp(self):
@ -58,10 +45,7 @@ class BaseTestCase(testtools.TestCase):
# command-line options - specifically we need config_dir for
# the following policy tests
config.parse_args(args=[])
def tearDown(self):
super(BaseTestCase, self).tearDown()
CONF.reset()
self.addCleanup(CONF.reset)
def config(self, **kw):
"""
@ -74,7 +58,7 @@ class BaseTestCase(testtools.TestCase):
the specified configuration option group.
All overrides are automatically cleared at the end of the current
test by the tearDown() method.
test by the fixtures cleanup process.
"""
group = kw.pop('group', None)
for k, v in kw.iteritems():

View File

@ -6,6 +6,7 @@ Babel
# Needed for testing
coverage
fixtures>=0.3.12
mox
nose
nose-exclude