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

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

Issue 1246523003: [Sync] Finch Experiment : Enable compression between sync client and server (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update build.gn file Created 5 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
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/metrics/field_trial.h"
5 #include "base/strings/stringprintf.h" 6 #include "base/strings/stringprintf.h"
6 #include "base/synchronization/waitable_event.h" 7 #include "base/synchronization/waitable_event.h"
8 #include "base/test/mock_entropy_provider.h"
7 #include "base/threading/thread.h" 9 #include "base/threading/thread.h"
8 #include "net/http/http_response_headers.h" 10 #include "net/http/http_response_headers.h"
9 #include "net/test/spawned_test_server/spawned_test_server.h" 11 #include "net/test/spawned_test_server/spawned_test_server.h"
10 #include "net/url_request/test_url_fetcher_factory.h" 12 #include "net/url_request/test_url_fetcher_factory.h"
11 #include "net/url_request/url_fetcher_delegate.h" 13 #include "net/url_request/url_fetcher_delegate.h"
12 #include "net/url_request/url_request_test_util.h" 14 #include "net/url_request/url_request_test_util.h"
13 #include "sync/internal_api/public/base/cancelation_signal.h" 15 #include "sync/internal_api/public/base/cancelation_signal.h"
14 #include "sync/internal_api/public/http_bridge.h" 16 #include "sync/internal_api/public/http_bridge.h"
15 #include "testing/gtest/include/gtest/gtest.h" 17 #include "testing/gtest/include/gtest/gtest.h"
18 #include "third_party/zlib/zlib.h"
16 19
17 namespace syncer { 20 namespace syncer {
18 21
19 namespace { 22 namespace {
Alexei Svitkine (slow) 2015/08/03 18:12:30 Nit: Add an empty line after this.
Gang Wu 2015/08/04 22:14:00 Done.
20 // TODO(timsteele): Should use PathService here. See Chromium Issue 3113. 23 // TODO(timsteele): Should use PathService here. See Chromium Issue 3113.
21 const base::FilePath::CharType kDocRoot[] = 24 const base::FilePath::CharType kDocRoot[] =
22 FILE_PATH_LITERAL("chrome/test/data"); 25 FILE_PATH_LITERAL("chrome/test/data");
26
27 // -----------------------------------------------------------------------------
28 // he rest of the code in the anon namespace is copied from
29 // components/metrics/compression_utils.cc
30 // TODO(gangwu): crbug.com/515695. The following codes are copied from
31 // components/metrics/compression_utils.cc, we copied them because if we
32 // reference them, we will get cycle dependency warning. Once the functions
33 // have been moved from //component to //base, we can remove the following
34 // functions.
35 //------------------------------------------------------------------------------
36 // Pass an integer greater than the following get a gzip header instead of a
37 // zlib header when calling deflateInit2() and inflateInit2().
38 const int kWindowBitsToGetGzipHeader = 16;
39
40 // This code is taken almost verbatim from third_party/zlib/uncompr.c. The only
41 // difference is inflateInit2() is called which sets the window bits to be > 16.
42 // That causes a gzip header to be parsed rather than a zlib header.
43 int GzipUncompressHelper(Bytef* dest,
44 uLongf* dest_length,
45 const Bytef* source,
46 uLong source_length) {
47 z_stream stream;
48
49 stream.next_in = bit_cast<Bytef*>(source);
50 stream.avail_in = static_cast<uInt>(source_length);
51 if (static_cast<uLong>(stream.avail_in) != source_length)
52 return Z_BUF_ERROR;
53
54 stream.next_out = dest;
55 stream.avail_out = static_cast<uInt>(*dest_length);
56 if (static_cast<uLong>(stream.avail_out) != *dest_length)
57 return Z_BUF_ERROR;
58
59 stream.zalloc = static_cast<alloc_func>(0);
60 stream.zfree = static_cast<free_func>(0);
61
62 int err = inflateInit2(&stream, MAX_WBITS + kWindowBitsToGetGzipHeader);
63 if (err != Z_OK)
64 return err;
65
66 err = inflate(&stream, Z_FINISH);
67 if (err != Z_STREAM_END) {
68 inflateEnd(&stream);
69 if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
70 return Z_DATA_ERROR;
71 return err;
72 }
73 *dest_length = stream.total_out;
74
75 err = inflateEnd(&stream);
76 return err;
77 }
78
79 // Returns the uncompressed size from GZIP-compressed |compressed_data|.
80 uint32 GetUncompressedSize(const std::string& compressed_data) {
81 // The uncompressed size is stored in the last 4 bytes of |input| in LE.
82 uint32 size;
83 if (compressed_data.length() < sizeof(size))
84 return 0;
85 memcpy(&size, &compressed_data[compressed_data.length() - sizeof(size)],
86 sizeof(size));
87 return base::ByteSwapToLE32(size);
88 }
89
90 bool GzipUncompress(const std::string& input, std::string* output) {
91 std::string uncompressed_output;
92 uLongf uncompressed_size = static_cast<uLongf>(GetUncompressedSize(input));
93 uncompressed_output.resize(uncompressed_size);
94 if (GzipUncompressHelper(bit_cast<Bytef*>(uncompressed_output.data()),
95 &uncompressed_size,
96 bit_cast<const Bytef*>(input.data()),
97 static_cast<uLongf>(input.length())) == Z_OK) {
98 output->swap(uncompressed_output);
99 return true;
100 }
101 return false;
102 }
Alexei Svitkine (slow) 2015/08/03 18:12:30 Nit: Add an empty line after this.
Gang Wu 2015/08/04 22:14:00 Done.
23 } 103 }
Alexei Svitkine (slow) 2015/08/03 18:12:30 Nit: // namespace
Gang Wu 2015/08/04 22:14:00 Done.
24 104
25 const char kUserAgent[] = "user-agent"; 105 const char kUserAgent[] = "user-agent";
26 106
27 class SyncHttpBridgeTest : public testing::Test { 107 class SyncHttpBridgeTest : public testing::Test {
28 public: 108 public:
29 SyncHttpBridgeTest() 109 SyncHttpBridgeTest()
30 : test_server_(net::SpawnedTestServer::TYPE_HTTP, 110 : test_server_(net::SpawnedTestServer::TYPE_HTTP,
31 net::SpawnedTestServer::kLocalhost, 111 net::SpawnedTestServer::kLocalhost,
32 base::FilePath(kDocRoot)), 112 base::FilePath(kDocRoot)),
33 fake_default_request_context_getter_(NULL), 113 fake_default_request_context_getter_(NULL),
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 private: 219 private:
140 ~ShuntedHttpBridge() override {} 220 ~ShuntedHttpBridge() override {}
141 221
142 void CallOnURLFetchComplete() { 222 void CallOnURLFetchComplete() {
143 ASSERT_TRUE(base::MessageLoop::current() == test_->GetIOThreadLoop()); 223 ASSERT_TRUE(base::MessageLoop::current() == test_->GetIOThreadLoop());
144 // We return no cookies and a dummy content response. 224 // We return no cookies and a dummy content response.
145 net::ResponseCookies cookies; 225 net::ResponseCookies cookies;
146 226
147 std::string response_content = "success!"; 227 std::string response_content = "success!";
148 net::TestURLFetcher fetcher(0, GURL("http://www.google.com"), NULL); 228 net::TestURLFetcher fetcher(0, GURL("http://www.google.com"), NULL);
229 scoped_refptr<net::HttpResponseHeaders> response_headers(
230 new net::HttpResponseHeaders(""));
149 fetcher.set_response_code(200); 231 fetcher.set_response_code(200);
150 fetcher.set_cookies(cookies); 232 fetcher.set_cookies(cookies);
151 fetcher.SetResponseString(response_content); 233 fetcher.SetResponseString(response_content);
234 fetcher.set_response_headers(response_headers);
152 OnURLFetchComplete(&fetcher); 235 OnURLFetchComplete(&fetcher);
153 } 236 }
154 SyncHttpBridgeTest* test_; 237 SyncHttpBridgeTest* test_;
155 bool never_finishes_; 238 bool never_finishes_;
156 }; 239 };
157 240
158 void SyncHttpBridgeTest::RunSyncThreadBridgeUseTest( 241 void SyncHttpBridgeTest::RunSyncThreadBridgeUseTest(
159 base::WaitableEvent* signal_when_created, 242 base::WaitableEvent* signal_when_created,
160 base::WaitableEvent* signal_when_released) { 243 base::WaitableEvent* signal_when_released) {
161 scoped_refptr<net::URLRequestContextGetter> ctx_getter( 244 scoped_refptr<net::URLRequestContextGetter> ctx_getter(
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code); 308 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
226 EXPECT_TRUE(success); 309 EXPECT_TRUE(success);
227 EXPECT_EQ(200, response_code); 310 EXPECT_EQ(200, response_code);
228 EXPECT_EQ(0, os_error); 311 EXPECT_EQ(0, os_error);
229 312
230 EXPECT_EQ(payload.length() + 1, 313 EXPECT_EQ(payload.length() + 1,
231 static_cast<size_t>(http_bridge->GetResponseContentLength())); 314 static_cast<size_t>(http_bridge->GetResponseContentLength()));
232 EXPECT_EQ(payload, std::string(http_bridge->GetResponseContent())); 315 EXPECT_EQ(payload, std::string(http_bridge->GetResponseContent()));
233 } 316 }
234 317
318 // Full round-trip test of the HttpBridge with compressed data, check if the
319 // data is correctly compressed.
320 TEST_F(SyncHttpBridgeTest, CompressedRequestPayloadCheck) {
321 ASSERT_TRUE(test_server_.Start());
322
323 scoped_refptr<HttpBridge> http_bridge(BuildBridge());
324
325 std::string payload = "this should be echoed back";
326 GURL echo = test_server_.GetURL("echo");
327 http_bridge->SetURL(echo.spec().c_str(), echo.IntPort());
328 http_bridge->SetPostPayload("application/x-www-form-urlencoded",
329 payload.length(), payload.c_str());
330 int os_error = 0;
331 int response_code = 0;
332 base::FieldTrialList field_trial_list(new base::MockEntropyProvider());
333 base::FieldTrialList::CreateFieldTrial("SyncHttpContentCompression",
334 "Enabled");
335 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
336 EXPECT_TRUE(success);
337 EXPECT_EQ(200, response_code);
338 EXPECT_EQ(0, os_error);
339
340 EXPECT_NE(payload.length() + 1,
341 static_cast<size_t>(http_bridge->GetResponseContentLength()));
342 std::string compressed_payload(http_bridge->GetResponseContent(),
343 http_bridge->GetResponseContentLength());
344 std::string uncompressed_payload;
345 GzipUncompress(compressed_payload, &uncompressed_payload);
346 EXPECT_EQ(payload, uncompressed_payload);
347 }
348
349 // Full round-trip test of the HttpBridge with compression, check if header
350 // fields("Content-Encoding" ,"Accept-Encoding" and user agent) are set
351 // correctly.
352 TEST_F(SyncHttpBridgeTest, CompressedRequestHeaderCheck) {
353 ASSERT_TRUE(test_server_.Start());
354
355 scoped_refptr<HttpBridge> http_bridge(BuildBridge());
356
357 GURL echo_header = test_server_.GetURL("echoall");
358 http_bridge->SetURL(echo_header.spec().c_str(), echo_header.IntPort());
359
360 std::string test_payload = "###TEST PAYLOAD###";
361 http_bridge->SetPostPayload("text/html", test_payload.length() + 1,
362 test_payload.c_str());
363
364 int os_error = 0;
365 int response_code = 0;
366 base::FieldTrialList field_trial_list(new base::MockEntropyProvider());
367 base::FieldTrialList::CreateFieldTrial("SyncHttpContentCompression",
368 "Enabled");
369 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
370 EXPECT_TRUE(success);
371 EXPECT_EQ(200, response_code);
372 EXPECT_EQ(0, os_error);
373
374 std::string response(http_bridge->GetResponseContent(),
375 http_bridge->GetResponseContentLength());
376 EXPECT_NE(std::string::npos, response.find("Content-Encoding: gzip"));
377 EXPECT_NE(std::string::npos, response.find("Accept-Encoding: gzip, deflate"));
378 EXPECT_NE(std::string::npos,
379 response.find(base::StringPrintf(
380 "%s: %s", net::HttpRequestHeaders::kUserAgent, kUserAgent)));
381 }
382
235 // Full round-trip test of the HttpBridge. 383 // Full round-trip test of the HttpBridge.
236 TEST_F(SyncHttpBridgeTest, TestMakeSynchronousPostLiveComprehensive) { 384 TEST_F(SyncHttpBridgeTest, TestMakeSynchronousPostLiveComprehensive) {
237 ASSERT_TRUE(test_server_.Start()); 385 ASSERT_TRUE(test_server_.Start());
238 386
239 scoped_refptr<HttpBridge> http_bridge(BuildBridge()); 387 scoped_refptr<HttpBridge> http_bridge(BuildBridge());
240 388
241 GURL echo_header = test_server_.GetURL("echoall"); 389 GURL echo_header = test_server_.GetURL("echoall");
242 http_bridge->SetURL(echo_header.spec().c_str(), echo_header.IntPort()); 390 http_bridge->SetURL(echo_header.spec().c_str(), echo_header.IntPort());
243 391
244 std::string test_payload = "###TEST PAYLOAD###"; 392 std::string test_payload = "###TEST PAYLOAD###";
245 http_bridge->SetPostPayload("text/html", test_payload.length() + 1, 393 http_bridge->SetPostPayload("text/html", test_payload.length() + 1,
246 test_payload.c_str()); 394 test_payload.c_str());
247 395
248 int os_error = 0; 396 int os_error = 0;
249 int response_code = 0; 397 int response_code = 0;
250 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code); 398 bool success = http_bridge->MakeSynchronousPost(&os_error, &response_code);
251 EXPECT_TRUE(success); 399 EXPECT_TRUE(success);
252 EXPECT_EQ(200, response_code); 400 EXPECT_EQ(200, response_code);
253 EXPECT_EQ(0, os_error); 401 EXPECT_EQ(0, os_error);
254 402
255 std::string response(http_bridge->GetResponseContent(), 403 std::string response(http_bridge->GetResponseContent(),
256 http_bridge->GetResponseContentLength()); 404 http_bridge->GetResponseContentLength());
257 EXPECT_EQ(std::string::npos, response.find("Cookie:")); 405 EXPECT_EQ(std::string::npos, response.find("Cookie:"));
406 EXPECT_NE(std::string::npos, response.find("Accept-Encoding: deflate"));
258 EXPECT_NE(std::string::npos, 407 EXPECT_NE(std::string::npos,
259 response.find(base::StringPrintf("%s: %s", 408 response.find(base::StringPrintf("%s: %s",
260 net::HttpRequestHeaders::kUserAgent, kUserAgent))); 409 net::HttpRequestHeaders::kUserAgent, kUserAgent)));
261 EXPECT_NE(std::string::npos, response.find(test_payload.c_str())); 410 EXPECT_NE(std::string::npos, response.find(test_payload.c_str()));
262 } 411 }
263 412
264 TEST_F(SyncHttpBridgeTest, TestExtraRequestHeaders) { 413 TEST_F(SyncHttpBridgeTest, TestExtraRequestHeaders) {
265 ASSERT_TRUE(test_server_.Start()); 414 ASSERT_TRUE(test_server_.Start());
266 415
267 scoped_refptr<HttpBridge> http_bridge(BuildBridge()); 416 scoped_refptr<HttpBridge> http_bridge(BuildBridge());
(...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 661
513 // Sync thread: Finally run the posted task, only to find that our 662 // Sync thread: Finally run the posted task, only to find that our
514 // HttpBridgeFactory has been neutered. Should not crash. 663 // HttpBridgeFactory has been neutered. Should not crash.
515 factory->Init("TestUserAgent"); 664 factory->Init("TestUserAgent");
516 665
517 // At this point, attempting to use the factory would trigger a crash. Both 666 // 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. 667 // this test and the real world code should make sure this never happens.
519 }; 668 };
520 669
521 } // namespace syncer 670 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698