Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(663)

Unified Diff: net/url_request/url_request_quic_unittest.cc

Issue 2324183002: Implement QuicHttpStream::GetLoadTimingInfo (Closed)
Patch Set: fix flaky TestTwoRequests Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/quic/chromium/quic_stream_factory.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/url_request/url_request_quic_unittest.cc
diff --git a/net/url_request/url_request_quic_unittest.cc b/net/url_request/url_request_quic_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..e37baffe69acd672c09dd013a5316f05460c1549
--- /dev/null
+++ b/net/url_request/url_request_quic_unittest.cc
@@ -0,0 +1,246 @@
+// Copyright 2016 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 <memory>
+
+#include "base/files/file_path.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/run_loop.h"
+#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
+#include "net/base/load_timing_info.h"
+#include "net/base/network_delegate.h"
+#include "net/cert/mock_cert_verifier.h"
+#include "net/dns/mapped_host_resolver.h"
+#include "net/dns/mock_host_resolver.h"
+#include "net/quic/chromium/crypto/proof_source_chromium.h"
+#include "net/quic/test_tools/crypto_test_utils.h"
+#include "net/test/cert_test_util.h"
+#include "net/test/gtest_util.h"
+#include "net/test/test_data_directory.h"
+#include "net/tools/quic/quic_in_memory_cache.h"
+#include "net/tools/quic/quic_simple_server.h"
+#include "net/tools/quic/test_tools/quic_in_memory_cache_peer.h"
+#include "net/url_request/url_request.h"
+#include "net/url_request/url_request_test_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "url/gurl.h"
+
+namespace net {
+
+namespace {
+
+// This must match the certificate used (quic_test.example.com.crt and
+// quic_test.example.com.key.pkcs8).
+const int kTestServerPort = 6121;
+const char kTestServerHost[] = "test.example.com:6121";
+// Used as a simple response from the server.
+const char kHelloPath[] = "/hello.txt";
+const char kHelloBodyValue[] = "Hello from QUIC Server";
+const int kHelloStatus = 200;
+
+class URLRequestQuicTest : public ::testing::Test {
+ protected:
+ URLRequestQuicTest() : context_(new TestURLRequestContext(true)) {
+ StartQuicServer();
+
+ std::unique_ptr<HttpNetworkSession::Params> params(
+ new HttpNetworkSession::Params);
+ CertVerifyResult verify_result;
+ verify_result.verified_cert = ImportCertFromFile(
+ GetTestCertsDirectory(), "quic_test.example.com.crt");
+ cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
+ "test.example.com", verify_result,
+ OK);
+ verify_result.verified_cert = ImportCertFromFile(
+ GetTestCertsDirectory(), "quic_test_ecc.example.com.crt");
+ cert_verifier_.AddResultForCertAndHost(verify_result.verified_cert.get(),
+ "test.example.com", verify_result,
+ OK);
+ // To simplify the test, and avoid the race with the HTTP request, we force
+ // QUIC for these requests.
+ params->origins_to_force_quic_on.insert(
+ HostPortPair::FromString(kTestServerHost));
+ params->cert_verifier = &cert_verifier_;
+ params->enable_quic = true;
+ params->host_resolver = host_resolver_.get();
+ context_->set_http_network_session_params(std::move(params));
+ context_->set_cert_verifier(&cert_verifier_);
+ }
+
+ void TearDown() override {
+ if (server_)
+ server_->Shutdown();
+ }
+
+ // Sets a NetworkDelegate to use for |context_|. Must be done before Init().
+ void SetNetworkDelegate(NetworkDelegate* network_delegate) {
+ context_->set_network_delegate(network_delegate);
+ }
+
+ // Initializes the TestURLRequestContext |context_|.
+ void Init() { context_->Init(); }
+
+ std::unique_ptr<URLRequest> CreateRequest(const GURL& url,
+ RequestPriority priority,
+ URLRequest::Delegate* delegate) {
+ return context_->CreateRequest(url, priority, delegate);
+ }
+
+ private:
+ void StartQuicServer() {
+ // Set up in-memory cache.
+ test::QuicInMemoryCachePeer::ResetForTests();
+ QuicInMemoryCache::GetInstance()->AddSimpleResponse(
+ kTestServerHost, kHelloPath, kHelloStatus, kHelloBodyValue);
+ net::QuicConfig config;
+ // Set up server certs.
+ std::unique_ptr<net::ProofSourceChromium> proof_source(
+ new net::ProofSourceChromium());
+ base::FilePath directory = GetTestCertsDirectory();
+ CHECK(proof_source->Initialize(
+ directory.Append(FILE_PATH_LITERAL("quic_test.example.com.crt")),
+ directory.Append(FILE_PATH_LITERAL("quic_test.example.com.key.pkcs8")),
+ directory.Append(FILE_PATH_LITERAL("quic_test.example.com.key.sct"))));
+ server_.reset(new QuicSimpleServer(
+ test::CryptoTestUtils::ProofSourceForTesting(), config,
+ net::QuicCryptoServerConfig::ConfigOptions(), AllSupportedVersions()));
+ int rv = server_->Listen(
+ net::IPEndPoint(net::IPAddress::IPv4AllZeros(), kTestServerPort));
+ EXPECT_GE(rv, 0) << "Quic server fails to start";
+
+ std::unique_ptr<MockHostResolver> resolver(new MockHostResolver());
+ resolver->rules()->AddRule("test.example.com", "127.0.0.1");
+ host_resolver_.reset(new MappedHostResolver(std::move(resolver)));
+ // Use a mapped host resolver so that request for test.example.com (port 80)
+ // reach the server running on localhost.
+ std::string map_rule = "MAP test.example.com test.example.com:" +
+ base::IntToString(server_->server_address().port());
+ EXPECT_TRUE(host_resolver_->AddRuleFromString(map_rule));
+ }
+
+ std::unique_ptr<MappedHostResolver> host_resolver_;
+ std::unique_ptr<QuicSimpleServer> server_;
+ std::unique_ptr<TestURLRequestContext> context_;
+ MockCertVerifier cert_verifier_;
+};
+
+// A URLRequest::Delegate that checks LoadTimingInfo when response headers are
+// received.
+class CheckLoadTimingDelegate : public TestDelegate {
+ public:
+ CheckLoadTimingDelegate(bool session_reused)
+ : session_reused_(session_reused) {}
+ void OnResponseStarted(URLRequest* request, int error) override {
+ TestDelegate::OnResponseStarted(request, error);
+ LoadTimingInfo load_timing_info;
+ request->GetLoadTimingInfo(&load_timing_info);
+ assertLoadTimingValid(load_timing_info, session_reused_);
+ }
+
+ private:
+ void assertLoadTimingValid(const LoadTimingInfo& load_timing_info,
+ bool session_reused) {
+ EXPECT_EQ(session_reused, load_timing_info.socket_reused);
+
+ // If |session_reused| is true, these fields should all be null, non-null
+ // otherwise.
+ EXPECT_EQ(session_reused,
+ load_timing_info.connect_timing.connect_start.is_null());
+ EXPECT_EQ(session_reused,
+ load_timing_info.connect_timing.connect_end.is_null());
+ EXPECT_EQ(session_reused,
+ load_timing_info.connect_timing.ssl_start.is_null());
+ EXPECT_EQ(session_reused,
+ load_timing_info.connect_timing.ssl_end.is_null());
+ EXPECT_EQ(load_timing_info.connect_timing.connect_start,
+ load_timing_info.connect_timing.ssl_start);
+ EXPECT_EQ(load_timing_info.connect_timing.connect_end,
+ load_timing_info.connect_timing.ssl_end);
+ EXPECT_EQ(session_reused,
+ load_timing_info.connect_timing.dns_start.is_null());
+ EXPECT_EQ(session_reused,
+ load_timing_info.connect_timing.dns_end.is_null());
+ }
+
+ bool session_reused_;
+
+ DISALLOW_COPY_AND_ASSIGN(CheckLoadTimingDelegate);
+};
+
+// A TestNetworkDelegate that invokes |all_requests_completed_callback| when
+// |num_expected_requests| requests are completed.
+class WaitForCompletionNetworkDelegate : public net::TestNetworkDelegate {
+ public:
+ WaitForCompletionNetworkDelegate(
+ const base::Closure& all_requests_completed_callback,
+ size_t num_expected_requests)
+ : all_requests_completed_callback_(all_requests_completed_callback),
+ num_expected_requests_(num_expected_requests) {}
+
+ void OnCompleted(URLRequest* request, bool started, int net_error) override {
+ net::TestNetworkDelegate::OnCompleted(request, started, net_error);
+ num_expected_requests_--;
+ if (num_expected_requests_ == 0)
+ all_requests_completed_callback_.Run();
+ }
+
+ private:
+ const base::Closure all_requests_completed_callback_;
+ size_t num_expected_requests_;
+ DISALLOW_COPY_AND_ASSIGN(WaitForCompletionNetworkDelegate);
+};
+
+} // namespace
+
+TEST_F(URLRequestQuicTest, TestGetRequest) {
+ Init();
+ CheckLoadTimingDelegate delegate(false);
+ std::string url =
+ base::StringPrintf("https://%s%s", kTestServerHost, kHelloPath);
+ std::unique_ptr<URLRequest> request =
+ CreateRequest(GURL(url), DEFAULT_PRIORITY, &delegate);
+
+ request->Start();
+ ASSERT_TRUE(request->is_pending());
+ base::RunLoop().Run();
+
+ EXPECT_TRUE(request->status().is_success());
+ EXPECT_EQ(kHelloBodyValue, delegate.data_received());
+}
+
+// Tests that if two requests use the same QUIC session, the second request
+// should not have |LoadTimingInfo::connect_timing|.
+TEST_F(URLRequestQuicTest, TestTwoRequests) {
+ base::RunLoop run_loop;
+ WaitForCompletionNetworkDelegate network_delegate(
+ run_loop.QuitClosure(), /*num_expected_requests=*/2);
+ SetNetworkDelegate(&network_delegate);
+ Init();
+ CheckLoadTimingDelegate delegate(false);
+ delegate.set_quit_on_complete(false);
+ std::string url =
+ base::StringPrintf("https://%s%s", kTestServerHost, kHelloPath);
+ std::unique_ptr<URLRequest> request =
+ CreateRequest(GURL(url), DEFAULT_PRIORITY, &delegate);
+
+ CheckLoadTimingDelegate delegate2(true);
+ delegate2.set_quit_on_complete(false);
+ std::unique_ptr<URLRequest> request2 =
+ CreateRequest(GURL(url), DEFAULT_PRIORITY, &delegate2);
+ request->Start();
+ request2->Start();
+ ASSERT_TRUE(request->is_pending());
+ ASSERT_TRUE(request2->is_pending());
+ run_loop.Run();
+
+ EXPECT_TRUE(request->status().is_success());
+ EXPECT_TRUE(request2->status().is_success());
+ EXPECT_EQ(kHelloBodyValue, delegate.data_received());
+ EXPECT_EQ(kHelloBodyValue, delegate2.data_received());
+}
+
+} // namespace net
« no previous file with comments | « net/quic/chromium/quic_stream_factory.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698