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-03-01 21:05:13 Functions: 8 8 100.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13