#include <string>
-#include <folly/Bits.h>
#include <folly/Format.h>
#include <folly/IPAddress.h>
#include <folly/MacAddress.h>
#include <folly/String.h>
+#include <folly/container/BitIterator.h>
#include <folly/detail/IPAddressSource.h>
+#include <folly/lang/Bits.h>
#include <folly/portability/GMock.h>
#include <folly/portability/GTest.h>
struct IPAddressByteAccessorTest : TestWithParam<AddressData> {};
struct IPAddressBitAccessorTest : TestWithParam<AddressData> {};
+struct StringTestParam {
+ std::string in;
+ folly::Optional<std::string> out;
+ folly::Optional<std::string> out4;
+ folly::Optional<std::string> out6;
+};
+
+struct TryFromStringTest : TestWithParam<StringTestParam> {
+ static std::vector<StringTestParam> ipInOutProvider() {
+ const std::string lo6{"::1"};
+ const std::string lo6brackets{"[::1]"};
+ const std::string ip6{"1234::abcd"};
+ const std::string invalid6{"[::aaaR]"};
+
+ const std::string lo4{"127.0.0.1"};
+ const std::string ip4{"192.168.0.1"};
+ const std::string invalid4{"127.0.0.256"};
+
+ const static std::vector<StringTestParam> ret = {
+ {lo6, lo6, none, lo6},
+ {lo6brackets, lo6, none, lo6},
+ {ip6, ip6, none, ip6},
+ {invalid6, none, none, none},
+ {lo4, lo4, lo4, none},
+ {ip4, ip4, ip4, none},
+ {invalid4, none, none, none},
+ };
+
+ return ret;
+ }
+};
+
// tests code example
TEST(IPAddress, CodeExample) {
EXPECT_EQ(4, sizeof(IPAddressV4));
}
}
+TEST_P(TryFromStringTest, IPAddress) {
+ auto param = GetParam();
+ auto maybeIp = IPAddress::tryFromString(param.in);
+ if (param.out) {
+ EXPECT_TRUE(maybeIp.hasValue());
+ EXPECT_EQ(param.out, maybeIp.value().str());
+ } else {
+ EXPECT_TRUE(maybeIp.hasError());
+ EXPECT_TRUE(
+ IPAddressFormatError::INVALID_IP == maybeIp.error() ||
+ IPAddressFormatError::UNSUPPORTED_ADDR_FAMILY == maybeIp.error());
+ }
+}
+
+TEST_P(TryFromStringTest, IPAddressV4) {
+ auto param = GetParam();
+ auto maybeIp = IPAddressV4::tryFromString(param.in);
+ if (param.out4) {
+ EXPECT_TRUE(maybeIp.hasValue());
+ EXPECT_EQ(param.out4, maybeIp.value().str());
+ } else {
+ EXPECT_TRUE(maybeIp.hasError());
+ EXPECT_EQ(IPAddressFormatError::INVALID_IP, maybeIp.error());
+ }
+}
+
+TEST_P(TryFromStringTest, IPAddressV6) {
+ auto param = GetParam();
+ auto maybeIp = IPAddressV6::tryFromString(param.in);
+ if (param.out6) {
+ EXPECT_TRUE(maybeIp.hasValue());
+ EXPECT_EQ(param.out6, maybeIp.value().str());
+ } else {
+ EXPECT_TRUE(maybeIp.hasError());
+ EXPECT_EQ(IPAddressFormatError::INVALID_IP, maybeIp.error());
+ }
+}
+
TEST(IPAddress, ToString) {
// Test with IPAddressV4
IPAddressV4 addr_10_0_0_1("10.0.0.1");
<< "should have thrown an IPAddressFormatException";
}
-// Test that invalid binary values throw an exception
+// Test that invalid binary values throw or return an exception
TEST_P(IPAddressCtorBinaryTest, InvalidBinary) {
auto bin = GetParam();
- EXPECT_THROW(
- IPAddress::fromBinary(ByteRange(&bin[0], bin.size())),
- IPAddressFormatException);
+ auto byteRange = ByteRange(&bin[0], bin.size());
+ // Throwing versions.
+ EXPECT_THROW(IPAddress::fromBinary(byteRange), IPAddressFormatException);
+ EXPECT_THROW(IPAddressV4::fromBinary(byteRange), IPAddressFormatException);
+ EXPECT_THROW(IPAddressV6::fromBinary(byteRange), IPAddressFormatException);
+ // Non-throwing versions.
+ EXPECT_TRUE(IPAddress::tryFromBinary(byteRange).hasError());
+ EXPECT_TRUE(IPAddressV4::tryFromBinary(byteRange).hasError());
+ EXPECT_TRUE(IPAddressV6::tryFromBinary(byteRange).hasError());
}
TEST(IPAddressSource, ToHex) {
addr2 = IPAddressV4::fromBinary(bytes);
EXPECT_EQ(fromStr, addr2);
+ auto maybeAddr3 = IPAddressV4::tryFromBinary(bytes);
+ EXPECT_TRUE(maybeAddr3.hasValue());
+ EXPECT_EQ(fromStr, maybeAddr3.value());
+
IPAddress genericAddr = IPAddress::fromBinary(bytes);
ASSERT_TRUE(genericAddr.isV4());
EXPECT_EQ(fromStr, genericAddr.asV4());
addr2 = IPAddressV6::fromBinary(bytes);
EXPECT_EQ(fromStr, addr2);
+ auto maybeAddr3 = IPAddressV6::tryFromBinary(bytes);
+ EXPECT_TRUE(maybeAddr3.hasValue());
+ EXPECT_EQ(fromStr, maybeAddr3.value());
+
IPAddress genericAddr = IPAddress::fromBinary(bytes);
ASSERT_TRUE(genericAddr.isV6());
EXPECT_EQ(fromStr, genericAddr.asV6());
EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
}
+TEST(IPAddress, getMacAddressFromEUI64) {
+ IPAddressV6 ip6("2401:db00:3020:51dc:4a57:ddff:fe04:5643");
+ EXPECT_TRUE(ip6.getMacAddressFromEUI64().hasValue());
+ EXPECT_EQ("48:57:dd:04:56:43", ip6.getMacAddressFromEUI64()->toString());
+ ip6 = IPAddressV6("fe80::4a57:ddff:fe04:5643");
+ EXPECT_TRUE(ip6.getMacAddressFromEUI64().hasValue());
+ EXPECT_EQ("48:57:dd:04:56:43", ip6.getMacAddressFromEUI64()->toString());
+}
+
+TEST(IPAddress, getMacAddressFromEUI64_Negative) {
+ IPAddressV6 not_eui64_ip6("2401:db00:3020:51dc:face:0000:009a:0000");
+ EXPECT_FALSE(not_eui64_ip6.getMacAddressFromEUI64().hasValue());
+}
+
TEST(IPAddress, LongestCommonPrefix) {
IPAddress ip10("10.0.0.0");
IPAddress ip11("11.0.0.0");
IPAddress,
IPAddressBitAccessorTest,
::testing::ValuesIn(validAddressProvider));
+INSTANTIATE_TEST_CASE_P(
+ IPAddress,
+ TryFromStringTest,
+ ::testing::ValuesIn(TryFromStringTest::ipInOutProvider()));
TEST(IPAddressV4, fetchMask) {
struct X : private IPAddressV4 {