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");
173 HeapFree(hProcessHeap
, 0, Data
);
181 * Requests a Suite ID from the web service for our module/test combination.
184 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
187 * Pointer to a *_GETSUITEID_DATA structure appropriate for our selected test type.
188 * Contains other input information for this request.
191 * Returns the Suite ID as a CHAR array if successful or NULL otherwise.
194 GetSuiteID(TESTTYPES TestType
, const PVOID TestData
)
196 const CHAR GetSuiteIDAction
[] = "getsuiteid";
197 const CHAR ModuleProp
[] = "&module=";
198 const CHAR TestProp
[] = "&test=";
202 PWINE_GETSUITEID_DATA WineData
;
204 DataLength
= sizeof(ActionProp
) - 1 + sizeof(GetSuiteIDAction
) - 1;
205 DataLength
+= strlen(AuthenticationRequestString
);
206 DataLength
+= sizeof(TestTypeProp
) - 1;
211 DataLength
+= sizeof(WineTestType
) - 1;
213 WineData
= (PWINE_GETSUITEID_DATA
)TestData
;
214 DataLength
+= sizeof(ModuleProp
) - 1;
215 DataLength
+= strlen(WineData
->Module
);
216 DataLength
+= sizeof(TestProp
) - 1;
217 DataLength
+= strlen(WineData
->Test
);
222 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
223 strcpy(Data
, ActionProp
);
224 strcat(Data
, GetSuiteIDAction
);
225 strcat(Data
, AuthenticationRequestString
);
226 strcat(Data
, TestTypeProp
);
231 strcat(Data
, WineTestType
);
233 /* Stupid GCC and MSVC: WineData is already initialized above, still it's reported as a potentially uninitialized variable :-( */
234 WineData
= (PWINE_GETSUITEID_DATA
)TestData
;
235 strcat(Data
, ModuleProp
);
236 strcat(Data
, WineData
->Module
);
237 strcat(Data
, TestProp
);
238 strcat(Data
, WineData
->Test
);
243 if(!IntDoRequest(&Data
, &DataLength
))
246 /* Verify that this is really a number */
249 StringOut("Expected Suite ID, but received:\n");
251 HeapFree(hProcessHeap
, 0, Data
);
259 * Submits the result of one test call to the web service.
262 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
265 * Pointer to a *_SUBMIT_DATA structure appropriate for our selected test type.
266 * Contains other input information for this request.
269 * TRUE if everything went well, FALSE otherwise.
272 Submit(TESTTYPES TestType
, const PVOID TestData
)
274 const CHAR SubmitAction
[] = "submit";
275 const CHAR SuiteIDProp
[] = "&suiteid=";
276 const CHAR LogProp
[] = "&log=";
281 PGENERAL_SUBMIT_DATA GeneralData
;
282 PWINE_SUBMIT_DATA WineData
;
284 /* Compute the full length of the POST data */
285 DataLength
= sizeof(ActionProp
) - 1 + sizeof(SubmitAction
) - 1;
286 DataLength
+= strlen(AuthenticationRequestString
);
288 GeneralData
= (PGENERAL_SUBMIT_DATA
)TestData
;
289 DataLength
+= sizeof(TestIDProp
) - 1;
290 DataLength
+= strlen(GeneralData
->TestID
);
291 DataLength
+= sizeof(SuiteIDProp
) - 1;
292 DataLength
+= strlen(GeneralData
->SuiteID
);
294 /* The rest of the POST data depends on the test type */
295 DataLength
+= sizeof(TestTypeProp
) - 1;
300 DataLength
+= sizeof(WineTestType
) - 1;
302 WineData
= (PWINE_SUBMIT_DATA
)TestData
;
303 DataLength
+= sizeof(LogProp
) - 1;
304 DataLength
+= 3 * strlen(WineData
->Log
);
309 /* Now collect all the POST data */
310 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
311 strcpy(Data
, ActionProp
);
312 strcat(Data
, SubmitAction
);
313 strcat(Data
, AuthenticationRequestString
);
315 strcat(Data
, TestIDProp
);
316 strcat(Data
, GeneralData
->TestID
);
317 strcat(Data
, SuiteIDProp
);
318 strcat(Data
, GeneralData
->SuiteID
);
320 strcat(Data
, TestTypeProp
);
325 strcat(Data
, WineTestType
);
327 /* Stupid GCC and MSVC: WineData is already initialized above, still it's reported as a potentially uninitialized variable :-( */
328 WineData
= (PWINE_SUBMIT_DATA
)TestData
;
330 strcat(Data
, LogProp
);
331 pData
= Data
+ strlen(Data
);
332 EscapeString(pData
, WineData
->Log
);
337 /* DataLength still contains the maximum length of the buffer, but not the actual data length we need for the request.
338 Determine that one now. */
339 DataLength
= strlen(Data
);
341 /* Send all the stuff */
342 if(!IntDoRequest(&Data
, &DataLength
))
345 /* Output the response */
346 StringOut("The server responded:\n");
350 if(!strcmp(Data
, "OK"))
357 * Finishes a test run for the web service.
360 * Value from the TESTTYPES enum indicating the type of test we are about to submit.
363 * Pointer to a *_FINISH_DATA structure appropriate for our selected test type.
364 * Contains other input information for this request.
367 * TRUE if everything went well, FALSE otherwise.
370 Finish(TESTTYPES TestType
, const PVOID TestData
)
372 const CHAR FinishAction
[] = "finish";
376 PGENERAL_FINISH_DATA GeneralData
;
378 /* Build the full request string */
379 DataLength
= sizeof(ActionProp
) - 1 + sizeof(FinishAction
) - 1;
380 DataLength
+= strlen(AuthenticationRequestString
);
382 GeneralData
= (PGENERAL_FINISH_DATA
)TestData
;
383 DataLength
+= sizeof(TestIDProp
) - 1;
384 DataLength
+= strlen(GeneralData
->TestID
);
386 DataLength
+= sizeof(TestTypeProp
) - 1;
391 DataLength
+= sizeof(WineTestType
) - 1;
395 Data
= HeapAlloc(hProcessHeap
, 0, DataLength
+ 1);
396 strcpy(Data
, ActionProp
);
397 strcat(Data
, FinishAction
);
398 strcat(Data
, AuthenticationRequestString
);
399 strcat(Data
, TestIDProp
);
400 strcat(Data
, GeneralData
->TestID
);
401 strcat(Data
, TestTypeProp
);
406 strcat(Data
, WineTestType
);
410 if(!IntDoRequest(&Data
, &DataLength
))
413 if(!strcmp(Data
, "OK"))