Author: janderwald Date: Tue Oct 2 20:09:29 2007 New Revision: 29356
URL: http://svn.reactos.org/svn/reactos?rev=29356&view=rev Log: - perform all boot tests in one launch of sysreg - check for timeouts in windows version to see if qemu has hung
Modified: trunk/reactos/tools/sysreg/os_support.cpp trunk/reactos/tools/sysreg/os_support.h trunk/reactos/tools/sysreg/rosboot_test.cpp trunk/reactos/tools/sysreg/rosboot_test.h trunk/reactos/tools/sysreg/sysreg.cpp trunk/reactos/tools/sysreg/txtmode.cfg
Modified: trunk/reactos/tools/sysreg/os_support.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/sysreg/os_support.cpp... ============================================================================== --- trunk/reactos/tools/sysreg/os_support.cpp (original) +++ trunk/reactos/tools/sysreg/os_support.cpp Tue Oct 2 20:09:29 2007 @@ -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 @@ return false; }
- bool ret = TerminateProcess(hProcess, 0); + bool ret = TerminateProcess(hProcess, exitcode); CloseHandle(hProcess); return ret; } @@ -88,9 +143,50 @@ 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 @@ 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_
Modified: trunk/reactos/tools/sysreg/os_support.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/sysreg/os_support.h?r... ============================================================================== --- trunk/reactos/tools/sysreg/os_support.h (original) +++ trunk/reactos/tools/sysreg/os_support.h Tue Oct 2 20:09:29 2007 @@ -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 @@ { public: #ifdef WIN32 - typedef DWORD ProcessID; #else - typedef pid_t ProcessID; #endif
@@ -74,8 +77,9 @@ /// 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 @@
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 @@ 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_
Modified: trunk/reactos/tools/sysreg/rosboot_test.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/sysreg/rosboot_test.c... ============================================================================== --- trunk/reactos/tools/sysreg/rosboot_test.cpp (original) +++ trunk/reactos/tools/sysreg/rosboot_test.cpp Tue Oct 2 20:09:29 2007 @@ -68,7 +68,7 @@ #endif
//--------------------------------------------------------------------------------------- - RosBootTest::RosBootTest() : m_MaxTime(0.0), m_DelayRead(0) + RosBootTest::RosBootTest() : m_MaxTime(65), m_DelayRead(0) {
} @@ -142,7 +142,6 @@ bool RosBootTest::isFileExisting(string output) { FILE * file; - file = _tfopen(output.c_str(), _T("r"));
if (file) @@ -629,10 +628,21 @@ cerr << "Error: ROS_EMU_PATH is not set" << endl; return false; } - - 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); + 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.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 @@
if (m_Pid) { - OsSupport::terminateProcess (m_Pid); + OsSupport::terminateProcess (m_Pid, 0); } delete m_DataSource; m_DataSource = NULL; @@ -741,6 +751,14 @@ 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();
@@ -912,36 +930,6 @@ 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() { vector<string> vect; @@ -959,12 +947,7 @@ write_log = file.is_open (); while(1) { - if (isTimeout(m_MaxTime)) - { - break; - } size_t prev_count = vect.size (); - if (!m_DataSource->readSource (vect)) { continue;
Modified: trunk/reactos/tools/sysreg/rosboot_test.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/sysreg/rosboot_test.h... ============================================================================== --- trunk/reactos/tools/sysreg/rosboot_test.h (original) +++ trunk/reactos/tools/sysreg/rosboot_test.h Tue Oct 2 20:09:29 2007 @@ -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 @@
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;
Modified: trunk/reactos/tools/sysreg/sysreg.cpp URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/sysreg/sysreg.cpp?rev... ============================================================================== --- trunk/reactos/tools/sysreg/sysreg.cpp (original) +++ trunk/reactos/tools/sysreg/sysreg.cpp Tue Oct 2 20:09:29 2007 @@ -70,15 +70,16 @@ #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; }
Modified: trunk/reactos/tools/sysreg/txtmode.cfg URL: http://svn.reactos.org/svn/reactos/trunk/reactos/tools/sysreg/txtmode.cfg?re... ============================================================================== --- trunk/reactos/tools/sysreg/txtmode.cfg (original) +++ trunk/reactos/tools/sysreg/txtmode.cfg Tue Oct 2 20:09:29 2007 @@ -38,7 +38,7 @@ ; ; 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 ;