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

Side by Side Diff: net/url_request/url_request_quic_perftest.cc

Issue 2875083002: Add url_request_quic_perftest.cc (Closed)
Patch Set: Rebased Created 3 years, 6 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 unified diff | Download patch
« no previous file with comments | « net/BUILD.gn ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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/callback.h"
10 #include "base/files/file_path.h"
11 #include "base/macros.h"
12 #include "base/memory/ptr_util.h"
13 #include "base/memory/ref_counted_memory.h"
14 #include "base/message_loop/message_loop.h"
15 #include "base/run_loop.h"
16 #include "base/single_thread_task_runner.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/test/trace_event_analyzer.h"
20 #include "base/time/time.h"
21 #include "base/trace_event/memory_dump_manager.h"
22 #include "base/trace_event/memory_dump_request_args.h"
23 #include "base/trace_event/process_memory_dump.h"
24 #include "base/trace_event/trace_buffer.h"
25 #include "base/trace_event/trace_config.h"
26 #include "base/trace_event/trace_config_memory_test_util.h"
27 #include "base/trace_event/trace_log.h"
28 #include "net/base/load_timing_info.h"
29 #include "net/cert/mock_cert_verifier.h"
30 #include "net/dns/mapped_host_resolver.h"
31 #include "net/dns/mock_host_resolver.h"
32 #include "net/http/http_status_code.h"
33 #include "net/quic/chromium/crypto/proof_source_chromium.h"
34 #include "net/quic/test_tools/crypto_test_utils.h"
35 #include "net/test/cert_test_util.h"
36 #include "net/test/embedded_test_server/embedded_test_server.h"
37 #include "net/test/embedded_test_server/http_response.h"
38 #include "net/test/gtest_util.h"
39 #include "net/test/test_data_directory.h"
40 #include "net/tools/quic/quic_http_response_cache.h"
41 #include "net/tools/quic/quic_simple_server.h"
42 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
43 #include "net/url_request/url_request.h"
44 #include "net/url_request/url_request_test_util.h"
45 #include "testing/gmock/include/gmock/gmock.h"
46 #include "testing/gtest/include/gtest/gtest.h"
47 #include "testing/perf/perf_test.h"
48 #include "url/gurl.h"
49
50 using testing::_;
51 using testing::Invoke;
52
53 namespace net {
54
55 namespace {
56
57 const int kAltSvcPort = 6121;
58 const char kOriginHost[] = "mail.example.com";
59 const char kAltSvcHost[] = "test.example.com";
60 // Used as a simple response from the server.
61 const char kHelloPath[] = "/hello.txt";
62 const char kHelloAltSvcResponse[] = "Hello from QUIC Server";
63 const char kHelloOriginResponse[] = "Hello from TCP Server";
64 const int kHelloStatus = 200;
65
66 std::unique_ptr<test_server::HttpResponse> HandleRequest(
67 const test_server::HttpRequest& request) {
68 std::unique_ptr<test_server::BasicHttpResponse> http_response(
69 new test_server::BasicHttpResponse());
70 http_response->AddCustomHeader(
71 "Alt-Svc", base::StringPrintf(
72 "quic=\"%s:%d\"; v=\"%u\"", kAltSvcHost, kAltSvcPort,
73 HttpNetworkSession::Params().quic_supported_versions[0]));
74 http_response->set_code(HTTP_OK);
75 http_response->set_content(kHelloOriginResponse);
76 http_response->set_content_type("text/plain");
77 return std::move(http_response);
78 }
79
80 void PrintPerfTest(const std::string& name,
81 int value,
82 const std::string& unit) {
83 const ::testing::TestInfo* test_info =
84 ::testing::UnitTest::GetInstance()->current_test_info();
85 perf_test::PrintResult(test_info->test_case_name(),
86 std::string(".") + test_info->name(), name,
87 static_cast<double>(value), unit, true);
88 }
89
90 void RequestGlobalDumpCallback(base::Closure quit_closure,
91 uint64_t,
92 bool success) {
93 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, quit_closure);
94 ASSERT_TRUE(success);
95 }
96
97 void ProcessDumpCallbackAdapter(
98 base::trace_event::GlobalMemoryDumpCallback callback,
99 uint64_t dump_guid,
100 bool success,
101 const base::Optional<base::trace_event::MemoryDumpCallbackResult>&) {
102 callback.Run(dump_guid, success);
103 }
104
105 void RequestGlobalMemoryDumpCallback(
106 const base::trace_event::MemoryDumpRequestArgs& args,
107 const base::trace_event::GlobalMemoryDumpCallback& callback) {
108 base::trace_event::ProcessMemoryDumpCallback process_callback =
109 base::Bind(&ProcessDumpCallbackAdapter, callback);
110 base::trace_event::MemoryDumpManager::GetInstance()->CreateProcessDump(
111 args, process_callback);
112 }
113
114 class URLRequestQuicPerfTest : public ::testing::Test {
115 protected:
116 URLRequestQuicPerfTest() : message_loop_(new base::MessageLoopForIO()) {
117 memory_dump_manager_ =
118 base::trace_event::MemoryDumpManager::CreateInstanceForTesting();
119 memory_dump_manager_->Initialize(
120 base::BindRepeating(&RequestGlobalMemoryDumpCallback),
121 /*is_coordinator_process=*/false);
122 memory_dump_manager_->set_dumper_registrations_ignored_for_testing(false);
123 context_ = base::MakeUnique<TestURLRequestContext>(true);
124 memory_dump_manager_->set_dumper_registrations_ignored_for_testing(true);
125 StartTcpServer();
126 StartQuicServer();
127
128 // Host mapping.
129 std::unique_ptr<MockHostResolver> resolver(new MockHostResolver());
130 resolver->rules()->AddRule(kAltSvcHost, "127.0.0.1");
131 host_resolver_.reset(new MappedHostResolver(std::move(resolver)));
132 std::string map_rule = base::StringPrintf("MAP %s 127.0.0.1:%d",
133 kOriginHost, tcp_server_->port());
134 EXPECT_TRUE(host_resolver_->AddRuleFromString(map_rule));
135
136 net::HttpNetworkSession::Context network_session_context;
137 network_session_context.cert_verifier = &cert_verifier_;
138 std::unique_ptr<HttpNetworkSession::Params> params(
139 new HttpNetworkSession::Params);
140 params->enable_quic = true;
141 params->enable_user_alternate_protocol_ports = true;
142 context_->set_host_resolver(host_resolver_.get());
143 context_->set_http_network_session_params(std::move(params));
144 context_->set_cert_verifier(&cert_verifier_);
145 context_->Init();
146 }
147
148 void TearDown() override {
149 if (quic_server_) {
150 quic_server_->Shutdown();
151 // If possible, deliver the conncetion close packet to the client before
152 // destruct the TestURLRequestContext.
153 base::RunLoop().RunUntilIdle();
154 }
155 // |tcp_server_| shuts down in EmbeddedTestServer destructor.
156 memory_dump_manager_.reset();
157 message_loop_.reset();
158 }
159
160 std::unique_ptr<URLRequest> CreateRequest(const GURL& url,
161 RequestPriority priority,
162 URLRequest::Delegate* delegate) {
163 return context_->CreateRequest(url, priority, delegate,
164 TRAFFIC_ANNOTATION_FOR_TESTS);
165 }
166
167 URLRequestContext* context() const { return context_.get(); }
168
169 private:
170 void StartQuicServer() {
171 net::QuicConfig config;
172 response_cache_.AddSimpleResponse(kOriginHost, kHelloPath, kHelloStatus,
173 kHelloAltSvcResponse);
174 quic_server_.reset(new QuicSimpleServer(
175 test::crypto_test_utils::ProofSourceForTesting(), config,
176 net::QuicCryptoServerConfig::ConfigOptions(), AllSupportedVersions(),
177 &response_cache_));
178 int rv = quic_server_->Listen(
179 net::IPEndPoint(net::IPAddress::IPv4AllZeros(), kAltSvcPort));
180 ASSERT_GE(rv, 0) << "Quic server fails to start";
181
182 CertVerifyResult verify_result;
183 verify_result.verified_cert = ImportCertFromFile(
184 GetTestCertsDirectory(), "quic_test.example.com.crt");
185 cert_verifier_.AddResultForCert(verify_result.verified_cert.get(),
186 verify_result, OK);
187 }
188
189 void StartTcpServer() {
190 tcp_server_ = base::MakeUnique<EmbeddedTestServer>(
191 net::EmbeddedTestServer::TYPE_HTTPS);
192 tcp_server_->RegisterRequestHandler(base::Bind(&HandleRequest));
193 ASSERT_TRUE(tcp_server_->Start()) << "HTTP/1.1 server fails to start";
194
195 CertVerifyResult verify_result;
196 verify_result.verified_cert = tcp_server_->GetCertificate();
197 cert_verifier_.AddResultForCert(tcp_server_->GetCertificate(),
198 verify_result, OK);
199 }
200
201 std::unique_ptr<base::trace_event::MemoryDumpManager> memory_dump_manager_;
202 std::unique_ptr<MappedHostResolver> host_resolver_;
203 std::unique_ptr<EmbeddedTestServer> tcp_server_;
204 std::unique_ptr<QuicSimpleServer> quic_server_;
205 std::unique_ptr<base::MessageLoop> message_loop_;
206 std::unique_ptr<TestURLRequestContext> context_;
207 std::vector<base::trace_event::MemoryDumpCallbackResult> results_;
208 QuicHttpResponseCache response_cache_;
209 MockCertVerifier cert_verifier_;
210 };
211
212 void OnTraceDataCollected(base::Closure quit_closure,
213 base::trace_event::TraceResultBuffer* buffer,
214 const scoped_refptr<base::RefCountedString>& json,
215 bool has_more_events) {
216 buffer->AddFragment(json->data());
217 if (!has_more_events)
218 quit_closure.Run();
219 }
220
221 std::unique_ptr<trace_analyzer::TraceAnalyzer> GetDeserializedTrace() {
222 // Flush the trace into JSON.
223 base::trace_event::TraceResultBuffer buffer;
224 base::trace_event::TraceResultBuffer::SimpleOutput trace_output;
225 buffer.SetOutputCallback(trace_output.GetCallback());
226 base::RunLoop run_loop;
227 buffer.Start();
228 base::trace_event::TraceLog::GetInstance()->Flush(
229 Bind(&OnTraceDataCollected, run_loop.QuitClosure(),
230 base::Unretained(&buffer)));
231 run_loop.Run();
232 buffer.Finish();
233
234 // Analyze the JSON.
235 return base::WrapUnique(
236 trace_analyzer::TraceAnalyzer::Create(trace_output.json_output));
237 }
238
239 } // namespace
240
241 TEST_F(URLRequestQuicPerfTest, TestGetRequest) {
242 bool quic_succeeded = false;
243 GURL url(base::StringPrintf("https://%s%s", kOriginHost, kHelloPath));
244 base::TimeTicks start = base::TimeTicks::Now();
245 const int kNumRequest = 1000;
246 for (int i = 0; i < kNumRequest; ++i) {
247 TestDelegate delegate;
248 std::unique_ptr<URLRequest> request =
249 CreateRequest(url, DEFAULT_PRIORITY, &delegate);
250
251 request->Start();
252 EXPECT_TRUE(request->is_pending());
253 base::RunLoop().Run();
254
255 EXPECT_TRUE(request->status().is_success());
256 if (delegate.data_received() == kHelloAltSvcResponse) {
257 quic_succeeded = true;
258 } else {
259 EXPECT_EQ(kHelloOriginResponse, delegate.data_received());
260 }
261 }
262 base::TimeTicks end = base::TimeTicks::Now();
263 PrintPerfTest("time", (end - start).InMilliseconds() / kNumRequest, "ms");
264
265 EXPECT_TRUE(quic_succeeded);
266 base::trace_event::TraceLog::GetInstance()->SetEnabled(
267 base::trace_event::TraceConfig(
268 base::trace_event::MemoryDumpManager::kTraceCategory, ""),
269 base::trace_event::TraceLog::RECORDING_MODE);
270
271 base::RunLoop run_loop;
272 base::trace_event::MemoryDumpManager::GetInstance()->RequestGlobalDump(
273 base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED,
274 base::trace_event::MemoryDumpLevelOfDetail::LIGHT,
275 base::Bind(&RequestGlobalDumpCallback, run_loop.QuitClosure()));
276
277 run_loop.Run();
278 base::trace_event::TraceLog::GetInstance()->SetDisabled();
279 std::unique_ptr<trace_analyzer::TraceAnalyzer> analyzer =
280 GetDeserializedTrace();
281
282 trace_analyzer::TraceEventVector events;
283 analyzer->FindEvents(
284 trace_analyzer::Query::EventPhaseIs(TRACE_EVENT_PHASE_MEMORY_DUMP),
285 &events);
286 EXPECT_EQ(
287 1u,
288 trace_analyzer::CountMatches(
289 events,
290 trace_analyzer::Query::EventNameIs(
291 base::trace_event::MemoryDumpTypeToString(
292 base::trace_event::MemoryDumpType::EXPLICITLY_TRIGGERED))));
293
294 const trace_analyzer::TraceEvent* event = events[0];
295 std::unique_ptr<base::Value> dumps;
296 event->GetArgAsValue("dumps", &dumps);
297 base::DictionaryValue* allocator_dumps;
298 ASSERT_TRUE(dumps->GetAsDictionary(&allocator_dumps));
299 ASSERT_TRUE(allocator_dumps->GetDictionary("allocators", &allocator_dumps));
300
301 base::DictionaryValue* url_request_context_dump;
302 ASSERT_TRUE(allocator_dumps->GetDictionary(
303 base::StringPrintf("net/url_request_context/unknown/0x%" PRIxPTR,
304 reinterpret_cast<uintptr_t>(context())),
305 &url_request_context_dump));
306 base::DictionaryValue* attrs;
307 ASSERT_TRUE(url_request_context_dump->GetDictionary("attrs", &attrs));
308 base::DictionaryValue* object_count_attrs;
309 ASSERT_TRUE(attrs->GetDictionary(
310 base::trace_event::MemoryAllocatorDump::kNameObjectCount,
311 &object_count_attrs));
312 std::string object_count_str;
313 ASSERT_TRUE(object_count_attrs->GetString("value", &object_count_str));
314 EXPECT_EQ("0", object_count_str);
315
316 base::DictionaryValue* quic_stream_factory_dump;
317 ASSERT_TRUE(allocator_dumps->GetDictionary(
318 base::StringPrintf(
319 "net/http_network_session_0x%" PRIxPTR "/quic_stream_factory",
320 reinterpret_cast<uintptr_t>(
321 context()->http_transaction_factory()->GetSession())),
322 &quic_stream_factory_dump));
323 ASSERT_TRUE(quic_stream_factory_dump->GetDictionary("attrs", &attrs));
324 ASSERT_TRUE(attrs->GetDictionary("active_jobs", &object_count_attrs));
325 ASSERT_TRUE(object_count_attrs->GetString("value", &object_count_str));
326 EXPECT_EQ("0", object_count_str);
327 int object_count = -1;
328 ASSERT_TRUE(base::HexStringToInt(object_count_str, &object_count));
329 PrintPerfTest("active_quic_jobs", object_count, "count");
330 ASSERT_TRUE(attrs->GetDictionary("all_sessions", &object_count_attrs));
331 ASSERT_TRUE(object_count_attrs->GetString("value", &object_count_str));
332 EXPECT_EQ("1", object_count_str);
333 ASSERT_TRUE(base::HexStringToInt(object_count_str, &object_count));
334 PrintPerfTest("active_quic_sessions", object_count, "count");
335
336 base::DictionaryValue* http_stream_factory_dump;
337 ASSERT_FALSE(allocator_dumps->GetDictionary(
338 base::StringPrintf(
339 "net/http_network_session_0x%" PRIxPTR "/stream_factory",
340 reinterpret_cast<uintptr_t>(
341 context()->http_transaction_factory()->GetSession())),
342 &http_stream_factory_dump));
343 }
344
345 } // namespace net
OLDNEW
« no previous file with comments | « net/BUILD.gn ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698