summaryrefslogtreecommitdiff
path: root/chromium/net/tools/quic/test_tools
diff options
context:
space:
mode:
authorZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
committerZeno Albisser <zeno.albisser@digia.com>2013-08-15 21:46:11 +0200
commit679147eead574d186ebf3069647b4c23e8ccace6 (patch)
treefc247a0ac8ff119f7c8550879ebb6d3dd8d1ff69 /chromium/net/tools/quic/test_tools
downloadqtwebengine-chromium-679147eead574d186ebf3069647b4c23e8ccace6.tar.gz
Initial import.
Diffstat (limited to 'chromium/net/tools/quic/test_tools')
-rw-r--r--chromium/net/tools/quic/test_tools/http_message_test_utils.cc175
-rw-r--r--chromium/net/tools/quic/test_tools/http_message_test_utils.h133
-rw-r--r--chromium/net/tools/quic/test_tools/mock_epoll_server.cc68
-rw-r--r--chromium/net/tools/quic/test_tools/mock_epoll_server.h106
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_dispatcher.cc21
-rw-r--r--chromium/net/tools/quic/test_tools/mock_quic_dispatcher.h38
-rw-r--r--chromium/net/tools/quic/test_tools/quic_client_peer.cc27
-rw-r--r--chromium/net/tools/quic/test_tools/quic_client_peer.h25
-rw-r--r--chromium/net/tools/quic/test_tools/quic_epoll_connection_helper_peer.cc21
-rw-r--r--chromium/net/tools/quic/test_tools/quic_epoll_connection_helper_peer.h31
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_client.cc342
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_client.h143
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_utils.cc81
-rw-r--r--chromium/net/tools/quic/test_tools/quic_test_utils.h112
-rw-r--r--chromium/net/tools/quic/test_tools/run_all_unittests.cc11
15 files changed, 1334 insertions, 0 deletions
diff --git a/chromium/net/tools/quic/test_tools/http_message_test_utils.cc b/chromium/net/tools/quic/test_tools/http_message_test_utils.cc
new file mode 100644
index 00000000000..7d6df7a7649
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/http_message_test_utils.cc
@@ -0,0 +1,175 @@
+// Copyright (c) 2012 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/tools/quic/test_tools/http_message_test_utils.h"
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/strings/string_number_conversions.h"
+
+using base::StringPiece;
+using std::string;
+using std::vector;
+
+namespace net {
+namespace tools {
+namespace test {
+
+namespace {
+
+//const char* kContentEncoding = "content-encoding";
+const char* kContentLength = "content-length";
+const char* kTransferCoding = "transfer-encoding";
+
+// Both kHTTPVersionString and kMethodString arrays are constructed to match
+// the enum values defined in Version and Method of HTTPMessage.
+const char* kHTTPVersionString[] = {
+ "",
+ "HTTP/0.9",
+ "HTTP/1.0",
+ "HTTP/1.1"
+};
+
+const char* kMethodString[] = {
+ "",
+ "OPTIONS",
+ "GET",
+ "HEAD",
+ "POST",
+ "PUT",
+ "DELETE",
+ "TRACE",
+ "CONNECT",
+ "MKCOL",
+ "UNLOCK",
+};
+
+// Returns true if the message represents a complete request or response.
+// Messages are considered complete if:
+// - Transfer-Encoding: chunked is present and message has a final chunk.
+// - Content-Length header is present and matches the message body length.
+// - Neither Transfer-Encoding nor Content-Length is present and message
+// is tagged as complete.
+bool IsCompleteMessage(const HTTPMessage& message) {
+ return true;
+ const BalsaHeaders* headers = message.headers();
+ StringPiece content_length = headers->GetHeader(kContentLength);
+ if (!content_length.empty()) {
+ int parsed_content_length;
+ if (!base::StringToInt(content_length, &parsed_content_length)) {
+ return false;
+ }
+ return (message.body().size() == (uint)parsed_content_length);
+ } else {
+ // Assume messages without transfer coding or content-length are
+ // tagged correctly.
+ return message.has_complete_message();
+ }
+}
+
+} // namespace
+
+HTTPMessage::Method HTTPMessage::StringToMethod(StringPiece str) {
+ // Skip the first element of the array since it is empty string.
+ for (unsigned long i = 1; i < arraysize(kMethodString); ++i) {
+ if (strncmp(str.data(), kMethodString[i], str.length()) == 0) {
+ return static_cast<HTTPMessage::Method>(i);
+ }
+ }
+ return HttpConstants::UNKNOWN_METHOD;
+}
+
+HTTPMessage::Version HTTPMessage::StringToVersion(StringPiece str) {
+ // Skip the first element of the array since it is empty string.
+ for (unsigned long i = 1; i < arraysize(kHTTPVersionString); ++i) {
+ if (strncmp(str.data(), kHTTPVersionString[i], str.length()) == 0) {
+ return static_cast<HTTPMessage::Version>(i);
+ }
+ }
+ return HttpConstants::HTTP_UNKNOWN;
+}
+
+const char* HTTPMessage::MethodToString(Method method) {
+ CHECK_LT(static_cast<size_t>(method), arraysize(kMethodString));
+ return kMethodString[method];
+}
+
+const char* HTTPMessage::VersionToString(Version version) {
+ CHECK_LT(static_cast<size_t>(version), arraysize(kHTTPVersionString));
+ return kHTTPVersionString[version];
+}
+
+HTTPMessage::HTTPMessage()
+ : is_request_(true) {
+ InitializeFields();
+}
+
+HTTPMessage::HTTPMessage(Version ver, Method request, const string& path)
+ : is_request_(true) {
+ InitializeFields();
+ if (ver != HttpConstants::HTTP_0_9) {
+ headers()->SetRequestVersion(VersionToString(ver));
+ }
+ headers()->SetRequestMethod(MethodToString(request));
+ headers()->SetRequestUri(path);
+}
+
+HTTPMessage::~HTTPMessage() {
+}
+
+void HTTPMessage::InitializeFields() {
+ has_complete_message_ = true;
+ skip_message_validation_ = false;
+}
+
+void HTTPMessage::AddHeader(const string& header, const string& value) {
+ headers()->AppendHeader(header, value);
+}
+
+void HTTPMessage::RemoveHeader(const string& header) {
+ headers()->RemoveAllOfHeader(header);
+}
+
+void HTTPMessage::ReplaceHeader(const string& header, const string& value) {
+ headers()->ReplaceOrAppendHeader(header, value);
+}
+
+void HTTPMessage::AddBody(const string& body, bool add_content_length) {
+ body_ = body;
+ // Remove any transfer-encoding that was left by a previous body.
+ RemoveHeader(kTransferCoding);
+ if (add_content_length) {
+ ReplaceHeader(kContentLength, base::IntToString(body.size()));
+ } else {
+ RemoveHeader(kContentLength);
+ }
+}
+
+void HTTPMessage::ValidateMessage() const {
+ if (skip_message_validation_) {
+ return;
+ }
+
+ vector<StringPiece> transfer_encodings;
+ headers()->GetAllOfHeader(kTransferCoding, &transfer_encodings);
+ CHECK_GE(1ul, transfer_encodings.size());
+ for (vector<StringPiece>::iterator it = transfer_encodings.begin();
+ it != transfer_encodings.end();
+ ++it) {
+ CHECK(StringPieceUtils::EqualIgnoreCase("identity", *it) ||
+ StringPieceUtils::EqualIgnoreCase("chunked", *it)) << *it;
+ }
+
+ vector<StringPiece> content_lengths;
+ headers()->GetAllOfHeader(kContentLength, &content_lengths);
+ CHECK_GE(1ul, content_lengths.size());
+
+ CHECK_EQ(has_complete_message_, IsCompleteMessage(*this));
+}
+
+} // namespace test
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/http_message_test_utils.h b/chromium/net/tools/quic/test_tools/http_message_test_utils.h
new file mode 100644
index 00000000000..d389e21c8f2
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/http_message_test_utils.h
@@ -0,0 +1,133 @@
+// Copyright (c) 2012 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_TOOLS_QUIC_TEST_TOOLS_TEST_TOOLS_HTTP_MESSAGE_TEST_UTILS_H_
+#define NET_TOOLS_QUIC_TEST_TOOLS_TEST_TOOLS_HTTP_MESSAGE_TEST_UTILS_H_
+
+#include <string>
+#include <vector>
+
+#include "base/strings/string_piece.h"
+#include "net/tools/flip_server/balsa_enums.h"
+#include "net/tools/flip_server/balsa_headers.h"
+
+namespace net {
+namespace tools {
+namespace test {
+
+class HttpConstants {
+ public:
+ enum Version {
+ HTTP_UNKNOWN = 0,
+ HTTP_0_9,
+ HTTP_1_0,
+ HTTP_1_1
+ };
+
+ enum Method {
+ UNKNOWN_METHOD = 0,
+ OPTIONS,
+ GET,
+ HEAD,
+ POST,
+ PUT,
+ DELETE,
+ TRACE,
+ CONNECT,
+
+ MKCOL,
+ UNLOCK,
+ };
+};
+
+// Stripped down wrapper class which basically contains headers and a body.
+class HTTPMessage {
+ public:
+ typedef HttpConstants::Version Version;
+ typedef HttpConstants::Method Method;
+
+ // Convenient functions to map strings into enums. The string passed in is
+ // not assumed to be NULL-terminated.
+ static Version StringToVersion(base::StringPiece str);
+ static Method StringToMethod(base::StringPiece str);
+
+ static const char* MethodToString(Method method);
+ static const char* VersionToString(Version version);
+
+ // Default constructor makes an empty HTTP/1.1 GET request. This is typically
+ // used to construct a message that will be Initialize()-ed.
+ HTTPMessage();
+
+ // Build a request message
+ HTTPMessage(Version version, Method request, const std::string& path);
+
+ virtual ~HTTPMessage();
+
+ const std::string& body() const { return body_; }
+
+ // Adds a header line to the message.
+ void AddHeader(const std::string& header, const std::string& value);
+
+ // Removes a header line from the message.
+ void RemoveHeader(const std::string& header);
+
+ // A utility function which calls RemoveHeader followed by AddHeader.
+ void ReplaceHeader(const std::string& header, const std::string& value);
+
+ // Adds a body and the optional content-length header field (omitted to test
+ // read until close test case). To generate a message that has a header field
+ // of 0 content-length, call AddBody("", true).
+ // Multiple calls to AddBody()/AddChunkedBody() has the effect of overwriting
+ // the previous entry without warning.
+ void AddBody(const std::string& body, bool add_content_length);
+
+ bool has_complete_message() const { return has_complete_message_; }
+ void set_has_complete_message(bool value) { has_complete_message_ = value; }
+
+ // Do some basic http message consistency checks like:
+ // - Valid transfer-encoding header
+ // - Valid content-length header
+ // - Messages we expect to be complete are complete.
+ // This check can be disabled by setting skip_message_validation.
+ void ValidateMessage() const;
+
+ bool skip_message_validation() const { return skip_message_validation_; }
+ void set_skip_message_validation(bool value) {
+ skip_message_validation_ = value;
+ }
+
+ // Allow direct access to the body string. This should be used with caution:
+ // it will not update the request headers like AddBody and AddChunkedBody do.
+ void set_body(const std::string& body) { body_ = body; }
+
+ const BalsaHeaders* headers() const { return &headers_; }
+ BalsaHeaders* headers() { return &headers_; }
+
+ protected:
+ BalsaHeaders headers_;
+
+ std::string body_; // the body with chunked framing/gzip compression
+
+ bool is_request_;
+
+ // True if the message should be considered complete during serialization.
+ // Used by SPDY and Streamed RPC clients to decide wherever or not
+ // to include fin flags and during message validation (if enabled).
+ bool has_complete_message_;
+
+ // Allows disabling message validation when creating test messages
+ // that are intentionally invalid.
+ bool skip_message_validation_;
+
+ private:
+ void InitializeFields();
+
+ DISALLOW_COPY_AND_ASSIGN(HTTPMessage);
+};
+
+} // namespace test
+} // namespace tools
+} // namespace net
+
+#endif // NET_TOOLS_QUIC_TEST_TOOLS_TEST_TOOLS_HTTP_MESSAGE_TEST_UTILS_H_
diff --git a/chromium/net/tools/quic/test_tools/mock_epoll_server.cc b/chromium/net/tools/quic/test_tools/mock_epoll_server.cc
new file mode 100644
index 00000000000..4101c5e9ab0
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/mock_epoll_server.cc
@@ -0,0 +1,68 @@
+// Copyright (c) 2012 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/tools/quic/test_tools/mock_epoll_server.h"
+
+namespace net {
+namespace tools {
+namespace test {
+
+FakeTimeEpollServer::FakeTimeEpollServer(): now_in_usec_(0) {
+}
+
+FakeTimeEpollServer::~FakeTimeEpollServer() {
+}
+
+int64 FakeTimeEpollServer::NowInUsec() const {
+ return now_in_usec_;
+}
+
+MockEpollServer::MockEpollServer() : until_in_usec_(-1) {
+}
+
+MockEpollServer::~MockEpollServer() {
+}
+
+int MockEpollServer::epoll_wait_impl(int epfd,
+ struct epoll_event* events,
+ int max_events,
+ int timeout_in_ms) {
+ int num_events = 0;
+ while (!event_queue_.empty() &&
+ num_events < max_events &&
+ event_queue_.begin()->first <= NowInUsec() &&
+ ((until_in_usec_ == -1) ||
+ (event_queue_.begin()->first < until_in_usec_))
+ ) {
+ int64 event_time_in_usec = event_queue_.begin()->first;
+ events[num_events] = event_queue_.begin()->second;
+ if (event_time_in_usec > NowInUsec()) {
+ set_now_in_usec(event_time_in_usec);
+ }
+ event_queue_.erase(event_queue_.begin());
+ ++num_events;
+ }
+ if (num_events == 0) { // then we'd have waited 'till the timeout.
+ if (until_in_usec_ < 0) { // then we don't care what the final time is.
+ if (timeout_in_ms > 0) {
+ AdvanceBy(timeout_in_ms * 1000);
+ }
+ } else { // except we assume that we don't wait for the timeout
+ // period if until_in_usec_ is a positive number.
+ set_now_in_usec(until_in_usec_);
+ // And reset until_in_usec_ to signal no waiting (as
+ // the AdvanceByExactly* stuff is meant to be one-shot,
+ // as are all similar EpollServer functions)
+ until_in_usec_ = -1;
+ }
+ }
+ if (until_in_usec_ >= 0) {
+ CHECK(until_in_usec_ >= NowInUsec());
+ }
+ return num_events;
+}
+
+} // namespace test
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/mock_epoll_server.h b/chromium/net/tools/quic/test_tools/mock_epoll_server.h
new file mode 100644
index 00000000000..710d5fdf772
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/mock_epoll_server.h
@@ -0,0 +1,106 @@
+// Copyright (c) 2012 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_TOOLS_QUIC_TEST_TOOLS_MOCK_EPOLL_SERVER_H_
+#define NET_TOOLS_QUIC_TEST_TOOLS_MOCK_EPOLL_SERVER_H_
+
+#include "base/logging.h"
+#include "net/tools/flip_server/epoll_server.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace net {
+namespace tools {
+namespace test {
+
+// Unlike the full MockEpollServer, this only lies about the time but lets
+// fd events operate normally. Usefully when interacting with real backends
+// but wanting to skip forward in time to trigger timeouts.
+class FakeTimeEpollServer : public EpollServer {
+ public:
+ FakeTimeEpollServer();
+ virtual ~FakeTimeEpollServer();
+
+ // Replaces the EpollServer NowInUsec.
+ virtual int64 NowInUsec() const OVERRIDE;
+
+ void set_now_in_usec(int64 nius) { now_in_usec_ = nius; }
+
+ // Advances the virtual 'now' by advancement_usec.
+ void AdvanceBy(int64 advancement_usec) {
+ set_now_in_usec(NowInUsec() + advancement_usec);
+ }
+
+ // Advances the virtual 'now' by advancement_usec, and
+ // calls WaitForEventAndExecteCallbacks.
+ // Note that the WaitForEventsAndExecuteCallbacks invocation
+ // may cause NowInUs to advance beyond what was specified here.
+ // If that is not desired, use the AdvanceByExactly calls.
+ void AdvanceByAndCallCallbacks(int64 advancement_usec) {
+ AdvanceBy(advancement_usec);
+ WaitForEventsAndExecuteCallbacks();
+ }
+
+ private:
+ int64 now_in_usec_;
+};
+
+class MockEpollServer : public FakeTimeEpollServer {
+ public: // type definitions
+ typedef base::hash_multimap<int64, struct epoll_event> EventQueue;
+
+ MockEpollServer();
+ virtual ~MockEpollServer();
+
+ // time_in_usec is the time at which the event specified
+ // by 'ee' will be delivered. Note that it -is- possible
+ // to add an event for a time which has already been passed..
+ // .. upon the next time that the callbacks are invoked,
+ // all events which are in the 'past' will be delivered.
+ void AddEvent(int64 time_in_usec, const struct epoll_event& ee) {
+ event_queue_.insert(std::make_pair(time_in_usec, ee));
+ }
+
+ // Advances the virtual 'now' by advancement_usec,
+ // and ensure that the next invocation of
+ // WaitForEventsAndExecuteCallbacks goes no farther than
+ // advancement_usec from the current time.
+ void AdvanceByExactly(int64 advancement_usec) {
+ until_in_usec_ = NowInUsec() + advancement_usec;
+ set_now_in_usec(NowInUsec() + advancement_usec);
+ }
+
+ // As above, except calls WaitForEventsAndExecuteCallbacks.
+ void AdvanceByExactlyAndCallCallbacks(int64 advancement_usec) {
+ AdvanceByExactly(advancement_usec);
+ WaitForEventsAndExecuteCallbacks();
+ }
+
+ base::hash_set<AlarmCB*>::size_type NumberOfAlarms() const {
+ return all_alarms_.size();
+ }
+
+ protected: // functions
+ // These functions do nothing here, as we're not actually
+ // using the epoll_* syscalls.
+ virtual void DelFD(int fd) const OVERRIDE { }
+ virtual void AddFD(int fd, int event_mask) const OVERRIDE { }
+ virtual void ModFD(int fd, int event_mask) const OVERRIDE { }
+
+ // Replaces the epoll_server's epoll_wait_impl.
+ virtual int epoll_wait_impl(int epfd,
+ struct epoll_event* events,
+ int max_events,
+ int timeout_in_ms) OVERRIDE;
+ virtual void SetNonblocking (int fd) OVERRIDE { }
+
+ private: // members
+ EventQueue event_queue_;
+ int64 until_in_usec_;
+};
+
+} // namespace test
+} // namespace tools
+} // namespace net
+
+#endif // NET_TOOLS_QUIC_TEST_TOOLS_MOCK_EPOLL_SERVER_H_
diff --git a/chromium/net/tools/quic/test_tools/mock_quic_dispatcher.cc b/chromium/net/tools/quic/test_tools/mock_quic_dispatcher.cc
new file mode 100644
index 00000000000..3a2b1d98252
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/mock_quic_dispatcher.cc
@@ -0,0 +1,21 @@
+// Copyright 2013 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/tools/quic/test_tools/mock_quic_dispatcher.h"
+
+namespace net {
+namespace tools {
+namespace test {
+
+MockQuicDispatcher::MockQuicDispatcher(
+ const QuicConfig& config,
+ const QuicCryptoServerConfig& crypto_config,
+ QuicGuid guid,
+ EpollServer* eps)
+ : QuicDispatcher(config, crypto_config, guid, eps) { }
+MockQuicDispatcher::~MockQuicDispatcher() {}
+
+} // namespace test
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/mock_quic_dispatcher.h b/chromium/net/tools/quic/test_tools/mock_quic_dispatcher.h
new file mode 100644
index 00000000000..563ab0de5fd
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/mock_quic_dispatcher.h
@@ -0,0 +1,38 @@
+// Copyright 2013 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_TOOLS_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
+#define NET_TOOLS_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
+
+#include "net/base/ip_endpoint.h"
+#include "net/quic/crypto/crypto_server_config.h"
+#include "net/quic/quic_config.h"
+#include "net/quic/quic_protocol.h"
+#include "net/tools/flip_server/epoll_server.h"
+#include "net/tools/quic/quic_dispatcher.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace net {
+namespace tools {
+namespace test {
+
+class MockQuicDispatcher : public QuicDispatcher {
+ public:
+ MockQuicDispatcher(const QuicConfig& config,
+ const QuicCryptoServerConfig& crypto_config,
+ QuicGuid guid,
+ EpollServer* eps);
+ virtual ~MockQuicDispatcher();
+
+ MOCK_METHOD4(ProcessPacket, void(const IPEndPoint& server_address,
+ const IPEndPoint& client_address,
+ QuicGuid guid,
+ const QuicEncryptedPacket& packet));
+};
+
+} // namespace test
+} // namespace tools
+} // namespace net
+
+#endif // NET_TOOLS_QUIC_TEST_TOOLS_MOCK_QUIC_DISPATCHER_H_
diff --git a/chromium/net/tools/quic/test_tools/quic_client_peer.cc b/chromium/net/tools/quic/test_tools/quic_client_peer.cc
new file mode 100644
index 00000000000..858359474c8
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/quic_client_peer.cc
@@ -0,0 +1,27 @@
+// Copyright (c) 2013 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/tools/quic/test_tools/quic_client_peer.h"
+
+#include "net/tools/quic/quic_client.h"
+
+namespace net {
+namespace tools {
+namespace test {
+
+// static
+void QuicClientPeer::Reinitialize(QuicClient* client) {
+ client->initialized_ = false;
+ client->epoll_server_.UnregisterFD(client->fd_);
+ client->Initialize();
+}
+
+// static
+int QuicClientPeer::GetFd(QuicClient* client) {
+ return client->fd_;
+}
+
+} // namespace test
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_client_peer.h b/chromium/net/tools/quic/test_tools/quic_client_peer.h
new file mode 100644
index 00000000000..8eaa17e675d
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/quic_client_peer.h
@@ -0,0 +1,25 @@
+// Copyright (c) 2013 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_TOOLS_QUIC_TEST_TOOLS_QUIC_CLIENT_PEER_H_
+#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_CLIENT_PEER_H_
+
+namespace net {
+namespace tools {
+
+class QuicClient;
+
+namespace test {
+
+class QuicClientPeer {
+ public:
+ static void Reinitialize(QuicClient* client);
+ static int GetFd(QuicClient* client);
+};
+
+} // namespace test
+} // namespace tools
+} // namespace net
+
+#endif // NET_TOOLS_QUIC_TEST_TOOLS_QUIC_CLIENT_PEER_H_
diff --git a/chromium/net/tools/quic/test_tools/quic_epoll_connection_helper_peer.cc b/chromium/net/tools/quic/test_tools/quic_epoll_connection_helper_peer.cc
new file mode 100644
index 00000000000..e358273d0a2
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/quic_epoll_connection_helper_peer.cc
@@ -0,0 +1,21 @@
+// Copyright (c) 2013 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/tools/quic/test_tools/quic_epoll_connection_helper_peer.h"
+
+#include "net/tools/quic/quic_epoll_connection_helper.h"
+
+namespace net {
+namespace tools {
+namespace test {
+
+// static
+void QuicEpollConnectionHelperPeer::SetWriter(QuicEpollConnectionHelper* helper,
+ QuicPacketWriter* writer) {
+ helper->writer_ = writer;
+}
+
+} // namespace test
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_epoll_connection_helper_peer.h b/chromium/net/tools/quic/test_tools/quic_epoll_connection_helper_peer.h
new file mode 100644
index 00000000000..72085dfde1c
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/quic_epoll_connection_helper_peer.h
@@ -0,0 +1,31 @@
+// Copyright (c) 2013 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_TOOLS_QUIC_TEST_TOOLS_QUIC_EPOLL_CONNECTION_HELPER_PEER_H_
+#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_EPOLL_CONNECTION_HELPER_PEER_H_
+
+#include "base/basictypes.h"
+
+namespace net {
+namespace tools {
+
+class QuicPacketWriter;
+class QuicEpollConnectionHelper;
+
+namespace test {
+
+class QuicEpollConnectionHelperPeer {
+ public:
+ static void SetWriter(QuicEpollConnectionHelper* helper,
+ QuicPacketWriter* writer);
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(QuicEpollConnectionHelperPeer);
+};
+
+} // namespace test
+} // namespace tools
+} // namespace net
+
+#endif // NET_TOOLS_QUIC_TEST_TOOLS_QUIC_EPOLL_CONNECTION_HELPER_PEER_H_
diff --git a/chromium/net/tools/quic/test_tools/quic_test_client.cc b/chromium/net/tools/quic/test_tools/quic_test_client.cc
new file mode 100644
index 00000000000..859d7a56044
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/quic_test_client.cc
@@ -0,0 +1,342 @@
+// Copyright (c) 2012 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/tools/quic/test_tools/quic_test_client.h"
+
+#include "net/base/completion_callback.h"
+#include "net/base/net_errors.h"
+#include "net/cert/cert_verify_result.h"
+#include "net/cert/x509_certificate.h"
+#include "net/quic/crypto/proof_verifier.h"
+#include "net/tools/flip_server/balsa_headers.h"
+#include "net/tools/quic/quic_epoll_connection_helper.h"
+#include "net/tools/quic/test_tools/http_message_test_utils.h"
+#include "url/gurl.h"
+
+using std::string;
+using std::vector;
+using base::StringPiece;
+
+namespace {
+
+// RecordingProofVerifier accepts any certificate chain and records the common
+// name of the leaf.
+class RecordingProofVerifier : public net::ProofVerifier {
+ public:
+ // ProofVerifier interface.
+ virtual net::ProofVerifier::Status VerifyProof(
+ net::QuicVersion version,
+ const string& hostname,
+ const string& server_config,
+ const vector<string>& certs,
+ const string& signature,
+ string* error_details,
+ scoped_ptr<net::ProofVerifyDetails>* details,
+ net::ProofVerifierCallback* callback) OVERRIDE {
+ delete callback;
+
+ common_name_.clear();
+ if (certs.empty()) {
+ return FAILURE;
+ }
+
+ // Convert certs to X509Certificate.
+ vector<StringPiece> cert_pieces(certs.size());
+ for (unsigned i = 0; i < certs.size(); i++) {
+ cert_pieces[i] = StringPiece(certs[i]);
+ }
+ scoped_refptr<net::X509Certificate> cert =
+ net::X509Certificate::CreateFromDERCertChain(cert_pieces);
+ if (!cert.get()) {
+ return FAILURE;
+ }
+
+ common_name_ = cert->subject().GetDisplayName();
+ return SUCCESS;
+ }
+
+ const string& common_name() const { return common_name_; }
+
+ private:
+ string common_name_;
+};
+
+} // anonymous namespace
+
+namespace net {
+namespace tools {
+namespace test {
+
+BalsaHeaders* MungeHeaders(const BalsaHeaders* const_headers,
+ bool secure) {
+ StringPiece uri = const_headers->request_uri();
+ if (uri.empty()) {
+ return NULL;
+ }
+ if (const_headers->request_method() == "CONNECT") {
+ return NULL;
+ }
+ BalsaHeaders* headers = new BalsaHeaders;
+ headers->CopyFrom(*const_headers);
+ if (!uri.starts_with("https://") &&
+ !uri.starts_with("http://")) {
+ // If we have a relative URL, set some defaults.
+ string full_uri = secure ? "https://www.google.com" :
+ "http://www.google.com";
+ full_uri.append(uri.as_string());
+ headers->SetRequestUri(full_uri);
+ }
+ return headers;
+}
+
+// A quic client which allows mocking out writes.
+class QuicEpollClient : public QuicClient {
+ public:
+ typedef QuicClient Super;
+
+ QuicEpollClient(IPEndPoint server_address,
+ const string& server_hostname,
+ const QuicVersion version)
+ : Super(server_address, server_hostname, version) {
+ }
+
+ QuicEpollClient(IPEndPoint server_address,
+ const string& server_hostname,
+ const QuicConfig& config,
+ const QuicVersion version)
+ : Super(server_address, server_hostname, config, version) {
+ }
+
+ virtual ~QuicEpollClient() {
+ if (connected()) {
+ Disconnect();
+ }
+ }
+
+ virtual QuicEpollConnectionHelper* CreateQuicConnectionHelper() OVERRIDE {
+ if (writer_.get() != NULL) {
+ writer_->set_fd(fd());
+ return new QuicEpollConnectionHelper(writer_.get(), epoll_server());
+ } else {
+ return Super::CreateQuicConnectionHelper();
+ }
+ }
+
+ void UseWriter(QuicTestWriter* writer) { writer_.reset(writer); }
+
+ private:
+ scoped_ptr<QuicTestWriter> writer_;
+};
+
+QuicTestClient::QuicTestClient(IPEndPoint address, const string& hostname,
+ const QuicVersion version)
+ : client_(new QuicEpollClient(address, hostname, version)) {
+ Initialize(address, hostname, true);
+}
+
+QuicTestClient::QuicTestClient(IPEndPoint address,
+ const string& hostname,
+ bool secure,
+ const QuicVersion version)
+ : client_(new QuicEpollClient(address, hostname, version)) {
+ Initialize(address, hostname, secure);
+}
+
+QuicTestClient::QuicTestClient(IPEndPoint address,
+ const string& hostname,
+ bool secure,
+ const QuicConfig& config,
+ const QuicVersion version)
+ : client_(new QuicEpollClient(address, hostname, config, version)) {
+ Initialize(address, hostname, secure);
+}
+
+void QuicTestClient::Initialize(IPEndPoint address,
+ const string& hostname,
+ bool secure) {
+ server_address_ = address;
+ stream_ = NULL;
+ stream_error_ = QUIC_STREAM_NO_ERROR;
+ bytes_read_ = 0;
+ bytes_written_= 0;
+ never_connected_ = true;
+ secure_ = secure;
+ auto_reconnect_ = false;
+ proof_verifier_ = NULL;
+ ExpectCertificates(secure_);
+}
+
+QuicTestClient::~QuicTestClient() {
+ if (stream_) {
+ stream_->set_visitor(NULL);
+ }
+}
+
+void QuicTestClient::ExpectCertificates(bool on) {
+ if (on) {
+ proof_verifier_ = new RecordingProofVerifier;
+ client_->SetProofVerifier(proof_verifier_);
+ } else {
+ proof_verifier_ = NULL;
+ client_->SetProofVerifier(NULL);
+ }
+}
+
+ssize_t QuicTestClient::SendRequest(const string& uri) {
+ HTTPMessage message(HttpConstants::HTTP_1_1, HttpConstants::GET, uri);
+ return SendMessage(message);
+}
+
+ssize_t QuicTestClient::SendMessage(const HTTPMessage& message) {
+ stream_ = NULL; // Always force creation of a stream for SendMessage.
+
+ // If we're not connected, try to find an sni hostname.
+ if (!connected()) {
+ GURL url(message.headers()->request_uri().as_string());
+ if (!url.host().empty()) {
+ client_->set_server_hostname(url.host());
+ }
+ }
+
+ QuicReliableClientStream* stream = GetOrCreateStream();
+ if (!stream) { return 0; }
+
+ scoped_ptr<BalsaHeaders> munged_headers(MungeHeaders(message.headers(),
+ secure_));
+ return GetOrCreateStream()->SendRequest(
+ munged_headers.get() ? *munged_headers.get() : *message.headers(),
+ message.body(),
+ message.has_complete_message());
+}
+
+ssize_t QuicTestClient::SendData(string data, bool last_data) {
+ QuicReliableClientStream* stream = GetOrCreateStream();
+ if (!stream) { return 0; }
+ GetOrCreateStream()->SendBody(data, last_data);
+ return data.length();
+}
+
+string QuicTestClient::SendCustomSynchronousRequest(
+ const HTTPMessage& message) {
+ SendMessage(message);
+ WaitForResponse();
+ return response_;
+}
+
+string QuicTestClient::SendSynchronousRequest(const string& uri) {
+ if (SendRequest(uri) == 0) {
+ DLOG(ERROR) << "Failed the request for uri:" << uri;
+ return "";
+ }
+ WaitForResponse();
+ return response_;
+}
+
+QuicReliableClientStream* QuicTestClient::GetOrCreateStream() {
+ if (never_connected_ == true || auto_reconnect_) {
+ if (!connected()) {
+ Connect();
+ }
+ if (!connected()) {
+ return NULL;
+ }
+ }
+ if (!stream_) {
+ stream_ = client_->CreateReliableClientStream();
+ if (stream_ != NULL) {
+ stream_->set_visitor(this);
+ }
+ }
+ return stream_;
+}
+
+const string& QuicTestClient::cert_common_name() const {
+ return reinterpret_cast<RecordingProofVerifier*>(proof_verifier_)
+ ->common_name();
+}
+
+bool QuicTestClient::connected() const {
+ return client_->connected();
+}
+
+void QuicTestClient::WaitForResponse() {
+ if (stream_ == NULL) {
+ // The client has likely disconnected.
+ return;
+ }
+ client_->WaitForStreamToClose(stream_->id());
+}
+
+void QuicTestClient::Connect() {
+ DCHECK(!connected());
+ client_->Initialize();
+ client_->Connect();
+ never_connected_ = false;
+}
+
+void QuicTestClient::ResetConnection() {
+ Disconnect();
+ Connect();
+}
+
+void QuicTestClient::Disconnect() {
+ client_->Disconnect();
+}
+
+IPEndPoint QuicTestClient::LocalSocketAddress() const {
+ return client_->client_address();
+}
+
+void QuicTestClient::ClearPerRequestState() {
+ stream_error_ = QUIC_STREAM_NO_ERROR;
+ stream_ = NULL;
+ response_ = "";
+ headers_.Clear();
+ bytes_read_ = 0;
+ bytes_written_ = 0;
+}
+
+void QuicTestClient::WaitForInitialResponse() {
+ DCHECK(stream_ != NULL);
+ while (stream_ && stream_->stream_bytes_read() == 0) {
+ client_->WaitForEvents();
+ }
+}
+
+ssize_t QuicTestClient::Send(const void *buffer, size_t size) {
+ return SendData(string(static_cast<const char*>(buffer), size), false);
+}
+
+int QuicTestClient::response_size() const {
+ return bytes_read_;
+}
+
+size_t QuicTestClient::bytes_read() const {
+ return bytes_read_;
+}
+
+size_t QuicTestClient::bytes_written() const {
+ return bytes_written_;
+}
+
+void QuicTestClient::OnClose(ReliableQuicStream* stream) {
+ if (stream_ != stream) {
+ return;
+ }
+ response_ = stream_->data();
+ headers_.CopyFrom(stream_->headers());
+ stream_error_ = stream_->stream_error();
+ bytes_read_ = stream_->stream_bytes_read();
+ bytes_written_ = stream_->stream_bytes_written();
+ stream_ = NULL;
+}
+
+void QuicTestClient::UseWriter(QuicTestWriter* writer) {
+ DCHECK(!connected());
+ reinterpret_cast<QuicEpollClient*>(client_.get())->UseWriter(writer);
+}
+
+} // namespace test
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_test_client.h b/chromium/net/tools/quic/test_tools/quic_test_client.h
new file mode 100644
index 00000000000..74bfc24646a
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/quic_test_client.h
@@ -0,0 +1,143 @@
+// Copyright (c) 2012 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_TEST_TOOLS_QUIC_CLIENT_H_
+#define NET_QUIC_TEST_TOOLS_QUIC_CLIENT_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "net/quic/quic_framer.h"
+#include "net/quic/quic_packet_creator.h"
+#include "net/quic/quic_protocol.h"
+#include "net/tools/quic/quic_client.h"
+#include "net/tools/quic/quic_packet_writer.h"
+
+namespace net {
+
+class ProofVerifier;
+
+namespace tools {
+
+namespace test {
+
+// Allows setting a writer for the client's QuicConnectionHelper, to allow
+// fine-grained control of writes.
+class QuicTestWriter : public QuicPacketWriter {
+ public:
+ virtual ~QuicTestWriter() {}
+ virtual void set_fd(int fd) = 0;
+};
+
+class HTTPMessage;
+
+// A toy QUIC client used for testing.
+class QuicTestClient : public ReliableQuicStream::Visitor {
+ public:
+ QuicTestClient(IPEndPoint server_address, const string& server_hostname,
+ const QuicVersion version);
+ QuicTestClient(IPEndPoint server_address,
+ const string& server_hostname,
+ bool secure,
+ const QuicVersion version);
+ QuicTestClient(IPEndPoint server_address,
+ const string& server_hostname,
+ bool secure,
+ const QuicConfig& config,
+ const QuicVersion version);
+
+ virtual ~QuicTestClient();
+
+ // ExpectCertificates controls whether the server is expected to provide
+ // certificates. The certificates, if any, are not verified, but the common
+ // name is recorded and available with |cert_common_name()|.
+ void ExpectCertificates(bool on);
+
+ // Clears any outstanding state and sends a simple GET of 'uri' to the
+ // server. Returns 0 if the request failed and no bytes were written.
+ ssize_t SendRequest(const string& uri);
+ ssize_t SendMessage(const HTTPMessage& message);
+
+ string SendCustomSynchronousRequest(const HTTPMessage& message);
+ string SendSynchronousRequest(const string& uri);
+
+ // Wraps data in a quic packet and sends it.
+ ssize_t SendData(string data, bool last_data);
+
+ QuicPacketCreator::Options* options() { return client_->options(); }
+
+ const BalsaHeaders *response_headers() const {return &headers_;}
+
+ void WaitForResponse();
+
+ void Connect();
+ void ResetConnection();
+ void Disconnect();
+ IPEndPoint LocalSocketAddress() const;
+ void ClearPerRequestState();
+ void WaitForInitialResponse();
+ ssize_t Send(const void *buffer, size_t size);
+ int response_size() const;
+ size_t bytes_read() const;
+ size_t bytes_written() const;
+
+ // From ReliableQuicStream::Visitor
+ virtual void OnClose(ReliableQuicStream* stream) OVERRIDE;
+
+ // Configures client_ to take ownership of and use the writer.
+ // Must be called before initial connect.
+ void UseWriter(QuicTestWriter* writer);
+
+ // Returns NULL if the maximum number of streams have already been created.
+ QuicReliableClientStream* GetOrCreateStream();
+
+ QuicRstStreamErrorCode stream_error() { return stream_error_; }
+ QuicErrorCode connection_error() { return client()->session()->error(); }
+
+ QuicClient* client() { return client_.get(); }
+
+ // cert_common_name returns the common name value of the server's certificate,
+ // or the empty string if no certificate was presented.
+ const string& cert_common_name() const;
+
+ const string& response_body() {return response_;}
+ bool connected() const;
+
+ void set_auto_reconnect(bool reconnect) { auto_reconnect_ = reconnect; }
+
+ private:
+ void Initialize(IPEndPoint address, const string& hostname, bool secure);
+
+ IPEndPoint server_address_;
+ IPEndPoint client_address_;
+ scoped_ptr<QuicClient> client_; // The actual client
+ QuicReliableClientStream* stream_;
+
+ QuicRstStreamErrorCode stream_error_;
+
+ BalsaHeaders headers_;
+ string response_;
+ uint64 bytes_read_;
+ uint64 bytes_written_;
+ // True if the client has never connected before. The client will
+ // auto-connect exactly once before sending data. If something causes a
+ // connection reset, it will not automatically reconnect.
+ bool never_connected_;
+ bool secure_;
+ // If true, the client will always reconnect if necessary before creating a
+ // stream.
+ bool auto_reconnect_;
+
+ // proof_verifier_ points to a RecordingProofVerifier that is owned by
+ // client_.
+ ProofVerifier* proof_verifier_;
+};
+
+} // namespace test
+
+} // namespace tools
+} // namespace net
+
+#endif // NET_QUIC_TEST_TOOLS_QUIC_CLIENT_H_
diff --git a/chromium/net/tools/quic/test_tools/quic_test_utils.cc b/chromium/net/tools/quic/test_tools/quic_test_utils.cc
new file mode 100644
index 00000000000..95f1fb215ea
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/quic_test_utils.cc
@@ -0,0 +1,81 @@
+// Copyright (c) 2012 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/tools/quic/test_tools/quic_test_utils.h"
+
+#include "net/quic/test_tools/quic_test_utils.h"
+#include "net/tools/quic/quic_epoll_connection_helper.h"
+
+using base::StringPiece;
+using net::test::MockHelper;
+
+namespace net {
+namespace tools {
+namespace test {
+
+MockConnection::MockConnection(QuicGuid guid,
+ IPEndPoint address,
+ int fd,
+ EpollServer* eps,
+ bool is_server)
+ : QuicConnection(guid, address,
+ new QuicEpollConnectionHelper(fd, eps), is_server,
+ QuicVersionMax()),
+ has_mock_helper_(false) {
+}
+
+MockConnection::MockConnection(QuicGuid guid,
+ IPEndPoint address,
+ bool is_server)
+ : QuicConnection(guid, address, new testing::NiceMock<MockHelper>(),
+ is_server, QuicVersionMax()),
+ has_mock_helper_(true) {
+}
+
+MockConnection::MockConnection(QuicGuid guid,
+ IPEndPoint address,
+ QuicConnectionHelperInterface* helper,
+ bool is_server)
+ : QuicConnection(guid, address, helper, is_server, QuicVersionMax()),
+ has_mock_helper_(false) {
+}
+
+MockConnection::~MockConnection() {
+}
+
+void MockConnection::AdvanceTime(QuicTime::Delta delta) {
+ CHECK(has_mock_helper_) << "Cannot advance time unless a MockClock is being"
+ " used";
+ static_cast<MockHelper*>(helper())->AdvanceTime(delta);
+}
+
+bool TestDecompressorVisitor::OnDecompressedData(StringPiece data) {
+ data.AppendToString(&data_);
+ return true;
+}
+
+void TestDecompressorVisitor::OnDecompressionError() {
+ error_ = true;
+}
+
+TestSession::TestSession(QuicConnection* connection,
+ const QuicConfig& config,
+ bool is_server)
+ : QuicSession(connection, config, is_server),
+ crypto_stream_(NULL) {
+}
+
+TestSession::~TestSession() {}
+
+void TestSession::SetCryptoStream(QuicCryptoStream* stream) {
+ crypto_stream_ = stream;
+}
+
+QuicCryptoStream* TestSession::GetCryptoStream() {
+ return crypto_stream_;
+}
+
+} // namespace test
+} // namespace tools
+} // namespace net
diff --git a/chromium/net/tools/quic/test_tools/quic_test_utils.h b/chromium/net/tools/quic/test_tools/quic_test_utils.h
new file mode 100644
index 00000000000..31ea1815e06
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/quic_test_utils.h
@@ -0,0 +1,112 @@
+// Copyright (c) 2012 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_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
+#define NET_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
+
+#include <string>
+
+#include "base/strings/string_piece.h"
+#include "net/quic/quic_connection.h"
+#include "net/quic/quic_session.h"
+#include "net/quic/quic_spdy_decompressor.h"
+#include "net/spdy/spdy_framer.h"
+#include "testing/gmock/include/gmock/gmock.h"
+
+namespace net {
+
+class EpollServer;
+class IPEndPoint;
+
+namespace tools {
+namespace test {
+
+std::string SerializeUncompressedHeaders(const SpdyHeaderBlock& headers);
+
+class MockConnection : public QuicConnection {
+ public:
+ // Uses a QuicConnectionHelper created with fd and eps.
+ MockConnection(QuicGuid guid,
+ IPEndPoint address,
+ int fd,
+ EpollServer* eps,
+ bool is_server);
+ // Uses a MockHelper.
+ MockConnection(QuicGuid guid, IPEndPoint address, bool is_server);
+ MockConnection(QuicGuid guid,
+ IPEndPoint address,
+ QuicConnectionHelperInterface* helper, bool is_server);
+ virtual ~MockConnection();
+
+ // If the constructor that uses a MockHelper has been used then this method
+ // will advance the time of the MockClock.
+ void AdvanceTime(QuicTime::Delta delta);
+
+ MOCK_METHOD3(ProcessUdpPacket, void(const IPEndPoint& self_address,
+ const IPEndPoint& peer_address,
+ const QuicEncryptedPacket& packet));
+ MOCK_METHOD1(SendConnectionClose, void(QuicErrorCode error));
+ MOCK_METHOD2(SendConnectionCloseWithDetails, void(
+ QuicErrorCode error,
+ const std::string& details));
+ MOCK_METHOD2(SendRstStream, void(QuicStreamId id,
+ QuicRstStreamErrorCode error));
+ MOCK_METHOD3(SendGoAway, void(QuicErrorCode error,
+ QuicStreamId last_good_stream_id,
+ const std::string& reason));
+ MOCK_METHOD0(OnCanWrite, bool());
+
+ void ReallyProcessUdpPacket(const IPEndPoint& self_address,
+ const IPEndPoint& peer_address,
+ const QuicEncryptedPacket& packet) {
+ return QuicConnection::ProcessUdpPacket(self_address, peer_address, packet);
+ }
+
+ virtual bool OnProtocolVersionMismatch(QuicVersion version) { return false; }
+
+ private:
+ const bool has_mock_helper_;
+
+ DISALLOW_COPY_AND_ASSIGN(MockConnection);
+};
+
+class TestDecompressorVisitor : public QuicSpdyDecompressor::Visitor {
+ public:
+ virtual ~TestDecompressorVisitor() {}
+ virtual bool OnDecompressedData(base::StringPiece data) OVERRIDE;
+ virtual void OnDecompressionError() OVERRIDE;
+
+ std::string data() { return data_; }
+ bool error() { return error_; }
+
+ private:
+ std::string data_;
+ bool error_;
+};
+
+class TestSession : public QuicSession {
+ public:
+ TestSession(QuicConnection* connection,
+ const QuicConfig& config,
+ bool is_server);
+ virtual ~TestSession();
+
+ MOCK_METHOD1(CreateIncomingReliableStream,
+ ReliableQuicStream*(QuicStreamId id));
+ MOCK_METHOD0(CreateOutgoingReliableStream, ReliableQuicStream*());
+
+ void SetCryptoStream(QuicCryptoStream* stream);
+
+ virtual QuicCryptoStream* GetCryptoStream();
+
+ private:
+ QuicCryptoStream* crypto_stream_;
+ DISALLOW_COPY_AND_ASSIGN(TestSession);
+};
+
+} // namespace test
+} // namespace tools
+} // namespace net
+
+#endif // NET_TOOLS_QUIC_TEST_TOOLS_QUIC_TEST_UTILS_H_
diff --git a/chromium/net/tools/quic/test_tools/run_all_unittests.cc b/chromium/net/tools/quic/test_tools/run_all_unittests.cc
new file mode 100644
index 00000000000..6d42d33eb8f
--- /dev/null
+++ b/chromium/net/tools/quic/test_tools/run_all_unittests.cc
@@ -0,0 +1,11 @@
+// Copyright (c) 2012 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 "base/test/test_suite.h"
+
+int main(int argc, char** argv) {
+ base::TestSuite test_suite(argc, argv);
+
+ return test_suite.Run();
+}