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

Side by Side Diff: sync/internal_api/http_bridge_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698