ReactOS 0.4.16-dev-1020-gf135cab
CWineTest Class Reference

#include <CWineTest.h>

Inheritance diagram for CWineTest:
Collaboration diagram for CWineTest:

Public Member Functions

 CWineTest ()
 
 ~CWineTest ()
 
void Run ()
 
virtual void Run ()=0
 

Private Member Functions

bool GetNextFile ()
 
bool GetNextTest ()
 
CTestInfoGetNextTestInfo ()
 
DWORD DoListCommand ()
 
void RunTest (CTestInfo *TestInfo)
 

Private Attributes

HANDLE m_hFind
 
PCHAR m_ListBuffer
 
string m_CurrentTest
 
wstring m_CurrentFile
 
wstring m_CurrentListCommand
 
wstring m_TestPath
 

Detailed Description

Definition at line 8 of file CWineTest.h.

Constructor & Destructor Documentation

◆ CWineTest()

CWineTest::CWineTest ( )

Constructs a CWineTest object.

Definition at line 20 of file CWineTest.cpp.

22{
23 WCHAR wszDirectory[MAX_PATH];
24
25 /* Set up m_TestPath */
26 if (GetEnvironmentVariableW(L"ROSAUTOTEST_DIR", wszDirectory, MAX_PATH))
27 {
28 m_TestPath = wszDirectory;
29 if (*m_TestPath.rbegin() != L'\\')
30 m_TestPath += L'\\';
31 }
32 else
33 {
34 if (!GetWindowsDirectoryW(wszDirectory, MAX_PATH))
35 FATAL("GetWindowsDirectoryW failed\n");
36
37 m_TestPath = wszDirectory;
38 m_TestPath += L"\\bin\\";
39 }
40}
PCHAR m_ListBuffer
Definition: CWineTest.h:12
wstring m_TestPath
Definition: CWineTest.h:16
HANDLE m_hFind
Definition: CWineTest.h:11
#define NULL
Definition: types.h:112
#define GetEnvironmentVariableW(x, y, z)
Definition: compat.h:755
#define MAX_PATH
Definition: compat.h:34
UINT WINAPI GetWindowsDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2352
#define FATAL(Message)
Definition: precomp.h:57
#define L(x)
Definition: ntvdm.h:50
__wchar_t WCHAR
Definition: xmlstorage.h:180

◆ ~CWineTest()

CWineTest::~CWineTest ( )

Destructs a CWineTest object.

Definition at line 45 of file CWineTest.cpp.

46{
47 if(m_hFind)
49
50 if(m_ListBuffer)
51 delete m_ListBuffer;
52}
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502

Member Function Documentation

◆ DoListCommand()

DWORD CWineTest::DoListCommand ( )
private

Executes the –list command of a module test file to get information about the available tests.

Returns
The number of bytes we read into the m_ListBuffer member variable by capturing the output of the –list command.

Definition at line 144 of file CWineTest.cpp.

145{
146 DWORD BytesAvailable;
147 DWORD Temp;
148 wstring CommandLine;
149 CPipe Pipe;
150
151 /* Build the command line */
152 CommandLine = m_TestPath;
153 CommandLine += m_CurrentFile;
154 CommandLine += L" --list";
155
156 {
157 /* Start the process for getting all available tests */
158 CPipedProcess Process(CommandLine, Pipe);
159
160 /* Wait till this process ended */
161 if(WaitForSingleObject(Process.GetProcessHandle(), ListTimeout) == WAIT_FAILED)
162 TESTEXCEPTION("WaitForSingleObject failed for the test list\n");
163 }
164
165 /* Read the output data into a buffer */
166 if(!Pipe.Peek(NULL, 0, NULL, &BytesAvailable))
167 TESTEXCEPTION("CPipe::Peek failed for the test list\n");
168
169 /* Check if we got any */
170 if(!BytesAvailable)
171 {
173
174 ss << "The --list command did not return any data for " << UnicodeToAscii(m_CurrentFile) << endl;
175 TESTEXCEPTION(ss.str());
176 }
177
178 /* Read the data */
179 m_ListBuffer = new char[BytesAvailable];
180
181 if(Pipe.Read(m_ListBuffer, BytesAvailable, &Temp, INFINITE) != ERROR_SUCCESS)
182 TESTEXCEPTION("CPipe::Read failed\n");
183
184 return BytesAvailable;
185}
static const DWORD ListTimeout
Definition: CWineTest.cpp:10
basic_ostream< _CharT, _Traits > &_STLP_CALL endl(basic_ostream< _CharT, _Traits > &__os)
Definition: _ostream.h:357
Definition: CPipe.h:10
wstring m_CurrentFile
Definition: CWineTest.h:14
#define ERROR_SUCCESS
Definition: deptool.c:10
#define INFINITE
Definition: serial.h:102
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
#define ss
Definition: i386-dis.c:441
string UnicodeToAscii(PCWSTR UnicodeString)
Definition: tools.cpp:261
#define TESTEXCEPTION(Message)
Definition: precomp.h:59
__crt_unique_heap_ptr< wchar_t > const wstring(_malloc_crt_t(wchar_t, maxsize))
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
_In_ WDFUSBPIPE Pipe
Definition: wdfusb.h:1741
#define WAIT_FAILED
Definition: winbase.h:439

Referenced by GetNextTest().

◆ GetNextFile()

bool CWineTest::GetNextFile ( )
private

Gets the next module test file using the FindFirstFileW/FindNextFileW API.

Returns
true if we found a next file, otherwise false.

Definition at line 61 of file CWineTest.cpp.

62{
63 bool FoundFile = false;
65
66 /* Did we already begin searching for files? */
67 if (m_hFind)
68 {
69 /* Then get the next file (if any) */
71 {
72 // printf("cFileName is '%S'.\n", fd.cFileName);
73 /* If it was NOT rosautotest.exe then proceed as normal */
74 if (_wcsicmp(fd.cFileName, TestName) != 0)
75 {
76 FoundFile = true;
77 }
78 else
79 {
80 /* It was rosautotest.exe so get the next file (if any) */
82 {
83 FoundFile = true;
84 }
85 // printf("cFileName is '%S'.\n", fd.cFileName);
86 }
87 }
88 }
89 else
90 {
91 /* Start searching for test files */
92 wstring FindPath = m_TestPath;
93
94 /* Did the user specify a module? */
95 if(Configuration.GetModule().empty())
96 {
97 /* No module, so search for all files in that directory */
98 FindPath += L"*.exe";
99 }
100 else
101 {
102 /* Search for files with the pattern "modulename_*" */
103 FindPath += Configuration.GetModule();
104 FindPath += L"_*.exe";
105 }
106
107 /* Search for the first file and check whether we got one */
108 m_hFind = FindFirstFileW(FindPath.c_str(), &fd);
109
110 /* If we returned a good handle */
112 {
113 // printf("cFileName is '%S'.\n", fd.cFileName);
114 /* If it was NOT rosautotest.exe then proceed as normal */
115 if (_wcsicmp(fd.cFileName, TestName) != 0)
116 {
117 FoundFile = true;
118 }
119 else
120 {
121 /* It was rosautotest.exe so get the next file (if any) */
122 if (FindNextFileW(m_hFind, &fd))
123 {
124 FoundFile = true;
125 }
126 // printf("cFileName is '%S'.\n", fd.cFileName);
127 }
128 }
129 }
130
131 if(FoundFile)
132 m_CurrentFile = fd.cFileName;
133
134 return FoundFile;
135}
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
HANDLE WINAPI FindFirstFileW(IN LPCWSTR lpFileName, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:320
BOOL WINAPI FindNextFileW(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAW lpFindFileData)
Definition: find.c:382
WCHAR TestName[MAX_PATH]
Definition: main.cpp:13
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static int fd
Definition: io.c:51
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_INTERRUPT_CONFIG Configuration
Definition: wdfinterrupt.h:374

Referenced by GetNextTestInfo().

◆ GetNextTest()

bool CWineTest::GetNextTest ( )
private

Gets the next test from m_ListBuffer, which was filled with information from the –list command.

Returns
true if a next test was found, otherwise false.

Definition at line 194 of file CWineTest.cpp.

195{
196 PCHAR pEnd;
197 static DWORD BufferSize;
198 static PCHAR pStart;
199
200 if(!m_ListBuffer)
201 {
202 /* Perform the --list command */
204
205 /* Move the pointer to the first test */
206 pStart = strchr(m_ListBuffer, '\n');
207 pStart += 5;
208 }
209
210 /* If we reach the buffer size, we finished analyzing the output of this test */
211 if(pStart >= (m_ListBuffer + BufferSize))
212 {
213 /* Clear m_CurrentFile to indicate that */
214 m_CurrentFile.clear();
215
216 /* Also free the memory for the list buffer */
217 delete[] m_ListBuffer;
219
220 return false;
221 }
222
223 /* Get start and end of this test name */
224 pEnd = pStart;
225
226 while(*pEnd != '\r')
227 ++pEnd;
228
229 /* Store the test name */
230 m_CurrentTest = string(pStart, pEnd);
231
232 /* Move the pointer to the next test */
233 pStart = pEnd + 6;
234
235 return true;
236}
char * strchr(const char *String, int ch)
Definition: utclib.c:501
string m_CurrentTest
Definition: CWineTest.h:13
DWORD DoListCommand()
Definition: CWineTest.cpp:144
#define BufferSize
Definition: mmc.h:75
char * PCHAR
Definition: typedefs.h:51
_In_ WDFMEMORY _Out_opt_ size_t * BufferSize
Definition: wdfmemory.h:254

Referenced by GetNextTestInfo().

◆ GetNextTestInfo()

CTestInfo * CWineTest::GetNextTestInfo ( )
privatevirtual

Interface to CTestList-derived classes for getting all information about the next test to be run.

Returns
Returns a pointer to a CTestInfo object containing all available information about the next test.

Implements CTest.

Definition at line 245 of file CWineTest.cpp.

246{
247 while(!m_CurrentFile.empty() || GetNextFile())
248 {
249 /* The user asked for a list of all modules */
250 if (Configuration.ListModulesOnly())
251 {
252 std::stringstream ss;
253 ss << "Module: " << UnicodeToAscii(m_CurrentFile) << endl;
254 m_CurrentFile.clear();
255 StringOut(ss.str());
256 continue;
257 }
258
259 try
260 {
261 while(GetNextTest())
262 {
263 /* If the user specified a test through the command line, check this here */
264 if(!Configuration.GetTest().empty() && Configuration.GetTest() != m_CurrentTest)
265 continue;
266
267 {
268 auto_ptr<CTestInfo> TestInfo(new CTestInfo());
269 size_t UnderscorePosition;
270
271 /* Build the command line */
272 TestInfo->CommandLine = m_TestPath;
273 TestInfo->CommandLine += m_CurrentFile;
274 TestInfo->CommandLine += ' ';
275 TestInfo->CommandLine += AsciiToUnicode(m_CurrentTest);
276
277 /* Store the Module name */
278 UnderscorePosition = m_CurrentFile.find_last_of('_');
279
280 if(UnderscorePosition == m_CurrentFile.npos)
281 {
283
284 ss << "Invalid test file name: " << UnicodeToAscii(m_CurrentFile) << endl;
286 }
287
288 TestInfo->Module = UnicodeToAscii(m_CurrentFile.substr(0, UnderscorePosition));
289
290 /* Store the test */
291 TestInfo->Test = m_CurrentTest;
292
293 return TestInfo.release();
294 }
295 }
296 }
297 catch(CTestException& e)
298 {
300
301 ss << "An exception occurred trying to list tests for: " << UnicodeToAscii(m_CurrentFile) << endl;
302 StringOut(ss.str());
303 StringOut(e.GetMessage());
304 StringOut("\n");
305 m_CurrentFile.clear();
306 delete[] m_ListBuffer;
307 }
308 }
309
310 return NULL;
311}
bool GetNextFile()
Definition: CWineTest.cpp:61
bool GetNextTest()
Definition: CWineTest.cpp:194
#define e
Definition: ke_i.h:82
#define SSEXCEPTION
Definition: precomp.h:58
string StringOut(const string &String, bool forcePrint=true)
Definition: tools.cpp:96
wstring AsciiToUnicode(const char *AsciiString)
Definition: tools.cpp:220

◆ Run()

void CWineTest::Run ( )
virtual

Interface to other classes for running all desired Wine tests.

Implements CTest.

Definition at line 397 of file CWineTest.cpp.

398{
400 auto_ptr<CWebService> WebService;
401 CTestInfo* TestInfo;
402 DWORD ErrorMode;
403
404 /* The virtual test list is of course faster, so it should be preferred over
405 the journaled one.
406 Enable the journaled one only in case ...
407 - we're running under ReactOS (as the journal is only useful in conjunction with sysreg2)
408 - we shall keep information for Crash Recovery
409 - and the user didn't specify a module (then doing Crash Recovery doesn't really make sense) */
410 if(Configuration.IsReactOS() && Configuration.DoCrashRecovery() && Configuration.GetModule().empty())
411 {
412 /* Use a test list with a permanent journal */
413 TestList.reset(new CJournaledTestList(this));
414 }
415 else
416 {
417 /* Use the fast virtual test list with no additional overhead */
418 TestList.reset(new CVirtualTestList(this));
419 }
420
421 /* Initialize the Web Service interface if required */
422 if(Configuration.DoSubmit())
423 WebService.reset(new CWebService());
424
425 /* Disable error dialogs if we're running in non-interactive mode */
426 if(!Configuration.IsInteractive())
428
429 /* Get information for each test to run */
430 while((TestInfo = TestList->GetNextTestInfo()) != 0)
431 {
432 auto_ptr<CTestInfo> TestInfoPtr(TestInfo);
433
434 RunTest(TestInfo);
435
436 if(Configuration.DoSubmit() && !TestInfo->Log.empty())
437 WebService->Submit("wine", TestInfo);
438
439 StringOut("\n\n");
440 }
441
442 /* We're done with all tests. Finish this run */
443 if(Configuration.DoSubmit())
444 WebService->Finish("wine");
445
446 /* Restore the original error mode */
447 if(!Configuration.IsInteractive())
448 SetErrorMode(ErrorMode);
449}
static KSTART_ROUTINE RunTest
Definition: NpfsConnect.c:238
string Log
Definition: CTestInfo.h:14
friend class CJournaledTestList
Definition: CTest.h:17
friend class CVirtualTestList
Definition: CTest.h:18
void reset(_Tp *__px=0) _STLP_NOTHROW
Definition: _auto_ptr.h:59
UINT WINAPI SetErrorMode(IN UINT uMode)
Definition: except.c:751
#define SEM_FAILCRITICALERRORS
Definition: rtltypes.h:69
#define SEM_NOGPFAULTERRORBOX
Definition: rtltypes.h:70
EH_STD::__list__< TestClass, eh_allocator(TestClass) > TestList
Definition: test_list.cpp:31

Referenced by wmain().

◆ RunTest()

void CWineTest::RunTest ( CTestInfo TestInfo)
private

Runs a Wine test and captures the output

Parameters
TestInfoPointer to a CTestInfo object containing information about the test. Will contain the test log afterwards if the user wants to submit data.

Definition at line 321 of file CWineTest.cpp.

322{
323 DWORD BytesAvailable;
324 stringstream ss, ssFinish;
326 float TotalTime;
327 string tailString;
328 CPipe Pipe;
329 char Buffer[1024];
330
331 ss << "Running Wine Test, Module: " << TestInfo->Module << ", Test: " << TestInfo->Test << endl;
332 StringOut(ss.str());
333
335
337
338 try
339 {
340 /* Execute the test */
342
343 /* Receive all the data from the pipe */
344 for (;;)
345 {
346 DWORD dwReadResult = Pipe.Read(Buffer, sizeof(Buffer) - 1, &BytesAvailable, ProcessActivityTimeout);
347 if (dwReadResult == ERROR_SUCCESS)
348 {
349 /* Output text through StringOut, even while the test is still running */
350 Buffer[BytesAvailable] = 0;
351 tailString = StringOut(tailString.append(string(Buffer)), false);
352
353 if (Configuration.DoSubmit())
354 TestInfo->Log += Buffer;
355 }
356 else if (dwReadResult == ERROR_BROKEN_PIPE)
357 {
358 // The process finished and has been terminated.
359 break;
360 }
361 else if (dwReadResult == WAIT_TIMEOUT)
362 {
363 // The process activity timeout above has elapsed without any new data.
364 TESTEXCEPTION("Timeout while waiting for the test process\n");
365 }
366 else
367 {
368 // An unexpected error.
369 TESTEXCEPTION("CPipe::Read failed for the test run\n");
370 }
371 }
372 }
373 catch(CTestException& e)
374 {
375 if(!tailString.empty())
376 StringOut(tailString);
377 tailString.clear();
378 StringOut(e.GetMessage());
379 TestInfo->Log += e.GetMessage();
380 }
381
382 /* Print what's left */
383 if(!tailString.empty())
384 StringOut(tailString);
385
386 TotalTime = ((float)GetTickCount() - StartTime)/1000;
387 ssFinish << "Test " << TestInfo->Test << " completed in ";
388 ssFinish << setprecision(2) << fixed << TotalTime << " seconds." << endl;
389 StringOut(ssFinish.str());
390 TestInfo->Log += ssFinish.str();
391}
static const DWORD ProcessActivityTimeout
Definition: CWineTest.cpp:14
_STLP_PRIV _Ios_Manip_1< streamsize > _STLP_CALL setprecision(int __n)
Definition: _iomanip.h:119
Definition: bufpool.h:45
wstring CommandLine
Definition: CTestInfo.h:11
string Module
Definition: CTestInfo.h:12
string Test
Definition: CTestInfo.h:13
void clear()
Definition: _string.h:421
bool empty() const
Definition: _string.h:428
_Self & append(const _CharT *__first, const _CharT *__last)
Definition: _string.h:509
_String str() const
Definition: _sstream.h:230
#define WAIT_TIMEOUT
Definition: dderror.h:14
BOOL WINAPI SetCurrentDirectoryW(IN LPCWSTR lpPathName)
Definition: path.c:2249
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
static LARGE_INTEGER StartTime
Definition: sys_arch.c:13
static float(__cdecl *square_half_float)(float x
#define ERROR_BROKEN_PIPE
Definition: winerror.h:183

Member Data Documentation

◆ m_CurrentFile

wstring CWineTest::m_CurrentFile
private

Definition at line 14 of file CWineTest.h.

Referenced by DoListCommand(), GetNextFile(), GetNextTest(), and GetNextTestInfo().

◆ m_CurrentListCommand

wstring CWineTest::m_CurrentListCommand
private

Definition at line 15 of file CWineTest.h.

◆ m_CurrentTest

string CWineTest::m_CurrentTest
private

Definition at line 13 of file CWineTest.h.

Referenced by GetNextTest(), and GetNextTestInfo().

◆ m_hFind

HANDLE CWineTest::m_hFind
private

Definition at line 11 of file CWineTest.h.

Referenced by GetNextFile(), and ~CWineTest().

◆ m_ListBuffer

PCHAR CWineTest::m_ListBuffer
private

Definition at line 12 of file CWineTest.h.

Referenced by DoListCommand(), GetNextTest(), GetNextTestInfo(), and ~CWineTest().

◆ m_TestPath

wstring CWineTest::m_TestPath
private

Definition at line 16 of file CWineTest.h.

Referenced by CWineTest(), DoListCommand(), GetNextFile(), GetNextTestInfo(), and RunTest().


The documentation for this class was generated from the following files: