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

Side by Side Diff: sync/internal_api/attachments/attachment_uploader_impl_unittest.cc

Issue 278263003: Add a minimal AttachmentUploaderImpl. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Clean up after self-review. Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 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/public/attachments/attachment_uploader_impl.h"
6
7 #include "base/bind.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/ref_counted_memory.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/threading/non_thread_safe.h"
12 #include "base/threading/thread.h"
13 #include "net/test/embedded_test_server/embedded_test_server.h"
14 #include "net/test/embedded_test_server/http_request.h"
15 #include "net/test/embedded_test_server/http_response.h"
16 #include "net/url_request/url_request_test_util.h"
17 #include "sync/api/attachments/attachment.h"
18 #include "sync/internal_api/public/attachments/attachment_server_url_builder.h"
19 #include "testing/gtest/include/gtest/gtest.h"
20
21 namespace {
22
23 const char kAttachmentData[] = "some data";
24
25 } // namespace
26
27 namespace syncer {
28
29 using net::test_server::BasicHttpResponse;
30 using net::test_server::HttpRequest;
31 using net::test_server::HttpResponse;
32
33 class AttachmentUploaderImplTest;
34 class RequestHandler;
35
36 // Text fixture for AttachmentUploaderImpl test.
37 //
38 // This fixture provides an embedded HTTP server for interacting with
39 // AttachmentUploaderImpl.
40 class AttachmentUploaderImplTest : public testing::Test,
41 public base::NonThreadSafe {
42 public:
43 void OnRequestReceived(const HttpRequest& request);
44
45 protected:
46 AttachmentUploaderImplTest();
47 virtual void SetUp();
48
49 // Run the message loop until UploadDone has been invoked |num_invocations|
50 // times.
51 void RunAndQuitAfter(int num_invocations);
52
53 scoped_ptr<AttachmentUploader>& uploader();
54 const AttachmentUploader::UploadCallback& upload_callback() const;
55 std::vector<HttpRequest>& http_requests_received();
56 std::vector<AttachmentUploader::UploadResult>& upload_results();
57 std::vector<AttachmentId>& updated_attachment_ids();
58
59 private:
60 base::MessageLoopForIO message_loop_;
61 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
62 scoped_ptr<RequestHandler> request_handler_;
63 scoped_ptr<AttachmentServerURLBuilder> url_builder_;
64 scoped_ptr<AttachmentUploader> uploader_;
65 AttachmentUploader::UploadCallback upload_callback_;
66 net::test_server::EmbeddedTestServer server_;
67
68 // Number of times we expect UploadDone to be invoked.
69 int invocations_remaining_;
70 std::vector<HttpRequest> http_requests_received_;
71 std::vector<AttachmentUploader::UploadResult> upload_results_;
72 std::vector<AttachmentId> updated_attachment_ids_;
73
74 private:
75 // An UploadCallback invoked by AttachmentUploaderImpl.
76 void UploadDone(const AttachmentUploader::UploadResult& result,
77 const AttachmentId& updated_attachment_id);
78
79 // Must be last data member.
80 base::WeakPtrFactory<AttachmentUploaderImplTest> weak_ptr_factory_;
81 };
82
83 // Handles HTTP requests received by the EmbeddedTestServer.
84 class RequestHandler : public base::NonThreadSafe {
85 public:
86 // Construct a RequestHandler that will PostTask to |test| using
87 // |test_task_runner|.
88 RequestHandler(
89 const scoped_refptr<base::SingleThreadTaskRunner>& test_task_runner,
90 const base::WeakPtr<AttachmentUploaderImplTest>& test);
91
92 ~RequestHandler();
93
94 scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request);
95
96 private:
97 scoped_refptr<base::SingleThreadTaskRunner> test_task_runner_;
98 base::WeakPtr<AttachmentUploaderImplTest> test_;
99 };
100
101 AttachmentUploaderImplTest::AttachmentUploaderImplTest()
102 : invocations_remaining_(0), weak_ptr_factory_(this) {
103 }
104
105 void AttachmentUploaderImplTest::OnRequestReceived(const HttpRequest& request) {
106 DCHECK(CalledOnValidThread());
107 http_requests_received_.push_back(request);
108 }
109
110 void AttachmentUploaderImplTest::SetUp() {
111 DCHECK(CalledOnValidThread());
112 request_handler_.reset(new RequestHandler(message_loop_.message_loop_proxy(),
113 weak_ptr_factory_.GetWeakPtr()));
114 url_request_context_getter_ =
115 new net::TestURLRequestContextGetter(message_loop_.message_loop_proxy());
116
117 ASSERT_TRUE(server_.InitializeAndWaitUntilReady());
118 server_.RegisterRequestHandler(
119 base::Bind(&RequestHandler::HandleRequest,
120 base::Unretained(request_handler_.get())));
121 url_builder_.reset(new AttachmentServerURLBuilder(
122 AttachmentServerURLBuilder::SCHEME_HTTP, "localhost", server_.port()));
123 uploader().reset(
124 new AttachmentUploaderImpl(*url_builder_, url_request_context_getter_));
125 upload_callback_ = base::Bind(&AttachmentUploaderImplTest::UploadDone,
126 base::Unretained(this));
127 }
128
129 void AttachmentUploaderImplTest::RunAndQuitAfter(int num_invocations) {
130 invocations_remaining_ = num_invocations;
131 message_loop_.Run();
132 }
133
134 scoped_ptr<AttachmentUploader>& AttachmentUploaderImplTest::uploader() {
135 return uploader_;
136 }
137
138 const AttachmentUploader::UploadCallback&
139 AttachmentUploaderImplTest::upload_callback() const {
140 return upload_callback_;
141 }
142
143 std::vector<HttpRequest>& AttachmentUploaderImplTest::http_requests_received() {
144 return http_requests_received_;
145 }
146
147 std::vector<AttachmentUploader::UploadResult>&
148 AttachmentUploaderImplTest::upload_results() {
149 return upload_results_;
150 }
151
152 std::vector<AttachmentId>&
153 AttachmentUploaderImplTest::updated_attachment_ids() {
154 return updated_attachment_ids_;
155 }
156
157 void AttachmentUploaderImplTest::UploadDone(
158 const AttachmentUploader::UploadResult& result,
159 const AttachmentId& updated_attachment_id) {
160 DCHECK(CalledOnValidThread());
161 upload_results_.push_back(result);
162 updated_attachment_ids_.push_back(updated_attachment_id);
163 --invocations_remaining_;
164 if (invocations_remaining_ == 0) {
165 base::MessageLoop::current()->Quit();
166 }
167 }
168
169 RequestHandler::RequestHandler(
170 const scoped_refptr<base::SingleThreadTaskRunner>& test_task_runner,
171 const base::WeakPtr<AttachmentUploaderImplTest>& test)
172 : test_task_runner_(test_task_runner), test_(test) {
173 DetachFromThread();
174 }
175
176 RequestHandler::~RequestHandler() {
177 DetachFromThread();
178 }
179
180 scoped_ptr<HttpResponse> RequestHandler::HandleRequest(
181 const HttpRequest& request) {
182 DCHECK(CalledOnValidThread());
183 test_task_runner_->PostTask(
184 FROM_HERE,
185 base::Bind(
186 &AttachmentUploaderImplTest::OnRequestReceived, test_, request));
187 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse);
188 http_response->set_code(net::HTTP_OK);
189 http_response->set_content("hello");
190 http_response->set_content_type("text/plain");
191 return http_response.PassAs<HttpResponse>();
192 }
193
194 // Verify the "happy case" of uploading an attachment.
195 TEST_F(AttachmentUploaderImplTest, UploadAttachment_HappyCase) {
196 scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
197 some_data->data() = kAttachmentData;
198 Attachment attachment = Attachment::Create(some_data);
199 uploader()->UploadAttachment(attachment, upload_callback());
200 RunAndQuitAfter(1);
201
202 // See that the HTTP server received one request.
203 EXPECT_EQ(1U, http_requests_received().size());
204 const HttpRequest& http_request = http_requests_received().front();
205 EXPECT_EQ(net::test_server::METHOD_POST, http_request.method);
206 EXPECT_TRUE(http_request.has_content);
207 EXPECT_EQ(kAttachmentData, http_request.content);
208
209 // See that the UploadCallback received a result and updated AttachmentId.
210 EXPECT_EQ(1U, upload_results().size());
211 EXPECT_EQ(1U, updated_attachment_ids().size());
212 EXPECT_EQ(AttachmentUploader::UPLOAD_SUCCESS, upload_results().front());
213 EXPECT_EQ(attachment.GetId(), updated_attachment_ids().front());
214 // TODO(maniscalco): Once AttachmentUploaderImpl is capable of updating the
215 // AttachmentId with server address information about the attachment, add some
216 // checks here to verify it works properly (bug 371522).
217 }
218
219 // Verify two calls to upload the same attachment result in only one HTTP
220 // request.
221 TEST_F(AttachmentUploaderImplTest, UploadAttachment_Collapse) {
222 scoped_refptr<base::RefCountedString> some_data(new base::RefCountedString);
223 some_data->data() = kAttachmentData;
224 Attachment attachment1 = Attachment::Create(some_data);
225 Attachment attachment2 = attachment1;
226 uploader()->UploadAttachment(attachment1, upload_callback());
227 uploader()->UploadAttachment(attachment2, upload_callback());
228 // Wait for upload_callback() to be invoked twice.
229 RunAndQuitAfter(2);
230 // See there was only one request.
231 EXPECT_EQ(1U, http_requests_received().size());
232 }
233
234 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698