LCOV - code coverage report
Current view: top level - tests - tld_test.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 82 127 64.6 %
Date: 2015-11-01 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* TLD library -- test the TLD interface
       2             :  * Copyright (C) 2011-2015  Made to Order Software Corp.
       3             :  *
       4             :  * Permission is hereby granted, free of charge, to any person obtaining a
       5             :  * copy of this software and associated documentation files (the
       6             :  * "Software"), to deal in the Software without restriction, including
       7             :  * without limitation the rights to use, copy, modify, merge, publish,
       8             :  * distribute, sublicense, and/or sell copies of the Software, and to
       9             :  * permit persons to whom the Software is furnished to do so, subject to
      10             :  * the following conditions:
      11             :  *
      12             :  * The above copyright notice and this permission notice shall be included
      13             :  * in all copies or substantial portions of the Software.
      14             :  *
      15             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      16             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      17             :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      18             :  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      19             :  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
      20             :  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      21             :  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      22             :  */
      23             : 
      24             : /** \file
      25             :  * \brief Test the tld() function like an end user.
      26             :  *
      27             :  * This file implements various tests verifying the tld() function.
      28             :  * The tests defined here are not for coverage but rather edge
      29             :  * cases which could be hard to expect in a full coverage test.
      30             :  */
      31             : 
      32             : #include "libtld/tld.h"
      33             : #include <string.h>
      34             : #include <stdlib.h>
      35             : #include <stdio.h>
      36             : #include <limits.h>
      37             : 
      38             : /* we get access to the table with all the TLDs so we can go through them all
      39             :  * the library does not give direct access by default... (although maybe we
      40             :  * could give users access to the data)
      41             :  */
      42             : #include "tld_data.h"
      43             : extern const struct tld_description tld_descriptions[];
      44             : extern unsigned short tld_start_offset;
      45             : extern unsigned short tld_end_offset;
      46             : 
      47             : int err_count = 0;
      48             : int verbose = 0;
      49             : 
      50             : /*
      51             :  * This test calls the tld() function with all the TLDs and then
      52             :  * with wrong TLDs to make sure that the tld() functions works as
      53             :  * expected.
      54             :  *
      55             :  * extern enum tld_result tld(const char *uri, struct tld_info *info);
      56             :  */
      57             : 
      58             : 
      59             : /** \brief Build an extension from any offset.
      60             :  *
      61             :  * Create a domain name extensions from any entry in the TLD
      62             :  * descriptions.
      63             :  *
      64             :  * \param[in] offset  The offset in the tld_descriptions table
      65             :  * \param[in] uri  The URI buffer
      66             :  */
      67       42790 : void cat_ext(int offset, char *uri)
      68             : {
      69             :         int     k, l;
      70             : 
      71       42790 :         strcat(uri, tld_descriptions[offset].f_tld);
      72       42790 :         l = offset;
      73   336291720 :         for(k = offset + 1; k < tld_end_offset; ++k)
      74             :         {
      75   336248930 :                 if(l >= tld_descriptions[k].f_start_offset
      76    24529920 :                 && l < tld_descriptions[k].f_end_offset)
      77             :                 {
      78             :                         /* found a parent */
      79       49970 :                         strcat(uri, ".");
      80       49970 :                         strcat(uri, tld_descriptions[k].f_tld);
      81       49970 :                         l = k;
      82       49970 :                         k = tld_descriptions[k].f_end_offset;
      83             :                 }
      84             :         }
      85       42790 : }
      86             : 
      87             : /*
      88             :  * This test goes through all the domain names and extracts the domain,
      89             :  * sub-domains and TLDs. (Or at least verifies that we get the correct
      90             :  * information in order to do so.)
      91             :  *
      92             :  * It builds a URI with zero to many sub-domain names, adds a specific
      93             :  * domain name, then append a complete TLD. The result is then checked
      94             :  * with the tld() function from the library. The tld() is expected to
      95             :  * either return VALID or INVALID but nothing else (since all those
      96             :  * TLDs exist in our table.) Then we verify that the returned offset is
      97             :  * a perfect match.
      98             :  */
      99           1 : void test_all()
     100             : {
     101           1 :         const char *sub_domains[] = {
     102             :                 "",
     103             :                 "www.",
     104             :                 "tld.",
     105             :                 "george.snap.",
     106             :                 "very.long.sub.domain.ext.en.sion.here."
     107             :                 "host.%20.space."
     108             :                 "host.%fa.u-acute."
     109             :                 "host.%FA.U-acute."
     110             :         };
     111             :         struct tld_info info;
     112             :         char                    uri[256], extension_uri[256];
     113             :         int                             i, j, p, max_subdomains;
     114             :         enum tld_result r;
     115             : 
     116           1 :         max_subdomains = sizeof(sub_domains) / sizeof(sub_domains[0]);
     117             : 
     118        8537 :         for(i = 0; i < tld_end_offset; ++i)
     119             :         {
     120       51216 :                 for(j = 0; j < max_subdomains; ++j)
     121             :                 {
     122       42680 :                         strcpy(uri, sub_domains[j]);
     123       42680 :                         strcat(uri, "domain-name.");
     124       42680 :                         cat_ext(i, uri);
     125             :                         /* reset the structure so we can verify it gets initialized */
     126       42680 :                         memset(&info, 0xFE, sizeof(info));
     127       42680 :                         r = tld(uri, &info);
     128             :                         /*
     129             :                         for(int l = 0; l < sizeof(info); ++l)
     130             :                         {
     131             :                                 fprintf(stderr, "0x%02X ", ((unsigned char*)&info)[l]);
     132             :                         }
     133             :                         fprintf(stderr, "\nresult for [%s]: category[%d], status[%d], country[%s],"
     134             :                                                                 " tld[%s], offset[%d]\n",
     135             :                                         uri,
     136             :                                         (int)info.f_category, (int)info.f_status, info.f_country,
     137             :                                                 info.f_tld, (int)info.f_offset);
     138             :                         */
     139       42680 :                         p = i;
     140       42680 :                         if(tld_descriptions[i].f_status == TLD_STATUS_EXCEPTION)
     141             :                         {
     142         110 :                                 if(tld_descriptions[i].f_exception_apply_to == USHRT_MAX)
     143             :                                 {
     144           0 :                                         fprintf(stderr, "error: domain name for \"%s\" (%d) is said to be an exception but it has no apply-to parameter. (result: %d)\n",
     145             :                                                         uri, i, r);
     146           0 :                                         ++err_count;
     147             :                                 }
     148             :                                 else
     149             :                                 {
     150         110 :                                         p = tld_descriptions[i].f_exception_apply_to;
     151             :                                 }
     152             :                         }
     153       42680 :                         if(tld_descriptions[i].f_status == TLD_STATUS_VALID)
     154             :                         {
     155       41765 :                                 if(r != TLD_RESULT_SUCCESS)
     156             :                                 {
     157           0 :                                         fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
     158             :                                                         uri, i, r);
     159           0 :                                         ++err_count;
     160             :                                 }
     161             :                                 else
     162             :                                 {
     163             :                                         /* in this case we have to test the top domain name only */
     164       41765 :                                         if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
     165             :                                         {
     166           0 :                                                 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
     167             :                                                                 uri, i, r);
     168           0 :                                                 ++err_count;
     169             :                                         }
     170             :                                         /*
     171             :                                         else
     172             :                                                 fprintf(stderr, "valid: \"%s\" -> \"%s\"\n", uri, info.f_tld);
     173             :                                         */
     174             :                                 }
     175             :                         }
     176         915 :                         else if(tld_descriptions[i].f_status == TLD_STATUS_EXCEPTION)
     177             :                         {
     178         110 :                                 if(r != TLD_RESULT_SUCCESS)
     179             :                                 {
     180           0 :                                         fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
     181             :                                                         uri, i, r);
     182           0 :                                         ++err_count;
     183             :                                 }
     184             :                                 else
     185             :                                 {
     186         110 :                                         strcpy(extension_uri, ".");
     187         110 :                                         cat_ext(p, extension_uri);
     188         110 :                                         if(strcmp(info.f_tld, extension_uri) != 0)
     189             :                                         //if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
     190             :                                         {
     191           0 :                                                 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d)\n",
     192             :                                                                 uri, i, r);
     193           0 :                                                 ++err_count;
     194             :                                         }
     195             :                                         /*
     196             :                                         else
     197             :                                                 fprintf(stderr, "valid: \"%s\" -> \"%s\"\n", uri, info.f_tld);
     198             :                                         */
     199             :                                 }
     200             :                         }
     201             :                         else
     202             :                         {
     203         805 :                                 if(r != TLD_RESULT_INVALID)
     204             :                                 {
     205           0 :                                         fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted as expected (returned: %d)\n",
     206             :                                                         uri, i, r);
     207           0 :                                         ++err_count;
     208             :                                 }
     209         805 :                                 else if(p != i)
     210             :                                 {
     211           0 :                                         strcpy(extension_uri, ".");
     212           0 :                                         cat_ext(p, extension_uri);
     213           0 :                                         if(strcmp(info.f_tld, extension_uri) != 0)
     214             :                                         {
     215           0 :                                                 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d/%s)\n",
     216             :                                                                 uri, i, r, info.f_tld);
     217           0 :                                                 ++err_count;
     218             :                                         }
     219             :                                         /*
     220             :                                         else
     221             :                                                 fprintf(stderr, "?? invalid: \"%s\" -> \"%s\"\n", uri, info.f_tld); 
     222             :                                         */
     223             :                                 }
     224             :                                 else
     225             :                                 {
     226         805 :                                         if(strncmp(uri + info.f_offset - 11, "domain-name", 11) != 0)
     227             :                                         {
     228           0 :                                                 fprintf(stderr, "error: domain name for \"%s\" (%d) could not be extracted successfully (returned: %d/%s)\n",
     229             :                                                                 uri, i, r, info.f_tld);
     230           0 :                                                 ++err_count;
     231             :                                         }
     232             :                                         /*
     233             :                                         else
     234             :                                                 fprintf(stderr, "?? invalid: \"%s\" -> \"%s\"\n", uri, info.f_tld); 
     235             :                                         */
     236             :                                 }
     237             :                         }
     238             :                 }
     239             :         }
     240           1 : }
     241             : 
     242             : 
     243             : /*
     244             :  * This test checks out URIs that end with an invalid TLD. This is
     245             :  * expected to return an error every single time.
     246             :  */
     247           1 : void test_unknown()
     248             : {
     249             :         struct bad_data
     250             :         {
     251             :                 const char *            f_uri;
     252             :         };
     253           1 :         struct bad_data d[] =
     254             :         {
     255             :                 { "this.is.wrong" },
     256             :                 { "missing.tld" },
     257             :                 { ".net.absolutely.com.no.info.on.this" }
     258             :         };
     259             :         struct tld_info info;
     260             :         int i, max;
     261             :         enum tld_result r;
     262             : 
     263           1 :         max = sizeof(d) / sizeof(d[0]);
     264           4 :         for(i = 0; i < max; ++i)
     265             :         {
     266           3 :                 memset(&info, 0xFE, sizeof(info));
     267           3 :                 r = tld(d[i].f_uri, &info);
     268           3 :                 if(r != TLD_RESULT_NOT_FOUND)
     269             :                 {
     270           0 :                         fprintf(stderr, "error: the invalid URI \"%s\" was found by tld()!\n", d[i].f_uri);
     271           0 :                         ++err_count;
     272             :                 }
     273             :         }
     274           1 : }
     275             : 
     276             : 
     277             : 
     278             : 
     279           1 : void test_invalid()
     280             : {
     281             :         struct tld_info undefined_info;
     282             :         struct tld_info clear_info;
     283             :         struct tld_info info;
     284             :         enum tld_result r;
     285             : 
     286             :         /*
     287             :          * We reset the undefined_info the same way we reset the info
     288             :          * structure because the alignment on 64bits may add another
     289             :          * 4 bytes at the end of the structure that are not otherwise
     290             :          * accessible.
     291             :          */
     292           1 :         memset(&undefined_info, 0xFE, sizeof(undefined_info));
     293           1 :         undefined_info.f_category = TLD_CATEGORY_UNDEFINED;
     294           1 :         undefined_info.f_status   = TLD_STATUS_UNDEFINED;
     295           1 :         undefined_info.f_country  = (const char *) 0;
     296           1 :         undefined_info.f_tld      = (const char *) 0;
     297           1 :         undefined_info.f_offset   = -1;
     298             : 
     299           1 :         memset(&clear_info, 0xFE, sizeof(clear_info));
     300             : 
     301             :         /* test: NULL */
     302           1 :         info = clear_info;
     303           1 :         r = tld(NULL, &info);
     304           1 :         if(r != TLD_RESULT_NULL)
     305             :         {
     306           0 :                 fprintf(stderr, "error: the NULL URI did not return the TLD_RESULT_NULL result.\n");
     307           0 :                 ++err_count;
     308             :         }
     309           1 :         if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     310             :         {
     311           0 :                 fprintf(stderr, "error: the NULL URI did not return a reset info structure.\n");
     312           0 :                 ++err_count;
     313             :         }
     314             : 
     315             :         /* test: "" */
     316           1 :         info = clear_info;
     317           1 :         r = tld("", &info);
     318           1 :         if(r != TLD_RESULT_NULL)
     319             :         {
     320           0 :                 fprintf(stderr, "error: the \"\" URI did not return the TLD_RESULT_NULL result.\n");
     321           0 :                 ++err_count;
     322             :         }
     323           1 :         if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     324             :         {
     325           0 :                 fprintf(stderr, "error: the \"\" URI did not return a reset info structure.\n");
     326           0 :                 ++err_count;
     327             :         }
     328             : 
     329             :         /* test: ".." (two periods one after another) */
     330           1 :         info = clear_info;
     331           1 :         r = tld("test..com", &info);
     332           1 :         if(r != TLD_RESULT_BAD_URI)
     333             :         {
     334           0 :                 fprintf(stderr, "error: the \"test..com\" URI did not return the TLD_RESULT_BAD_URI result.\n");
     335           0 :                 ++err_count;
     336             :         }
     337           1 :         if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     338             :         {
     339           0 :                 fprintf(stderr, "error: the \"test..com\" URI did not return a reset info structure.\n");
     340           0 :                 ++err_count;
     341             :         }
     342             : 
     343             :         /* test: ".." (two periods one after another) */
     344           1 :         info = clear_info;
     345           1 :         r = tld("more..test.com", &info);
     346           1 :         if(r != TLD_RESULT_BAD_URI)
     347             :         {
     348           0 :                 fprintf(stderr, "error: the \"more..test.com\" URI did not return the TLD_RESULT_BAD_URI result.\n");
     349           0 :                 ++err_count;
     350             :         }
     351           1 :         if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     352             :         {
     353           0 :                 fprintf(stderr, "error: the \"more..test.com\" URI did not return a reset info structure.\n");
     354           0 :                 ++err_count;
     355             :         }
     356             : 
     357             :         /* test: "noperiodanywhere" (no periods anywhere) */
     358           1 :         info = clear_info;
     359           1 :         r = tld("noperiodanywhere", &info);
     360           1 :         if(r != TLD_RESULT_NO_TLD)
     361             :         {
     362           0 :                 fprintf(stderr, "error: the \"noperiodanywhere\" URI did not return the TLD_RESULT_NO_TLD result.\n");
     363           0 :                 ++err_count;
     364             :         }
     365           1 :         if(memcmp(&info, &undefined_info, sizeof(info)) != 0)
     366             :         {
     367           0 :                 fprintf(stderr, "error: the \"noperiodanywhere\" URI did not return a reset info structure.\n");
     368           0 :                 ++err_count;
     369             :         }
     370           1 : }
     371             : 
     372             : 
     373             : 
     374             : 
     375           1 : int main(int argc, char *argv[])
     376             : {
     377           1 :         fprintf(stderr, "testing tld version %s\n", tld_version());
     378             : 
     379           1 :         if(argc > 1)
     380             :         {
     381           0 :                 if(strcmp(argv[1], "-v") == 0)
     382             :                 {
     383           0 :                         verbose = 1;
     384             :                 }
     385             :         }
     386             : 
     387             :         /* call all the tests, one by one
     388             :          * failures are "recorded" in the err_count global variable
     389             :          * and the process stops with an error message and exit(1)
     390             :          * if err_count is not zero.
     391             :          */
     392           1 :         test_all();
     393           1 :         test_unknown();
     394           1 :         test_invalid();
     395             : 
     396           1 :         if(err_count)
     397             :         {
     398           0 :                 fprintf(stderr, "%d error%s occured.\n",
     399           0 :                                         err_count, err_count != 1 ? "s" : "");
     400             :         }
     401           1 :         exit(err_count ? 1 : 0);
     402             : }
     403             : 
     404             : /* vim: ts=4 sw=4
     405             :  */

Generated by: LCOV version 1.10