01aa3c49021485caf61b464ba020e03b4c569367
[folly.git] / folly / test / IPAddressTest.h
1 /*
2  * Copyright 2016 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #pragma once
18
19 #include <string>
20
21 #include <gtest/gtest.h>
22
23 #include <sys/types.h>
24
25 #include <folly/IPAddress.h>
26 #include <folly/portability/Sockets.h>
27
28 namespace folly {
29
30 class IPAddress;
31
32 typedef std::vector<uint8_t> ByteVector;
33
34 struct AddressData {
35   std::string address;
36   ByteVector bytes;
37   uint8_t version;
38
39   AddressData(const std::string& address, const ByteVector& bytes,
40               uint8_t version)
41     : address(address), bytes(bytes), version(version) {}
42   AddressData(const std::string& address, uint8_t version)
43     : address(address), bytes(), version(version) {}
44   explicit AddressData(const std::string& address)
45     : address(address), bytes(), version(0) {}
46   AddressData(): address(""), bytes(), version(0) {}
47
48   static in_addr parseAddress4(const std::string& src) {
49     in_addr addr;
50     inet_pton(AF_INET, src.c_str(), &addr);
51     return addr;
52   }
53
54   static in6_addr parseAddress6(const std::string& src) {
55     in6_addr addr;
56     inet_pton(AF_INET6, src.c_str(), &addr);
57     return addr;
58   }
59 };
60
61 struct AddressFlags {
62   std::string address;
63   uint8_t flags;
64   uint8_t version;
65
66   static const uint8_t IS_LOCAL = 1 << 0;
67   static const uint8_t IS_NONROUTABLE = 1 << 1;
68   static const uint8_t IS_PRIVATE = 1 << 2;
69   static const uint8_t IS_ZERO = 1 << 3;
70   static const uint8_t IS_LINK_LOCAL = 1 << 4;
71   static const uint8_t IS_MULTICAST = 1 << 5;
72   static const uint8_t IS_LINK_LOCAL_BROADCAST = 1 << 6;
73
74   AddressFlags(const std::string& addr, uint8_t version, uint8_t flags)
75     : address(addr)
76     , flags(flags)
77     , version(version)
78   {}
79
80   bool isLoopback() const {
81     return (flags & IS_LOCAL);
82   }
83   bool isNonroutable() const {
84     return (flags & IS_NONROUTABLE);
85   }
86   bool isPrivate() const {
87     return (flags & IS_PRIVATE);
88   }
89   bool isZero() const {
90     return (flags & IS_ZERO);
91   }
92   bool isLinkLocal() const {
93     return (flags & IS_LINK_LOCAL);
94   }
95   bool isLinkLocalBroadcast() const {
96     return (flags & IS_LINK_LOCAL_BROADCAST);
97   }
98 };
99
100 struct MaskData {
101   std::string address;
102   uint8_t mask;
103   std::string subnet;
104   MaskData(const std::string& addr, uint8_t mask,
105            const std::string& subnet)
106     : address(addr)
107     , mask(mask)
108     , subnet(subnet)
109   {}
110 };
111
112 struct MaskBoundaryData : MaskData {
113   bool inSubnet;
114   MaskBoundaryData(const std::string& addr, uint8_t mask,
115                    const std::string& subnet, bool inSubnet)
116     : MaskData(addr, mask, subnet)
117     , inSubnet(inSubnet)
118   {}
119 };
120
121 struct SerializeData {
122   std::string address;
123   ByteVector bytes;
124
125   SerializeData(const std::string& addr, const ByteVector& bytes)
126     : address(addr)
127     , bytes(bytes)
128   {}
129 };
130
131 struct IPAddressTest : public ::testing::TestWithParam<AddressData> {
132   void ExpectIsValid(const IPAddress& addr) {
133     AddressData param = GetParam();
134     EXPECT_EQ(param.version, addr.version());
135     EXPECT_EQ(param.address, addr.str());
136     if (param.version == 4) {
137       in_addr v4addr = AddressData::parseAddress4(param.address);
138       EXPECT_EQ(0, memcmp(&v4addr, addr.asV4().toByteArray().data(), 4));
139       EXPECT_TRUE(addr.isV4());
140       EXPECT_FALSE(addr.isV6());
141     } else {
142       in6_addr v6addr = AddressData::parseAddress6(param.address);
143       EXPECT_EQ(0, memcmp(&v6addr, addr.asV6().toByteArray().data(), 16));
144       EXPECT_TRUE(addr.isV6());
145       EXPECT_FALSE(addr.isV4());
146     }
147   }
148 };
149 struct IPAddressFlagTest : public ::testing::TestWithParam<AddressFlags> {};
150 struct IPAddressCtorTest : public ::testing::TestWithParam<std::string> {};
151 struct IPAddressCtorBinaryTest : public ::testing::TestWithParam<ByteVector> {};
152 struct IPAddressMappedTest :
153     public ::testing::TestWithParam<std::pair<std::string,std::string> > {};
154 struct IPAddressMaskTest : public ::testing::TestWithParam<MaskData> {};
155 struct IPAddressMaskBoundaryTest :
156     public ::testing::TestWithParam<MaskBoundaryData> {};
157 struct IPAddressSerializeTest :
158     public ::testing::TestWithParam<SerializeData> {};
159 struct IPAddressByteAccessorTest:
160     public ::testing::TestWithParam<AddressData> {};
161 struct IPAddressBitAccessorTest:
162     public ::testing::TestWithParam<AddressData> {};
163 } // folly