[QMGR_WINETEST] Sync with Wine Staging 2.16. CORE-13762
[reactos.git] / modules / rostests / winetests / qmgr / job.c
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 }