Add a unit test for the Net.QuicSession.PublicResetAddressMismatch
histogram.

[email protected],[email protected]
BUG=none
TEST=none

Review URL: https://codereview.chromium.org/171413005

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252300 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/net/quic/quic_address_mismatch.cc b/net/quic/quic_address_mismatch.cc
new file mode 100644
index 0000000..36b53a10
--- /dev/null
+++ b/net/quic/quic_address_mismatch.cc
@@ -0,0 +1,43 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/quic_address_mismatch.h"
+
+#include "net/base/ip_endpoint.h"
+
+namespace net {
+
+int GetAddressMismatch(const IPEndPoint& first_address,
+                       const IPEndPoint& second_address) {
+  if (first_address.address().empty() || second_address.address().empty()) {
+    return -1;
+  }
+
+  int sample;
+  if (first_address.address() != second_address.address()) {
+    sample = QUIC_ADDRESS_MISMATCH_BASE;
+  } else if (first_address.port() != second_address.port()) {
+    sample = QUIC_PORT_MISMATCH_BASE;
+  } else {
+    sample = QUIC_ADDRESS_AND_PORT_MATCH_BASE;
+  }
+
+  // Add an offset to |sample|:
+  //   V4_V4: add 0
+  //   V6_V6: add 1
+  //   V4_V6: add 2
+  //   V6_V4: add 3
+  bool first_ipv4 = (first_address.address().size() == kIPv4AddressSize);
+  bool second_ipv4 = (second_address.address().size() == kIPv4AddressSize);
+  if (first_ipv4 != second_ipv4) {
+    CHECK_EQ(sample, QUIC_ADDRESS_MISMATCH_BASE);
+    sample += 2;
+  }
+  if (!first_ipv4) {
+    sample += 1;
+  }
+  return sample;
+}
+
+}  // namespace net
diff --git a/net/quic/quic_address_mismatch.h b/net/quic/quic_address_mismatch.h
new file mode 100644
index 0000000..3179c20a
--- /dev/null
+++ b/net/quic/quic_address_mismatch.h
@@ -0,0 +1,44 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_QUIC_QUIC_ADDRESS_MISMATCH_H_
+#define NET_QUIC_QUIC_ADDRESS_MISMATCH_H_
+
+#include "net/base/net_export.h"
+
+namespace net {
+
+class IPEndPoint;
+
+enum QuicAddressMismatch {
+  // The addresses don't match.
+  QUIC_ADDRESS_MISMATCH_BASE = 0,
+  QUIC_ADDRESS_MISMATCH_V4_V4 = 0,
+  QUIC_ADDRESS_MISMATCH_V6_V6 = 1,
+  QUIC_ADDRESS_MISMATCH_V4_V6 = 2,
+  QUIC_ADDRESS_MISMATCH_V6_V4 = 3,
+
+  // The addresses match, but the ports don't match.
+  QUIC_PORT_MISMATCH_BASE = 4,
+  QUIC_PORT_MISMATCH_V4_V4 = 4,
+  QUIC_PORT_MISMATCH_V6_V6 = 5,
+
+  QUIC_ADDRESS_AND_PORT_MATCH_BASE = 6,
+  QUIC_ADDRESS_AND_PORT_MATCH_V4_V4 = 6,
+  QUIC_ADDRESS_AND_PORT_MATCH_V6_V6 = 7,
+
+  QUIC_ADDRESS_MISMATCH_MAX,
+};
+
+// Returns a value of the QuicAddressMismatch enum type that indicates how
+// |first_address| differs from |second_address|. Returns -1 if either address
+// is empty.
+//
+// Only used by the Net.QuicSession.PublicResetAddressMismatch histogram.
+NET_EXPORT_PRIVATE int GetAddressMismatch(const IPEndPoint& first_address,
+                                          const IPEndPoint& second_address);
+
+}  // namespace net
+
+#endif  // NET_QUIC_QUIC_ADDRESS_MISMATCH_H_
diff --git a/net/quic/quic_address_mismatch_test.cc b/net/quic/quic_address_mismatch_test.cc
new file mode 100644
index 0000000..7c3dca4
--- /dev/null
+++ b/net/quic/quic_address_mismatch_test.cc
@@ -0,0 +1,72 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/quic/quic_address_mismatch.h"
+
+#include "net/base/ip_endpoint.h"
+#include "net/base/net_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+namespace test {
+
+// Test all cases of the GetAddressMismatch function.
+TEST(QuicAddressMismatchTest, GetAddressMismatch) {
+  IPAddressNumber ip4_1;
+  IPAddressNumber ip4_2;
+  IPAddressNumber ip6_1;
+  IPAddressNumber ip6_2;
+  ASSERT_TRUE(ParseIPLiteralToNumber("1.2.3.4", &ip4_1));
+  ASSERT_TRUE(ParseIPLiteralToNumber("5.6.7.8", &ip4_2));
+  ASSERT_TRUE(ParseIPLiteralToNumber("1234::1", &ip6_1));
+  ASSERT_TRUE(ParseIPLiteralToNumber("1234::2", &ip6_2));
+  ASSERT_NE(ip4_1, ip4_2);
+  ASSERT_NE(ip6_1, ip6_2);
+
+  EXPECT_EQ(-1, GetAddressMismatch(IPEndPoint(), IPEndPoint()));
+  EXPECT_EQ(-1, GetAddressMismatch(IPEndPoint(), IPEndPoint(ip4_1, 443)));
+  EXPECT_EQ(-1, GetAddressMismatch(IPEndPoint(ip4_1, 443), IPEndPoint()));
+
+  EXPECT_EQ(QUIC_ADDRESS_AND_PORT_MATCH_V4_V4,
+            GetAddressMismatch(IPEndPoint(ip4_1, 443),
+                               IPEndPoint(ip4_1, 443)));
+  EXPECT_EQ(QUIC_ADDRESS_AND_PORT_MATCH_V6_V6,
+            GetAddressMismatch(IPEndPoint(ip6_1, 443),
+                               IPEndPoint(ip6_1, 443)));
+
+  EXPECT_EQ(QUIC_PORT_MISMATCH_V4_V4,
+            GetAddressMismatch(IPEndPoint(ip4_1, 80),
+                               IPEndPoint(ip4_1, 443)));
+  EXPECT_EQ(QUIC_PORT_MISMATCH_V6_V6,
+            GetAddressMismatch(IPEndPoint(ip6_1, 80),
+                               IPEndPoint(ip6_1, 443)));
+
+  EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V4,
+            GetAddressMismatch(IPEndPoint(ip4_1, 443),
+                               IPEndPoint(ip4_2, 443)));
+  EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V4,
+            GetAddressMismatch(IPEndPoint(ip4_1, 80),
+                               IPEndPoint(ip4_2, 443)));
+  EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V6_V6,
+            GetAddressMismatch(IPEndPoint(ip6_1, 443),
+                               IPEndPoint(ip6_2, 443)));
+  EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V6_V6,
+            GetAddressMismatch(IPEndPoint(ip6_1, 80),
+                               IPEndPoint(ip6_2, 443)));
+  EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V6,
+            GetAddressMismatch(IPEndPoint(ip4_1, 443),
+                               IPEndPoint(ip6_1, 443)));
+  EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V4_V6,
+            GetAddressMismatch(IPEndPoint(ip4_1, 80),
+                               IPEndPoint(ip6_1, 443)));
+  EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V6_V4,
+            GetAddressMismatch(IPEndPoint(ip6_1, 443),
+                               IPEndPoint(ip4_1, 443)));
+  EXPECT_EQ(QUIC_ADDRESS_MISMATCH_V6_V4,
+            GetAddressMismatch(IPEndPoint(ip6_1, 80),
+                               IPEndPoint(ip4_1, 443)));
+}
+
+}  // namespace test
+}  // namespace net
diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc
index 84fcfae..d52debe 100644
--- a/net/quic/quic_connection_logger.cc
+++ b/net/quic/quic_connection_logger.cc
@@ -13,6 +13,7 @@
 #include "net/base/net_log.h"
 #include "net/quic/crypto/crypto_handshake_message.h"
 #include "net/quic/crypto/crypto_protocol.h"
+#include "net/quic/quic_address_mismatch.h"
 #include "net/quic/quic_socket_address_coder.h"
 
 using base::StringPiece;
@@ -201,60 +202,14 @@
 void UpdatePublicResetAddressMismatchHistogram(
     const IPEndPoint& server_hello_address,
     const IPEndPoint& public_reset_address) {
-  enum {
-    // The addresses don't match.
-    kAddressMismatch_base = 0,
-    kAddressMismatch_v4_v4 = 0,
-    kAddressMismatch_v6_v6 = 1,
-    kAddressMismatch_v4_v6 = 2,
-    kAddressMismatch_v6_v4 = 3,
-
-    // The addresses match, but the ports don't match.
-    kPortMismatch_base = 4,
-    kPortMismatch_v4_v4 = 4,
-    kPortMismatch_v6_v6 = 5,
-
-    kAddressAndPortMatch_base = 6,
-    kAddressAndPortMatch_v4_v4 = 6,
-    kAddressAndPortMatch_v6_v6 = 7,
-
-    kBoundaryValue,
-  };
-
+  int sample = GetAddressMismatch(server_hello_address, public_reset_address);
   // We are seemingly talking to an older server that does not support the
   // feature, so we can't report the results in the histogram.
-  if (server_hello_address.address().empty() ||
-      public_reset_address.address().empty()) {
+  if (sample < 0) {
     return;
   }
-
-  int sample;
-  if (server_hello_address.address() != public_reset_address.address()) {
-    sample = kAddressMismatch_base;
-  } else if (server_hello_address.port() != public_reset_address.port()) {
-    sample = kPortMismatch_base;
-  } else {
-    sample = kAddressAndPortMatch_base;
-  }
-
-  // Add an offset to |sample|:
-  //   v4_v4: add 0
-  //   v6_v6: add 1
-  //   v4_v6: add 2
-  //   v6_v4: add 3
-  bool first_ipv4 =
-    (server_hello_address.address().size() == kIPv4AddressSize);
-  bool second_ipv4 =
-    (public_reset_address.address().size() == kIPv4AddressSize);
-  if (first_ipv4 != second_ipv4) {
-    CHECK_EQ(sample, kAddressMismatch_base);
-    sample += 2;
-  }
-  if (!first_ipv4) {
-    sample += 1;
-  }
   UMA_HISTOGRAM_ENUMERATION("Net.QuicSession.PublicResetAddressMismatch",
-                            sample, kBoundaryValue);
+                            sample, QUIC_ADDRESS_MISMATCH_MAX);
 }
 
 }  // namespace