Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixes LP Bug#913608 - tests should be isolated
This reworks the stubs.FAKE_FILESYSTEM_ROOTDIR used in unit
tests by making each test case create and destroy its own little
sandbox in /tmp/test.*/images. Adds a base IsolatedUnitTest that
tests needing to have an isolated filesystem_store_datadir and
configuration can inherit from.

Change-Id: I396f5127c6a687da8dcef3368e7ed0912efc9b3a
  • Loading branch information
jaypipes committed Jan 16, 2012
1 parent 6fd0054 commit b4624ec
Show file tree
Hide file tree
Showing 9 changed files with 165 additions and 154 deletions.
11 changes: 5 additions & 6 deletions glance/tests/functional/__init__.py
Expand Up @@ -34,10 +34,12 @@
import unittest
import urlparse

from sqlalchemy import create_engine

from glance.common import utils
from glance.tests.utils import execute, get_unused_port
from glance.tests import utils as test_utils

from sqlalchemy import create_engine
execute, get_unused_port = test_utils.execute, test_utils.get_unused_port


def runs_sql(func):
Expand Down Expand Up @@ -326,10 +328,7 @@ class FunctionalTest(unittest.TestCase):
disabled = False

def setUp(self):

self.test_id = random.randint(0, 100000)
self.test_dir = os.path.join("/", "tmp", "test.%d" % self.test_id)
utils.safe_mkdirs(self.test_dir)
self.test_id, self.test_dir = test_utils.get_isolated_test_env()

self.api_protocol = 'http'
self.api_port = get_unused_port()
Expand Down
37 changes: 2 additions & 35 deletions glance/tests/stubs.py
Expand Up @@ -31,44 +31,11 @@
from glance.tests import utils


FAKE_FILESYSTEM_ROOTDIR = os.path.join('/tmp', 'glance-tests')
VERBOSE = False
DEBUG = False


def clean_out_fake_filesystem_backend():
"""
Removes any leftover directories used in fake filesystem
backend
"""
if os.path.exists(FAKE_FILESYSTEM_ROOTDIR):
shutil.rmtree(FAKE_FILESYSTEM_ROOTDIR, ignore_errors=True)


def stub_out_filesystem_backend():
"""
Stubs out the Filesystem Glance service to return fake
pped image data from files.
We establish a few fake images in a directory under //tmp/glance-tests
and ensure that this directory contains the following files:
//tmp/glance-tests/2 <-- file containing "chunk00000remainder"
The stubbed service yields the data in the above files.
"""

# Establish a clean faked filesystem with dummy images
if os.path.exists(FAKE_FILESYSTEM_ROOTDIR):
shutil.rmtree(FAKE_FILESYSTEM_ROOTDIR, ignore_errors=True)
os.mkdir(FAKE_FILESYSTEM_ROOTDIR)

f = open(os.path.join(FAKE_FILESYSTEM_ROOTDIR, '2'), "wb")
f.write("chunk00000remainder")
f.close()


def stub_out_registry_and_store_server(stubs):
def stub_out_registry_and_store_server(stubs, images_dir):
"""
Mocks calls to 127.0.0.1 on 9191 and 9292 for testing so
that a real Glance server does not need to be up and
Expand Down Expand Up @@ -158,7 +125,7 @@ def getresponse(self):
'registry_host': '0.0.0.0',
'registry_port': '9191',
'default_store': 'file',
'filesystem_store_datadir': FAKE_FILESYSTEM_ROOTDIR
'filesystem_store_datadir': images_dir
})
api = version_negotiation.VersionNegotiationFilter(
context.ContextMiddleware(router.API(conf), conf),
Expand Down
51 changes: 51 additions & 0 deletions glance/tests/unit/base.py
@@ -0,0 +1,51 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4

# Copyright 2012 OpenStack LLC.
# 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.

import os
import shutil
import unittest

import stubout

from glance.common import utils
from glance.tests import stubs
from glance.tests import utils as test_utils


class IsolatedUnitTest(unittest.TestCase):

"""
Unit test case that establishes a mock environment within
a testing directory (in isolation)
"""

def setUp(self):
self.test_id, self.test_dir = test_utils.get_isolated_test_env()
self.stubs = stubout.StubOutForTesting()
stubs.stub_out_registry_and_store_server(self.stubs, self.test_dir)
options = {'sql_connection': 'sqlite://',
'verbose': False,
'debug': False,
'default_store': 'filesystem',
'filesystem_store_datadir': os.path.join(self.test_dir)}

self.conf = test_utils.TestConfigOpts(options)

def tearDown(self):
self.stubs.UnsetAll()
if os.path.exists(self.test_dir):
shutil.rmtree(self.test_dir)
75 changes: 28 additions & 47 deletions glance/tests/unit/test_api.py
Expand Up @@ -18,7 +18,6 @@
import datetime
import hashlib
import httplib
import os
import json
import unittest

Expand All @@ -33,8 +32,8 @@
from glance.registry.api import v1 as rserver
from glance.registry.db import api as db_api
from glance.registry.db import models as db_models
from glance.tests import stubs
from glance.tests import utils as test_utils
from glance.tests.unit import base


_gen_uuid = utils.generate_uuid
Expand All @@ -43,15 +42,6 @@
UUID2 = _gen_uuid()


CONF = {'sql_connection': 'sqlite://',
'verbose': False,
'debug': False,
'registry_host': '0.0.0.0',
'registry_port': '9191',
'default_store': 'file',
'filesystem_store_datadir': stubs.FAKE_FILESYSTEM_ROOTDIR}


class TestRegistryDb(unittest.TestCase):

def setUp(self):
Expand Down Expand Up @@ -97,16 +87,14 @@ def tearDown(self):
self.stubs.UnsetAll()


class TestRegistryAPI(unittest.TestCase):
class TestRegistryAPI(base.IsolatedUnitTest):
def setUp(self):
"""Establish a clean test environment"""
self.stubs = stubout.StubOutForTesting()
stubs.stub_out_registry_and_store_server(self.stubs)
stubs.stub_out_filesystem_backend()
conf = test_utils.TestConfigOpts(CONF)
super(TestRegistryAPI, self).setUp()
context_class = 'glance.registry.context.RequestContext'
self.api = context.ContextMiddleware(rserver.API(conf),
conf, context_class=context_class)
self.api = context.ContextMiddleware(rserver.API(self.conf),
self.conf,
context_class=context_class)
self.FIXTURES = [
{'id': UUID1,
'name': 'fake image #1',
Expand All @@ -122,7 +110,7 @@ def setUp(self):
'min_disk': 0,
'min_ram': 0,
'size': 13,
'location': "swift://user:passwd@acct/container/obj.tar.0",
'location': "file:///%s/%s" % (self.test_dir, UUID1),
'properties': {'type': 'kernel'}},
{'id': UUID2,
'name': 'fake image #2',
Expand All @@ -138,22 +126,25 @@ def setUp(self):
'min_disk': 5,
'min_ram': 256,
'size': 19,
'location': "file:///tmp/glance-tests/2",
'location': "file:///%s/%s" % (self.test_dir, UUID2),
'properties': {}}]
self.context = rcontext.RequestContext(is_admin=True)
db_api.configure_db(conf)
db_api.configure_db(self.conf)
self.destroy_fixtures()
self.create_fixtures()

def tearDown(self):
"""Clear the test environment"""
stubs.clean_out_fake_filesystem_backend()
self.stubs.UnsetAll()
super(TestRegistryAPI, self).tearDown()
self.destroy_fixtures()

def create_fixtures(self):
for fixture in self.FIXTURES:
db_api.image_create(self.context, fixture)
# We write a fake image file to the filesystem
with open("%s/%s" % (self.test_dir, fixture['id']), 'wb') as image:
image.write("chunk00000remainder")
image.flush()

def destroy_fixtures(self):
# Easiest to just drop the models and re-create them...
Expand Down Expand Up @@ -1932,16 +1923,11 @@ def test_delete_member(self):
self.assertEquals(res.status_int, webob.exc.HTTPUnauthorized.code)


class TestGlanceAPI(unittest.TestCase):
class TestGlanceAPI(base.IsolatedUnitTest):
def setUp(self):
"""Establish a clean test environment"""

self.stubs = stubout.StubOutForTesting()
stubs.stub_out_registry_and_store_server(self.stubs)
stubs.stub_out_filesystem_backend()
sql_connection = os.environ.get('GLANCE_SQL_CONNECTION', "sqlite://")
conf = test_utils.TestConfigOpts(CONF)
self.api = context.ContextMiddleware(router.API(conf), conf)
super(TestGlanceAPI, self).setUp()
self.api = context.ContextMiddleware(router.API(self.conf), self.conf)
self.FIXTURES = [
{'id': UUID1,
'name': 'fake image #1',
Expand All @@ -1955,7 +1941,7 @@ def setUp(self):
'deleted': False,
'checksum': None,
'size': 13,
'location': "swift://user:passwd@acct/container/obj.tar.0",
'location': "file:///%s/%s" % (self.test_dir, UUID1),
'properties': {'type': 'kernel'}},
{'id': UUID2,
'name': 'fake image #2',
Expand All @@ -1969,22 +1955,25 @@ def setUp(self):
'deleted': False,
'checksum': None,
'size': 19,
'location': "file:///tmp/glance-tests/2",
'location': "file:///%s/%s" % (self.test_dir, UUID2),
'properties': {}}]
self.context = rcontext.RequestContext(is_admin=True)
db_api.configure_db(conf)
db_api.configure_db(self.conf)
self.destroy_fixtures()
self.create_fixtures()

def tearDown(self):
"""Clear the test environment"""
stubs.clean_out_fake_filesystem_backend()
self.stubs.UnsetAll()
super(TestGlanceAPI, self).tearDown()
self.destroy_fixtures()

def create_fixtures(self):
for fixture in self.FIXTURES:
db_api.image_create(self.context, fixture)
# We write a fake image file to the filesystem
with open("%s/%s" % (self.test_dir, fixture['id']), 'wb') as image:
image.write("chunk00000remainder")
image.flush()

def destroy_fixtures(self):
# Easiest to just drop the models and re-create them...
Expand Down Expand Up @@ -2691,19 +2680,16 @@ def test_delete_member(self):
self.assertEquals(res.status_int, webob.exc.HTTPUnauthorized.code)


class TestImageSerializer(unittest.TestCase):
class TestImageSerializer(base.IsolatedUnitTest):
def setUp(self):
"""Establish a clean test environment"""
self.stubs = stubout.StubOutForTesting()
stubs.stub_out_registry_and_store_server(self.stubs)
stubs.stub_out_filesystem_backend()
conf = test_utils.TestConfigOpts(CONF)
super(TestImageSerializer, self).setUp()
self.receiving_user = 'fake_user'
self.receiving_tenant = 2
self.context = rcontext.RequestContext(is_admin=True,
user=self.receiving_user,
tenant=self.receiving_tenant)
self.serializer = images.ImageSerializer(conf)
self.serializer = images.ImageSerializer(self.conf)

def image_iter():
for x in ['chunk', '678911234', '56789']:
Expand All @@ -2729,11 +2715,6 @@ def image_iter():
'properties': {}}
}

def tearDown(self):
"""Clear the test environment"""
stubs.clean_out_fake_filesystem_backend()
self.stubs.UnsetAll()

def test_meta(self):
exp_headers = {'x-image-meta-id': UUID2,
'x-image-meta-location': 'file:///tmp/glance-tests/2',
Expand Down

0 comments on commit b4624ec

Please sign in to comment.