/Users/deen/code/yugabyte-db/src/yb/util/net/net_util-test.cc
Line | Count | Source |
1 | | // Licensed to the Apache Software Foundation (ASF) under one |
2 | | // or more contributor license agreements. See the NOTICE file |
3 | | // distributed with this work for additional information |
4 | | // regarding copyright ownership. The ASF licenses this file |
5 | | // to you under the Apache License, Version 2.0 (the |
6 | | // "License"); you may not use this file except in compliance |
7 | | // with the License. You may obtain a copy of the License at |
8 | | // |
9 | | // http://www.apache.org/licenses/LICENSE-2.0 |
10 | | // |
11 | | // Unless required by applicable law or agreed to in writing, |
12 | | // software distributed under the License is distributed on an |
13 | | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | | // KIND, either express or implied. See the License for the |
15 | | // specific language governing permissions and limitations |
16 | | // under the License. |
17 | | // |
18 | | // The following only applies to changes made to this file as part of YugaByte development. |
19 | | // |
20 | | // Portions Copyright (c) YugaByte, Inc. |
21 | | // |
22 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
23 | | // in compliance with the License. You may obtain a copy of the License at |
24 | | // |
25 | | // http://www.apache.org/licenses/LICENSE-2.0 |
26 | | // |
27 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
28 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
29 | | // or implied. See the License for the specific language governing permissions and limitations |
30 | | // under the License. |
31 | | // |
32 | | |
33 | | #include <string> |
34 | | #include <vector> |
35 | | |
36 | | #include <gtest/gtest.h> |
37 | | |
38 | | #include "yb/gutil/strings/join.h" |
39 | | #include "yb/gutil/strings/util.h" |
40 | | |
41 | | #include "yb/util/net/net_util.h" |
42 | | #include "yb/util/net/sockaddr.h" |
43 | | #include "yb/util/net/socket.h" |
44 | | #include "yb/util/status.h" |
45 | | #include "yb/util/test_macros.h" |
46 | | #include "yb/util/test_util.h" |
47 | | #include "yb/util/tostring.h" |
48 | | |
49 | | namespace yb { |
50 | | |
51 | | class NetUtilTest : public YBTest { |
52 | | protected: |
53 | 6 | Status DoParseBindAddresses(const string& input, string* result) { |
54 | 6 | std::vector<Endpoint> addrs; |
55 | 6 | RETURN_NOT_OK(ParseAddressList(input, kDefaultPort, &addrs)); |
56 | 3 | std::sort(addrs.begin(), addrs.end()); |
57 | | |
58 | 3 | std::vector<string> addr_strs; |
59 | 4 | for (const auto& addr : addrs) { |
60 | 4 | addr_strs.push_back(ToString(addr)); |
61 | 4 | } |
62 | 3 | *result = JoinStrings(addr_strs, ","); |
63 | 3 | return Status::OK(); |
64 | 6 | } |
65 | | |
66 | 2 | Status GetHostPorts(const string &endpoint_str, vector<HostPort> *hps) { |
67 | 2 | return HostPort::ParseStrings(endpoint_str, NetUtilTest::kDefaultPort, hps); |
68 | 2 | } |
69 | | |
70 | 10 | Status GetHostPort(const string &endpoint_str, HostPort *hp) { |
71 | 10 | return hp->ParseString(endpoint_str, NetUtilTest::kDefaultPort); |
72 | 10 | } |
73 | | |
74 | 5 | uint16_t GetDefaultPort() { return NetUtilTest::kDefaultPort; } |
75 | | |
76 | | static const uint16_t kDefaultPort = 7150; |
77 | | }; |
78 | | |
79 | 1 | TEST(SockaddrTest, Test) { |
80 | 1 | boost::system::error_code ec; |
81 | 1 | const auto& kRegularAddr = "1.1.1.1"; |
82 | 1 | auto address = IpAddress::from_string(kRegularAddr, ec); |
83 | 1 | ASSERT_FALSE(ec); |
84 | 1 | Endpoint endpoint(address, 12345); |
85 | 1 | ASSERT_EQ("1.1.1.1:12345", ToString(endpoint)); |
86 | 1 | ASSERT_EQ(12345, endpoint.port()); |
87 | | |
88 | 1 | ASSERT_FALSE(IsWildcardAddress(kRegularAddr)); |
89 | 1 | const auto kWildcardAddr1 = "0.0.0.0"; |
90 | 1 | ASSERT_TRUE(IsWildcardAddress(kWildcardAddr1)); |
91 | 1 | const auto kWildcardAddr2 = "::"; |
92 | 1 | ASSERT_TRUE(IsWildcardAddress(kWildcardAddr2)); |
93 | 1 | ASSERT_FALSE(IsWildcardAddress("::1")); |
94 | 1 | } |
95 | | |
96 | 1 | TEST_F(NetUtilTest, TestParseAddresses) { |
97 | 1 | string ret; |
98 | 1 | ASSERT_OK(DoParseBindAddresses("0.0.0.0:12345", &ret)); |
99 | 1 | ASSERT_EQ("0.0.0.0:12345", ret); |
100 | | |
101 | 1 | ASSERT_OK(DoParseBindAddresses("0.0.0.0", &ret)); |
102 | 1 | ASSERT_EQ("0.0.0.0:7150", ret); |
103 | | |
104 | 1 | ASSERT_OK(DoParseBindAddresses("0.0.0.0:12345, 0.0.0.0:12346", &ret)); |
105 | 1 | ASSERT_EQ("0.0.0.0:12345,0.0.0.0:12346", ret); |
106 | | |
107 | | // Test some invalid addresses. |
108 | 1 | Status s = DoParseBindAddresses("0.0.0.0:xyz", &ret); |
109 | 1 | ASSERT_STR_CONTAINS(s.ToString(), "Invalid port"); |
110 | | |
111 | 1 | s = DoParseBindAddresses("0.0.0.0:100000", &ret); |
112 | 1 | ASSERT_STR_CONTAINS(s.ToString(), "Invalid port"); |
113 | | |
114 | 1 | s = DoParseBindAddresses("0.0.0.0:", &ret); |
115 | 1 | ASSERT_STR_CONTAINS(s.ToString(), "Invalid port"); |
116 | 1 | } |
117 | | |
118 | 1 | TEST_F(NetUtilTest, TestHostPortParsing) { |
119 | 1 | const vector<string> hosts = { "samplehost.example.org", "192.168.1.45" }; |
120 | 1 | const vector<string> ipv6_hosts = { "2600:1f18:1094:c832:36e6:43b9:e6c8:02", |
121 | 1 | "0:0:0:0:0:0:0:1", "fe80%lo" }; |
122 | 2 | for (const auto &host : hosts) { |
123 | 2 | std::unique_ptr<HostPort> hp(new HostPort()); |
124 | 2 | ASSERT_OK(GetHostPort(Format("$0:7100", host), hp.get())); |
125 | 2 | ASSERT_EQ(hp->port(), 7100); |
126 | 2 | ASSERT_EQ(hp->host(), host); |
127 | | |
128 | 2 | hp.reset(new HostPort()); |
129 | 2 | ASSERT_OK(GetHostPort(Format("$0", host), hp.get())); |
130 | 2 | ASSERT_EQ(hp->port(), GetDefaultPort()); |
131 | 2 | ASSERT_EQ(hp->host(), host); |
132 | 2 | } |
133 | | |
134 | 3 | for (const auto &host : ipv6_hosts) { |
135 | 3 | std::unique_ptr<HostPort> hp(new HostPort()); |
136 | 3 | ASSERT_OK(GetHostPort(Format("[$0]:7100", host), hp.get())); |
137 | 3 | ASSERT_EQ(hp->port(), 7100); |
138 | 3 | ASSERT_EQ(hp->host(), host); |
139 | | |
140 | 3 | hp.reset(new HostPort()); |
141 | 3 | ASSERT_OK(GetHostPort(Format("[$0]", host), hp.get())); |
142 | 3 | ASSERT_EQ(hp->port(), GetDefaultPort()); |
143 | 3 | ASSERT_EQ(hp->host(), host); |
144 | 3 | } |
145 | | |
146 | 1 | vector<HostPort> hps; |
147 | 1 | ASSERT_OK(GetHostPorts("[::1]:7100,127.0.0.1:7200", &hps)); |
148 | 1 | ASSERT_EQ(hps.size(), 2); |
149 | 1 | ASSERT_EQ(hps[0].port(), 7100); |
150 | 1 | ASSERT_EQ(hps[1].port(), 7200); |
151 | | |
152 | 1 | hps.clear(); |
153 | 1 | ASSERT_OK(GetHostPorts( |
154 | 1 | "[2600:1f18:1094:c832:36e6:43b9:e6c8:f02]:7100,0.0.0.0:7200", &hps)); |
155 | 1 | ASSERT_EQ(hps.size(), 2); |
156 | 1 | ASSERT_EQ(hps[0].port(), 7100); |
157 | 1 | ASSERT_EQ(hps[1].port(), 7200); |
158 | 1 | } |
159 | | |
160 | 1 | TEST_F(NetUtilTest, TestResolveAddresses) { |
161 | 1 | HostPort hp("localhost", 12345); |
162 | 1 | std::vector<Endpoint> addrs; |
163 | 1 | ASSERT_OK(hp.ResolveAddresses(&addrs)); |
164 | 1 | ASSERT_TRUE(!addrs.empty()); |
165 | 2 | for (const auto& addr : addrs) { |
166 | 2 | LOG(INFO) << "Address: " << ToString(addr); |
167 | 2 | if (addr.address().is_v4()) { |
168 | 1 | EXPECT_TRUE(HasPrefixString(ToString(addr), "127.")); |
169 | 1 | EXPECT_TRUE(HasSuffixString(ToString(addr), ":12345")); |
170 | 1 | } else if (addr.address().is_v6()) { |
171 | 1 | EXPECT_TRUE(HasPrefixString(ToString(addr), "[::1]")); |
172 | 1 | EXPECT_TRUE(HasSuffixString(ToString(addr), ":12345")); |
173 | 1 | } |
174 | 2 | EXPECT_TRUE(addr.address().is_loopback()); |
175 | 2 | } |
176 | | |
177 | 1 | ASSERT_OK(hp.ResolveAddresses(nullptr)); |
178 | 1 | } |
179 | | |
180 | | // Ensure that we are able to do a reverse DNS lookup on various IP addresses. |
181 | | // The reverse lookups should never fail, but may return numeric strings. |
182 | 1 | TEST_F(NetUtilTest, TestReverseLookup) { |
183 | 1 | string host; |
184 | 1 | Endpoint addr(boost::asio::ip::address_v4(), 12345); |
185 | 1 | HostPort hp; |
186 | 1 | EXPECT_EQ(12345, addr.port()); |
187 | 1 | ASSERT_OK(HostPortFromEndpointReplaceWildcard(addr, &hp)); |
188 | 1 | EXPECT_NE("0.0.0.0", hp.host()); |
189 | 1 | EXPECT_NE("", hp.host()); |
190 | 1 | EXPECT_EQ(12345, hp.port()); |
191 | | |
192 | 1 | addr = Endpoint(boost::asio::ip::address_v4::loopback(), 12345); |
193 | 1 | ASSERT_OK(HostPortFromEndpointReplaceWildcard(addr, &hp)); |
194 | 1 | EXPECT_EQ("127.0.0.1", hp.host()); |
195 | 1 | EXPECT_EQ(12345, hp.port()); |
196 | 1 | } |
197 | | |
198 | 1 | TEST_F(NetUtilTest, TestLsof) { |
199 | 1 | Socket s; |
200 | 1 | ASSERT_OK(s.Init(0)); |
201 | | |
202 | 1 | Endpoint addr; // wildcard |
203 | 1 | ASSERT_OK(s.BindAndListen(addr, 1)); |
204 | | |
205 | 1 | ASSERT_OK(s.GetSocketAddress(&addr)); |
206 | 1 | ASSERT_NE(addr.port(), 0); |
207 | 1 | vector<string> lsof_lines; |
208 | 1 | TryRunLsof(addr, &lsof_lines); |
209 | 1 | SCOPED_TRACE(JoinStrings(lsof_lines, "\n")); |
210 | | |
211 | 1 | ASSERT_GE(lsof_lines.size(), 3); |
212 | 1 | ASSERT_STR_CONTAINS(lsof_lines[2], "net_util-test"); |
213 | 1 | } |
214 | | |
215 | 1 | TEST_F(NetUtilTest, TestGetFQDN) { |
216 | 1 | string fqdn; |
217 | 1 | ASSERT_OK(GetFQDN(&fqdn)); |
218 | 1 | LOG(INFO) << "fqdn is " << fqdn; |
219 | 1 | } |
220 | | |
221 | 1 | TEST_F(NetUtilTest, LocalAddresses) { |
222 | 1 | std::vector<IpAddress> addresses, external_addresses; |
223 | 1 | ASSERT_OK(GetLocalAddresses(&addresses, AddressFilter::ANY)); |
224 | 1 | LOG(INFO) << "Any addresses: " << ToString(addresses); |
225 | 1 | ASSERT_OK(GetLocalAddresses(&external_addresses, AddressFilter::EXTERNAL)); |
226 | 1 | LOG(INFO) << "External addresses: " << ToString(external_addresses); |
227 | 1 | ASSERT_GT(addresses.size(), external_addresses.size()); |
228 | 1 | } |
229 | | |
230 | | } // namespace yb |