advapi32: Create MachineGuid value if it doesn't exist.
[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: %llu\n", progress.BytesTotal);
250     ok(progress.BytesTransferred == 0, "Incorrect BytesTransferred: %llu\n", progress.BytesTransferred);
251     ok(progress.FilesTotal == 0, "Incorrect FilesTotal: %u\n", progress.FilesTotal);
252     ok(progress.FilesTransferred == 0, "Incorrect FilesTransferred %u\n", progress.FilesTransferred);
253 }
254
255 /* Test getting job state */
256 static void test_GetState(void)
257 {
258     HRESULT hres;
259     BG_JOB_STATE state;
260
261     state = BG_JOB_STATE_ERROR;
262     hres = IBackgroundCopyJob_GetState(test_job, &state);
263     ok(hres == S_OK, "GetState failed: 0x%08x\n", hres);
264     if (hres != S_OK)
265     {
266         skip("Unable to get job state\n");
267         return;
268     }
269     ok(state == BG_JOB_STATE_SUSPENDED, "Incorrect job state: %d\n", state);
270 }
271
272 /* Test resuming a job */
273 static void test_ResumeEmpty(void)
274 {
275     HRESULT hres;
276     BG_JOB_STATE state;
277
278     hres = IBackgroundCopyJob_Resume(test_job);
279     ok(hres == BG_E_EMPTY, "Resume failed to return BG_E_EMPTY error: 0x%08x\n", hres);
280     if (hres != BG_E_EMPTY)
281     {
282         skip("Failed calling resume job\n");
283         return;
284     }
285
286     state = BG_JOB_STATE_ERROR;
287     hres = IBackgroundCopyJob_GetState(test_job, &state);
288     if (hres != S_OK)
289     {
290         skip("Unable to get job state\n");
291         return;
292     }
293     ok(state == BG_JOB_STATE_SUSPENDED, "Incorrect job state: %d\n", state);
294 }
295
296 static void makeFile(WCHAR *name, const char *contents)
297 {
298     HANDLE file;
299     DWORD w, len = strlen(contents);
300
301     DeleteFileW(name);
302     file = CreateFileW(name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
303                        FILE_ATTRIBUTE_NORMAL, NULL);
304     ok(file != INVALID_HANDLE_VALUE, "CreateFile\n");
305     ok(WriteFile(file, contents, len, &w, NULL), "WriteFile\n");
306     CloseHandle(file);
307 }
308
309 static void compareFiles(WCHAR *n1, WCHAR *n2)
310 {
311     char b1[256];
312     char b2[256];
313     DWORD s1, s2;
314     HANDLE f1, f2;
315
316     f1 = CreateFileW(n1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
317                      FILE_ATTRIBUTE_NORMAL, NULL);
318     ok(f1 != INVALID_HANDLE_VALUE, "CreateFile\n");
319
320     f2 = CreateFileW(n2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
321                      FILE_ATTRIBUTE_NORMAL, NULL);
322     ok(f2 != INVALID_HANDLE_VALUE, "CreateFile\n");
323
324     /* Neither of these files is very big */
325     ok(ReadFile(f1, b1, sizeof b1, &s1, NULL), "ReadFile\n");
326     ok(ReadFile(f2, b2, sizeof b2, &s2, NULL), "ReadFile\n");
327
328     CloseHandle(f1);
329     CloseHandle(f2);
330
331     ok(s1 == s2, "Files differ in length\n");
332     ok(memcmp(b1, b2, s1) == 0, "Files differ in contents\n");
333 }
334
335 /* Test a complete transfer for local files */
336 static void test_CompleteLocal(void)
337 {
338     static const int timeout_sec = 30;
339     HRESULT hres;
340     BG_JOB_STATE state;
341     int i;
342
343     DeleteFileW(test_localPathA);
344     DeleteFileW(test_localPathB);
345     makeFile(test_remotePathA, "This is a WINE test file for BITS\n");
346     makeFile(test_remotePathB, "This is another WINE test file for BITS\n");
347
348     hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathA,
349                                       test_localPathA);
350     if (hres != S_OK)
351     {
352         skip("Unable to add file to job\n");
353         return;
354     }
355
356     hres = IBackgroundCopyJob_AddFile(test_job, test_remotePathB,
357                                       test_localPathB);
358     if (hres != S_OK)
359     {
360         skip("Unable to add file to job\n");
361         return;
362     }
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         return;
418     }
419
420     lstrcpyW(urlA, prot);
421     lstrcatW(urlA, test_remotePathA);
422     lstrcpyW(urlB, prot);
423     lstrcatW(urlB, test_remotePathB);
424
425     hres = IBackgroundCopyJob_AddFile(test_job, urlA, test_localPathA);
426     if (hres != S_OK)
427     {
428         skip("Unable to add file to job\n");
429         return;
430     }
431
432     hres = IBackgroundCopyJob_AddFile(test_job, urlB, test_localPathB);
433     if (hres != S_OK)
434     {
435         skip("Unable to add file to job\n");
436         return;
437     }
438
439     hres = IBackgroundCopyJob_Resume(test_job);
440     ok(hres == S_OK, "IBackgroundCopyJob_Resume\n");
441
442     for (i = 0; i < timeout_sec; ++i)
443     {
444         hres = IBackgroundCopyJob_GetState(test_job, &state);
445         ok(hres == S_OK, "IBackgroundCopyJob_GetState\n");
446         ok(state == BG_JOB_STATE_QUEUED || state == BG_JOB_STATE_CONNECTING
447            || state == BG_JOB_STATE_TRANSFERRING || state == BG_JOB_STATE_TRANSFERRED,
448            "Bad state: %d\n", state);
449         if (state == BG_JOB_STATE_TRANSFERRED)
450             break;
451         Sleep(1000);
452     }
453
454     ok(i < timeout_sec, "BITS jobs timed out\n");
455     hres = IBackgroundCopyJob_Complete(test_job);
456     ok(hres == S_OK, "IBackgroundCopyJob_Complete\n");
457     hres = IBackgroundCopyJob_GetState(test_job, &state);
458     ok(hres == S_OK, "IBackgroundCopyJob_GetState\n");
459     ok(state == BG_JOB_STATE_ACKNOWLEDGED, "Bad state: %d\n", state);
460
461     compareFiles(test_remotePathA, test_localPathA);
462     compareFiles(test_remotePathB, test_localPathB);
463
464     ok(DeleteFileW(test_remotePathA), "DeleteFile\n");
465     ok(DeleteFileW(test_remotePathB), "DeleteFile\n");
466     DeleteFileW(test_localPathA);
467     DeleteFileW(test_localPathB);
468
469     HeapFree(GetProcessHeap(), 0, urlA);
470     HeapFree(GetProcessHeap(), 0, urlB);
471 }
472
473 typedef void (*test_t)(void);
474
475 START_TEST(job)
476 {
477     static const test_t tests[] = {
478         test_GetId,
479         test_GetType,
480         test_GetName,
481         test_AddFile,
482         test_AddFileSet,
483         test_EnumFiles,
484         test_GetProgress_preTransfer,
485         test_GetState,
486         test_ResumeEmpty,
487         test_CompleteLocal,
488         test_CompleteLocalURL,
489         0
490     };
491     const test_t *test;
492
493     if (!init_paths())
494         return;
495
496     CoInitialize(NULL);
497     for (test = tests; *test; ++test)
498     {
499         /* Keep state separate between tests. */
500         if (!setup())
501         {
502             skip("Unable to setup test\n");
503             break;
504         }
505         (*test)();
506         teardown();
507     }
508     CoUninitialize();
509 }