1 /* 2 * Unit test suite for Background Copy Job Interface 3 * 4 * Copyright 2007 Google (Roy Shea) 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include <stdio.h> 22 23 #define COBJMACROS 24 25 #include "wine/test.h" 26 #include "bits.h" 27 #include "initguid.h" 28 #include "bits2_0.h" 29 #include "bits2_5.h" 30 31 /* Globals used by many tests */ 32 static const WCHAR test_displayName[] = {'T', 'e', 's', 't', 0}; 33 static WCHAR test_remotePathA[MAX_PATH]; 34 static WCHAR test_remotePathB[MAX_PATH]; 35 static WCHAR test_localPathA[MAX_PATH]; 36 static WCHAR test_localPathB[MAX_PATH]; 37 static IBackgroundCopyManager *test_manager; 38 static IBackgroundCopyJob *test_job; 39 static GUID test_jobId; 40 static BG_JOB_TYPE test_type; 41 42 static HRESULT test_create_manager(void) 43 { 44 HRESULT hres; 45 IBackgroundCopyManager *manager = NULL; 46 47 /* Creating BITS instance */ 48 hres = CoCreateInstance(&CLSID_BackgroundCopyManager, NULL, CLSCTX_LOCAL_SERVER, 49 &IID_IBackgroundCopyManager, (void **) &manager); 50 51 if(hres == HRESULT_FROM_WIN32(ERROR_SERVICE_DISABLED)) { 52 win_skip("Needed Service is disabled\n"); 53 return hres; 54 } 55 56 if (hres == S_OK) 57 IBackgroundCopyManager_Release(manager); 58 59 return hres; 60 } 61 62 static void init_paths(void) 63 { 64 WCHAR tmpDir[MAX_PATH]; 65 WCHAR prefix[] = {'q', 'm', 'g', 'r', 0}; 66 67 GetTempPathW(MAX_PATH, tmpDir); 68 69 GetTempFileNameW(tmpDir, prefix, 0, test_localPathA); 70 GetTempFileNameW(tmpDir, prefix, 0, test_localPathB); 71 GetTempFileNameW(tmpDir, prefix, 0, test_remotePathA); 72 GetTempFileNameW(tmpDir, prefix, 0, test_remotePathB); 73 } 74 75 /* Generic test setup */ 76 static BOOL setup(void) 77 { 78 HRESULT hres; 79 80 test_manager = NULL; 81 test_job = NULL; 82 memset(&test_jobId, 0, sizeof test_jobId); 83 test_type = BG_JOB_TYPE_DOWNLOAD; 84 85 hres = CoCreateInstance(&CLSID_BackgroundCopyManager, NULL, 86 CLSCTX_LOCAL_SERVER, 87 &IID_IBackgroundCopyManager, 88 (void **) &test_manager); 89 if(hres != S_OK) 90 return FALSE; 91 92 hres = IBackgroundCopyManager_CreateJob(test_manager, test_displayName, 93 test_type, &test_jobId, &test_job); 94 if(hres != S_OK) 95 { 96 IBackgroundCopyManager_Release(test_manager); 97 return FALSE; 98 } 99 100 return TRUE; 101 } 102 103 /* Generic test cleanup */ 104 static void teardown(void) 105 { 106 IBackgroundCopyJob_Cancel(test_job); 107 IBackgroundCopyJob_Release(test_job); 108 IBackgroundCopyManager_Release(test_manager); 109 } 110 111 static BOOL check_bits20(void) 112 { 113 HRESULT hres; 114 IBackgroundCopyManager *manager; 115 IBackgroundCopyJob *job, *job3; 116 117 hres = CoCreateInstance(&CLSID_BackgroundCopyManager, NULL, 118 CLSCTX_LOCAL_SERVER, &IID_IBackgroundCopyManager, 119 (void **)&manager); 120 if (hres != S_OK) return FALSE; 121 122 hres = IBackgroundCopyManager_CreateJob(manager, test_displayName, test_type, &test_jobId, &job); 123 if (hres != S_OK) 124 { 125 IBackgroundCopyManager_Release(manager); 126 return FALSE; 127 } 128 129 hres = IBackgroundCopyJob_QueryInterface(job, &IID_IBackgroundCopyJob3, (void **)&job3); 130 IBackgroundCopyJob_Cancel(job); 131 IBackgroundCopyJob_Release(job); 132 if (hres != S_OK) 133 { 134 IBackgroundCopyManager_Release(manager); 135 return FALSE; 136 } 137 138 IBackgroundCopyJob_Release(job3); 139 IBackgroundCopyManager_Release(manager); 140 return TRUE; 141 } 142 143 static BOOL check_bits25(void) 144 { 145 HRESULT hres; 146 IBackgroundCopyManager *manager; 147 IBackgroundCopyJob *job; 148 IBackgroundCopyJobHttpOptions *options; 149 150 hres = CoCreateInstance(&CLSID_BackgroundCopyManager, NULL, 151 CLSCTX_LOCAL_SERVER, &IID_IBackgroundCopyManager, 152 (void **)&manager); 153 if (hres != S_OK) return FALSE; 154 155 hres = IBackgroundCopyManager_CreateJob(manager, test_displayName, test_type, &test_jobId, &job); 156 if (hres != S_OK) 157 { 158 IBackgroundCopyManager_Release(manager); 159 return FALSE; 160 } 161 162 hres = IBackgroundCopyJob_QueryInterface(job, &IID_IBackgroundCopyJobHttpOptions, (void **)&options); 163 IBackgroundCopyJob_Cancel(job); 164 IBackgroundCopyJob_Release(job); 165 if (hres != S_OK) 166 { 167 IBackgroundCopyManager_Release(manager); 168 return FALSE; 169 } 170 171 IBackgroundCopyJobHttpOptions_Release(options); 172 IBackgroundCopyManager_Release(manager); 173 return TRUE; 174 } 175 176 /* Test that the jobId is properly set */ 177 static void test_GetId(void) 178 { 179 HRESULT hres; 180 GUID tmpId; 181 182 hres = IBackgroundCopyJob_GetId(test_job, &tmpId); 183 ok(hres == S_OK, "GetId failed: %08x\n", hres); 184 ok(memcmp(&tmpId, &test_jobId, sizeof tmpId) == 0, "Got incorrect GUID\n"); 185 } 186 187 /* Test that the type is properly set */ 188 static void test_GetType(void) 189 { 190 HRESULT hres; 191 BG_JOB_TYPE type; 192 193 hres = IBackgroundCopyJob_GetType(test_job, &type); 194 ok(hres == S_OK, "GetType failed: %08x\n", hres); 195 ok(type == test_type, "Got incorrect type\n"); 196 } 197 198 /* Test that the display name is properly set */ 199 static void test_GetName(void) 200 { 201 HRESULT hres; 202 LPWSTR displayName; 203 204 hres = IBackgroundCopyJob_GetDisplayName(test_job, &displayName); 205 ok(hres == S_OK, "GetName failed: %08x\n", hres); 206 ok(lstrcmpW(displayName, test_displayName) == 0, "Got incorrect type\n"); 207 CoTaskMemFree(displayName); 208 } 209 210 /* Test adding a file */ 211 static void test_AddFile(void) 212 { 213 HRESULT hres; 214 215 hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathA, 216 test_localPathA); 217 ok(hres == S_OK, "First call to AddFile failed: 0x%08x\n", hres); 218 219 hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathB, 220 test_localPathB); 221 ok(hres == S_OK, "Second call to AddFile failed: 0x%08x\n", hres); 222 } 223 224 /* Test adding a set of files */ 225 static void test_AddFileSet(void) 226 { 227 HRESULT hres; 228 BG_FILE_INFO files[2] = 229 { 230 {test_remotePathA, test_localPathA}, 231 {test_remotePathB, test_localPathB} 232 }; 233 hres = IBackgroundCopyJob_AddFileSet(test_job, 2, files); 234 ok(hres == S_OK, "AddFileSet failed: 0x%08x\n", hres); 235 } 236 237 /* Test creation of a job enumerator */ 238 static void test_EnumFiles(void) 239 { 240 HRESULT hres; 241 IEnumBackgroundCopyFiles *enumFiles; 242 ULONG res; 243 244 hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathA, 245 test_localPathA); 246 ok(hres == S_OK, "got 0x%08x\n", hres); 247 248 hres = IBackgroundCopyJob_EnumFiles(test_job, &enumFiles); 249 ok(hres == S_OK, "EnumFiles failed: 0x%08x\n", hres); 250 251 res = IEnumBackgroundCopyFiles_Release(enumFiles); 252 ok(res == 0, "Bad ref count on release: %u\n", res); 253 } 254 255 /* Test getting job progress */ 256 static void test_GetProgress_preTransfer(void) 257 { 258 HRESULT hres; 259 BG_JOB_PROGRESS progress; 260 261 hres = IBackgroundCopyJob_GetProgress(test_job, &progress); 262 ok(hres == S_OK, "GetProgress failed: 0x%08x\n", hres); 263 264 ok(progress.BytesTotal == 0, "Incorrect BytesTotal: %s\n", 265 wine_dbgstr_longlong(progress.BytesTotal)); 266 ok(progress.BytesTransferred == 0, "Incorrect BytesTransferred: %s\n", 267 wine_dbgstr_longlong(progress.BytesTransferred)); 268 ok(progress.FilesTotal == 0, "Incorrect FilesTotal: %u\n", progress.FilesTotal); 269 ok(progress.FilesTransferred == 0, "Incorrect FilesTransferred %u\n", progress.FilesTransferred); 270 } 271 272 /* Test getting job state */ 273 static void test_GetState(void) 274 { 275 HRESULT hres; 276 BG_JOB_STATE state; 277 278 state = BG_JOB_STATE_ERROR; 279 hres = IBackgroundCopyJob_GetState(test_job, &state); 280 ok(hres == S_OK, "GetState failed: 0x%08x\n", hres); 281 ok(state == BG_JOB_STATE_SUSPENDED, "Incorrect job state: %d\n", state); 282 } 283 284 /* Test resuming a job */ 285 static void test_ResumeEmpty(void) 286 { 287 HRESULT hres; 288 BG_JOB_STATE state; 289 290 hres = IBackgroundCopyJob_Resume(test_job); 291 ok(hres == BG_E_EMPTY, "Resume failed to return BG_E_EMPTY error: 0x%08x\n", hres); 292 293 state = BG_JOB_STATE_ERROR; 294 hres = IBackgroundCopyJob_GetState(test_job, &state); 295 ok(hres == S_OK, "got 0x%08x\n", hres); 296 ok(state == BG_JOB_STATE_SUSPENDED, "Incorrect job state: %d\n", state); 297 } 298 299 static void makeFile(WCHAR *name, const char *contents) 300 { 301 HANDLE file; 302 DWORD w, len = strlen(contents); 303 304 DeleteFileW(name); 305 file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 306 FILE_ATTRIBUTE_NORMAL, NULL); 307 ok(file != INVALID_HANDLE_VALUE, "CreateFile\n"); 308 ok(WriteFile(file, contents, len, &w, NULL), "WriteFile\n"); 309 CloseHandle(file); 310 } 311 312 static void compareFiles(WCHAR *n1, WCHAR *n2) 313 { 314 char b1[256]; 315 char b2[256]; 316 DWORD s1, s2; 317 HANDLE f1, f2; 318 319 f1 = CreateFileW(n1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 320 FILE_ATTRIBUTE_NORMAL, NULL); 321 ok(f1 != INVALID_HANDLE_VALUE, "CreateFile\n"); 322 323 f2 = CreateFileW(n2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 324 FILE_ATTRIBUTE_NORMAL, NULL); 325 ok(f2 != INVALID_HANDLE_VALUE, "CreateFile\n"); 326 327 /* Neither of these files is very big */ 328 ok(ReadFile(f1, b1, sizeof b1, &s1, NULL), "ReadFile\n"); 329 ok(ReadFile(f2, b2, sizeof b2, &s2, NULL), "ReadFile\n"); 330 331 CloseHandle(f1); 332 CloseHandle(f2); 333 334 ok(s1 == s2, "Files differ in length\n"); 335 ok(memcmp(b1, b2, s1) == 0, "Files differ in contents\n"); 336 } 337 338 /* Test a complete transfer for local files */ 339 static void test_CompleteLocal(void) 340 { 341 static const int timeout_sec = 30; 342 HRESULT hres; 343 BG_JOB_STATE state; 344 int i; 345 346 DeleteFileW(test_localPathA); 347 DeleteFileW(test_localPathB); 348 makeFile(test_remotePathA, "This is a WINE test file for BITS\n"); 349 makeFile(test_remotePathB, "This is another WINE test file for BITS\n"); 350 351 hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathA, 352 test_localPathA); 353 ok(hres == S_OK, "got 0x%08x\n", hres); 354 355 hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathB, 356 test_localPathB); 357 ok(hres == S_OK, "got 0x%08x\n", hres); 358 359 hres = IBackgroundCopyJob_Resume(test_job); 360 ok(hres == S_OK, "IBackgroundCopyJob_Resume\n"); 361 362 disable_success_count 363 for (i = 0; i < timeout_sec; ++i) 364 { 365 hres = IBackgroundCopyJob_GetState(test_job, &state); 366 ok(hres == S_OK, "IBackgroundCopyJob_GetState\n"); 367 ok(state == BG_JOB_STATE_QUEUED || state == BG_JOB_STATE_CONNECTING 368 || state == BG_JOB_STATE_TRANSFERRING || state == BG_JOB_STATE_TRANSFERRED, 369 "Bad state: %d\n", state); 370 if (state == BG_JOB_STATE_TRANSFERRED) 371 break; 372 Sleep(1000); 373 } 374 375 ok(i < timeout_sec, "BITS jobs timed out\n"); 376 hres = IBackgroundCopyJob_Complete(test_job); 377 ok(hres == S_OK, "IBackgroundCopyJob_Complete\n"); 378 hres = IBackgroundCopyJob_GetState(test_job, &state); 379 ok(hres == S_OK, "IBackgroundCopyJob_GetState\n"); 380 ok(state == BG_JOB_STATE_ACKNOWLEDGED, "Bad state: %d\n", state); 381 382 compareFiles(test_remotePathA, test_localPathA); 383 compareFiles(test_remotePathB, test_localPathB); 384 385 ok(DeleteFileW(test_remotePathA), "DeleteFile\n"); 386 ok(DeleteFileW(test_remotePathB), "DeleteFile\n"); 387 DeleteFileW(test_localPathA); 388 DeleteFileW(test_localPathB); 389 } 390 391 /* Test a complete transfer for local files */ 392 static void test_CompleteLocalURL(void) 393 { 394 static const WCHAR prot[] = {'f','i','l','e',':','/','/', 0}; 395 static const int timeout_sec = 30; 396 WCHAR *urlA, *urlB; 397 HRESULT hres; 398 BG_JOB_STATE state; 399 int i; 400 401 DeleteFileW(test_localPathA); 402 DeleteFileW(test_localPathB); 403 makeFile(test_remotePathA, "This is a WINE test file for BITS\n"); 404 makeFile(test_remotePathB, "This is another WINE test file for BITS\n"); 405 406 urlA = HeapAlloc(GetProcessHeap(), 0, 407 (7 + lstrlenW(test_remotePathA) + 1) * sizeof urlA[0]); 408 urlB = HeapAlloc(GetProcessHeap(), 0, 409 (7 + lstrlenW(test_remotePathB) + 1) * sizeof urlB[0]); 410 if (!urlA || !urlB) 411 { 412 skip("Unable to allocate memory for URLs\n"); 413 HeapFree(GetProcessHeap(), 0, urlA); 414 HeapFree(GetProcessHeap(), 0, urlB); 415 return; 416 } 417 418 lstrcpyW(urlA, prot); 419 lstrcatW(urlA, test_remotePathA); 420 lstrcpyW(urlB, prot); 421 lstrcatW(urlB, test_remotePathB); 422 423 hres = IBackgroundCopyJob_AddFile(test_job, urlA, test_localPathA); 424 ok(hres == S_OK, "got 0x%08x\n", hres); 425 426 hres = IBackgroundCopyJob_AddFile(test_job, urlB, test_localPathB); 427 ok(hres == S_OK, "got 0x%08x\n", hres); 428 429 hres = IBackgroundCopyJob_Resume(test_job); 430 ok(hres == S_OK, "IBackgroundCopyJob_Resume\n"); 431 432 disable_success_count 433 for (i = 0; i < timeout_sec; ++i) 434 { 435 hres = IBackgroundCopyJob_GetState(test_job, &state); 436 ok(hres == S_OK, "IBackgroundCopyJob_GetState\n"); 437 ok(state == BG_JOB_STATE_QUEUED || state == BG_JOB_STATE_CONNECTING 438 || state == BG_JOB_STATE_TRANSFERRING || state == BG_JOB_STATE_TRANSFERRED, 439 "Bad state: %d\n", state); 440 if (state == BG_JOB_STATE_TRANSFERRED) 441 break; 442 Sleep(1000); 443 } 444 445 ok(i < timeout_sec, "BITS jobs timed out\n"); 446 hres = IBackgroundCopyJob_Complete(test_job); 447 ok(hres == S_OK, "IBackgroundCopyJob_Complete\n"); 448 hres = IBackgroundCopyJob_GetState(test_job, &state); 449 ok(hres == S_OK, "IBackgroundCopyJob_GetState\n"); 450 ok(state == BG_JOB_STATE_ACKNOWLEDGED, "Bad state: %d\n", state); 451 452 compareFiles(test_remotePathA, test_localPathA); 453 compareFiles(test_remotePathB, test_localPathB); 454 455 ok(DeleteFileW(test_remotePathA), "DeleteFile\n"); 456 ok(DeleteFileW(test_remotePathB), "DeleteFile\n"); 457 DeleteFileW(test_localPathA); 458 DeleteFileW(test_localPathB); 459 460 HeapFree(GetProcessHeap(), 0, urlA); 461 HeapFree(GetProcessHeap(), 0, urlB); 462 } 463 464 static void test_NotifyFlags(void) 465 { 466 ULONG flags; 467 HRESULT hr; 468 469 /* check default flags */ 470 flags = 0; 471 hr = IBackgroundCopyJob_GetNotifyFlags(test_job, &flags); 472 ok(hr == S_OK, "got 0x%08x\n", hr); 473 ok(flags == (BG_NOTIFY_JOB_ERROR | BG_NOTIFY_JOB_TRANSFERRED), "flags 0x%08x\n", flags); 474 } 475 476 static void test_NotifyInterface(void) 477 { 478 HRESULT hr; 479 IUnknown *unk; 480 481 unk = (IUnknown*)0xdeadbeef; 482 hr = IBackgroundCopyJob_GetNotifyInterface(test_job, &unk); 483 ok(hr == S_OK, "got 0x%08x\n", hr); 484 ok(unk == NULL, "got %p\n", unk); 485 } 486 487 static void test_Cancel(void) 488 { 489 HRESULT hr; 490 BG_JOB_STATE state; 491 492 state = BG_JOB_STATE_ERROR; 493 hr = IBackgroundCopyJob_GetState(test_job, &state); 494 ok(hr == S_OK, "got 0x%08x\n", hr); 495 ok(state != BG_JOB_STATE_CANCELLED, "got %u\n", state); 496 497 hr = IBackgroundCopyJob_Cancel(test_job); 498 ok(hr == S_OK, "got 0x%08x\n", hr); 499 500 state = BG_JOB_STATE_ERROR; 501 hr = IBackgroundCopyJob_GetState(test_job, &state); 502 ok(hr == S_OK, "got 0x%08x\n", hr); 503 ok(state == BG_JOB_STATE_CANCELLED, "got %u\n", state); 504 505 hr = IBackgroundCopyJob_Cancel(test_job); 506 ok(hr == BG_E_INVALID_STATE, "got 0x%08x\n", hr); 507 } 508 509 static void test_HttpOptions(void) 510 { 511 static const WCHAR urlW[] = 512 {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g','/',0}; 513 static const WCHAR winetestW[] = 514 {'W','i','n','e',':',' ','t','e','s','t','\r','\n',0}; 515 static const unsigned int timeout = 30; 516 HRESULT hr; 517 IBackgroundCopyJobHttpOptions *options; 518 IBackgroundCopyError *error; 519 BG_JOB_STATE state; 520 unsigned int i; 521 WCHAR *headers; 522 ULONG flags, orig_flags; 523 524 DeleteFileW(test_localPathA); 525 hr = IBackgroundCopyJob_AddFile(test_job, urlW, test_localPathA); 526 ok(hr == S_OK, "got 0x%08x\n", hr); 527 528 hr = IBackgroundCopyJob_QueryInterface(test_job, &IID_IBackgroundCopyJobHttpOptions, (void **)&options); 529 ok(hr == S_OK, "got 0x%08x\n", hr); 530 531 if (options) 532 { 533 headers = (WCHAR *)0xdeadbeef; 534 hr = IBackgroundCopyJobHttpOptions_GetCustomHeaders(options, &headers); 535 ok(hr == S_FALSE, "got 0x%08x\n", hr); 536 ok(headers == NULL, "got %p\n", headers); 537 538 hr = IBackgroundCopyJobHttpOptions_SetCustomHeaders(options, winetestW); 539 ok(hr == S_OK, "got 0x%08x\n", hr); 540 541 headers = (WCHAR *)0xdeadbeef; 542 hr = IBackgroundCopyJobHttpOptions_GetCustomHeaders(options, &headers); 543 ok(hr == S_OK, "got 0x%08x\n", hr); 544 if (hr == S_OK) 545 { 546 ok(!lstrcmpW(headers, winetestW), "got %s\n", wine_dbgstr_w(headers)); 547 CoTaskMemFree(headers); 548 } 549 550 hr = IBackgroundCopyJobHttpOptions_SetCustomHeaders(options, NULL); 551 ok(hr == S_OK, "got 0x%08x\n", hr); 552 553 headers = (WCHAR *)0xdeadbeef; 554 hr = IBackgroundCopyJobHttpOptions_GetCustomHeaders(options, &headers); 555 ok(hr == S_FALSE, "got 0x%08x\n", hr); 556 ok(headers == NULL, "got %p\n", headers); 557 558 orig_flags = 0xdeadbeef; 559 hr = IBackgroundCopyJobHttpOptions_GetSecurityFlags(options, &orig_flags); 560 ok(hr == S_OK, "got 0x%08x\n", hr); 561 ok(!orig_flags, "got 0x%08x\n", orig_flags); 562 563 hr = IBackgroundCopyJobHttpOptions_SetSecurityFlags(options, 0); 564 ok(hr == S_OK, "got 0x%08x\n", hr); 565 566 flags = 0xdeadbeef; 567 hr = IBackgroundCopyJobHttpOptions_GetSecurityFlags(options, &flags); 568 ok(hr == S_OK, "got 0x%08x\n", hr); 569 ok(!flags, "got 0x%08x\n", flags); 570 } 571 572 hr = IBackgroundCopyJob_Resume(test_job); 573 ok(hr == S_OK, "got 0x%08x\n", hr); 574 575 disable_success_count 576 for (i = 0; i < timeout; i++) 577 { 578 hr = IBackgroundCopyJob_GetState(test_job, &state); 579 ok(hr == S_OK, "got 0x%08x\n", hr); 580 581 ok(state == BG_JOB_STATE_QUEUED || 582 state == BG_JOB_STATE_CONNECTING || 583 state == BG_JOB_STATE_TRANSFERRING || 584 state == BG_JOB_STATE_TRANSFERRED, "unexpected state: %u\n", state); 585 586 if (state == BG_JOB_STATE_TRANSFERRED) break; 587 Sleep(1000); 588 } 589 ok(i < timeout, "BITS job timed out\n"); 590 if (i < timeout) 591 { 592 hr = IBackgroundCopyJob_GetError(test_job, &error); 593 ok(hr == BG_E_ERROR_INFORMATION_UNAVAILABLE, "got 0x%08x\n", hr); 594 } 595 596 if (options) 597 { 598 headers = (WCHAR *)0xdeadbeef; 599 hr = IBackgroundCopyJobHttpOptions_GetCustomHeaders(options, &headers); 600 ok(hr == S_FALSE, "got 0x%08x\n", hr); 601 ok(headers == NULL, "got %p\n", headers); 602 603 hr = IBackgroundCopyJobHttpOptions_SetCustomHeaders(options, NULL); 604 ok(hr == S_OK, "got 0x%08x\n", hr); 605 606 hr = IBackgroundCopyJobHttpOptions_GetCustomHeaders(options, &headers); 607 ok(hr == S_FALSE, "got 0x%08x\n", hr); 608 609 flags = 0xdeadbeef; 610 hr = IBackgroundCopyJobHttpOptions_GetSecurityFlags(options, &flags); 611 ok(hr == S_OK, "got 0x%08x\n", hr); 612 ok(!flags, "got 0x%08x\n", flags); 613 614 hr = IBackgroundCopyJobHttpOptions_SetSecurityFlags(options, orig_flags); 615 ok(hr == S_OK, "got 0x%08x\n", hr); 616 617 IBackgroundCopyJobHttpOptions_Release(options); 618 } 619 620 hr = IBackgroundCopyJob_Complete(test_job); 621 ok(hr == S_OK, "got 0x%08x\n", hr); 622 623 hr = IBackgroundCopyJob_GetState(test_job, &state); 624 ok(hr == S_OK, "got 0x%08x\n", hr); 625 ok(state == BG_JOB_STATE_ACKNOWLEDGED, "unexpected state: %u\n", state); 626 627 hr = IBackgroundCopyJob_Complete(test_job); 628 ok(hr == BG_E_INVALID_STATE, "got 0x%08x\n", hr); 629 630 DeleteFileW(test_localPathA); 631 } 632 633 typedef void (*test_t)(void); 634 635 START_TEST(job) 636 { 637 static const test_t tests[] = { 638 test_GetId, 639 test_GetType, 640 test_GetName, 641 test_GetProgress_preTransfer, 642 test_GetState, 643 test_ResumeEmpty, 644 test_NotifyFlags, 645 test_NotifyInterface, 646 0 647 }; 648 static const test_t tests_bits20[] = { 649 test_AddFile, 650 test_AddFileSet, 651 test_EnumFiles, 652 test_CompleteLocal, 653 test_CompleteLocalURL, 654 test_Cancel, /* must be last */ 655 0 656 }; 657 static const test_t tests_bits25[] = { 658 test_HttpOptions, 659 0 660 }; 661 const test_t *test; 662 int i; 663 664 init_paths(); 665 666 CoInitialize(NULL); 667 668 if (FAILED(test_create_manager())) 669 { 670 CoUninitialize(); 671 win_skip("Failed to create Manager instance, skipping tests\n"); 672 return; 673 } 674 675 for (test = tests, i = 0; *test; ++test, ++i) 676 { 677 /* Keep state separate between tests. */ 678 if (!setup()) 679 { 680 ok(0, "tests:%d: Unable to setup test\n", i); 681 break; 682 } 683 (*test)(); 684 teardown(); 685 } 686 687 if (check_bits20()) 688 { 689 for (test = tests_bits20, i = 0; *test; ++test, ++i) 690 { 691 /* Keep state separate between tests. */ 692 if (!setup()) 693 { 694 ok(0, "tests_bits20:%d: Unable to setup test\n", i); 695 break; 696 } 697 (*test)(); 698 teardown(); 699 } 700 } 701 else 702 { 703 win_skip("Tests need BITS 2.0 or higher\n"); 704 } 705 706 if (check_bits25()) 707 { 708 for (test = tests_bits25, i = 0; *test; ++test, ++i) 709 { 710 /* Keep state separate between tests. */ 711 if (!setup()) 712 { 713 ok(0, "tests_bits25:%d: Unable to setup test\n", i); 714 break; 715 } 716 (*test)(); 717 teardown(); 718 } 719 } 720 else 721 { 722 win_skip("Tests need BITS 2.5 or higher\n"); 723 } 724 725 CoUninitialize(); 726 } 727