1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "net/dns/dns_hosts.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include "base/test/metrics/histogram_tester.h"
8*6777b538SAndroid Build Coastguard Worker #include "base/trace_event/memory_usage_estimator.h"
9*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
10*6777b538SAndroid Build Coastguard Worker #include "net/base/cronet_buildflags.h"
11*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_address.h"
12*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker namespace net {
15*6777b538SAndroid Build Coastguard Worker
16*6777b538SAndroid Build Coastguard Worker namespace {
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker struct ExpectedHostsEntry {
19*6777b538SAndroid Build Coastguard Worker const char* host;
20*6777b538SAndroid Build Coastguard Worker AddressFamily family;
21*6777b538SAndroid Build Coastguard Worker const char* ip;
22*6777b538SAndroid Build Coastguard Worker };
23*6777b538SAndroid Build Coastguard Worker
PopulateExpectedHosts(const ExpectedHostsEntry * entries,size_t num_entries,DnsHosts * expected_hosts_out)24*6777b538SAndroid Build Coastguard Worker void PopulateExpectedHosts(const ExpectedHostsEntry* entries,
25*6777b538SAndroid Build Coastguard Worker size_t num_entries,
26*6777b538SAndroid Build Coastguard Worker DnsHosts* expected_hosts_out) {
27*6777b538SAndroid Build Coastguard Worker for (size_t i = 0; i < num_entries; ++i) {
28*6777b538SAndroid Build Coastguard Worker DnsHostsKey key(entries[i].host, entries[i].family);
29*6777b538SAndroid Build Coastguard Worker IPAddress& ip_ref = (*expected_hosts_out)[key];
30*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(ip_ref.empty());
31*6777b538SAndroid Build Coastguard Worker ASSERT_TRUE(ip_ref.AssignFromIPLiteral(entries[i].ip));
32*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(ip_ref.size(),
33*6777b538SAndroid Build Coastguard Worker (entries[i].family == ADDRESS_FAMILY_IPV4) ? 4u : 16u);
34*6777b538SAndroid Build Coastguard Worker }
35*6777b538SAndroid Build Coastguard Worker }
36*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,ParseHosts)37*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, ParseHosts) {
38*6777b538SAndroid Build Coastguard Worker const std::string kContents =
39*6777b538SAndroid Build Coastguard Worker "127.0.0.1 localhost # standard\n"
40*6777b538SAndroid Build Coastguard Worker "\n"
41*6777b538SAndroid Build Coastguard Worker "1.0.0.1 localhost # ignored, first hit above\n"
42*6777b538SAndroid Build Coastguard Worker "fe00::x example company # ignored, malformed IPv6\n"
43*6777b538SAndroid Build Coastguard Worker "1.0.0.300 company # ignored, malformed IPv4\n"
44*6777b538SAndroid Build Coastguard Worker "1.0.0.1 # ignored, missing hostname\n"
45*6777b538SAndroid Build Coastguard Worker "1.0.0.1\t CoMpANy # normalized to 'company' \n"
46*6777b538SAndroid Build Coastguard Worker "::1\tlocalhost ip6-localhost ip6-loopback # comment # within a comment\n"
47*6777b538SAndroid Build Coastguard Worker "\t fe00::0 ip6-localnet\r\n"
48*6777b538SAndroid Build Coastguard Worker "2048::2 example\n"
49*6777b538SAndroid Build Coastguard Worker "2048::1 company example # ignored for 'example' \n"
50*6777b538SAndroid Build Coastguard Worker "127.0.0.1 cache1\n"
51*6777b538SAndroid Build Coastguard Worker "127.0.0.1 cache2 # should reuse parsed IP\n"
52*6777b538SAndroid Build Coastguard Worker "256.0.0.0 cache3 # bogus IP should not clear parsed IP cache\n"
53*6777b538SAndroid Build Coastguard Worker "127.0.0.1 cache4 # should still be reused\n"
54*6777b538SAndroid Build Coastguard Worker "127.0.0.2 cache5\n"
55*6777b538SAndroid Build Coastguard Worker "127.0.0.3 .foo # entries with leading dot are ignored\n"
56*6777b538SAndroid Build Coastguard Worker "127.0.0.3 . # just a dot is ignored\n"
57*6777b538SAndroid Build Coastguard Worker "127.0.0.4 bar. # trailing dot is allowed, for now\n"
58*6777b538SAndroid Build Coastguard Worker "gibberish\n"
59*6777b538SAndroid Build Coastguard Worker "127.0.0.5 fóó.test # canonicalizes to 'xn--f-vgaa.test' due to RFC3490\n"
60*6777b538SAndroid Build Coastguard Worker "127.0.0.6 127.0.0.1 # ignore IP host\n"
61*6777b538SAndroid Build Coastguard Worker "2048::3 [::1] # ignore IP host";
62*6777b538SAndroid Build Coastguard Worker
63*6777b538SAndroid Build Coastguard Worker const ExpectedHostsEntry kEntries[] = {
64*6777b538SAndroid Build Coastguard Worker {"localhost", ADDRESS_FAMILY_IPV4, "127.0.0.1"},
65*6777b538SAndroid Build Coastguard Worker {"company", ADDRESS_FAMILY_IPV4, "1.0.0.1"},
66*6777b538SAndroid Build Coastguard Worker {"localhost", ADDRESS_FAMILY_IPV6, "::1"},
67*6777b538SAndroid Build Coastguard Worker {"ip6-localhost", ADDRESS_FAMILY_IPV6, "::1"},
68*6777b538SAndroid Build Coastguard Worker {"ip6-loopback", ADDRESS_FAMILY_IPV6, "::1"},
69*6777b538SAndroid Build Coastguard Worker {"ip6-localnet", ADDRESS_FAMILY_IPV6, "fe00::0"},
70*6777b538SAndroid Build Coastguard Worker {"company", ADDRESS_FAMILY_IPV6, "2048::1"},
71*6777b538SAndroid Build Coastguard Worker {"example", ADDRESS_FAMILY_IPV6, "2048::2"},
72*6777b538SAndroid Build Coastguard Worker {"cache1", ADDRESS_FAMILY_IPV4, "127.0.0.1"},
73*6777b538SAndroid Build Coastguard Worker {"cache2", ADDRESS_FAMILY_IPV4, "127.0.0.1"},
74*6777b538SAndroid Build Coastguard Worker {"cache4", ADDRESS_FAMILY_IPV4, "127.0.0.1"},
75*6777b538SAndroid Build Coastguard Worker {"cache5", ADDRESS_FAMILY_IPV4, "127.0.0.2"},
76*6777b538SAndroid Build Coastguard Worker {"bar.", ADDRESS_FAMILY_IPV4, "127.0.0.4"},
77*6777b538SAndroid Build Coastguard Worker {"xn--f-vgaa.test", ADDRESS_FAMILY_IPV4, "127.0.0.5"},
78*6777b538SAndroid Build Coastguard Worker };
79*6777b538SAndroid Build Coastguard Worker
80*6777b538SAndroid Build Coastguard Worker DnsHosts expected_hosts, actual_hosts;
81*6777b538SAndroid Build Coastguard Worker PopulateExpectedHosts(kEntries, std::size(kEntries), &expected_hosts);
82*6777b538SAndroid Build Coastguard Worker
83*6777b538SAndroid Build Coastguard Worker base::HistogramTester histograms;
84*6777b538SAndroid Build Coastguard Worker ParseHosts(kContents, &actual_hosts);
85*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(expected_hosts, actual_hosts);
86*6777b538SAndroid Build Coastguard Worker histograms.ExpectUniqueSample("Net.DNS.DnsHosts.Count", std::size(kEntries),
87*6777b538SAndroid Build Coastguard Worker 1);
88*6777b538SAndroid Build Coastguard Worker #if !BUILDFLAG(CRONET_BUILD)
89*6777b538SAndroid Build Coastguard Worker histograms.ExpectUniqueSample(
90*6777b538SAndroid Build Coastguard Worker "Net.DNS.DnsHosts.EstimateMemoryUsage",
91*6777b538SAndroid Build Coastguard Worker base::trace_event::EstimateMemoryUsage(actual_hosts), 1);
92*6777b538SAndroid Build Coastguard Worker #endif
93*6777b538SAndroid Build Coastguard Worker }
94*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,ParseHosts_CommaIsToken)95*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, ParseHosts_CommaIsToken) {
96*6777b538SAndroid Build Coastguard Worker const std::string kContents = "127.0.0.1 comma1,comma2";
97*6777b538SAndroid Build Coastguard Worker
98*6777b538SAndroid Build Coastguard Worker const ExpectedHostsEntry kEntries[] = {
99*6777b538SAndroid Build Coastguard Worker { "comma1,comma2", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
100*6777b538SAndroid Build Coastguard Worker };
101*6777b538SAndroid Build Coastguard Worker
102*6777b538SAndroid Build Coastguard Worker DnsHosts expected_hosts, actual_hosts;
103*6777b538SAndroid Build Coastguard Worker PopulateExpectedHosts(kEntries, std::size(kEntries), &expected_hosts);
104*6777b538SAndroid Build Coastguard Worker ParseHostsWithCommaModeForTesting(
105*6777b538SAndroid Build Coastguard Worker kContents, &actual_hosts, PARSE_HOSTS_COMMA_IS_TOKEN);
106*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(0UL, actual_hosts.size());
107*6777b538SAndroid Build Coastguard Worker }
108*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,ParseHosts_CommaIsWhitespace)109*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, ParseHosts_CommaIsWhitespace) {
110*6777b538SAndroid Build Coastguard Worker std::string kContents = "127.0.0.1 comma1,comma2";
111*6777b538SAndroid Build Coastguard Worker
112*6777b538SAndroid Build Coastguard Worker const ExpectedHostsEntry kEntries[] = {
113*6777b538SAndroid Build Coastguard Worker { "comma1", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
114*6777b538SAndroid Build Coastguard Worker { "comma2", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
115*6777b538SAndroid Build Coastguard Worker };
116*6777b538SAndroid Build Coastguard Worker
117*6777b538SAndroid Build Coastguard Worker DnsHosts expected_hosts, actual_hosts;
118*6777b538SAndroid Build Coastguard Worker PopulateExpectedHosts(kEntries, std::size(kEntries), &expected_hosts);
119*6777b538SAndroid Build Coastguard Worker ParseHostsWithCommaModeForTesting(
120*6777b538SAndroid Build Coastguard Worker kContents, &actual_hosts, PARSE_HOSTS_COMMA_IS_WHITESPACE);
121*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(expected_hosts, actual_hosts);
122*6777b538SAndroid Build Coastguard Worker }
123*6777b538SAndroid Build Coastguard Worker
124*6777b538SAndroid Build Coastguard Worker // Test that the right comma mode is used on each platform.
TEST(DnsHostsTest,ParseHosts_CommaModeByPlatform)125*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, ParseHosts_CommaModeByPlatform) {
126*6777b538SAndroid Build Coastguard Worker std::string kContents = "127.0.0.1 comma1,comma2";
127*6777b538SAndroid Build Coastguard Worker DnsHosts actual_hosts;
128*6777b538SAndroid Build Coastguard Worker ParseHosts(kContents, &actual_hosts);
129*6777b538SAndroid Build Coastguard Worker
130*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_APPLE)
131*6777b538SAndroid Build Coastguard Worker const ExpectedHostsEntry kEntries[] = {
132*6777b538SAndroid Build Coastguard Worker { "comma1", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
133*6777b538SAndroid Build Coastguard Worker { "comma2", ADDRESS_FAMILY_IPV4, "127.0.0.1" },
134*6777b538SAndroid Build Coastguard Worker };
135*6777b538SAndroid Build Coastguard Worker DnsHosts expected_hosts;
136*6777b538SAndroid Build Coastguard Worker PopulateExpectedHosts(kEntries, std::size(kEntries), &expected_hosts);
137*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(expected_hosts, actual_hosts);
138*6777b538SAndroid Build Coastguard Worker #else
139*6777b538SAndroid Build Coastguard Worker ASSERT_EQ(0UL, actual_hosts.size());
140*6777b538SAndroid Build Coastguard Worker #endif
141*6777b538SAndroid Build Coastguard Worker }
142*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,HostsParser_Empty)143*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, HostsParser_Empty) {
144*6777b538SAndroid Build Coastguard Worker DnsHosts hosts;
145*6777b538SAndroid Build Coastguard Worker ParseHosts("", &hosts);
146*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, hosts.size());
147*6777b538SAndroid Build Coastguard Worker }
148*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,HostsParser_OnlyWhitespace)149*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, HostsParser_OnlyWhitespace) {
150*6777b538SAndroid Build Coastguard Worker DnsHosts hosts;
151*6777b538SAndroid Build Coastguard Worker ParseHosts(" ", &hosts);
152*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(0u, hosts.size());
153*6777b538SAndroid Build Coastguard Worker }
154*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,HostsParser_EndsWithNothing)155*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, HostsParser_EndsWithNothing) {
156*6777b538SAndroid Build Coastguard Worker DnsHosts hosts;
157*6777b538SAndroid Build Coastguard Worker ParseHosts("127.0.0.1 localhost", &hosts);
158*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, hosts.size());
159*6777b538SAndroid Build Coastguard Worker }
160*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,HostsParser_EndsWithWhitespace)161*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, HostsParser_EndsWithWhitespace) {
162*6777b538SAndroid Build Coastguard Worker DnsHosts hosts;
163*6777b538SAndroid Build Coastguard Worker ParseHosts("127.0.0.1 localhost ", &hosts);
164*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, hosts.size());
165*6777b538SAndroid Build Coastguard Worker }
166*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,HostsParser_EndsWithComment)167*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, HostsParser_EndsWithComment) {
168*6777b538SAndroid Build Coastguard Worker DnsHosts hosts;
169*6777b538SAndroid Build Coastguard Worker ParseHosts("127.0.0.1 localhost # comment", &hosts);
170*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, hosts.size());
171*6777b538SAndroid Build Coastguard Worker }
172*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,HostsParser_EndsWithNewline)173*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, HostsParser_EndsWithNewline) {
174*6777b538SAndroid Build Coastguard Worker DnsHosts hosts;
175*6777b538SAndroid Build Coastguard Worker ParseHosts("127.0.0.1 localhost\n", &hosts);
176*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, hosts.size());
177*6777b538SAndroid Build Coastguard Worker }
178*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,HostsParser_EndsWithTwoNewlines)179*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, HostsParser_EndsWithTwoNewlines) {
180*6777b538SAndroid Build Coastguard Worker DnsHosts hosts;
181*6777b538SAndroid Build Coastguard Worker ParseHosts("127.0.0.1 localhost\n\n", &hosts);
182*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, hosts.size());
183*6777b538SAndroid Build Coastguard Worker }
184*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,HostsParser_EndsWithNewlineAndWhitespace)185*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, HostsParser_EndsWithNewlineAndWhitespace) {
186*6777b538SAndroid Build Coastguard Worker DnsHosts hosts;
187*6777b538SAndroid Build Coastguard Worker ParseHosts("127.0.0.1 localhost\n ", &hosts);
188*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, hosts.size());
189*6777b538SAndroid Build Coastguard Worker }
190*6777b538SAndroid Build Coastguard Worker
TEST(DnsHostsTest,HostsParser_EndsWithNewlineAndToken)191*6777b538SAndroid Build Coastguard Worker TEST(DnsHostsTest, HostsParser_EndsWithNewlineAndToken) {
192*6777b538SAndroid Build Coastguard Worker DnsHosts hosts;
193*6777b538SAndroid Build Coastguard Worker ParseHosts("127.0.0.1 localhost\ntoken", &hosts);
194*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1u, hosts.size());
195*6777b538SAndroid Build Coastguard Worker }
196*6777b538SAndroid Build Coastguard Worker
197*6777b538SAndroid Build Coastguard Worker } // namespace
198*6777b538SAndroid Build Coastguard Worker
199*6777b538SAndroid Build Coastguard Worker } // namespace net
200