|
@@ -0,0 +1,115 @@
|
|
|
+# Copyright (C) 2013 Internet Systems Consortium.
|
|
|
+#
|
|
|
+# Permission to use, copy, modify, and distribute this software for any
|
|
|
+# purpose with or without fee is hereby granted, provided that the above
|
|
|
+# copyright notice and this permission notice appear in all copies.
|
|
|
+#
|
|
|
+# THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SYSTEMS CONSORTIUM
|
|
|
+# DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
|
|
|
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
|
|
|
+# INTERNET SYSTEMS CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
|
+# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
|
|
|
+# FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
|
|
|
+# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
|
|
|
+# WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
|
+
|
|
|
+"""
|
|
|
+In this test file, we actually start msgq as a process and test it
|
|
|
+as a whole. It may be considered a system test instead of unit test,
|
|
|
+but apart from the terminology, we don't care much. We need to test
|
|
|
+the message queue works as expected, together with the libraries.
|
|
|
+
|
|
|
+In each test, we first start a timeout (because we do some waits
|
|
|
+for messages and if they wouldn't come, the test could block indefinitely).
|
|
|
+The timeout is long, because it is for the case the test fails.
|
|
|
+
|
|
|
+We then start the msgq and wait for the socket file to appear
|
|
|
+(that should indicate it is ready to receive connections). Then the
|
|
|
+actual test starts. After the test, we kill it and remove the test file.
|
|
|
+
|
|
|
+We also register signal handlers for many signals. Even in the case
|
|
|
+the test is interrupted or crashes, we should ensure the message queue
|
|
|
+itself is terminated.
|
|
|
+"""
|
|
|
+
|
|
|
+import unittest
|
|
|
+import os
|
|
|
+import signal
|
|
|
+import sys
|
|
|
+import subprocess
|
|
|
+import time
|
|
|
+
|
|
|
+import isc.log
|
|
|
+
|
|
|
+SOCKET_PATH = os.path.abspath(os.environ['BIND10_TEST_SOCKET_FILE'])
|
|
|
+MSGQ_PATH = os.environ['B10_FROM_BUILD'] + '/src/bin/msgq/run_msgq.sh'
|
|
|
+TIMEOUT = 15 # Some long time (seconds), for single test.
|
|
|
+
|
|
|
+class MsgqRunTest(unittest.TestCase):
|
|
|
+ def setUp(self):
|
|
|
+ """
|
|
|
+ As described above - check the socket file does not exist.
|
|
|
+ Then register signals and timeouts. Finally, launch msgq
|
|
|
+ and wait for it to start.
|
|
|
+ """
|
|
|
+ self.__msgq = None
|
|
|
+ # A precondition check
|
|
|
+ self.assertFalse(os.path.exists(SOCKET_PATH))
|
|
|
+ signal.alarm(TIMEOUT)
|
|
|
+ self.__orig_signals = {}
|
|
|
+ # Register handlers for many signals. Most of them probably
|
|
|
+ # can't happen in python, but we register them anyway just to be
|
|
|
+ # safe.
|
|
|
+ for sig in [signal.SIGHUP, signal.SIGINT, signal.SIGQUIT,
|
|
|
+ signal.SIGILL, signal.SIGTRAP, signal.SIGABRT, signal.SIGBUS,
|
|
|
+ signal.SIGFPE, signal.SIGALRM, signal.SIGTERM]:
|
|
|
+ self.__orig_signals[sig] = signal.signal(sig, self.__signal)
|
|
|
+ # Start msgq
|
|
|
+ self.__msgq = subprocess.Popen([MSGQ_PATH, '-s', SOCKET_PATH],
|
|
|
+ close_fds=True)
|
|
|
+ # Wait for it to become ready (up to the alarm-set timeout)
|
|
|
+ while not os.path.exists(SOCKET_PATH):
|
|
|
+ # Just a short wait, so we don't hog CPU, but don't wait too long
|
|
|
+ time.sleep(0.01)
|
|
|
+
|
|
|
+ def tearDown(self):
|
|
|
+ """
|
|
|
+ Perform cleanup after the test.
|
|
|
+ """
|
|
|
+ self.__cleanup()
|
|
|
+
|
|
|
+ def __signal(self, signal, frame):
|
|
|
+ """
|
|
|
+ Called from a signal handler. We perform some cleanup, output
|
|
|
+ a complain and terminate with error.
|
|
|
+ """
|
|
|
+ self.__cleanup()
|
|
|
+ sys.stderr.write("Test terminating from signal " + str(signal) +
|
|
|
+ " in " + str(frame) + "\n")
|
|
|
+ sys.exit(1)
|
|
|
+
|
|
|
+ def __cleanup(self):
|
|
|
+ """
|
|
|
+ Kill msgq (if running) and restore original signal handlers.
|
|
|
+ """
|
|
|
+ # Remove the socket (as we kill, msgq might not clean up)
|
|
|
+ if self.__msgq:
|
|
|
+ self.__msgq.kill()
|
|
|
+ self.__msgq = None
|
|
|
+ if os.path.exists(SOCKET_PATH):
|
|
|
+ os.unlink(SOCKET_PATH)
|
|
|
+ for sig in self.__orig_signals:
|
|
|
+ signal.signal(sig, self.__orig_signals[sig])
|
|
|
+ # Cancel timeout (so someone else is not hit by it)
|
|
|
+ signal.alarm(0)
|
|
|
+
|
|
|
+ def test_empty_run(self):
|
|
|
+ """
|
|
|
+ Temporary empty test, to see if we can start and stop msgq.
|
|
|
+ Testing the test harness.
|
|
|
+ """
|
|
|
+ pass
|
|
|
+
|
|
|
+if __name__ == '__main__':
|
|
|
+ isc.log.resetUnitTestRootLogger()
|
|
|
+ unittest.main()
|