LCOV - code coverage report
Current view: top level - tests - resolv-tests.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 226 440 51.4 %
Date: 2012-11-29 Functions: 13 23 56.5 %
Branches: 51 330 15.5 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :    SSSD
       3                 :            : 
       4                 :            :    Async resolver tests
       5                 :            : 
       6                 :            :    Authors:
       7                 :            :         Martin Nagy <mnagy@redhat.com>
       8                 :            :         Jakub Hrozek <jhrozek@redhat.com>
       9                 :            : 
      10                 :            :    Copyright (C) Red Hat, Inc 2009
      11                 :            : 
      12                 :            :    This program is free software; you can redistribute it and/or modify
      13                 :            :    it under the terms of the GNU General Public License as published by
      14                 :            :    the Free Software Foundation; either version 3 of the License, or
      15                 :            :    (at your option) any later version.
      16                 :            : 
      17                 :            :    This program is distributed in the hope that it will be useful,
      18                 :            :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      19                 :            :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20                 :            :    GNU General Public License for more details.
      21                 :            : 
      22                 :            :    You should have received a copy of the GNU General Public License
      23                 :            :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24                 :            : */
      25                 :            : 
      26                 :            : #include <stdlib.h>
      27                 :            : #include <check.h>
      28                 :            : #include <string.h>
      29                 :            : #include <talloc.h>
      30                 :            : #include <tevent.h>
      31                 :            : #include <popt.h>
      32                 :            : #include <arpa/inet.h>
      33                 :            : 
      34                 :            : #include "tests/common.h"
      35                 :            : #include "util/util.h"
      36                 :            : #include "tests/common.h"
      37                 :            : 
      38                 :            : /* Interface under test */
      39                 :            : #include "resolv/async_resolv.h"
      40                 :            : 
      41                 :            : #define RESOLV_DEFAULT_TIMEOUT 5
      42                 :            : 
      43                 :            : static int use_net_test;
      44                 :            : static char *txt_host;
      45                 :            : static char *srv_host;
      46                 :            : 
      47                 :            : struct resolv_test_ctx {
      48                 :            :     struct tevent_context *ev;
      49                 :            :     struct resolv_ctx *resolv;
      50                 :            : 
      51                 :            :     enum {
      52                 :            :         TESTING_HOSTNAME,
      53                 :            :         TESTING_TXT,
      54                 :            :         TESTING_SRV,
      55                 :            :     } tested_function;
      56                 :            : 
      57                 :            :     int error;
      58                 :            :     bool done;
      59                 :            : };
      60                 :            : 
      61                 :          4 : static int setup_resolv_test(int timeout, struct resolv_test_ctx **ctx)
      62                 :            : {
      63                 :            :     struct resolv_test_ctx *test_ctx;
      64                 :            :     int ret;
      65                 :            : 
      66                 :          4 :     test_ctx = talloc_zero(global_talloc_context, struct resolv_test_ctx);
      67         [ -  + ]:          4 :     if (test_ctx == NULL) {
      68                 :          0 :         fail("Could not allocate memory for test context");
      69                 :          0 :         return ENOMEM;
      70                 :            :     }
      71                 :            : 
      72                 :          4 :     test_ctx->ev = tevent_context_init(test_ctx);
      73         [ -  + ]:          4 :     if (test_ctx->ev == NULL) {
      74                 :          0 :         fail("Could not init tevent context");
      75                 :          0 :         talloc_free(test_ctx);
      76                 :          0 :         return EFAULT;
      77                 :            :     }
      78                 :            : 
      79                 :          4 :     ret = resolv_init(test_ctx, test_ctx->ev, timeout, &test_ctx->resolv);
      80         [ -  + ]:          4 :     if (ret != EOK) {
      81                 :          0 :         fail("Could not init resolv context");
      82                 :          0 :         talloc_free(test_ctx);
      83                 :          0 :         return ret;
      84                 :            :     }
      85                 :            : 
      86                 :          4 :     *ctx = test_ctx;
      87                 :          4 :     return EOK;
      88                 :            : }
      89                 :            : 
      90                 :          3 : static int test_loop(struct resolv_test_ctx *data)
      91                 :            : {
      92         [ +  + ]:         16 :     while (!data->done)
      93                 :         13 :         tevent_loop_once(data->ev);
      94                 :            : 
      95                 :          3 :     return data->error;
      96                 :            : }
      97                 :            : 
      98                 :          1 : START_TEST(test_copy_hostent)
      99                 :            : {
     100                 :            :     void *ctx;
     101                 :            :     struct resolv_hostent *rhe;
     102                 :            : 
     103                 :          1 :     char name[] = "foo.example.com";
     104                 :          1 :     char alias_1[] = "bar.example.com";
     105                 :          1 :     char alias_2[] = "baz.example.com";
     106                 :          1 :     char *aliases[] = { alias_1, alias_2, NULL };
     107                 :          1 :     struct in_addr addr_1 = { 1234 };
     108                 :          1 :     struct in_addr addr_2 = { 5678 };
     109                 :          1 :     int ttl_1 = 12;
     110                 :          1 :     int ttl_2 = 34;
     111                 :          1 :     char *addr_list[] = { (char *) &addr_2, (char *) &addr_1, NULL };
     112                 :          1 :     struct hostent he = {
     113                 :            :             name, aliases, AF_INET,
     114                 :            :             sizeof(addr_1), addr_list
     115                 :            :     };
     116                 :          1 :     struct ares_addrttl attl[] = { { addr_1, ttl_1 }, { addr_2, ttl_2 } };
     117                 :            : 
     118                 :          1 :     ctx = talloc_new(global_talloc_context);
     119                 :          1 :     fail_if(ctx == NULL);
     120                 :            : 
     121                 :          1 :     check_leaks_push(ctx);
     122                 :            : 
     123                 :          1 :     rhe = resolv_copy_hostent_ares(ctx, &he, AF_INET, &attl, 2);
     124                 :            : 
     125                 :          1 :     fail_if(rhe == NULL);
     126                 :          1 :     fail_if(strcmp(rhe->name, name));
     127                 :          1 :     fail_if(strcmp(rhe->aliases[0], alias_1));
     128                 :          1 :     fail_if(strcmp(rhe->aliases[1], alias_2));
     129                 :          1 :     fail_if(rhe->aliases[2] != NULL);
     130                 :          1 :     fail_if(rhe->family != AF_INET);
     131                 :          1 :     fail_if(memcmp(rhe->addr_list[0]->ipaddr, &addr_1, sizeof(addr_1)));
     132                 :          1 :     fail_if(rhe->addr_list[0]->ttl != ttl_1);
     133                 :          1 :     fail_if(memcmp(rhe->addr_list[1]->ipaddr, &addr_2, sizeof(addr_2)));
     134                 :          1 :     fail_if(rhe->addr_list[1]->ttl != ttl_2);
     135                 :          1 :     fail_if(rhe->addr_list[2] != NULL);
     136                 :            : 
     137                 :          1 :     talloc_zfree(rhe);
     138                 :            : 
     139                 :          1 :     rhe = resolv_copy_hostent(ctx, &he);
     140                 :          1 :     fail_if(rhe == NULL);
     141                 :          1 :     fail_if(strcmp(rhe->name, name));
     142                 :          1 :     fail_if(strcmp(rhe->aliases[0], alias_1));
     143                 :          1 :     fail_if(strcmp(rhe->aliases[1], alias_2));
     144                 :          1 :     fail_if(rhe->aliases[2] != NULL);
     145                 :          1 :     fail_if(rhe->family != AF_INET);
     146                 :          1 :     fail_if(memcmp(rhe->addr_list[0]->ipaddr, &addr_2, sizeof(addr_1)));
     147                 :          1 :     fail_if(rhe->addr_list[0]->ttl != RESOLV_DEFAULT_TTL);
     148                 :          1 :     fail_if(memcmp(rhe->addr_list[1]->ipaddr, &addr_1, sizeof(addr_2)));
     149                 :          1 :     fail_if(rhe->addr_list[1]->ttl != RESOLV_DEFAULT_TTL);
     150                 :          1 :     fail_if(rhe->addr_list[2] != NULL);
     151                 :            : 
     152                 :          1 :     talloc_free(rhe);
     153                 :            : 
     154                 :          1 :     check_leaks_pop(ctx);
     155                 :            : }
     156                 :          1 : END_TEST
     157                 :            : 
     158                 :          1 : static void test_ip_addr(struct tevent_req *req)
     159                 :            : {
     160                 :            :     int recv_status;
     161                 :            :     int status;
     162                 :            :     struct resolv_hostent *rhostent;
     163                 :            :     int i;
     164                 :          1 :     struct resolv_test_ctx *test_ctx = tevent_req_callback_data(req,
     165                 :            :                                                                 struct resolv_test_ctx);
     166                 :            : 
     167                 :          1 :     test_ctx->done = true;
     168                 :            : 
     169                 :          1 :     recv_status = resolv_gethostbyname_recv(req, test_ctx,
     170                 :            :                                             &status, NULL, &rhostent);
     171                 :          1 :     talloc_zfree(req);
     172         [ -  + ]:          1 :     if (recv_status != EOK) {
     173 [ #  # ][ #  # ]:          0 :         DEBUG(2, ("resolv_gethostbyname_recv failed: %d\n", recv_status));
         [ #  # ][ #  # ]
                 [ #  # ]
     174                 :          0 :         test_ctx->error = recv_status;
     175                 :          1 :         return;
     176                 :            :     }
     177 [ +  - ][ -  + ]:          1 :     DEBUG(7, ("resolv_gethostbyname_recv status: %d\n", status));
         [ #  # ][ #  # ]
                 [ #  # ]
     178                 :            : 
     179                 :          1 :     test_ctx->error = ENOENT;
     180         [ +  + ]:          2 :     for (i = 0; rhostent->addr_list[i]; i++) {
     181                 :            :         char addr_buf[256];
     182                 :          1 :         inet_ntop(rhostent->family,
     183                 :          1 :                   rhostent->addr_list[i]->ipaddr,
     184                 :            :                   addr_buf, sizeof(addr_buf));
     185                 :            : 
     186         [ +  - ]:          1 :         if (strcmp(addr_buf, "127.0.0.1") == 0) {
     187                 :          1 :             test_ctx->error = EOK;
     188                 :            :         }
     189                 :            :     }
     190                 :          1 :     talloc_free(rhostent);
     191                 :            : }
     192                 :            : 
     193                 :          1 : START_TEST(test_resolv_ip_addr)
     194                 :            : {
     195                 :            :     struct resolv_test_ctx *test_ctx;
     196                 :          1 :     int ret = EOK;
     197                 :            :     struct tevent_req *req;
     198                 :          1 :     const char *hostname = "127.0.0.1";
     199                 :            : 
     200                 :          1 :     ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
     201         [ -  + ]:          1 :     if (ret != EOK) {
     202                 :          0 :         fail("Could not set up test");
     203                 :          1 :         return;
     204                 :            :     }
     205                 :            : 
     206                 :          1 :     check_leaks_push(test_ctx);
     207                 :          1 :     req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
     208                 :          1 :                                     test_ctx->resolv, hostname, IPV4_ONLY,
     209                 :            :                                     default_host_dbs);
     210 [ +  - ][ -  + ]:          1 :     DEBUG(7, ("Sent resolv_gethostbyname\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     211         [ -  + ]:          1 :     if (req == NULL) {
     212                 :          0 :         ret = ENOMEM;
     213                 :            :     }
     214                 :            : 
     215         [ +  - ]:          1 :     if (ret == EOK) {
     216                 :          1 :         tevent_req_set_callback(req, test_ip_addr, test_ctx);
     217                 :          1 :         ret = test_loop(test_ctx);
     218                 :            :     }
     219                 :            : 
     220                 :          1 :     check_leaks_pop(test_ctx);
     221                 :          1 :     fail_unless(ret == EOK);
     222                 :            : 
     223                 :          1 :     talloc_zfree(test_ctx);
     224                 :            : }
     225                 :            : END_TEST
     226                 :            : 
     227                 :          0 : static void test_localhost(struct tevent_req *req)
     228                 :            : {
     229                 :            :     int recv_status;
     230                 :            :     int status;
     231                 :            :     struct resolv_hostent *rhostent;
     232                 :            :     int i;
     233                 :          0 :     struct resolv_test_ctx *test_ctx = tevent_req_callback_data(req,
     234                 :            :                                                                 struct resolv_test_ctx);
     235                 :            : 
     236                 :          0 :     test_ctx->done = true;
     237                 :            : 
     238                 :          0 :     recv_status = resolv_gethostbyname_recv(req, test_ctx,
     239                 :            :                                             &status, NULL, &rhostent);
     240                 :          0 :     talloc_zfree(req);
     241         [ #  # ]:          0 :     if (recv_status != EOK) {
     242 [ #  # ][ #  # ]:          0 :         DEBUG(2, ("resolv_gethostbyname_recv failed: %d\n", recv_status));
         [ #  # ][ #  # ]
                 [ #  # ]
     243                 :          0 :         test_ctx->error = recv_status;
     244                 :          0 :         return;
     245                 :            :     }
     246 [ #  # ][ #  # ]:          0 :     DEBUG(7, ("resolv_gethostbyname_recv status: %d\n", status));
         [ #  # ][ #  # ]
                 [ #  # ]
     247                 :            : 
     248                 :          0 :     test_ctx->error = ENOENT;
     249         [ #  # ]:          0 :     for (i = 0; rhostent->addr_list[i]; i++) {
     250                 :            :         char addr_buf[256];
     251                 :          0 :         inet_ntop(rhostent->family, rhostent->addr_list[i]->ipaddr,
     252                 :            :                   addr_buf, sizeof(addr_buf));
     253                 :            : 
     254                 :            :         /* test that localhost resolves to 127.0.0.1 or ::1 */
     255 [ #  # ][ #  # ]:          0 :         if (strcmp(addr_buf, "127.0.0.1") == 0 || strcmp(addr_buf, "::1") == 0) {
         [ #  # ][ #  # ]
                 [ #  # ]
     256                 :          0 :             test_ctx->error = EOK;
     257                 :            :         }
     258                 :            :     }
     259                 :          0 :     talloc_free(rhostent);
     260                 :            : }
     261                 :            : 
     262                 :          0 : START_TEST(test_resolv_localhost)
     263                 :            : {
     264                 :            :     struct resolv_test_ctx *test_ctx;
     265                 :          0 :     int ret = EOK;
     266                 :            :     struct tevent_req *req;
     267                 :          0 :     const char *hostname = "localhost.localdomain";
     268                 :            : 
     269                 :          0 :     ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
     270         [ #  # ]:          0 :     if (ret != EOK) {
     271                 :          0 :         fail("Could not set up test");
     272                 :          0 :         return;
     273                 :            :     }
     274                 :            : 
     275                 :          0 :     check_leaks_push(test_ctx);
     276                 :          0 :     req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
     277                 :          0 :                                     test_ctx->resolv, hostname, IPV4_FIRST,
     278                 :            :                                     default_host_dbs);
     279 [ #  # ][ #  # ]:          0 :     DEBUG(7, ("Sent resolv_gethostbyname\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     280         [ #  # ]:          0 :     if (req == NULL) {
     281                 :          0 :         ret = ENOMEM;
     282                 :            :     }
     283                 :            : 
     284         [ #  # ]:          0 :     if (ret == EOK) {
     285                 :          0 :         tevent_req_set_callback(req, test_localhost, test_ctx);
     286                 :          0 :         ret = test_loop(test_ctx);
     287                 :            :     }
     288                 :            : 
     289                 :          0 :     check_leaks_pop(test_ctx);
     290                 :          0 :     fail_unless(ret == EOK);
     291                 :            : 
     292                 :          0 :     talloc_zfree(test_ctx);
     293                 :            : }
     294                 :            : END_TEST
     295                 :            : 
     296                 :          0 : static void test_negative(struct tevent_req *req)
     297                 :            : {
     298                 :            :      int recv_status;
     299                 :            :      int status;
     300                 :            :      struct resolv_hostent *hostent;
     301                 :            :      struct resolv_test_ctx *test_ctx;
     302                 :            : 
     303                 :          0 :      test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx);
     304                 :          0 :      test_ctx->done = true;
     305                 :            : 
     306                 :          0 :      recv_status = resolv_gethostbyname_recv(req, test_ctx,
     307                 :            :                                              &status, NULL, &hostent);
     308                 :          0 :      talloc_zfree(req);
     309         [ #  # ]:          0 :      if (recv_status == EOK) {
     310 [ #  # ][ #  # ]:          0 :          DEBUG(7, ("resolv_gethostbyname_recv succeeded in a negative test\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     311                 :          0 :          return;
     312                 :            :      }
     313                 :            : 
     314                 :          0 :      test_ctx->error = status;
     315 [ #  # ][ #  # ]:          0 :      DEBUG(2, ("resolv_gethostbyname_recv status: %d: %s\n", status, resolv_strerror(status)));
         [ #  # ][ #  # ]
                 [ #  # ]
     316                 :            : }
     317                 :            : 
     318                 :          0 : START_TEST(test_resolv_negative)
     319                 :            : {
     320                 :          0 :     int ret = EOK;
     321                 :            :     struct tevent_req *req;
     322                 :          0 :     const char *hostname = "sssd.foo";
     323                 :            :     struct resolv_test_ctx *test_ctx;
     324                 :            : 
     325                 :          0 :     ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
     326         [ #  # ]:          0 :     if (ret != EOK) {
     327                 :          0 :         fail("Could not set up test");
     328                 :          0 :         return;
     329                 :            :     }
     330                 :            : 
     331                 :          0 :     check_leaks_push(test_ctx);
     332                 :          0 :     req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
     333                 :          0 :                                     test_ctx->resolv, hostname, IPV4_FIRST,
     334                 :            :                                     default_host_dbs);
     335 [ #  # ][ #  # ]:          0 :     DEBUG(7, ("Sent resolv_gethostbyname\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     336         [ #  # ]:          0 :     if (req == NULL) {
     337                 :          0 :         ret = ENOMEM;
     338                 :            :     }
     339                 :            : 
     340         [ #  # ]:          0 :     if (ret == EOK) {
     341                 :          0 :         tevent_req_set_callback(req, test_negative, test_ctx);
     342                 :          0 :         ret = test_loop(test_ctx);
     343                 :            :     }
     344                 :            : 
     345                 :          0 :     check_leaks_pop(test_ctx);
     346                 :            : 
     347                 :          0 :     fail_unless(ret != EOK);
     348                 :          0 :     fail_unless(test_ctx->error == ARES_ENOTFOUND);
     349                 :          0 :     talloc_zfree(test_ctx);
     350                 :            : }
     351                 :            : END_TEST
     352                 :            : 
     353                 :          0 : static void test_internet(struct tevent_req *req)
     354                 :            : {
     355                 :            :     int recv_status;
     356                 :            :     int status;
     357                 :            :     struct resolv_test_ctx *test_ctx;
     358                 :            :     void *tmp_ctx;
     359                 :          0 :     struct resolv_hostent *rhostent = NULL;
     360                 :          0 :     struct ares_txt_reply *txt_replies = NULL, *txtptr;
     361                 :          0 :     struct ares_srv_reply *srv_replies = NULL, *srvptr;
     362                 :            :     int i;
     363                 :            : 
     364                 :          0 :     test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx);
     365                 :            : 
     366                 :          0 :     test_ctx->done = true;
     367                 :            : 
     368                 :          0 :     tmp_ctx = talloc_new(test_ctx);
     369                 :          0 :     check_leaks_push(tmp_ctx);
     370                 :            : 
     371   [ #  #  #  # ]:          0 :     switch (test_ctx->tested_function) {
     372                 :            :     case TESTING_HOSTNAME:
     373                 :          0 :         recv_status = resolv_gethostbyname_recv(req, tmp_ctx,
     374                 :            :                                                 &status, NULL, &rhostent);
     375         [ #  # ]:          0 :         test_ctx->error = (rhostent->name == NULL) ? ENOENT : EOK;
     376         [ #  # ]:          0 :         if (test_ctx->error == EOK) {
     377                 :            :             char addr_buf[256];
     378         [ #  # ]:          0 :             for (i=0; rhostent->addr_list[i]; i++) {
     379                 :          0 :                 inet_ntop(rhostent->family,
     380                 :          0 :                           rhostent->addr_list[i]->ipaddr,
     381                 :            :                           addr_buf, sizeof(addr_buf));
     382 [ #  # ][ #  # ]:          0 :                 DEBUG(2, ("Found address %s with TTL %d\n",
         [ #  # ][ #  # ]
                 [ #  # ]
     383                 :            :                           addr_buf, rhostent->addr_list[i]->ttl));
     384                 :            :             }
     385                 :            :         }
     386                 :            :         break;
     387                 :            :     case TESTING_TXT:
     388                 :          0 :         recv_status = resolv_gettxt_recv(tmp_ctx, req, &status, NULL,
     389                 :            :                                          &txt_replies);
     390         [ #  # ]:          0 :         test_ctx->error = (txt_replies == NULL) ? ENOENT : EOK;
     391         [ #  # ]:          0 :         for (txtptr = txt_replies; txtptr != NULL; txtptr = txtptr->next) {
     392 [ #  # ][ #  # ]:          0 :             DEBUG(2, ("TXT Record: %s\n", txtptr->txt));
         [ #  # ][ #  # ]
                 [ #  # ]
     393                 :            :         }
     394                 :            :         break;
     395                 :            :     case TESTING_SRV:
     396                 :          0 :         recv_status = resolv_getsrv_recv(tmp_ctx, req, &status, NULL,
     397                 :            :                                          &srv_replies);
     398         [ #  # ]:          0 :         test_ctx->error = (srv_replies == NULL) ? ENOENT : EOK;
     399         [ #  # ]:          0 :         for (srvptr = srv_replies; srvptr != NULL; srvptr = srvptr->next) {
     400 [ #  # ][ #  # ]:          0 :             DEBUG(2, ("SRV Record: %d %d %d %s\n", srvptr->weight,
         [ #  # ][ #  # ]
                 [ #  # ]
     401                 :            :                       srvptr->priority, srvptr->port,
     402                 :            :                       srvptr->host));
     403                 :            :         }
     404                 :            :         break;
     405                 :            :     default:
     406                 :            :         recv_status = EINVAL;
     407                 :            :         break;
     408                 :            :     }
     409                 :          0 :     talloc_zfree(req);
     410                 :          0 :     fail_if(recv_status != EOK, "The recv function failed: %d", recv_status);
     411 [ #  # ][ #  # ]:          0 :     DEBUG(7, ("recv status: %d\n", status));
         [ #  # ][ #  # ]
                 [ #  # ]
     412                 :            : 
     413         [ #  # ]:          0 :     if (rhostent != NULL) {
     414                 :          0 :         talloc_free(rhostent);
     415         [ #  # ]:          0 :     } else if (txt_replies != NULL) {
     416                 :          0 :         talloc_free(txt_replies);
     417         [ #  # ]:          0 :     } else if (srv_replies != NULL) {
     418                 :          0 :         talloc_free(srv_replies);
     419                 :            :     }
     420                 :          0 :     check_leaks_pop(tmp_ctx);
     421                 :          0 : }
     422                 :            : 
     423                 :          0 : START_TEST(test_resolv_internet)
     424                 :            : {
     425                 :          0 :     int ret = EOK;
     426                 :            :     struct tevent_req *req;
     427                 :          0 :     const char *hostname = "redhat.com";
     428                 :            :     struct resolv_test_ctx *test_ctx;
     429                 :            : 
     430                 :          0 :     ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
     431         [ #  # ]:          0 :     if (ret != EOK) {
     432                 :          0 :         fail("Could not set up test");
     433                 :          0 :         return;
     434                 :            :     }
     435                 :          0 :     test_ctx->tested_function = TESTING_HOSTNAME;
     436                 :            : 
     437                 :          0 :     check_leaks_push(test_ctx);
     438                 :          0 :     req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
     439                 :          0 :                                     test_ctx->resolv, hostname, IPV4_FIRST,
     440                 :            :                                     default_host_dbs);
     441 [ #  # ][ #  # ]:          0 :     DEBUG(7, ("Sent resolv_gethostbyname\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     442         [ #  # ]:          0 :     if (req == NULL) {
     443                 :          0 :         ret = ENOMEM;
     444                 :            :     }
     445                 :            : 
     446         [ #  # ]:          0 :     if (ret == EOK) {
     447                 :          0 :         tevent_req_set_callback(req, test_internet, test_ctx);
     448                 :          0 :         ret = test_loop(test_ctx);
     449                 :            :     }
     450                 :            : 
     451                 :          0 :     fail_unless(ret == EOK);
     452                 :          0 :     check_leaks_pop(test_ctx);
     453                 :          0 :     talloc_zfree(test_ctx);
     454                 :            : }
     455                 :            : END_TEST
     456                 :            : 
     457                 :          0 : START_TEST(test_resolv_internet_txt)
     458                 :            : {
     459                 :            :     int ret;
     460                 :            :     struct tevent_req *req;
     461                 :            :     struct resolv_test_ctx *test_ctx;
     462                 :            : 
     463                 :          0 :     ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
     464                 :          0 :     fail_if(ret != EOK, "Could not set up test");
     465                 :          0 :     test_ctx->tested_function = TESTING_TXT;
     466                 :            : 
     467                 :          0 :     check_leaks_push(test_ctx);
     468                 :            : 
     469                 :          0 :     req = resolv_gettxt_send(test_ctx, test_ctx->ev, test_ctx->resolv, txt_host);
     470                 :          0 :     fail_if(req == NULL, "Function resolv_gettxt_send failed");
     471                 :            : 
     472                 :          0 :     tevent_req_set_callback(req, test_internet, test_ctx);
     473                 :          0 :     ret = test_loop(test_ctx);
     474                 :          0 :     fail_unless(ret == EOK);
     475                 :            : 
     476                 :          0 :     check_leaks_pop(test_ctx);
     477                 :            : 
     478                 :          0 :     talloc_zfree(test_ctx);
     479                 :            : }
     480                 :          0 : END_TEST
     481                 :            : 
     482                 :          0 : START_TEST(test_resolv_internet_srv)
     483                 :            : {
     484                 :            :     int ret;
     485                 :            :     struct tevent_req *req;
     486                 :            :     struct resolv_test_ctx *test_ctx;
     487                 :            : 
     488                 :          0 :     ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
     489                 :          0 :     fail_if(ret != EOK, "Could not set up test");
     490                 :          0 :     test_ctx->tested_function = TESTING_SRV;
     491                 :            : 
     492                 :          0 :     check_leaks_push(test_ctx);
     493                 :            : 
     494                 :          0 :     req = resolv_getsrv_send(test_ctx, test_ctx->ev, test_ctx->resolv, srv_host);
     495                 :          0 :     fail_if(req == NULL, "Function resolv_getsrv_send failed");
     496                 :            : 
     497                 :          0 :     tevent_req_set_callback(req, test_internet, test_ctx);
     498                 :          0 :     ret = test_loop(test_ctx);
     499                 :          0 :     fail_unless(ret == EOK);
     500                 :            : 
     501                 :          0 :     check_leaks_pop(test_ctx);
     502                 :            : 
     503                 :          0 :     talloc_zfree(test_ctx);
     504                 :            : }
     505                 :          0 : END_TEST
     506                 :            : 
     507                 :          1 : static void resolv_free_context(struct tevent_context *ev,
     508                 :            :                                 struct tevent_timer *te,
     509                 :            :                                 struct timeval t, void *ptr)
     510                 :            : {
     511                 :          1 :     struct resolv_ctx *rctx = talloc_get_type(ptr, struct resolv_ctx);
     512 [ +  - ][ -  + ]:          1 :     DEBUG(7, ("freeing the context\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     513                 :            : 
     514                 :          1 :     talloc_free(rctx);
     515                 :          1 : }
     516                 :            : 
     517                 :          2 : static void resolv_free_done(struct tevent_context *ev,
     518                 :            :                              struct tevent_timer *te,
     519                 :            :                              struct timeval t, void *ptr)
     520                 :            : {
     521                 :          2 :     struct resolv_test_ctx *tctx = talloc_get_type(ptr, struct resolv_test_ctx);
     522 [ +  - ][ -  + ]:          2 :     DEBUG(7, ("marking test as done\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     523                 :            : 
     524                 :          2 :     tctx->error = EOK;
     525                 :          2 :     tctx->done = true;
     526                 :          2 : }
     527                 :            : 
     528                 :          1 : START_TEST(test_resolv_free_context)
     529                 :            : {
     530                 :          1 :     int ret = EOK;
     531                 :            :     struct tevent_req *req;
     532                 :          1 :     const char *hostname = "redhat.com";
     533                 :            :     struct resolv_test_ctx *test_ctx;
     534                 :            :     struct tevent_timer *free_timer, *terminate_timer;
     535                 :            :     struct timeval free_tv, terminate_tv;
     536                 :            : 
     537                 :          1 :     ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
     538         [ -  + ]:          1 :     if (ret != EOK) {
     539                 :          0 :         fail("Could not set up test");
     540                 :          1 :         return;
     541                 :            :     }
     542                 :            : 
     543                 :          1 :     req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
     544                 :          1 :                                     test_ctx->resolv, hostname, IPV4_FIRST,
     545                 :            :                                     default_host_dbs);
     546 [ +  - ][ -  + ]:          1 :     DEBUG(7, ("Sent resolv_gethostbyname\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     547         [ -  + ]:          1 :     if (req == NULL) {
     548                 :          0 :         fail("Error calling resolv_gethostbyname_send");
     549                 :            :         goto done;
     550                 :            :     }
     551                 :            : 
     552                 :          1 :     gettimeofday(&free_tv, NULL);
     553                 :          1 :     free_tv.tv_sec += 1;
     554                 :          1 :     free_tv.tv_usec = 0;
     555                 :          1 :     terminate_tv.tv_sec  = free_tv.tv_sec + 1;
     556                 :          1 :     terminate_tv.tv_usec = 0;
     557                 :            : 
     558                 :          1 :     free_timer = tevent_add_timer(test_ctx->ev, test_ctx, free_tv, resolv_free_context, test_ctx->resolv);
     559         [ -  + ]:          1 :     if (free_timer == NULL) {
     560                 :          0 :         fail("Error calling tevent_add_timer");
     561                 :            :         goto done;
     562                 :            :     }
     563                 :            : 
     564                 :          1 :     terminate_timer = tevent_add_timer(test_ctx->ev, test_ctx, terminate_tv, resolv_free_done, test_ctx);
     565         [ -  + ]:          1 :     if (terminate_timer == NULL) {
     566                 :          0 :         fail("Error calling tevent_add_timer");
     567                 :            :         goto done;
     568                 :            :     }
     569                 :            : 
     570                 :          1 :     ret = test_loop(test_ctx);
     571                 :          1 :     fail_unless(ret == EOK);
     572                 :            : 
     573                 :            : done:
     574                 :          1 :     talloc_zfree(test_ctx);
     575                 :            : }
     576                 :            : END_TEST
     577                 :            : 
     578                 :          1 : static void resolv_free_req(struct tevent_context *ev,
     579                 :            :                             struct tevent_timer *te,
     580                 :            :                             struct timeval t, void *ptr)
     581                 :            : {
     582                 :          1 :     struct tevent_req *req = talloc_get_type(ptr, struct tevent_req);
     583 [ +  - ][ -  + ]:          1 :     DEBUG(7, ("freeing the request\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     584                 :            : 
     585                 :          1 :     talloc_free(req);
     586                 :          1 : }
     587                 :            : 
     588                 :          1 : START_TEST(test_resolv_sort_srv_reply)
     589                 :            : {
     590                 :            :     int ret;
     591                 :          1 :     struct ares_srv_reply *replies = NULL;
     592                 :          1 :     struct ares_srv_reply *r, *prev = NULL;
     593                 :            :     struct resolv_test_ctx *test_ctx;
     594                 :          1 :     int num_replies = 3;
     595                 :            :     int i;
     596                 :            : 
     597                 :          1 :     ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
     598         [ -  + ]:          1 :     if (ret != EOK) {
     599                 :          0 :         fail("Could not set up test");
     600                 :          1 :         return;
     601                 :            :     }
     602                 :            : 
     603                 :          1 :     check_leaks_push(test_ctx);
     604                 :            : 
     605                 :            :     /* prepare linked list with reversed values */
     606         [ +  + ]:          4 :     for (i = 0; i<num_replies; i++) {
     607                 :          3 :         r = talloc_zero(test_ctx, struct ares_srv_reply);
     608                 :          3 :         fail_if(r == NULL);
     609                 :          3 :         r->priority = num_replies-i;
     610                 :          3 :         r->weight   = i;
     611                 :            : 
     612         [ +  + ]:          3 :         if (!replies) {
     613                 :          1 :             replies = r;
     614                 :          1 :             prev = r;
     615                 :            :         } else {
     616                 :          2 :             prev->next = r;
     617                 :          2 :             prev = prev->next;
     618                 :            :         }
     619                 :            :     }
     620                 :            : 
     621                 :            :     /* do the sort */
     622                 :          1 :     ret = resolv_sort_srv_reply(test_ctx, &replies);
     623                 :          1 :     fail_if(ret != EOK);
     624                 :            : 
     625                 :            :     /* check if the list is sorted */
     626                 :          1 :     prev = NULL;
     627         [ +  + ]:          4 :     for (i = 1, r = replies; r; r=r->next, i++) {
     628                 :          3 :         talloc_zfree(prev);
     629                 :          3 :         prev = r;
     630                 :          3 :         fail_unless(r->priority == i);
     631                 :            :     }
     632                 :          1 :     talloc_zfree(prev);
     633                 :            : 
     634                 :            :     /* check if the list is complete */
     635                 :          1 :     fail_unless(i-1 == num_replies);
     636                 :            : 
     637                 :            :     /* test if the weighting algorithm runs..not much do
     638                 :            :      * deterministically test here since it is based on
     639                 :            :      * random weight-selection */
     640                 :          1 :     replies = NULL;
     641         [ +  + ]:          4 :     for (i = 0; i<num_replies; i++) {
     642                 :          3 :         r = talloc_zero(test_ctx, struct ares_srv_reply);
     643                 :          3 :         fail_if(r == NULL);
     644                 :          3 :         r->priority = i % 2 + 1;
     645                 :          3 :         r->weight   = i;
     646                 :            : 
     647         [ +  + ]:          3 :         if (!replies) {
     648                 :          1 :             replies = r;
     649                 :          1 :             prev = r;
     650                 :            :         } else {
     651                 :          2 :             prev->next = r;
     652                 :          2 :             prev = prev->next;
     653                 :            :         }
     654                 :            :     }
     655                 :            : 
     656                 :            :     /* do the sort */
     657                 :          1 :     ret = resolv_sort_srv_reply(test_ctx, &replies);
     658                 :          1 :     fail_if(ret != EOK);
     659                 :            : 
     660                 :            :     /* clean up */
     661                 :          1 :     prev = NULL;
     662         [ +  + ]:          4 :     for (i = 1, r = replies; r; r=r->next, i++) {
     663                 :          3 :         talloc_zfree(prev);
     664                 :          3 :         prev = r;
     665                 :            :     }
     666                 :          1 :     talloc_zfree(prev);
     667                 :            : 
     668                 :            : 
     669                 :            :     /* check for leaks */
     670                 :          1 :     check_leaks_pop(test_ctx);
     671                 :          1 :     talloc_zfree(test_ctx);
     672                 :            : }
     673                 :            : END_TEST
     674                 :            : 
     675                 :          1 : START_TEST(test_resolv_free_req)
     676                 :            : {
     677                 :          1 :     int ret = EOK;
     678                 :            :     struct tevent_req *req;
     679                 :          1 :     const char *hostname = "redhat.com";
     680                 :            :     struct resolv_test_ctx *test_ctx;
     681                 :            :     struct tevent_timer *free_timer, *terminate_timer;
     682                 :            :     struct timeval free_tv, terminate_tv;
     683                 :            : 
     684                 :          1 :     ret = setup_resolv_test(RESOLV_DEFAULT_TIMEOUT, &test_ctx);
     685         [ -  + ]:          1 :     if (ret != EOK) {
     686                 :          0 :         fail("Could not set up test");
     687                 :          1 :         return;
     688                 :            :     }
     689                 :            : 
     690                 :          1 :     check_leaks_push(test_ctx);
     691                 :          1 :     req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
     692                 :          1 :                                     test_ctx->resolv, hostname, IPV4_FIRST,
     693                 :            :                                     default_host_dbs);
     694 [ +  - ][ -  + ]:          1 :     DEBUG(7, ("Sent resolv_gethostbyname\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     695         [ -  + ]:          1 :     if (req == NULL) {
     696                 :          0 :         fail("Error calling resolv_gethostbyname_send");
     697                 :            :         goto done;
     698                 :            :     }
     699                 :            : 
     700                 :          1 :     gettimeofday(&free_tv, NULL);
     701                 :          1 :     free_tv.tv_sec += 1;
     702                 :          1 :     free_tv.tv_usec = 0;
     703                 :          1 :     terminate_tv.tv_sec  = free_tv.tv_sec + 1;
     704                 :          1 :     terminate_tv.tv_usec = 0;
     705                 :            : 
     706                 :          1 :     free_timer = tevent_add_timer(test_ctx->ev, test_ctx, free_tv, resolv_free_req, req);
     707         [ -  + ]:          1 :     if (free_timer == NULL) {
     708                 :          0 :         fail("Error calling tevent_add_timer");
     709                 :            :         goto done;
     710                 :            :     }
     711                 :            : 
     712                 :          1 :     terminate_timer = tevent_add_timer(test_ctx->ev, test_ctx, terminate_tv, resolv_free_done, test_ctx);
     713         [ -  + ]:          1 :     if (terminate_timer == NULL) {
     714                 :          0 :         fail("Error calling tevent_add_timer");
     715                 :            :         goto done;
     716                 :            :     }
     717                 :            : 
     718                 :          1 :     ret = test_loop(test_ctx);
     719                 :          1 :     check_leaks_pop(test_ctx);
     720                 :          1 :     fail_unless(ret == EOK);
     721                 :            : 
     722                 :            : done:
     723                 :          1 :     talloc_zfree(test_ctx);
     724                 :            : }
     725                 :            : END_TEST
     726                 :            : 
     727                 :          0 : static void test_timeout(struct tevent_req *req)
     728                 :            : {
     729                 :            :     int recv_status;
     730                 :            :     int status;
     731                 :            :     struct resolv_test_ctx *test_ctx;
     732                 :            :     TALLOC_CTX *tmp_ctx;
     733                 :          0 :     struct resolv_hostent *rhostent = NULL;
     734                 :            : 
     735                 :          0 :     test_ctx = tevent_req_callback_data(req, struct resolv_test_ctx);
     736                 :            : 
     737                 :          0 :     test_ctx->done = true;
     738                 :            : 
     739                 :          0 :     tmp_ctx = talloc_new(test_ctx);
     740                 :          0 :     check_leaks_push(tmp_ctx);
     741                 :            : 
     742                 :          0 :     fail_unless(test_ctx->tested_function == TESTING_HOSTNAME);
     743                 :          0 :     recv_status = resolv_gethostbyname_recv(req, tmp_ctx,
     744                 :            :                                             &status, NULL, &rhostent);
     745                 :          0 :     talloc_zfree(req);
     746                 :          0 :     fail_unless(recv_status == ETIMEDOUT);
     747                 :          0 :     fail_unless(status == ARES_ETIMEOUT);
     748                 :          0 :     check_leaks_pop(tmp_ctx);
     749                 :          0 :     talloc_free(tmp_ctx);
     750                 :          0 : }
     751                 :            : 
     752                 :          0 : START_TEST(test_resolv_timeout)
     753                 :            : {
     754                 :            :     struct resolv_test_ctx *test_ctx;
     755                 :            :     errno_t ret;
     756                 :            :     struct tevent_req *req;
     757                 :          0 :     const char *hostname = "redhat.com";
     758                 :            : 
     759                 :          0 :     ret = setup_resolv_test(0, &test_ctx);
     760         [ #  # ]:          0 :     if (ret != EOK) {
     761                 :          0 :         fail("Could not set up test");
     762                 :          0 :         return;
     763                 :            :     }
     764                 :            : 
     765                 :          0 :     test_ctx->tested_function = TESTING_HOSTNAME;
     766                 :            : 
     767                 :          0 :     req = resolv_gethostbyname_send(test_ctx, test_ctx->ev,
     768                 :            :                                     test_ctx->resolv, hostname, IPV4_FIRST,
     769                 :            :                                     default_host_dbs);
     770 [ #  # ][ #  # ]:          0 :     DEBUG(7, ("Sent resolv_gethostbyname\n"));
         [ #  # ][ #  # ]
                 [ #  # ]
     771         [ #  # ]:          0 :     if (req == NULL) {
     772                 :          0 :         ret = ENOMEM;
     773                 :            :     }
     774                 :            : 
     775         [ #  # ]:          0 :     if (ret == EOK) {
     776                 :          0 :         tevent_req_set_callback(req, test_timeout, test_ctx);
     777                 :          0 :         ret = test_loop(test_ctx);
     778                 :            :     }
     779                 :            : 
     780                 :          0 :     fail_unless(ret == EOK);
     781                 :          0 :     talloc_zfree(test_ctx);
     782                 :            : }
     783                 :            : END_TEST
     784                 :            : 
     785                 :          6 : Suite *create_resolv_suite(void)
     786                 :            : {
     787                 :          6 :     Suite *s = suite_create("resolv");
     788                 :            : 
     789                 :          6 :     TCase *tc_resolv = tcase_create("RESOLV Tests");
     790                 :            : 
     791                 :          6 :     tcase_add_checked_fixture(tc_resolv, leak_check_setup, leak_check_teardown);
     792                 :            :     /* Do some testing */
     793                 :          6 :     tcase_add_test(tc_resolv, test_copy_hostent);
     794                 :          6 :     tcase_add_test(tc_resolv, test_resolv_ip_addr);
     795                 :          6 :     tcase_add_test(tc_resolv, test_resolv_sort_srv_reply);
     796         [ -  + ]:          6 :     if (use_net_test) {
     797                 :          0 :         tcase_add_test(tc_resolv, test_resolv_internet);
     798                 :          0 :         tcase_add_test(tc_resolv, test_resolv_negative);
     799                 :          0 :         tcase_add_test(tc_resolv, test_resolv_localhost);
     800                 :          0 :         tcase_add_test(tc_resolv, test_resolv_timeout);
     801         [ #  # ]:          0 :         if (txt_host != NULL) {
     802                 :          0 :             tcase_add_test(tc_resolv, test_resolv_internet_txt);
     803                 :            :         }
     804         [ #  # ]:          0 :         if (srv_host != NULL) {
     805                 :          0 :             tcase_add_test(tc_resolv, test_resolv_internet_srv);
     806                 :            :         }
     807                 :            :     }
     808                 :          6 :     tcase_add_test(tc_resolv, test_resolv_free_context);
     809                 :          6 :     tcase_add_test(tc_resolv, test_resolv_free_req);
     810                 :            : 
     811                 :            :     /* Add all test cases to the test suite */
     812                 :          6 :     suite_add_tcase(s, tc_resolv);
     813                 :            : 
     814                 :          6 :     return s;
     815                 :            : }
     816                 :            : 
     817                 :          6 : int main(int argc, const char *argv[])
     818                 :            : {
     819                 :            :     int opt;
     820                 :            :     poptContext pc;
     821                 :            :     int failure_count;
     822                 :            :     Suite *resolv_suite;
     823                 :            :     SRunner *sr;
     824                 :          6 :     int debug = 0;
     825                 :            : 
     826                 :          6 :     struct poptOption long_options[] = {
     827                 :            :         POPT_AUTOHELP
     828                 :            :         { "debug-level", 'd', POPT_ARG_INT, &debug, 0, "Set debug level", NULL },
     829                 :            :         { "use-net-test", 'n', POPT_ARG_NONE, 0, 'n', "Run tests that need an active internet connection", NULL },
     830                 :            :         { "txt-host", 't', POPT_ARG_STRING, 0, 't', "Specify the host used for TXT record testing", NULL },
     831                 :            :         { "srv-host", 's', POPT_ARG_STRING, 0, 's', "Specify the host used for SRV record testing", NULL },
     832                 :            :         POPT_TABLEEND
     833                 :            :     };
     834                 :            : 
     835                 :            :     /* Set debug level to invalid value so we can deside if -d 0 was used. */
     836                 :          6 :     debug_level = SSSDBG_INVALID;
     837                 :            : 
     838                 :          6 :     pc = poptGetContext(argv[0], argc, argv, long_options, 0);
     839         [ -  + ]:          6 :     while((opt = poptGetNextOpt(pc)) != -1) {
     840   [ #  #  #  # ]:          0 :         switch(opt) {
     841                 :            :         case 'n':
     842                 :          0 :             use_net_test = 1;
     843                 :          0 :             break;
     844                 :            :         case 't':
     845                 :          0 :             txt_host = poptGetOptArg(pc);
     846                 :          0 :             break;
     847                 :            :         case 's':
     848                 :          0 :             srv_host = poptGetOptArg(pc);
     849                 :          0 :             break;
     850                 :            :         default:
     851                 :          0 :             fprintf(stderr, "\nInvalid option %s: %s\n\n",
     852                 :            :                     poptBadOption(pc, 0), poptStrerror(opt));
     853                 :          0 :             poptPrintUsage(pc, stderr, 0);
     854                 :            :             return 1;
     855                 :            :         }
     856                 :            :     }
     857                 :          6 :     poptFreeContext(pc);
     858                 :            : 
     859         [ +  - ]:          6 :     DEBUG_INIT(debug);
     860                 :            : 
     861         [ +  - ]:          6 :     if (!use_net_test) {
     862                 :          6 :         printf("Network tests disabled. Rerun with the \"-n\" "
     863                 :            :                "option to run the full suite of tests\n");
     864                 :            :     }
     865                 :            : 
     866                 :          6 :     tests_set_cwd();
     867                 :            : 
     868                 :          6 :     resolv_suite = create_resolv_suite();
     869                 :          6 :     sr = srunner_create(resolv_suite);
     870                 :            :     /* If CK_VERBOSITY is set, use that, otherwise it defaults to CK_NORMAL */
     871                 :          6 :     srunner_run_all(sr, CK_ENV);
     872                 :          1 :     failure_count = srunner_ntests_failed(sr);
     873                 :          1 :     srunner_free(sr);
     874                 :          1 :     return (failure_count==0 ? EXIT_SUCCESS : EXIT_FAILURE);
     875                 :            : }
     876                 :            : 

Generated by: LCOV version 1.9