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