|
@@ -0,0 +1,167 @@
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+from init import ProcessInfo, parse_args, dump_pid, unlink_pid_file, _BASETIME
|
|
|
|
+
|
|
|
|
+import unittest
|
|
|
|
+import sys
|
|
|
|
+import os
|
|
|
|
+import signal
|
|
|
|
+import socket
|
|
|
|
+from isc.net.addr import IPAddr
|
|
|
|
+import time
|
|
|
|
+import isc
|
|
|
|
+import fcntl
|
|
|
|
+
|
|
|
|
+class TestD2Daemon(unittest.TestCase):
|
|
|
|
+ def setUp(self):
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ lockdir_envvar = "B10_LOCKFILE_DIR_FROM_BUILD"
|
|
|
|
+ if lockdir_envvar not in os.environ:
|
|
|
|
+ os.environ[lockdir_envvar] = os.getcwd()
|
|
|
|
+
|
|
|
|
+ def tearDown(self):
|
|
|
|
+ pass
|
|
|
|
+
|
|
|
|
+ def readPipe(self, pipe_fd):
|
|
|
|
+ """
|
|
|
|
+ Reads bytes from a pipe and returns a character string. If nothing is
|
|
|
|
+ read, or if there is an error, an empty string is returned.
|
|
|
|
+
|
|
|
|
+ pipe_fd - Pipe file descriptor to read
|
|
|
|
+ """
|
|
|
|
+ try:
|
|
|
|
+ data = os.read(pipe_fd, 16384)
|
|
|
|
+
|
|
|
|
+ if (data is None):
|
|
|
|
+ data = ""
|
|
|
|
+ else:
|
|
|
|
+ data = str(data)
|
|
|
|
+ except OSError:
|
|
|
|
+ data = ""
|
|
|
|
+
|
|
|
|
+ return data
|
|
|
|
+
|
|
|
|
+ def runCommand(self, params, wait=1):
|
|
|
|
+ """
|
|
|
|
+ This method runs a command and returns a tuple: (returncode, stdout, stderr)
|
|
|
|
+ """
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ print("Running command: %s" % (" ".join(params)))
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ self.stdout_old = os.dup(sys.stdout.fileno())
|
|
|
|
+ self.stdout_pipes = os.pipe()
|
|
|
|
+ os.dup2(self.stdout_pipes[1], sys.stdout.fileno())
|
|
|
|
+ os.close(self.stdout_pipes[1])
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ self.stderr_old = os.dup(sys.stderr.fileno())
|
|
|
|
+ self.stderr_pipes = os.pipe()
|
|
|
|
+ os.dup2(self.stderr_pipes[1], sys.stderr.fileno())
|
|
|
|
+ os.close(self.stderr_pipes[1])
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ pi = ProcessInfo('Test Process', params)
|
|
|
|
+ pi.spawn()
|
|
|
|
+ time.sleep(wait)
|
|
|
|
+ os.dup2(self.stdout_old, sys.stdout.fileno())
|
|
|
|
+ os.dup2(self.stderr_old, sys.stderr.fileno())
|
|
|
|
+ self.assertNotEqual(pi.process, None)
|
|
|
|
+ self.assertTrue(type(pi.pid) is int)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ fd = self.stdout_pipes[0]
|
|
|
|
+ fl = fcntl.fcntl(fd, fcntl.F_GETFL)
|
|
|
|
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
|
|
|
|
+
|
|
|
|
+ fd = self.stderr_pipes[0]
|
|
|
|
+ fl = fcntl.fcntl(fd, fcntl.F_GETFL)
|
|
|
|
+ fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ for count in range(20):
|
|
|
|
+
|
|
|
|
+ output = self.readPipe(self.stdout_pipes[0])
|
|
|
|
+ error = self.readPipe(self.stderr_pipes[0])
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if pi.process.poll() is not None or len(error) > 0 or len(output) > 0:
|
|
|
|
+ break
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ time.sleep(0.25)
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if pi.process.poll() is None:
|
|
|
|
+ try:
|
|
|
|
+ pi.process.terminate()
|
|
|
|
+ except OSError:
|
|
|
|
+ print("Ignoring failed kill attempt. Process is dead already.")
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ rc = pi.process.wait()
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ os.dup2(self.stdout_old, sys.stdout.fileno())
|
|
|
|
+ os.close(self.stdout_old)
|
|
|
|
+ os.close(self.stdout_pipes[0])
|
|
|
|
+
|
|
|
|
+ os.dup2(self.stderr_old, sys.stderr.fileno())
|
|
|
|
+ os.close(self.stderr_old)
|
|
|
|
+ os.close(self.stderr_pipes[0])
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ pi = None
|
|
|
|
+
|
|
|
|
+ print ("Process finished, return code=%d, stdout=%d bytes, stderr=%d bytes"
|
|
|
|
+ % (rc, len(output), len(error)) )
|
|
|
|
+
|
|
|
|
+ return (rc, output, error)
|
|
|
|
+
|
|
|
|
+ def test_alive(self):
|
|
|
|
+ print("Note: Simple test to verify that D2 server can be started.")
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ (returncode, output, error) = self.runCommand(["../b10-d2", "-s"])
|
|
|
|
+ output_text = str(output) + str(error)
|
|
|
|
+ self.assertEqual(output_text.count("D2_STARTING"), 1)
|
|
|
|
+
|
|
|
|
+if __name__ == '__main__':
|
|
|
|
+ unittest.main()
|