1// Copyright (c) 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 "sync/internal_api/syncapi_server_connection_manager.h" 6 7#include "base/bind.h" 8#include "base/bind_helpers.h" 9#include "base/compiler_specific.h" 10#include "base/synchronization/waitable_event.h" 11#include "base/test/test_timeouts.h" 12#include "base/threading/thread.h" 13#include "base/time/time.h" 14#include "net/base/net_errors.h" 15#include "sync/internal_api/public/base/cancelation_signal.h" 16#include "sync/internal_api/public/http_post_provider_factory.h" 17#include "sync/internal_api/public/http_post_provider_interface.h" 18#include "testing/gtest/include/gtest/gtest.h" 19 20namespace syncer { 21namespace { 22 23using base::TimeDelta; 24 25class BlockingHttpPost : public HttpPostProviderInterface { 26 public: 27 BlockingHttpPost() : wait_for_abort_(false, false) {} 28 virtual ~BlockingHttpPost() {} 29 30 virtual void SetExtraRequestHeaders(const char* headers) OVERRIDE {} 31 virtual void SetURL(const char* url, int port) OVERRIDE {} 32 virtual void SetPostPayload(const char* content_type, 33 int content_length, 34 const char* content) OVERRIDE {} 35 virtual bool MakeSynchronousPost(int* error_code, int* response_code) 36 OVERRIDE { 37 wait_for_abort_.TimedWait(TestTimeouts::action_max_timeout()); 38 *error_code = net::ERR_ABORTED; 39 return false; 40 } 41 virtual int GetResponseContentLength() const OVERRIDE { 42 return 0; 43 } 44 virtual const char* GetResponseContent() const OVERRIDE { 45 return ""; 46 } 47 virtual const std::string GetResponseHeaderValue( 48 const std::string& name) const OVERRIDE { 49 return std::string(); 50 } 51 virtual void Abort() OVERRIDE { 52 wait_for_abort_.Signal(); 53 } 54 private: 55 base::WaitableEvent wait_for_abort_; 56}; 57 58class BlockingHttpPostFactory : public HttpPostProviderFactory { 59 public: 60 virtual ~BlockingHttpPostFactory() {} 61 virtual void Init(const std::string& user_agent) OVERRIDE {} 62 virtual HttpPostProviderInterface* Create() OVERRIDE { 63 return new BlockingHttpPost(); 64 } 65 virtual void Destroy(HttpPostProviderInterface* http) OVERRIDE { 66 delete static_cast<BlockingHttpPost*>(http); 67 } 68}; 69 70} // namespace 71 72// Ask the ServerConnectionManager to stop before it is created. 73TEST(SyncAPIServerConnectionManagerTest, VeryEarlyAbortPost) { 74 CancelationSignal signal; 75 signal.Signal(); 76 SyncAPIServerConnectionManager server( 77 "server", 0, true, new BlockingHttpPostFactory(), &signal); 78 79 ServerConnectionManager::PostBufferParams params; 80 ScopedServerStatusWatcher watcher(&server, ¶ms.response); 81 82 bool result = server.PostBufferToPath( 83 ¶ms, "/testpath", "testauth", &watcher); 84 85 EXPECT_FALSE(result); 86 EXPECT_EQ(HttpResponse::CONNECTION_UNAVAILABLE, 87 params.response.server_status); 88} 89 90// Ask the ServerConnectionManager to stop before its first request is made. 91TEST(SyncAPIServerConnectionManagerTest, EarlyAbortPost) { 92 CancelationSignal signal; 93 SyncAPIServerConnectionManager server( 94 "server", 0, true, new BlockingHttpPostFactory(), &signal); 95 96 ServerConnectionManager::PostBufferParams params; 97 ScopedServerStatusWatcher watcher(&server, ¶ms.response); 98 99 signal.Signal(); 100 bool result = server.PostBufferToPath( 101 ¶ms, "/testpath", "testauth", &watcher); 102 103 EXPECT_FALSE(result); 104 EXPECT_EQ(HttpResponse::CONNECTION_UNAVAILABLE, 105 params.response.server_status); 106} 107 108// Ask the ServerConnectionManager to stop during a request. 109TEST(SyncAPIServerConnectionManagerTest, AbortPost) { 110 CancelationSignal signal; 111 SyncAPIServerConnectionManager server( 112 "server", 0, true, new BlockingHttpPostFactory(), &signal); 113 114 ServerConnectionManager::PostBufferParams params; 115 ScopedServerStatusWatcher watcher(&server, ¶ms.response); 116 117 base::Thread abort_thread("Test_AbortThread"); 118 ASSERT_TRUE(abort_thread.Start()); 119 abort_thread.message_loop()->PostDelayedTask( 120 FROM_HERE, 121 base::Bind(&CancelationSignal::Signal, 122 base::Unretained(&signal)), 123 TestTimeouts::tiny_timeout()); 124 125 bool result = server.PostBufferToPath( 126 ¶ms, "/testpath", "testauth", &watcher); 127 128 EXPECT_FALSE(result); 129 EXPECT_EQ(HttpResponse::CONNECTION_UNAVAILABLE, 130 params.response.server_status); 131 abort_thread.Stop(); 132} 133 134} // namespace syncer 135