mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 18:02:05 +00:00
- perform all boot tests in one launch of sysreg
- check for timeouts in windows version to see if qemu has hung svn path=/trunk/; revision=29356
This commit is contained in:
parent
384ad5f156
commit
86ff6bfeaa
6 changed files with 231 additions and 75 deletions
|
@ -11,8 +11,63 @@
|
|||
|
||||
namespace System_
|
||||
{
|
||||
|
||||
OsSupport::TimeEntryVector OsSupport::s_Entries;
|
||||
|
||||
void OsSupport::checkAlarms()
|
||||
{
|
||||
struct timeval tm;
|
||||
gettimeofday(&tm, 0);
|
||||
for (size_t i = 0; i < s_Entries.size(); i++)
|
||||
{
|
||||
long diffsec = s_Entries[i]->tm.tv_sec - tm.tv_sec;
|
||||
if (diffsec < 0)
|
||||
{
|
||||
cout << "terminating process pid:" << s_Entries[i]->pid << endl;
|
||||
terminateProcess(s_Entries[i]->pid, -2);
|
||||
free(s_Entries[i]);
|
||||
s_Entries.erase (s_Entries.begin () + i);
|
||||
i = MAX(0, i-1);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __LINUX__
|
||||
if (s_Entries.size())
|
||||
{
|
||||
long secs = Entries[i]->tm.tv_sec - tm.tv_sec;
|
||||
alarm(secs);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void OsSupport::cancelAlarms()
|
||||
{
|
||||
|
||||
#ifndef __LINUX__
|
||||
bool OsSupport::terminateProcess(OsSupport::ProcessID pid)
|
||||
if (s_hThread)
|
||||
{
|
||||
TerminateThread(s_hThread, 0);
|
||||
s_hThread = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
for(size_t i = 0; i < s_Entries.size(); i++)
|
||||
{
|
||||
free(s_Entries[i]);
|
||||
}
|
||||
|
||||
s_Entries.clear();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#ifndef __LINUX__
|
||||
|
||||
HANDLE OsSupport::s_hTimer = INVALID_HANDLE_VALUE;
|
||||
HANDLE OsSupport::s_hThread = 0;
|
||||
static HANDLE hTimer;
|
||||
bool OsSupport::terminateProcess(OsSupport::ProcessID pid, int exitcode)
|
||||
{
|
||||
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
|
||||
if (!hProcess)
|
||||
|
@ -20,7 +75,7 @@ namespace System_
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ret = TerminateProcess(hProcess, 0);
|
||||
bool ret = TerminateProcess(hProcess, exitcode);
|
||||
CloseHandle(hProcess);
|
||||
return ret;
|
||||
}
|
||||
|
@ -88,9 +143,50 @@ namespace System_
|
|||
return pid;
|
||||
}
|
||||
void OsSupport::delayExecution(long value)
|
||||
{
|
||||
Sleep(value * 1000);
|
||||
}
|
||||
{
|
||||
Sleep(value * 1000);
|
||||
}
|
||||
|
||||
DWORD WINAPI AlarmThread(LPVOID param)
|
||||
{
|
||||
LARGE_INTEGER liDueTime;
|
||||
|
||||
hTimer = CreateWaitableTimer(NULL, TRUE, _T("SysRegTimer"));
|
||||
if (!hTimer)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
liDueTime.QuadPart = -100000000LL;
|
||||
while(1)
|
||||
{
|
||||
SetWaitableTimer(hTimer, &liDueTime, 5000, NULL, NULL, FALSE);
|
||||
WaitForSingleObject(hTimer, INFINITE);
|
||||
OsSupport::checkAlarms ();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OsSupport::setAlarm(long secs, OsSupport::ProcessID pid)
|
||||
{
|
||||
|
||||
PTIME_ENTRY entry = (PTIME_ENTRY) malloc(sizeof(TIME_ENTRY));
|
||||
if (entry)
|
||||
{
|
||||
cout << "secs: " << secs << endl;
|
||||
struct timeval tm;
|
||||
gettimeofday(&tm, 0);
|
||||
tm.tv_sec += secs;
|
||||
|
||||
entry->tm = tm;
|
||||
entry->pid = pid;
|
||||
s_Entries.push_back(entry);
|
||||
if (s_Entries.size () == 1)
|
||||
{
|
||||
s_hThread = CreateThread(NULL, 0, AlarmThread, 0, 0, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/********************************************************************************************************************/
|
||||
OsSupport::ProcessID OsSupport::createProcess(TCHAR *procname, int procargsnum, TCHAR **procargs, bool bWait)
|
||||
|
@ -118,18 +214,59 @@ namespace System_
|
|||
return pid;
|
||||
}
|
||||
|
||||
bool OsSupport::terminateProcess(OsSupport::ProcessID pid)
|
||||
bool OsSupport::terminateProcess(OsSupport::ProcessID pid, int exitcode)
|
||||
{
|
||||
kill(pid, SIGKILL);
|
||||
return true;
|
||||
}
|
||||
|
||||
void OsSupport::delayExecution(long value)
|
||||
{
|
||||
sleep( value );
|
||||
}
|
||||
void OsSupport::delayExecution(long value)
|
||||
{
|
||||
sleep( value );
|
||||
}
|
||||
|
||||
void handleSignal(int sig)
|
||||
{
|
||||
if (sig == SIGALRM)
|
||||
{
|
||||
OsSupport::checkAlarms();
|
||||
}
|
||||
}
|
||||
void setAlarm(long secs, OsSupport::ProcessID pid)
|
||||
{
|
||||
sigemptyset( &sact.sa_mask );
|
||||
s_sact.sa_flags = 0;
|
||||
s_sact.sa_handler = catcher;
|
||||
sigaction( SIGALRM, &sact, NULL );
|
||||
|
||||
alarm(timeout);
|
||||
|
||||
PTIME_ENTRY entry = (PTIME_ENTRY) malloc(sizeof(TIME_ENTRY));
|
||||
if (entry)
|
||||
{
|
||||
struct timeval tm;
|
||||
gettimeofday(&tm, 0);
|
||||
tm.tv_sec += secs;
|
||||
|
||||
entry->tm = tm;
|
||||
entry->pid = pid;
|
||||
for(int i = 0; i < s_Entries.size(); i++)
|
||||
{
|
||||
if (tm.tv_sec < s_Entries[i]->tm.tv_sec && tm.tv_usec < s_Entries[i]->tm.tv_usec)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
/* adjust alarm timer to new period */
|
||||
alarm(secs);
|
||||
}
|
||||
s_Entries.insert(s_Entries.begin() + i, entry);
|
||||
return;
|
||||
}
|
||||
}
|
||||
s_Entries.push_back(entry);
|
||||
alarm(secs);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
} // end of namespace System_
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
#endif
|
||||
|
||||
#include "user_types.h"
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
|
||||
namespace System_
|
||||
{
|
||||
|
@ -35,10 +40,8 @@ namespace System_
|
|||
{
|
||||
public:
|
||||
#ifdef WIN32
|
||||
|
||||
typedef DWORD ProcessID;
|
||||
#else
|
||||
|
||||
typedef pid_t ProcessID;
|
||||
#endif
|
||||
|
||||
|
@ -74,8 +77,9 @@ namespace System_
|
|||
/// Note: returns true if the process with the given pid was terminated
|
||||
///
|
||||
/// @param pid process id of the process to terminate
|
||||
/// @param exitcode for the killed process
|
||||
|
||||
static bool terminateProcess(ProcessID pid);
|
||||
static bool terminateProcess(ProcessID pid, int exitcode);
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
@ -88,6 +92,32 @@ namespace System_
|
|||
|
||||
static void delayExecution(long sec);
|
||||
|
||||
///---------------------------------------------------------------------------------------
|
||||
///
|
||||
/// initializeTimer
|
||||
///
|
||||
/// Description: this function initializes an alarm. When the alarm expires, it will terminate
|
||||
/// the given process
|
||||
|
||||
static void setAlarm(long sec, OsSupport::ProcessID pid);
|
||||
|
||||
///---------------------------------------------------------------------------------------
|
||||
///
|
||||
/// cancelAlarms
|
||||
///
|
||||
/// Description: this function cancels all available timers
|
||||
|
||||
static void cancelAlarms();
|
||||
|
||||
///---------------------------------------------------------------------------------------
|
||||
///
|
||||
/// checkAlarms
|
||||
///
|
||||
/// Description: this function checks for expired alarams
|
||||
|
||||
static void checkAlarms();
|
||||
|
||||
|
||||
protected:
|
||||
//---------------------------------------------------------------------------------------
|
||||
///
|
||||
|
@ -98,6 +128,19 @@ namespace System_
|
|||
OsSupport()
|
||||
{}
|
||||
|
||||
#ifdef __LINUX__
|
||||
static struct sigaction s_sact;
|
||||
#else
|
||||
static HANDLE s_hThread;
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
struct timeval tm;
|
||||
ProcessID pid;
|
||||
}TIME_ENTRY, *PTIME_ENTRY;
|
||||
typedef std::vector<PTIME_ENTRY> TimeEntryVector;
|
||||
static TimeEntryVector s_Entries;
|
||||
}; // end of class OsSupport
|
||||
|
||||
} // end of namespace System_
|
||||
|
|
|
@ -68,7 +68,7 @@ namespace Sysreg_
|
|||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
RosBootTest::RosBootTest() : m_MaxTime(0.0), m_DelayRead(0)
|
||||
RosBootTest::RosBootTest() : m_MaxTime(65), m_DelayRead(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -142,7 +142,6 @@ namespace Sysreg_
|
|||
bool RosBootTest::isFileExisting(string output)
|
||||
{
|
||||
FILE * file;
|
||||
|
||||
file = _tfopen(output.c_str(), _T("r"));
|
||||
|
||||
if (file)
|
||||
|
@ -629,10 +628,21 @@ namespace Sysreg_
|
|||
cerr << "Error: ROS_EMU_PATH is not set" << endl;
|
||||
return false;
|
||||
}
|
||||
if (!m_HDDImage.length())
|
||||
{
|
||||
/* only read image once */
|
||||
conf_parser.getStringValue (RosBootTest::ROS_HDD_IMAGE, m_HDDImage);
|
||||
}
|
||||
if (!m_CDImage.length())
|
||||
{
|
||||
/* only read cdimage once */
|
||||
conf_parser.getStringValue (RosBootTest::ROS_CD_IMAGE, m_CDImage);
|
||||
}
|
||||
/* reset boot cmd */
|
||||
m_BootCmd = _T("");
|
||||
|
||||
conf_parser.getStringValue (RosBootTest::ROS_HDD_IMAGE, m_HDDImage);
|
||||
conf_parser.getStringValue (RosBootTest::ROS_CD_IMAGE, m_CDImage);
|
||||
conf_parser.getDoubleValue (RosBootTest::ROS_MAX_TIME, m_MaxTime);
|
||||
|
||||
conf_parser.getIntValue (RosBootTest::ROS_MAX_TIME, m_MaxTime);
|
||||
conf_parser.getStringValue (RosBootTest::ROS_LOG_FILE, m_DebugFile);
|
||||
conf_parser.getStringValue (RosBootTest::ROS_SYM_DIR, m_SymDir);
|
||||
conf_parser.getIntValue (RosBootTest::ROS_DELAY_READ, m_DelayRead);
|
||||
|
@ -652,7 +662,7 @@ namespace Sysreg_
|
|||
|
||||
if (m_Pid)
|
||||
{
|
||||
OsSupport::terminateProcess (m_Pid);
|
||||
OsSupport::terminateProcess (m_Pid, 0);
|
||||
}
|
||||
delete m_DataSource;
|
||||
m_DataSource = NULL;
|
||||
|
@ -741,6 +751,14 @@ namespace Sysreg_
|
|||
m_Pid = atoi(buffer);
|
||||
fclose(file);
|
||||
#endif
|
||||
OsSupport::cancelAlarms();
|
||||
OsSupport::setAlarm (m_MaxTime, m_Pid);
|
||||
#ifdef __LINUX__
|
||||
OsSupport::setAlarm(m_MaxTime, _getpid());
|
||||
#else
|
||||
OsSupport::setAlarm(m_MaxTime, GetCurrentProcessId());
|
||||
#endif
|
||||
|
||||
bool ret = analyzeDebugData();
|
||||
cleanup();
|
||||
|
||||
|
@ -911,36 +929,6 @@ namespace Sysreg_
|
|||
}
|
||||
return state;
|
||||
}
|
||||
//---------------------------------------------------------------------------------------
|
||||
bool RosBootTest::isTimeout(double max_timeout)
|
||||
{
|
||||
if (max_timeout == 0)
|
||||
{
|
||||
// no timeout specified
|
||||
return false;
|
||||
}
|
||||
static time_t start = 0;
|
||||
|
||||
if (!start)
|
||||
{
|
||||
time(&start);
|
||||
return false;
|
||||
}
|
||||
|
||||
time_t stop;
|
||||
time(&stop);
|
||||
|
||||
double elapsed = difftime(stop, start);
|
||||
if (elapsed > max_timeout)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
//---------------------------------------------------------------------------------------
|
||||
bool RosBootTest::analyzeDebugData()
|
||||
{
|
||||
|
@ -959,12 +947,7 @@ namespace Sysreg_
|
|||
write_log = file.is_open ();
|
||||
while(1)
|
||||
{
|
||||
if (isTimeout(m_MaxTime))
|
||||
{
|
||||
break;
|
||||
}
|
||||
size_t prev_count = vect.size ();
|
||||
|
||||
if (!m_DataSource->readSource (vect))
|
||||
{
|
||||
continue;
|
||||
|
|
|
@ -14,8 +14,9 @@
|
|||
#include "os_support.h"
|
||||
#include "user_types.h"
|
||||
#include <vector>
|
||||
#ifdef __LINUX__
|
||||
#include <unistd.h>
|
||||
|
||||
#endif
|
||||
|
||||
namespace Sysreg_
|
||||
{
|
||||
|
@ -132,22 +133,13 @@ typedef enum DebugState
|
|||
|
||||
DebugState checkDebugData(vector<string> & debug_data);
|
||||
|
||||
//---------------------------------------------------------------------------------------
|
||||
///
|
||||
/// checkTimeOut
|
||||
///
|
||||
/// Description: this function checks if the ReactOS has run longer than the maximum available
|
||||
/// time
|
||||
|
||||
bool isTimeout(double max_timeout);
|
||||
|
||||
protected:
|
||||
|
||||
string m_EmuType;
|
||||
string m_EmuPath;
|
||||
string m_HDDImage;
|
||||
string m_CDImage;
|
||||
double m_MaxTime;
|
||||
long int m_MaxTime;
|
||||
string m_DebugFile;
|
||||
string m_SymDir;
|
||||
long int m_DelayRead;
|
||||
|
|
|
@ -70,15 +70,16 @@ int _tmain(int argc, TCHAR * argv[])
|
|||
#if 0
|
||||
SymbolFile::initialize (config, envvar);
|
||||
#endif
|
||||
if (regtest->execute (config))
|
||||
{
|
||||
cout << "The regression test completed successfully" << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "The regression test failed" << endl;
|
||||
return -2;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
bool ret = regtest->execute(config);
|
||||
if (!ret)
|
||||
{
|
||||
cout << "The regression test has failed at stage: " << i << endl;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
cout << "The regression test completed successfully" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ ROS_EMU_PATH_LIN=/usr/bin/qemu
|
|||
;
|
||||
; Set this variable to value which is the maximum time the emulator lets ReactOS run
|
||||
; If not set, the emulator runs as long as no exception occurs in the emulator.
|
||||
; ROS_MAX_TIME=180.0
|
||||
ROS_MAX_TIME=180
|
||||
|
||||
; ROS_LOG_FILE
|
||||
;
|
||||
|
|
Loading…
Reference in a new issue