- 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:
Johannes Anderwald 2007-10-02 16:09:29 +00:00
parent 384ad5f156
commit 86ff6bfeaa
6 changed files with 231 additions and 75 deletions

View file

@ -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_

View file

@ -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_

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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
;