diff --git a/reactos/tools/sysreg/comp_factory.h b/reactos/tools/sysreg/comp_factory.h new file mode 100644 index 00000000000..6babd1a5a75 --- /dev/null +++ b/reactos/tools/sysreg/comp_factory.h @@ -0,0 +1,204 @@ +#ifndef COMPONENT_FACTORY_TEMPLATE_H_ //comp_factory.h +#define COMPONENT_FACTORY_TEMPLATE_H_ + +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/comp_factory.h + * PURPOSE: component management + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + + +#include +#include + +namespace System_ +{ + using std::map; + using std::vector; + using std::endl; +//---------------------------------------------------------- +/// +/// ComponentFactoryTemplate +/// +/// This class servess as a factory class for components. In general +/// can be used for any possible class which has base class +/// and a derrived class +/// + +//-------------------------------------------------------------------- +/// +/// create +/// +/// Description: this template function creates a function which returns +/// objects of type ElementType but in real are objects of DerrivedType +/// + + template + static ElementType * create () + { + return new DerrivedType(); + } + +//-------------------------------------------------------------------- + + template + class ComponentFactoryTemplate + { + typedef ElementType * (*creation_function)(); + typedef map ElementMap; + typedef vector ElementIdVector; + public: + +//-------------------------------------------------------------------- +/// +/// ComponentFactoryTemplate +/// +/// Description: default destructor of class ComponentFactoryTemplate +/// + + ComponentFactoryTemplate() + { + + } + +//-------------------------------------------------------------------- +/// +/// ~ComponentFactoryTemplate +/// +/// Description: default destructor of class ComponentFactoryTemplate +/// + + virtual ~ComponentFactoryTemplate() + { + + } +//-------------------------------------------------------------------- +/// +/// listComponent +/// +/// Description: lists all registererd components ids + + void listComponentIds() + { + for(unsigned i = 0; i < ids_.size (); i++) + cout< + bool registerComponent(ElementId const & id) + { + typename ElementMap::const_iterator iter = elements_.find(id); + if(iter != elements_.end()) + return false; + ids_.insert(ids_.begin(),id); + elements_.insert(std::make_pair(id, &create)); + return true; + + } + + //-------------------------------------------------------------------- +/// +/// deregisterComponent +/// +/// Description: unregisters a given component indentified by param id +/// After unregistration, the specified component can no longer be +/// created +/// @return bool +/// @param id the element id of the ContentType + + template + const bool deregisterComponent(ElementId const & id) + { + typename ElementMap::const_iterator iterator = elements_.find(id); + if(iterator != elements_.end()) + { + elements_.erase(iterator); + return true; + } + else + return false; + } + + +//-------------------------------------------------------------------- +/// +/// createComponent +/// +/// Description: creates a component according to the specified information +/// returns the component encapsulated in an std::auto_ptr +/// @param id specifies the key id, to look for +/// @return std::auto_ptr + ElementType * createComponent(ElementId const & id) const + { + typename ElementMap::const_iterator first_it = elements_.find(id); + if(first_it != elements_.end()) + return (first_it->second)(); + else + return 0; + } + +//-------------------------------------------------------------------- +/// +/// deleteComponent +/// +/// Description: deletes a component +/// @param element the element to be deleted + + void deleteComponent(ElementType * element) + { + delete element; + } + protected: + ElementMap elements_; + ElementIdVector ids_; + }; + + +} //end of namespace Sysreg_ + +#endif + diff --git a/reactos/tools/sysreg/conf_parser.cpp b/reactos/tools/sysreg/conf_parser.cpp new file mode 100644 index 00000000000..f09ba2fe0d3 --- /dev/null +++ b/reactos/tools/sysreg/conf_parser.cpp @@ -0,0 +1,98 @@ +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: configuration parser + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + +#include "conf_parser.h" +#include +#include +#include + +namespace Sysreg_ +{ + using std::cout; + using std::cerr; + using std::endl; + using std::ifstream; +//--------------------------------------------------------------------------------------- + ConfigParser::ConfigParser() + { + + } + +//--------------------------------------------------------------------------------------- + ConfigParser::~ConfigParser() + { + m_Map.clear (); + } + +//--------------------------------------------------------------------------------------- + bool ConfigParser::parseFile(TCHAR * FileName) + { + FILE * file; +#ifdef UNICODE + file = _tfopen(FileName, _T("rt,ccs=UNICODE")); +#else + file = _tfopen(FileName, _T("rt")); +#endif + if (!file) + { + cerr << " Error: ConfigParser::parseFile failed to open configuration file " <second; + return true; + } + + +} // end of namespace Sysreg_ diff --git a/reactos/tools/sysreg/conf_parser.h b/reactos/tools/sysreg/conf_parser.h new file mode 100644 index 00000000000..2fa9c9ece62 --- /dev/null +++ b/reactos/tools/sysreg/conf_parser.h @@ -0,0 +1,92 @@ +#ifndef CONF_PARSER_H__ +#define CONF_PARSER_H__ + +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: configuration parser + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + + +#include +#include +#include + +namespace Sysreg_ +{ + using std::map; +//--------------------------------------------------------------------------------------- +/// +/// class ConfigParser +/// +/// Description: this class reads configuration entries from a configuration file +/// Each entry must have the form of VALUE=XXX. The entries are stored +/// in a map which can be queried after parsing the configuration file +/// +/// Note: lines beginning with an ; are ignored +/// +/// Usage: First, call parseFile with param to file. Finally, call getValue with the +/// appropiate type + + class ConfigParser + { + public: + typedef std::basic_string string; + typedef std::basic_istringstream istringstream; + typedef map ConfigMap; +//--------------------------------------------------------------------------------------- +/// +/// ConfigParser +/// +/// Description: constructor of class ConfigParser + + ConfigParser(); + +//--------------------------------------------------------------------------------------- +/// +/// ~ConfigParser +/// +/// Description: destructor of class ConfigParser + + virtual ~ConfigParser(); + +//--------------------------------------------------------------------------------------- +/// +/// parseFile +/// +/// Description: this function takes as param a path to file. it attempts to parse this specific +/// file with the given syntax. On success it returns true. +/// +/// Note: Everytime parseFile is called, the previous stored values are cleared +/// +/// @param FileName path to configuration file +/// @return bool + + bool parseFile(TCHAR * FileName); + +//-------------------------------------------------------------------------------------- +/// +/// getStringValue +/// +/// Description: attempts to read a config variable from the configuration file +/// If the variable name is not found, it returns false and the param +/// ConfValue remains untouched. On success it returns the true. +/// +/// @param ConfVariable name of the configuration variable to retrieve +/// @param ConfValue type of value to retrieve + + bool getStringValue(string & ConfVariable, string & ConfValue); + + protected: + ConfigMap m_Map; + + }; // end of class ConfigParser + + +} // end of namspace Sysreg_ + + +#endif /* end of CONF_PARSER_H__ */ diff --git a/reactos/tools/sysreg/env_var.cpp b/reactos/tools/sysreg/env_var.cpp new file mode 100644 index 00000000000..f67f48ce516 --- /dev/null +++ b/reactos/tools/sysreg/env_var.cpp @@ -0,0 +1,67 @@ +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: environment variable lookup + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + + +#include "env_var.h" +#include + +namespace System_ +{ + using std::cout; + using std::endl; + using std::cerr; + +//--------------------------------------------------------------------------------------- + EnvironmentVariable::EnvironmentVariable() + { + + } + +//--------------------------------------------------------------------------------------- + EnvironmentVariable::~EnvironmentVariable() + { + m_Map.clear (); + } + +//--------------------------------------------------------------------------------------- + + bool EnvironmentVariable::getValue(const System_::string &EnvName, System_::string &EnvValue) + { + EnvironmentMap::const_iterator it = m_Map.find (EnvName); + if (it != m_Map.end()) + { + EnvValue = it->second; + return true; + } + + TCHAR * value = _tgetenv(EnvName.c_str ()); + + if (!value) + { +#ifdef NDEBUG + cerr << "EnvironmentVariable::getValue found no value for " << EnvName << endl; +#endif + return false; + } + + if (!_tcslen(value)) + { +#ifdef NDEBUG + cerr << "EnvironmentVariable::getValue found no value for " << EnvName << endl; +#endif + return false; + } + + EnvValue = value; + m_Map[EnvName] = EnvValue; + return true; + } + + +} // end of namespace System_ diff --git a/reactos/tools/sysreg/env_var.h b/reactos/tools/sysreg/env_var.h new file mode 100644 index 00000000000..45b38d32bd0 --- /dev/null +++ b/reactos/tools/sysreg/env_var.h @@ -0,0 +1,71 @@ +#ifndef ENV_VAR_H__ +#define ENV_VAR_H__ + +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: environment variable lookup + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + +#include +#include +#include + +namespace System_ +{ + + using std::map; + typedef std::basic_string string; +//--------------------------------------------------------------------------------------- +/// +/// class EnvironmentVariable +/// +/// Description: this class performs looking up environment variable from the system +/// The result is also stored in its internal map to cache results + + class EnvironmentVariable + { + typedef map EnvironmentMap; + public: +//--------------------------------------------------------------------------------------- +/// +/// EnvironmentVariable +/// +/// Description: constructor of class EnvironmentVariable + + EnvironmentVariable(); + +//--------------------------------------------------------------------------------------- +/// +/// ~EnvironmentVariable +/// +/// Description: destructor of class EnvironmentVariable + + virtual ~EnvironmentVariable(); + +//--------------------------------------------------------------------------------------- +/// +/// getValue +/// +/// Description: this function returns the value of an associated environment variable. if +/// the variable is set it returns true and the value in the parameter EnvValue. On error +/// it returns false and the param EnvValue remains untouched +/// +/// @param EnvName name of environment variable to retrieve +/// @param EnvValue value of the environment variable +/// @return bool + + bool getValue(const string & EnvName, string & EnvValue); + + + protected: + EnvironmentMap m_Map; + + }; // end of class EnvironmentVariable + +} // end of namespace System_ + +#endif /* end of ENV_VAR_H__ */ diff --git a/reactos/tools/sysreg/pipe_reader.cpp b/reactos/tools/sysreg/pipe_reader.cpp new file mode 100644 index 00000000000..b2739775b2a --- /dev/null +++ b/reactos/tools/sysreg/pipe_reader.cpp @@ -0,0 +1,132 @@ +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: pipe reader support + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + +#include "pipe_reader.h" + +#include +#include + +namespace System_ +{ + using std::cout; + using std::endl; + using std::cerr; + +//--------------------------------------------------------------------------------------- + PipeReader::PipeReader() : m_File(NULL) + { + + } + +//--------------------------------------------------------------------------------------- + PipeReader::~PipeReader() + { + + } + +//--------------------------------------------------------------------------------------- + + bool PipeReader::openPipe(const System_::string &PipeCmd, System_::string AccessMode) + { + if (m_File != NULL) + { +#ifdef NDEBUG + cerr << "PipeReader::openPipe> pipe already open" << endl; +#endif + return false; + } + // + m_File = _tpopen(PipeCmd.c_str(), AccessMode.c_str()); + if (m_File) + { +#ifdef NDEBUG + cerr << "PipeReader::openPipe> successfully opened pipe" << endl; +#endif + return true; + } + +#ifdef NDEBUG + cerr << "PipeReader::openPipe> failed to open pipe " << PipeCmd << endl; +#endif + return false; + } + +//--------------------------------------------------------------------------------------- + + bool PipeReader::closePipe() + { + if (!m_File) + { +#ifdef NDEBUG + cerr << "PipeReader::closePipe> pipe is not open" << endl; +#endif + return false; + } + + int res = _pclose(m_File); + + if (res == UINT_MAX) + { +#ifdef NDEBUG + cerr << "Error: _pclose failed " < res: " << Buffer << endl; +#endif + + return _tcslen(buf); + } + +//--------------------------------------------------------------------------------------- + + bool PipeReader::writePipe(const string & Buffer) + { + //TODO + // implement me + cerr << "PipeReader::writePipe is not yet implemented" << endl; + + return false; + } + +} // end of namespace System_ diff --git a/reactos/tools/sysreg/pipe_reader.h b/reactos/tools/sysreg/pipe_reader.h new file mode 100644 index 00000000000..2430951ba90 --- /dev/null +++ b/reactos/tools/sysreg/pipe_reader.h @@ -0,0 +1,117 @@ +#ifndef PIPE_READER_H__ +#define PIPE_READER_H__ + +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: pipe reader support + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + + + +#include +#include +#include +#include + +namespace System_ +{ + typedef std::basic_string string; +//--------------------------------------------------------------------------------------- +/// +/// class PipeReader +/// +/// Description: this class implements a pipe reader. It uses _popen to perform opening of +/// pipe / _pclose + + class PipeReader + { + public: + +//--------------------------------------------------------------------------------------- +/// +/// PipeReader +/// +/// Description: constructor of class PipeReader + + PipeReader(); + +//--------------------------------------------------------------------------------------- +/// +/// virtual ~PipeReader +/// +/// Description: destructor of class PipeReader + + virtual ~PipeReader(); + +//--------------------------------------------------------------------------------------- +/// +/// openPipe +/// +/// Description: this function attempts to open a pipe. If an pipe is already open or +/// it fails to open a pipe, the function returns false +/// +/// @param PipeCmd command of the pipe to open +/// @param AccessMode on how to open the pipe +/// accepted modes are t ... text mode - not compatible with b +/// b ... binary mode - not compatible with t +/// r ... allows reading from the pipe +/// w ... allows writing to the pipe +/// @return bool + + bool openPipe(const string & PipeCmd, string AccessMode = _T("rt")); + +//--------------------------------------------------------------------------------------- +/// +/// closePipe +/// +/// Description: closes a pipe. Returns true on success +/// +/// @return bool + + bool closePipe(); + +//--------------------------------------------------------------------------------------- +/// +/// readPipe +/// +/// Description: attempts to read from the pipe. Returns true on success. If it returns +/// false, call PipeReader::isEoF() to determine if the pipe should be closed +/// +/// @param Buffer to be written to +/// @return string::size_type + + string::size_type readPipe(string & Buffer); + +//--------------------------------------------------------------------------------------- +/// +/// writePipe +/// +/// Description: attempts to write to the pipe. Returns true on success. +/// +/// @param Buffer containing information which is written to the pipe + + bool writePipe(const string & Buffer); + +//--------------------------------------------------------------------------------------- +/// +/// isEof +/// +/// Description: returns true if the pipe has reached end of file. The caller should call +/// closePipe if this function returns true + + bool isEof() const; + +protected: + FILE * m_File; + + }; // end of class PipeReader + +} // end of namespace System_ + + + +#endif /* end of PIPE_READER_H__ */ diff --git a/reactos/tools/sysreg/reg_test.h b/reactos/tools/sysreg/reg_test.h new file mode 100644 index 00000000000..ffae205de16 --- /dev/null +++ b/reactos/tools/sysreg/reg_test.h @@ -0,0 +1,87 @@ +#ifndef REG_TEST_H__ +#define REG_TEST_H__ + +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: regression test abstract class + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + +#include "conf_parser.h" + +#include +#include + +namespace Sysreg_ +{ + using Sysreg_::ConfigParser; + + typedef std::basic_string string; +//------------------------------------------------------------------- +/// +/// class RegressionTest +/// +/// Description: The class RegressionTest is an abstract base class. Every +/// regression test class derives from this class. + + + class RegressionTest + { + public: + +//--------------------------------------------------------------------------------------- +/// +/// RegressionTest +/// +/// Description: constructor of class RegressionTest +/// +/// @param RegName name of derriving subclass + + RegressionTest(const string RegName) : m_Name(RegName) + {} + +//--------------------------------------------------------------------------------------- +/// +/// ~RegressionTest +/// +/// Description: destructor of class RegressionTest + + virtual ~RegressionTest() + {} + +//--------------------------------------------------------------------------------------- +/// +/// getName +/// +/// Description: returns the value of the member m_Name + + const string & getName() const + { return m_Name; } + +//--------------------------------------------------------------------------------------- +/// +/// execute +/// +/// Description: the execute function passes an System_::ConfigParser object to the +/// derriving RegresssionTest class. The class can then read required options from the +/// configuration file. The RegressionTest shall then perform its specific regression test. +/// @see System_::PipeReader +/// @see System_::SymbolFile +/// +/// Note : if an error happens or the option cannot be found, this function +/// should return false. + + virtual bool execute(ConfigParser & conf_parser) = 0; + + protected: + string m_Name; + + }; // end of class RegressionTest + + +} // end of namespace Sysreg_ + +#endif \ No newline at end of file diff --git a/reactos/tools/sysreg/rosboot_test.cpp b/reactos/tools/sysreg/rosboot_test.cpp new file mode 100644 index 00000000000..ac713a3f7e8 --- /dev/null +++ b/reactos/tools/sysreg/rosboot_test.cpp @@ -0,0 +1,161 @@ + +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: ReactOS boot test + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + + +#include "rosboot_test.h" +#include "pipe_reader.h" + +#include + +namespace Sysreg_ +{ + using std::cout; + using std::endl; + using std::cerr; + + using System_::PipeReader; + + string RosBootTest::VARIABLE_NAME = _T("ROSBOOT_CMD"); + string RosBootTest::CLASS_NAME = _T("rosboot"); + string RosBootTest::DEBUG_PORT = _T("ROSBOOT_DEBUG_PORT"); + string RosBootTest::DEBUG_FILE = _T("ROSBOOT_DEBUG_FILE"); +//--------------------------------------------------------------------------------------- + RosBootTest::RosBootTest() : RegressionTest(RosBootTest::CLASS_NAME) + { + + } + +//--------------------------------------------------------------------------------------- + RosBootTest::~RosBootTest() + { + + } + +//--------------------------------------------------------------------------------------- + bool RosBootTest::execute(ConfigParser &conf_parser) + { + string boot_cmd; + string debug_port; + bool ret; + + if (!conf_parser.getStringValue (RosBootTest::DEBUG_PORT, debug_port)) + { + cerr << "Error: ROSBOOT_DEBUG_TYPE is not set in configuration file" << endl; + return false; + } + if (!conf_parser.getStringValue(RosBootTest::VARIABLE_NAME, boot_cmd)) + { + cerr << "Error: ROSBOOT_CMD is not set in configuration file" << endl; + return false; + } + + if (!_tcscmp(debug_port.c_str(), _T("pipe"))) + { + ret = fetchDebugByPipe(boot_cmd); + } + else if (!_tcscmp(debug_port.c_str(), _T("file"))) + { + string debug_file; + if (!conf_parser.getStringValue (RosBootTest::DEBUG_FILE, debug_file)) + { + cerr << "Error: ROSBOOT_DEBUG_FILE is not set in configuration file" << endl; + return false; + } + ret = fetchDebugByFile(boot_cmd, debug_file); + } + else + { + _tprintf(_T("Error: unknown debug port %s Currently only file|pipe is supported\n"), debug_port); + return false; + } + + + return ret; + } +//--------------------------------------------------------------------------------------- + bool RosBootTest::checkDebugData(string debug_data) + { + /// + /// FIXME + /// + /// parse debug_data and output STOP errors, UM exception + /// as well as important stages i.e. ntoskrnl loaded + /// TBD the information needs to be written into an provided log object + /// which writes the info into HTML/log / sends etc .... + + _tprintf(debug_data.c_str ()); + return true; + + } +//--------------------------------------------------------------------------------------- + bool RosBootTest::fetchDebugByPipe(string boot_cmd) + { + struct timeval ts; + PipeReader pipe_reader; + + if (!pipe_reader.openPipe(boot_cmd, string(_T("rt")))) + { + _tprintf(_T("Error: failed to open pipe with cmd: %s\n"), boot_cmd.c_str ()); + return false; + } + string Buffer; + Buffer.reserve (10000); + +// gettimeofday(&ts, NULL); + + while(!pipe_reader.isEof ()) + { + pipe_reader.readPipe (Buffer); + if (!checkDebugData(Buffer)) + { + break; + } + if (hasTimeout(&ts, 60000) + + } + pipe_reader.closePipe (); + return true; + } +//--------------------------------------------------------------------------------------- + bool RosBootTest::fetchDebugByFile(Sysreg_::string boot_cmd, Sysreg_::string debug_log) + { + PipeReader pipe_reader; + + if (!pipe_reader.openPipe(boot_cmd, string(_T("rt")))) + { + _tprintf(_T("Error: failed to open pipe with cmd: %s\n"), boot_cmd.c_str ()); + return false; + } + FILE * file = _tfopen(debug_log.c_str (), _T("rt")); + if (!file) + { + _tprintf(_T("Error: failed to open debug log %s\n", debug_log.c_str ())); + pipe_reader.closePipe (); + return false; + } + + TCHAR szBuffer[500]; + + do + { + if (_fgetts(szBuffer, sizeof(szBuffer) / sizeof(TCHAR), file)) + { + string buffer = szBuffer; + if (!checkDebugData(buffer)) + { + break; + } + } + }while(!pipe_reader.isEof ()); + + pipe_reader.closePipe (); + } + +} // end of namespace Sysreg_ \ No newline at end of file diff --git a/reactos/tools/sysreg/rosboot_test.h b/reactos/tools/sysreg/rosboot_test.h new file mode 100644 index 00000000000..08ad5ff0bd2 --- /dev/null +++ b/reactos/tools/sysreg/rosboot_test.h @@ -0,0 +1,116 @@ +#ifndef ROSBOOT_TEST_H__ +#define ROSBOOT_TEST_H__ + +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: ReactOS boot test + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + + +#include "reg_test.h" +#include + +namespace Sysreg_ +{ +//--------------------------------------------------------------------------------------- +/// +/// class RosBootTest +/// +/// Description: this class attempts to boot ReactOS in an emulator with console logging enabled. +/// It + + class RosBootTest : public RegressionTest + { + public: + static string VARIABLE_NAME; + static string CLASS_NAME; + static string DEBUG_PORT; + static string DEBUG_FILE; + +//--------------------------------------------------------------------------------------- +/// +/// RosBootTest +/// +/// Description: constructor of class RosBootTest +/// + + RosBootTest(); + +//--------------------------------------------------------------------------------------- +/// +/// ~RosBootTest +/// +/// Description: destructor of class RosBootTest +/// + + virtual ~RosBootTest(); + +//--------------------------------------------------------------------------------------- +/// +/// execute +/// +/// Description: this function performs a ReactOS boot test. It reads the variable +/// ROSBOOT_CMD and executes this specific command. This command shall contain the path +/// to an emulator (i.e. qemu) and the required arguments (-serial switch, hdd img etc) to be able +/// to read from console. If an error is detected, it attempts to resolve the faulting +/// module and address. + + virtual bool execute(ConfigParser & conf_parser); + + protected: +//--------------------------------------------------------------------------------------- +/// +/// fetchDebugByPipe +/// +/// Description: this functions debugs ReactOS by PipeReader class +/// +/// Note: if an error occurs, this function returns false +/// +/// @param BootCmd the command which is passed to PipeReader class +/// @return bool + + bool fetchDebugByPipe(string BootCmd); + +//--------------------------------------------------------------------------------------- +/// +/// fetchDebugByFile +/// +/// Description: this functions fetches debug info by reading a debug log +/// +/// Note: if an error occurs, this function returns false +/// +/// @param BootCmd the command which is passed to PipeReader class +/// @param debug_log path pointing to debug log +/// @return bool + + bool fetchDebugByFile(string BootCmd, string debug_log); + +//--------------------------------------------------------------------------------------- +/// +/// checkDebugData +/// +/// Description: this function parses the given debug data for BSOD, UM exception etc +/// If it detects an fatal error, it should return false +/// +/// Note: the received debug information should be written to an internal log object +/// to facilate post-processing of the results + + bool checkDebugData(string debug_data); + + }; // end of class RosBootTest + +//--------------------------------------------------------------------------------------- +/// +/// checkTimeOut +/// +/// Description: this function checks if the the application has already hung + + bool checkTimeOut(struct timeval * ts, unsigned max_timeout); + +} // end of namespace Sysreg_ + +#endif /* end of ROSBOOT_H__ */ diff --git a/reactos/tools/sysreg/sym_file.cpp b/reactos/tools/sysreg/sym_file.cpp new file mode 100644 index 00000000000..dc202b3c5b2 --- /dev/null +++ b/reactos/tools/sysreg/sym_file.cpp @@ -0,0 +1,144 @@ + +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: source symbol lookup + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + + +#include "sym_file.h" +#include "env_var.h" +#include "pipe_reader.h" + +#include +#include +#include +#include +#include + + +namespace System_ +{ + using std::cout; + using std::endl; + using std::cerr; + + string SymbolFile::VAR_ROS_OUTPUT = _T("ROS_OUTPUT"); +//--------------------------------------------------------------------------------------- + SymbolFile::SymbolFile() + { + + } + +//--------------------------------------------------------------------------------------- + SymbolFile::~SymbolFile() + { + + } + +//--------------------------------------------------------------------------------------- + bool SymbolFile::initialize(const System_::string &Path) + { + char szBuffer[260]; +// vector vect; + EnvironmentVariable envvar; + + string val = _T("output-i386"); + + envvar.getValue(SymbolFile::VAR_ROS_OUTPUT, val); + + struct _finddata_t c_file; + strcpy(szBuffer, "D:\\reactos\\output-i386\\*"); + intptr_t hFile = _findfirst(szBuffer, &c_file); + + if (hFile == -1L) + { + cerr << "SymbolFile::initialize> failed" < no symbol file found for module " << module_name << endl; +#endif + return false; + } +*/ + /// + /// fetch environment path + /// + EnvironmentVariable envvar; +#if 1 + string pipe_cmd = _T("");//D:\\reactos\\output-i386"); +#else + string path = _T("output-i386"); + envvar.getValue(SymbolFile::VAR_ROS_OUTPUT, path); +#endif + pipe_cmd += _T("addr2line.exe "); //FIXXME file extension + pipe_cmd += _T("--exe="); +#if 1 + pipe_cmd += _T("D:\\reactos\\output-i386\\dll\\win32\\kernel32\\kernel32.nostrip.dll"); +#else + path += it->second; +#endif + + pipe_cmd += _T(" "); + pipe_cmd += module_address; + + + PipeReader pipe_reader; + + if (!pipe_reader.openPipe (pipe_cmd)) + { +#ifdef NDEBUG + _tprintf(_T("SymbolFile::resolveAddress> failed to open pipe %s"), pipe_cmd); +#endif + return false; + } + + if (Buffer.capacity () < 100) + { + Buffer.reserve (500); + } + + return pipe_reader.readPipe (Buffer); + } + +//--------------------------------------------------------------------------------------- + bool SymbolFile::getSymbolFilePath(const System_::string &ModuleName, System_::string &FilePath) + { + cerr << "SymbolFile::getSymbolFilePath is not yet implemented" < +#include +#include + +namespace System_ +{ + + typedef std::basic_string string; + +//--------------------------------------------------------------------------------------- +/// +/// class SymbolFile +/// +/// Description: this class performs 2 tasks: First, it locates all available module names +/// and their associated symbol files. Secondly, it performs resolving address to source addresses +/// via the function resolveAddress +/// +/// Usage: call initialize(). Then call resolveAddress(); +/// i.e. resolveAddress("comctl32.dll", 0xBLABLABLA, result); + + class SymbolFile + { + typedef std::map SymbolMap; + public: + static string VAR_ROS_OUTPUT; +//--------------------------------------------------------------------------------------- +/// +/// SymbolFile +/// +/// Description: constructor of class SymbolFile + + SymbolFile(); + +//--------------------------------------------------------------------------------------- +/// +/// ~SymbolFile +/// +/// Description: destructor of class SymbolFile + + virtual ~SymbolFile(); + +//--------------------------------------------------------------------------------------- +/// +/// initialize +/// +/// Description: this function initialize the class. It searches the subdirs +/// of ROS_OUTPUT and adds all files with name *.nostrip.* to a map with module +/// name as the key. +/// +/// Note: if the param Path is not empty, it adds all found modules to the internal +/// map +/// +/// Note: if the path does not exist or the no symbol files were added then false is returned +/// +/// Note: if a module with same module name is already in the map, then the new module is not added +/// +/// @param Path path to ROS_OUTPUT containing symbol files +/// @return bool + + bool initialize(const string & Path = _T("output-i386")); + +//--------------------------------------------------------------------------------------- +/// +/// resolveAddress +/// +/// Description: this function attempts to resolve an address using a given symbol file +/// +/// Note: the lookup is performed with raddr2line +/// +/// @param module_name name of the module to examine +/// @param module_address address of the module to resolve +/// @param buffer receives information about the resolved location +/// @return bool + + bool resolveAddress(const string & module_name, const string & module_address, string & Buffer); + +//--------------------------------------------------------------------------------------- +/// +/// getSymbolFilePath +/// +/// Description: this function returns the associated FilePath to a given module name. If +/// the module name is not known, it returns false and the param FilePath remains untouched +/// +/// @param ModuleName name of the module to lookup +/// @param FilePath buffer receiving the address of symbol file + + bool getSymbolFilePath(const string & ModuleName, string & FilePath); + + protected: + SymbolMap m_Map; + + }; +} // end of namespace System_ + + + +#endif /* end of SYM_FILE_H__ */ diff --git a/reactos/tools/sysreg/sysreg.cpp b/reactos/tools/sysreg/sysreg.cpp new file mode 100644 index 00000000000..051d650f3e9 --- /dev/null +++ b/reactos/tools/sysreg/sysreg.cpp @@ -0,0 +1,82 @@ + +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: app initialization + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + + +#include "sysreg.h" + + +typedef std::basic_string string; + +using std::cout; +using std::endl; +using std::cerr; + + +using System_::EnvironmentVariable; +using System_::ComponentFactoryTemplate; + +using Sysreg_::ConfigParser; + +//regression test classes +using Sysreg_::RegressionTest; +using Sysreg_::RosBootTest; + + +//test include +using System_::SymbolFile; + +typedef ComponentFactoryTemplate ComponentFactory; + +static const TCHAR USAGE[] = +_T("sysreg.exe \n\nconf_file ... path to a configuration file\ntest_name ... name of test to execute\n"); + + + + +int _tmain(int argc, TCHAR * argv[]) +{ + ConfigParser config; + ComponentFactory comp_factory; + + if (argc != 3) + { + cerr << USAGE << endl; + return -1; + } +//--------------------------------------------------------------------------------------- + /// regression tests should be registered here + comp_factory.registerComponent(RosBootTest::CLASS_NAME); + +//--------------------------------------------------------------------------------------- + + if (!config.parseFile (argv[1])) + { + cerr << USAGE << endl; + return -1; + } + + RegressionTest * regtest = comp_factory.createComponent (argv[2]); + if (!regtest) + { + _tprintf(_T("Error: the requested regression test does not exist")); + return -1; + } + + if (regtest->execute (config)) + { + _tprintf(_T("The regression test %s completed successfully\n"), regtest->getName ().c_str ()); + } + else + { + _tprintf(_T("The regression test %s failed\n"), regtest->getName ().c_str ()); + } + + return 0; +} \ No newline at end of file diff --git a/reactos/tools/sysreg/sysreg.h b/reactos/tools/sysreg/sysreg.h new file mode 100644 index 00000000000..1932b95671f --- /dev/null +++ b/reactos/tools/sysreg/sysreg.h @@ -0,0 +1,34 @@ +#ifndef SYSREG_H__ +#define SYSREG_H__ + +/* $Id$ + * + * PROJECT: System regression tool for ReactOS + * LICENSE: GPL - See COPYING in the top level directory + * FILE: tools/sysreg/conf_parser.h + * PURPOSE: app initialization + * PROGRAMMERS: Johannes Anderwald (johannes.anderwald at sbox tugraz at) + */ + +#include +#include +#include + + + +#include "env_var.h" +#include "pipe_reader.h" +#include "comp_factory.h" +#include "conf_parser.h" + +// regression test classes +#include "rosboot_test.h" + +//test include +#include "sym_file.h" + + + + + +#endif /* end of SYSREG_H__ */