LCOV - code coverage report
Current view: top level - tests - catch_unix.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 623 623 100.0 %
Date: 2022-06-26 14:27:46 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2011-2022  Made to Order Software Corp.  All Rights Reserved
       2             : //
       3             : // https://snapwebsites.org/project/libaddr
       4             : // contact@m2osw.com
       5             : //
       6             : // Permission is hereby granted, free of charge, to any
       7             : // person obtaining a copy of this software and
       8             : // associated documentation files (the "Software"), to
       9             : // deal in the Software without restriction, including
      10             : // without limitation the rights to use, copy, modify,
      11             : // merge, publish, distribute, sublicense, and/or sell
      12             : // copies of the Software, and to permit persons to whom
      13             : // the Software is furnished to do so, subject to the
      14             : // following conditions:
      15             : //
      16             : // The above copyright notice and this permission notice
      17             : // shall be included in all copies or substantial
      18             : // portions of the Software.
      19             : //
      20             : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
      21             : // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
      22             : // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
      23             : // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
      24             : // EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
      25             : // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
      26             : // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
      27             : // ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      28             : // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
      29             : // SOFTWARE.
      30             : 
      31             : 
      32             : /** \file
      33             :  * \brief Test the Unix address.
      34             :  *
      35             :  * These tests verify that the Unix address functions as expected.
      36             :  */
      37             : 
      38             : // addr lib
      39             : //
      40             : #include    <libaddr/unix.h>
      41             : 
      42             : 
      43             : // self
      44             : //
      45             : #include    "catch_main.h"
      46             : 
      47             : 
      48             : // libutf8 lib
      49             : //
      50             : #include    <libutf8/libutf8.h>
      51             : #include    <libutf8/exception.h>
      52             : 
      53             : 
      54             : // snapdev lib
      55             : //
      56             : #include    <snapdev/raii_generic_deleter.h>
      57             : 
      58             : 
      59             : // C lib
      60             : //
      61             : #include    <sys/stat.h>
      62             : 
      63             : 
      64             : // last include
      65             : //
      66             : #include    <snapdev/poison.h>
      67             : 
      68             : 
      69             : 
      70             : 
      71             : 
      72             : 
      73             : 
      74           7 : CATCH_TEST_CASE("unix::unnamed", "[unix]")
      75             : {
      76          10 :     CATCH_START_SECTION("unix() defaults (a.k.a. unnamed address)")
      77             :     {
      78           1 :         addr::unix u;
      79             : 
      80           1 :         CATCH_REQUIRE_FALSE(u.is_file());
      81           1 :         CATCH_REQUIRE_FALSE(u.is_abstract());
      82           1 :         CATCH_REQUIRE(u.is_unnamed());
      83           1 :         CATCH_REQUIRE(u.to_string() == std::string());
      84           1 :         CATCH_REQUIRE(u.to_uri() == "unix:");
      85             : 
      86           1 :         sockaddr_un un;
      87           1 :         u.get_un(un);
      88           1 :         CATCH_REQUIRE(un.sun_family == AF_UNIX);
      89         109 :         for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
      90             :         {
      91         108 :             CATCH_CHECK(un.sun_path[idx] == 0);
      92             :         }
      93             :     }
      94             :     CATCH_END_SECTION()
      95             : 
      96          10 :     CATCH_START_SECTION("unix() with an unnamed address")
      97             :     {
      98           1 :         sockaddr_un init = addr::init_un();
      99           1 :         CATCH_REQUIRE(init.sun_family == AF_UNIX);
     100         109 :         for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
     101             :         {
     102         108 :             CATCH_CHECK(init.sun_path[idx] == 0);
     103             :         }
     104             : 
     105           1 :         addr::unix u(init);
     106             : 
     107           1 :         CATCH_REQUIRE_FALSE(u.is_file());
     108           1 :         CATCH_REQUIRE_FALSE(u.is_abstract());
     109           1 :         CATCH_REQUIRE(u.is_unnamed());
     110           1 :         CATCH_REQUIRE(u.to_string() == std::string());
     111           1 :         CATCH_REQUIRE(u.to_uri() == "unix:");
     112             : 
     113           1 :         sockaddr_un un;
     114           1 :         u.get_un(un);
     115           1 :         CATCH_REQUIRE(un.sun_family == AF_UNIX);
     116         109 :         for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
     117             :         {
     118         108 :             CATCH_CHECK(un.sun_path[idx] == 0);
     119             :         }
     120             :     }
     121             :     CATCH_END_SECTION()
     122             : 
     123          10 :     CATCH_START_SECTION("unix() with an unnamed string")
     124             :     {
     125           2 :         std::string no_name;
     126           1 :         addr::unix u(no_name);
     127             : 
     128           1 :         CATCH_REQUIRE_FALSE(u.is_file());
     129           1 :         CATCH_REQUIRE_FALSE(u.is_abstract());
     130           1 :         CATCH_REQUIRE(u.is_unnamed());
     131           1 :         CATCH_REQUIRE(u.to_string() == std::string());
     132           1 :         CATCH_REQUIRE(u.to_uri() == "unix:");
     133             : 
     134           1 :         sockaddr_un un;
     135           1 :         u.get_un(un);
     136           1 :         CATCH_REQUIRE(un.sun_family == AF_UNIX);
     137         109 :         for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
     138             :         {
     139         108 :             CATCH_CHECK(un.sun_path[idx] == 0);
     140             :         }
     141             :     }
     142             :     CATCH_END_SECTION()
     143             : 
     144          10 :     CATCH_START_SECTION("unix() with a forced unnamed URI")
     145             :     {
     146           1 :         addr::unix u;
     147             : 
     148           1 :         u.set_uri("unix:?unnamed");
     149             : 
     150           1 :         CATCH_REQUIRE_FALSE(u.is_file());
     151           1 :         CATCH_REQUIRE_FALSE(u.is_abstract());
     152           1 :         CATCH_REQUIRE(u.is_unnamed());
     153           1 :         CATCH_REQUIRE(u.to_string() == std::string());
     154           1 :         CATCH_REQUIRE(u.to_uri() == "unix:");
     155           1 :         CATCH_REQUIRE(u.unlink() == 0);
     156             : 
     157           1 :         sockaddr_un un;
     158           1 :         u.get_un(un);
     159           1 :         CATCH_REQUIRE(un.sun_family == AF_UNIX);
     160         109 :         for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
     161             :         {
     162         108 :             CATCH_CHECK(un.sun_path[idx] == 0);
     163             :         }
     164             :     }
     165             :     CATCH_END_SECTION()
     166             : 
     167          10 :     CATCH_START_SECTION("unix() with an unnamed which we re-collect from socket")
     168             :     {
     169           1 :         sockaddr_un un;
     170             : 
     171           1 :         addr::unix u;
     172             : 
     173           1 :         CATCH_REQUIRE_FALSE(u.is_file());
     174           1 :         CATCH_REQUIRE_FALSE(u.is_abstract());
     175           1 :         CATCH_REQUIRE(u.is_unnamed());
     176           1 :         CATCH_REQUIRE(u.to_string() == std::string());
     177           1 :         CATCH_REQUIRE(u.to_uri() == "unix:");
     178             : 
     179           1 :         u.get_un(un);
     180           1 :         CATCH_REQUIRE(un.sun_family == AF_UNIX);
     181         109 :         for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
     182             :         {
     183         108 :             CATCH_CHECK(un.sun_path[idx] == 0);
     184             :         }
     185             : 
     186           2 :         snapdev::raii_fd_t s(socket(AF_UNIX, SOCK_STREAM, 0));
     187           1 :         CATCH_REQUIRE(s != nullptr);
     188             : 
     189             :         // unnamed sockets are unbound...
     190             : 
     191           1 :         addr::unix retrieve;
     192           1 :         retrieve.set_from_socket(s.get());
     193           1 :         CATCH_REQUIRE(retrieve == u);
     194             :     }
     195             :     CATCH_END_SECTION()
     196           5 : }
     197             : 
     198             : 
     199           9 : CATCH_TEST_CASE("unix::file", "[unix]")
     200             : {
     201          14 :     CATCH_START_SECTION("unix() with a relative file name")
     202             :     {
     203          11 :         for(int count(0); count < 10; ++count)
     204             :         {
     205          20 :             std::string name("test");
     206          10 :             int const max(rand() % 5 + 3);
     207          51 :             for(int id(0); id < max; ++id)
     208             :             {
     209          41 :                 name += '0' + rand() % 10;
     210             :             }
     211             : 
     212             :             // verify the init_un() as we're at it
     213             :             //
     214          10 :             sockaddr_un init = addr::init_un();
     215          10 :             CATCH_REQUIRE(init.sun_family == AF_UNIX);
     216        1090 :             for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
     217             :             {
     218        1080 :                 CATCH_CHECK(init.sun_path[idx] == 0);
     219             :             }
     220          10 :             strncpy(init.sun_path, name.c_str(), sizeof(init.sun_path) - 1);
     221             : 
     222          10 :             addr::unix u(init);
     223             : 
     224          10 :             CATCH_REQUIRE(u.is_file());
     225          10 :             CATCH_REQUIRE_FALSE(u.is_abstract());
     226          10 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     227          10 :             CATCH_REQUIRE(u.to_string() == name);
     228          10 :             CATCH_REQUIRE(u.to_uri() == "unix:" + name);
     229             : 
     230          10 :             sockaddr_un un;
     231          10 :             u.get_un(un);
     232          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     233          10 :             CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
     234        1009 :             for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
     235             :             {
     236         999 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     237             :             }
     238             :         }
     239             :     }
     240             :     CATCH_END_SECTION()
     241             : 
     242          14 :     CATCH_START_SECTION("unix() with a relative file name; string constructor")
     243             :     {
     244          11 :         for(int count(0); count < 10; ++count)
     245             :         {
     246          20 :             std::string name("test");
     247          10 :             int const max(rand() % 5 + 3);
     248          56 :             for(int id(0); id < max; ++id)
     249             :             {
     250          46 :                 name += '0' + rand() % 10;
     251             :             }
     252             : 
     253          10 :             addr::unix u(name);
     254             : 
     255          10 :             CATCH_REQUIRE(u.is_file());
     256          10 :             CATCH_REQUIRE_FALSE(u.is_abstract());
     257          10 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     258          10 :             CATCH_REQUIRE(u.to_string() == name);
     259          10 :             CATCH_REQUIRE(u.to_uri() == "unix:" + name);
     260             : 
     261          10 :             sockaddr_un un;
     262          10 :             u.get_un(un);
     263          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     264          10 :             CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
     265        1004 :             for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
     266             :             {
     267         994 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     268             :             }
     269             :         }
     270             :     }
     271             :     CATCH_END_SECTION()
     272             : 
     273          14 :     CATCH_START_SECTION("unix() with a relative file name using set_file()")
     274             :     {
     275           1 :         addr::unix u;
     276             : 
     277          11 :         for(int count(0); count < 10; ++count)
     278             :         {
     279          20 :             std::string name("test");
     280          10 :             int const max(rand() % 25 + 3); // vary more to correctly verify that we clear the end of the buffer
     281         202 :             for(int id(0); id < max; ++id)
     282             :             {
     283         192 :                 name += '0' + rand() % 10;
     284             :             }
     285             : 
     286             :             // verify the init_un() as we're at it
     287             :             //
     288          10 :             sockaddr_un init = addr::init_un();
     289          10 :             CATCH_REQUIRE(init.sun_family == AF_UNIX);
     290        1090 :             for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
     291             :             {
     292        1080 :                 CATCH_CHECK(init.sun_path[idx] == 0);
     293             :             }
     294          10 :             strncpy(init.sun_path, name.c_str(), sizeof(init.sun_path) - 1);
     295             : 
     296          10 :             u.set_file(name);
     297             : 
     298          10 :             CATCH_REQUIRE(u.is_file());
     299          10 :             CATCH_REQUIRE_FALSE(u.is_abstract());
     300          10 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     301          10 :             CATCH_REQUIRE(u.to_string() == name);
     302          10 :             CATCH_REQUIRE(u.to_uri() == "unix:" + name);
     303             : 
     304          10 :             sockaddr_un un;
     305          10 :             u.get_un(un);
     306          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     307          10 :             CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
     308         858 :             for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
     309             :             {
     310         848 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     311             :             }
     312             :         }
     313             :     }
     314             :     CATCH_END_SECTION()
     315             : 
     316          14 :     CATCH_START_SECTION("unix() with a full file name")
     317             :     {
     318          11 :         for(int count(0); count < 10; ++count)
     319             :         {
     320          20 :             std::string name("/run/snapwebsites/sockets/test");
     321          10 :             int const max(rand() % 25 + 3);
     322         178 :             for(int id(0); id < max; ++id)
     323             :             {
     324         168 :                 name += '0' + rand() % 10;
     325             :             }
     326             : 
     327             :             // verify the init_un() as we're at it
     328             :             //
     329          10 :             sockaddr_un init = addr::init_un();
     330          10 :             CATCH_REQUIRE(init.sun_family == AF_UNIX);
     331        1090 :             for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
     332             :             {
     333        1080 :                 CATCH_CHECK(init.sun_path[idx] == 0);
     334             :             }
     335          10 :             strncpy(init.sun_path, name.c_str(), sizeof(init.sun_path) - 1);
     336             : 
     337          10 :             addr::unix u(init);
     338             : 
     339          10 :             CATCH_REQUIRE(u.is_file());
     340          10 :             CATCH_REQUIRE_FALSE(u.is_abstract());
     341          10 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     342          10 :             CATCH_REQUIRE(u.to_string() == name);
     343          10 :             CATCH_REQUIRE(u.to_uri() == "unix://" + name);
     344             : 
     345          10 :             sockaddr_un un;
     346          10 :             u.get_un(un);
     347          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     348          10 :             CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
     349         622 :             for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
     350             :             {
     351         612 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     352             :             }
     353             :         }
     354             :     }
     355             :     CATCH_END_SECTION()
     356             : 
     357          14 :     CATCH_START_SECTION("unix() with a long file name")
     358             :     {
     359           1 :         sockaddr_un un;
     360         107 :         for(int count(1); count < static_cast<int>(sizeof(un.sun_path) - 1); ++count)
     361             :         {
     362         212 :             std::string name;
     363        5777 :             for(int id(0); id < count; ++id)
     364             :             {
     365        5671 :                 name += '0' + rand() % 10;
     366             :             }
     367             : 
     368         106 :             addr::unix u(name);
     369             : 
     370         106 :             CATCH_REQUIRE(u.is_file());
     371         106 :             CATCH_REQUIRE_FALSE(u.is_abstract());
     372         106 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     373         106 :             CATCH_REQUIRE(u.to_string() == name);
     374         106 :             CATCH_REQUIRE(u.to_uri() == "unix:" + name);
     375             : 
     376         106 :             u.get_un(un);
     377         106 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     378         106 :             CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
     379        5883 :             for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
     380             :             {
     381        5777 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     382             :             }
     383             :         }
     384             :     }
     385             :     CATCH_END_SECTION()
     386             : 
     387          14 :     CATCH_START_SECTION("unix() verify that file gets unlink()'ed")
     388             :     {
     389          11 :         for(int count(0); count < 10; ++count)
     390             :         {
     391          20 :             std::string name("test");
     392          10 :             int const max(rand() % 5 + 3);
     393          57 :             for(int id(0); id < max; ++id)
     394             :             {
     395          47 :                 name += '0' + rand() % 10;
     396             :             }
     397             : 
     398             :             // verify the init_un() as we're at it
     399             :             //
     400          10 :             addr::unix u(name);
     401             : 
     402          20 :             std::string cmd("touch ");
     403          10 :             cmd += name;
     404          10 :             CATCH_REQUIRE(system(cmd.c_str()) == 0);
     405             : 
     406          10 :             struct stat s;
     407          10 :             CATCH_REQUIRE(stat(name.c_str(), &s) == 0);
     408             : 
     409          10 :             CATCH_REQUIRE(u.unlink() == 0);
     410             : 
     411          10 :             CATCH_REQUIRE(stat(name.c_str(), &s) != 0);
     412             :         }
     413             :     }
     414             :     CATCH_END_SECTION()
     415             : 
     416          14 :     CATCH_START_SECTION("unix() with a file name which we re-collect from socket")
     417             :     {
     418           1 :         sockaddr_un un;
     419             : 
     420           2 :         std::string name("socket-test");
     421           1 :         int count(rand() % 5 + 3);
     422           4 :         for(int id(0); id < count; ++id)
     423             :         {
     424           3 :             name += '0' + rand() % 10;
     425             :         }
     426           1 :         unlink(name.c_str());
     427             : 
     428           1 :         addr::unix u(name);
     429             : 
     430           1 :         CATCH_REQUIRE(u.is_file());
     431           1 :         CATCH_REQUIRE_FALSE(u.is_abstract());
     432           1 :         CATCH_REQUIRE_FALSE(u.is_unnamed());
     433           1 :         CATCH_REQUIRE(u.to_string() == name);
     434           1 :         CATCH_REQUIRE(u.to_uri() == "unix:" + name);
     435             : 
     436           1 :         u.get_un(un);
     437           1 :         CATCH_REQUIRE(un.sun_family == AF_UNIX);
     438           1 :         CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
     439          95 :         for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
     440             :         {
     441          94 :             CATCH_CHECK(un.sun_path[idx] == 0);
     442             :         }
     443             : 
     444           2 :         snapdev::raii_fd_t s(socket(AF_UNIX, SOCK_STREAM, 0));
     445           1 :         CATCH_REQUIRE(s != nullptr);
     446           1 :         sockaddr_un address;
     447           1 :         u.get_un(address);
     448           1 :         CATCH_REQUIRE(bind(s.get(), reinterpret_cast<sockaddr *>(&address), sizeof(address)) == 0);
     449             : 
     450           1 :         addr::unix retrieve;
     451           1 :         retrieve.set_from_socket(s.get());
     452           1 :         CATCH_REQUIRE(retrieve == u);
     453             :     }
     454             :     CATCH_END_SECTION()
     455           7 : }
     456             : 
     457             : 
     458           8 : CATCH_TEST_CASE("unix::abstract", "[unix]")
     459             : {
     460          12 :     CATCH_START_SECTION("unix() with a relative abstract name")
     461             :     {
     462          11 :         for(int count(0); count < 10; ++count)
     463             :         {
     464          20 :             std::string name("abstract/test");
     465          10 :             int const max(rand() % 25 + 3);
     466         148 :             for(int id(0); id < max; ++id)
     467             :             {
     468         138 :                 name += '0' + rand() % 10;
     469             :             }
     470             : 
     471             :             // verify the init_un() as we're at it
     472             :             //
     473          10 :             sockaddr_un init = addr::init_un();
     474          10 :             CATCH_REQUIRE(init.sun_family == AF_UNIX);
     475        1090 :             for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
     476             :             {
     477        1080 :                 CATCH_CHECK(init.sun_path[idx] == 0);
     478             :             }
     479          10 :             strncpy(init.sun_path + 1, name.c_str(), sizeof(init.sun_path) - 2);
     480             : 
     481          10 :             addr::unix u(init);
     482             : 
     483          10 :             CATCH_REQUIRE_FALSE(u.is_file());
     484          10 :             CATCH_REQUIRE(u.is_abstract());
     485          10 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     486          10 :             CATCH_REQUIRE(u.to_string() == name);
     487          10 :             CATCH_REQUIRE(u.to_uri() == "unix:" + name + "?abstract");
     488          10 :             CATCH_REQUIRE(u.unlink() == 0);
     489             : 
     490          10 :             sockaddr_un un;
     491          10 :             u.get_un(un);
     492          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     493          10 :             CATCH_REQUIRE(un.sun_path[0] == '\0');
     494          10 :             CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
     495         812 :             for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
     496             :             {
     497         802 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     498             :             }
     499             :         }
     500             :     }
     501             :     CATCH_END_SECTION()
     502             : 
     503          12 :     CATCH_START_SECTION("unix() with a relative abstract name with string constructor")
     504             :     {
     505          11 :         for(int count(0); count < 10; ++count)
     506             :         {
     507          20 :             std::string name("abstract/test");
     508          10 :             int const max(rand() % 25 + 3);
     509         165 :             for(int id(0); id < max; ++id)
     510             :             {
     511         155 :                 name += '0' + rand() % 10;
     512             :             }
     513             : 
     514          10 :             addr::unix u(name, true);
     515             : 
     516          10 :             CATCH_REQUIRE_FALSE(u.is_file());
     517          10 :             CATCH_REQUIRE(u.is_abstract());
     518          10 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     519          10 :             CATCH_REQUIRE(u.to_string() == name);
     520          10 :             CATCH_REQUIRE(u.to_uri() == "unix:" + name + "?abstract");
     521             : 
     522          10 :             sockaddr_un un;
     523          10 :             u.get_un(un);
     524          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     525          10 :             CATCH_REQUIRE(un.sun_path[0] == '\0');
     526          10 :             CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
     527         795 :             for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
     528             :             {
     529         785 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     530             :             }
     531             :         }
     532             :     }
     533             :     CATCH_END_SECTION()
     534             : 
     535          12 :     CATCH_START_SECTION("unix() with an abstract name using set_abstract()")
     536             :     {
     537           1 :         addr::unix u;
     538             : 
     539          11 :         for(int count(0); count < 10; ++count)
     540             :         {
     541          20 :             std::string name("test");
     542          10 :             int const max(rand() % 25 + 3); // vary more to correctly verify that we clear the end of the buffer
     543         127 :             for(int id(0); id < max; ++id)
     544             :             {
     545         117 :                 name += '0' + rand() % 10;
     546             :             }
     547             : 
     548             :             // verify the init_un() as we're at it
     549             :             //
     550          10 :             sockaddr_un init = addr::init_un();
     551          10 :             CATCH_REQUIRE(init.sun_family == AF_UNIX);
     552        1090 :             for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
     553             :             {
     554        1080 :                 CATCH_CHECK(init.sun_path[idx] == 0);
     555             :             }
     556          10 :             strncpy(init.sun_path, name.c_str(), sizeof(init.sun_path) - 1);
     557             : 
     558          10 :             u.set_abstract(name);
     559             : 
     560          10 :             CATCH_REQUIRE_FALSE(u.is_file());
     561          10 :             CATCH_REQUIRE(u.is_abstract());
     562          10 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     563          10 :             CATCH_REQUIRE(u.to_string() == name);
     564          10 :             CATCH_REQUIRE(u.to_uri() == "unix:" + name + "?abstract");
     565             : 
     566          10 :             sockaddr_un un;
     567          10 :             u.get_un(un);
     568          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     569          10 :             CATCH_REQUIRE(un.sun_path[0] == '\0');
     570          10 :             CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
     571         923 :             for(std::size_t idx(name.length() +1); idx < sizeof(un.sun_path); ++idx)
     572             :             {
     573         913 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     574             :             }
     575             :         }
     576             :     }
     577             :     CATCH_END_SECTION()
     578             : 
     579          12 :     CATCH_START_SECTION("unix() with a full abstract name")
     580             :     {
     581          11 :         for(int count(0); count < 10; ++count)
     582             :         {
     583          20 :             std::string name("/net/snapwebsites/settings/test");
     584          10 :             int const max(rand() % 25 + 3);
     585         188 :             for(int id(0); id < max; ++id)
     586             :             {
     587         178 :                 name += '0' + rand() % 10;
     588             :             }
     589             : 
     590             :             // verify the init_un() as we're at it
     591             :             //
     592          10 :             sockaddr_un init = addr::init_un();
     593          10 :             CATCH_REQUIRE(init.sun_family == AF_UNIX);
     594        1090 :             for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
     595             :             {
     596        1080 :                 CATCH_CHECK(init.sun_path[idx] == 0);
     597             :             }
     598          10 :             strncpy(init.sun_path + 1, name.c_str(), sizeof(init.sun_path) - 2);
     599             : 
     600          10 :             addr::unix u(init);
     601             : 
     602          10 :             CATCH_REQUIRE_FALSE(u.is_file());
     603          10 :             CATCH_REQUIRE(u.is_abstract());
     604          10 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     605          10 :             CATCH_REQUIRE(u.to_string() == name);
     606          10 :             CATCH_REQUIRE(u.to_uri() == "unix://" + name + "?abstract");
     607             : 
     608          10 :             sockaddr_un un;
     609          10 :             u.get_un(un);
     610          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     611          10 :             CATCH_REQUIRE(un.sun_path[0] == '\0');
     612          10 :             CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
     613         592 :             for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
     614             :             {
     615         582 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     616             :             }
     617             :         }
     618             :     }
     619             :     CATCH_END_SECTION()
     620             : 
     621          12 :     CATCH_START_SECTION("unix() with a long abstract name")
     622             :     {
     623           1 :         sockaddr_un un;
     624         106 :         for(int count(1); count < static_cast<int>(sizeof(un.sun_path) - 2); ++count)
     625             :         {
     626         210 :             std::string name;
     627        5670 :             for(int id(0); id < count; ++id)
     628             :             {
     629        5565 :                 name += '0' + rand() % 10;
     630             :             }
     631             : 
     632         105 :             addr::unix u(name, true);
     633             : 
     634         105 :             CATCH_REQUIRE_FALSE(u.is_file());
     635         105 :             CATCH_REQUIRE(u.is_abstract());
     636         105 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     637         105 :             CATCH_REQUIRE(u.to_string() == name);
     638         105 :             CATCH_REQUIRE(u.to_uri() == "unix:" + name + "?abstract");
     639             : 
     640         105 :             u.get_un(un);
     641         105 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     642         105 :             CATCH_REQUIRE(un.sun_path[0] == '\0');
     643         105 :             CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
     644        5775 :             for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
     645             :             {
     646        5670 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     647             :             }
     648             :         }
     649             :     }
     650             :     CATCH_END_SECTION()
     651             : 
     652          12 :     CATCH_START_SECTION("unix() with an abstract name which we re-collect from socket")
     653             :     {
     654           1 :         sockaddr_un un;
     655             : 
     656           2 :         std::string name("/net/snapwebsites/test");
     657           1 :         int count(rand() % 5 + 3);
     658           7 :         for(int id(0); id < count; ++id)
     659             :         {
     660           6 :             name += '0' + rand() % 10;
     661             :         }
     662             : 
     663           1 :         addr::unix u(name, true);
     664             : 
     665           1 :         CATCH_REQUIRE_FALSE(u.is_file());
     666           1 :         CATCH_REQUIRE(u.is_abstract());
     667           1 :         CATCH_REQUIRE_FALSE(u.is_unnamed());
     668           1 :         CATCH_REQUIRE(u.to_string() == name);
     669           1 :         CATCH_REQUIRE(u.to_uri() == "unix://" + name + "?abstract");
     670             : 
     671           1 :         u.get_un(un);
     672           1 :         CATCH_REQUIRE(un.sun_family == AF_UNIX);
     673           1 :         CATCH_REQUIRE(un.sun_path[0] == '\0');
     674           1 :         CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
     675          80 :         for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
     676             :         {
     677          79 :             CATCH_CHECK(un.sun_path[idx] == 0);
     678             :         }
     679             : 
     680           2 :         snapdev::raii_fd_t s(socket(AF_UNIX, SOCK_STREAM, 0));
     681           1 :         CATCH_REQUIRE(s != nullptr);
     682           1 :         sockaddr_un address;
     683           1 :         u.get_un(address);
     684           1 :         socklen_t const len(sizeof(address.sun_family) + 1 + strlen(address.sun_path + 1));
     685           1 :         CATCH_REQUIRE(bind(s.get(), reinterpret_cast<sockaddr *>(&address), len) == 0);
     686             : 
     687           1 :         addr::unix retrieve;
     688           1 :         retrieve.set_from_socket(s.get());
     689           1 :         CATCH_REQUIRE(retrieve == u);
     690             :     }
     691             :     CATCH_END_SECTION()
     692           6 : }
     693             : 
     694             : 
     695           4 : CATCH_TEST_CASE("unix::compare", "[unix]")
     696             : {
     697           4 :     CATCH_START_SECTION("two unix() to compare with ==, !=, <, <=, >, >=")
     698             :     {
     699           1 :         addr::unix a;
     700           1 :         addr::unix b;
     701             : 
     702           1 :         CATCH_REQUIRE(a == b);
     703           1 :         CATCH_REQUIRE_FALSE(a != b);
     704           1 :         CATCH_REQUIRE_FALSE(a < b);
     705           1 :         CATCH_REQUIRE(a <= b);
     706           1 :         CATCH_REQUIRE_FALSE(a > b);
     707           1 :         CATCH_REQUIRE(a >= b);
     708             : 
     709           1 :         a.set_uri("unix:flowers");
     710           1 :         b.set_uri("unix:oranges");
     711             : 
     712           1 :         CATCH_REQUIRE_FALSE(a == b);
     713           1 :         CATCH_REQUIRE(a != b);
     714           1 :         CATCH_REQUIRE(a < b);
     715           1 :         CATCH_REQUIRE(a <= b);
     716           1 :         CATCH_REQUIRE_FALSE(a > b);
     717           1 :         CATCH_REQUIRE_FALSE(a >= b);
     718             : 
     719           1 :         std::swap(a, b);
     720             : 
     721           1 :         CATCH_REQUIRE_FALSE(a == b);
     722           1 :         CATCH_REQUIRE(a != b);
     723           1 :         CATCH_REQUIRE_FALSE(a < b);
     724           1 :         CATCH_REQUIRE_FALSE(a <= b);
     725           1 :         CATCH_REQUIRE(a > b);
     726           1 :         CATCH_REQUIRE(a >= b);
     727             :     }
     728             :     CATCH_END_SECTION()
     729             : 
     730           4 :     CATCH_START_SECTION("two sockaddr_un to compare with ==, !=, <, <=, >, >=")
     731             :     {
     732           1 :         sockaddr_un a = addr::init_un();
     733           1 :         sockaddr_un b = addr::init_un();
     734             : 
     735           1 :         CATCH_REQUIRE(a == b);
     736           1 :         CATCH_REQUIRE_FALSE(a != b);
     737           1 :         CATCH_REQUIRE_FALSE(a < b);
     738           1 :         CATCH_REQUIRE(a <= b);
     739           1 :         CATCH_REQUIRE_FALSE(a > b);
     740           1 :         CATCH_REQUIRE(a >= b);
     741             : 
     742           1 :         strncpy(a.sun_path, "unix:flowers", sizeof(a.sun_path) - 1);
     743           1 :         strncpy(b.sun_path, "unix:oranges", sizeof(a.sun_path) - 1);
     744             : 
     745           1 :         CATCH_REQUIRE_FALSE(a == b);
     746           1 :         CATCH_REQUIRE(a != b);
     747           1 :         CATCH_REQUIRE(a < b);
     748           1 :         CATCH_REQUIRE(a <= b);
     749           1 :         CATCH_REQUIRE_FALSE(a > b);
     750           1 :         CATCH_REQUIRE_FALSE(a >= b);
     751             : 
     752           1 :         std::swap(a, b);
     753             : 
     754           1 :         CATCH_REQUIRE_FALSE(a == b);
     755           1 :         CATCH_REQUIRE(a != b);
     756           1 :         CATCH_REQUIRE_FALSE(a < b);
     757           1 :         CATCH_REQUIRE_FALSE(a <= b);
     758           1 :         CATCH_REQUIRE(a > b);
     759           1 :         CATCH_REQUIRE(a >= b);
     760             :     }
     761             :     CATCH_END_SECTION()
     762           2 : }
     763             : 
     764             : 
     765           5 : CATCH_TEST_CASE("unix::mix", "[unix]")
     766             : {
     767           6 :     CATCH_START_SECTION("unix() with a relative file name then unnamed")
     768             :     {
     769          11 :         for(int count(0); count < 10; ++count)
     770             :         {
     771          20 :             std::string name("test");
     772          10 :             int const max(rand() % 5 + 3);
     773          60 :             for(int id(0); id < max; ++id)
     774             :             {
     775          50 :                 name += '0' + rand() % 10;
     776             :             }
     777             : 
     778             :             // verify the init_un() as we're at it
     779             :             //
     780          10 :             sockaddr_un init = addr::init_un();
     781          10 :             CATCH_REQUIRE(init.sun_family == AF_UNIX);
     782        1090 :             for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
     783             :             {
     784        1080 :                 CATCH_CHECK(init.sun_path[idx] == 0);
     785             :             }
     786          10 :             strncpy(init.sun_path, name.c_str(), sizeof(init.sun_path) - 1);
     787             : 
     788          10 :             addr::unix u(init);
     789             : 
     790          10 :             CATCH_REQUIRE(u.is_file());
     791          10 :             CATCH_REQUIRE_FALSE(u.is_abstract());
     792          10 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     793          10 :             CATCH_REQUIRE(u.to_string() == name);
     794          10 :             CATCH_REQUIRE(u.to_uri() == "unix:" + name);
     795             : 
     796          10 :             sockaddr_un un;
     797          10 :             u.get_un(un);
     798          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     799          10 :             CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
     800        1000 :             for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
     801             :             {
     802         990 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     803             :             }
     804             : 
     805          10 :             u.make_unnamed();
     806             : 
     807          10 :             CATCH_REQUIRE_FALSE(u.is_file());
     808          10 :             CATCH_REQUIRE_FALSE(u.is_abstract());
     809          10 :             CATCH_REQUIRE(u.is_unnamed());
     810          10 :             CATCH_REQUIRE(u.to_string() == std::string());
     811          10 :             CATCH_REQUIRE(u.to_uri() == "unix:");
     812             : 
     813          10 :             u.get_un(un);
     814          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     815        1090 :             for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
     816             :             {
     817        1080 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     818             :             }
     819             :         }
     820             :     }
     821             :     CATCH_END_SECTION()
     822             : 
     823           6 :     CATCH_START_SECTION("unix() with a full abstract name then unnamed")
     824             :     {
     825          11 :         for(int count(0); count < 10; ++count)
     826             :         {
     827          20 :             std::string name("/net/snapwebsites/settings/test");
     828          10 :             int const max(rand() % 25 + 3);
     829         129 :             for(int id(0); id < max; ++id)
     830             :             {
     831         119 :                 name += '0' + rand() % 10;
     832             :             }
     833             : 
     834             :             // verify the init_un() as we're at it
     835             :             //
     836          10 :             sockaddr_un init = addr::init_un();
     837          10 :             CATCH_REQUIRE(init.sun_family == AF_UNIX);
     838        1090 :             for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
     839             :             {
     840        1080 :                 CATCH_CHECK(init.sun_path[idx] == 0);
     841             :             }
     842          10 :             strncpy(init.sun_path + 1, name.c_str(), sizeof(init.sun_path) - 2);
     843             : 
     844          10 :             addr::unix u(init);
     845             : 
     846          10 :             CATCH_REQUIRE_FALSE(u.is_file());
     847          10 :             CATCH_REQUIRE(u.is_abstract());
     848          10 :             CATCH_REQUIRE_FALSE(u.is_unnamed());
     849          10 :             CATCH_REQUIRE(u.to_string() == name);
     850          10 :             CATCH_REQUIRE(u.to_uri() == "unix://" + name + "?abstract");
     851             : 
     852          10 :             sockaddr_un un;
     853          10 :             u.get_un(un);
     854          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     855          10 :             CATCH_REQUIRE(un.sun_path[0] == '\0');
     856          10 :             CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
     857         651 :             for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
     858             :             {
     859         641 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     860             :             }
     861             : 
     862          10 :             u.make_unnamed();
     863             : 
     864          10 :             CATCH_REQUIRE_FALSE(u.is_file());
     865          10 :             CATCH_REQUIRE_FALSE(u.is_abstract());
     866          10 :             CATCH_REQUIRE(u.is_unnamed());
     867          10 :             CATCH_REQUIRE(u.to_string() == std::string());
     868          10 :             CATCH_REQUIRE(u.to_uri() == "unix:");
     869             : 
     870          10 :             u.get_un(un);
     871          10 :             CATCH_REQUIRE(un.sun_family == AF_UNIX);
     872        1090 :             for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
     873             :             {
     874        1080 :                 CATCH_CHECK(un.sun_path[idx] == 0);
     875             :             }
     876             :         }
     877             :     }
     878             :     CATCH_END_SECTION()
     879             : 
     880           6 :     CATCH_START_SECTION("unix() with various set_uri()")
     881             :     {
     882           1 :         addr::unix u;
     883             : 
     884         223 :         for(int count(0); count < 222; ++count)
     885             :         {
     886         222 :             int type(count % 3);
     887             : 
     888         444 :             std::string name;
     889         222 :             if(type != 2)
     890             :             {
     891         148 :                 name = "/run/snapwebsites/sockets/test";
     892         148 :                 int const max(rand() % 25 + 3);
     893        2307 :                 for(int id(0); id < max; ++id)
     894             :                 {
     895        2159 :                     name += '0' + rand() % 10;
     896             :                 }
     897             :             }
     898             : 
     899         222 :             bool force(count % 6 != type);
     900             : 
     901         222 :             sockaddr_un un;
     902         222 :             switch(count % 3)
     903             :             {
     904          74 :             case 0:
     905          74 :                 u.set_uri("unix://" + name + (force ? "?file" : ""));
     906             : 
     907          74 :                 CATCH_REQUIRE(u.is_file());
     908          74 :                 CATCH_REQUIRE_FALSE(u.is_abstract());
     909          74 :                 CATCH_REQUIRE_FALSE(u.is_unnamed());
     910          74 :                 CATCH_REQUIRE(u.to_string() == name);
     911          74 :                 CATCH_REQUIRE(u.to_uri() == "unix://" + name);
     912             : 
     913          74 :                 u.get_un(un);
     914          74 :                 CATCH_REQUIRE(un.sun_family == AF_UNIX);
     915          74 :                 CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
     916        4813 :                 for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
     917             :                 {
     918        4739 :                     CATCH_CHECK(un.sun_path[idx] == 0);
     919          74 :                 }
     920          74 :                 break;
     921             : 
     922          74 :             case 1:
     923          74 :                 u.set_uri("unix://" + name + "?abstract");
     924             : 
     925          74 :                 CATCH_REQUIRE_FALSE(u.is_file());
     926          74 :                 CATCH_REQUIRE(u.is_abstract());
     927          74 :                 CATCH_REQUIRE_FALSE(u.is_unnamed());
     928          74 :                 CATCH_REQUIRE(u.to_string() == name);
     929          74 :                 CATCH_REQUIRE(u.to_uri() == "unix://" + name + "?abstract");
     930             : 
     931          74 :                 u.get_un(un);
     932          74 :                 CATCH_REQUIRE(un.sun_family == AF_UNIX);
     933          74 :                 CATCH_REQUIRE(un.sun_path[0] == '\0');
     934          74 :                 CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
     935        4646 :                 for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
     936             :                 {
     937        4572 :                     CATCH_CHECK(un.sun_path[idx] == 0);
     938          74 :                 }
     939          74 :                 break;
     940             : 
     941          74 :             case 2:
     942          74 :                 u.set_uri(force ? "unix:?unnamed" : "unix:");
     943             : 
     944          74 :                 CATCH_REQUIRE_FALSE(u.is_file());
     945          74 :                 CATCH_REQUIRE_FALSE(u.is_abstract());
     946          74 :                 CATCH_REQUIRE(u.is_unnamed());
     947          74 :                 CATCH_REQUIRE(u.to_string() == std::string());
     948          74 :                 CATCH_REQUIRE(u.to_uri() == "unix:");
     949             : 
     950          74 :                 u.get_un(un);
     951          74 :                 CATCH_REQUIRE(un.sun_family == AF_UNIX);
     952        8066 :                 for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
     953             :                 {
     954        7992 :                     CATCH_CHECK(un.sun_path[idx] == 0);
     955          74 :                 }
     956          74 :                 break;
     957             : 
     958             :             }
     959             :         }
     960             :     }
     961             :     CATCH_END_SECTION()
     962           3 : }
     963             : 
     964             : 
     965          14 : CATCH_TEST_CASE("unix::invalid", "[unix]")
     966             : {
     967          24 :     CATCH_START_SECTION("unix() with an invalid address family")
     968             :     {
     969          52 :         for(int family(-25); family <= 25; ++family)
     970             :         {
     971          51 :             if(family == AF_UNIX)
     972             :             {
     973           1 :                 continue;
     974             :             }
     975             : 
     976          50 :             sockaddr_un init = addr::init_un();
     977          50 :             init.sun_family = family;
     978             : 
     979             :             // constructor
     980             :             //
     981          50 :             CATCH_REQUIRE_THROWS_AS(addr::unix(init), addr::addr_invalid_structure);
     982             : 
     983             :             // set_un()
     984             :             //
     985          50 :             addr::unix u;
     986          50 :             CATCH_REQUIRE_THROWS_AS(u.set_un(init), addr::addr_invalid_structure);
     987             :         }
     988             :     }
     989             :     CATCH_END_SECTION()
     990             : 
     991          24 :     CATCH_START_SECTION("unix() with an unnamed string but marked abstract")
     992             :     {
     993           1 :         CATCH_REQUIRE_THROWS_AS(addr::unix(std::string(), true), addr::addr_invalid_argument);
     994             :     }
     995             :     CATCH_END_SECTION()
     996             : 
     997          24 :     CATCH_START_SECTION("unix() with a URI and a missing path")
     998             :     {
     999           1 :         addr::unix u;
    1000           1 :         CATCH_REQUIRE_THROWS_AS(u.set_uri("unix://"), addr::addr_invalid_argument);
    1001             :     }
    1002             :     CATCH_END_SECTION()
    1003             : 
    1004          24 :     CATCH_START_SECTION("unix() with too long a file name")
    1005             :     {
    1006             :         sockaddr_un un;
    1007          12 :         for(int count(static_cast<int>(sizeof(un.sun_path)));
    1008          12 :             count < static_cast<int>(sizeof(un.sun_path) + 11);
    1009             :             ++count)
    1010             :         {
    1011          22 :             std::string name;
    1012        1254 :             for(int id(0); id < count; ++id)
    1013             :             {
    1014        1243 :                 name += '0' + rand() % 10;
    1015             :             }
    1016             : 
    1017          11 :             CATCH_REQUIRE_THROWS_AS(addr::unix(name), addr::addr_invalid_argument);
    1018             : 
    1019          11 :             addr::unix u;
    1020          11 :             CATCH_REQUIRE_THROWS_AS(u.set_uri("unix:" + name), addr::addr_invalid_argument);
    1021             :         }
    1022             :     }
    1023             :     CATCH_END_SECTION()
    1024             : 
    1025          24 :     CATCH_START_SECTION("unix() with too long an abstract name")
    1026             :     {
    1027             :         sockaddr_un un;
    1028          12 :         for(int count(static_cast<int>(sizeof(un.sun_path) - 1));
    1029          12 :             count < static_cast<int>(sizeof(un.sun_path) + 10);
    1030             :             ++count)
    1031             :         {
    1032          22 :             std::string name;
    1033        1243 :             for(int id(0); id < count; ++id)
    1034             :             {
    1035        1232 :                 name += '0' + rand() % 10;
    1036             :             }
    1037             : 
    1038          11 :             CATCH_REQUIRE_THROWS_AS(addr::unix(name, true), addr::addr_invalid_argument);
    1039             : 
    1040          11 :             addr::unix u;
    1041          11 :             CATCH_REQUIRE_THROWS_AS(u.set_uri("unix:" + name + "?abstract"), addr::addr_invalid_argument);
    1042             :         }
    1043             :     }
    1044             :     CATCH_END_SECTION()
    1045             : 
    1046          24 :     CATCH_START_SECTION("unix() with a long filename (missing '\\0')")
    1047             :     {
    1048           1 :         sockaddr_un init = addr::init_un();
    1049         109 :         for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
    1050             :         {
    1051         108 :             init.sun_path[idx] = '0' + rand() % 10;
    1052             :         }
    1053             : 
    1054             :         // constructor
    1055             :         //
    1056           1 :         CATCH_REQUIRE_THROWS_AS(addr::unix(init), addr::addr_invalid_argument);
    1057             : 
    1058             :         // set_un()
    1059             :         //
    1060           1 :         addr::unix u;
    1061           1 :         CATCH_REQUIRE_THROWS_AS(u.set_un(init), addr::addr_invalid_argument);
    1062             :     }
    1063             :     CATCH_END_SECTION()
    1064             : 
    1065          24 :     CATCH_START_SECTION("unix() with a long abstrat name (missing '\\0')")
    1066             :     {
    1067           1 :         sockaddr_un init = addr::init_un();
    1068         108 :         for(std::size_t idx(1); idx < sizeof(init.sun_path); ++idx)
    1069             :         {
    1070         107 :             init.sun_path[idx] = '0' + rand() % 10;
    1071             :         }
    1072             : 
    1073             :         // constructor
    1074             :         //
    1075           1 :         CATCH_REQUIRE_THROWS_AS(addr::unix(init), addr::addr_invalid_argument);
    1076             : 
    1077             :         // set_un()
    1078             :         //
    1079           1 :         addr::unix u;
    1080           1 :         CATCH_REQUIRE_THROWS_AS(u.set_un(init), addr::addr_invalid_argument);
    1081             :     }
    1082             :     CATCH_END_SECTION()
    1083             : 
    1084          24 :     CATCH_START_SECTION("unix() with a long abstrat name (missing '\\0')")
    1085             :     {
    1086           1 :         addr::unix u;
    1087             : 
    1088             :         // missing ":"
    1089             :         //
    1090           1 :         CATCH_REQUIRE_THROWS_AS(u.set_uri("unix/run/snapwebsites/sockets"), addr::addr_invalid_argument);
    1091             : 
    1092             :         // "?alexis"
    1093             :         //
    1094           1 :         CATCH_REQUIRE_THROWS_AS(u.set_uri("unix:/run/snapwebsites/sockets?alexis"), addr::addr_invalid_argument);
    1095             : 
    1096             :         // "http:"
    1097             :         //
    1098           1 :         CATCH_REQUIRE_THROWS_AS(u.set_uri("http:/run/snapwebsites/sockets?abstract"), addr::addr_invalid_argument);
    1099             : 
    1100             :         // name with "?unnamed"
    1101             :         //
    1102           1 :         CATCH_REQUIRE_THROWS_AS(u.set_uri("unix:not-empty?unnamed"), addr::addr_invalid_argument);
    1103             :     }
    1104             :     CATCH_END_SECTION()
    1105             : 
    1106          24 :     CATCH_START_SECTION("unix() with invalid characters (controls)")
    1107             :     {
    1108          32 :         for(int c(1); c < 0x20; ++c)
    1109             :         {
    1110          62 :             std::string name;
    1111          31 :             name += c;
    1112          31 :             CATCH_REQUIRE_THROWS_AS(addr::unix(name), addr::addr_invalid_argument);
    1113             :         }
    1114             : 
    1115          34 :         for(int c(0x7F); c < 0xA0; ++c)
    1116             :         {
    1117          66 :             std::u32string u32;
    1118          33 :             u32 += c;
    1119          66 :             std::string name(libutf8::to_u8string(u32));
    1120          33 :             CATCH_REQUIRE_THROWS_AS(addr::unix(name), addr::addr_invalid_argument);
    1121             :         }
    1122             :     }
    1123             :     CATCH_END_SECTION()
    1124             : 
    1125          24 :     CATCH_START_SECTION("unix() with invalid UTF-8 characters")
    1126             :     {
    1127           2 :         std::string name;
    1128          11 :         for(int c(0); c < 10; ++c)
    1129             :         {
    1130          10 :             name += static_cast<char>(0x80);
    1131             :         }
    1132           1 :         CATCH_REQUIRE_THROWS_AS(addr::unix(name), libutf8::libutf8_exception_decoding);
    1133             :     }
    1134             :     CATCH_END_SECTION()
    1135             : 
    1136          24 :     CATCH_START_SECTION("get unix() of socket set to -1")
    1137             :     {
    1138           1 :         addr::unix u;
    1139           1 :         bool const result(u.set_from_socket(-1));
    1140           1 :         int const e(errno);
    1141           1 :         CATCH_REQUIRE_FALSE(result);
    1142           1 :         CATCH_REQUIRE(e == EBADF);
    1143             :     }
    1144             :     CATCH_END_SECTION()
    1145             : 
    1146          24 :     CATCH_START_SECTION("get unix() of socket set to UDP")
    1147             :     {
    1148           1 :         addr::addr udp(addr::string_to_addr(
    1149             :                   "127.0.0.1:3999"
    1150             :                 , "127.0.0.1"
    1151             :                 , 3999
    1152           2 :                 , "udp"));
    1153           2 :         snapdev::raii_fd_t s(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
    1154           1 :         CATCH_REQUIRE(s != nullptr);
    1155           1 :         sockaddr_in in;
    1156           1 :         udp.get_ipv4(in);
    1157           1 :         CATCH_REQUIRE(bind(s.get(), reinterpret_cast<sockaddr *>(&in), sizeof(in)) == 0);
    1158             : 
    1159           1 :         addr::unix u;
    1160           1 :         bool const result(u.set_from_socket(s.get()));
    1161           1 :         int const e(errno);
    1162           1 :         CATCH_REQUIRE_FALSE(result);
    1163           1 :         CATCH_REQUIRE(e == EADDRNOTAVAIL);
    1164             :     }
    1165             :     CATCH_END_SECTION()
    1166          18 : }
    1167             : 
    1168             : 
    1169             : // vim: ts=4 sw=4 et

Generated by: LCOV version 1.13