13c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#ifndef _XSWIN32TESTPROCESS_HPP
23c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#define _XSWIN32TESTPROCESS_HPP
33c827367444ee418f129b2c238299f49d3264554Jarkko Poyry/*-------------------------------------------------------------------------
43c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * drawElements Quality Program Execution Server
53c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * ---------------------------------------------
63c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
73c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Copyright 2014 The Android Open Source Project
83c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
93c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Licensed under the Apache License, Version 2.0 (the "License");
103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * you may not use this file except in compliance with the License.
113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * You may obtain a copy of the License at
123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *      http://www.apache.org/licenses/LICENSE-2.0
143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * Unless required by applicable law or agreed to in writing, software
163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * distributed under the License is distributed on an "AS IS" BASIS,
173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * See the License for the specific language governing permissions and
193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * limitations under the License.
203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *
213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*!
223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \file
233c827367444ee418f129b2c238299f49d3264554Jarkko Poyry * \brief TestProcess implementation for Win32.
243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry *//*--------------------------------------------------------------------*/
253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xsDefs.hpp"
273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "xsTestProcess.hpp"
283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include "deThread.hpp"
293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <vector>
313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <string>
323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
333c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(VC_EXTRALEAN)
343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	define VC_EXTRALEAN 1
353c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(WIN32_LEAN_AND_MEAN)
373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	define WIN32_LEAN_AND_MEAN 1
383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#if !defined(NOMINMAX)
403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#	define NOMINMAX 1
413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif
423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#include <windows.h>
433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
443c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace xs
453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
463c827367444ee418f129b2c238299f49d3264554Jarkko Poyrynamespace win32
473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
493c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Error : public std::runtime_error
503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
513c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
523c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							Error				(DWORD error, const char* msg);
533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
543c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	DWORD					m_error;
563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
583c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Event
593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
603c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							Event				(bool manualReset, bool initialState);
623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~Event				(void);
633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					setSignaled			(void);
653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					reset				(void);
663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HANDLE					getHandle			(void) const { return m_handle; }
683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
693c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							Event				(const Event& other);
713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Event&					operator=			(const Event& other);
723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HANDLE					m_handle;
743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
763c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass CaseListWriter : public de::Thread
773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
783c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
793c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							CaseListWriter		(void);
803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~CaseListWriter		(void);
813c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					start				(const char* caseList, HANDLE dst);
833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					stop				(void);
843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					run					(void);
863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
873c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::vector<char>		m_caseList;
893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HANDLE					m_dst;
903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Event					m_cancelEvent;
913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
933c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass FileReader : public de::Thread
943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
953c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							FileReader			(ThreadedByteBuffer* dst);
973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~FileReader			(void);
983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					start				(HANDLE file);
1003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					stop				(void);
1013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					run					(void);
1033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1043c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ThreadedByteBuffer*		m_dstBuf;
1063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HANDLE					m_handle;
1073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Event					m_cancelEvent;
1083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1103c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass TestLogReader
1113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1123c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							TestLogReader		(void);
1143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~TestLogReader		(void);
1153c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1163c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					start				(const char* filename);
1173c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					stop				(void);
1183c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1193c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					isRunning			(void) const					{ return m_reader.isStarted();					}
1203c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1213c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						read				(deUint8* dst, int numBytes)	{ return m_logBuffer.tryRead(numBytes, dst);	}
1223c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1233c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1243c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ThreadedByteBuffer		m_logBuffer;
1253c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HANDLE					m_logFile;
1263c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1273c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	FileReader				m_reader;
1283c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1293c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1303c827367444ee418f129b2c238299f49d3264554Jarkko Poyry// \note deProcess uses anonymous pipes that don't have overlapped IO available.
1313c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		 For ExecServer purposes we need overlapped IO, and it makes the handles
1323c827367444ee418f129b2c238299f49d3264554Jarkko Poyry//		 incompatible with deFile. Thus separate Process implementation is used for now.
1333c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Process
1343c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1353c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1363c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							Process				(void);
1373c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							~Process			(void);
1383c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1393c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					start				(const char* commandLine, const char* workingDirectory);
1403c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1413c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					waitForFinish		(void);
1423c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					terminate			(void);
1433c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					kill				(void);
1443c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1453c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	bool					isRunning			(void);
1463c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						getExitCode			(void) const { return m_exitCode;		}
1473c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1483c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HANDLE					getStdIn			(void) const { return m_standardIn;		}
1493c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HANDLE					getStdOut			(void) const { return m_standardOut;	}
1503c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HANDLE					getStdErr			(void) const { return m_standardErr;	}
1513c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1523c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1533c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							Process				(const Process& other);
1543c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Process&				operator=			(const Process& other);
1553c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1563c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					stopProcess			(bool kill);
1573c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	void					cleanupHandles		(void);
1583c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1593c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	enum State
1603c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	{
1613c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STATE_NOT_STARTED = 0,
1623c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STATE_RUNNING,
1633c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STATE_FINISHED,
1643c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1653c827367444ee418f129b2c238299f49d3264554Jarkko Poyry		STATE_LAST
1663c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	};
1673c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1683c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	State					m_state;
1693c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	int						m_exitCode;
1703c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1713c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	PROCESS_INFORMATION		m_procInfo;
1723c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HANDLE					m_standardIn;
1733c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HANDLE					m_standardOut;
1743c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	HANDLE					m_standardErr;
1753c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
1763c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1773c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // win32
1783c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1793c827367444ee418f129b2c238299f49d3264554Jarkko Poyryclass Win32TestProcess : public TestProcess
1803c827367444ee418f129b2c238299f49d3264554Jarkko Poyry{
1813c827367444ee418f129b2c238299f49d3264554Jarkko Poyrypublic:
1823c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							Win32TestProcess		(void);
1833c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual					~Win32TestProcess		(void);
1843c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1853c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			start					(const char* name, const char* params, const char* workingDir, const char* caseList);
1863c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			terminate				(void);
1873c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual void			cleanup					(void);
1883c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1893c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual bool			isRunning				(void);
1903c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual int				getExitCode				(void) const;
1913c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1923c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual int				readTestLog				(deUint8* dst, int numBytes);
1933c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	virtual int				readInfoLog				(deUint8* dst, int numBytes) { return m_infoBuffer.tryRead(numBytes, dst); }
1943c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1953c827367444ee418f129b2c238299f49d3264554Jarkko Poyryprivate:
1963c827367444ee418f129b2c238299f49d3264554Jarkko Poyry							Win32TestProcess		(const Win32TestProcess& other);
1973c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	Win32TestProcess&		operator=				(const Win32TestProcess& other);
1983c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
1993c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	win32::Process*			m_process;
2003c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	deUint64				m_processStartTime;
2013c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	std::string				m_logFileName;
2023c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2033c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	ThreadedByteBuffer		m_infoBuffer;
2043c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2053c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	// Threads.
2063c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	win32::CaseListWriter	m_caseListWriter;
2073c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	win32::FileReader		m_stdOutReader;
2083c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	win32::FileReader		m_stdErrReader;
2093c827367444ee418f129b2c238299f49d3264554Jarkko Poyry	win32::TestLogReader	m_testLogReader;
2103c827367444ee418f129b2c238299f49d3264554Jarkko Poyry};
2113c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2123c827367444ee418f129b2c238299f49d3264554Jarkko Poyry} // xs
2133c827367444ee418f129b2c238299f49d3264554Jarkko Poyry
2143c827367444ee418f129b2c238299f49d3264554Jarkko Poyry#endif // _XSWIN32TESTPROCESS_HPP
215