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

Side by Side Diff: components/sync/core/http_bridge_unittest.cc

Issue 2408463002: [Sync] Move network-related code from core/ to engine/net/. (Closed)
Patch Set: Use SyncServerConnectionManager instead of ServerConnectionManagerImpl. Created 4 years, 2 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
OLDNEW
(Empty)
1 // Copyright 2012 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 "components/sync/core/http_bridge.h"
6
7 #include <stddef.h>
8
9 #include "base/bit_cast.h"
10 #include "base/run_loop.h"
11 #include "base/single_thread_task_runner.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/threading/thread.h"
14 #include "build/build_config.h"
15 #include "components/sync/base/cancelation_signal.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/test/embedded_test_server/embedded_test_server.h"
18 #include "net/url_request/test_url_fetcher_factory.h"
19 #include "net/url_request/url_request_test_util.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace syncer {
23
24 namespace {
25
26 // TODO(timsteele): Should use PathService here. See Chromium Issue 3113.
27 const base::FilePath::CharType kDocRoot[] =
28 FILE_PATH_LITERAL("chrome/test/data");
29
30 } // namespace
31
32 const char kUserAgent[] = "user-agent";
33
34 #if defined(OS_ANDROID)
35 #define MAYBE_SyncHttpBridgeTest DISABLED_SyncHttpBridgeTest
36 #else
37 #define MAYBE_SyncHttpBridgeTest SyncHttpBridgeTest
38 #endif // defined(OS_ANDROID)
39 class MAYBE_SyncHttpBridgeTest : public testing::Test {
40 public:
41 MAYBE_SyncHttpBridgeTest()
42 : fake_default_request_context_getter_(NULL),
43 bridge_for_race_test_(NULL),
44 io_thread_("IO thread") {
45 test_server_.AddDefaultHandlers(base::FilePath(kDocRoot));
46 }
47
48 void SetUp() override {
49 base::Thread::Options options;
50 options.message_loop_type = base::MessageLoop::TYPE_IO;
51 io_thread_.StartWithOptions(options);
52 }
53
54 void TearDown() override {
55 if (fake_default_request_context_getter_) {
56 GetIOThreadLoop()->task_runner()->ReleaseSoon(
57 FROM_HERE, fake_default_request_context_getter_);
58 fake_default_request_context_getter_ = NULL;
59 }
60 io_thread_.Stop();
61 }
62
63 HttpBridge* BuildBridge() {
64 if (!fake_default_request_context_getter_) {
65 fake_default_request_context_getter_ =
66 new net::TestURLRequestContextGetter(io_thread_.task_runner());
67 fake_default_request_context_getter_->AddRef();
68 }
69 HttpBridge* bridge =
70 new HttpBridge(kUserAgent, fake_default_request_context_getter_,
71 NetworkTimeUpdateCallback(), BindToTrackerCallback());
72 return bridge;
73 }
74
75 static void Abort(HttpBridge* bridge) { bridge->Abort(); }
76
77 // Used by AbortAndReleaseBeforeFetchCompletes to test an interesting race
78 // condition.
79 void RunSyncThreadBridgeUseTest(base::WaitableEvent* signal_when_created,
80 base::WaitableEvent* signal_when_released);
81
82 static void TestSameHttpNetworkSession(base::MessageLoop* main_message_loop,
83 MAYBE_SyncHttpBridgeTest* test) {
84 scoped_refptr<HttpBridge> http_bridge(test->BuildBridge());
85 EXPECT_TRUE(test->GetTestRequestContextGetter());
86 net::HttpNetworkSession* test_session = test->GetTestRequestContextGetter()
87 ->GetURLRequestContext()
88 ->http_transaction_factory()
89 ->GetSession();
90 EXPECT_EQ(test_session, http_bridge->GetRequestContextGetterForTest()
91 ->GetURLRequestContext()
92 ->http_transaction_factory()
93 ->GetSession());
94 main_message_loop->task_runner()->PostTask(
95 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
96 }
97
98 base::MessageLoop* GetIOThreadLoop() { return io_thread_.message_loop(); }
99
100 // Note this is lazy created, so don't call this before your bridge.
101 net::TestURLRequestContextGetter* GetTestRequestContextGetter() {
102 return fake_default_request_context_getter_;
103 }
104
105 net::EmbeddedTestServer test_server_;
106
107 base::Thread* io_thread() { return &io_thread_; }
108
109 HttpBridge* bridge_for_race_test() { return bridge_for_race_test_; }
110
111 private:
112 // A make-believe "default" request context, as would be returned by
113 // Profile::GetDefaultRequestContext(). Created lazily by BuildBridge.
114 net::TestURLRequestContextGetter* fake_default_request_context_getter_;
115
116 HttpBridge* bridge_for_race_test_;
117
118 // Separate thread for IO used by the HttpBridge.
119 base::Thread io_thread_;
120 base::MessageLoop loop_;
121 };
122
123 // An HttpBridge that doesn't actually make network requests and just calls
124 // back with dummy response info.
125 // TODO(tim): Instead of inheriting here we should inject a component
126 // responsible for the MakeAsynchronousPost bit.
127 class ShuntedHttpBridge : public HttpBridge {
128 public:
129 // If |never_finishes| is true, the simulated request never actually
130 // returns.
131 ShuntedHttpBridge(net::URLRequestContextGetter* baseline_context_getter,
132 MAYBE_SyncHttpBridgeTest* test,
133 bool never_finishes)
134 : HttpBridge(kUserAgent,
135 baseline_context_getter,
136 NetworkTimeUpdateCallback(),
137 BindToTrackerCallback()),
138 test_(test),
139 never_finishes_(never_finishes) {}
140
141 protected:
142 void MakeAsynchronousPost() override {
143 ASSERT_TRUE(
144 test_->GetIOThreadLoop()->task_runner()->BelongsToCurrentThread());
145 if (never_finishes_)
146 return;
147
148 // We don't actually want to make a request for this test, so just callback
149 // as if it completed.
150 test_->GetIOThreadLoop()->task_runner()->PostTask(
151 FROM_HERE,
152 base::Bind(&ShuntedHttpBridge::CallOnURLFetchComplete, this));
153 }
154
155 private:
156 ~ShuntedHttpBridge() override {}
157
158 void CallOnURLFetchComplete() {
159 ASSERT_TRUE(
160 test_->GetIOThreadLoop()->task_runner()->BelongsToCurrentThread());
161 // We return a dummy content response.
162 std::string response_content = "success!";
163 net::TestURLFetcher fetcher(0, GURL("http://www.google.com"), NULL);
164 scoped_refptr<net::HttpResponseHeaders> response_headers(
165 new net::HttpResponseHeaders(""));
166 fetcher.set_response_code(200);
167 fetcher.SetResponseString(response_content);
168 fetcher.set_response_headers(response_headers);
169 OnURLFetchComplete(&fetcher);
170 }
171 MAYBE_SyncHttpBridgeTest* test_;
172 bool never_finishes_;
173 };
174
175 void MAYBE_SyncHttpBridgeTest::RunSyncThreadBridgeUseTest(
176 base::WaitableEvent* signal_when_created,
177 base::WaitableEvent* signal_when_released) {
178 scoped_refptr<net::URLRequestContextGetter> ctx_getter(
179 new net::TestURLRequestContextGetter(io_thread_.task_runner()));
180 {
181 scoped_refptr<ShuntedHttpBridge> bridge(
182 new ShuntedHttpBridge(ctx_getter.get(), this, true));
183 bridge->SetURL("http://www.google.com", 9999);
184 bridge->SetPostPayload("text/plain", 2, " ");
185 bridge_for_race_test_ = bridge.get();
186 signal_when_created->Signal();
187
188 int os_error = 0;
189 int response_code = 0;
190 bridge->MakeSynchronousPost(&os_error, &response_code);
191 bridge_for_race_test_ = NULL;
192 }
193 signal_when_released->Signal();
194 }
195
196 TEST_F(MAYBE_SyncHttpBridgeTest, TestUsesSameHttpNetworkSession) {
197 // Run this test on the IO thread because we can only call
198 // URLRequestContextGetter::GetURLRequestContext on the IO thread.
199 io_thread()->task_runner()->PostTask(
200 FROM_HERE,
201 base::Bind(&MAYBE_SyncHttpBridgeTest::TestSameHttpNetworkSession,
202 base::MessageLoop::current(), this));
203 base::RunLoop().Run();
204 }
205
206 // Test the HttpBridge without actually making any network requests.
207 TEST_F(MAYBE_SyncHttpBridgeTest, TestMakeSynchronousPostShunted) {
208 scoped_refptr<net::URLRequestContextGetter> ctx_getter(
209 new net::TestURLRequestContextGetter(io_thread()->task_runner()));
210 scoped_refptr<HttpBridge> http_bridge(
211 new ShuntedHttpBridge(ctx_getter.get(), this, false));
212 http_bridge->SetURL("http://www.google.com", 9999);
213 http_bridge->SetPostPayload("text/plain", 2, " ");
214
215 int os_error = 0;
216 int response_code = 0;
217 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
218 EXPECT_TRUE(success);
219 EXPECT_EQ(200, response_code);
220 EXPECT_EQ(0, os_error);
221
222 EXPECT_EQ(8, http_bridge->GetResponseContentLength());
223 EXPECT_EQ(std::string("success!"),
224 std::string(http_bridge->GetResponseContent()));
225 }
226
227 // Full round-trip test of the HttpBridge, using default UA string and
228 // no request cookies.
229 TEST_F(MAYBE_SyncHttpBridgeTest, TestMakeSynchronousPostLiveWithPayload) {
230 ASSERT_TRUE(test_server_.Start());
231
232 scoped_refptr<HttpBridge> http_bridge(BuildBridge());
233
234 std::string payload = "this should be echoed back";
235 GURL echo = test_server_.GetURL("/echo");
236 http_bridge->SetURL(echo.spec().c_str(), echo.IntPort());
237 http_bridge->SetPostPayload("application/x-www-form-urlencoded",
238 payload.length() + 1, payload.c_str());
239 int os_error = 0;
240 int response_code = 0;
241 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
242 EXPECT_TRUE(success);
243 EXPECT_EQ(200, response_code);
244 EXPECT_EQ(0, os_error);
245
246 EXPECT_EQ(payload.length() + 1,
247 static_cast<size_t>(http_bridge->GetResponseContentLength()));
248 EXPECT_EQ(payload, std::string(http_bridge->GetResponseContent()));
249 }
250
251 // Full round-trip test of the HttpBridge with compression, check if header
252 // fields("Content-Encoding" ,"Accept-Encoding" and user agent) are set
253 // correctly.
254 TEST_F(MAYBE_SyncHttpBridgeTest, CompressedRequestHeaderCheck) {
255 ASSERT_TRUE(test_server_.Start());
256
257 scoped_refptr<HttpBridge> http_bridge(BuildBridge());
258
259 GURL echo_header = test_server_.GetURL("/echoall");
260 http_bridge->SetURL(echo_header.spec().c_str(), echo_header.IntPort());
261
262 std::string test_payload = "###TEST PAYLOAD###";
263 http_bridge->SetPostPayload("text/html", test_payload.length() + 1,
264 test_payload.c_str());
265
266 int os_error = 0;
267 int response_code = 0;
268 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
269 EXPECT_TRUE(success);
270 EXPECT_EQ(200, response_code);
271 EXPECT_EQ(0, os_error);
272
273 std::string response(http_bridge->GetResponseContent(),
274 http_bridge->GetResponseContentLength());
275 EXPECT_NE(std::string::npos,
276 response.find(base::StringPrintf(
277 "%s: %s", net::HttpRequestHeaders::kAcceptEncoding,
278 "gzip, deflate")));
279 EXPECT_NE(std::string::npos,
280 response.find(base::StringPrintf(
281 "%s: %s", net::HttpRequestHeaders::kUserAgent, kUserAgent)));
282 }
283
284 // Full round-trip test of the HttpBridge.
285 TEST_F(MAYBE_SyncHttpBridgeTest, TestMakeSynchronousPostLiveComprehensive) {
286 ASSERT_TRUE(test_server_.Start());
287
288 scoped_refptr<HttpBridge> http_bridge(BuildBridge());
289
290 GURL echo_header = test_server_.GetURL("/echoall");
291 http_bridge->SetURL(echo_header.spec().c_str(), echo_header.IntPort());
292
293 std::string test_payload = "###TEST PAYLOAD###";
294 http_bridge->SetPostPayload("text/html", test_payload.length() + 1,
295 test_payload.c_str());
296
297 int os_error = 0;
298 int response_code = 0;
299 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
300 EXPECT_TRUE(success);
301 EXPECT_EQ(200, response_code);
302 EXPECT_EQ(0, os_error);
303
304 std::string response(http_bridge->GetResponseContent(),
305 http_bridge->GetResponseContentLength());
306 EXPECT_EQ(std::string::npos, response.find("Cookie:"));
307 EXPECT_NE(std::string::npos,
308 response.find(base::StringPrintf(
309 "%s: %s", net::HttpRequestHeaders::kUserAgent, kUserAgent)));
310 EXPECT_NE(std::string::npos, response.find(test_payload.c_str()));
311 }
312
313 TEST_F(MAYBE_SyncHttpBridgeTest, TestExtraRequestHeaders) {
314 ASSERT_TRUE(test_server_.Start());
315
316 scoped_refptr<HttpBridge> http_bridge(BuildBridge());
317
318 GURL echo_header = test_server_.GetURL("/echoall");
319
320 http_bridge->SetURL(echo_header.spec().c_str(), echo_header.IntPort());
321 http_bridge->SetExtraRequestHeaders("test:fnord");
322
323 std::string test_payload = "###TEST PAYLOAD###";
324 http_bridge->SetPostPayload("text/html", test_payload.length() + 1,
325 test_payload.c_str());
326
327 int os_error = 0;
328 int response_code = 0;
329 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
330 EXPECT_TRUE(success);
331 EXPECT_EQ(200, response_code);
332 EXPECT_EQ(0, os_error);
333
334 std::string response(http_bridge->GetResponseContent(),
335 http_bridge->GetResponseContentLength());
336
337 EXPECT_NE(std::string::npos, response.find("fnord"));
338 EXPECT_NE(std::string::npos, response.find(test_payload.c_str()));
339 }
340
341 TEST_F(MAYBE_SyncHttpBridgeTest, TestResponseHeader) {
342 ASSERT_TRUE(test_server_.Start());
343
344 scoped_refptr<HttpBridge> http_bridge(BuildBridge());
345
346 GURL echo_header = test_server_.GetURL("/echoall");
347 http_bridge->SetURL(echo_header.spec().c_str(), echo_header.IntPort());
348
349 std::string test_payload = "###TEST PAYLOAD###";
350 http_bridge->SetPostPayload("text/html", test_payload.length() + 1,
351 test_payload.c_str());
352
353 int os_error = 0;
354 int response_code = 0;
355 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
356 EXPECT_TRUE(success);
357 EXPECT_EQ(200, response_code);
358 EXPECT_EQ(0, os_error);
359
360 EXPECT_EQ(http_bridge->GetResponseHeaderValue("Content-type"), "text/html");
361 EXPECT_TRUE(http_bridge->GetResponseHeaderValue("invalid-header").empty());
362 }
363
364 TEST_F(MAYBE_SyncHttpBridgeTest, Abort) {
365 scoped_refptr<net::URLRequestContextGetter> ctx_getter(
366 new net::TestURLRequestContextGetter(io_thread()->task_runner()));
367 scoped_refptr<ShuntedHttpBridge> http_bridge(
368 new ShuntedHttpBridge(ctx_getter.get(), this, true));
369 http_bridge->SetURL("http://www.google.com", 9999);
370 http_bridge->SetPostPayload("text/plain", 2, " ");
371
372 int os_error = 0;
373 int response_code = 0;
374
375 io_thread()->task_runner()->PostTask(
376 FROM_HERE, base::Bind(&MAYBE_SyncHttpBridgeTest::Abort,
377 base::RetainedRef(http_bridge)));
378 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
379 EXPECT_FALSE(success);
380 EXPECT_EQ(net::ERR_ABORTED, os_error);
381 }
382
383 TEST_F(MAYBE_SyncHttpBridgeTest, AbortLate) {
384 scoped_refptr<net::URLRequestContextGetter> ctx_getter(
385 new net::TestURLRequestContextGetter(io_thread()->task_runner()));
386 scoped_refptr<ShuntedHttpBridge> http_bridge(
387 new ShuntedHttpBridge(ctx_getter.get(), this, false));
388 http_bridge->SetURL("http://www.google.com", 9999);
389 http_bridge->SetPostPayload("text/plain", 2, " ");
390
391 int os_error = 0;
392 int response_code = 0;
393
394 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
395 ASSERT_TRUE(success);
396 http_bridge->Abort();
397 // Ensures no double-free of URLFetcher, etc.
398 }
399
400 // Tests an interesting case where code using the HttpBridge aborts the fetch
401 // and releases ownership before a pending fetch completed callback is issued by
402 // the underlying URLFetcher (and before that URLFetcher is destroyed, which
403 // would cancel the callback).
404 TEST_F(MAYBE_SyncHttpBridgeTest, AbortAndReleaseBeforeFetchComplete) {
405 base::Thread sync_thread("SyncThread");
406 sync_thread.Start();
407
408 // First, block the sync thread on the post.
409 base::WaitableEvent signal_when_created(
410 base::WaitableEvent::ResetPolicy::AUTOMATIC,
411 base::WaitableEvent::InitialState::NOT_SIGNALED);
412 base::WaitableEvent signal_when_released(
413 base::WaitableEvent::ResetPolicy::AUTOMATIC,
414 base::WaitableEvent::InitialState::NOT_SIGNALED);
415 sync_thread.task_runner()->PostTask(
416 FROM_HERE,
417 base::Bind(&MAYBE_SyncHttpBridgeTest::RunSyncThreadBridgeUseTest,
418 base::Unretained(this), &signal_when_created,
419 &signal_when_released));
420
421 // Stop IO so we can control order of operations.
422 base::WaitableEvent io_waiter(
423 base::WaitableEvent::ResetPolicy::AUTOMATIC,
424 base::WaitableEvent::InitialState::NOT_SIGNALED);
425 ASSERT_TRUE(io_thread()->task_runner()->PostTask(
426 FROM_HERE,
427 base::Bind(&base::WaitableEvent::Wait, base::Unretained(&io_waiter))));
428
429 signal_when_created.Wait(); // Wait till we have a bridge to abort.
430 ASSERT_TRUE(bridge_for_race_test());
431
432 // Schedule the fetch completion callback (but don't run it yet). Don't take
433 // a reference to the bridge to mimic URLFetcher's handling of the delegate.
434 net::URLFetcherDelegate* delegate =
435 static_cast<net::URLFetcherDelegate*>(bridge_for_race_test());
436 std::string response_content = "success!";
437 net::TestURLFetcher fetcher(0, GURL("http://www.google.com"), NULL);
438 fetcher.set_response_code(200);
439 fetcher.SetResponseString(response_content);
440 ASSERT_TRUE(io_thread()->task_runner()->PostTask(
441 FROM_HERE, base::Bind(&net::URLFetcherDelegate::OnURLFetchComplete,
442 base::Unretained(delegate), &fetcher)));
443
444 // Abort the fetch. This should be smart enough to handle the case where
445 // the bridge is destroyed before the callback scheduled above completes.
446 bridge_for_race_test()->Abort();
447
448 // Wait until the sync thread releases its ref on the bridge.
449 signal_when_released.Wait();
450 ASSERT_FALSE(bridge_for_race_test());
451
452 // Unleash the hounds. The fetch completion callback should fire first, and
453 // succeed even though we Release()d the bridge above because the call to
454 // Abort should have held a reference.
455 io_waiter.Signal();
456
457 // Done.
458 sync_thread.Stop();
459 io_thread()->Stop();
460 }
461
462 void HttpBridgeRunOnSyncThread(
463 net::URLRequestContextGetter* baseline_context_getter,
464 CancelationSignal* factory_cancelation_signal,
465 HttpPostProviderFactory** bridge_factory_out,
466 HttpPostProviderInterface** bridge_out,
467 base::WaitableEvent* signal_when_created,
468 base::WaitableEvent* wait_for_shutdown) {
469 std::unique_ptr<HttpBridgeFactory> bridge_factory(new HttpBridgeFactory(
470 baseline_context_getter, NetworkTimeUpdateCallback(),
471 factory_cancelation_signal));
472 bridge_factory->Init("test", BindToTrackerCallback());
473 *bridge_factory_out = bridge_factory.get();
474
475 HttpPostProviderInterface* bridge = bridge_factory->Create();
476 *bridge_out = bridge;
477
478 signal_when_created->Signal();
479 wait_for_shutdown->Wait();
480
481 bridge_factory->Destroy(bridge);
482 }
483
484 void WaitOnIOThread(base::WaitableEvent* signal_wait_start,
485 base::WaitableEvent* wait_done) {
486 signal_wait_start->Signal();
487 wait_done->Wait();
488 }
489
490 // Tests RequestContextGetter is properly released on IO thread even when
491 // IO thread stops before sync thread.
492 TEST_F(MAYBE_SyncHttpBridgeTest, RequestContextGetterReleaseOrder) {
493 base::Thread sync_thread("SyncThread");
494 sync_thread.Start();
495
496 HttpPostProviderFactory* factory = NULL;
497 HttpPostProviderInterface* bridge = NULL;
498
499 scoped_refptr<net::URLRequestContextGetter> baseline_context_getter(
500 new net::TestURLRequestContextGetter(io_thread()->task_runner()));
501
502 base::WaitableEvent signal_when_created(
503 base::WaitableEvent::ResetPolicy::AUTOMATIC,
504 base::WaitableEvent::InitialState::NOT_SIGNALED);
505 base::WaitableEvent wait_for_shutdown(
506 base::WaitableEvent::ResetPolicy::AUTOMATIC,
507 base::WaitableEvent::InitialState::NOT_SIGNALED);
508
509 CancelationSignal release_request_context_signal;
510
511 // Create bridge factory and factory on sync thread and wait for the creation
512 // to finish.
513 sync_thread.task_runner()->PostTask(
514 FROM_HERE, base::Bind(&HttpBridgeRunOnSyncThread,
515 base::Unretained(baseline_context_getter.get()),
516 &release_request_context_signal, &factory, &bridge,
517 &signal_when_created, &wait_for_shutdown));
518 signal_when_created.Wait();
519
520 // Simulate sync shutdown by aborting bridge and shutting down factory on
521 // frontend.
522 bridge->Abort();
523 release_request_context_signal.Signal();
524
525 // Wait for sync's RequestContextGetter to be cleared on IO thread and
526 // check for reference count.
527 base::WaitableEvent signal_wait_start(
528 base::WaitableEvent::ResetPolicy::AUTOMATIC,
529 base::WaitableEvent::InitialState::NOT_SIGNALED);
530 base::WaitableEvent wait_done(
531 base::WaitableEvent::ResetPolicy::AUTOMATIC,
532 base::WaitableEvent::InitialState::NOT_SIGNALED);
533 io_thread()->task_runner()->PostTask(
534 FROM_HERE, base::Bind(&WaitOnIOThread, &signal_wait_start, &wait_done));
535 signal_wait_start.Wait();
536 // |baseline_context_getter| should have only one reference from local
537 // variable.
538 EXPECT_TRUE(baseline_context_getter->HasOneRef());
539 baseline_context_getter = NULL;
540
541 // Unblock and stop IO thread before sync thread.
542 wait_done.Signal();
543 io_thread()->Stop();
544
545 // Unblock and stop sync thread.
546 wait_for_shutdown.Signal();
547 sync_thread.Stop();
548 }
549
550 // Attempt to release the URLRequestContextGetter before the HttpBridgeFactory
551 // is initialized.
552 TEST_F(MAYBE_SyncHttpBridgeTest, EarlyAbortFactory) {
553 // In a real scenario, the following would happen on many threads. For
554 // simplicity, this test uses only one thread.
555
556 scoped_refptr<net::URLRequestContextGetter> baseline_context_getter(
557 new net::TestURLRequestContextGetter(io_thread()->task_runner()));
558 CancelationSignal release_request_context_signal;
559
560 // UI Thread: Initialize the HttpBridgeFactory. The next step would be to
561 // post a task to SBH::Core to have it initialized.
562 std::unique_ptr<HttpBridgeFactory> factory(new HttpBridgeFactory(
563 baseline_context_getter.get(), NetworkTimeUpdateCallback(),
564 &release_request_context_signal));
565
566 // UI Thread: A very early shutdown request arrives and executes on the UI
567 // thread before the posted sync thread task is run.
568 release_request_context_signal.Signal();
569
570 // Sync thread: Finally run the posted task, only to find that our
571 // HttpBridgeFactory has been neutered. Should not crash.
572 factory->Init("TestUserAgent", BindToTrackerCallback());
573
574 // At this point, attempting to use the factory would trigger a crash. Both
575 // this test and the real world code should make sure this never happens.
576 }
577
578 } // namespace syncer
OLDNEW
« no previous file with comments | « components/sync/core/http_bridge_network_resources.cc ('k') | components/sync/core/http_post_provider_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698