tests: Add a unit test for res_nquery and res_nsearch
authorJakub Hrozek <jhrozek@redhat.com>
Fri, 12 Sep 2014 13:49:01 +0000 (15:49 +0200)
committerMichael Adam <obnox@samba.org>
Tue, 21 Oct 2014 11:39:39 +0000 (13:39 +0200)
Adds a test that connects to a test DNS server and searches it using
res_query and res_search.

Signed-off-by: Jakub Hrozek <jakub.hrozek@gmail.com>
Reviewed-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
ConfigureChecks.cmake
tests/CMakeLists.txt
tests/test_res_query_search.c [new file with mode: 0644]

index 079737587d14fcc85eef2579cb3280c3f14ef61b..2633d23c2c0cab1c85d2eb1d8312f6a64dc3b404 100644 (file)
@@ -51,11 +51,12 @@ check_include_file(sys/types.h HAVE_SYS_TYPES_H)
 check_include_file(resolv.h HAVE_RESOLV_H)
 
 # FUNCTIONS
-check_library_exists(resolv res_send "" RES_SEND_IN_LIBRESOLV)
-check_library_exists(resolv __res_send "" __RES_SEND_IN_LIBRESOLV)
-if (RES_SEND_IN_LIBRESOLV OR __RES_SEND_IN_LIBRESOLV)
+find_library(RESOLV_LIRBRARY resolv)
+check_library_exists(${RESOLV_LIRBRARY} res_send "" RES_SEND_IN_LIBRESOLV)
+check_library_exists(${RESOLV_LIRBRARY} __res_send "" __RES_SEND_IN_LIBRESOLV)
+if (RESOLV_LIRBRARY AND RES_SEND_IN_LIBRESOLV OR __RES_SEND_IN_LIBRESOLV)
     set(HAVE_LIBRESOLV TRUE)
-    set(CMAKE_REQUIRED_LIBRARIES resolv)
+    set(CMAKE_REQUIRED_LIBRARIES ${RESOLV_LIRBRARY})
 endif()
 
 check_function_exists(res_init HAVE_RES_INIT)
index 06a3800405c13472b83a528659981c74d2afbfba..06f4903b5d2c37c4a38d792229d181038f89eb37 100644 (file)
@@ -20,10 +20,22 @@ target_link_libraries(${TORTURE_LIBRARY}
 
 
 set(TESTSUITE_LIBRARIES ${RWRAP_REQUIRED_LIBRARIES} ${CMOCKA_LIBRARY})
+if (HAVE_LIBRESOLV)
+    set(TESTSUITE_LIBRARIES ${TESTSUITE_LIBRARIES} resolv)
+endif()
 
 set(RWRAP_TESTS
     test_res_init)
 
+set(PRELOAD_LIBS ${RESOLV_WRAPPER_LOCATION})
+
+# Some tests require socket_wrapper as well.
+find_package(socket_wrapper)
+if (HAVE_LIBRESOLV AND SOCKET_WRAPPER_LIBRARY)
+    set(RWRAP_TESTS ${RWRAP_TESTS} test_res_query_search)
+    set(PRELOAD_LIBS ${RESOLV_WRAPPER_LOCATION}:${SOCKET_WRAPPER_LIBRARY})
+endif()
+
 foreach(_RWRAP_TEST ${RWRAP_TESTS})
     add_cmocka_test(${_RWRAP_TEST} ${_RWRAP_TEST}.c ${TORTURE_LIBRARY} ${TESTSUITE_LIBRARIES})
 
@@ -32,12 +44,12 @@ foreach(_RWRAP_TEST ${RWRAP_TESTS})
             TEST
                 ${_RWRAP_TEST}
             PROPERTY
-                ENVIRONMENT DYLD_FORCE_FLAT_NAMESPACE=1;DYLD_INSERT_LIBRARIES=${RESOLV_WRAPPER_LOCATION})
+                ENVIRONMENT DYLD_FORCE_FLAT_NAMESPACE=1;DYLD_INSERT_LIBRARIES=${PRELOAD_LIBS})
     else ()
         set_property(
             TEST
                 ${_RWRAP_TEST}
             PROPERTY
-                ENVIRONMENT LD_PRELOAD=${RESOLV_WRAPPER_LOCATION})
+                ENVIRONMENT LD_PRELOAD=${PRELOAD_LIBS})
     endif()
 endforeach()
diff --git a/tests/test_res_query_search.c b/tests/test_res_query_search.c
new file mode 100644 (file)
index 0000000..2188f76
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) Jakub Hrozek 2014 <jakub.hrozek@gmail.com>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the author nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <cmocka.h>
+
+#include "config.h"
+#include "torture.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <resolv.h>
+
+#define ANSIZE 256
+
+static void setup_dns_srv_ipv4(void **state)
+{
+       torture_setup_dns_srv_ipv4(state);
+       setenv("RESOLV_WRAPPER_CONF", torture_server_resolv_conf(state), 1);
+}
+
+static void teardown(void **state)
+{
+       torture_teardown_dns_srv(state);
+}
+
+static void test_res_query(void **state)
+{
+       int rv;
+       struct __res_state dnsstate;
+       unsigned char answer[ANSIZE];
+       char addr[INET_ADDRSTRLEN];
+       ns_msg handle;
+       ns_rr rr;   /* expanded resource record */
+
+       (void) state; /* unused */
+
+       memset(&dnsstate, 0, sizeof(struct __res_state));
+       rv = res_ninit(&dnsstate);
+       assert_int_equal(rv, 0);
+
+       rv = res_nquery(&dnsstate, "www.cwrap.org", ns_c_in, ns_t_a,
+                       answer, ANSIZE);
+       assert_int_not_equal(rv, -1);
+
+       ns_initparse(answer, 256, &handle);
+       /*
+        * The query must finish w/o an error, have one answer and the answer
+        * must be a parseable RR of type A and have the address that our
+        * test server sends.
+        */
+       assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
+       assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
+       assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
+       assert_int_equal(ns_rr_type(rr), ns_t_a);
+       assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr), addr, 256));
+       assert_string_equal(addr, "127.0.10.10");
+}
+
+static void test_res_search(void **state)
+{
+       int rv;
+       struct __res_state dnsstate;
+       unsigned char answer[ANSIZE];
+       char addr[INET_ADDRSTRLEN];
+       ns_msg handle;
+       ns_rr rr;   /* expanded resource record */
+
+       (void) state; /* unused */
+
+       memset(&dnsstate, 0, sizeof(struct __res_state));
+       rv = res_ninit(&dnsstate);
+       assert_int_equal(rv, 0);
+
+       rv = res_nsearch(&dnsstate, "www.cwrap.org", ns_c_in, ns_t_a,
+                        answer, ANSIZE);
+       assert_int_not_equal(rv, -1);
+
+       ns_initparse(answer, 256, &handle);
+       /* The query must finish w/o an error, have one answer and the answer
+        * must be a parseable RR of type A and have the address that our
+        * test server sends
+        */
+       assert_int_equal(ns_msg_getflag(handle, ns_f_rcode), ns_r_noerror);
+       assert_int_equal(ns_msg_count(handle, ns_s_an), 1);
+       assert_int_equal(ns_parserr(&handle, ns_s_an, 0, &rr), 0);
+       assert_int_equal(ns_rr_type(rr), ns_t_a);
+       assert_non_null(inet_ntop(AF_INET, ns_rr_rdata(rr), addr, 256));
+       assert_string_equal(addr, "127.0.10.10");
+}
+
+int main(void)
+{
+       int rc;
+
+       const UnitTest tests[] = {
+               unit_test_setup_teardown(test_res_query,
+                                        setup_dns_srv_ipv4,
+                                        teardown),
+               unit_test_setup_teardown(test_res_search,
+                                        setup_dns_srv_ipv4,
+                                        teardown),
+       };
+
+       rc = run_tests(tests);
+
+       return rc;
+}