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";
148 PCHAR ReturnValue
= NULL
;
150 /* Build the full request string */
151 DataLength
= sizeof(ActionProp
) - 1 + sizeof(GetTestIDAction
) - 1;
152 DataLength
+= strlen(AuthenticationRequestString
) + strlen(SystemInfoRequestString
);
153 DataLength
+= sizeof(TestTypeProp
) - 1;
158 DataLength
+= sizeof(WineTestType
) - 1;
162 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
163 strcpy(Data
, ActionProp
);
164 strcat(Data
, GetTestIDAction
);
165 strcat(Data
, AuthenticationRequestString
);
166 strcat(Data
, SystemInfoRequestString
);
167 strcat(Data
, TestTypeProp
);
172 strcat(Data
, WineTestType
);
176 if(!IntDoRequest(&Data
, &DataLength
))
179 /* Verify that this is really a number */
182 StringOut("Expected Test ID, but received:\n");
191 if(Data
&& ReturnValue
!= Data
)
192 HeapFree(hProcessHeap
, 0, Data
);
198 * Requests a Suite ID from the web service for our module/test combination.
201 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
204 * Pointer to a *_GETSUITEID_DATA structure appropriate for our selected test type.
205 * Contains other input information for this request.
208 * Returns the Suite ID as a CHAR array if successful or NULL otherwise.
209 * The caller needs to HeapFree the returned pointer in case of success.
212 GetSuiteID(TESTTYPES TestType
, const PVOID TestData
)
214 const CHAR GetSuiteIDAction
[] = "getsuiteid";
215 const CHAR ModuleProp
[] = "&module=";
216 const CHAR TestProp
[] = "&test=";
220 PCHAR ReturnValue
= NULL
;
221 PWINE_GETSUITEID_DATA WineData
;
223 DataLength
= sizeof(ActionProp
) - 1 + sizeof(GetSuiteIDAction
) - 1;
224 DataLength
+= strlen(AuthenticationRequestString
);
225 DataLength
+= sizeof(TestTypeProp
) - 1;
230 DataLength
+= sizeof(WineTestType
) - 1;
232 WineData
= (PWINE_GETSUITEID_DATA
)TestData
;
233 DataLength
+= sizeof(ModuleProp
) - 1;
234 DataLength
+= strlen(WineData
->Module
);
235 DataLength
+= sizeof(TestProp
) - 1;
236 DataLength
+= strlen(WineData
->Test
);
241 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
242 strcpy(Data
, ActionProp
);
243 strcat(Data
, GetSuiteIDAction
);
244 strcat(Data
, AuthenticationRequestString
);
245 strcat(Data
, TestTypeProp
);
250 strcat(Data
, WineTestType
);
252 /* Stupid GCC and MSVC: WineData is already initialized above, still it's reported as a potentially uninitialized variable :-( */
253 WineData
= (PWINE_GETSUITEID_DATA
)TestData
;
254 strcat(Data
, ModuleProp
);
255 strcat(Data
, WineData
->Module
);
256 strcat(Data
, TestProp
);
257 strcat(Data
, WineData
->Test
);
262 if(!IntDoRequest(&Data
, &DataLength
))
265 /* Verify that this is really a number */
268 StringOut("Expected Suite ID, but received:\n");
277 if(Data
&& ReturnValue
!= Data
)
278 HeapFree(hProcessHeap
, 0, Data
);
284 * Submits the result of one test call to the web service.
287 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
290 * Pointer to a *_SUBMIT_DATA structure appropriate for our selected test type.
291 * Contains other input information for this request.
294 * TRUE if everything went well, FALSE otherwise.
297 Submit(TESTTYPES TestType
, const PVOID TestData
)
299 const CHAR SubmitAction
[] = "submit";
300 const CHAR SuiteIDProp
[] = "&suiteid=";
301 const CHAR LogProp
[] = "&log=";
303 BOOL ReturnValue
= FALSE
;
307 PGENERAL_SUBMIT_DATA GeneralData
;
308 PWINE_SUBMIT_DATA WineData
;
310 /* Compute the full length of the POST data */
311 DataLength
= sizeof(ActionProp
) - 1 + sizeof(SubmitAction
) - 1;
312 DataLength
+= strlen(AuthenticationRequestString
);
314 GeneralData
= (PGENERAL_SUBMIT_DATA
)TestData
;
315 DataLength
+= sizeof(TestIDProp
) - 1;
316 DataLength
+= strlen(GeneralData
->TestID
);
317 DataLength
+= sizeof(SuiteIDProp
) - 1;
318 DataLength
+= strlen(GeneralData
->SuiteID
);
320 /* The rest of the POST data depends on the test type */
321 DataLength
+= sizeof(TestTypeProp
) - 1;
326 DataLength
+= sizeof(WineTestType
) - 1;
328 WineData
= (PWINE_SUBMIT_DATA
)TestData
;
329 DataLength
+= sizeof(LogProp
) - 1;
330 DataLength
+= 3 * strlen(WineData
->Log
);
335 /* Now collect all the POST data */
336 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
337 strcpy(Data
, ActionProp
);
338 strcat(Data
, SubmitAction
);
339 strcat(Data
, AuthenticationRequestString
);
341 strcat(Data
, TestIDProp
);
342 strcat(Data
, GeneralData
->TestID
);
343 strcat(Data
, SuiteIDProp
);
344 strcat(Data
, GeneralData
->SuiteID
);
346 strcat(Data
, TestTypeProp
);
351 strcat(Data
, WineTestType
);
353 /* Stupid GCC and MSVC: WineData is already initialized above, still it's reported as a potentially uninitialized variable :-( */
354 WineData
= (PWINE_SUBMIT_DATA
)TestData
;
356 strcat(Data
, LogProp
);
357 pData
= Data
+ strlen(Data
);
358 EscapeString(pData
, WineData
->Log
);
363 /* DataLength still contains the maximum length of the buffer, but not the actual data length we need for the request.
364 Determine that one now. */
365 DataLength
= strlen(Data
);
367 /* Send all the stuff */
368 if(!IntDoRequest(&Data
, &DataLength
))
371 /* Output the response */
372 StringOut("The server responded:\n");
376 if(!strcmp(Data
, "OK"))
381 HeapFree(hProcessHeap
, 0, Data
);
387 * Finishes a test run for the web service.
390 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
393 * Pointer to a *_FINISH_DATA structure appropriate for our selected test type.
394 * Contains other input information for this request.
397 * TRUE if everything went well, FALSE otherwise.
400 Finish(TESTTYPES TestType
, const PVOID TestData
)
402 const CHAR FinishAction
[] = "finish";
404 BOOL ReturnValue
= FALSE
;
407 PGENERAL_FINISH_DATA GeneralData
;
409 /* Build the full request string */
410 DataLength
= sizeof(ActionProp
) - 1 + sizeof(FinishAction
) - 1;
411 DataLength
+= strlen(AuthenticationRequestString
);
413 GeneralData
= (PGENERAL_FINISH_DATA
)TestData
;
414 DataLength
+= sizeof(TestIDProp
) - 1;
415 DataLength
+= strlen(GeneralData
->TestID
);
417 DataLength
+= sizeof(TestTypeProp
) - 1;
422 DataLength
+= sizeof(WineTestType
) - 1;
426 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
427 strcpy(Data
, ActionProp
);
428 strcat(Data
, FinishAction
);
429 strcat(Data
, AuthenticationRequestString
);
430 strcat(Data
, TestIDProp
);
431 strcat(Data
, GeneralData
->TestID
);
432 strcat(Data
, TestTypeProp
);
437 strcat(Data
, WineTestType
);
441 if(!IntDoRequest(&Data
, &DataLength
))
444 if(!strcmp(Data
, "OK"))
449 HeapFree(hProcessHeap
, 0, Data
);