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

Side by Side Diff: net/simple_request_unittest.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 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
« no previous file with comments | « net/simple_request.cc ('k') | net/urlmon_request.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2007-2010 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15
16 //
17 // Tests Get over http and https, using direct connection and wpad proxy.
18 //
19 // TODO(omaha): missing Post unit tests
20
21 #include <windows.h>
22 #include <winhttp.h>
23 #include <atlstr.h>
24 #include "base/basictypes.h"
25 #include "omaha/base/app_util.h"
26 #include "omaha/base/const_addresses.h"
27 #include "omaha/base/error.h"
28 #include "omaha/base/scope_guard.h"
29 #include "omaha/base/string.h"
30 #include "omaha/net/network_config.h"
31 #include "omaha/net/simple_request.h"
32 #include "omaha/testing/unit_test.h"
33
34 namespace omaha {
35
36 const TCHAR* kBigFileUrl =
37 _T("http://dl.google.com/dl/edgedl/update2/UpdateData_10M.bin");
38
39 DWORD WINAPI PauseAndResumeThreadProc(void* parameter) {
40 SimpleRequest* simple_request = reinterpret_cast<SimpleRequest*>(parameter);
41 ASSERT1(simple_request);
42
43 bool request_paused = false;
44
45 // Loop even times so the download thread won't be blocked by Pause() after
46 // loop exit.
47 for (int i = 0; i < 10; ++i) {
48 ::Sleep(100);
49
50 if (request_paused) {
51 simple_request->Resume();
52 } else {
53 simple_request->Pause();
54 }
55
56 request_paused = !request_paused;
57 }
58
59 return 0;
60 }
61
62 DWORD WINAPI CancelRequestThreadProc(void* parameter) {
63 SimpleRequest* simple_request = reinterpret_cast<SimpleRequest*>(parameter);
64 ASSERT1(simple_request);
65
66 // Wait a short period of time so the download can start. Assumes the file
67 // is large enough so that download will not complete within the sleep time.
68 ::Sleep(500);
69
70 simple_request->Cancel();
71 return 0;
72 }
73
74 class SimpleRequestTest : public testing::Test {
75 protected:
76 SimpleRequestTest() {}
77
78 void SimpleGet(const CString& url, const ProxyConfig& config);
79 void SimpleDownloadFile(const CString& url,
80 const CString& filename,
81 const ProxyConfig& config);
82 void SimpleDownloadFilePauseAndResume(const CString& url,
83 const CString& filename,
84 const ProxyConfig& config);
85 void SimpleDownloadFileCancellation(const CString& filename, bool do_cancel);
86 void SimpleGetHostNotFound(const CString& url, const ProxyConfig& config);
87
88 void SimpleGetFileNotFound(const CString& url, const ProxyConfig& config);
89
90 void SimpleGetRedirect(const CString& url, const ProxyConfig& config);
91
92 void PrepareRequest(const CString& url,
93 const ProxyConfig& config,
94 SimpleRequest* simple_request);
95 };
96
97 void SimpleRequestTest::PrepareRequest(const CString& url,
98 const ProxyConfig& config,
99 SimpleRequest* simple_request) {
100 ASSERT_TRUE(simple_request);
101 NetworkConfig* network_config = NULL;
102 EXPECT_HRESULT_SUCCEEDED(
103 NetworkConfigManager::Instance().GetUserNetworkConfig(&network_config));
104
105 HINTERNET handle = network_config->session().session_handle;
106 simple_request->set_session_handle(handle);
107 simple_request->set_url(url);
108 simple_request->set_proxy_configuration(config);
109
110 CString user_agent_header;
111 user_agent_header.Format(_T("User-Agent: %s\r\n"),
112 simple_request->user_agent());
113 simple_request->set_additional_headers(user_agent_header);
114 }
115
116 void SimpleRequestTest::SimpleGet(const CString& url,
117 const ProxyConfig& config) {
118 SimpleRequest simple_request;
119 PrepareRequest(url, config, &simple_request);
120 EXPECT_HRESULT_SUCCEEDED(simple_request.Send());
121 EXPECT_EQ(HTTP_STATUS_OK, simple_request.GetHttpStatusCode());
122 CString response = Utf8BufferToWideChar(simple_request.GetResponse());
123
124 // robots.txt response contains "User-agent: *". This is not the "User-Agent"
125 // http header.
126 EXPECT_NE(-1, response.Find(_T("User-agent: *")));
127 CString content_type;
128 simple_request.QueryHeadersString(WINHTTP_QUERY_CONTENT_TYPE,
129 NULL, &content_type);
130 EXPECT_STREQ(_T("text/plain"), content_type);
131
132 // Uses custom query for content type and it should match what we just got.
133 CString content_type_from_custom_query;
134 simple_request.QueryHeadersString(WINHTTP_QUERY_CUSTOM,
135 _T("Content-Type"),
136 &content_type_from_custom_query);
137 EXPECT_STREQ(content_type, content_type_from_custom_query);
138
139 EXPECT_FALSE(simple_request.GetResponseHeaders().IsEmpty());
140
141 // Check the user agent went out with the request.
142 CString user_agent;
143 simple_request.QueryHeadersString(
144 WINHTTP_QUERY_FLAG_REQUEST_HEADERS | WINHTTP_QUERY_USER_AGENT,
145 WINHTTP_HEADER_NAME_BY_INDEX,
146 &user_agent);
147 EXPECT_STREQ(simple_request.user_agent(), user_agent);
148 }
149
150 void SimpleRequestTest::SimpleDownloadFile(const CString& url,
151 const CString& filename,
152 const ProxyConfig& config) {
153 SimpleRequest simple_request;
154 PrepareRequest(url, config, &simple_request);
155 simple_request.set_filename(filename);
156
157 EXPECT_HRESULT_SUCCEEDED(simple_request.Send());
158
159 int http_status = simple_request.GetHttpStatusCode();
160 EXPECT_TRUE(http_status == HTTP_STATUS_OK ||
161 http_status == HTTP_STATUS_PARTIAL_CONTENT);
162 }
163
164 void SimpleRequestTest::SimpleDownloadFilePauseAndResume(
165 const CString& url,
166 const CString& filename,
167 const ProxyConfig& config) {
168 const int kNumThreads = 3;
169 const int kMaxWaitTimeMs = 10000;
170 SimpleRequest simple_request;
171 PrepareRequest(url, config, &simple_request);
172 simple_request.set_filename(filename);
173
174 // Testing call Pause before Send.
175 simple_request.Pause();
176 simple_request.Resume();
177 HANDLE pause_and_resume_threads[kNumThreads] = { NULL };
178
179 // Now create some threads to run Pause/Resume in the middle of sending.
180 for (int i = 0; i < kNumThreads; ++i) {
181 pause_and_resume_threads[i] = ::CreateThread(NULL,
182 0,
183 PauseAndResumeThreadProc,
184 &simple_request,
185 0,
186 NULL);
187 EXPECT_TRUE(pause_and_resume_threads[i] != NULL);
188 }
189
190 EXPECT_HRESULT_SUCCEEDED(simple_request.Send());
191
192 int http_status = simple_request.GetHttpStatusCode();
193 EXPECT_TRUE(http_status == HTTP_STATUS_OK ||
194 http_status == HTTP_STATUS_PARTIAL_CONTENT);
195
196 DWORD result = ::WaitForMultipleObjects(arraysize(pause_and_resume_threads),
197 pause_and_resume_threads,
198 true, // Wait all threads to exit.
199 kMaxWaitTimeMs);
200 EXPECT_NE(result, WAIT_FAILED);
201 EXPECT_NE(result, WAIT_TIMEOUT);
202
203 for (int i = 0; i < kNumThreads; ++i) {
204 ::CloseHandle(pause_and_resume_threads[i]);
205 }
206 }
207
208 void SimpleRequestTest::SimpleDownloadFileCancellation(
209 const CString& filename, bool do_cancel) {
210 SimpleRequest simple_request;
211 PrepareRequest(kBigFileUrl, ProxyConfig(), &simple_request);
212 simple_request.set_filename(filename);
213
214 scoped_handle cancel_thread_handle;
215 if (do_cancel) {
216 reset(cancel_thread_handle, ::CreateThread(NULL,
217 0,
218 CancelRequestThreadProc,
219 &simple_request,
220 0, NULL));
221 }
222
223 HRESULT hr = simple_request.Send();
224 if (do_cancel) {
225 EXPECT_TRUE(hr == GOOPDATE_E_CANCELLED || SUCCEEDED(hr));
226 ::WaitForSingleObject(get(cancel_thread_handle), INFINITE);
227 } else {
228 EXPECT_HRESULT_SUCCEEDED(hr);
229 }
230 }
231
232 void SimpleRequestTest::SimpleGetHostNotFound(const CString& url,
233 const ProxyConfig& config) {
234 SimpleRequest simple_request;
235 PrepareRequest(url, config, &simple_request);
236
237 HRESULT hr = simple_request.Send();
238 int status_code = simple_request.GetHttpStatusCode();
239
240 if (config.auto_detect) {
241 // Either a direct connection or a proxy will be used in the case of
242 // proxy auto detect.
243 //
244 // When a proxy is detected, the proxy server can return some html content
245 // indicating an error has occured. The status codes will be different,
246 // depending on how each proxy is configured. This may be a flaky unit test.
247 if (FAILED(hr)) {
248 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_WINHTTP_NAME_NOT_RESOLVED), hr);
249 } else {
250 if (String_StartsWith(url, kHttpsProtoScheme, true)) {
251 EXPECT_EQ(HTTP_STATUS_NOT_FOUND, status_code);
252 } else {
253 EXPECT_EQ(HTTP_STATUS_SERVICE_UNAVAIL, status_code);
254 }
255 }
256 } else {
257 EXPECT_EQ(HRESULT_FROM_WIN32(ERROR_WINHTTP_NAME_NOT_RESOLVED), hr);
258 EXPECT_EQ(0, status_code);
259 }
260 }
261
262 void SimpleRequestTest::SimpleGetFileNotFound(const CString& url,
263 const ProxyConfig& config) {
264 SimpleRequest simple_request;
265 PrepareRequest(url, config, &simple_request);
266 EXPECT_HRESULT_SUCCEEDED(simple_request.Send());
267 EXPECT_EQ(HTTP_STATUS_NOT_FOUND, simple_request.GetHttpStatusCode());
268 }
269
270 void SimpleRequestTest::SimpleGetRedirect(const CString& url,
271 const ProxyConfig& config) {
272 SimpleRequest simple_request;
273 PrepareRequest(url, config, &simple_request);
274 EXPECT_HRESULT_SUCCEEDED(simple_request.Send());
275
276 int http_status = simple_request.GetHttpStatusCode();
277 EXPECT_TRUE(http_status == HTTP_STATUS_OK ||
278 http_status == HTTP_STATUS_PARTIAL_CONTENT);
279 }
280
281 //
282 // http tests.
283 //
284 // http get, direct connection.
285 TEST_F(SimpleRequestTest, HttpGetDirect) {
286 if (IsTestRunByLocalSystem()) {
287 return;
288 }
289
290 SimpleGet(_T("http://www.google.com/robots.txt"), ProxyConfig());
291 }
292
293 // http get, direct connection, download to file
294 TEST_F(SimpleRequestTest, HttpDownloadDirect) {
295 if (IsTestRunByLocalSystem()) {
296 return;
297 }
298
299 CString temp_file;
300 EXPECT_TRUE(::GetTempFileName(app_util::GetModuleDirectory(NULL),
301 _T("SRT"),
302 0,
303 CStrBuf(temp_file, MAX_PATH)));
304 ScopeGuard guard = MakeGuard(::DeleteFile, temp_file);
305
306 SimpleDownloadFile(
307 _T("http://dl.google.com/update2/UpdateData.bin"),
308 temp_file, ProxyConfig());
309 }
310
311 // http get, direct connection, download to file, pause/resume
312 // Download same file twice with and without pause/resume. The downloaded
313 // files should be same.
314 TEST_F(SimpleRequestTest, HttpDownloadDirectPauseAndResume) {
315 if (!ShouldRunLargeTest()) {
316 return;
317 }
318
319 // Download the same URL with and without pause/resume.
320 CString temp_file1;
321 EXPECT_TRUE(::GetTempFileName(app_util::GetModuleDirectory(NULL),
322 _T("SRT"),
323 0,
324 CStrBuf(temp_file1, MAX_PATH)));
325 ScopeGuard guard = MakeGuard(::DeleteFile, temp_file1);
326
327 SimpleDownloadFilePauseAndResume(kBigFileUrl, temp_file1, ProxyConfig());
328
329 CString temp_file2;
330 EXPECT_TRUE(::GetTempFileName(app_util::GetModuleDirectory(NULL),
331 _T("SRT"),
332 0,
333 CStrBuf(temp_file2, MAX_PATH)));
334 ScopeGuard guard2 = MakeGuard(::DeleteFile, temp_file2);
335
336 SimpleDownloadFile(kBigFileUrl, temp_file2, ProxyConfig());
337
338 // Compares that the downloaded files are equal
339 scoped_hfile file_handle1(::CreateFile(temp_file1, GENERIC_READ,
340 FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
341 EXPECT_NE(get(file_handle1), INVALID_HANDLE_VALUE);
342
343 scoped_hfile file_handle2(::CreateFile(temp_file2, GENERIC_READ,
344 FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL));
345
346 // Compare file size
347 DWORD file_size = GetFileSize(get(file_handle1), NULL);
348 EXPECT_EQ(file_size, GetFileSize(get(file_handle2), NULL));
349
350 // Compare file contents
351 const int kBufferLength = 1024;
352 BYTE buffer1[kBufferLength] = {0};
353 BYTE buffer2[kBufferLength] = {0};
354
355 for (int i = static_cast<int>(file_size); i > 0; i -= kBufferLength) {
356 int bytes_to_read = std::min(kBufferLength, i);
357 DWORD num_bytes_got = 0;
358
359 EXPECT_TRUE(ReadFile(get(file_handle1), buffer1,
360 bytes_to_read, &num_bytes_got, NULL));
361 EXPECT_EQ(num_bytes_got, static_cast<DWORD>(bytes_to_read));
362 EXPECT_TRUE(ReadFile(get(file_handle2), buffer2,
363 bytes_to_read, &num_bytes_got, NULL));
364 EXPECT_EQ(num_bytes_got, static_cast<DWORD>(bytes_to_read));
365 EXPECT_EQ(memcmp(buffer1, buffer2, bytes_to_read), 0);
366 }
367
368 // Make sure that file handles are closed first so that the delete guards
369 // can delete the temp files.
370 reset(file_handle1);
371 reset(file_handle2);
372 }
373
374 // http get, direct connection, negative test.
375 TEST_F(SimpleRequestTest, HttpGetDirectHostNotFound) {
376 if (IsTestRunByLocalSystem()) {
377 return;
378 }
379
380 SimpleGetHostNotFound(_T("http://no_such_host.google.com/"), ProxyConfig());
381 }
382
383 // http get, direct connection, negative test.
384 TEST_F(SimpleRequestTest, HttpGetDirectFileNotFound) {
385 if (IsTestRunByLocalSystem()) {
386 return;
387 }
388
389 SimpleGetFileNotFound(_T("http://tools.google.com/no_such_file"),
390 ProxyConfig());
391 }
392
393 // http get, proxy wpad.
394 TEST_F(SimpleRequestTest, HttpGetProxy) {
395 ProxyConfig config;
396 config.auto_detect = true;
397 SimpleGet(_T("http://www.google.com/robots.txt"), config);
398 }
399
400 // http get, proxy wpad, negative test.
401 TEST_F(SimpleRequestTest, HttpGetProxyHostNotFound) {
402 ProxyConfig config;
403 config.auto_detect = true;
404 SimpleGetHostNotFound(_T("http://no_such_host.google.com/"), config);
405 }
406
407 // http get, proxy wpad.
408 TEST_F(SimpleRequestTest, HttpGetProxyFileNotFound) {
409 ProxyConfig config;
410 config.auto_detect = true;
411 SimpleGetFileNotFound(_T("http://tools.google.com/no_such_file"), config);
412 }
413
414
415 //
416 // https tests.
417 //
418 // https get, direct.
419 TEST_F(SimpleRequestTest, HttpsGetDirect) {
420 if (IsTestRunByLocalSystem()) {
421 return;
422 }
423
424 SimpleGet(_T("https://www.google.com/robots.txt"), ProxyConfig());
425 }
426
427 // https get, direct, negative test.
428 TEST_F(SimpleRequestTest, HttpsGetDirectHostNotFound) {
429 SimpleGetHostNotFound(_T("https://no_such_host.google.com/"), ProxyConfig());
430 }
431
432 // https get, direct connection, negative test.
433 TEST_F(SimpleRequestTest, HttpsGetDirectFileNotFound) {
434 if (IsTestRunByLocalSystem()) {
435 return;
436 }
437
438 SimpleGetFileNotFound(_T("https://tools.google.com/no_such_file"),
439 ProxyConfig());
440 }
441
442 // https get, proxy wpad.
443 TEST_F(SimpleRequestTest, HttpsGetProxy) {
444 ProxyConfig config;
445 config.auto_detect = true;
446 SimpleGet(_T("https://www.google.com/robots.txt"), config);
447 }
448
449 // https get, proxy wpad, negative test.
450 TEST_F(SimpleRequestTest, HttpsGetProxyHostNotFound) {
451 ProxyConfig config;
452 config.auto_detect = true;
453 SimpleGetHostNotFound(_T("https://no_such_host.google.com/"), config);
454 }
455
456 // https get, proxy wpad, negative test.
457 TEST_F(SimpleRequestTest, HttpsGetProxyFileNotFound) {
458 ProxyConfig config;
459 config.auto_detect = true;
460 SimpleGetFileNotFound(_T("https://tools.google.com/no_such_file"), config);
461 }
462
463 // Should not be able to reuse the object once canceled, even if closed.
464 TEST_F(SimpleRequestTest, Cancel_CannotReuse) {
465 SimpleRequest simple_request;
466 PrepareRequest(_T("http:\\foo\\"), ProxyConfig(), &simple_request);
467 EXPECT_HRESULT_SUCCEEDED(simple_request.Cancel());
468 EXPECT_EQ(GOOPDATE_E_CANCELLED, simple_request.Send());
469 EXPECT_HRESULT_SUCCEEDED(simple_request.Close());
470 EXPECT_EQ(GOOPDATE_E_CANCELLED, simple_request.Send());
471 }
472
473 TEST_F(SimpleRequestTest, Cancel_ShouldDeleteTempFile) {
474 CString temp_file;
475 EXPECT_TRUE(::GetTempFileName(app_util::GetModuleDirectory(NULL),
476 _T("SRT"),
477 0,
478 CStrBuf(temp_file, MAX_PATH)));
479 ScopeGuard guard = MakeGuard(::DeleteFile, temp_file);
480
481 // Verify that cancellation should remove partially downloaded file.
482 bool do_cancel = true;
483 SimpleDownloadFileCancellation(temp_file, do_cancel);
484 EXPECT_EQ(INVALID_FILE_ATTRIBUTES, ::GetFileAttributes(temp_file));
485 EXPECT_EQ(ERROR_FILE_NOT_FOUND, ::GetLastError());
486
487 if (ShouldRunLargeTest()) {
488 // Verify that target file is preserved if download is not cancelled.
489 do_cancel = false;
490 SimpleDownloadFileCancellation(temp_file, do_cancel);
491 EXPECT_NE(INVALID_FILE_ATTRIBUTES, ::GetFileAttributes(temp_file));
492 }
493 }
494
495 // Http get request should follow redirects. The url below redirects to
496 // https://tools.google.com/service/update2/oneclick and then it returns
497 // 200 OK and some xml body.
498 // TODO(omaha): Pick a new URL since this service is now obsolete and could
499 // be removed at some point.
500 TEST_F(SimpleRequestTest, HttpGet_Redirect) {
501 if (IsTestRunByLocalSystem()) {
502 return;
503 }
504
505 SimpleGetRedirect(_T("http://tools.google.com/service/update2/oneclick"),
506 ProxyConfig());
507 }
508
509 } // namespace omaha
510
OLDNEW
« no previous file with comments | « net/simple_request.cc ('k') | net/urlmon_request.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698