diff --git a/test/meson.build b/test/meson.build index 25a8d38a1..628e5cbfd 100644 --- a/test/meson.build +++ b/test/meson.build @@ -18,6 +18,8 @@ gtest_dep = declare_dependency( compile_args: gtest_compile_args, ) +subdir('net') + executable( 'ParseSongFilter', 'ParseSongFilter.cxx', diff --git a/test/net/TestIPv4Address.cxx b/test/net/TestIPv4Address.cxx new file mode 100644 index 000000000..08b995855 --- /dev/null +++ b/test/net/TestIPv4Address.cxx @@ -0,0 +1,90 @@ +/* + * Copyright 2012-2019 Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "net/IPv4Address.hxx" +#include "net/ToString.hxx" + +#include + +#include + +#include + +static std::string +ToString(const struct in_addr &a) +{ + char buffer[256]; + const char *result = inet_ntop(AF_INET, &a, buffer, sizeof(buffer)); + if (result == nullptr) + throw std::runtime_error("inet_ntop() failed"); + return result; +} + +TEST(IPv4Address, Octets) +{ + static constexpr auto a = IPv4Address(11, 22, 33, 44, 1234); + EXPECT_EQ(ToString(a.GetAddress()), "11.22.33.44"); +} + +TEST(IPv4Address, Any) +{ + EXPECT_EQ(ToString(IPv4Address(1234).GetAddress()), "0.0.0.0"); + EXPECT_EQ(ToString(IPv4Address(1234)), "0.0.0.0:1234"); +} + +TEST(IPv4Address, Port) +{ + EXPECT_EQ(IPv4Address(0).GetPort(), 0); + EXPECT_EQ(IPv4Address(1).GetPort(), 1); + EXPECT_EQ(IPv4Address(1234).GetPort(), 1234); + EXPECT_EQ(IPv4Address(0xffff).GetPort(), 0xffff); +} + +TEST(IPv4Address, Loopback) +{ + static constexpr auto a = IPv4Address(IPv4Address::Loopback(), 1234); + EXPECT_EQ(ToString(a.GetAddress()), "127.0.0.1"); +} + +TEST(IPv4Address, MaskFromPrefix) +{ + EXPECT_EQ(ToString(IPv4Address::MaskFromPrefix(0).GetAddress()), "0.0.0.0"); + EXPECT_EQ(ToString(IPv4Address::MaskFromPrefix(4).GetAddress()), "240.0.0.0"); + EXPECT_EQ(ToString(IPv4Address::MaskFromPrefix(8).GetAddress()), "255.0.0.0"); + EXPECT_EQ(ToString(IPv4Address::MaskFromPrefix(16).GetAddress()), "255.255.0.0"); + EXPECT_EQ(ToString(IPv4Address::MaskFromPrefix(24).GetAddress()), "255.255.255.0"); + EXPECT_EQ(ToString(IPv4Address::MaskFromPrefix(31).GetAddress()), "255.255.255.254"); + EXPECT_EQ(ToString(IPv4Address::MaskFromPrefix(32).GetAddress()), "255.255.255.255"); +} + +TEST(IPv4Address, Numeric) +{ + EXPECT_EQ(IPv4Address(1, 2, 3, 4, 0).GetNumericAddress(), 0x01020304); + EXPECT_EQ(IPv4Address(1, 2, 3, 4, 0).GetNumericAddressBE(), htonl(0x01020304)); +} diff --git a/test/net/TestIPv6Address.cxx b/test/net/TestIPv6Address.cxx new file mode 100644 index 000000000..69a9dc1b1 --- /dev/null +++ b/test/net/TestIPv6Address.cxx @@ -0,0 +1,82 @@ +/* + * Copyright 2012-2019 Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "net/IPv6Address.hxx" +#include "net/ToString.hxx" + +#include + +#include + +#include + +static std::string +ToString(const struct in6_addr &a) +{ + char buffer[256]; + const char *result = inet_ntop(AF_INET6, &a, buffer, sizeof(buffer)); + if (result == nullptr) + throw std::runtime_error("inet_ntop() failed"); + return result; +} + +TEST(IPv6Address, Octets) +{ + static constexpr auto a = IPv6Address(0x1110, 0x2220, 0x3330, 0x4440, + 0x5550, 0x6660, 0x7770, 0x8880, + 1234); + EXPECT_EQ(ToString(a.GetAddress()), "1110:2220:3330:4440:5550:6660:7770:8880"); +} + +TEST(IPv6Address, Any) +{ + EXPECT_EQ(ToString(IPv6Address(1234).GetAddress()), "::"); + EXPECT_EQ(ToString(IPv6Address(1234)), "[::]:1234"); +} + +TEST(IPv6Address, Port) +{ + EXPECT_EQ(IPv6Address(0).GetPort(), 0); + EXPECT_EQ(IPv6Address(1).GetPort(), 1); + EXPECT_EQ(IPv6Address(1234).GetPort(), 1234); + EXPECT_EQ(IPv6Address(0xffff).GetPort(), 0xffff); +} + +TEST(IPv6Address, MaskFromPrefix) +{ + EXPECT_EQ(ToString(IPv6Address::MaskFromPrefix(0).GetAddress()), "::"); + EXPECT_EQ(ToString(IPv6Address::MaskFromPrefix(1).GetAddress()), "8000::"); + EXPECT_EQ(ToString(IPv6Address::MaskFromPrefix(8).GetAddress()), "ff00::"); + EXPECT_EQ(ToString(IPv6Address::MaskFromPrefix(16).GetAddress()), "ffff::"); + EXPECT_EQ(ToString(IPv6Address::MaskFromPrefix(17).GetAddress()), "ffff:8000::"); + EXPECT_EQ(ToString(IPv6Address::MaskFromPrefix(32).GetAddress()), "ffff:ffff::"); + EXPECT_EQ(ToString(IPv6Address::MaskFromPrefix(64).GetAddress()), "ffff:ffff:ffff:ffff::"); + EXPECT_EQ(ToString(IPv6Address::MaskFromPrefix(112).GetAddress()), "ffff:ffff:ffff:ffff:ffff:ffff:ffff:0"); + EXPECT_EQ(ToString(IPv6Address::MaskFromPrefix(128).GetAddress()), "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"); +} diff --git a/test/net/TestLocalSocketAddress.cxx b/test/net/TestLocalSocketAddress.cxx new file mode 100644 index 000000000..1eef4882f --- /dev/null +++ b/test/net/TestLocalSocketAddress.cxx @@ -0,0 +1,74 @@ +/* + * Copyright 2012-2019 Max Kellermann + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "net/AllocatedSocketAddress.hxx" +#include "net/ToString.hxx" + +#include + +#include + +TEST(LocalSocketAddress, Path) +{ + const char *path = "/run/foo/bar.socket"; + AllocatedSocketAddress a; + a.SetLocal(path); + EXPECT_FALSE(a.IsNull()); + EXPECT_TRUE(a.IsDefined()); + EXPECT_EQ(a.GetFamily(), AF_LOCAL); + EXPECT_EQ(ToString(a), path); + + const auto &sun = *(const struct sockaddr_un *)a.GetAddress(); + EXPECT_STREQ(sun.sun_path, path); + EXPECT_EQ(sun.sun_path + strlen(path) + 1, (const char *)a.GetAddress() + a.GetSize()); +} + +#ifdef __linux__ + +TEST(LocalSocketAddress, Abstract) +{ + const char *path = "@foo.bar"; + AllocatedSocketAddress a; + a.SetLocal(path); + EXPECT_FALSE(a.IsNull()); + EXPECT_TRUE(a.IsDefined()); + EXPECT_EQ(a.GetFamily(), AF_LOCAL); + EXPECT_EQ(ToString(a), path); + + const auto &sun = *(const struct sockaddr_un *)a.GetAddress(); + + /* Linux's abstract sockets start with a null byte, ... */ + EXPECT_EQ(sun.sun_path[0], 0); + + /* ... but are not null-terminated */ + EXPECT_STREQ(sun.sun_path + 1, path + 1); + EXPECT_EQ(sun.sun_path + strlen(path), (const char *)a.GetAddress() + a.GetSize()); +} + +#endif diff --git a/test/net/meson.build b/test/net/meson.build new file mode 100644 index 000000000..076e6f062 --- /dev/null +++ b/test/net/meson.build @@ -0,0 +1,25 @@ +test_net_sources = [] + +if have_tcp + test_net_sources += 'TestIPv4Address.cxx' + if have_ipv6 + test_net_sources += 'TestIPv6Address.cxx' + endif +endif + +if have_local_socket + test_net_sources += 'TestLocalSocketAddress.cxx' +endif + +test( + 'TestNet', + executable( + 'TestNet', + test_net_sources, + include_directories: inc, + dependencies: [ + net_dep, + gtest_dep, + ], + ), +)