2 * PROJECT: ReactOS Automatic Testing Utility
3 * LICENSE: GNU GPLv2 or any later version as published by the Free Software Foundation
4 * PURPOSE: Submitting test results to the Web Service
5 * COPYRIGHT: Copyright 2008-2009 Colin Finck <colin@reactos.org>
10 static const CHAR ActionProp
[] = "action=";
11 static const CHAR TestIDProp
[] = "&testid=";
12 static const CHAR TestTypeProp
[] = "&testtype=";
13 static const CHAR WineTestType
[] = "wine";
16 * Sends data to the ReactOS Web Test Manager web service.
19 * Pointer to a CHAR pointer, which contains the data to submit as HTTP POST data.
20 * The buffer behind this pointer had to be allocated with HeapAlloc.
21 * Returns the data received by the web service after the call.
24 * Pointer to a DWORD, which contains the length of the data to submit (in bytes).
25 * Returns the length of the data received by the web service after the call (in bytes).
28 * TRUE if everything went well, FALSE if an error occured while submitting the request.
29 * In case of an error, the function will output an appropriate error message through StringOut.
32 IntDoRequest(char** Data
, PDWORD DataLength
)
34 const WCHAR Headers
[] = L
"Content-Type: application/x-www-form-urlencoded";
36 BOOL ReturnValue
= FALSE
;
37 HINTERNET hHTTP
= NULL
;
38 HINTERNET hHTTPRequest
= NULL
;
39 HINTERNET hInet
= NULL
;
41 /* Establish an internet connection to the "testman" server */
42 hInet
= InternetOpenW(L
"rosautotest", INTERNET_OPEN_TYPE_PRECONFIG
, NULL
, NULL
, 0);
46 StringOut("InternetOpenW failed\n");
50 hHTTP
= InternetConnectW(hInet
, SERVER_HOSTNAME
, INTERNET_DEFAULT_HTTP_PORT
, NULL
, NULL
, INTERNET_SERVICE_HTTP
, 0, 0);
54 StringOut("InternetConnectW failed\n");
58 /* Post our test results to the web service */
59 hHTTPRequest
= HttpOpenRequestW(hHTTP
, L
"POST", SERVER_FILE
, NULL
, NULL
, NULL
, INTERNET_FLAG_NO_COOKIES
| INTERNET_FLAG_RELOAD
| INTERNET_FLAG_NO_CACHE_WRITE
, 0);
63 StringOut("HttpOpenRequestW failed\n");
67 if(!HttpSendRequestW(hHTTPRequest
, Headers
, wcslen(Headers
), *Data
, *DataLength
))
69 StringOut("HttpSendRequestW failed\n");
73 HeapFree(hProcessHeap
, 0, *Data
);
76 /* Get the response */
77 if(!InternetQueryDataAvailable(hHTTPRequest
, DataLength
, 0, 0))
79 StringOut("InternetQueryDataAvailable failed\n");
83 *Data
= HeapAlloc(hProcessHeap
, 0, *DataLength
+ 1);
85 if(!InternetReadFile(hHTTPRequest
, *Data
, *DataLength
, DataLength
))
87 StringOut("InternetReadFile failed\n");
91 (*Data
)[*DataLength
] = 0;
96 InternetCloseHandle(hHTTPRequest
);
99 InternetCloseHandle(hHTTP
);
102 InternetCloseHandle(hInet
);
108 * Determines whether a string contains entirely numeric values.
111 * The string to check.
114 * TRUE if the string is entirely numeric, FALSE otherwise.
117 IsNumber(PCHAR Input
)
132 * Requests a Test ID from the web service for our test run.
135 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
138 * Returns the Test ID as a CHAR array if successful or NULL otherwise.
139 * The caller needs to HeapFree the returned pointer in case of success.
142 GetTestID(TESTTYPES TestType
)
144 const CHAR GetTestIDAction
[] = "gettestid";
145 const CHAR CommentProp
[] = "&comment=";
149 PCHAR ReturnValue
= NULL
;
151 /* Build the full request string */
152 DataLength
= sizeof(ActionProp
) - 1 + sizeof(GetTestIDAction
) - 1;
153 DataLength
+= strlen(AuthenticationRequestString
) + strlen(SystemInfoRequestString
);
155 if(AppOptions
.Comment
)
156 DataLength
+= sizeof(CommentProp
) - 1 + strlen(AppOptions
.Comment
);
158 DataLength
+= sizeof(TestTypeProp
) - 1;
163 DataLength
+= sizeof(WineTestType
) - 1;
167 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
168 strcpy(Data
, ActionProp
);
169 strcat(Data
, GetTestIDAction
);
170 strcat(Data
, AuthenticationRequestString
);
171 strcat(Data
, SystemInfoRequestString
);
173 if(AppOptions
.Comment
)
175 strcat(Data
, CommentProp
);
176 strcat(Data
, AppOptions
.Comment
);
179 strcat(Data
, TestTypeProp
);
184 strcat(Data
, WineTestType
);
188 if(!IntDoRequest(&Data
, &DataLength
))
191 /* Verify that this is really a number */
194 StringOut("Expected Test ID, but received:\n");
203 if(Data
&& ReturnValue
!= Data
)
204 HeapFree(hProcessHeap
, 0, Data
);
210 * Requests a Suite ID from the web service for our module/test combination.
213 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
216 * Pointer to a *_GETSUITEID_DATA structure appropriate for our selected test type.
217 * Contains other input information for this request.
220 * Returns the Suite ID as a CHAR array if successful or NULL otherwise.
221 * The caller needs to HeapFree the returned pointer in case of success.
224 GetSuiteID(TESTTYPES TestType
, const PVOID TestData
)
226 const CHAR GetSuiteIDAction
[] = "getsuiteid";
227 const CHAR ModuleProp
[] = "&module=";
228 const CHAR TestProp
[] = "&test=";
232 PCHAR ReturnValue
= NULL
;
233 PWINE_GETSUITEID_DATA WineData
;
235 DataLength
= sizeof(ActionProp
) - 1 + sizeof(GetSuiteIDAction
) - 1;
236 DataLength
+= strlen(AuthenticationRequestString
);
237 DataLength
+= sizeof(TestTypeProp
) - 1;
242 DataLength
+= sizeof(WineTestType
) - 1;
244 WineData
= (PWINE_GETSUITEID_DATA
)TestData
;
245 DataLength
+= sizeof(ModuleProp
) - 1;
246 DataLength
+= strlen(WineData
->Module
);
247 DataLength
+= sizeof(TestProp
) - 1;
248 DataLength
+= strlen(WineData
->Test
);
253 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
254 strcpy(Data
, ActionProp
);
255 strcat(Data
, GetSuiteIDAction
);
256 strcat(Data
, AuthenticationRequestString
);
257 strcat(Data
, TestTypeProp
);
262 strcat(Data
, WineTestType
);
264 /* Stupid GCC and MSVC: WineData is already initialized above, still it's reported as a potentially uninitialized variable :-( */
265 WineData
= (PWINE_GETSUITEID_DATA
)TestData
;
266 strcat(Data
, ModuleProp
);
267 strcat(Data
, WineData
->Module
);
268 strcat(Data
, TestProp
);
269 strcat(Data
, WineData
->Test
);
274 if(!IntDoRequest(&Data
, &DataLength
))
277 /* Verify that this is really a number */
280 StringOut("Expected Suite ID, but received:\n");
289 if(Data
&& ReturnValue
!= Data
)
290 HeapFree(hProcessHeap
, 0, Data
);
296 * Submits the result of one test call to the web service.
299 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
302 * Pointer to a *_SUBMIT_DATA structure appropriate for our selected test type.
303 * Contains other input information for this request.
306 * TRUE if everything went well, FALSE otherwise.
309 Submit(TESTTYPES TestType
, const PVOID TestData
)
311 const CHAR SubmitAction
[] = "submit";
312 const CHAR SuiteIDProp
[] = "&suiteid=";
313 const CHAR LogProp
[] = "&log=";
315 BOOL ReturnValue
= FALSE
;
319 PGENERAL_SUBMIT_DATA GeneralData
;
320 PWINE_SUBMIT_DATA WineData
;
322 /* Compute the full length of the POST data */
323 DataLength
= sizeof(ActionProp
) - 1 + sizeof(SubmitAction
) - 1;
324 DataLength
+= strlen(AuthenticationRequestString
);
326 GeneralData
= (PGENERAL_SUBMIT_DATA
)TestData
;
327 DataLength
+= sizeof(TestIDProp
) - 1;
328 DataLength
+= strlen(GeneralData
->TestID
);
329 DataLength
+= sizeof(SuiteIDProp
) - 1;
330 DataLength
+= strlen(GeneralData
->SuiteID
);
332 /* The rest of the POST data depends on the test type */
333 DataLength
+= sizeof(TestTypeProp
) - 1;
338 DataLength
+= sizeof(WineTestType
) - 1;
340 WineData
= (PWINE_SUBMIT_DATA
)TestData
;
341 DataLength
+= sizeof(LogProp
) - 1;
342 DataLength
+= 3 * strlen(WineData
->Log
);
347 /* Now collect all the POST data */
348 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
349 strcpy(Data
, ActionProp
);
350 strcat(Data
, SubmitAction
);
351 strcat(Data
, AuthenticationRequestString
);
353 strcat(Data
, TestIDProp
);
354 strcat(Data
, GeneralData
->TestID
);
355 strcat(Data
, SuiteIDProp
);
356 strcat(Data
, GeneralData
->SuiteID
);
358 strcat(Data
, TestTypeProp
);
363 strcat(Data
, WineTestType
);
365 /* Stupid GCC and MSVC: WineData is already initialized above, still it's reported as a potentially uninitialized variable :-( */
366 WineData
= (PWINE_SUBMIT_DATA
)TestData
;
368 strcat(Data
, LogProp
);
369 pData
= Data
+ strlen(Data
);
370 EscapeString(pData
, WineData
->Log
);
375 /* DataLength still contains the maximum length of the buffer, but not the actual data length we need for the request.
376 Determine that one now. */
377 DataLength
= strlen(Data
);
379 /* Send all the stuff */
380 if(!IntDoRequest(&Data
, &DataLength
))
383 /* Output the response */
384 StringOut("The server responded:\n");
388 if(!strcmp(Data
, "OK"))
393 HeapFree(hProcessHeap
, 0, Data
);
399 * Finishes a test run for the web service.
402 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
405 * Pointer to a *_FINISH_DATA structure appropriate for our selected test type.
406 * Contains other input information for this request.
409 * TRUE if everything went well, FALSE otherwise.
412 Finish(TESTTYPES TestType
, const PVOID TestData
)
414 const CHAR FinishAction
[] = "finish";
416 BOOL ReturnValue
= FALSE
;
419 PGENERAL_FINISH_DATA GeneralData
;
421 /* Build the full request string */
422 DataLength
= sizeof(ActionProp
) - 1 + sizeof(FinishAction
) - 1;
423 DataLength
+= strlen(AuthenticationRequestString
);
425 GeneralData
= (PGENERAL_FINISH_DATA
)TestData
;
426 DataLength
+= sizeof(TestIDProp
) - 1;
427 DataLength
+= strlen(GeneralData
->TestID
);
429 DataLength
+= sizeof(TestTypeProp
) - 1;
434 DataLength
+= sizeof(WineTestType
) - 1;
438 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
439 strcpy(Data
, ActionProp
);
440 strcat(Data
, FinishAction
);
441 strcat(Data
, AuthenticationRequestString
);
442 strcat(Data
, TestIDProp
);
443 strcat(Data
, GeneralData
->TestID
);
444 strcat(Data
, TestTypeProp
);
449 strcat(Data
, WineTestType
);
453 if(!IntDoRequest(&Data
, &DataLength
))
456 if(!strcmp(Data
, "OK"))
461 HeapFree(hProcessHeap
, 0, Data
);