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";
37 HINTERNET hHTTPRequest
;
40 /* Establish an internet connection to the "testman" server */
41 hInet
= InternetOpenW(L
"rosautotest", INTERNET_OPEN_TYPE_PRECONFIG
, NULL
, NULL
, 0);
45 StringOut("InternetOpenW failed\n");
49 hHTTP
= InternetConnectW(hInet
, SERVER_HOSTNAME
, INTERNET_DEFAULT_HTTP_PORT
, NULL
, NULL
, INTERNET_SERVICE_HTTP
, 0, 0);
53 StringOut("InternetConnectW failed\n");
57 /* Post our test results to the web service */
58 hHTTPRequest
= HttpOpenRequestW(hHTTP
, L
"POST", SERVER_FILE
, NULL
, NULL
, NULL
, INTERNET_FLAG_NO_COOKIES
| INTERNET_FLAG_RELOAD
| INTERNET_FLAG_NO_CACHE_WRITE
, 0);
62 StringOut("HttpOpenRequestW failed\n");
66 if(!HttpSendRequestW(hHTTPRequest
, Headers
, wcslen(Headers
), *Data
, *DataLength
))
68 StringOut("HttpSendRequestW failed\n");
72 HeapFree(hProcessHeap
, 0, *Data
);
74 /* Get the response */
75 if(!InternetQueryDataAvailable(hHTTPRequest
, DataLength
, 0, 0))
77 StringOut("InternetQueryDataAvailable failed\n");
81 *Data
= HeapAlloc(hProcessHeap
, 0, *DataLength
+ 1);
83 if(!InternetReadFile(hHTTPRequest
, *Data
, *DataLength
, DataLength
))
85 StringOut("InternetReadFile failed\n");
89 (*Data
)[*DataLength
] = 0;
91 InternetCloseHandle(hHTTPRequest
);
92 InternetCloseHandle(hHTTP
);
93 InternetCloseHandle(hInet
);
99 * Determines whether a string contains entirely numeric values.
102 * The string to check.
105 * TRUE if the string is entirely numeric, FALSE otherwise.
108 IsNumber(PCHAR Input
)
123 * Requests a Test ID from the web service for our test run.
126 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
129 * Returns the Test ID as a CHAR array if successful or NULL otherwise.
132 GetTestID(TESTTYPES TestType
)
134 const CHAR GetTestIDAction
[] = "gettestid";
139 /* Build the full request string */
140 DataLength
= sizeof(ActionProp
) - 1 + sizeof(GetTestIDAction
) - 1;
141 DataLength
+= strlen(AuthenticationRequestString
) + strlen(SystemInfoRequestString
);
142 DataLength
+= sizeof(TestTypeProp
) - 1;
147 DataLength
+= sizeof(WineTestType
) - 1;
151 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
152 strcpy(Data
, ActionProp
);
153 strcat(Data
, GetTestIDAction
);
154 strcat(Data
, AuthenticationRequestString
);
155 strcat(Data
, SystemInfoRequestString
);
156 strcat(Data
, TestTypeProp
);
161 strcat(Data
, WineTestType
);
165 if(!IntDoRequest(&Data
, &DataLength
))
168 /* Verify that this is really a number */
171 StringOut("Expected Test ID, but received:\n");
174 HeapFree(hProcessHeap
, 0, Data
);
182 * Requests a Suite ID from the web service for our module/test combination.
185 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
188 * Pointer to a *_GETSUITEID_DATA structure appropriate for our selected test type.
189 * Contains other input information for this request.
192 * Returns the Suite ID as a CHAR array if successful or NULL otherwise.
195 GetSuiteID(TESTTYPES TestType
, const PVOID TestData
)
197 const CHAR GetSuiteIDAction
[] = "getsuiteid";
198 const CHAR ModuleProp
[] = "&module=";
199 const CHAR TestProp
[] = "&test=";
203 PWINE_GETSUITEID_DATA WineData
;
205 DataLength
= sizeof(ActionProp
) - 1 + sizeof(GetSuiteIDAction
) - 1;
206 DataLength
+= strlen(AuthenticationRequestString
);
207 DataLength
+= sizeof(TestTypeProp
) - 1;
212 DataLength
+= sizeof(WineTestType
) - 1;
214 WineData
= (PWINE_GETSUITEID_DATA
)TestData
;
215 DataLength
+= sizeof(ModuleProp
) - 1;
216 DataLength
+= strlen(WineData
->Module
);
217 DataLength
+= sizeof(TestProp
) - 1;
218 DataLength
+= strlen(WineData
->Test
);
223 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
224 strcpy(Data
, ActionProp
);
225 strcat(Data
, GetSuiteIDAction
);
226 strcat(Data
, AuthenticationRequestString
);
227 strcat(Data
, TestTypeProp
);
232 strcat(Data
, WineTestType
);
234 /* Stupid GCC and MSVC: WineData is already initialized above, still it's reported as a potentially uninitialized variable :-( */
235 WineData
= (PWINE_GETSUITEID_DATA
)TestData
;
236 strcat(Data
, ModuleProp
);
237 strcat(Data
, WineData
->Module
);
238 strcat(Data
, TestProp
);
239 strcat(Data
, WineData
->Test
);
244 if(!IntDoRequest(&Data
, &DataLength
))
247 /* Verify that this is really a number */
250 StringOut("Expected Suite ID, but received:\n");
253 HeapFree(hProcessHeap
, 0, Data
);
261 * Submits the result of one test call to the web service.
264 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
267 * Pointer to a *_SUBMIT_DATA structure appropriate for our selected test type.
268 * Contains other input information for this request.
271 * TRUE if everything went well, FALSE otherwise.
274 Submit(TESTTYPES TestType
, const PVOID TestData
)
276 const CHAR SubmitAction
[] = "submit";
277 const CHAR SuiteIDProp
[] = "&suiteid=";
278 const CHAR LogProp
[] = "&log=";
283 PGENERAL_SUBMIT_DATA GeneralData
;
284 PWINE_SUBMIT_DATA WineData
;
286 /* Compute the full length of the POST data */
287 DataLength
= sizeof(ActionProp
) - 1 + sizeof(SubmitAction
) - 1;
288 DataLength
+= strlen(AuthenticationRequestString
);
290 GeneralData
= (PGENERAL_SUBMIT_DATA
)TestData
;
291 DataLength
+= sizeof(TestIDProp
) - 1;
292 DataLength
+= strlen(GeneralData
->TestID
);
293 DataLength
+= sizeof(SuiteIDProp
) - 1;
294 DataLength
+= strlen(GeneralData
->SuiteID
);
296 /* The rest of the POST data depends on the test type */
297 DataLength
+= sizeof(TestTypeProp
) - 1;
302 DataLength
+= sizeof(WineTestType
) - 1;
304 WineData
= (PWINE_SUBMIT_DATA
)TestData
;
305 DataLength
+= sizeof(LogProp
) - 1;
306 DataLength
+= 3 * strlen(WineData
->Log
);
311 /* Now collect all the POST data */
312 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
313 strcpy(Data
, ActionProp
);
314 strcat(Data
, SubmitAction
);
315 strcat(Data
, AuthenticationRequestString
);
317 strcat(Data
, TestIDProp
);
318 strcat(Data
, GeneralData
->TestID
);
319 strcat(Data
, SuiteIDProp
);
320 strcat(Data
, GeneralData
->SuiteID
);
322 strcat(Data
, TestTypeProp
);
327 strcat(Data
, WineTestType
);
329 /* Stupid GCC and MSVC: WineData is already initialized above, still it's reported as a potentially uninitialized variable :-( */
330 WineData
= (PWINE_SUBMIT_DATA
)TestData
;
332 strcat(Data
, LogProp
);
333 pData
= Data
+ strlen(Data
);
334 EscapeString(pData
, WineData
->Log
);
339 /* DataLength still contains the maximum length of the buffer, but not the actual data length we need for the request.
340 Determine that one now. */
341 DataLength
= strlen(Data
);
343 /* Send all the stuff */
344 if(!IntDoRequest(&Data
, &DataLength
))
347 /* Output the response */
348 StringOut("The server responded:\n");
352 if(!strcmp(Data
, "OK"))
359 * Finishes a test run for the web service.
362 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
365 * Pointer to a *_FINISH_DATA structure appropriate for our selected test type.
366 * Contains other input information for this request.
369 * TRUE if everything went well, FALSE otherwise.
372 Finish(TESTTYPES TestType
, const PVOID TestData
)
374 const CHAR FinishAction
[] = "finish";
378 PGENERAL_FINISH_DATA GeneralData
;
380 /* Build the full request string */
381 DataLength
= sizeof(ActionProp
) - 1 + sizeof(FinishAction
) - 1;
382 DataLength
+= strlen(AuthenticationRequestString
);
384 GeneralData
= (PGENERAL_FINISH_DATA
)TestData
;
385 DataLength
+= sizeof(TestIDProp
) - 1;
386 DataLength
+= strlen(GeneralData
->TestID
);
388 DataLength
+= sizeof(TestTypeProp
) - 1;
393 DataLength
+= sizeof(WineTestType
) - 1;
397 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
398 strcpy(Data
, ActionProp
);
399 strcat(Data
, FinishAction
);
400 strcat(Data
, AuthenticationRequestString
);
401 strcat(Data
, TestIDProp
);
402 strcat(Data
, GeneralData
->TestID
);
403 strcat(Data
, TestTypeProp
);
408 strcat(Data
, WineTestType
);
412 if(!IntDoRequest(&Data
, &DataLength
))
415 if(!strcmp(Data
, "OK"))