- combotst: Fix uninitialized variable usage spotted by MSVC
[reactos.git] / rostests / tests / tmrqueue / tmrqueue.c
1 #include <windows.h>
2 #include <stdio.h>
3 #include <tchar.h>
4
5 #define N_TIMEOUT 3
6
7 /*******************************************************************************/
8
9 typedef struct _TEST *PTEST;
10
11 typedef VOID (*PFNTEST)(PTEST Test, HANDLE hEvent);
12
13 typedef struct _TEST
14 {
15 TCHAR *description;
16 BOOL Result;
17 PFNTEST Routine;
18 int id;
19 } TEST;
20
21 static TEST Tests[3];
22
23 VOID RunTests(VOID)
24 {
25 int i, nTests;
26 static HANDLE hEvent;
27
28 hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
29 if(hEvent == NULL)
30 {
31 _tprintf(_T("Unable to create event!"));
32 return;
33 }
34
35 nTests = sizeof(Tests) / sizeof(TEST);
36
37 for(i = 0; i < nTests; i++)
38 {
39 Tests[i].id = i + 1;
40
41 if(Tests[i].Routine == NULL)
42 {
43 continue;
44 }
45
46 _tprintf(_T("+++ TEST %d: %s\n"), Tests[i].id, Tests[i].description);
47
48 Tests[i].Routine(&Tests[i], hEvent);
49
50 WaitForSingleObject(hEvent, INFINITE);
51
52 _tprintf(_T("\n\n"));
53 }
54
55 CloseHandle(hEvent);
56 }
57
58 VOID PrintTestResults(VOID)
59 {
60 int i, nTests, nsuccess = 0, nfailed = 0;
61 TCHAR *status;
62
63 nTests = sizeof(Tests) / sizeof(TEST);
64
65 for(i = 0; i < nTests; i++)
66 {
67 if(Tests[i].Routine == NULL)
68 {
69 status = _T("SKIPPED");
70 }
71 else if(Tests[i].Result == TRUE)
72 {
73 status = _T("SUCCESS");
74 nsuccess++;
75 }
76 else
77 {
78 status = _T("FAILED ");
79 nfailed++;
80 }
81
82 _tprintf(_T("Test %d: %s %s\n"), i, status, Tests[i].description);
83 }
84
85 _tprintf(_T("\nTests succeeded: %d, failed: %d\n"), nsuccess, nfailed);
86 if(nfailed == 0)
87 {
88 _tprintf(_T(" ALL TESTS SUCCESSFUL!\n"));
89 }
90 }
91
92 /*******************************************************************************/
93
94 typedef struct _TESTINFO
95 {
96 PTEST Test;
97 int secsleft;
98 HANDLE hTimer;
99 HANDLE hEvent;
100 /* additional stuff */
101 union
102 {
103 struct
104 {
105 HANDLE Dummy;
106 } Test1;
107 struct
108 {
109 HANDLE hWaitEvent;
110 } Test2;
111 struct
112 {
113 HANDLE hWaitEvent;
114 HANDLE hNotification;
115 } Test3;
116 };
117 } TESTINFO, *PTESTINFO;
118
119 VOID CALLBACK TimerCallback1(PVOID Param, BOOLEAN Fired)
120 {
121 PTESTINFO Info = (PTESTINFO)Param;
122
123 _tprintf(_T("[%d]TimerCallback(0x%x, %d) called (%d)\n"), (int)Info->Test->id, (int)Info->hTimer, (int)Fired, --Info->secsleft);
124
125 if(Info->secsleft == 0)
126 {
127 BOOL stat;
128
129 _tprintf(_T("[%d]Timout finished, delete timer queue..."), (int)Info->Test->id);
130 stat = DeleteTimerQueueTimer(NULL, Info->hTimer, NULL);
131 if(stat)
132 _tprintf(_T("returned OK -> test FAILED!\n"));
133 else
134 {
135 int error = GetLastError();
136
137 switch(error)
138 {
139 case ERROR_IO_PENDING:
140 _tprintf(_T("OK, Overlapped I/O operation in progress\n"));
141 /* this test is only successful in this case */
142 Info->Test->Result = TRUE;
143 break;
144 default:
145 _tprintf(_T("Failed, LastError: %d\n"), (int)GetLastError());
146 break;
147 }
148 }
149
150 /* set the event to continue tests */
151 SetEvent(Info->hEvent);
152 }
153 }
154
155 VOID Test1(PTEST Test, HANDLE hEvent)
156 {
157 static TESTINFO Info;
158
159 Info.Test = Test;
160 Info.hEvent = hEvent;
161 Info.secsleft = N_TIMEOUT;
162
163 if(!CreateTimerQueueTimer(&Info.hTimer, NULL, TimerCallback1, &Info, 1000, 1000, 0))
164 {
165 _tprintf(_T("[%d]CreateTimerQueueTimer() failed, LastError: %d!"), (int)Info.Test->id, (int)GetLastError());
166 /* we failed, set the event to continue tests */
167 SetEvent(hEvent);
168 return;
169 }
170
171 _tprintf(_T("[%d]CreateTimerQueueTimer() created timer 0x%x, countdown (%d sec)...\n"), (int)Info.Test->id, (int)Info.hTimer, (int)Info.secsleft);
172 }
173
174 /*******************************************************************************/
175
176 VOID CALLBACK TimerCallback2(PVOID Param, BOOLEAN Fired)
177 {
178 PTESTINFO Info = (PTESTINFO)Param;
179
180 _tprintf(_T("[%d]TimerCallback(0x%x, %d) called (%d)\n"), (int)Info->Test->id, (int)Info->hTimer, (int)Fired, --Info->secsleft);
181
182 if(Info->secsleft == 0)
183 {
184 /* set the event to continue tests */
185 SetEvent(Info->Test2.hWaitEvent);
186
187 /* sleep a bit */
188 Sleep(1500);
189 }
190 }
191
192 VOID Test2(PTEST Test, HANDLE hEvent)
193 {
194 static TESTINFO Info;
195 BOOL stat;
196
197 Info.Test = Test;
198 Info.hEvent = hEvent;
199 Info.secsleft = N_TIMEOUT;
200
201 Info.Test2.hWaitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
202 if(Info.Test2.hWaitEvent == NULL)
203 {
204 _tprintf(_T("[%d]Unable to create event!\n"), (int)Info.Test->id);
205 return;
206 }
207
208 if(!CreateTimerQueueTimer(&Info.hTimer, NULL, TimerCallback2, &Info, 1000, 1000, 0))
209 {
210 _tprintf(_T("[%d]CreateTimerQueueTimer() failed, LastError: %d!"), (int)Info.Test->id, (int)GetLastError());
211
212 CloseHandle(Info.Test2.hWaitEvent);
213 /* we failed, set the event to continue tests */
214 SetEvent(hEvent);
215 return;
216 }
217
218 _tprintf(_T("[%d]CreateTimerQueueTimer() created timer 0x%x, countdown (%d sec)...\n"), (int)Test->id, (int)Info.hTimer, (int)Info.secsleft);
219
220 WaitForSingleObject(Info.Test2.hWaitEvent, INFINITE);
221
222 _tprintf(_T("[%d]Timout finished, delete timer queue..."), (int)Test->id);
223 stat = DeleteTimerQueueTimer(NULL, Info.hTimer, INVALID_HANDLE_VALUE);
224 if(stat)
225 {
226 _tprintf(_T("OK\n"));
227 /* this test is only successful in this case */
228 Test->Result = TRUE;
229 }
230 else
231 {
232 int error = GetLastError();
233
234 switch(error)
235 {
236 case ERROR_IO_PENDING:
237 _tprintf(_T("FAILED, Overlapped I/O operation in progress\n"));
238 break;
239 default:
240 _tprintf(_T("Failed, LastError: %d\n"), (int)GetLastError());
241 break;
242 }
243 }
244
245 SetEvent(Info.hEvent);
246 }
247
248 /*******************************************************************************/
249
250 VOID CALLBACK TimerCallback3(PVOID Param, BOOLEAN Fired)
251 {
252 PTESTINFO Info = (PTESTINFO)Param;
253
254 _tprintf(_T("[%d]TimerCallback(0x%x, %d) called (%d)\n"), (int)Info->Test->id, (int)Info->hTimer, (int)Fired, --Info->secsleft);
255
256 if(Info->secsleft == 0)
257 {
258 /* set the event to continue tests */
259 SetEvent(Info->Test3.hWaitEvent);
260
261 /* sleep a bit */
262 Sleep(1500);
263 }
264 }
265
266 VOID Test3(PTEST Test, HANDLE hEvent)
267 {
268 static TESTINFO Info;
269 BOOL stat;
270
271 Info.Test = Test;
272 Info.hEvent = hEvent;
273 Info.secsleft = N_TIMEOUT;
274
275 Info.Test3.hWaitEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
276 if(Info.Test3.hWaitEvent == NULL)
277 {
278 _tprintf(_T("[%d]Unable to create event!\n"), (int)Info.Test->id);
279 return;
280 }
281
282 Info.Test3.hNotification = CreateEvent(NULL, FALSE, FALSE, NULL);
283 if(Info.Test3.hNotification == NULL)
284 {
285 _tprintf(_T("[%d]Unable to create notification event!\n"), (int)Info.Test->id);
286 return;
287 }
288
289 if(!CreateTimerQueueTimer(&Info.hTimer, NULL, TimerCallback3, &Info, 1000, 1000, 0))
290 {
291 _tprintf(_T("[%d]CreateTimerQueueTimer() failed, LastError: %d!"), (int)Info.Test->id, (int)GetLastError());
292
293 CloseHandle(Info.Test3.hWaitEvent);
294 CloseHandle(Info.Test3.hNotification);
295 /* we failed, set the event to continue tests */
296 SetEvent(hEvent);
297 return;
298 }
299
300 _tprintf(_T("[%d]CreateTimerQueueTimer() created timer 0x%x, countdown (%d sec)...\n"), (int)Test->id, (int)Info.hTimer, (int)Info.secsleft);
301
302 WaitForSingleObject(Info.Test3.hWaitEvent, INFINITE);
303
304 _tprintf(_T("[%d]Timout finished, delete timer queue..."), (int)Test->id);
305 stat = DeleteTimerQueueTimer(NULL, Info.hTimer, Info.Test3.hNotification);
306 if(stat)
307 {
308 _tprintf(_T("returned OK -> test FAILED!\n"));
309 }
310 else
311 {
312 int error = GetLastError();
313
314 switch(error)
315 {
316 case ERROR_IO_PENDING:
317 _tprintf(_T("OK, Overlapped I/O operation in progress\n"));
318 /* this test is only successful in this case */
319 Test->Result = TRUE;
320 break;
321 default:
322 _tprintf(_T("Failed, LastError: %d\n"), (int)GetLastError());
323 break;
324 }
325 }
326
327 WaitForSingleObject(Info.Test3.hNotification, INFINITE);
328
329 CloseHandle(Info.Test3.hWaitEvent);
330 CloseHandle(Info.Test3.hNotification);
331
332 SetEvent(Info.hEvent);
333 }
334
335 /*******************************************************************************/
336
337 VOID
338 InitTests(VOID)
339 {
340 ZeroMemory(Tests, sizeof(Tests));
341
342 Tests[0].description = _T("non-blocking DeleteTimerQueueTimer() call from callback");
343 Tests[0].Routine = Test1;
344
345 Tests[1].description = _T("blocking DeleteTimerQueueTimer() call");
346 Tests[1].Routine = Test2;
347
348 Tests[2].description = _T("blocking DeleteTimerQueueTimer() call with specified event");
349 Tests[2].Routine = Test3;
350 }
351
352 int main(int argc, char* argv[])
353 {
354 _tprintf(_T("+++ TimerQueue test running +++\n\n"));
355
356 InitTests();
357
358 RunTests();
359
360 _tprintf(_T("\n+++ RESULTS +++\n"));
361
362 PrintTestResults();
363
364 return 0;
365 }