LCOV - code coverage report
Current view: top level - tests/cmocka - test_dyndns.c (source / functions) Hit Total Coverage
Test: .coverage.total Lines: 438 474 92.4 %
Date: 2015-10-19 Functions: 25 26 96.2 %

          Line data    Source code
       1             : /*
       2             :     Authors:
       3             :         Jakub Hrozek <jhrozek@redhat.com>
       4             : 
       5             :     Copyright (C) 2013 Red Hat
       6             : 
       7             :     SSSD tests: Dynamic DNS tests
       8             : 
       9             :     This program is free software; you can redistribute it and/or modify
      10             :     it under the terms of the GNU General Public License as published by
      11             :     the Free Software Foundation; either version 3 of the License, or
      12             :     (at your option) any later version.
      13             : 
      14             :     This program is distributed in the hope that it will be useful,
      15             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :     GNU General Public License for more details.
      18             : 
      19             :     You should have received a copy of the GNU General Public License
      20             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include <talloc.h>
      24             : #include <tevent.h>
      25             : #include <errno.h>
      26             : #include <popt.h>
      27             : #include <unistd.h>
      28             : #include <sys/types.h>
      29             : #include <ifaddrs.h>
      30             : #include <arpa/inet.h>
      31             : 
      32             : /* In order to access opaque types */
      33             : #include "providers/dp_dyndns.c"
      34             : 
      35             : #include "tests/cmocka/common_mock.h"
      36             : #include "tests/cmocka/common_mock_be.h"
      37             : #include "src/providers/dp_dyndns.h"
      38             : 
      39             : #define TESTS_PATH "tp_" BASE_FILE_STEM
      40             : #define TEST_CONF_DB "test_dyndns_conf.ldb"
      41             : #define TEST_DOM_NAME "dyndns_test"
      42             : #define TEST_ID_PROVIDER "ldap"
      43             : 
      44             : enum mock_nsupdate_states {
      45             :     MOCK_NSUPDATE_OK,
      46             :     MOCK_NSUPDATE_ERR,
      47             :     MOCK_NSUPDATE_TIMEOUT,
      48             : };
      49             : 
      50             : static TALLOC_CTX *global_mock_context = NULL;
      51             : 
      52             : struct dyndns_test_ctx {
      53             :     struct sss_test_ctx *tctx;
      54             : 
      55             :     struct be_ctx *be_ctx;
      56             :     struct be_nsupdate_ctx *update_ctx;
      57             : 
      58             :     enum mock_nsupdate_states state;
      59             :     int child_status;
      60             :     int child_retval;
      61             : };
      62             : 
      63             : static struct dyndns_test_ctx *dyndns_test_ctx;
      64             : 
      65           0 : void __wrap_execv(const char *path, char *const argv[])
      66             : {
      67             :     int err;
      68             : 
      69           0 :     switch (dyndns_test_ctx->state) {
      70             :         case MOCK_NSUPDATE_OK:
      71           0 :             DEBUG(SSSDBG_FUNC_DATA, "nsupdate success test case\n");
      72           0 :             err = 0;
      73           0 :             usleep(50000); /* 50 miliseconds */
      74           0 :             break;
      75             :         case MOCK_NSUPDATE_ERR:
      76           0 :             DEBUG(SSSDBG_FUNC_DATA, "nsupdate error test case\n");
      77           0 :             err = 1;
      78           0 :             break;
      79             :         case MOCK_NSUPDATE_TIMEOUT:
      80           0 :             DEBUG(SSSDBG_FUNC_DATA, "nsupdate timeout test case\n");
      81           0 :             err = 2;
      82           0 :             sleep(3);
      83           0 :             break;
      84             :         default:
      85           0 :             DEBUG(SSSDBG_CRIT_FAILURE, "unknown test case\n");
      86           0 :             err = 255;
      87           0 :             break;
      88             :     }
      89             : 
      90           0 :     DEBUG(SSSDBG_TRACE_LIBS, "Child exiting with status %d\n", err);
      91           0 :     _exit(err);
      92             : }
      93             : 
      94          17 : int __wrap_getifaddrs(struct ifaddrs **_ifap)
      95             : {
      96          17 :     struct ifaddrs *ifap = NULL;
      97          17 :     struct ifaddrs *ifap_prev = NULL;
      98          17 :     struct ifaddrs *ifap_head = NULL;
      99             :     char *name;
     100             :     char *straddr;
     101             :     int ad_family;
     102             :     struct sockaddr_in *sa;
     103             :     void *dst;
     104             : 
     105          92 :     while ((name = sss_mock_ptr_type(char *)) != NULL) {
     106          58 :         straddr = sss_mock_ptr_type(char *);
     107          58 :         if (straddr == NULL) {
     108           0 :             errno = EINVAL;
     109           0 :             goto fail;
     110             :         }
     111          58 :         ad_family = sss_mock_type(int);
     112             : 
     113          58 :         ifap = talloc_zero(global_mock_context, struct ifaddrs);
     114          58 :         if (ifap == NULL) {
     115           0 :             errno = ENOMEM;    /* getifaddrs sets errno, too */
     116           0 :             goto fail;
     117             :         }
     118             : 
     119          58 :         if (ifap_prev) {
     120          41 :             ifap_prev->ifa_next = ifap;
     121             :         } else {
     122          17 :             ifap_head = ifap;
     123             :         }
     124          58 :         ifap_prev = ifap;
     125             : 
     126          58 :         ifap->ifa_name = talloc_strdup(ifap, name);
     127          58 :         if (ifap->ifa_name == NULL) {
     128           0 :             errno = ENOMEM;
     129           0 :             goto fail;
     130             :         }
     131             : 
     132             :         /* Do not alocate directly on ifap->ifa_addr to
     133             :          * avoid alignment warnings */
     134          58 :         if (ad_family == AF_INET) {
     135          30 :             sa = talloc(ifap, struct sockaddr_in);
     136          28 :         } else if (ad_family == AF_INET6) {
     137          28 :             sa = (struct sockaddr_in *) talloc(ifap, struct sockaddr_in6);
     138             :         } else {
     139           0 :             errno = EINVAL;
     140           0 :             goto fail;
     141             :         }
     142             : 
     143          58 :         if (sa == NULL) {
     144           0 :             errno = ENOMEM;
     145           0 :             goto fail;
     146             :         }
     147             : 
     148          58 :         sa->sin_family = ad_family;
     149             : 
     150          58 :         if (ad_family == AF_INET) {
     151          30 :             dst = &sa->sin_addr;
     152          28 :         } else if (ad_family == AF_INET6) {
     153          28 :             dst = &((struct sockaddr_in6 *)sa)->sin6_addr;
     154             :         } else {
     155           0 :             errno = EINVAL;
     156           0 :             goto fail;
     157             :         }
     158             : 
     159             :         /* convert straddr into ifa_addr */
     160          58 :         if (inet_pton(ad_family, straddr, dst) != 1) {
     161           0 :             goto fail;
     162             :         }
     163             : 
     164          58 :         ifap->ifa_addr = (struct sockaddr *) sa;
     165             :     }
     166             : 
     167          17 :     *_ifap = ifap_head;
     168          17 :     return 0;
     169             : 
     170             : fail:
     171           0 :     talloc_free(ifap);
     172           0 :     return -1;
     173             : }
     174             : 
     175          17 : void __wrap_freeifaddrs(struct ifaddrs *ifap)
     176             : {
     177          17 :     talloc_free(ifap);
     178          17 : }
     179             : 
     180           3 : static void dyndns_test_done(struct tevent_req *req)
     181             : {
     182           3 :     struct dyndns_test_ctx *ctx =
     183           3 :             tevent_req_callback_data(req, struct dyndns_test_ctx);
     184             : 
     185           3 :     ctx->child_retval = -1;
     186           3 :     ctx->tctx->error = be_nsupdate_recv(req, &ctx->child_status);
     187           3 :     talloc_zfree(req);
     188             : 
     189           3 :     ctx->tctx->done = true;
     190           3 : }
     191             : 
     192          75 : void will_return_getifaddrs(const char *ifname, const char *straddr,
     193             :                             int af_family)
     194             : {
     195          75 :     will_return(__wrap_getifaddrs, ifname);
     196          75 :     if (ifname) {
     197          58 :         will_return(__wrap_getifaddrs, straddr);
     198             :     }
     199          75 :     if (straddr) {
     200          58 :         will_return(__wrap_getifaddrs, af_family);
     201             :     }
     202          75 : }
     203             : 
     204           1 : void dyndns_test_sss_iface_addr_get_misc(void **state)
     205             : {
     206             :     struct sss_iface_addr addrs[3];
     207             :     struct sockaddr_storage ss[3];
     208             : 
     209           1 :     addrs[0].prev = NULL;
     210           1 :     addrs[0].next = &addrs[1];
     211           1 :     addrs[0].addr = &ss[0];
     212           1 :     addrs[1].prev = &addrs[0];
     213           1 :     addrs[1].next = &addrs[2];
     214           1 :     addrs[1].addr = &ss[1];
     215           1 :     addrs[2].prev = &addrs[1];
     216           1 :     addrs[2].next = NULL;
     217           1 :     addrs[2].addr = &ss[2];
     218             : 
     219           1 :     assert_ptr_equal(sss_iface_addr_get_address(NULL), NULL);
     220           1 :     assert_ptr_equal(sss_iface_addr_get_address(&addrs[0]), &ss[0]);
     221           1 :     assert_ptr_equal(sss_iface_addr_get_address(&addrs[1]), &ss[1]);
     222           1 :     assert_ptr_equal(sss_iface_addr_get_address(&addrs[2]), &ss[2]);
     223             : 
     224           1 :     assert_ptr_equal(sss_iface_addr_get_next(NULL), NULL);
     225           1 :     assert_ptr_equal(sss_iface_addr_get_next(&addrs[0]), &addrs[1]);
     226           1 :     assert_ptr_equal(sss_iface_addr_get_next(&addrs[1]), &addrs[2]);
     227           1 :     assert_ptr_equal(sss_iface_addr_get_next(&addrs[2]), NULL);
     228           1 : }
     229             : 
     230           1 : void dyndns_test_get_ifaddr(void **state)
     231             : {
     232             :     errno_t ret;
     233             :     struct sss_iface_addr *addrlist;
     234             :     char straddr[128];
     235             : 
     236           1 :     check_leaks_push(dyndns_test_ctx);
     237           1 :     will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
     238           1 :     will_return_getifaddrs("eth1", "192.168.0.2", AF_INET);
     239           1 :     will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
     240           1 :     ret = sss_iface_addr_list_get(dyndns_test_ctx, "eth0", &addrlist);
     241           1 :     assert_int_equal(ret, EOK);
     242             : 
     243             :     /* There must be only one address with the correct value */
     244           1 :     assert_non_null(addrlist);
     245           1 :     assert_non_null(addrlist->addr);
     246           1 :     assert_null(addrlist->next);
     247           1 :     assert_null(addrlist->prev);
     248             : 
     249           1 :     assert_non_null(inet_ntop(AF_INET,
     250             :                               &((struct sockaddr_in *) addrlist->addr)->sin_addr,
     251             :                               straddr, INET_ADDRSTRLEN));
     252           1 :     assert_string_equal(straddr, "192.168.0.1");
     253             : 
     254           1 :     talloc_free(addrlist);
     255             : 
     256           1 :     assert_true(check_leaks_pop(dyndns_test_ctx) == true);
     257           1 : }
     258             : 
     259           1 : void dyndns_test_get_multi_ifaddr(void **state)
     260             : {
     261             :     errno_t ret;
     262             :     struct sss_iface_addr *addrlist;
     263             :     struct sss_iface_addr *sss_if_addr;
     264             :     char straddr[128];
     265             : 
     266           1 :     check_leaks_push(dyndns_test_ctx);
     267           1 :     will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
     268           1 :     will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
     269           1 :     will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
     270           1 :     ret = sss_iface_addr_list_get(dyndns_test_ctx, "eth0", &addrlist);
     271           1 :     assert_int_equal(ret, EOK);
     272             : 
     273           1 :     sss_if_addr = addrlist;
     274           1 :     assert_non_null(sss_if_addr);
     275           1 :     assert_non_null(sss_if_addr->addr);
     276           1 :     assert_non_null(sss_if_addr->next);
     277           1 :     assert_null(sss_if_addr->prev);
     278             : 
     279           1 :     assert_non_null(inet_ntop(AF_INET,
     280             :                               &((struct sockaddr_in *) sss_if_addr->addr)->sin_addr,
     281             :                               straddr, INET_ADDRSTRLEN));
     282             :     /* ip addresses are returned in different order */
     283           1 :     assert_string_equal(straddr, "192.168.0.1");
     284             : 
     285           1 :     sss_if_addr = addrlist->next;
     286           1 :     assert_non_null(sss_if_addr);
     287           1 :     assert_non_null(sss_if_addr->addr);
     288           1 :     assert_null(sss_if_addr->next);
     289           1 :     assert_non_null(sss_if_addr->prev);
     290             : 
     291           1 :     assert_non_null(inet_ntop(AF_INET,
     292             :                               &((struct sockaddr_in *) sss_if_addr->addr)->sin_addr,
     293             :                               straddr, INET_ADDRSTRLEN));
     294             :     /* ip addresses are returned in different order */
     295           1 :     assert_string_equal(straddr, "192.168.0.2");
     296             : 
     297           1 :     talloc_free(addrlist);
     298             : 
     299           1 :     assert_true(check_leaks_pop(dyndns_test_ctx) == true);
     300           1 : }
     301             : 
     302           1 : void dyndns_test_get_ifaddr_enoent(void **state)
     303             : {
     304             :     errno_t ret;
     305           1 :     struct sss_iface_addr *addrlist = NULL;
     306             : 
     307           1 :     check_leaks_push(dyndns_test_ctx);
     308           1 :     will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
     309           1 :     will_return_getifaddrs("eth1", "192.168.0.2", AF_INET);
     310           1 :     will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
     311           1 :     ret = sss_iface_addr_list_get(dyndns_test_ctx, "non_existing_interface",
     312             :                                   &addrlist);
     313           1 :     assert_int_equal(ret, ENOENT);
     314           1 :     talloc_free(addrlist);
     315             : 
     316           1 :     assert_true(check_leaks_pop(dyndns_test_ctx) == true);
     317           1 : }
     318             : 
     319           1 : void dyndns_test_addr_list_as_str_list(void **state)
     320             : {
     321             :     int i;
     322             :     char **output;
     323             :     errno_t ret;
     324             :     struct sss_iface_addr *addrlist;
     325             :     struct {
     326             :         const char* addr;
     327             :         int af;
     328           1 :     } input[] = {
     329             :         {"2001:cdba::555", AF_INET6},
     330             :         {"192.168.0.1", AF_INET},
     331             :         {"192.168.0.2", AF_INET},
     332             :         {"2001:cdba::444", AF_INET6}
     333             :     };
     334           1 :     int size = 4;
     335             : 
     336           1 :     check_leaks_push(dyndns_test_ctx);
     337             : 
     338           5 :     for (i = 0; i < size; i++) {
     339           4 :         will_return_getifaddrs("eth0", input[i].addr, input[i].af);
     340             :     }
     341           1 :     will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
     342             : 
     343           1 :     ret = sss_iface_addr_list_get(dyndns_test_ctx, "eth0", &addrlist);
     344           1 :     assert_int_equal(ret, EOK);
     345             : 
     346           1 :     ret = sss_iface_addr_list_as_str_list(dyndns_test_ctx, addrlist, &output);
     347           1 :     assert_int_equal(ret, EOK);
     348           5 :     for (i = 0; i < size; i++) {
     349             :         /* addresses are returned in reversed order */
     350           4 :         assert_int_equal(strcmp(input[i].addr, output[size - 1 - i]), 0);
     351             :     }
     352             : 
     353           1 :     talloc_free(addrlist);
     354           1 :     talloc_free(output);
     355           1 :     assert_true(check_leaks_pop(dyndns_test_ctx) == true);
     356           1 : }
     357             : 
     358           1 : void dyndns_test_create_fwd_msg(void **state)
     359             : {
     360             :     errno_t ret;
     361             :     char *msg;
     362             :     struct sss_iface_addr *addrlist;
     363             :     int i;
     364             : 
     365           1 :     check_leaks_push(dyndns_test_ctx);
     366             : 
     367             :     /* getifaddrs is called twice in sss_get_dualstack_addresses() */
     368           3 :     for (i = 0; i < 2; i++) {
     369           2 :         will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
     370           2 :         will_return_getifaddrs("eth1", "192.168.0.1", AF_INET);
     371           2 :         will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
     372           2 :         will_return_getifaddrs("eth1", "2001:cdba::444", AF_INET6);
     373           2 :         will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
     374             :     }
     375             : 
     376             :     struct sockaddr_in sin;
     377           1 :     memset(&sin, 0, sizeof (sin));
     378           1 :     sin.sin_family = AF_INET;
     379           1 :     sin.sin_addr.s_addr = inet_addr ("192.168.0.2");
     380           1 :     ret = sss_get_dualstack_addresses(dyndns_test_ctx,
     381             :                                       (struct sockaddr *) &sin,
     382             :                                       &addrlist);
     383           1 :     assert_int_equal(ret, EOK);
     384             : 
     385           1 :     ret = be_nsupdate_create_fwd_msg(dyndns_test_ctx, NULL, NULL, "bran_stark",
     386             :                                      1234, DYNDNS_REMOVE_A | DYNDNS_REMOVE_AAAA,
     387             :                                      addrlist, &msg);
     388           1 :     assert_int_equal(ret, EOK);
     389             : 
     390           1 :     assert_string_equal(msg,
     391             :                         "\nupdate delete bran_stark. in A\n"
     392             :                         "update add bran_stark. 1234 in A 192.168.0.2\n"
     393             :                         "send\n"
     394             :                         "update delete bran_stark. in AAAA\n"
     395             :                         "update add bran_stark. 1234 in AAAA 2001:cdba::555\n"
     396             :                         "send\n");
     397           1 :     talloc_zfree(msg);
     398             : 
     399             :     /* fallback case realm and server */
     400           1 :     ret = be_nsupdate_create_fwd_msg(dyndns_test_ctx, "North", "Winterfell",
     401             :                                      "bran_stark",
     402             :                                      1234, DYNDNS_REMOVE_A | DYNDNS_REMOVE_AAAA,
     403             :                                      addrlist, &msg);
     404           1 :     assert_int_equal(ret, EOK);
     405             : 
     406           1 :     assert_string_equal(msg,
     407             :                         "server Winterfell\n"
     408             :                         "realm North\n"
     409             :                         "update delete bran_stark. in A\n"
     410             :                         "update add bran_stark. 1234 in A 192.168.0.2\n"
     411             :                         "send\n"
     412             :                         "update delete bran_stark. in AAAA\n"
     413             :                         "update add bran_stark. 1234 in AAAA 2001:cdba::555\n"
     414             :                         "send\n");
     415           1 :     talloc_zfree(msg);
     416             : 
     417             :     /* just realm */
     418           1 :     ret = be_nsupdate_create_fwd_msg(dyndns_test_ctx, "North", NULL,
     419             :                                      "bran_stark",
     420             :                                      1234, DYNDNS_REMOVE_A | DYNDNS_REMOVE_AAAA,
     421             :                                      addrlist, &msg);
     422           1 :     assert_int_equal(ret, EOK);
     423             : 
     424           1 :     assert_string_equal(msg,
     425             :                         "realm North\n"
     426             :                         "update delete bran_stark. in A\n"
     427             :                         "update add bran_stark. 1234 in A 192.168.0.2\n"
     428             :                         "send\n"
     429             :                         "update delete bran_stark. in AAAA\n"
     430             :                         "update add bran_stark. 1234 in AAAA 2001:cdba::555\n"
     431             :                         "send\n");
     432           1 :     talloc_zfree(msg);
     433             : 
     434             :     /* just server */
     435           1 :     ret = be_nsupdate_create_fwd_msg(dyndns_test_ctx, NULL, "Winterfell",
     436             :                                      "bran_stark",
     437             :                                      1234, DYNDNS_REMOVE_A | DYNDNS_REMOVE_AAAA,
     438             :                                      addrlist, &msg);
     439           1 :     assert_int_equal(ret, EOK);
     440             : 
     441           1 :     assert_string_equal(msg,
     442             :                         "server Winterfell\n"
     443             :                         "\n"
     444             :                         "update delete bran_stark. in A\n"
     445             :                         "update add bran_stark. 1234 in A 192.168.0.2\n"
     446             :                         "send\n"
     447             :                         "update delete bran_stark. in AAAA\n"
     448             :                         "update add bran_stark. 1234 in AAAA 2001:cdba::555\n"
     449             :                         "send\n");
     450           1 :     talloc_zfree(msg);
     451             : 
     452             :     /* remove just A */
     453           1 :     ret = be_nsupdate_create_fwd_msg(dyndns_test_ctx, NULL, NULL, "bran_stark",
     454             :                                      1234, DYNDNS_REMOVE_A,
     455             :                                      addrlist, &msg);
     456           1 :     assert_int_equal(ret, EOK);
     457             : 
     458           1 :     assert_string_equal(msg,
     459             :                         "\nupdate delete bran_stark. in A\n"
     460             :                         "update add bran_stark. 1234 in A 192.168.0.2\n"
     461             :                         "send\n"
     462             :                         "update add bran_stark. 1234 in AAAA 2001:cdba::555\n"
     463             :                         "send\n");
     464           1 :     talloc_zfree(msg);
     465             : 
     466             :     /* remove just AAAA */
     467           1 :     ret = be_nsupdate_create_fwd_msg(dyndns_test_ctx, NULL, NULL, "bran_stark",
     468             :                                      1234, DYNDNS_REMOVE_AAAA,
     469             :                                      addrlist, &msg);
     470           1 :     assert_int_equal(ret, EOK);
     471             : 
     472           1 :     assert_string_equal(msg,
     473             :                         "\nupdate add bran_stark. 1234 in A 192.168.0.2\n"
     474             :                         "send\n"
     475             :                         "update delete bran_stark. in AAAA\n"
     476             :                         "update add bran_stark. 1234 in AAAA 2001:cdba::555\n"
     477             :                         "send\n");
     478           1 :     talloc_zfree(msg);
     479             : 
     480           1 :     talloc_free(addrlist);
     481           1 :     assert_true(check_leaks_pop(dyndns_test_ctx) == true);
     482           1 : }
     483             : 
     484           1 : void dyndns_test_create_fwd_msg_mult(void **state)
     485             : {
     486             :     errno_t ret;
     487             :     char *msg;
     488             :     struct sss_iface_addr *addrlist;
     489             :     int i;
     490             : 
     491           1 :     check_leaks_push(dyndns_test_ctx);
     492             : 
     493             :     /* getifaddrs is called twice in sss_get_dualstack_addresses() */
     494           3 :     for (i = 0; i < 2; i++) {
     495           2 :         will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
     496           2 :         will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
     497           2 :         will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
     498           2 :         will_return_getifaddrs("eth0", "2001:cdba::444", AF_INET6);
     499           2 :         will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
     500             :     }
     501             : 
     502             :     struct sockaddr_in sin;
     503           1 :     memset(&sin, 0, sizeof (sin));
     504           1 :     sin.sin_family = AF_INET;
     505           1 :     sin.sin_addr.s_addr = inet_addr ("192.168.0.2");
     506           1 :     ret = sss_get_dualstack_addresses(dyndns_test_ctx,
     507             :                                       (struct sockaddr *) &sin,
     508             :                                       &addrlist);
     509           1 :     assert_int_equal(ret, EOK);
     510             : 
     511           1 :     ret = be_nsupdate_create_fwd_msg(dyndns_test_ctx, NULL, NULL, "bran_stark",
     512             :                                      1234, DYNDNS_REMOVE_A | DYNDNS_REMOVE_AAAA,
     513             :                                      addrlist, &msg);
     514           1 :     assert_int_equal(ret, EOK);
     515             : 
     516           1 :     assert_string_equal(msg,
     517             :                         "\nupdate delete bran_stark. in A\n"
     518             :                         "update add bran_stark. 1234 in A 192.168.0.1\n"
     519             :                         "update add bran_stark. 1234 in A 192.168.0.2\n"
     520             :                         "send\n"
     521             :                         "update delete bran_stark. in AAAA\n"
     522             :                         "update add bran_stark. 1234 in AAAA 2001:cdba::444\n"
     523             :                         "update add bran_stark. 1234 in AAAA 2001:cdba::555\n"
     524             :                         "send\n");
     525           1 :     talloc_zfree(msg);
     526             : 
     527           1 :     talloc_free(addrlist);
     528           1 :     assert_true(check_leaks_pop(dyndns_test_ctx) == true);
     529           1 : }
     530             : 
     531           1 : void dyndns_test_create_fwd_msg_A(void **state)
     532             : {
     533             :     errno_t ret;
     534             :     char *msg;
     535             :     struct sss_iface_addr *addrlist;
     536             :     int i;
     537             : 
     538           1 :     check_leaks_push(dyndns_test_ctx);
     539             : 
     540             :     /* getifaddrs is called twice in sss_get_dualstack_addresses() */
     541           3 :     for (i = 0; i < 2; i++) {
     542           2 :         will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
     543           2 :         will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
     544           2 :         will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
     545             :     }
     546             : 
     547             :     struct sockaddr_in sin;
     548           1 :     memset(&sin, 0, sizeof (sin));
     549           1 :     sin.sin_family = AF_INET;
     550           1 :     sin.sin_addr.s_addr = inet_addr ("192.168.0.2");
     551           1 :     ret = sss_get_dualstack_addresses(dyndns_test_ctx,
     552             :                                       (struct sockaddr *) &sin,
     553             :                                       &addrlist);
     554           1 :     assert_int_equal(ret, EOK);
     555             : 
     556           1 :     ret = be_nsupdate_create_fwd_msg(dyndns_test_ctx, NULL, NULL, "bran_stark",
     557             :                                      1234, DYNDNS_REMOVE_A | DYNDNS_REMOVE_AAAA,
     558             :                                      addrlist, &msg);
     559           1 :     assert_int_equal(ret, EOK);
     560             : 
     561           1 :     assert_string_equal(msg,
     562             :                         "\nupdate delete bran_stark. in A\n"
     563             :                         "update add bran_stark. 1234 in A 192.168.0.1\n"
     564             :                         "update add bran_stark. 1234 in A 192.168.0.2\n"
     565             :                         "send\n"
     566             :                         "update delete bran_stark. in AAAA\n"
     567             :                         "send\n");
     568           1 :     talloc_zfree(msg);
     569             : 
     570           1 :     talloc_free(addrlist);
     571           1 :     assert_true(check_leaks_pop(dyndns_test_ctx) == true);
     572           1 : }
     573             : 
     574           1 : void dyndns_test_create_fwd_msg_AAAA(void **state)
     575             : {
     576             :     errno_t ret;
     577             :     char *msg;
     578             :     struct sss_iface_addr *addrlist;
     579             :     int i;
     580             : 
     581           1 :     check_leaks_push(dyndns_test_ctx);
     582             : 
     583             :     /* getifaddrs is called twice in sss_get_dualstack_addresses() */
     584           3 :     for (i = 0; i < 2; i++) {
     585           2 :         will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
     586           2 :         will_return_getifaddrs("eth0", "2001:cdba::444", AF_INET6);
     587           2 :         will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
     588             :     }
     589             : 
     590             :     struct sockaddr_in6 sin;
     591           1 :     memset(&sin, 0, sizeof (sin));
     592           1 :     sin.sin6_family = AF_INET6;
     593           1 :     ret = inet_pton(AF_INET6, "2001:cdba::555", &sin.sin6_addr.s6_addr);
     594           1 :     assert_int_equal(ret, 1);
     595           1 :     ret = sss_get_dualstack_addresses(dyndns_test_ctx,
     596             :                                       (struct sockaddr *) &sin,
     597             :                                       &addrlist);
     598           1 :     assert_int_equal(ret, EOK);
     599             : 
     600           1 :     ret = be_nsupdate_create_fwd_msg(dyndns_test_ctx, NULL, NULL, "bran_stark",
     601             :                                      1234, DYNDNS_REMOVE_A | DYNDNS_REMOVE_AAAA,
     602             :                                      addrlist, &msg);
     603           1 :     assert_int_equal(ret, EOK);
     604             : 
     605           1 :     assert_string_equal(msg,
     606             :                         "\nupdate delete bran_stark. in A\n"
     607             :                         "send\n"
     608             :                         "update delete bran_stark. in AAAA\n"
     609             :                         "update add bran_stark. 1234 in AAAA 2001:cdba::444\n"
     610             :                         "update add bran_stark. 1234 in AAAA 2001:cdba::555\n"
     611             :                         "send\n");
     612           1 :     talloc_zfree(msg);
     613             : 
     614           1 :     talloc_free(addrlist);
     615           1 :     assert_true(check_leaks_pop(dyndns_test_ctx) == true);
     616           1 : }
     617             : 
     618           1 : void dyndns_test_dualstack(void **state)
     619             : {
     620             :     errno_t ret;
     621             :     struct sss_iface_addr *addrlist;
     622             :     struct sss_iface_addr *sss_if_addrs;
     623             :     char straddr[128];
     624             :     int i;
     625             : 
     626           1 :     check_leaks_push(dyndns_test_ctx);
     627             : 
     628             :     /* getifaddrs is called twice in sss_get_dualstack_addresses() */
     629           3 :     for (i = 0; i < 2; i++) {
     630           2 :         will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
     631           2 :         will_return_getifaddrs("eth1", "192.168.0.1", AF_INET);
     632           2 :         will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
     633           2 :         will_return_getifaddrs("eth1", "2001:cdba::444", AF_INET6);
     634           2 :         will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
     635             :     }
     636             : 
     637             :     struct sockaddr_in sin;
     638           1 :     memset(&sin, 0, sizeof (sin));
     639           1 :     sin.sin_family = AF_INET;
     640           1 :     sin.sin_addr.s_addr = inet_addr ("192.168.0.2");
     641           1 :     ret = sss_get_dualstack_addresses(dyndns_test_ctx,
     642             :                                       (struct sockaddr *) &sin,
     643             :                                       &addrlist);
     644           1 :     assert_int_equal(ret, EOK);
     645             : 
     646           1 :     sss_if_addrs = addrlist;
     647           1 :     assert_non_null(sss_if_addrs);
     648           1 :     assert_non_null(sss_if_addrs->addr);
     649           1 :     assert_non_null(sss_if_addrs->next);
     650           1 :     assert_null(sss_if_addrs->prev);
     651             : 
     652           1 :     assert_non_null(inet_ntop(AF_INET6,
     653             :                               &((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr,
     654             :                               straddr, INET6_ADDRSTRLEN));
     655             :     /* ip addresses are returned in different order */
     656           1 :     assert_string_equal(straddr, "2001:cdba::555");
     657             : 
     658           1 :     sss_if_addrs = addrlist->next;
     659           1 :     assert_non_null(sss_if_addrs);
     660           1 :     assert_non_null(sss_if_addrs->addr);
     661           1 :     assert_null(sss_if_addrs->next);
     662           1 :     assert_non_null(sss_if_addrs->prev);
     663             : 
     664           1 :     assert_non_null(inet_ntop(AF_INET,
     665             :                               &((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr,
     666             :                               straddr, INET_ADDRSTRLEN));
     667             :     /* ip addresses are returned in different order */
     668           1 :     assert_string_equal(straddr, "192.168.0.2");
     669             : 
     670           1 :     talloc_free(addrlist);
     671             : 
     672           1 :     assert_true(check_leaks_pop(dyndns_test_ctx) == true);
     673           1 : }
     674             : 
     675           1 : void dyndns_test_dualstack_multiple_addresses(void **state)
     676             : {
     677             :     errno_t ret;
     678             :     struct sss_iface_addr *addrlist;
     679             :     struct sss_iface_addr *sss_if_addrs;
     680             :     char straddr[128];
     681             :     int i;
     682             : 
     683           1 :     check_leaks_push(dyndns_test_ctx);
     684             : 
     685             :     /* getifaddrs is called twice in sss_get_dualstack_addresses() */
     686           3 :     for (i = 0; i < 2; i++) {
     687           2 :         will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
     688           2 :         will_return_getifaddrs("eth0", "192.168.0.1", AF_INET);
     689             :         /* loopback - invalid for dns (should be skipped) */
     690           2 :         will_return_getifaddrs("eth0", "::1", AF_INET6);
     691             :         /* linklocal - invalid for dns (should be skipped) */
     692           2 :         will_return_getifaddrs("eth0", "fe80::5054:ff:fe4a:65ae", AF_INET6);
     693           2 :         will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
     694           2 :         will_return_getifaddrs("eth0", "2001:cdba::444", AF_INET6);
     695           2 :         will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
     696             :     }
     697             : 
     698             :     struct sockaddr_in sin;
     699           1 :     memset(&sin, 0, sizeof (sin));
     700           1 :     sin.sin_family = AF_INET;
     701           1 :     sin.sin_addr.s_addr = inet_addr ("192.168.0.2");
     702           1 :     ret = sss_get_dualstack_addresses(dyndns_test_ctx,
     703             :                                       (struct sockaddr *) &sin,
     704             :                                       &addrlist);
     705           1 :     assert_int_equal(ret, EOK);
     706             : 
     707           1 :     sss_if_addrs = addrlist;
     708           1 :     assert_non_null(sss_if_addrs);
     709           1 :     assert_non_null(sss_if_addrs->addr);
     710           1 :     assert_non_null(sss_if_addrs->next);
     711           1 :     assert_null(sss_if_addrs->prev);
     712             : 
     713           1 :     assert_non_null(inet_ntop(AF_INET6,
     714             :                               &((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr,
     715             :                               straddr, INET6_ADDRSTRLEN));
     716             :     /* ip addresses are returned in different order */
     717           1 :     assert_string_equal(straddr, "2001:cdba::444");
     718             : 
     719           1 :     sss_if_addrs = sss_if_addrs->next;
     720           1 :     assert_non_null(sss_if_addrs);
     721           1 :     assert_non_null(sss_if_addrs->addr);
     722           1 :     assert_non_null(sss_if_addrs->prev);
     723           1 :     assert_non_null(sss_if_addrs->next);
     724             : 
     725           1 :     assert_non_null(inet_ntop(AF_INET6,
     726             :                               &((struct sockaddr_in6 *) sss_if_addrs->addr)->sin6_addr,
     727             :                               straddr, INET6_ADDRSTRLEN));
     728             :     /* ip addresses are returned in different order */
     729           1 :     assert_string_equal(straddr, "2001:cdba::555");
     730             : 
     731           1 :     sss_if_addrs = sss_if_addrs->next;
     732           1 :     assert_non_null(sss_if_addrs);
     733           1 :     assert_non_null(sss_if_addrs->addr);
     734           1 :     assert_non_null(sss_if_addrs->next);
     735           1 :     assert_non_null(sss_if_addrs->prev);
     736             : 
     737           1 :     assert_non_null(inet_ntop(AF_INET,
     738             :                               &((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr,
     739             :                               straddr, INET_ADDRSTRLEN));
     740             :     /* ip addresses are returned in different order */
     741           1 :     assert_string_equal(straddr, "192.168.0.1");
     742             : 
     743           1 :     sss_if_addrs = sss_if_addrs->next;
     744           1 :     assert_non_null(sss_if_addrs);
     745           1 :     assert_non_null(sss_if_addrs->addr);
     746           1 :     assert_null(sss_if_addrs->next);
     747           1 :     assert_non_null(sss_if_addrs->prev);
     748             : 
     749           1 :     assert_non_null(inet_ntop(AF_INET,
     750             :                               &((struct sockaddr_in *) sss_if_addrs->addr)->sin_addr,
     751             :                               straddr, INET_ADDRSTRLEN));
     752             :     /* ip addresses are returned in different order */
     753           1 :     assert_string_equal(straddr, "192.168.0.2");
     754             : 
     755           1 :     talloc_free(addrlist);
     756             : 
     757           1 :     assert_true(check_leaks_pop(dyndns_test_ctx) == true);
     758           1 : }
     759             : 
     760           1 : void dyndns_test_dualstack_no_iface(void **state)
     761             : {
     762             :     errno_t ret;
     763             :     struct sss_iface_addr *addrlist;
     764             : 
     765           1 :     check_leaks_push(dyndns_test_ctx);
     766             : 
     767           1 :     will_return_getifaddrs("eth0", "192.168.0.2", AF_INET);
     768           1 :     will_return_getifaddrs("eth1", "192.168.0.1", AF_INET);
     769           1 :     will_return_getifaddrs("eth0", "2001:cdba::555", AF_INET6);
     770           1 :     will_return_getifaddrs("eth1", "2001:cdba::444", AF_INET6);
     771           1 :     will_return_getifaddrs(NULL, NULL, 0); /* sentinel */
     772             : 
     773             :     struct sockaddr_in sin;
     774           1 :     memset(&sin, 0, sizeof (sin));
     775           1 :     sin.sin_family = AF_INET;
     776           1 :     sin.sin_addr.s_addr = inet_addr ("192.168.0.3");
     777           1 :     ret = sss_get_dualstack_addresses(dyndns_test_ctx,
     778             :                                       (struct sockaddr *) &sin,
     779             :                                       &addrlist);
     780           1 :     assert_int_equal(ret, ENOENT);
     781             : 
     782           1 :     assert_true(check_leaks_pop(dyndns_test_ctx) == true);
     783           1 : }
     784             : 
     785           1 : void dyndns_test_ok(void **state)
     786             : {
     787             :     struct tevent_req *req;
     788             :     errno_t ret;
     789             :     TALLOC_CTX *tmp_ctx;
     790             : 
     791           1 :     tmp_ctx = talloc_new(global_talloc_context);
     792           1 :     assert_non_null(tmp_ctx);
     793           1 :     check_leaks_push(tmp_ctx);
     794             : 
     795           1 :     dyndns_test_ctx->state = MOCK_NSUPDATE_OK;
     796             : 
     797           1 :     req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev,
     798             :                            BE_NSUPDATE_AUTH_GSS_TSIG,
     799             :                            discard_const("test message"), false);
     800           1 :     assert_non_null(req);
     801           1 :     tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx);
     802             : 
     803             :     /* Wait until the test finishes with EOK */
     804           1 :     ret = test_ev_loop(dyndns_test_ctx->tctx);
     805           1 :     DEBUG(SSSDBG_TRACE_LIBS,
     806             :           "Child request returned [%d]: %s\n", ret, strerror(ret));
     807           1 :     assert_int_equal(ret, EOK);
     808             : 
     809           1 :     assert_true(WIFEXITED(dyndns_test_ctx->child_status));
     810           1 :     assert_int_equal(WEXITSTATUS(dyndns_test_ctx->child_status), 0);
     811             : 
     812           1 :     assert_true(check_leaks_pop(tmp_ctx) == true);
     813           1 :     talloc_free(tmp_ctx);
     814           1 : }
     815             : 
     816           1 : void dyndns_test_error(void **state)
     817             : {
     818             :     struct tevent_req *req;
     819             :     errno_t ret;
     820             :     TALLOC_CTX *tmp_ctx;
     821             : 
     822           1 :     tmp_ctx = talloc_new(global_talloc_context);
     823           1 :     assert_non_null(tmp_ctx);
     824           1 :     check_leaks_push(tmp_ctx);
     825             : 
     826           1 :     dyndns_test_ctx->state = MOCK_NSUPDATE_ERR;
     827             : 
     828           1 :     req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev,
     829             :                            BE_NSUPDATE_AUTH_GSS_TSIG,
     830             :                            discard_const("test message"), false);
     831           1 :     assert_non_null(req);
     832           1 :     tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx);
     833             : 
     834             :     /* Wait until the test finishes with EIO (child error) */
     835           1 :     ret = test_ev_loop(dyndns_test_ctx->tctx);
     836           1 :     DEBUG(SSSDBG_TRACE_LIBS,
     837             :           "Child request returned [%d]: %s\n", ret, strerror(ret));
     838           1 :     assert_int_equal(ret, ERR_DYNDNS_FAILED);
     839             : 
     840           1 :     assert_true(WIFEXITED(dyndns_test_ctx->child_status));
     841           1 :     assert_int_equal(WEXITSTATUS(dyndns_test_ctx->child_status), 1);
     842             : 
     843           1 :     assert_true(check_leaks_pop(tmp_ctx) == true);
     844           1 :     talloc_free(tmp_ctx);
     845           1 : }
     846             : 
     847           1 : void dyndns_test_timeout(void **state)
     848             : {
     849             :     struct tevent_req *req;
     850             :     errno_t ret;
     851             :     TALLOC_CTX *tmp_ctx;
     852             : 
     853           1 :     tmp_ctx = talloc_new(global_talloc_context);
     854           1 :     assert_non_null(tmp_ctx);
     855           1 :     check_leaks_push(tmp_ctx);
     856             : 
     857           1 :     dyndns_test_ctx->state = MOCK_NSUPDATE_TIMEOUT;
     858             : 
     859           1 :     req = be_nsupdate_send(tmp_ctx, dyndns_test_ctx->tctx->ev,
     860             :                            BE_NSUPDATE_AUTH_GSS_TSIG,
     861             :                            discard_const("test message"), false);
     862           1 :     assert_non_null(req);
     863           1 :     tevent_req_set_callback(req, dyndns_test_done, dyndns_test_ctx);
     864             : 
     865             :     /* Wait until the test finishes with EIO (child error) */
     866           1 :     ret = test_ev_loop(dyndns_test_ctx->tctx);
     867             : 
     868             :     /* The event queue may not be empty. We need to make sure that all events
     869             :      * are processed. Unfortunately, tevent_loop_wait() contains a bug that
     870             :      * prevents exiting the loop even if there are no remaining events, thus
     871             :      * we have to use tevent_loop_once().
     872             :      *
     873             :      * FIXME: use tevent_loop_wait() when the bug is fixed
     874             :      * https://bugzilla.samba.org/show_bug.cgi?id=10012
     875             :      */
     876           1 :     tevent_loop_once(dyndns_test_ctx->tctx->ev); /* SIGCHLD handler */
     877           1 :     tevent_loop_once(dyndns_test_ctx->tctx->ev); /* nsupdate_child_handler */
     878             : 
     879           1 :     DEBUG(SSSDBG_TRACE_LIBS,
     880             :           "Child request returned [%d]: %s\n", ret, strerror(ret));
     881           1 :     assert_int_equal(ret, ERR_DYNDNS_TIMEOUT);
     882             : 
     883           1 :     assert_true(check_leaks_pop(tmp_ctx) == true);
     884           1 :     talloc_free(tmp_ctx);
     885           1 : }
     886             : 
     887           2 : void dyndns_test_timer(void *pvt)
     888             : {
     889           2 :     struct dyndns_test_ctx *ctx = talloc_get_type(pvt, struct dyndns_test_ctx);
     890             :     static int ncalls = 0;
     891             : 
     892           2 :     ncalls++;
     893           2 :     if (ncalls == 1) {
     894           1 :         be_nsupdate_timer_schedule(ctx->tctx->ev, ctx->update_ctx);
     895           1 :     } else if (ncalls == 2) {
     896           1 :         ctx->tctx->done = true;
     897             :     }
     898           2 :     ctx->tctx->error = ERR_OK;
     899           2 : }
     900             : 
     901           1 : void dyndns_test_interval(void **state)
     902             : {
     903             :     errno_t ret;
     904             :     TALLOC_CTX *tmp_ctx;
     905             : 
     906           1 :     tmp_ctx = talloc_new(global_talloc_context);
     907           1 :     assert_non_null(tmp_ctx);
     908           1 :     check_leaks_push(tmp_ctx);
     909             : 
     910           1 :     ret = be_nsupdate_init(tmp_ctx, dyndns_test_ctx->be_ctx, NULL,
     911           1 :                            &dyndns_test_ctx->update_ctx);
     912           1 :     assert_int_equal(ret, EOK);
     913             : 
     914           2 :     ret = be_nsupdate_init_timer(dyndns_test_ctx->update_ctx,
     915           1 :                                  dyndns_test_ctx->be_ctx->ev,
     916             :                                  dyndns_test_timer, dyndns_test_ctx);
     917           1 :     assert_int_equal(ret, EOK);
     918             : 
     919             :     /* Wait until the timer hits */
     920           1 :     ret = test_ev_loop(dyndns_test_ctx->tctx);
     921           1 :     DEBUG(SSSDBG_TRACE_LIBS,
     922             :           "Child request returned [%d]: %s\n", ret, strerror(ret));
     923           1 :     assert_int_equal(ret, ERR_OK);
     924             : 
     925           1 :     talloc_free(dyndns_test_ctx->update_ctx);
     926           1 :     assert_true(check_leaks_pop(tmp_ctx) == true);
     927           1 :     talloc_free(tmp_ctx);
     928           1 : }
     929             : 
     930             : /* Testsuite setup and teardown */
     931           8 : static int dyndns_test_setup(void **state)
     932             : {
     933           8 :     struct sss_test_conf_param params[] = {
     934             :         { "dyndns_update", "true" },
     935             :         { "dyndns_refresh_interval", "2" },
     936             :         { NULL, NULL },             /* Sentinel */
     937             :     };
     938             : 
     939           8 :     assert_true(leak_check_setup());
     940           8 :     global_mock_context = talloc_new(global_talloc_context);
     941           8 :     assert_non_null(global_mock_context);
     942             : 
     943           8 :     dyndns_test_ctx = talloc_zero(global_talloc_context, struct dyndns_test_ctx);
     944           8 :     assert_non_null(dyndns_test_ctx);
     945             : 
     946           8 :     dyndns_test_ctx->tctx = create_dom_test_ctx(dyndns_test_ctx, TESTS_PATH,
     947             :                                                 TEST_CONF_DB, TEST_DOM_NAME,
     948             :                                                 TEST_ID_PROVIDER, params);
     949           8 :     assert_non_null(dyndns_test_ctx->tctx);
     950             : 
     951           8 :     dyndns_test_ctx->be_ctx = mock_be_ctx(dyndns_test_ctx, dyndns_test_ctx->tctx);
     952           8 :     assert_non_null(dyndns_test_ctx->be_ctx);
     953             : 
     954           8 :     return 0;
     955             : }
     956             : 
     957           8 : static int dyndns_test_simple_setup(void **state)
     958             : {
     959           8 :     assert_true(leak_check_setup());
     960           8 :     global_mock_context = talloc_new(global_talloc_context);
     961           8 :     assert_non_null(global_mock_context);
     962             : 
     963           8 :     dyndns_test_ctx = talloc_zero(global_talloc_context, struct dyndns_test_ctx);
     964           8 :     assert_non_null(dyndns_test_ctx);
     965           8 :     return 0;
     966             : }
     967             : 
     968          16 : static int dyndns_test_teardown(void **state)
     969             : {
     970          16 :     talloc_free(dyndns_test_ctx);
     971          16 :     talloc_free(global_mock_context);
     972          16 :     assert_true(leak_check_teardown());
     973          16 :     return 0;
     974             : }
     975             : 
     976           1 : int main(int argc, const char *argv[])
     977             : {
     978             :     int rv;
     979           1 :     int no_cleanup = 0;
     980             :     poptContext pc;
     981             :     int opt;
     982           7 :     struct poptOption long_options[] = {
     983             :         POPT_AUTOHELP
     984           5 :         SSSD_DEBUG_OPTS
     985             :         {"no-cleanup", 'n', POPT_ARG_NONE, &no_cleanup, 0,
     986           1 :          _("Do not delete the test database after a test run"), NULL },
     987             :         POPT_TABLEEND
     988             :     };
     989             : 
     990           1 :     const struct CMUnitTest tests[] = {
     991             :         /* Utility functions unit test */
     992             :         cmocka_unit_test_setup_teardown(dyndns_test_sss_iface_addr_get_misc,
     993             :                                         dyndns_test_simple_setup,
     994             :                                         dyndns_test_teardown),
     995             :         cmocka_unit_test_setup_teardown(dyndns_test_get_ifaddr,
     996             :                                         dyndns_test_simple_setup,
     997             :                                         dyndns_test_teardown),
     998             :         cmocka_unit_test_setup_teardown(dyndns_test_get_multi_ifaddr,
     999             :                                         dyndns_test_simple_setup,
    1000             :                                         dyndns_test_teardown),
    1001             :         cmocka_unit_test_setup_teardown(dyndns_test_get_ifaddr_enoent,
    1002             :                                         dyndns_test_simple_setup,
    1003             :                                         dyndns_test_teardown),
    1004             :         cmocka_unit_test_setup_teardown(dyndns_test_addr_list_as_str_list,
    1005             :                                         dyndns_test_simple_setup,
    1006             :                                         dyndns_test_teardown),
    1007             : 
    1008             :         /* Dynamic DNS update unit tests*/
    1009             :         cmocka_unit_test_setup_teardown(dyndns_test_ok,
    1010             :                                         dyndns_test_setup,
    1011             :                                         dyndns_test_teardown),
    1012             :         cmocka_unit_test_setup_teardown(dyndns_test_error,
    1013             :                                         dyndns_test_setup,
    1014             :                                         dyndns_test_teardown),
    1015             :         cmocka_unit_test_setup_teardown(dyndns_test_timeout,
    1016             :                                         dyndns_test_setup,
    1017             :                                         dyndns_test_teardown),
    1018             :         cmocka_unit_test_setup_teardown(dyndns_test_interval,
    1019             :                                         dyndns_test_setup,
    1020             :                                         dyndns_test_teardown),
    1021             : 
    1022             :         /* Dynamic DNS dualstack unit tests*/
    1023             :         cmocka_unit_test_setup_teardown(dyndns_test_dualstack,
    1024             :                                         dyndns_test_simple_setup,
    1025             :                                         dyndns_test_teardown),
    1026             :         cmocka_unit_test_setup_teardown(dyndns_test_dualstack_multiple_addresses,
    1027             :                                         dyndns_test_simple_setup,
    1028             :                                         dyndns_test_teardown),
    1029             :         cmocka_unit_test_setup_teardown(dyndns_test_dualstack_no_iface,
    1030             :                                         dyndns_test_simple_setup,
    1031             :                                         dyndns_test_teardown),
    1032             : 
    1033             :         /* Messages for nsupdate */
    1034             :         cmocka_unit_test_setup_teardown(dyndns_test_create_fwd_msg,
    1035             :                                         dyndns_test_setup,
    1036             :                                         dyndns_test_teardown),
    1037             :         cmocka_unit_test_setup_teardown(dyndns_test_create_fwd_msg_mult,
    1038             :                                         dyndns_test_setup,
    1039             :                                         dyndns_test_teardown),
    1040             :         cmocka_unit_test_setup_teardown(dyndns_test_create_fwd_msg_A,
    1041             :                                         dyndns_test_setup,
    1042             :                                         dyndns_test_teardown),
    1043             :         cmocka_unit_test_setup_teardown(dyndns_test_create_fwd_msg_AAAA,
    1044             :                                         dyndns_test_setup,
    1045             :                                         dyndns_test_teardown),
    1046             :     };
    1047             : 
    1048             :     /* Set debug level to invalid value so we can deside if -d 0 was used. */
    1049           1 :     debug_level = SSSDBG_INVALID;
    1050             : 
    1051           1 :     pc = poptGetContext(argv[0], argc, argv, long_options, 0);
    1052           1 :     while((opt = poptGetNextOpt(pc)) != -1) {
    1053             :         switch(opt) {
    1054             :         default:
    1055           0 :             fprintf(stderr, "\nInvalid option %s: %s\n\n",
    1056             :                     poptBadOption(pc, 0), poptStrerror(opt));
    1057           0 :             poptPrintUsage(pc, stderr, 0);
    1058           0 :             return 1;
    1059             :         }
    1060             :     }
    1061           1 :     poptFreeContext(pc);
    1062             : 
    1063           1 :     DEBUG_CLI_INIT(debug_level);
    1064             : 
    1065             :     /* Even though normally the tests should clean up after themselves
    1066             :      * they might not after a failed run. Remove the old db to be sure */
    1067           1 :     tests_set_cwd();
    1068           1 :     test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
    1069           1 :     test_dom_suite_setup(TESTS_PATH);
    1070             : 
    1071           1 :     rv = cmocka_run_group_tests(tests, NULL, NULL);
    1072           1 :     if (rv == 0 && !no_cleanup) {
    1073           1 :         test_dom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, TEST_DOM_NAME);
    1074             :     }
    1075           1 :     return rv;
    1076             : }

Generated by: LCOV version 1.10