Monkeypatch Fake Clients for tests

We currently branch based on the names of providers, images, etc in
order to test with our fakes. We can get a lot more coverage by
monkeypatching our fakes over the clients they are faking for.

Change-Id: If80eb1f4d914f8b2fbd914311ecda2cf66e7a803
This commit is contained in:
Gregory Haynes 2015-03-19 03:27:54 +00:00
parent 7dd935105c
commit 3caaf8ac18
12 changed files with 90 additions and 35 deletions

View File

@ -31,6 +31,26 @@ class Dummy(object):
def delete(self): def delete(self):
self.manager.delete(self) self.manager.delete(self)
def update(self, data):
try:
if self.should_fail:
raise RuntimeError('This image has SHOULD_FAIL set to True.')
except AttributeError:
pass
fake_images_list = None
def get_fake_images_list():
global fake_images_list
if fake_images_list is None:
fake_images_list = FakeList([Dummy(id='fake-image-id',
status='READY',
name='Fake Precise',
metadata={})])
return fake_images_list
class FakeList(object): class FakeList(object):
def __init__(self, l): def __init__(self, l):
@ -67,6 +87,7 @@ class FakeList(object):
self._list.remove(self.get(obj)) self._list.remove(self.get(obj))
def create(self, **kw): def create(self, **kw):
should_fail = kw.get('SHOULD_FAIL', '').lower() == 'true'
s = Dummy(id=uuid.uuid4().hex, s = Dummy(id=uuid.uuid4().hex,
name=kw['name'], name=kw['name'],
status='BUILD', status='BUILD',
@ -76,7 +97,8 @@ class FakeList(object):
private=[dict(version=4, addr='fake')] private=[dict(version=4, addr='fake')]
), ),
metadata={}, metadata={},
manager=self) manager=self,
should_fail=should_fail)
self._list.append(s) self._list.append(s)
t = threading.Thread(target=self._finish, t = threading.Thread(target=self._finish,
name='FakeProvider create', name='FakeProvider create',
@ -97,27 +119,32 @@ class FakeHTTPClient(object):
class FakeClient(object): class FakeClient(object):
def __init__(self): def __init__(self, *args, **kwargs):
self.flavors = FakeList([ self.flavors = FakeList([
Dummy(id='f1', ram=8192, name='Fake Flavor'), Dummy(id='f1', ram=8192, name='Fake Flavor'),
Dummy(id='f2', ram=8192, name='Unreal Flavor'), Dummy(id='f2', ram=8192, name='Unreal Flavor'),
]) ])
self.images = FakeList([Dummy(id='i1', name='Fake Precise')]) self.images = get_fake_images_list()
self.client = FakeHTTPClient() self.client = FakeHTTPClient()
self.servers = FakeList([]) self.servers = FakeList([])
self.servers.api = self self.servers.api = self
class FakeGlanceClient(object): class FakeGlanceClient(object):
def __init__(self, **kwargs): def __init__(self, *args, **kwargs):
self.id = 'fake-glance-id' self.id = 'fake-glance-id'
self.should_fail = kwargs.get('SHOULD_FAIL', '').lower() == 'true' self.images = get_fake_images_list()
def update(self, **kwargs):
if self.should_fail: class FakeServiceCatalog(object):
raise RuntimeError('This image has SHOULD_FAIL set to True.') def url_for(self, **kwargs):
else: return 'fake-url'
return True
class FakeKeystoneClient(object):
def __init__(self, **kwargs):
self.service_catalog = FakeServiceCatalog()
self.auth_token = 'fake-auth-token'
class FakeFile(StringIO.StringIO): class FakeFile(StringIO.StringIO):

View File

@ -28,7 +28,6 @@ import glanceclient.client
import keystoneclient.v2_0.client as ksclient import keystoneclient.v2_0.client as ksclient
import time import time
import fakeprovider
from nodeutils import iterate_timeout from nodeutils import iterate_timeout
from task_manager import Task, TaskManager, ManagerStoppedException from task_manager import Task, TaskManager, ManagerStoppedException
@ -296,8 +295,6 @@ class ProviderManager(TaskManager):
kwargs['region_name'] = self.provider.region_name kwargs['region_name'] = self.provider.region_name
if self.provider.api_timeout: if self.provider.api_timeout:
kwargs['timeout'] = self.provider.api_timeout kwargs['timeout'] = self.provider.api_timeout
if self.provider.auth_url == 'fake':
return fakeprovider.FAKE_CLIENT
return novaclient.client.Client(*args, **kwargs) return novaclient.client.Client(*args, **kwargs)
def _getFlavors(self): def _getFlavors(self):
@ -503,22 +500,18 @@ class ProviderManager(TaskManager):
def uploadImage(self, image_name, filename, disk_format, container_format, def uploadImage(self, image_name, filename, disk_format, container_format,
meta): meta):
if image_name.startswith('fake-'): # configure glance and upload image. Note the meta flags
image = fakeprovider.FakeGlanceClient(**meta) # are provided as custom glance properties
image.update(data='fake') glanceclient = self.get_glance_client(self.provider)
else: image = glanceclient.images.create(
# configure glance and upload image. Note the meta flags name=image_name,
# are provided as custom glance properties is_public=False,
glanceclient = self.get_glance_client(self.provider) disk_format=disk_format,
image = glanceclient.images.create( container_format=container_format,
name=image_name, **meta)
is_public=False, filename = '%s.%s' % (filename, disk_format)
disk_format=disk_format, image.update(data=open(filename, 'rb'))
container_format=container_format, glanceclient = None
**meta)
filename = '%s.%s' % (filename, disk_format)
image.update(data=open(filename, 'rb'))
glanceclient = None
return image.id return image.id
def listExtensions(self): def listExtensions(self):

View File

@ -29,7 +29,7 @@ import fixtures
import testresources import testresources
import testtools import testtools
from nodepool import nodepool, allocation from nodepool import allocation, fakeprovider, nodepool
TRUE_VALUES = ('true', '1', 'yes') TRUE_VALUES = ('true', '1', 'yes')
@ -76,6 +76,16 @@ class BaseTestCase(testtools.TestCase, testresources.ResourcedTestCase):
self.useFixture(fixtures.MonkeyPatch('subprocess.Popen', self.useFixture(fixtures.MonkeyPatch('subprocess.Popen',
LoggingPopenFactory)) LoggingPopenFactory))
self.setUpFakes()
def setUpFakes(self):
self.useFixture(fixtures.MonkeyPatch('keystoneclient.v2_0.client.'
'Client',
fakeprovider.FakeKeystoneClient))
self.useFixture(fixtures.MonkeyPatch('glanceclient.client.Client',
fakeprovider.FakeGlanceClient))
self.useFixture(fixtures.MonkeyPatch('novaclient.client.Client',
fakeprovider.FakeClient))
def wait_for_threads(self): def wait_for_threads(self):
whitelist = ['APScheduler', whitelist = ['APScheduler',
@ -176,11 +186,14 @@ class DBTestCase(BaseTestCase):
self.dburi = f.dburi self.dburi = f.dburi
def setup_config(self, filename): def setup_config(self, filename):
images_dir = fixtures.TempDir()
self.useFixture(images_dir)
configfile = os.path.join(os.path.dirname(__file__), configfile = os.path.join(os.path.dirname(__file__),
'fixtures', filename) 'fixtures', filename)
config = open(configfile).read() config = open(configfile).read()
(fd, path) = tempfile.mkstemp() (fd, path) = tempfile.mkstemp()
os.write(fd, config.format(dburi=self.dburi)) os.write(fd, config.format(dburi=self.dburi,
images_dir=images_dir.path))
os.close(fd) os.close(fd)
return path return path

View File

@ -38,4 +38,22 @@ if [[ "${BASE_IMAGE_FILE}" != "Fedora-Cloud-Base-20141029-21_Beta.x86_64.qcow2"
exit 1 exit 1
fi fi
outfile=
TEMP=$(getopt -o o: -- "$@")
eval set -- "$TEMP"
while true ; do
case "$1" in
-o) outfile=$2; shift 2;;
--) shift ; break ;;
esac
done
if [ -z "$outfile" ]; then
echo "No output file specified."
exit 1
else
echo "fake-data" > $outfile
fi
echo "*** fake-image-create: done" echo "*** fake-image-create: done"

View File

@ -1,5 +1,6 @@
script-dir: . script-dir: .
dburi: '{dburi}' dburi: '{dburi}'
images-dir: '{images_dir}'
cron: cron:
check: '*/15 * * * *' check: '*/15 * * * *'

View File

@ -1,5 +1,6 @@
script-dir: . script-dir: .
dburi: '{dburi}' dburi: '{dburi}'
images-dir: '{images_dir}'
cron: cron:
check: '*/15 * * * *' check: '*/15 * * * *'

View File

@ -1,5 +1,6 @@
script-dir: . script-dir: .
dburi: '{dburi}' dburi: '{dburi}'
images-dir: '{images_dir}'
cron: cron:
check: '*/15 * * * *' check: '*/15 * * * *'

View File

@ -1,6 +1,6 @@
script-dir: . script-dir: .
elements-dir: . elements-dir: .
images-dir: . images-dir: '{images_dir}'
dburi: '{dburi}' dburi: '{dburi}'

View File

@ -1,6 +1,6 @@
script-dir: . script-dir: .
elements-dir: . elements-dir: .
images-dir: . images-dir: '{images_dir}'
dburi: '{dburi}' dburi: '{dburi}'

View File

@ -1,6 +1,6 @@
script-dir: . script-dir: .
elements-dir: . elements-dir: .
images-dir: . images-dir: '{images_dir}'
dburi: '{dburi}' dburi: '{dburi}'

View File

@ -1,6 +1,6 @@
script-dir: . script-dir: .
elements-dir: . elements-dir: .
images-dir: . images-dir: '{images_dir}'
dburi: '{dburi}' dburi: '{dburi}'

View File

@ -1,5 +1,6 @@
script-dir: . script-dir: .
dburi: '{dburi}' dburi: '{dburi}'
images-dir: '{images_dir}'
cron: cron:
check: '*/15 * * * *' check: '*/15 * * * *'