OLD | NEW |
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/strings/stringprintf.h" | 5 #include "base/strings/stringprintf.h" |
6 #include "base/synchronization/waitable_event.h" | 6 #include "base/synchronization/waitable_event.h" |
7 #include "base/threading/thread.h" | 7 #include "base/threading/thread.h" |
8 #include "net/http/http_response_headers.h" | 8 #include "net/http/http_response_headers.h" |
9 #include "net/test/spawned_test_server/spawned_test_server.h" | 9 #include "net/test/spawned_test_server/spawned_test_server.h" |
10 #include "net/url_request/test_url_fetcher_factory.h" | 10 #include "net/url_request/test_url_fetcher_factory.h" |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 GetIOThreadLoop()->ReleaseSoon(FROM_HERE, | 46 GetIOThreadLoop()->ReleaseSoon(FROM_HERE, |
47 fake_default_request_context_getter_); | 47 fake_default_request_context_getter_); |
48 fake_default_request_context_getter_ = NULL; | 48 fake_default_request_context_getter_ = NULL; |
49 } | 49 } |
50 io_thread_.Stop(); | 50 io_thread_.Stop(); |
51 } | 51 } |
52 | 52 |
53 HttpBridge* BuildBridge() { | 53 HttpBridge* BuildBridge() { |
54 if (!fake_default_request_context_getter_) { | 54 if (!fake_default_request_context_getter_) { |
55 fake_default_request_context_getter_ = | 55 fake_default_request_context_getter_ = |
56 new net::TestURLRequestContextGetter(io_thread_.message_loop_proxy()); | 56 new net::TestURLRequestContextGetter(io_thread_.task_runner()); |
57 fake_default_request_context_getter_->AddRef(); | 57 fake_default_request_context_getter_->AddRef(); |
58 } | 58 } |
59 HttpBridge* bridge = | 59 HttpBridge* bridge = |
60 new HttpBridge(kUserAgent, | 60 new HttpBridge(kUserAgent, |
61 fake_default_request_context_getter_, | 61 fake_default_request_context_getter_, |
62 NetworkTimeUpdateCallback()); | 62 NetworkTimeUpdateCallback()); |
63 return bridge; | 63 return bridge; |
64 } | 64 } |
65 | 65 |
66 static void Abort(HttpBridge* bridge) { | 66 static void Abort(HttpBridge* bridge) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 OnURLFetchComplete(&fetcher); | 152 OnURLFetchComplete(&fetcher); |
153 } | 153 } |
154 SyncHttpBridgeTest* test_; | 154 SyncHttpBridgeTest* test_; |
155 bool never_finishes_; | 155 bool never_finishes_; |
156 }; | 156 }; |
157 | 157 |
158 void SyncHttpBridgeTest::RunSyncThreadBridgeUseTest( | 158 void SyncHttpBridgeTest::RunSyncThreadBridgeUseTest( |
159 base::WaitableEvent* signal_when_created, | 159 base::WaitableEvent* signal_when_created, |
160 base::WaitableEvent* signal_when_released) { | 160 base::WaitableEvent* signal_when_released) { |
161 scoped_refptr<net::URLRequestContextGetter> ctx_getter( | 161 scoped_refptr<net::URLRequestContextGetter> ctx_getter( |
162 new net::TestURLRequestContextGetter(io_thread_.message_loop_proxy())); | 162 new net::TestURLRequestContextGetter(io_thread_.task_runner())); |
163 { | 163 { |
164 scoped_refptr<ShuntedHttpBridge> bridge( | 164 scoped_refptr<ShuntedHttpBridge> bridge( |
165 new ShuntedHttpBridge(ctx_getter.get(), this, true)); | 165 new ShuntedHttpBridge(ctx_getter.get(), this, true)); |
166 bridge->SetURL("http://www.google.com", 9999); | 166 bridge->SetURL("http://www.google.com", 9999); |
167 bridge->SetPostPayload("text/plain", 2, " "); | 167 bridge->SetPostPayload("text/plain", 2, " "); |
168 bridge_for_race_test_ = bridge.get(); | 168 bridge_for_race_test_ = bridge.get(); |
169 signal_when_created->Signal(); | 169 signal_when_created->Signal(); |
170 | 170 |
171 int os_error = 0; | 171 int os_error = 0; |
172 int response_code = 0; | 172 int response_code = 0; |
(...skipping 10 matching lines...) Expand all Loading... |
183 ->PostTask(FROM_HERE, | 183 ->PostTask(FROM_HERE, |
184 base::Bind(&SyncHttpBridgeTest::TestSameHttpNetworkSession, | 184 base::Bind(&SyncHttpBridgeTest::TestSameHttpNetworkSession, |
185 base::MessageLoop::current(), | 185 base::MessageLoop::current(), |
186 this)); | 186 this)); |
187 base::MessageLoop::current()->Run(); | 187 base::MessageLoop::current()->Run(); |
188 } | 188 } |
189 | 189 |
190 // Test the HttpBridge without actually making any network requests. | 190 // Test the HttpBridge without actually making any network requests. |
191 TEST_F(SyncHttpBridgeTest, TestMakeSynchronousPostShunted) { | 191 TEST_F(SyncHttpBridgeTest, TestMakeSynchronousPostShunted) { |
192 scoped_refptr<net::URLRequestContextGetter> ctx_getter( | 192 scoped_refptr<net::URLRequestContextGetter> ctx_getter( |
193 new net::TestURLRequestContextGetter(io_thread()->message_loop_proxy())); | 193 new net::TestURLRequestContextGetter(io_thread()->task_runner())); |
194 scoped_refptr<HttpBridge> http_bridge( | 194 scoped_refptr<HttpBridge> http_bridge( |
195 new ShuntedHttpBridge(ctx_getter.get(), this, false)); | 195 new ShuntedHttpBridge(ctx_getter.get(), this, false)); |
196 http_bridge->SetURL("http://www.google.com", 9999); | 196 http_bridge->SetURL("http://www.google.com", 9999); |
197 http_bridge->SetPostPayload("text/plain", 2, " "); | 197 http_bridge->SetPostPayload("text/plain", 2, " "); |
198 | 198 |
199 int os_error = 0; | 199 int os_error = 0; |
200 int response_code = 0; | 200 int response_code = 0; |
201 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code); | 201 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code); |
202 EXPECT_TRUE(success); | 202 EXPECT_TRUE(success); |
203 EXPECT_EQ(200, response_code); | 203 EXPECT_EQ(200, response_code); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 EXPECT_TRUE(success); | 307 EXPECT_TRUE(success); |
308 EXPECT_EQ(200, response_code); | 308 EXPECT_EQ(200, response_code); |
309 EXPECT_EQ(0, os_error); | 309 EXPECT_EQ(0, os_error); |
310 | 310 |
311 EXPECT_EQ(http_bridge->GetResponseHeaderValue("Content-type"), "text/html"); | 311 EXPECT_EQ(http_bridge->GetResponseHeaderValue("Content-type"), "text/html"); |
312 EXPECT_TRUE(http_bridge->GetResponseHeaderValue("invalid-header").empty()); | 312 EXPECT_TRUE(http_bridge->GetResponseHeaderValue("invalid-header").empty()); |
313 } | 313 } |
314 | 314 |
315 TEST_F(SyncHttpBridgeTest, Abort) { | 315 TEST_F(SyncHttpBridgeTest, Abort) { |
316 scoped_refptr<net::URLRequestContextGetter> ctx_getter( | 316 scoped_refptr<net::URLRequestContextGetter> ctx_getter( |
317 new net::TestURLRequestContextGetter(io_thread()->message_loop_proxy())); | 317 new net::TestURLRequestContextGetter(io_thread()->task_runner())); |
318 scoped_refptr<ShuntedHttpBridge> http_bridge( | 318 scoped_refptr<ShuntedHttpBridge> http_bridge( |
319 new ShuntedHttpBridge(ctx_getter.get(), this, true)); | 319 new ShuntedHttpBridge(ctx_getter.get(), this, true)); |
320 http_bridge->SetURL("http://www.google.com", 9999); | 320 http_bridge->SetURL("http://www.google.com", 9999); |
321 http_bridge->SetPostPayload("text/plain", 2, " "); | 321 http_bridge->SetPostPayload("text/plain", 2, " "); |
322 | 322 |
323 int os_error = 0; | 323 int os_error = 0; |
324 int response_code = 0; | 324 int response_code = 0; |
325 | 325 |
326 io_thread()->message_loop_proxy()->PostTask( | 326 io_thread()->task_runner()->PostTask( |
327 FROM_HERE, | 327 FROM_HERE, |
328 base::Bind(&SyncHttpBridgeTest::Abort, http_bridge)); | 328 base::Bind(&SyncHttpBridgeTest::Abort, http_bridge)); |
329 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code); | 329 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code); |
330 EXPECT_FALSE(success); | 330 EXPECT_FALSE(success); |
331 EXPECT_EQ(net::ERR_ABORTED, os_error); | 331 EXPECT_EQ(net::ERR_ABORTED, os_error); |
332 } | 332 } |
333 | 333 |
334 TEST_F(SyncHttpBridgeTest, AbortLate) { | 334 TEST_F(SyncHttpBridgeTest, AbortLate) { |
335 scoped_refptr<net::URLRequestContextGetter> ctx_getter( | 335 scoped_refptr<net::URLRequestContextGetter> ctx_getter( |
336 new net::TestURLRequestContextGetter(io_thread()->message_loop_proxy())); | 336 new net::TestURLRequestContextGetter(io_thread()->task_runner())); |
337 scoped_refptr<ShuntedHttpBridge> http_bridge( | 337 scoped_refptr<ShuntedHttpBridge> http_bridge( |
338 new ShuntedHttpBridge(ctx_getter.get(), this, false)); | 338 new ShuntedHttpBridge(ctx_getter.get(), this, false)); |
339 http_bridge->SetURL("http://www.google.com", 9999); | 339 http_bridge->SetURL("http://www.google.com", 9999); |
340 http_bridge->SetPostPayload("text/plain", 2, " "); | 340 http_bridge->SetPostPayload("text/plain", 2, " "); |
341 | 341 |
342 int os_error = 0; | 342 int os_error = 0; |
343 int response_code = 0; | 343 int response_code = 0; |
344 | 344 |
345 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code); | 345 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code); |
346 ASSERT_TRUE(success); | 346 ASSERT_TRUE(success); |
(...skipping 13 matching lines...) Expand all Loading... |
360 base::WaitableEvent signal_when_created(false, false); | 360 base::WaitableEvent signal_when_created(false, false); |
361 base::WaitableEvent signal_when_released(false, false); | 361 base::WaitableEvent signal_when_released(false, false); |
362 sync_thread.message_loop()->PostTask(FROM_HERE, | 362 sync_thread.message_loop()->PostTask(FROM_HERE, |
363 base::Bind(&SyncHttpBridgeTest::RunSyncThreadBridgeUseTest, | 363 base::Bind(&SyncHttpBridgeTest::RunSyncThreadBridgeUseTest, |
364 base::Unretained(this), | 364 base::Unretained(this), |
365 &signal_when_created, | 365 &signal_when_created, |
366 &signal_when_released)); | 366 &signal_when_released)); |
367 | 367 |
368 // Stop IO so we can control order of operations. | 368 // Stop IO so we can control order of operations. |
369 base::WaitableEvent io_waiter(false, false); | 369 base::WaitableEvent io_waiter(false, false); |
370 ASSERT_TRUE(io_thread()->message_loop_proxy()->PostTask( | 370 ASSERT_TRUE(io_thread()->task_runner()->PostTask( |
371 FROM_HERE, | 371 FROM_HERE, |
372 base::Bind(&base::WaitableEvent::Wait, base::Unretained(&io_waiter)))); | 372 base::Bind(&base::WaitableEvent::Wait, base::Unretained(&io_waiter)))); |
373 | 373 |
374 signal_when_created.Wait(); // Wait till we have a bridge to abort. | 374 signal_when_created.Wait(); // Wait till we have a bridge to abort. |
375 ASSERT_TRUE(bridge_for_race_test()); | 375 ASSERT_TRUE(bridge_for_race_test()); |
376 | 376 |
377 // Schedule the fetch completion callback (but don't run it yet). Don't take | 377 // Schedule the fetch completion callback (but don't run it yet). Don't take |
378 // a reference to the bridge to mimic URLFetcher's handling of the delegate. | 378 // a reference to the bridge to mimic URLFetcher's handling of the delegate. |
379 net::URLFetcherDelegate* delegate = | 379 net::URLFetcherDelegate* delegate = |
380 static_cast<net::URLFetcherDelegate*>(bridge_for_race_test()); | 380 static_cast<net::URLFetcherDelegate*>(bridge_for_race_test()); |
381 net::ResponseCookies cookies; | 381 net::ResponseCookies cookies; |
382 std::string response_content = "success!"; | 382 std::string response_content = "success!"; |
383 net::TestURLFetcher fetcher(0, GURL("http://www.google.com"), NULL); | 383 net::TestURLFetcher fetcher(0, GURL("http://www.google.com"), NULL); |
384 fetcher.set_response_code(200); | 384 fetcher.set_response_code(200); |
385 fetcher.set_cookies(cookies); | 385 fetcher.set_cookies(cookies); |
386 fetcher.SetResponseString(response_content); | 386 fetcher.SetResponseString(response_content); |
387 ASSERT_TRUE(io_thread()->message_loop_proxy()->PostTask( | 387 ASSERT_TRUE(io_thread()->task_runner()->PostTask( |
388 FROM_HERE, | 388 FROM_HERE, |
389 base::Bind(&net::URLFetcherDelegate::OnURLFetchComplete, | 389 base::Bind(&net::URLFetcherDelegate::OnURLFetchComplete, |
390 base::Unretained(delegate), &fetcher))); | 390 base::Unretained(delegate), &fetcher))); |
391 | 391 |
392 // Abort the fetch. This should be smart enough to handle the case where | 392 // Abort the fetch. This should be smart enough to handle the case where |
393 // the bridge is destroyed before the callback scheduled above completes. | 393 // the bridge is destroyed before the callback scheduled above completes. |
394 bridge_for_race_test()->Abort(); | 394 bridge_for_race_test()->Abort(); |
395 | 395 |
396 // Wait until the sync thread releases its ref on the bridge. | 396 // Wait until the sync thread releases its ref on the bridge. |
397 signal_when_released.Wait(); | 397 signal_when_released.Wait(); |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 // Tests RequestContextGetter is properly released on IO thread even when | 439 // Tests RequestContextGetter is properly released on IO thread even when |
440 // IO thread stops before sync thread. | 440 // IO thread stops before sync thread. |
441 TEST_F(SyncHttpBridgeTest, RequestContextGetterReleaseOrder) { | 441 TEST_F(SyncHttpBridgeTest, RequestContextGetterReleaseOrder) { |
442 base::Thread sync_thread("SyncThread"); | 442 base::Thread sync_thread("SyncThread"); |
443 sync_thread.Start(); | 443 sync_thread.Start(); |
444 | 444 |
445 syncer::HttpPostProviderFactory* factory = NULL; | 445 syncer::HttpPostProviderFactory* factory = NULL; |
446 syncer::HttpPostProviderInterface* bridge = NULL; | 446 syncer::HttpPostProviderInterface* bridge = NULL; |
447 | 447 |
448 scoped_refptr<net::URLRequestContextGetter> baseline_context_getter( | 448 scoped_refptr<net::URLRequestContextGetter> baseline_context_getter( |
449 new net::TestURLRequestContextGetter(io_thread()->message_loop_proxy())); | 449 new net::TestURLRequestContextGetter(io_thread()->task_runner())); |
450 | 450 |
451 base::WaitableEvent signal_when_created(false, false); | 451 base::WaitableEvent signal_when_created(false, false); |
452 base::WaitableEvent wait_for_shutdown(false, false); | 452 base::WaitableEvent wait_for_shutdown(false, false); |
453 | 453 |
454 CancelationSignal release_request_context_signal; | 454 CancelationSignal release_request_context_signal; |
455 | 455 |
456 // Create bridge factory and factory on sync thread and wait for the creation | 456 // Create bridge factory and factory on sync thread and wait for the creation |
457 // to finish. | 457 // to finish. |
458 sync_thread.message_loop()->PostTask(FROM_HERE, | 458 sync_thread.message_loop()->PostTask(FROM_HERE, |
459 base::Bind(&HttpBridgeRunOnSyncThread, | 459 base::Bind(&HttpBridgeRunOnSyncThread, |
(...skipping 29 matching lines...) Expand all Loading... |
489 sync_thread.Stop(); | 489 sync_thread.Stop(); |
490 } | 490 } |
491 | 491 |
492 // Attempt to release the URLRequestContextGetter before the HttpBridgeFactory | 492 // Attempt to release the URLRequestContextGetter before the HttpBridgeFactory |
493 // is initialized. | 493 // is initialized. |
494 TEST_F(SyncHttpBridgeTest, EarlyAbortFactory) { | 494 TEST_F(SyncHttpBridgeTest, EarlyAbortFactory) { |
495 // In a real scenario, the following would happen on many threads. For | 495 // In a real scenario, the following would happen on many threads. For |
496 // simplicity, this test uses only one thread. | 496 // simplicity, this test uses only one thread. |
497 | 497 |
498 scoped_refptr<net::URLRequestContextGetter> baseline_context_getter( | 498 scoped_refptr<net::URLRequestContextGetter> baseline_context_getter( |
499 new net::TestURLRequestContextGetter(io_thread()->message_loop_proxy())); | 499 new net::TestURLRequestContextGetter(io_thread()->task_runner())); |
500 CancelationSignal release_request_context_signal; | 500 CancelationSignal release_request_context_signal; |
501 | 501 |
502 // UI Thread: Initialize the HttpBridgeFactory. The next step would be to | 502 // UI Thread: Initialize the HttpBridgeFactory. The next step would be to |
503 // post a task to SBH::Core to have it initialized. | 503 // post a task to SBH::Core to have it initialized. |
504 scoped_ptr<syncer::HttpBridgeFactory> factory( | 504 scoped_ptr<syncer::HttpBridgeFactory> factory( |
505 new HttpBridgeFactory(baseline_context_getter.get(), | 505 new HttpBridgeFactory(baseline_context_getter.get(), |
506 NetworkTimeUpdateCallback(), | 506 NetworkTimeUpdateCallback(), |
507 &release_request_context_signal)); | 507 &release_request_context_signal)); |
508 | 508 |
509 // UI Thread: A very early shutdown request arrives and executes on the UI | 509 // UI Thread: A very early shutdown request arrives and executes on the UI |
510 // thread before the posted sync thread task is run. | 510 // thread before the posted sync thread task is run. |
511 release_request_context_signal.Signal(); | 511 release_request_context_signal.Signal(); |
512 | 512 |
513 // Sync thread: Finally run the posted task, only to find that our | 513 // Sync thread: Finally run the posted task, only to find that our |
514 // HttpBridgeFactory has been neutered. Should not crash. | 514 // HttpBridgeFactory has been neutered. Should not crash. |
515 factory->Init("TestUserAgent"); | 515 factory->Init("TestUserAgent"); |
516 | 516 |
517 // At this point, attempting to use the factory would trigger a crash. Both | 517 // At this point, attempting to use the factory would trigger a crash. Both |
518 // this test and the real world code should make sure this never happens. | 518 // this test and the real world code should make sure this never happens. |
519 }; | 519 }; |
520 | 520 |
521 } // namespace syncer | 521 } // namespace syncer |
OLD | NEW |