|
@@ -19,6 +19,7 @@ Tests for the bind10.component module
|
|
|
|
|
|
import unittest
|
|
|
import isc.log
|
|
|
+import time
|
|
|
from isc.bind10.component import Component
|
|
|
|
|
|
class ComponentTests(unittest.TestCase):
|
|
@@ -34,6 +35,8 @@ class ComponentTests(unittest.TestCase):
|
|
|
self.__start_called = False
|
|
|
self.__stop_called = False
|
|
|
self.__failed_called = False
|
|
|
+ # Back up the time function, we may want to replace it with something
|
|
|
+ self.__orig_time = isc.bind10.component.time.time
|
|
|
|
|
|
def shutdown(self, exitcode=0):
|
|
|
"""
|
|
@@ -41,6 +44,17 @@ class ComponentTests(unittest.TestCase):
|
|
|
"""
|
|
|
self.__shutdown = True
|
|
|
self.__exitcode = None
|
|
|
+ # Return the original time function
|
|
|
+ isc.bind10.component.time.time = self.__orig_time
|
|
|
+
|
|
|
+ def timeskip(self):
|
|
|
+ """
|
|
|
+ Skip in time to future some 30s. Implemented by replacing the
|
|
|
+ time.time function in the tested module with function that returns
|
|
|
+ current time increased by 30.
|
|
|
+ """
|
|
|
+ tm = time.time()
|
|
|
+ isc.bind10.component.time.time = lambda: tm + 30
|
|
|
|
|
|
def start(self):
|
|
|
"""
|
|
@@ -78,28 +92,56 @@ class ComponentTests(unittest.TestCase):
|
|
|
component.failed_internal = self.fail
|
|
|
return component
|
|
|
|
|
|
- def do_start_stop(self, kind):
|
|
|
+ def check_startup(self, component):
|
|
|
"""
|
|
|
- This is a body of a test. It creates a componend of given kind,
|
|
|
- then starts it and stops it. It checks correct functions are called
|
|
|
- and the component's status is correct.
|
|
|
-
|
|
|
- It also checks the component can't be started/stopped twice.
|
|
|
+ Check that nothing was called yet. A newly created component should
|
|
|
+ not get started right away, so this should pass after the creation.
|
|
|
"""
|
|
|
- # Create it and check it did not do any funny stuff yet
|
|
|
- component = self.create_component(kind)
|
|
|
self.assertFalse(self.__shutdown)
|
|
|
self.assertFalse(self.__start_called)
|
|
|
self.assertFalse(self.__stop_called)
|
|
|
self.assertFalse(self.__failed_called)
|
|
|
self.assertFalse(component.running())
|
|
|
- # Start it and check it called the correct starting functions
|
|
|
- component.start()
|
|
|
+
|
|
|
+ def check_started(self, component):
|
|
|
+ """
|
|
|
+ Check the component was started, but not stopped anyhow yet.
|
|
|
+ """
|
|
|
self.assertFalse(self.__shutdown)
|
|
|
self.assertTrue(self.__start_called)
|
|
|
self.assertFalse(self.__stop_called)
|
|
|
self.assertFalse(self.__failed_called)
|
|
|
self.assertTrue(component.running())
|
|
|
+
|
|
|
+ def check_dead(self, component):
|
|
|
+ """
|
|
|
+ Check the component is completely dead, and the server too.
|
|
|
+ """
|
|
|
+ self.assertTrue(self.__shutdown)
|
|
|
+ self.assertTrue(self.__start_called)
|
|
|
+ self.assertFalse(self.__stop_called)
|
|
|
+ self.assertTrue(self.__failed_called)
|
|
|
+ self.assertNotEqual(0, self.__exitcode)
|
|
|
+ self.assertFalse(component.running())
|
|
|
+ # Surely it can't be stopped again
|
|
|
+ self.assertRaises(ValueError, component.stop)
|
|
|
+ # Nor started
|
|
|
+ self.assertRaises(ValueError, component.start)
|
|
|
+
|
|
|
+ def do_start_stop(self, kind):
|
|
|
+ """
|
|
|
+ This is a body of a test. It creates a componend of given kind,
|
|
|
+ then starts it and stops it. It checks correct functions are called
|
|
|
+ and the component's status is correct.
|
|
|
+
|
|
|
+ It also checks the component can't be started/stopped twice.
|
|
|
+ """
|
|
|
+ # Create it and check it did not do any funny stuff yet
|
|
|
+ component = self.create_component(kind)
|
|
|
+ self.check_startup(component)
|
|
|
+ # Start it and check it called the correct starting functions
|
|
|
+ component.start()
|
|
|
+ self.check_started(component)
|
|
|
# Check it can't be started twice
|
|
|
self.assertRaises(ValueError, component.start)
|
|
|
# Stop it again and check
|
|
@@ -131,6 +173,36 @@ class ComponentTests(unittest.TestCase):
|
|
|
"""
|
|
|
self.do_start_stop('dispensable')
|
|
|
|
|
|
+ def test_start_fail_core(self):
|
|
|
+ """
|
|
|
+ Start and then fail a core component. It should stop the whole server.
|
|
|
+ """
|
|
|
+ # Just ordinary startup
|
|
|
+ component = self.create_component('core')
|
|
|
+ self.check_startup(component)
|
|
|
+ component.start()
|
|
|
+ self.check_started(component)
|
|
|
+ # Pretend the component died
|
|
|
+ component.failed()
|
|
|
+ # It should bring down the whole server
|
|
|
+ self.check_dead(component)
|
|
|
+
|
|
|
+ def test_start_fail_core_later(self):
|
|
|
+ """
|
|
|
+ Start and then fail a core component, but let it be running for longer time.
|
|
|
+ It should still stop the whole server.
|
|
|
+ """
|
|
|
+ # Just ordinary startup
|
|
|
+ component = self.create_component('core')
|
|
|
+ self.check_startup(component)
|
|
|
+ component.start()
|
|
|
+ self.check_started(component)
|
|
|
+ self.timeskip()
|
|
|
+ # Pretend the componend died some time later
|
|
|
+ component.failed()
|
|
|
+ # Check the component is still dead
|
|
|
+ self.check_dead(component)
|
|
|
+
|
|
|
if __name__ == '__main__':
|
|
|
isc.log.init("bind10") # FIXME Should this be needed?
|
|
|
isc.log.resetUnitTestRootLogger()
|