1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "net/quic/port_suggester.h" 6 7 #include <set> 8 9 #include "base/basictypes.h" 10 #include "net/base/host_port_pair.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 namespace net { 14 namespace test { 15 16 class PortSuggesterTest : public ::testing::Test { 17 protected: 18 PortSuggesterTest() 19 : entropy_(1345689), 20 min_ephemeral_port_(1025), 21 max_ephemeral_port_(65535) { 22 } 23 24 uint64 entropy_; 25 int min_ephemeral_port_; 26 int max_ephemeral_port_; 27 }; 28 29 TEST_F(PortSuggesterTest, SmallRangeTest) { 30 // When the range is small (one wide), we always get that as our answer. 31 scoped_refptr<PortSuggester> port_suggester = 32 new PortSuggester(HostPortPair("www.example.com", 443), entropy_); 33 // Test this for a few different (small) ranges. 34 for (int port = 2000; port < 2010; ++port) { 35 // Use |port| for both |min| and |max| delimiting the suggestion range. 36 EXPECT_EQ(port, port_suggester->SuggestPort(port, port)); 37 EXPECT_EQ(port, port_suggester->previous_suggestion()); 38 } 39 } 40 41 TEST_F(PortSuggesterTest, SuggestAllPorts) { 42 // We should eventually fill out any range, but we'll just ensure that we 43 // fill out a small range of ports. 44 scoped_refptr<PortSuggester> port_suggester = 45 new PortSuggester(HostPortPair("www.example.com", 443), entropy_); 46 std::set<int> ports; 47 const uint32 port_range = 20; 48 const int insertion_limit = 200; // We should be done by then. 49 for (int i = 0; i < insertion_limit; ++i) { 50 ports.insert(port_suggester->SuggestPort(min_ephemeral_port_, 51 min_ephemeral_port_ + port_range - 1)); 52 if (ports.size() == port_range) { 53 break; 54 } 55 } 56 EXPECT_EQ(port_range, ports.size()); 57 } 58 59 TEST_F(PortSuggesterTest, AvoidDuplication) { 60 // When the range is large, duplicates are rare, but we'll ask for a few 61 // suggestions and make sure they are unique. 62 scoped_refptr<PortSuggester> port_suggester = 63 new PortSuggester(HostPortPair("www.example.com", 80), entropy_); 64 std::set<int> ports; 65 const size_t port_count = 200; 66 for (size_t i = 0; i < port_count; ++i) { 67 ports.insert(port_suggester->SuggestPort(min_ephemeral_port_, 68 max_ephemeral_port_)); 69 } 70 EXPECT_EQ(port_suggester->call_count(), port_count); 71 EXPECT_EQ(port_count, ports.size()); 72 } 73 74 TEST_F(PortSuggesterTest, ConsistentPorts) { 75 // For given hostname, port, and entropy, we should always get the same 76 // suggestions. 77 scoped_refptr<PortSuggester> port_suggester1 = 78 new PortSuggester(HostPortPair("www.example.com", 443), entropy_); 79 scoped_refptr<PortSuggester> port_suggester2 = 80 new PortSuggester(HostPortPair("www.example.com", 443), entropy_); 81 for (int test_count = 20; test_count > 0; --test_count) { 82 EXPECT_EQ(port_suggester1->SuggestPort(min_ephemeral_port_, 83 min_ephemeral_port_), 84 port_suggester2->SuggestPort(min_ephemeral_port_, 85 min_ephemeral_port_)); 86 } 87 } 88 89 TEST_F(PortSuggesterTest, DifferentHostPortEntropy) { 90 // When we have different hosts, port, or entropy, we probably won't collide. 91 scoped_refptr<PortSuggester> port_suggester[] = { 92 new PortSuggester(HostPortPair("www.example.com", 80), entropy_), 93 new PortSuggester(HostPortPair("www.example.ORG", 80), entropy_), 94 new PortSuggester(HostPortPair("www.example.com", 443), entropy_), 95 new PortSuggester(HostPortPair("www.example.com", 80), entropy_ + 123456), 96 }; 97 98 std::set<int> ports; 99 const int port_count = 40; 100 size_t insertion_count = 0; 101 for (size_t j = 0; j < arraysize(port_suggester); ++j) { 102 for (int i = 0; i < port_count; ++i) { 103 ports.insert(port_suggester[j]->SuggestPort(min_ephemeral_port_, 104 max_ephemeral_port_)); 105 ++insertion_count; 106 } 107 } 108 EXPECT_EQ(insertion_count, ports.size()); 109 } 110 111 } // namespace test 112 } // namespace net 113