mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 22:52:58 +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_
|
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__
|
#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);
|
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
|
||||||
if (!hProcess)
|
if (!hProcess)
|
||||||
|
@ -20,7 +75,7 @@ namespace System_
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ret = TerminateProcess(hProcess, 0);
|
bool ret = TerminateProcess(hProcess, exitcode);
|
||||||
CloseHandle(hProcess);
|
CloseHandle(hProcess);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -91,6 +146,47 @@ namespace System_
|
||||||
{
|
{
|
||||||
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
|
#else
|
||||||
/********************************************************************************************************************/
|
/********************************************************************************************************************/
|
||||||
OsSupport::ProcessID OsSupport::createProcess(TCHAR *procname, int procargsnum, TCHAR **procargs, bool bWait)
|
OsSupport::ProcessID OsSupport::createProcess(TCHAR *procname, int procargsnum, TCHAR **procargs, bool bWait)
|
||||||
|
@ -118,7 +214,7 @@ namespace System_
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OsSupport::terminateProcess(OsSupport::ProcessID pid)
|
bool OsSupport::terminateProcess(OsSupport::ProcessID pid, int exitcode)
|
||||||
{
|
{
|
||||||
kill(pid, SIGKILL);
|
kill(pid, SIGKILL);
|
||||||
return true;
|
return true;
|
||||||
|
@ -129,7 +225,48 @@ namespace System_
|
||||||
sleep( 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
|
#endif
|
||||||
|
|
||||||
} // end of namespace System_
|
} // end of namespace System_
|
||||||
|
|
|
@ -20,6 +20,11 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "user_types.h"
|
#include "user_types.h"
|
||||||
|
#include <ctime>
|
||||||
|
#include <vector>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
|
||||||
namespace System_
|
namespace System_
|
||||||
{
|
{
|
||||||
|
@ -35,10 +40,8 @@ namespace System_
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
||||||
typedef DWORD ProcessID;
|
typedef DWORD ProcessID;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
typedef pid_t ProcessID;
|
typedef pid_t ProcessID;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -74,8 +77,9 @@ namespace System_
|
||||||
/// Note: returns true if the process with the given pid was terminated
|
/// Note: returns true if the process with the given pid was terminated
|
||||||
///
|
///
|
||||||
/// @param pid process id of the process to terminate
|
/// @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);
|
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:
|
protected:
|
||||||
//---------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------
|
||||||
///
|
///
|
||||||
|
@ -98,6 +128,19 @@ namespace System_
|
||||||
OsSupport()
|
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 class OsSupport
|
||||||
|
|
||||||
} // end of namespace System_
|
} // end of namespace System_
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace Sysreg_
|
||||||
#endif
|
#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)
|
bool RosBootTest::isFileExisting(string output)
|
||||||
{
|
{
|
||||||
FILE * file;
|
FILE * file;
|
||||||
|
|
||||||
file = _tfopen(output.c_str(), _T("r"));
|
file = _tfopen(output.c_str(), _T("r"));
|
||||||
|
|
||||||
if (file)
|
if (file)
|
||||||
|
@ -629,10 +628,21 @@ namespace Sysreg_
|
||||||
cerr << "Error: ROS_EMU_PATH is not set" << endl;
|
cerr << "Error: ROS_EMU_PATH is not set" << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (!m_HDDImage.length())
|
||||||
|
{
|
||||||
|
/* only read image once */
|
||||||
conf_parser.getStringValue (RosBootTest::ROS_HDD_IMAGE, m_HDDImage);
|
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);
|
conf_parser.getStringValue (RosBootTest::ROS_CD_IMAGE, m_CDImage);
|
||||||
conf_parser.getDoubleValue (RosBootTest::ROS_MAX_TIME, m_MaxTime);
|
}
|
||||||
|
/* reset boot cmd */
|
||||||
|
m_BootCmd = _T("");
|
||||||
|
|
||||||
|
|
||||||
|
conf_parser.getIntValue (RosBootTest::ROS_MAX_TIME, m_MaxTime);
|
||||||
conf_parser.getStringValue (RosBootTest::ROS_LOG_FILE, m_DebugFile);
|
conf_parser.getStringValue (RosBootTest::ROS_LOG_FILE, m_DebugFile);
|
||||||
conf_parser.getStringValue (RosBootTest::ROS_SYM_DIR, m_SymDir);
|
conf_parser.getStringValue (RosBootTest::ROS_SYM_DIR, m_SymDir);
|
||||||
conf_parser.getIntValue (RosBootTest::ROS_DELAY_READ, m_DelayRead);
|
conf_parser.getIntValue (RosBootTest::ROS_DELAY_READ, m_DelayRead);
|
||||||
|
@ -652,7 +662,7 @@ namespace Sysreg_
|
||||||
|
|
||||||
if (m_Pid)
|
if (m_Pid)
|
||||||
{
|
{
|
||||||
OsSupport::terminateProcess (m_Pid);
|
OsSupport::terminateProcess (m_Pid, 0);
|
||||||
}
|
}
|
||||||
delete m_DataSource;
|
delete m_DataSource;
|
||||||
m_DataSource = NULL;
|
m_DataSource = NULL;
|
||||||
|
@ -741,6 +751,14 @@ namespace Sysreg_
|
||||||
m_Pid = atoi(buffer);
|
m_Pid = atoi(buffer);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
#endif
|
#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();
|
bool ret = analyzeDebugData();
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|
||||||
|
@ -911,36 +929,6 @@ namespace Sysreg_
|
||||||
}
|
}
|
||||||
return state;
|
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()
|
bool RosBootTest::analyzeDebugData()
|
||||||
{
|
{
|
||||||
|
@ -959,12 +947,7 @@ namespace Sysreg_
|
||||||
write_log = file.is_open ();
|
write_log = file.is_open ();
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
if (isTimeout(m_MaxTime))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
size_t prev_count = vect.size ();
|
size_t prev_count = vect.size ();
|
||||||
|
|
||||||
if (!m_DataSource->readSource (vect))
|
if (!m_DataSource->readSource (vect))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -14,8 +14,9 @@
|
||||||
#include "os_support.h"
|
#include "os_support.h"
|
||||||
#include "user_types.h"
|
#include "user_types.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#ifdef __LINUX__
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Sysreg_
|
namespace Sysreg_
|
||||||
{
|
{
|
||||||
|
@ -132,22 +133,13 @@ typedef enum DebugState
|
||||||
|
|
||||||
DebugState checkDebugData(vector<string> & debug_data);
|
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:
|
protected:
|
||||||
|
|
||||||
string m_EmuType;
|
string m_EmuType;
|
||||||
string m_EmuPath;
|
string m_EmuPath;
|
||||||
string m_HDDImage;
|
string m_HDDImage;
|
||||||
string m_CDImage;
|
string m_CDImage;
|
||||||
double m_MaxTime;
|
long int m_MaxTime;
|
||||||
string m_DebugFile;
|
string m_DebugFile;
|
||||||
string m_SymDir;
|
string m_SymDir;
|
||||||
long int m_DelayRead;
|
long int m_DelayRead;
|
||||||
|
|
|
@ -70,15 +70,16 @@ int _tmain(int argc, TCHAR * argv[])
|
||||||
#if 0
|
#if 0
|
||||||
SymbolFile::initialize (config, envvar);
|
SymbolFile::initialize (config, envvar);
|
||||||
#endif
|
#endif
|
||||||
if (regtest->execute (config))
|
|
||||||
|
for(int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
cout << "The regression test completed successfully" << endl;
|
bool ret = regtest->execute(config);
|
||||||
}
|
if (!ret)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
cout << "The regression test failed" << endl;
|
cout << "The regression test has failed at stage: " << i << endl;
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
cout << "The regression test completed successfully" << endl;
|
||||||
return 0;
|
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
|
; 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.
|
; 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
|
; ROS_LOG_FILE
|
||||||
;
|
;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue