Merge with trunk

This commit is contained in:
Johannes Erdfelt
2011-06-15 14:33:52 +00:00
9 changed files with 109 additions and 40 deletions

View File

@@ -270,8 +270,10 @@ DEFINE_list('region_list',
DEFINE_string('connection_type', 'libvirt', 'libvirt, xenapi or fake') DEFINE_string('connection_type', 'libvirt', 'libvirt, xenapi or fake')
DEFINE_string('aws_access_key_id', 'admin', 'AWS Access ID') DEFINE_string('aws_access_key_id', 'admin', 'AWS Access ID')
DEFINE_string('aws_secret_access_key', 'admin', 'AWS Access Key') DEFINE_string('aws_secret_access_key', 'admin', 'AWS Access Key')
DEFINE_integer('glance_port', 9292, 'glance port') # NOTE(sirp): my_ip interpolation doesn't work within nested structures
DEFINE_string('glance_host', '$my_ip', 'glance host') DEFINE_list('glance_api_servers',
['127.0.0.1:9292'],
'list of glance api servers available to nova (host:port)')
DEFINE_integer('s3_port', 3333, 's3 port') DEFINE_integer('s3_port', 3333, 's3 port')
DEFINE_string('s3_host', '$my_ip', 's3 host (for infrastructure)') DEFINE_string('s3_host', '$my_ip', 's3 host (for infrastructure)')
DEFINE_string('s3_dmz', '$my_ip', 's3 dmz ip (for instances)') DEFINE_string('s3_dmz', '$my_ip', 's3 dmz ip (for instances)')

View File

@@ -111,7 +111,8 @@ def _process(func, zone):
return func(nova, zone) return func(nova, zone)
def call_zone_method(context, method, errors_to_ignore=None, *args, **kwargs): def call_zone_method(context, method_name, errors_to_ignore=None,
novaclient_collection_name='zones', *args, **kwargs):
"""Returns a list of (zone, call_result) objects.""" """Returns a list of (zone, call_result) objects."""
if not isinstance(errors_to_ignore, (list, tuple)): if not isinstance(errors_to_ignore, (list, tuple)):
# This will also handle the default None # This will also handle the default None
@@ -131,18 +132,16 @@ def call_zone_method(context, method, errors_to_ignore=None, *args, **kwargs):
#TODO (dabo) - add logic for failure counts per zone, #TODO (dabo) - add logic for failure counts per zone,
# with escalation after a given number of failures. # with escalation after a given number of failures.
continue continue
zone_method = getattr(nova.zones, method) novaclient_collection = getattr(nova, novaclient_collection_name)
collection_method = getattr(novaclient_collection, method_name)
def _error_trap(*args, **kwargs): def _error_trap(*args, **kwargs):
try: try:
return zone_method(*args, **kwargs) return collection_method(*args, **kwargs)
except Exception as e: except Exception as e:
if type(e) in errors_to_ignore: if type(e) in errors_to_ignore:
return None return None
# TODO (dabo) - want to be able to re-raise here. raise
# Returning a string now; raising was causing issues.
# raise e
return "ERROR", "%s" % e
res = pool.spawn(_error_trap, *args, **kwargs) res = pool.spawn(_error_trap, *args, **kwargs)
results.append((zone, res)) results.append((zone, res))

View File

@@ -91,6 +91,7 @@ class ZoneAwareScheduler(driver.Scheduler):
image_id = instance_properties['image_id'] image_id = instance_properties['image_id']
meta = instance_properties['metadata'] meta = instance_properties['metadata']
flavor_id = instance_type['flavorid'] flavor_id = instance_type['flavorid']
reservation_id = instance_properties['reservation_id']
files = kwargs['injected_files'] files = kwargs['injected_files']
ipgroup = None # Not supported in OS API ... yet ipgroup = None # Not supported in OS API ... yet
@@ -99,7 +100,8 @@ class ZoneAwareScheduler(driver.Scheduler):
child_blob = zone_info['child_blob'] child_blob = zone_info['child_blob']
zone = db.zone_get(context, child_zone) zone = db.zone_get(context, child_zone)
url = zone.api_url url = zone.api_url
LOG.debug(_("Forwarding instance create call to child zone %(url)s") LOG.debug(_("Forwarding instance create call to child zone %(url)s"
". ReservationID=%(reservation_id)s")
% locals()) % locals())
nova = None nova = None
try: try:
@@ -110,7 +112,7 @@ class ZoneAwareScheduler(driver.Scheduler):
"to talk to zone at %(url)s.") % locals()) "to talk to zone at %(url)s.") % locals())
nova.servers.create(name, image_id, flavor_id, ipgroup, meta, files, nova.servers.create(name, image_id, flavor_id, ipgroup, meta, files,
child_blob) child_blob, reservation_id=reservation_id)
def _provision_resource_from_blob(self, context, item, instance_id, def _provision_resource_from_blob(self, context, item, instance_id,
request_spec, kwargs): request_spec, kwargs):

View File

@@ -133,11 +133,11 @@ class HostFilterTestCase(test.TestCase):
raw = ['or', raw = ['or',
['and', ['and',
['<', '$compute.host_memory_free', 30], ['<', '$compute.host_memory_free', 30],
['<', '$compute.disk_available', 300] ['<', '$compute.disk_available', 300],
], ],
['and', ['and',
['>', '$compute.host_memory_free', 70], ['>', '$compute.host_memory_free', 70],
['>', '$compute.disk_available', 700] ['>', '$compute.disk_available', 700],
] ]
] ]
cooked = json.dumps(raw) cooked = json.dumps(raw)
@@ -183,12 +183,12 @@ class HostFilterTestCase(test.TestCase):
self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps([]))) self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps([])))
self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps({}))) self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps({})))
self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps( self.assertTrue(hf.filter_hosts(self.zone_manager, json.dumps(
['not', True, False, True, False] ['not', True, False, True, False],
))) )))
try: try:
hf.filter_hosts(self.zone_manager, json.dumps( hf.filter_hosts(self.zone_manager, json.dumps(
'not', True, False, True, False 'not', True, False, True, False,
)) ))
self.fail("Should give KeyError") self.fail("Should give KeyError")
except KeyError, e: except KeyError, e:

View File

@@ -44,7 +44,7 @@ class WeightedSumTestCase(test.TestCase):
hosts = [ hosts = [
FakeHost(1, 512 * MB, 100), FakeHost(1, 512 * MB, 100),
FakeHost(2, 256 * MB, 400), FakeHost(2, 256 * MB, 400),
FakeHost(3, 512 * MB, 100) FakeHost(3, 512 * MB, 100),
] ]
weighted_fns = [ weighted_fns = [
@@ -96,7 +96,7 @@ class LeastCostSchedulerTestCase(test.TestCase):
def test_noop_cost_fn(self): def test_noop_cost_fn(self):
FLAGS.least_cost_scheduler_cost_functions = [ FLAGS.least_cost_scheduler_cost_functions = [
'nova.scheduler.least_cost.noop_cost_fn' 'nova.scheduler.least_cost.noop_cost_fn',
] ]
FLAGS.noop_cost_fn_weight = 1 FLAGS.noop_cost_fn_weight = 1
@@ -110,7 +110,7 @@ class LeastCostSchedulerTestCase(test.TestCase):
def test_cost_fn_weights(self): def test_cost_fn_weights(self):
FLAGS.least_cost_scheduler_cost_functions = [ FLAGS.least_cost_scheduler_cost_functions = [
'nova.scheduler.least_cost.noop_cost_fn' 'nova.scheduler.least_cost.noop_cost_fn',
] ]
FLAGS.noop_cost_fn_weight = 2 FLAGS.noop_cost_fn_weight = 2
@@ -124,7 +124,7 @@ class LeastCostSchedulerTestCase(test.TestCase):
def test_fill_first_cost_fn(self): def test_fill_first_cost_fn(self):
FLAGS.least_cost_scheduler_cost_functions = [ FLAGS.least_cost_scheduler_cost_functions = [
'nova.scheduler.least_cost.fill_first_cost_fn' 'nova.scheduler.least_cost.fill_first_cost_fn',
] ]
FLAGS.fill_first_cost_fn_weight = 1 FLAGS.fill_first_cost_fn_weight = 1

View File

@@ -201,7 +201,7 @@ class ZoneAwareSchedulerTestCase(test.TestCase):
'instance_properties': {}, 'instance_properties': {},
'instance_type': {}, 'instance_type': {},
'filter_driver': 'nova.scheduler.host_filter.AllHostsFilter', 'filter_driver': 'nova.scheduler.host_filter.AllHostsFilter',
'blob': "Non-None blob data" 'blob': "Non-None blob data",
} }
result = sched.schedule_run_instance(None, 1, request_spec) result = sched.schedule_run_instance(None, 1, request_spec)

View File

@@ -115,6 +115,18 @@ class CloudTestCase(test.TestCase):
public_ip=address) public_ip=address)
db.floating_ip_destroy(self.context, address) db.floating_ip_destroy(self.context, address)
def test_allocate_address(self):
address = "10.10.10.10"
allocate = self.cloud.allocate_address
db.floating_ip_create(self.context,
{'address': address,
'host': self.network.host})
self.assertEqual(allocate(self.context)['publicIp'], address)
db.floating_ip_destroy(self.context, address)
self.assertRaises(exception.NoMoreFloatingIps,
allocate,
self.context)
def test_associate_disassociate_address(self): def test_associate_disassociate_address(self):
"""Verifies associate runs cleanly without raising an exception""" """Verifies associate runs cleanly without raising an exception"""
address = "10.10.10.10" address = "10.10.10.10"

View File

@@ -331,7 +331,7 @@ class XenAPIVMTestCase(test.TestCase):
def check_vm_params_for_linux(self): def check_vm_params_for_linux(self):
self.assertEquals(self.vm['platform']['nx'], 'false') self.assertEquals(self.vm['platform']['nx'], 'false')
self.assertEquals(self.vm['PV_args'], 'clocksource=jiffies') self.assertEquals(self.vm['PV_args'], '')
self.assertEquals(self.vm['PV_bootloader'], 'pygrub') self.assertEquals(self.vm['PV_bootloader'], 'pygrub')
# check that these are not set # check that these are not set

View File

@@ -56,9 +56,11 @@ To run a single test module:
""" """
import gettext import gettext
import heapq
import os import os
import unittest import unittest
import sys import sys
import time
gettext.install('nova', unicode=1) gettext.install('nova', unicode=1)
@@ -183,9 +185,21 @@ class _NullColorizer(object):
self.stream.write(text) self.stream.write(text)
def get_elapsed_time_color(elapsed_time):
if elapsed_time > 1.0:
return 'red'
elif elapsed_time > 0.25:
return 'yellow'
else:
return 'green'
class NovaTestResult(result.TextTestResult): class NovaTestResult(result.TextTestResult):
def __init__(self, *args, **kw): def __init__(self, *args, **kw):
self.show_elapsed = kw.pop('show_elapsed')
result.TextTestResult.__init__(self, *args, **kw) result.TextTestResult.__init__(self, *args, **kw)
self.num_slow_tests = 5
self.slow_tests = [] # this is a fixed-sized heap
self._last_case = None self._last_case = None
self.colorizer = None self.colorizer = None
# NOTE(vish): reset stdout for the terminal check # NOTE(vish): reset stdout for the terminal check
@@ -200,25 +214,40 @@ class NovaTestResult(result.TextTestResult):
def getDescription(self, test): def getDescription(self, test):
return str(test) return str(test)
def _handleElapsedTime(self, test):
self.elapsed_time = time.time() - self.start_time
item = (self.elapsed_time, test)
# Record only the n-slowest tests using heap
if len(self.slow_tests) >= self.num_slow_tests:
heapq.heappushpop(self.slow_tests, item)
else:
heapq.heappush(self.slow_tests, item)
def _writeElapsedTime(self, test):
color = get_elapsed_time_color(self.elapsed_time)
self.colorizer.write(" %.2f" % self.elapsed_time, color)
def _writeResult(self, test, long_result, color, short_result, success):
if self.showAll:
self.colorizer.write(long_result, color)
if self.show_elapsed and success:
self._writeElapsedTime(test)
self.stream.writeln()
elif self.dots:
self.stream.write(short_result)
self.stream.flush()
# NOTE(vish): copied from unittest with edit to add color # NOTE(vish): copied from unittest with edit to add color
def addSuccess(self, test): def addSuccess(self, test):
unittest.TestResult.addSuccess(self, test) unittest.TestResult.addSuccess(self, test)
if self.showAll: self._handleElapsedTime(test)
self.colorizer.write("OK", 'green') self._writeResult(test, 'OK', 'green', '.', True)
self.stream.writeln()
elif self.dots:
self.stream.write('.')
self.stream.flush()
# NOTE(vish): copied from unittest with edit to add color # NOTE(vish): copied from unittest with edit to add color
def addFailure(self, test, err): def addFailure(self, test, err):
unittest.TestResult.addFailure(self, test, err) unittest.TestResult.addFailure(self, test, err)
if self.showAll: self._handleElapsedTime(test)
self.colorizer.write("FAIL", 'red') self._writeResult(test, 'FAIL', 'red', 'F', False)
self.stream.writeln()
elif self.dots:
self.stream.write('F')
self.stream.flush()
# NOTE(vish): copied from nose with edit to add color # NOTE(vish): copied from nose with edit to add color
def addError(self, test, err): def addError(self, test, err):
@@ -226,6 +255,7 @@ class NovaTestResult(result.TextTestResult):
errorClasses. If the exception is a registered class, the errorClasses. If the exception is a registered class, the
error will be added to the list for that class, not errors. error will be added to the list for that class, not errors.
""" """
self._handleElapsedTime(test)
stream = getattr(self, 'stream', None) stream = getattr(self, 'stream', None)
ec, ev, tb = err ec, ev, tb = err
try: try:
@@ -252,14 +282,11 @@ class NovaTestResult(result.TextTestResult):
self.errors.append((test, exc_info)) self.errors.append((test, exc_info))
test.passed = False test.passed = False
if stream is not None: if stream is not None:
if self.showAll: self._writeResult(test, 'ERROR', 'red', 'E', False)
self.colorizer.write("ERROR", 'red')
self.stream.writeln()
elif self.dots:
stream.write('E')
def startTest(self, test): def startTest(self, test):
unittest.TestResult.startTest(self, test) unittest.TestResult.startTest(self, test)
self.start_time = time.time()
current_case = test.test.__class__.__name__ current_case = test.test.__class__.__name__
if self.showAll: if self.showAll:
@@ -273,21 +300,47 @@ class NovaTestResult(result.TextTestResult):
class NovaTestRunner(core.TextTestRunner): class NovaTestRunner(core.TextTestRunner):
def __init__(self, *args, **kwargs):
self.show_elapsed = kwargs.pop('show_elapsed')
core.TextTestRunner.__init__(self, *args, **kwargs)
def _makeResult(self): def _makeResult(self):
return NovaTestResult(self.stream, return NovaTestResult(self.stream,
self.descriptions, self.descriptions,
self.verbosity, self.verbosity,
self.config) self.config,
show_elapsed=self.show_elapsed)
def _writeSlowTests(self, result_):
# Pare out 'fast' tests
slow_tests = [item for item in result_.slow_tests
if get_elapsed_time_color(item[0]) != 'green']
if slow_tests:
slow_total_time = sum(item[0] for item in slow_tests)
self.stream.writeln("Slowest %i tests took %.2f secs:"
% (len(slow_tests), slow_total_time))
for elapsed_time, test in sorted(slow_tests, reverse=True):
time_str = "%.2f" % elapsed_time
self.stream.writeln(" %s %s" % (time_str.ljust(10), test))
def run(self, test):
result_ = core.TextTestRunner.run(self, test)
if self.show_elapsed:
self._writeSlowTests(result_)
return result_
if __name__ == '__main__': if __name__ == '__main__':
logging.setup() logging.setup()
# If any argument looks like a test name but doesn't have "nova.tests" in # If any argument looks like a test name but doesn't have "nova.tests" in
# front of it, automatically add that so we don't have to type as much # front of it, automatically add that so we don't have to type as much
show_elapsed = True
argv = [] argv = []
for x in sys.argv: for x in sys.argv:
if x.startswith('test_'): if x.startswith('test_'):
argv.append('nova.tests.%s' % x) argv.append('nova.tests.%s' % x)
elif x.startswith('--hide-elapsed'):
show_elapsed = False
else: else:
argv.append(x) argv.append(x)
@@ -300,5 +353,6 @@ if __name__ == '__main__':
runner = NovaTestRunner(stream=c.stream, runner = NovaTestRunner(stream=c.stream,
verbosity=c.verbosity, verbosity=c.verbosity,
config=c) config=c,
show_elapsed=show_elapsed)
sys.exit(not core.run(config=c, testRunner=runner, argv=argv)) sys.exit(not core.run(config=c, testRunner=runner, argv=argv))