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, &params.response);
81
82  bool result = server.PostBufferToPath(
83      &params, "/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, &params.response);
98
99  signal.Signal();
100  bool result = server.PostBufferToPath(
101      &params, "/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, &params.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      &params, "/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