From: Thomas Markwalder Date: Tue, 14 May 2013 20:53:39 +0000 (-0400) Subject: [2954] Created the initial server source directory, configuration, X-Git-Tag: bind10-1.2.0beta1-release~461^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e448bbba3ecae68b261612954aa9777edc384be4;p=thirdparty%2Fkea.git [2954] Created the initial server source directory, configuration, and make files; and process framework for the DHCP-DDNS daemon, b10-d2srv. --- diff --git a/configure.ac b/configure.ac index 159841f439..9201c5d94f 100644 --- a/configure.ac +++ b/configure.ac @@ -891,9 +891,6 @@ if test X$use_shared_memory = Xyes -a "$BOOST_MAPPED_FILE_WOULDFAIL" = "yes"; th AC_MSG_ERROR([Boost shared memory does not compile on this system. If you don't need it (most normal users won't) build without it by rerunning this script with --without-shared-memory; using a different compiler or a different version of Boost may also help.]) fi AM_CONDITIONAL([USE_SHARED_MEMORY], [test x$use_shared_memory = xyes]) -if test "x$use_shared_memory" = "xyes"; then - AC_DEFINE(USE_SHARED_MEMORY, 1, [Define to 1 if shared memory support is enabled]) -fi AC_SUBST(BOOST_MAPPED_FILE_CXXFLAG) # Add some default CPP flags needed for Boost, identified by the AX macro. @@ -1204,6 +1201,8 @@ AC_CONFIG_FILES([Makefile src/bin/dhcp6/tests/Makefile src/bin/dhcp4/Makefile src/bin/dhcp4/tests/Makefile + src/bin/d2srv/Makefile + src/bin/d2srv/tests/Makefile src/bin/resolver/Makefile src/bin/resolver/tests/Makefile src/bin/resolver/bench/Makefile @@ -1382,6 +1381,7 @@ AC_OUTPUT([doc/version.ent src/bin/auth/gen-statisticsitems.py.pre src/bin/dhcp4/spec_config.h.pre src/bin/dhcp6/spec_config.h.pre + src/bin/d2srv/spec_config.h.pre src/bin/tests/process_rename_test.py src/lib/config/tests/data_def_unittests_config.h src/lib/python/isc/config/tests/config_test diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 0b4c1ae796..7951b4cf98 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -1,5 +1,5 @@ SUBDIRS = bind10 bindctl cfgmgr ddns loadzone msgq cmdctl auth xfrin \ - xfrout usermgr zonemgr stats tests resolver sockcreator dhcp4 dhcp6 \ + xfrout usermgr zonemgr stats tests resolver sockcreator dhcp4 dhcp6 d2srv\ dbutil sysinfo check-recursive: all-recursive diff --git a/src/bin/d2srv/Makefile.am b/src/bin/d2srv/Makefile.am new file mode 100644 index 0000000000..6040cc5218 --- /dev/null +++ b/src/bin/d2srv/Makefile.am @@ -0,0 +1,65 @@ +SUBDIRS = . tests + +AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib +AM_CPPFLAGS += -I$(top_srcdir)/src/bin -I$(top_builddir)/src/bin +AM_CPPFLAGS += $(BOOST_INCLUDES) + +AM_CXXFLAGS = $(B10_CXXFLAGS) +if USE_CLANGPP +# Disable unused parameter warning caused by some Boost headers when compiling with clang +AM_CXXFLAGS += -Wno-unused-parameter +endif + +if USE_STATIC_LINK +AM_LDFLAGS = -static +endif + +pkglibexecdir = $(libexecdir)/@PACKAGE@ + +CLEANFILES = *.gcno *.gcda spec_config.h d2_srv_messages.h d2_srv_messages.cc + +man_MANS = b10-d2srv.8 +DISTCLEANFILES = $(man_MANS) +EXTRA_DIST = $(man_MANS) b10-d2srv.xml d2srv.spec + +if GENERATE_DOCS +b10-d2srv.8: b10-d2srv.xml + @XSLTPROC@ --novalid --xinclude --nonet -o $@ \ + http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl \ + $(srcdir)/b10-d2srv.xml + +else + +$(man_MANS): + @echo Man generation disabled. Creating dummy $@. Configure with --enable-generate-docs to enable it. + @echo Man generation disabled. Remove this file, configure with --enable-generate-docs, and rebuild BIND 10 > $@ + +endif + +spec_config.h: spec_config.h.pre + $(SED) -e "s|@@LOCALSTATEDIR@@|$(localstatedir)|" spec_config.h.pre >$@ + +d2srv_messages.h d2srv_messages.cc: d2srv_messages.mes + $(top_builddir)/src/lib/log/compiler/message $(top_srcdir)/src/bin/d2srv/d2srv_messages.mes + +BUILT_SOURCES = spec_config.h d2srv_messages.h d2srv_messages.cc + +pkglibexec_PROGRAMS = b10-d2srv + +b10_d2srv_SOURCES = main.cc +b10_d2srv_SOURCES += d2srv_log.cc d2srv_log.h + +nodist_b10_d2srv_SOURCES = d2srv_messages.h d2srv_messages.cc +EXTRA_DIST += d2srv_messages.mes + +b10_d2srv_LDADD = $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la +b10_d2srv_LDADD += $(top_builddir)/src/lib/util/libb10-util.la +b10_d2srv_LDADD += $(top_builddir)/src/lib/dhcpsrv/libb10-dhcpsrv.la +b10_d2srv_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la +b10_d2srv_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la +b10_d2srv_LDADD += $(top_builddir)/src/lib/log/libb10-log.la +b10_d2srv_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la +b10_d2srv_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la + +b10_d2srvdir = $(pkgdatadir) +b10_d2srv_DATA = d2srv.spec diff --git a/src/bin/d2srv/b10-d2srv.xml b/src/bin/d2srv/b10-d2srv.xml new file mode 100644 index 0000000000..ed4b73db22 --- /dev/null +++ b/src/bin/d2srv/b10-d2srv.xml @@ -0,0 +1,101 @@ +]> + + + + + + October 27, 2011 + + + + b10-d2srv + 8 + BIND10 + + + + b10-d2srv + DHCPv4 server in BIND 10 architecture + + + + + 2011 + Internet Systems Consortium, Inc. ("ISC") + + + + + + b10-d2srv + + + + + + DESCRIPTION + + The b10-d2srv daemon will provide the + D2 server implementation when it becomes functional. + + + + + + ARGUMENTS + + The arguments are as follows: + + + + + + + Enable verbose mode. + + + + + + + + + SEE ALSO + + + b10-init8 + , + + bind108 + . + + + + + HISTORY + + The b10-d2srv daemon was first coded in + November 2013 by Thomas Markwalder + + + diff --git a/src/bin/d2srv/d2srv.spec b/src/bin/d2srv/d2srv.spec new file mode 100644 index 0000000000..11a8a60c6c --- /dev/null +++ b/src/bin/d2srv/d2srv.spec @@ -0,0 +1,21 @@ +{ + "module_spec": { + "module_name": "D2Srv", + "module_description": "DHCP-DDNS server daemon", + "config_data": [ + ], + "commands": [ + { + "command_name": "shutdown", + "command_description": "Shuts down D2Srv server.", + "command_args": [ + { + "item_name": "pid", + "item_type": "integer", + "item_optional": true + } + ] + } + ] + } +} diff --git a/src/bin/d2srv/d2srv_log.cc b/src/bin/d2srv/d2srv_log.cc new file mode 100644 index 0000000000..4a81880cb5 --- /dev/null +++ b/src/bin/d2srv/d2srv_log.cc @@ -0,0 +1,26 @@ +// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC 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. + +/// Defines the logger used by the top-level component of b10-dhcp4. + +#include + +namespace isc { +namespace d2srv { + +isc::log::Logger d2srv_logger("d2srv"); + +} // namespace d2srv +} // namespace isc + diff --git a/src/bin/d2srv/d2srv_log.h b/src/bin/d2srv/d2srv_log.h new file mode 100644 index 0000000000..82a4ef9fb1 --- /dev/null +++ b/src/bin/d2srv/d2srv_log.h @@ -0,0 +1,34 @@ +// Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC 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. + +#ifndef D2SRV_LOG_H +#define D2SRV_LOG_H + +#include +#include +#include + +namespace isc { +namespace d2srv { + +/// Define the logger for the "dhcp4" module part of b10-dhcp4. We could define +/// a logger in each file, but we would want to define a common name to avoid +/// spelling mistakes, so it is just one small step from there to define a +/// module-common logger. +extern isc::log::Logger d2srv_logger; + +} // namespace d2srv +} // namespace isc + +#endif // D2SRV_LOG_H diff --git a/src/bin/d2srv/d2srv_messages.mes b/src/bin/d2srv/d2srv_messages.mes new file mode 100644 index 0000000000..4cd7087c22 --- /dev/null +++ b/src/bin/d2srv/d2srv_messages.mes @@ -0,0 +1,28 @@ +# Copyright (C) 2012-2013 Internet Systems Consortium, Inc. ("ISC") +# +# Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL ISC 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. + +$NAMESPACE isc::d2srv + +% D2SRV_STARTING : server starting +This is a debug message issued during a DController server startup. + +% D2SRV_START_INFO pid: %1, verbose: %2, standalone: %3 +This is a debug message issued during the DController server startup. +It lists some information about the parameters with which the server +is running. + +% D2SRV_SHUTDOWN : server is performing a normal shutting down +This is a debug message issued when a D2Server shuts down +normally in response to command to stop. + diff --git a/src/bin/d2srv/main.cc b/src/bin/d2srv/main.cc new file mode 100644 index 0000000000..c6bf05b125 --- /dev/null +++ b/src/bin/d2srv/main.cc @@ -0,0 +1,89 @@ +// Copyright (C) 2011-2012 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC 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. + +#include +#include +#include +#include + +#include + +using namespace isc::d2srv; +using namespace std; + +/// This file contains entry point (main() function) for standard DHCP-DDNS +/// server, b10-d2srv, component for BIND10 framework. It parses command-line +/// arguments and instantiates D2Controller class that is responsible for +/// establishing connection with msgq (receiving commands and configuration) +/// and also creating D2Server object as well. +/// +/// For detailed explanation or relations between main(), D2Controller, +/// D2Server and other classes, see \ref d2srvSession. + +namespace { + +const char* const D2SRV_NAME = "b10-d2srv"; + +void +usage() { + cerr << "Usage: " << D2SRV_NAME << " [-v] [-s] [-p number]" << endl; + cerr << " -v: verbose output" << endl; + cerr << " -s: stand-alone mode (don't connect to BIND10)" << endl; + exit(EXIT_FAILURE); +} +} // end of anonymous namespace + +int +main(int argc, char* argv[]) { + int ch; + bool stand_alone = false; // Should be connect to BIND10 msgq? + bool verbose_mode = false; // Should server be verbose? + + while ((ch = getopt(argc, argv, "vsp:")) != -1) { + switch (ch) { + case 'v': + verbose_mode = true; + break; + + case 's': + stand_alone = true; + break; + + default: + usage(); + } + } + + // Check for extraneous parameters. + if (argc > optind) { + usage(); + } + + // Initialize logging. If verbose, we'll use maximum verbosity. + // If standalone is enabled, do not buffer initial log messages + isc::log::initLogger(D2SRV_NAME, + (verbose_mode ? isc::log::DEBUG : isc::log::INFO), + isc::log::MAX_DEBUG_LEVEL, NULL, !stand_alone); + LOG_INFO(d2srv_logger, D2SRV_STARTING); + LOG_DEBUG(d2srv_logger, DBGLVL_START_SHUT, D2SRV_START_INFO) + .arg(getpid()).arg(verbose_mode ? "yes" : "no") + .arg(stand_alone ? "yes" : "no" ); + + + int ret = EXIT_SUCCESS; + sleep(1000); + LOG_INFO(d2srv_logger, D2SRV_SHUTDOWN); + return (ret); +} + diff --git a/src/bin/d2srv/spec_config.h.pre.in b/src/bin/d2srv/spec_config.h.pre.in new file mode 100644 index 0000000000..17623edecc --- /dev/null +++ b/src/bin/d2srv/spec_config.h.pre.in @@ -0,0 +1,15 @@ +// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC 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. + +#define DHCP4_SPECFILE_LOCATION "@prefix@/share/@PACKAGE@/dhcp4.spec" diff --git a/src/bin/d2srv/tests/Makefile.am b/src/bin/d2srv/tests/Makefile.am new file mode 100644 index 0000000000..34b0c13cfa --- /dev/null +++ b/src/bin/d2srv/tests/Makefile.am @@ -0,0 +1,71 @@ +PYCOVERAGE_RUN = @PYCOVERAGE_RUN@ + +PYTESTS = d2srv_test.py +EXTRA_DIST = $(PYTESTS) + +# Explicitly specify paths to dynamic libraries required by loadable python +# modules. That is required on Mac OS systems. Otherwise we will get exception +# about python not being able to load liblog library. +LIBRARY_PATH_PLACEHOLDER = +if SET_ENV_LIBRARY_PATH +LIBRARY_PATH_PLACEHOLDER += $(ENV_LIBRARY_PATH)=$(abs_top_builddir)/src/lib/cryptolink/.libs:$(abs_top_builddir)/src/lib/dns/.libs:$(abs_top_builddir)/src/lib/dns/python/.libs:$(abs_top_builddir)/src/lib/cc/.libs:$(abs_top_builddir)/src/lib/config/.libs:$(abs_top_builddir)/src/lib/log/.libs:$(abs_top_builddir)/src/lib/util/.libs:$(abs_top_builddir)/src/lib/util/threads/.libs:$(abs_top_builddir)/src/lib/exceptions/.libs:$(abs_top_builddir)/src/lib/util/io/.libs:$(abs_top_builddir)/src/lib/datasrc/.libs:$$$(ENV_LIBRARY_PATH) +endif + +# test using command-line arguments, so use check-local target instead of TESTS +check-local: + for pytest in $(PYTESTS) ; do \ + echo Running test: $$pytest ; \ + PYTHONPATH=$(COMMON_PYTHON_PATH):$(abs_top_srcdir)/src/bin:$(abs_top_builddir)/src/bin/bind10:$(abs_top_builddir)/src/lib/util/io/.libs \ + B10_LOCKFILE_DIR_FROM_BUILD=$(abs_top_builddir) \ + $(LIBRARY_PATH_PLACEHOLDER) \ + $(PYCOVERAGE_RUN) $(abs_srcdir)/$$pytest || exit ; \ + done + +AM_CPPFLAGS = -I$(top_srcdir)/src/lib -I$(top_builddir)/src/lib +AM_CPPFLAGS += -I$(top_builddir)/src/bin # for generated spec_config.h header +AM_CPPFLAGS += -I$(top_srcdir)/src/bin +AM_CPPFLAGS += -I$(top_builddir)/src/lib/cc +AM_CPPFLAGS += -I$(top_srcdir)/src/lib/asiolink +AM_CPPFLAGS += $(BOOST_INCLUDES) +AM_CPPFLAGS += -DTEST_DATA_DIR=\"$(abs_top_srcdir)/src/lib/testutils/testdata\" +AM_CPPFLAGS += -DTEST_DATA_BUILDDIR=\"$(abs_top_builddir)/src/bin/d2srv/tests\" +AM_CPPFLAGS += -DINSTALL_PROG=\"$(abs_top_srcdir)/install-sh\" + +CLEANFILES = $(builddir)/interfaces.txt $(builddir)/logger_lockfile + +AM_CXXFLAGS = $(B10_CXXFLAGS) +if USE_CLANGPP +# Disable unused parameter warning caused by some Boost headers when compiling with clang +AM_CXXFLAGS += -Wno-unused-parameter +endif + +if USE_STATIC_LINK +AM_LDFLAGS = -static +endif + +TESTS_ENVIRONMENT = \ + $(LIBTOOL) --mode=execute $(VALGRIND_COMMAND) + +TESTS = +if HAVE_GTEST + +TESTS += d2srv_unittests + +d2srv_unittests_SOURCES = ../d2srv_log.h ../d2srv_log.cc +d2srv_unittests_SOURCES += d2srv_unittests.cc +nodist_d2srv_unittests_SOURCES = ../d2srv_messages.h ../d2srv_messages.cc + +d2srv_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) +d2srv_unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) +d2srv_unittests_LDADD = $(GTEST_LDADD) +d2srv_unittests_LDADD += $(top_builddir)/src/lib/asiolink/libb10-asiolink.la +d2srv_unittests_LDADD += $(top_builddir)/src/lib/cc/libb10-cc.la +d2srv_unittests_LDADD += $(top_builddir)/src/lib/config/libb10-cfgclient.la +d2srv_unittests_LDADD += $(top_builddir)/src/lib/dhcp/libb10-dhcp++.la +d2srv_unittests_LDADD += $(top_builddir)/src/lib/dhcpsrv/libb10-dhcpsrv.la +d2srv_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libb10-exceptions.la +d2srv_unittests_LDADD += $(top_builddir)/src/lib/log/libb10-log.la +d2srv_unittests_LDADD += $(top_builddir)/src/lib/util/libb10-util.la +endif + +noinst_PROGRAMS = $(TESTS) diff --git a/src/bin/d2srv/tests/d2srv_test.py b/src/bin/d2srv/tests/d2srv_test.py new file mode 100644 index 0000000000..1bac753215 --- /dev/null +++ b/src/bin/d2srv/tests/d2srv_test.py @@ -0,0 +1,168 @@ +# Copyright (C) 2012 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. + +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 TestD2srvDaemon(unittest.TestCase): + def setUp(self): + # Don't redirect stdout/stderr here as we want to print out things + # during the test + # + # However, we do want to set the logging lock directory to somewhere + # to which we can write - use the current working directory. We then + # set the appropriate environment variable. os.putenv() may be not + # supported on some platforms as suggested in + # http://docs.python.org/release/3.2/library/os.html?highlight=putenv#os.environ: + # "If the platform supports the putenv() function...". It was checked + # that it does not work on Ubuntu. To overcome this problem we access + # os.environ directly. + 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) + # Make sure we have a string + 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) + """ + ## @todo: Convert this into generic method and reuse it in dhcp4 and dhcp6 + + print("Running command: %s" % (" ".join(params))) + + # redirect stdout to a pipe so we can check that our + # process spawning is doing the right thing with stdout + 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]) + + # do the same trick for stderr: + 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]) + + # note that we use dup2() to restore the original stdout + # to the main program ASAP in each test... this prevents + # hangs reading from the child process (as the pipe is only + # open in the child), and also insures nice pretty output + + 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) + + # Set non-blocking read on pipes. Process may not print anything + # on specific output and the we would hang without this. + 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) + + # As we don't know how long the subprocess will take to start and + # produce output, we'll loop and sleep for 250 ms between each + # iteration. To avoid an infinite loop, we'll loop for a maximum + # of five seconds: that should be enough. + for count in range(20): + # Read something from stderr and stdout (these reads don't block). + output = self.readPipe(self.stdout_pipes[0]) + error = self.readPipe(self.stderr_pipes[0]) + + # If the process has already exited, or if it has output something, + # quit the loop now. + if pi.process.poll() is not None or len(error) > 0 or len(output) > 0: + break + + # Process still running, try again in 250 ms. + time.sleep(0.25) + + # Exited loop, kill the process if it is still running + if pi.process.poll() is None: + try: + pi.process.terminate() + except OSError: + print("Ignoring failed kill attempt. Process is dead already.") + + # call this to get returncode, process should be dead by now + rc = pi.process.wait() + + # Clean up our stdout/stderr munging. + 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]) + + # Free up resources (file descriptors) from the ProcessInfo object + # TODO: For some reason, this gives an error if the process has ended, + # although it does cause all descriptors still allocated to the + # object to be freed. + 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: Purpose of some of the tests is to check if D2 server can be started,") + print(" not that is can bind sockets correctly. Please ignore binding errors.") + print("THIS TEST IS A PLACE HOLDER DURING INITIAL D2 SERVER WORK - IT ALWAYS PASSES") + + #(returncode, output, error) = self.runCommand(["../b10-d2srv", "-v"]) + #output_text = str(output) + str(error) + #self.assertEqual(output_text.count("D2SRV_STARTING"), 1) + +if __name__ == '__main__': + unittest.main() diff --git a/src/bin/d2srv/tests/d2srv_unittests.cc b/src/bin/d2srv/tests/d2srv_unittests.cc new file mode 100644 index 0000000000..ddc53108b6 --- /dev/null +++ b/src/bin/d2srv/tests/d2srv_unittests.cc @@ -0,0 +1,31 @@ +// Copyright (C) 2011 Internet Systems Consortium, Inc. ("ISC") +// +// Permission to use, copy, modify, and/or 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 ISC DISCLAIMS ALL WARRANTIES WITH +// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +// AND FITNESS. IN NO EVENT SHALL ISC 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. + +#include +#include +#include + +int +main(int argc, char* argv[]) { + + ::testing::InitGoogleTest(&argc, argv); + + // See the documentation of the B10_* environment variables in + // src/lib/log/README for info on how to tweak logging + isc::log::initLogger(); + + int result = RUN_ALL_TESTS(); + + return (result); +}