qmgr: Avoid %ll printf formats.
[wine] / dlls / qmgr / tests / 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 COBJMACROS
24
25 #include "wine/test.h"
26 #include "bits.h"
27
28 /* Globals used by many tests */
29 static const WCHAR test_displayName[] = {'T', 'e', 's', 't', 0};
30 static const WCHAR test_remoteNameA[] = {'r','e','m','o','t','e','A', 0};
31 static const WCHAR test_remoteNameB[] = {'r','e','m','o','t','e','B', 0};
32 static const WCHAR test_localNameA[] = {'l','o','c','a','l','A', 0};
33 static const WCHAR test_localNameB[] = {'l','o','c','a','l','B', 0};
34 static WCHAR *test_currentDir;
35 static WCHAR *test_remotePathA;
36 static WCHAR *test_remotePathB;
37 static WCHAR *test_localPathA;
38 static WCHAR *test_localPathB;
39 static IBackgroundCopyManager *test_manager;
40 static IBackgroundCopyJob *test_job;
41 static GUID test_jobId;
42 static BG_JOB_TYPE test_type;
43
44 static BOOL init_paths(void)
45 {
46     static const WCHAR format[] = {'%','s','\\','%','s', 0};
47     DWORD n;
48
49     n = GetCurrentDirectoryW(0, NULL);
50     if (n == 0)
51     {
52         skip("Couldn't get current directory size\n");
53         return FALSE;
54     }
55
56     test_currentDir = HeapAlloc(GetProcessHeap(), 0, n * sizeof(WCHAR));
57     test_localPathA
58         = HeapAlloc(GetProcessHeap(), 0,
59                     (n + 1 + lstrlenW(test_localNameA)) * sizeof(WCHAR));
60     test_localPathB
61         = HeapAlloc(GetProcessHeap(), 0,
62                     (n + 1 + lstrlenW(test_localNameB)) * sizeof(WCHAR));
63     test_remotePathA
64         = HeapAlloc(GetProcessHeap(), 0,
65                     (n + 1 + lstrlenW(test_remoteNameA)) * sizeof(WCHAR));
66     test_remotePathB
67         = HeapAlloc(GetProcessHeap(), 0,
68                     (n + 1 + lstrlenW(test_remoteNameB)) * sizeof(WCHAR));
69
70     if (!test_currentDir || !test_localPathA || !test_localPathB
71         || !test_remotePathA || !test_remotePathB)
72     {
73         skip("Couldn't allocate memory for full paths\n");
74         return FALSE;
75     }
76
77     if (GetCurrentDirectoryW(n, test_currentDir) != n - 1)
78     {
79         skip("Couldn't get current directory\n");
80         return FALSE;
81     }
82
83     wsprintfW(test_localPathA, format, test_currentDir, test_localNameA);
84     wsprintfW(test_localPathB, format, test_currentDir, test_localNameB);
85     wsprintfW(test_remotePathA, format, test_currentDir, test_remoteNameA);
86     wsprintfW(test_remotePathB, format, test_currentDir, test_remoteNameB);
87
88     return TRUE;
89 }
90
91 /* Generic test setup */
92 static BOOL setup(void)
93 {
94     HRESULT hres;
95
96     test_manager = NULL;
97     test_job = NULL;
98     memset(&test_jobId, 0, sizeof test_jobId);
99     test_type = BG_JOB_TYPE_DOWNLOAD;
100
101     hres = CoCreateInstance(&CLSID_BackgroundCopyManager, NULL,
102                             CLSCTX_LOCAL_SERVER,
103                             &IID_IBackgroundCopyManager,
104                             (void **) &test_manager);
105     if(hres != S_OK)
106         return FALSE;
107
108     hres = IBackgroundCopyManager_CreateJob(test_manager, test_displayName,
109                                             test_type, &test_jobId, &test_job);
110     if(hres != S_OK)
111     {
112         IBackgroundCopyManager_Release(test_manager);
113         return FALSE;
114     }
115
116     return TRUE;
117 }
118
119 /* Generic test cleanup */
120 static void teardown(void)
121 {
122     IBackgroundCopyJob_Release(test_job);
123     IBackgroundCopyManager_Release(test_manager);
124 }
125
126 /* Test that the jobId is properly set */
127 static void test_GetId(void)
128 {
129     HRESULT hres;
130     GUID tmpId;
131
132     hres = IBackgroundCopyJob_GetId(test_job, &tmpId);
133     ok(hres == S_OK, "GetId failed: %08x\n", hres);
134     if(hres != S_OK)
135     {
136         skip("Unable to get ID of test_job.\n");
137         return;
138     }
139     ok(memcmp(&tmpId, &test_jobId, sizeof tmpId) == 0, "Got incorrect GUID\n");
140 }
141
142 /* Test that the type is properly set */
143 static void test_GetType(void)
144 {
145     HRESULT hres;
146     BG_JOB_TYPE type;
147
148     hres = IBackgroundCopyJob_GetType(test_job, &type);
149     ok(hres == S_OK, "GetType failed: %08x\n", hres);
150     if(hres != S_OK)
151     {
152         skip("Unable to get type of test_job.\n");
153         return;
154     }
155     ok(type == test_type, "Got incorrect type\n");
156 }
157
158 /* Test that the display name is properly set */
159 static void test_GetName(void)
160 {
161     HRESULT hres;
162     LPWSTR displayName;
163
164     hres = IBackgroundCopyJob_GetDisplayName(test_job, &displayName);
165     ok(hres == S_OK, "GetName failed: %08x\n", hres);
166     if(hres != S_OK)
167     {
168         skip("Unable to get display name of test_job.\n");
169         return;
170     }
171     ok(lstrcmpW(displayName, test_displayName) == 0, "Got incorrect type\n");
172     CoTaskMemFree(displayName);
173 }
174
175 /* Test adding a file */
176 static void test_AddFile(void)
177 {
178     HRESULT hres;
179
180     hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathA,
181                                       test_localPathA);
182     ok(hres == S_OK, "First call to AddFile failed: 0x%08x\n", hres);
183     if (hres != S_OK)
184     {
185         skip("Unable to add first file to job\n");
186         return;
187     }
188
189     hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathB,
190                                       test_localPathB);
191     ok(hres == S_OK, "Second call to AddFile failed: 0x%08x\n", hres);
192 }
193
194 /* Test adding a set of files */
195 static void test_AddFileSet(void)
196 {
197     HRESULT hres;
198     BG_FILE_INFO files[2] =
199         {
200             {test_remotePathA, test_localPathA},
201             {test_remotePathB, test_localPathB}
202         };
203     hres = IBackgroundCopyJob_AddFileSet(test_job, 2, files);
204     ok(hres == S_OK, "AddFileSet failed: 0x%08x\n", hres);
205 }
206
207 /* Test creation of a job enumerator */
208 static void test_EnumFiles(void)
209 {
210     HRESULT hres;
211     IEnumBackgroundCopyFiles *enumFiles;
212     ULONG res;
213
214     hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathA,
215                                       test_localPathA);
216     if (hres != S_OK)
217     {
218         skip("Unable to add file to job\n");
219         return;
220     }
221
222     hres = IBackgroundCopyJob_EnumFiles(test_job, &enumFiles);
223     ok(hres == S_OK, "EnumFiles failed: 0x%08x\n", hres);
224     if(hres != S_OK)
225     {
226         skip("Unable to create file enumerator.\n");
227         return;
228     }
229
230     res = IEnumBackgroundCopyFiles_Release(enumFiles);
231     ok(res == 0, "Bad ref count on release: %u\n", res);
232 }
233
234 /* Test getting job progress */
235 static void test_GetProgress_preTransfer(void)
236 {
237     HRESULT hres;
238     BG_JOB_PROGRESS progress;
239
240     hres = IBackgroundCopyJob_GetProgress(test_job, &progress);
241     ok(hres == S_OK, "GetProgress failed: 0x%08x\n", hres);
242     if (hres != S_OK)
243     {
244         skip("Unable to get job progress\n");
245         teardown();
246         return;
247     }
248
249     ok(progress.BytesTotal == 0, "Incorrect BytesTotal: %x%08x\n",
250        (DWORD)(progress.BytesTotal >> 32), (DWORD)progress.BytesTotal);
251     ok(progress.BytesTransferred == 0, "Incorrect BytesTransferred: %x%08x\n",
252        (DWORD)(progress.BytesTransferred >> 32), (DWORD)progress.BytesTransferred);
253     ok(progress.FilesTotal == 0, "Incorrect FilesTotal: %u\n", progress.FilesTotal);
254     ok(progress.FilesTransferred == 0, "Incorrect FilesTransferred %u\n", progress.FilesTransferred);
255 }
256
257 /* Test getting job state */
258 static void test_GetState(void)
259 {
260     HRESULT hres;
261     BG_JOB_STATE state;
262
263     state = BG_JOB_STATE_ERROR;
264     hres = IBackgroundCopyJob_GetState(test_job, &state);
265     ok(hres == S_OK, "GetState failed: 0x%08x\n", hres);
266     if (hres != S_OK)
267     {
268         skip("Unable to get job state\n");
269         return;
270     }
271     ok(state == BG_JOB_STATE_SUSPENDED, "Incorrect job state: %d\n", state);
272 }
273
274 /* Test resuming a job */
275 static void test_ResumeEmpty(void)
276 {
277     HRESULT hres;
278     BG_JOB_STATE state;
279
280     hres = IBackgroundCopyJob_Resume(test_job);
281     ok(hres == BG_E_EMPTY, "Resume failed to return BG_E_EMPTY error: 0x%08x\n", hres);
282     if (hres != BG_E_EMPTY)
283     {
284         skip("Failed calling resume job\n");
285         return;
286     }
287
288     state = BG_JOB_STATE_ERROR;
289     hres = IBackgroundCopyJob_GetState(test_job, &state);
290     if (hres != S_OK)
291     {
292         skip("Unable to get job state\n");
293         return;
294     }
295     ok(state == BG_JOB_STATE_SUSPENDED, "Incorrect job state: %d\n", state);
296 }
297
298 static void makeFile(WCHAR *name, const char *contents)
299 {
300     HANDLE file;
301     DWORD w, len = strlen(contents);
302
303     DeleteFileW(name);
304     file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
305                        FILE_ATTRIBUTE_NORMAL, NULL);
306     ok(file != INVALID_HANDLE_VALUE, "CreateFile\n");
307     ok(WriteFile(file, contents, len, &w, NULL), "WriteFile\n");
308     CloseHandle(file);
309 }
310
311 static void compareFiles(WCHAR *n1, WCHAR *n2)
312 {
313     char b1[256];
314     char b2[256];
315     DWORD s1, s2;
316     HANDLE f1, f2;
317
318     f1 = CreateFileW(n1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
319                      FILE_ATTRIBUTE_NORMAL, NULL);
320     ok(f1 != INVALID_HANDLE_VALUE, "CreateFile\n");
321
322     f2 = CreateFileW(n2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
323                      FILE_ATTRIBUTE_NORMAL, NULL);
324     ok(f2 != INVALID_HANDLE_VALUE, "CreateFile\n");
325
326     /* Neither of these files is very big */
327     ok(ReadFile(f1, b1, sizeof b1, &s1, NULL), "ReadFile\n");
328     ok(ReadFile(f2, b2, sizeof b2, &s2, NULL), "ReadFile\n");
329
330     CloseHandle(f1);
331     CloseHandle(f2);
332
333     ok(s1 == s2, "Files differ in length\n");
334     ok(memcmp(b1, b2, s1) == 0, "Files differ in contents\n");
335 }
336
337 /* Test a complete transfer for local files */
338 static void test_CompleteLocal(void)
339 {
340     static const int timeout_sec = 30;
341     HRESULT hres;
342     BG_JOB_STATE state;
343     int i;
344
345     DeleteFileW(test_localPathA);
346     DeleteFileW(test_localPathB);
347     makeFile(test_remotePathA, "This is a WINE test file for BITS\n");
348     makeFile(test_remotePathB, "This is another WINE test file for BITS\n");
349
350     hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathA,
351                                       test_localPathA);
352     if (hres != S_OK)
353     {
354         skip("Unable to add file to job\n");
355         return;
356     }
357
358     hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathB,
359                                       test_localPathB);
360     if (hres != S_OK)
361     {
362         skip("Unable to add file to job\n");
363         return;
364     }
365
366     hres = IBackgroundCopyJob_Resume(test_job);
367     ok(hres == S_OK, "IBackgroundCopyJob_Resume\n");
368
369     for (i = 0; i < timeout_sec; ++i)
370     {
371         hres = IBackgroundCopyJob_GetState(test_job, &state);
372         ok(hres == S_OK, "IBackgroundCopyJob_GetState\n");
373         ok(state == BG_JOB_STATE_QUEUED || state == BG_JOB_STATE_CONNECTING
374            || state == BG_JOB_STATE_TRANSFERRING || state == BG_JOB_STATE_TRANSFERRED,
375            "Bad state: %d\n", state);
376         if (state == BG_JOB_STATE_TRANSFERRED)
377             break;
378         Sleep(1000);
379     }
380
381     ok(i < timeout_sec, "BITS jobs timed out\n");
382     hres = IBackgroundCopyJob_Complete(test_job);
383     ok(hres == S_OK, "IBackgroundCopyJob_Complete\n");
384     hres = IBackgroundCopyJob_GetState(test_job, &state);
385     ok(hres == S_OK, "IBackgroundCopyJob_GetState\n");
386     ok(state == BG_JOB_STATE_ACKNOWLEDGED, "Bad state: %d\n", state);
387
388     compareFiles(test_remotePathA, test_localPathA);
389     compareFiles(test_remotePathB, test_localPathB);
390
391     ok(DeleteFileW(test_remotePathA), "DeleteFile\n");
392     ok(DeleteFileW(test_remotePathB), "DeleteFile\n");
393     DeleteFileW(test_localPathA);
394     DeleteFileW(test_localPathB);
395 }
396
397 /* Test a complete transfer for local files */
398 static void test_CompleteLocalURL(void)
399 {
400     static const WCHAR prot[] = {'f','i','l','e',':','/','/', 0};
401     static const int timeout_sec = 30;
402     WCHAR *urlA, *urlB;
403     HRESULT hres;
404     BG_JOB_STATE state;
405     int i;
406
407     DeleteFileW(test_localPathA);
408     DeleteFileW(test_localPathB);
409     makeFile(test_remotePathA, "This is a WINE test file for BITS\n");
410     makeFile(test_remotePathB, "This is another WINE test file for BITS\n");
411
412     urlA = HeapAlloc(GetProcessHeap(), 0,
413                      (7 + lstrlenW(test_remotePathA) + 1) * sizeof urlA[0]);
414     urlB = HeapAlloc(GetProcessHeap(), 0,
415                      (7 + lstrlenW(test_remotePathB) + 1) * sizeof urlB[0]);
416     if (!urlA || !urlB)
417     {
418         skip("Unable to allocate memory for URLs\n");
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     if (hres != S_OK)
429     {
430         skip("Unable to add file to job\n");
431         return;
432     }
433
434     hres = IBackgroundCopyJob_AddFile(test_job, urlB, test_localPathB);
435     if (hres != S_OK)
436     {
437         skip("Unable to add file to job\n");
438         return;
439     }
440
441     hres = IBackgroundCopyJob_Resume(test_job);
442     ok(hres == S_OK, "IBackgroundCopyJob_Resume\n");
443
444     for (i = 0; i < timeout_sec; ++i)
445     {
446         hres = IBackgroundCopyJob_GetState(test_job, &state);
447         ok(hres == S_OK, "IBackgroundCopyJob_GetState\n");
448         ok(state == BG_JOB_STATE_QUEUED || state == BG_JOB_STATE_CONNECTING
449            || state == BG_JOB_STATE_TRANSFERRING || state == BG_JOB_STATE_TRANSFERRED,
450            "Bad state: %d\n", state);
451         if (state == BG_JOB_STATE_TRANSFERRED)
452             break;
453         Sleep(1000);
454     }
455
456     ok(i < timeout_sec, "BITS jobs timed out\n");
457     hres = IBackgroundCopyJob_Complete(test_job);
458     ok(hres == S_OK, "IBackgroundCopyJob_Complete\n");
459     hres = IBackgroundCopyJob_GetState(test_job, &state);
460     ok(hres == S_OK, "IBackgroundCopyJob_GetState\n");
461     ok(state == BG_JOB_STATE_ACKNOWLEDGED, "Bad state: %d\n", state);
462
463     compareFiles(test_remotePathA, test_localPathA);
464     compareFiles(test_remotePathB, test_localPathB);
465
466     ok(DeleteFileW(test_remotePathA), "DeleteFile\n");
467     ok(DeleteFileW(test_remotePathB), "DeleteFile\n");
468     DeleteFileW(test_localPathA);
469     DeleteFileW(test_localPathB);
470
471     HeapFree(GetProcessHeap(), 0, urlA);
472     HeapFree(GetProcessHeap(), 0, urlB);
473 }
474
475 typedef void (*test_t)(void);
476
477 START_TEST(job)
478 {
479     static const test_t tests[] = {
480         test_GetId,
481         test_GetType,
482         test_GetName,
483         test_AddFile,
484         test_AddFileSet,
485         test_EnumFiles,
486         test_GetProgress_preTransfer,
487         test_GetState,
488         test_ResumeEmpty,
489         test_CompleteLocal,
490         test_CompleteLocalURL,
491         0
492     };
493     const test_t *test;
494
495     if (!init_paths())
496         return;
497
498     CoInitialize(NULL);
499     for (test = tests; *test; ++test)
500     {
501         /* Keep state separate between tests. */
502         if (!setup())
503         {
504             skip("Unable to setup test\n");
505             break;
506         }
507         (*test)();
508         teardown();
509     }
510     CoUninitialize();
511 }