Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 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 <inttypes.h> | |
| 6 | |
| 7 #include <memory> | |
| 8 | |
| 9 #include "base/files/file_path.h" | |
| 10 #include "base/memory/ptr_util.h" | |
| 11 #include "base/message_loop/message_loop.h" | |
| 12 #include "base/run_loop.h" | |
| 13 #include "base/strings/string_number_conversions.h" | |
| 14 #include "base/strings/stringprintf.h" | |
| 15 #include "base/time/time.h" | |
| 16 #include "base/trace_event/memory_dump_request_args.h" | |
| 17 #include "base/trace_event/process_memory_dump.h" | |
| 18 #include "base/trace_event/trace_event_argument.h" | |
| 19 #include "net/base/load_timing_info.h" | |
| 20 #include "net/cert/mock_cert_verifier.h" | |
| 21 #include "net/dns/mapped_host_resolver.h" | |
| 22 #include "net/dns/mock_host_resolver.h" | |
| 23 #include "net/http/http_status_code.h" | |
| 24 #include "net/quic/chromium/crypto/proof_source_chromium.h" | |
| 25 #include "net/quic/test_tools/crypto_test_utils.h" | |
| 26 #include "net/test/cert_test_util.h" | |
| 27 #include "net/test/embedded_test_server/embedded_test_server.h" | |
| 28 #include "net/test/embedded_test_server/http_response.h" | |
| 29 #include "net/test/gtest_util.h" | |
| 30 #include "net/test/test_data_directory.h" | |
| 31 #include "net/tools/quic/quic_http_response_cache.h" | |
| 32 #include "net/tools/quic/quic_simple_server.h" | |
| 33 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" | |
| 34 #include "net/url_request/url_request.h" | |
| 35 #include "net/url_request/url_request_test_util.h" | |
| 36 #include "testing/gmock/include/gmock/gmock.h" | |
| 37 #include "testing/gtest/include/gtest/gtest.h" | |
| 38 #include "testing/perf/perf_test.h" | |
| 39 #include "url/gurl.h" | |
| 40 | |
| 41 namespace net { | |
| 42 | |
| 43 namespace { | |
| 44 | |
| 45 const int kAltSvcPort = 6121; | |
| 46 const char kOriginHost[] = "mail.example.com"; | |
| 47 const char kAltSvcHost[] = "test.example.com"; | |
| 48 // Used as a simple response from the server. | |
| 49 const char kHelloPath[] = "/hello.txt"; | |
| 50 const char kHelloAltSvcResponse[] = "Hello from QUIC Server"; | |
| 51 const char kHelloOriginResponse[] = "Hello from TCP Server"; | |
| 52 const int kHelloStatus = 200; | |
| 53 | |
| 54 std::unique_ptr<test_server::HttpResponse> HandleRequest( | |
| 55 const test_server::HttpRequest& request) { | |
| 56 std::unique_ptr<test_server::BasicHttpResponse> http_response( | |
| 57 new test_server::BasicHttpResponse()); | |
| 58 http_response->AddCustomHeader( | |
| 59 "Alt-Svc", base::StringPrintf( | |
| 60 "quic=\"%s:%d\"; v=\"%u\"", kAltSvcHost, kAltSvcPort, | |
| 61 HttpNetworkSession::Params().quic_supported_versions[0])); | |
| 62 http_response->set_code(HTTP_OK); | |
| 63 http_response->set_content(kHelloOriginResponse); | |
| 64 http_response->set_content_type("text/plain"); | |
| 65 return std::move(http_response); | |
| 66 } | |
| 67 | |
| 68 void PrintPerfTest(const std::string& name, | |
| 69 int value, | |
| 70 const std::string& unit) { | |
| 71 const ::testing::TestInfo* test_info = | |
| 72 ::testing::UnitTest::GetInstance()->current_test_info(); | |
| 73 perf_test::PrintResult(test_info->test_case_name(), | |
| 74 std::string(".") + test_info->name(), name, | |
| 75 static_cast<double>(value), unit, true); | |
| 76 } | |
| 77 | |
| 78 class URLRequestQuicPerfTest : public ::testing::Test { | |
| 79 protected: | |
| 80 URLRequestQuicPerfTest() | |
| 81 : message_loop_(new base::MessageLoopForIO()), | |
| 82 context_(new TestURLRequestContext(true)) { | |
| 83 StartTcpServer(); | |
| 84 StartQuicServer(); | |
| 85 | |
| 86 // Host mapping. | |
| 87 std::unique_ptr<MockHostResolver> resolver(new MockHostResolver()); | |
| 88 resolver->rules()->AddRule(kAltSvcHost, "127.0.0.1"); | |
| 89 host_resolver_.reset(new MappedHostResolver(std::move(resolver))); | |
| 90 std::string map_rule = base::StringPrintf("MAP %s 127.0.0.1:%d", | |
| 91 kOriginHost, tcp_server_->port()); | |
| 92 EXPECT_TRUE(host_resolver_->AddRuleFromString(map_rule)); | |
| 93 | |
| 94 std::unique_ptr<HttpNetworkSession::Params> params( | |
| 95 new HttpNetworkSession::Params); | |
| 96 params->cert_verifier = &cert_verifier_; | |
| 97 params->enable_quic = true; | |
| 98 params->enable_user_alternate_protocol_ports = true; | |
| 99 context_->set_host_resolver(host_resolver_.get()); | |
| 100 context_->set_http_network_session_params(std::move(params)); | |
| 101 context_->set_cert_verifier(&cert_verifier_); | |
| 102 context_->Init(); | |
| 103 } | |
| 104 | |
| 105 void TearDown() override { | |
| 106 if (quic_server_) { | |
| 107 quic_server_->Shutdown(); | |
| 108 // If possible, deliver the conncetion close packet to the client before | |
| 109 // destruct the TestURLRequestContext. | |
| 110 base::RunLoop().RunUntilIdle(); | |
| 111 } | |
| 112 message_loop_.reset(); | |
| 113 } | |
| 114 | |
| 115 std::unique_ptr<URLRequest> CreateRequest(const GURL& url, | |
| 116 RequestPriority priority, | |
| 117 URLRequest::Delegate* delegate) { | |
| 118 return context_->CreateRequest(url, priority, delegate, | |
| 119 TRAFFIC_ANNOTATION_FOR_TESTS); | |
| 120 } | |
| 121 | |
| 122 URLRequestContext* context() const { return context_.get(); } | |
| 123 | |
| 124 private: | |
| 125 void StartQuicServer() { | |
| 126 net::QuicConfig config; | |
| 127 response_cache_.AddSimpleResponse(kOriginHost, kHelloPath, kHelloStatus, | |
| 128 kHelloAltSvcResponse); | |
| 129 quic_server_.reset(new QuicSimpleServer( | |
| 130 test::crypto_test_utils::ProofSourceForTesting(), config, | |
| 131 net::QuicCryptoServerConfig::ConfigOptions(), AllSupportedVersions(), | |
| 132 &response_cache_)); | |
| 133 int rv = quic_server_->Listen( | |
| 134 net::IPEndPoint(net::IPAddress::IPv4AllZeros(), kAltSvcPort)); | |
| 135 ASSERT_GE(rv, 0) << "Quic server fails to start"; | |
| 136 | |
| 137 CertVerifyResult verify_result; | |
| 138 verify_result.verified_cert = ImportCertFromFile( | |
| 139 GetTestCertsDirectory(), "quic_test.example.com.crt"); | |
| 140 cert_verifier_.AddResultForCert(verify_result.verified_cert.get(), | |
| 141 verify_result, OK); | |
| 142 } | |
| 143 | |
| 144 void StartTcpServer() { | |
| 145 tcp_server_ = base::MakeUnique<EmbeddedTestServer>( | |
| 146 net::EmbeddedTestServer::TYPE_HTTPS); | |
| 147 tcp_server_->RegisterRequestHandler(base::Bind(&HandleRequest)); | |
| 148 ASSERT_TRUE(tcp_server_->Start()) << "HTTP/1.1 server fails to start"; | |
| 149 | |
| 150 CertVerifyResult verify_result; | |
| 151 verify_result.verified_cert = tcp_server_->GetCertificate(); | |
| 152 cert_verifier_.AddResultForCert(tcp_server_->GetCertificate(), | |
| 153 verify_result, OK); | |
| 154 } | |
| 155 | |
| 156 std::unique_ptr<MappedHostResolver> host_resolver_; | |
| 157 std::unique_ptr<EmbeddedTestServer> tcp_server_; | |
| 158 std::unique_ptr<QuicSimpleServer> quic_server_; | |
| 159 std::unique_ptr<base::MessageLoop> message_loop_; | |
| 160 std::unique_ptr<TestURLRequestContext> context_; | |
| 161 QuicHttpResponseCache response_cache_; | |
| 162 MockCertVerifier cert_verifier_; | |
| 163 }; | |
| 164 | |
| 165 } // namespace | |
| 166 | |
| 167 TEST_F(URLRequestQuicPerfTest, TestGetRequest) { | |
| 168 bool quic_succeeded = false; | |
| 169 GURL url(base::StringPrintf("https://%s%s", kOriginHost, kHelloPath)); | |
| 170 base::TimeTicks start = base::TimeTicks::Now(); | |
| 171 const int kNumRequest = 1000; | |
| 172 for (int i = 0; i < kNumRequest; ++i) { | |
| 173 TestDelegate delegate; | |
| 174 std::unique_ptr<URLRequest> request = | |
| 175 CreateRequest(url, DEFAULT_PRIORITY, &delegate); | |
| 176 | |
| 177 request->Start(); | |
| 178 EXPECT_TRUE(request->is_pending()); | |
| 179 base::RunLoop().Run(); | |
| 180 | |
| 181 EXPECT_TRUE(request->status().is_success()); | |
| 182 if (delegate.data_received() == kHelloAltSvcResponse) { | |
| 183 quic_succeeded = true; | |
| 184 } else { | |
| 185 EXPECT_EQ(kHelloOriginResponse, delegate.data_received()); | |
| 186 } | |
| 187 } | |
| 188 base::TimeTicks end = base::TimeTicks::Now(); | |
| 189 PrintPerfTest("time", (end - start).InMilliseconds() / kNumRequest, "ms"); | |
| 190 | |
| 191 EXPECT_TRUE(quic_succeeded); | |
| 192 base::trace_event::MemoryDumpArgs dump_args = { | |
| 193 base::trace_event::MemoryDumpLevelOfDetail::DETAILED}; | |
| 194 std::unique_ptr<base::trace_event::ProcessMemoryDump> process_memory_dump( | |
| 195 new base::trace_event::ProcessMemoryDump(nullptr, dump_args)); | |
| 196 context()->OnMemoryDump(dump_args, process_memory_dump.get()); | |
| 197 const base::trace_event::MemoryAllocatorDump* url_request_context_dump = | |
| 198 process_memory_dump->GetAllocatorDump( | |
| 199 base::StringPrintf("net/url_request_context/unknown/0x%" PRIxPTR, | |
| 200 reinterpret_cast<uintptr_t>(context()))); | |
| 201 ASSERT_NE(nullptr, url_request_context_dump); | |
| 202 auto raw_attrs = | |
| 203 url_request_context_dump->attributes_for_testing()->ToBaseValue(); | |
| 204 base::DictionaryValue* attrs; | |
| 205 ASSERT_TRUE(raw_attrs->GetAsDictionary(&attrs)); | |
| 206 base::DictionaryValue* object_count_attrs; | |
| 207 ASSERT_TRUE(attrs->GetDictionary( | |
| 208 base::trace_event::MemoryAllocatorDump::kNameObjectCount, | |
| 209 &object_count_attrs)); | |
| 210 std::string object_count_str; | |
| 211 ASSERT_TRUE(object_count_attrs->GetString("value", &object_count_str)); | |
| 212 EXPECT_EQ("0", object_count_str); | |
| 213 | |
| 214 // HttpStreamFactory | |
| 215 const base::trace_event::MemoryAllocatorDump* http_stream_factory_dump = | |
| 216 process_memory_dump->GetAllocatorDump(base::StringPrintf( | |
| 217 "net/http_network_session_%p/stream_factory", | |
| 218 context()->http_transaction_factory()->GetSession())); | |
| 219 EXPECT_EQ(nullptr, http_stream_factory_dump); | |
| 220 | |
| 221 // QuicStreamFactory | |
| 222 const base::trace_event::MemoryAllocatorDump* quic_stream_factory_dump = | |
| 223 process_memory_dump->GetAllocatorDump(base::StringPrintf( | |
| 224 "net/http_network_session_%p/quic_stream_factory", | |
| 225 context()->http_transaction_factory()->GetSession())); | |
| 226 ASSERT_NE(nullptr, quic_stream_factory_dump); | |
| 227 | |
| 228 raw_attrs = quic_stream_factory_dump->attributes_for_testing()->ToBaseValue(); | |
| 229 ASSERT_TRUE(raw_attrs->GetAsDictionary(&attrs)); | |
| 230 ASSERT_TRUE(attrs->GetDictionary("active_jobs", &object_count_attrs)); | |
| 231 ASSERT_TRUE(object_count_attrs->GetString("value", &object_count_str)); | |
| 232 EXPECT_EQ("0", object_count_str); | |
| 233 int object_count = -1; | |
| 234 ASSERT_TRUE(base::HexStringToInt(object_count_str, &object_count)); | |
|
nednguyen
2017/05/26 18:38:57
If this test can be enable on CQ, why not change t
xunjieli
2017/05/26 19:13:41
Isn't this already an ASSERT? It shouldn't be flak
nednguyen
2017/05/26 19:15:52
Ooops, wrong line. I mean the line that does: "EXP
xunjieli
2017/05/26 23:57:16
I used EXPECT_EQ() there instead of ASSERT_EQ() be
nednguyen
2017/05/27 00:28:38
Ah I see, as long as the final return code is non
| |
| 235 PrintPerfTest("active_quic_jobs", object_count, "count"); | |
| 236 | |
| 237 ASSERT_TRUE(attrs->GetDictionary("all_sessions", &object_count_attrs)); | |
| 238 ASSERT_TRUE(object_count_attrs->GetString("value", &object_count_str)); | |
| 239 EXPECT_EQ("1", object_count_str); | |
| 240 ASSERT_TRUE(base::HexStringToInt(object_count_str, &object_count)); | |
| 241 PrintPerfTest("active_quic_sessions", object_count, "count"); | |
| 242 } | |
| 243 | |
| 244 } // namespace net | |
| OLD | NEW |