• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1  #ifndef _XSWIN32TESTPROCESS_HPP
2  #define _XSWIN32TESTPROCESS_HPP
3  /*-------------------------------------------------------------------------
4   * drawElements Quality Program Execution Server
5   * ---------------------------------------------
6   *
7   * Copyright 2014 The Android Open Source Project
8   *
9   * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   *
13   *      http://www.apache.org/licenses/LICENSE-2.0
14   *
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   *
21   *//*!
22   * \file
23   * \brief TestProcess implementation for Win32.
24   *//*--------------------------------------------------------------------*/
25  
26  #include "xsDefs.hpp"
27  #include "xsTestProcess.hpp"
28  #include "deThread.hpp"
29  
30  #include <vector>
31  #include <string>
32  
33  #if !defined(VC_EXTRALEAN)
34  #	define VC_EXTRALEAN 1
35  #endif
36  #if !defined(WIN32_LEAN_AND_MEAN)
37  #	define WIN32_LEAN_AND_MEAN 1
38  #endif
39  #if !defined(NOMINMAX)
40  #	define NOMINMAX 1
41  #endif
42  #include <windows.h>
43  
44  namespace xs
45  {
46  namespace win32
47  {
48  
49  class Error : public std::runtime_error
50  {
51  public:
52  							Error				(DWORD error, const char* msg);
53  
54  private:
55  	DWORD					m_error;
56  };
57  
58  class Event
59  {
60  public:
61  							Event				(bool manualReset, bool initialState);
62  							~Event				(void);
63  
64  	void					setSignaled			(void);
65  	void					reset				(void);
66  
getHandle(void) const67  	HANDLE					getHandle			(void) const { return m_handle; }
68  
69  private:
70  							Event				(const Event& other);
71  	Event&					operator=			(const Event& other);
72  
73  	HANDLE					m_handle;
74  };
75  
76  class CaseListWriter : public de::Thread
77  {
78  public:
79  							CaseListWriter		(void);
80  							~CaseListWriter		(void);
81  
82  	void					start				(const char* caseList, HANDLE dst);
83  	void					stop				(void);
84  
85  	void					run					(void);
86  
87  private:
88  	std::vector<char>		m_caseList;
89  	HANDLE					m_dst;
90  	Event					m_cancelEvent;
91  };
92  
93  class FileReader : public de::Thread
94  {
95  public:
96  							FileReader			(ThreadedByteBuffer* dst);
97  							~FileReader			(void);
98  
99  	void					start				(HANDLE file);
100  	void					stop				(void);
101  
102  	void					run					(void);
103  
104  private:
105  	ThreadedByteBuffer*		m_dstBuf;
106  	HANDLE					m_handle;
107  	Event					m_cancelEvent;
108  };
109  
110  class TestLogReader
111  {
112  public:
113  							TestLogReader		(void);
114  							~TestLogReader		(void);
115  
116  	void					start				(const char* filename);
117  	void					stop				(void);
118  
isRunning(void) const119  	bool					isRunning			(void) const					{ return m_reader.isStarted();					}
120  
read(deUint8 * dst,int numBytes)121  	int						read				(deUint8* dst, int numBytes)	{ return m_logBuffer.tryRead(numBytes, dst);	}
122  
123  private:
124  	ThreadedByteBuffer		m_logBuffer;
125  	HANDLE					m_logFile;
126  
127  	FileReader				m_reader;
128  };
129  
130  // \note deProcess uses anonymous pipes that don't have overlapped IO available.
131  //		 For ExecServer purposes we need overlapped IO, and it makes the handles
132  //		 incompatible with deFile. Thus separate Process implementation is used for now.
133  class Process
134  {
135  public:
136  							Process				(void);
137  							~Process			(void);
138  
139  	void					start				(const char* commandLine, const char* workingDirectory);
140  
141  	void					waitForFinish		(void);
142  	void					terminate			(void);
143  	void					kill				(void);
144  
145  	bool					isRunning			(void);
getExitCode(void) const146  	int						getExitCode			(void) const { return m_exitCode;		}
147  
getStdIn(void) const148  	HANDLE					getStdIn			(void) const { return m_standardIn;		}
getStdOut(void) const149  	HANDLE					getStdOut			(void) const { return m_standardOut;	}
getStdErr(void) const150  	HANDLE					getStdErr			(void) const { return m_standardErr;	}
151  
152  private:
153  							Process				(const Process& other);
154  	Process&				operator=			(const Process& other);
155  
156  	void					stopProcess			(bool kill);
157  	void					cleanupHandles		(void);
158  
159  	enum State
160  	{
161  		STATE_NOT_STARTED = 0,
162  		STATE_RUNNING,
163  		STATE_FINISHED,
164  
165  		STATE_LAST
166  	};
167  
168  	State					m_state;
169  	int						m_exitCode;
170  
171  	PROCESS_INFORMATION		m_procInfo;
172  	HANDLE					m_standardIn;
173  	HANDLE					m_standardOut;
174  	HANDLE					m_standardErr;
175  };
176  
177  } // win32
178  
179  class Win32TestProcess : public TestProcess
180  {
181  public:
182  							Win32TestProcess		(void);
183  	virtual					~Win32TestProcess		(void);
184  
185  	virtual void			start					(const char* name, const char* params, const char* workingDir, const char* caseList);
186  	virtual void			terminate				(void);
187  	virtual void			cleanup					(void);
188  
189  	virtual bool			isRunning				(void);
190  	virtual int				getExitCode				(void) const;
191  
192  	virtual int				readTestLog				(deUint8* dst, int numBytes);
readInfoLog(deUint8 * dst,int numBytes)193  	virtual int				readInfoLog				(deUint8* dst, int numBytes) { return m_infoBuffer.tryRead(numBytes, dst); }
194  
195  private:
196  							Win32TestProcess		(const Win32TestProcess& other);
197  	Win32TestProcess&		operator=				(const Win32TestProcess& other);
198  
199  	win32::Process*			m_process;
200  	deUint64				m_processStartTime;
201  	std::string				m_logFileName;
202  
203  	ThreadedByteBuffer		m_infoBuffer;
204  
205  	// Threads.
206  	win32::CaseListWriter	m_caseListWriter;
207  	win32::FileReader		m_stdOutReader;
208  	win32::FileReader		m_stdErrReader;
209  	win32::TestLogReader	m_testLogReader;
210  };
211  
212  } // xs
213  
214  #endif // _XSWIN32TESTPROCESS_HPP
215