diff --git a/nova/scheduler/zone_manager.py b/nova/scheduler/zone_manager.py index 0974f271..a6bbc2eb 100644 --- a/nova/scheduler/zone_manager.py +++ b/nova/scheduler/zone_manager.py @@ -68,22 +68,27 @@ class ZoneState(object): marked as offline.""" self.last_exception = exception self.last_exception_time = datetime.now() - logging.warning(_("%s error talking to zone %s") % (exception, - zone.api_url, FLAGS.zone_failures_to_offline)) + logging.warning(_("'%s' error talking to zone %s") % (exception, + self.api_url)) self.attempt += 1 if self.attempt >= FLAGS.zone_failures_to_offline: self.is_active = False logging.error(_("No answer from zone %s after %d " - "attempts. Marking inactive.") % (zone.api_url, + "attempts. Marking inactive.") % (self.api_url, FLAGS.zone_failures_to_offline)) + +def _call_novatools(zone): + """Call novatools. Broken out for testing purposes.""" + os = novatools.OpenStack(zone.username, zone.password, zone.api_url) + return os.zones.info()._info + def _poll_zone(zone): """Eventlet worker to poll a zone.""" logging.debug("_POLL_ZONE: STARTING") - os = novatools.OpenStack(zone.username, zone.password, zone.api_url) try: - zone.update_metadata(os.zones.info()._info) + zone.update_metadata(_call_novatools(zone)) except Exception, e: zone.log_error(e) diff --git a/nova/tests/test_zones.py b/nova/tests/test_zones.py index b4c8815d..2cb070ac 100644 --- a/nova/tests/test_zones.py +++ b/nova/tests/test_zones.py @@ -19,6 +19,7 @@ Tests For ZoneManager import datetime import mox +import novatools from nova import context from nova import db @@ -30,6 +31,8 @@ from nova import utils from nova.auth import manager as auth_manager from nova.scheduler import zone_manager +FLAGS = flags.FLAGS + class FakeZone: """Represents a fake zone from the db""" @@ -38,6 +41,11 @@ class FakeZone: setattr(self, k, v) +def exploding_novatools(zone): + """Used when we want to simulate a novatools call failing.""" + raise Exception("kaboom") + + class ZoneManagerTestCase(test.TestCase): """Test case for zone manager""" def test_ping(self): @@ -130,3 +138,36 @@ class ZoneManagerTestCase(test.TestCase): self.assertEquals(len(zm.zone_states), 1) self.assertEquals(zm.zone_states[2].username, 'user2') + + def test_poll_zone(self): + self.mox.StubOutWithMock(zone_manager, '_call_novatools') + zone_manager._call_novatools(mox.IgnoreArg()).AndReturn( + dict(name='zohan', capabilities='hairdresser')) + + zone_state = zone_manager.ZoneState() + zone_state.update_credentials(FakeZone(id=2, + api_url='http://foo.com', username='user2', + password='pass2')) + zone_state.attempt = 1 + + self.mox.ReplayAll() + zone_manager._poll_zone(zone_state) + self.mox.VerifyAll() + self.assertEquals(zone_state.attempt, 0) + self.assertEquals(zone_state.name, 'zohan') + + def test_poll_zone_fails(self): + self.stubs.Set(zone_manager, "_call_novatools", exploding_novatools) + + zone_state = zone_manager.ZoneState() + zone_state.update_credentials(FakeZone(id=2, + api_url='http://foo.com', username='user2', + password='pass2')) + zone_state.attempt = FLAGS.zone_failures_to_offline - 1 + + self.mox.ReplayAll() + zone_manager._poll_zone(zone_state) + self.mox.VerifyAll() + self.assertEquals(zone_state.attempt, 3) + self.assertFalse(zone_state.is_active) + self.assertEquals(zone_state.name, None)