Browse Source

Merge branch 'master' into trac1384

Jelte Jansen 13 years ago
parent
commit
11a4fe2def

+ 3 - 0
configure.ac

@@ -107,6 +107,9 @@ case "$host" in
 	SET_ENV_LIBRARY_PATH=yes
 	ENV_LIBRARY_PATH=DYLD_LIBRARY_PATH
 	;;
+*-freebsd*)
+	SET_ENV_LIBRARY_PATH=yes
+	;;
 esac
 AM_CONDITIONAL(SET_ENV_LIBRARY_PATH, test $SET_ENV_LIBRARY_PATH = yes)
 AC_SUBST(SET_ENV_LIBRARY_PATH)

+ 54 - 23
src/lib/datasrc/tests/Makefile.am

@@ -18,23 +18,43 @@ CLEANFILES = *.gcno *.gcda
 
 TESTS =
 if HAVE_GTEST
-TESTS += run_unittests
-run_unittests_SOURCES = run_unittests.cc
-run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.h
-run_unittests_SOURCES += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
+TESTS += run_unittests run_unittests_sqlite3 run_unittests_memory
+
+#
+# For each specific datasource, there is a separate binary that includes
+# the code itself (we can't unittest through the public API). These need
+# to be separate because the included code, by design, contains conflicting
+# symbols.
+# We also have a 'general' run_unittests with non-datasource-specific tests
+#
+
+# First define the parts shared by all
+common_sources = run_unittests.cc
+common_sources += $(top_srcdir)/src/lib/dns/tests/unittest_util.h
+common_sources += $(top_srcdir)/src/lib/dns/tests/unittest_util.cc
+
+common_ldadd  = $(GTEST_LDADD)
+common_ldadd += $(SQLITE_LIBS)
+common_ldadd += $(top_builddir)/src/lib/datasrc/libdatasrc.la
+common_ldadd += $(top_builddir)/src/lib/dns/libdns++.la
+common_ldadd += $(top_builddir)/src/lib/util/libutil.la
+common_ldadd += $(top_builddir)/src/lib/log/liblog.la
+common_ldadd += $(top_builddir)/src/lib/exceptions/libexceptions.la
+common_ldadd += $(top_builddir)/src/lib/cc/libcc.la
+common_ldadd += $(top_builddir)/src/lib/testutils/libtestutils.la
+common_ldadd += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
+
+
+# The general tests
+run_unittests_SOURCES = $(common_sources)
 run_unittests_SOURCES += datasrc_unittest.cc
-run_unittests_SOURCES += sqlite3_unittest.cc
 run_unittests_SOURCES += static_unittest.cc
 run_unittests_SOURCES += query_unittest.cc
 run_unittests_SOURCES += cache_unittest.cc
 run_unittests_SOURCES += test_datasrc.h test_datasrc.cc
 run_unittests_SOURCES += rbtree_unittest.cc
-#run_unittests_SOURCES += zonetable_unittest.cc
-#run_unittests_SOURCES += memory_datasrc_unittest.cc
 run_unittests_SOURCES += logger_unittest.cc
-run_unittests_SOURCES += database_unittest.cc
 run_unittests_SOURCES += client_unittest.cc
-run_unittests_SOURCES += sqlite3_accessor_unittest.cc
 if !USE_STATIC_LINK
 # This test uses dynamically loadable module.  It will cause various
 # troubles with static link such as "missing" symbols in the static object
@@ -42,24 +62,35 @@ if !USE_STATIC_LINK
 # in this case.
 run_unittests_SOURCES += factory_unittest.cc
 endif
-# for the dlopened types we have tests for, we also need to include the
-# sources
-run_unittests_SOURCES += $(top_srcdir)/src/lib/datasrc/sqlite3_accessor.cc
-#run_unittests_SOURCES += $(top_srcdir)/src/lib/datasrc/memory_datasrc.cc
 
 run_unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
 run_unittests_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
 
-run_unittests_LDADD  = $(GTEST_LDADD)
-run_unittests_LDADD += $(SQLITE_LIBS)
-run_unittests_LDADD += $(top_builddir)/src/lib/datasrc/libdatasrc.la
-run_unittests_LDADD += $(top_builddir)/src/lib/dns/libdns++.la
-run_unittests_LDADD += $(top_builddir)/src/lib/util/libutil.la
-run_unittests_LDADD += $(top_builddir)/src/lib/log/liblog.la
-run_unittests_LDADD += $(top_builddir)/src/lib/exceptions/libexceptions.la
-run_unittests_LDADD += $(top_builddir)/src/lib/cc/libcc.la
-run_unittests_LDADD += $(top_builddir)/src/lib/testutils/libtestutils.la
-run_unittests_LDADD += $(top_builddir)/src/lib/util/unittests/libutil_unittests.la
+run_unittests_LDADD = $(common_ldadd)
+
+
+# SQlite3 datasource tests
+run_unittests_sqlite3_SOURCES = $(common_sources)
+run_unittests_sqlite3_SOURCES += database_unittest.cc
+run_unittests_sqlite3_SOURCES += sqlite3_unittest.cc
+run_unittests_sqlite3_SOURCES += sqlite3_accessor_unittest.cc
+run_unittests_sqlite3_SOURCES += $(top_srcdir)/src/lib/datasrc/sqlite3_accessor.cc
+
+run_unittests_sqlite3_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+run_unittests_sqlite3_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
+
+run_unittests_sqlite3_LDADD = $(common_ldadd)
+
+# In-memory datasource tests
+run_unittests_memory_SOURCES = $(common_sources)
+run_unittests_memory_SOURCES += memory_datasrc_unittest.cc
+run_unittests_memory_SOURCES += $(top_srcdir)/src/lib/datasrc/memory_datasrc.cc
+
+run_unittests_memory_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES)
+run_unittests_memory_LDFLAGS  = $(AM_LDFLAGS)  $(GTEST_LDFLAGS)
+
+run_unittests_memory_LDADD = $(common_ldadd)
+
 endif
 
 noinst_PROGRAMS = $(TESTS)

+ 22 - 0
tests/lettuce/configurations/xfrin/retransfer_master.conf

@@ -0,0 +1,22 @@
+{
+    "version": 2,
+    "Logging": {
+        "loggers": [ {
+            "debuglevel": 99,
+            "severity": "DEBUG",
+            "name": "auth"
+        } ]
+    },
+    "Auth": {
+        "database_file": "data/example.org.sqlite3",
+        "listen_on": [ {
+            "port": 47807,
+            "address": "127.0.0.1"
+        } ]
+    },
+    "Xfrout": {
+        "zone_config": [ {
+            "origin": "example.org"
+        } ]
+    }
+}

+ 17 - 0
tests/lettuce/configurations/xfrin/retransfer_slave.conf

@@ -0,0 +1,17 @@
+{
+    "version": 2,
+    "Logging": {
+        "loggers": [ {
+            "debuglevel": 99,
+            "severity": "DEBUG",
+            "name": "auth"
+        } ]
+    },
+    "Auth": {
+        "database_file": "data/test_nonexistent_db.sqlite3",
+        "listen_on": [ {
+            "port": 47806,
+            "address": "127.0.0.1"
+        } ]
+    }
+}

+ 43 - 10
tests/lettuce/features/terrain/bind10_control.py

@@ -18,8 +18,10 @@ import subprocess
 import re
 
 @step('start bind10(?: with configuration (\S+))?' +\
-      '(?: with cmdctl port (\d+))?(?: as (\S+))?')
-def start_bind10(step, config_file, cmdctl_port, process_name):
+      '(?: with cmdctl port (\d+))?' +\
+      '(?: with msgq socket file (\S+))?' +\
+      '(?: as (\S+))?')
+def start_bind10(step, config_file, cmdctl_port, msgq_sockfile, process_name):
     """
     Start BIND 10 with the given optional config file, cmdctl port, and
     store the running process in world with the given process name.
@@ -29,6 +31,8 @@ def start_bind10(step, config_file, cmdctl_port, process_name):
                 directory.
     cmdctl_port ('with cmdctl port <portnr>', optional): The port on which
                 b10-cmdctl listens for bindctl commands. Defaults to 47805.
+    msgq_sockfile ('with msgq socket file', optional): The msgq socket file
+                that will be used for internal communication
     process_name ('as <name>', optional). This is the name that can be used
                  in the following steps of the scenario to refer to this
                  BIND 10 instance. Defaults to 'bind10'.
@@ -57,10 +61,10 @@ def start_bind10(step, config_file, cmdctl_port, process_name):
     world.processes.add_process(step, process_name, args)
 
     # check output to know when startup has been completed
-    message = world.processes.wait_for_stderr_str(process_name,
-                                                  ["BIND10_STARTUP_COMPLETE",
-                                                   "BIND10_STARTUP_ERROR"])
-    assert message == "BIND10_STARTUP_COMPLETE", "Got: " + str(message)
+    (message, line) = world.processes.wait_for_stderr_str(process_name,
+                                                     ["BIND10_STARTUP_COMPLETE",
+                                                      "BIND10_STARTUP_ERROR"])
+    assert message == "BIND10_STARTUP_COMPLETE", "Got: " + str(line)
 
 @step('wait for bind10 auth (?:of (\w+) )?to start')
 def wait_for_auth(step, process_name):
@@ -75,15 +79,24 @@ def wait_for_auth(step, process_name):
     world.processes.wait_for_stderr_str(process_name, ['AUTH_SERVER_STARTED'],
                                         False)
 
-@step('have bind10 running(?: with configuration ([\w.]+))?')
-def have_bind10_running(step, config_file):
+@step('have bind10 running(?: with configuration ([\S]+))?' +\
+      '(?: with cmdctl port (\d+))?' +\
+      '(?: as ([\S]+))?')
+def have_bind10_running(step, config_file, cmdctl_port, process_name):
     """
     Compound convenience step for running bind10, which consists of
     start_bind10 and wait_for_auth.
     Currently only supports the 'with configuration' option.
     """
-    step.given('start bind10 with configuration ' + config_file)
-    step.given('wait for bind10 auth to start')
+    start_step = 'start bind10 with configuration ' + config_file
+    wait_step = 'wait for bind10 auth to start'
+    if cmdctl_port is not None:
+        start_step += ' with cmdctl port ' + str(cmdctl_port)
+    if process_name is not None:
+        start_step += ' as ' + process_name
+        wait_step = 'wait for bind10 auth of ' + process_name + ' to start'
+    step.given(start_step)
+    step.given(wait_step)
 
 @step('set bind10 configuration (\S+) to (.*)(?: with cmdctl port (\d+))?')
 def set_config_command(step, name, value, cmdctl_port):
@@ -106,3 +119,23 @@ def set_config_command(step, name, value, cmdctl_port):
     bindctl.stdin.write("quit\n")
     result = bindctl.wait()
     assert result == 0, "bindctl exit code: " + str(result)
+
+@step('send bind10 the command (.+)(?: with cmdctl port (\d+))?')
+def send_command(step, command, cmdctl_port):
+    """
+    Run bindctl, send the given command, and exit bindctl.
+    Parameters:
+    command ('the command <command>'): The command to send.
+    cmdctl_port ('with cmdctl port <portnr>', optional): cmdctl port to send
+                the command to. Defaults to 47805.
+    Fails if cmdctl does not exit with status code 0.
+    """
+    if cmdctl_port is None:
+        cmdctl_port = '47805'
+    args = ['bindctl', '-p', cmdctl_port]
+    bindctl = subprocess.Popen(args, 1, None, subprocess.PIPE,
+                               subprocess.PIPE, None)
+    bindctl.stdin.write(command + "\n")
+    bindctl.stdin.write("quit\n")
+    result = bindctl.wait()
+    assert result == 0, "bindctl exit code: " + str(result)

+ 19 - 7
tests/lettuce/features/terrain/steps.py

@@ -30,8 +30,8 @@ def stop_a_named_process(step, process_name):
     """
     world.processes.stop_process(process_name)
 
-@step('wait for (new )?(\w+) stderr message (\w+)')
-def wait_for_message(step, new, process_name, message):
+@step('wait for (new )?(\w+) stderr message (\w+)(?: not (\w+))?')
+def wait_for_message(step, new, process_name, message, not_message):
     """
     Block until the given message is printed to the given process's stderr
     output.
@@ -40,12 +40,18 @@ def wait_for_message(step, new, process_name, message):
                              this step was used for this process.
     process_name ('<name> stderr'): Name of the process to check the output of.
     message ('message <message>'): Output (part) to wait for.
+    not_message ('not <message>'): Output (part) to wait for, and fail
     Fails if the message is not found after 10 seconds.
     """
-    world.processes.wait_for_stderr_str(process_name, [message], new)
+    strings = [message]
+    if not_message is not None:
+        strings.append(not_message)
+    (found, line) = world.processes.wait_for_stderr_str(process_name, strings, new)
+    if not_message is not None:
+        assert found != not_message, line
 
-@step('wait for (new )?(\w+) stdout message (\w+)')
-def wait_for_message(step, process_name, message):
+@step('wait for (new )?(\w+) stdout message (\w+)(?: not (\w+))?')
+def wait_for_message(step, process_name, message, not_message):
     """
     Block until the given message is printed to the given process's stdout
     output.
@@ -53,10 +59,16 @@ def wait_for_message(step, process_name, message):
     new: (' new', optional): Only check the output printed since last time
                              this step was used for this process.
     process_name ('<name> stderr'): Name of the process to check the output of.
-    message ('message <message>'): Output (part) to wait for.
+    message ('message <message>'): Output (part) to wait for, and succeed.
+    not_message ('not <message>'): Output (part) to wait for, and fail
     Fails if the message is not found after 10 seconds.
     """
-    world.processes.wait_for_stdout_str(process_name, [message], new)
+    strings = [message]
+    if not_message is not None:
+        strings.append(not_message)
+    (found, line) = world.processes.wait_for_stdout_str(process_name, strings, new)
+    if not_message is not None:
+        assert found != not_message, line
 
 @step('the file (\S+) should (not )?exist')
 def check_existence(step, file_name, should_not_exist):

+ 9 - 6
tests/lettuce/features/terrain/terrain.py

@@ -173,7 +173,8 @@ class RunningProcess:
         strings: Array of strings to look for.
         only_new: If true, only check output since last time this method was
                   called. If false, first check earlier output.
-        Returns the matched string.
+        Returns a tuple containing the matched string, and the complete line
+        it was found in.
         Fails if none of the strings was read after 10 seconds
         (OUTPUT_WAIT_INTERVAL * OUTPUT_WAIT_MAX_INTERVALS).
         """
@@ -183,7 +184,7 @@ class RunningProcess:
                 for string in strings:
                     if line.find(string) != -1:
                         full_file.close()
-                        return string
+                        return (string, line)
         wait_count = 0
         while wait_count < OUTPUT_WAIT_MAX_INTERVALS:
             where = running_file.tell()
@@ -191,7 +192,7 @@ class RunningProcess:
             if line:
                 for string in strings:
                     if line.find(string) != -1:
-                        return string
+                        return (string, line)
             else:
                 wait_count += 1
                 time.sleep(OUTPUT_WAIT_INTERVAL)
@@ -205,7 +206,8 @@ class RunningProcess:
         strings: Array of strings to look for.
         only_new: If true, only check output since last time this method was
                   called. If false, first check earlier output.
-        Returns the matched string.
+        Returns a tuple containing the matched string, and the complete line
+        it was found in.
         Fails if none of the strings was read after 10 seconds
         (OUTPUT_WAIT_INTERVAL * OUTPUT_WAIT_MAX_INTERVALS).
         """
@@ -219,7 +221,8 @@ class RunningProcess:
         strings: Array of strings to look for.
         only_new: If true, only check output since last time this method was
                   called. If false, first check earlier output.
-        Returns the matched string.
+        Returns a tuple containing the matched string, and the complete line
+        it was found in.
         Fails if none of the strings was read after 10 seconds
         (OUTPUT_WAIT_INTERVAL * OUTPUT_WAIT_MAX_INTERVALS).
         """
@@ -249,7 +252,7 @@ class RunningProcesses:
         Fails if a process with the given name is already running.
         """
         assert process_name not in self.processes,\
-            "Process " + name + " already running"
+            "Process " + process_name + " already running"
         self.processes[process_name] = RunningProcess(step, process_name, args)
 
     def get_process(self, process_name):

+ 10 - 0
tests/lettuce/features/xfrin_bind10.feature

@@ -0,0 +1,10 @@
+Feature: Xfrin 
+    Tests for Xfrin, specific for BIND 10 behaviour.
+    
+    Scenario: Retransfer command
+    Given I have bind10 running with configuration xfrin/retransfer_master.conf with cmdctl port 47804 as master
+    And I have bind10 running with configuration xfrin/retransfer_slave.conf
+    A query for www.example.org should have rcode REFUSED
+    When I send bind10 the command Xfrin retransfer example.org IN 127.0.0.1 47807
+    Then wait for new bind10 stderr message XFRIN_XFR_TRANSFER_SUCCESS not XFRIN_XFR_PROCESS_FAILURE
+    A query for www.example.org should have rcode NOERROR