mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 09:25:10 +00:00
* beginning of a system regression tools
svn path=/trunk/; revision=24584
This commit is contained in:
parent
66e157c5eb
commit
4ba2129226
14 changed files with 1515 additions and 0 deletions
204
reactos/tools/sysreg/comp_factory.h
Normal file
204
reactos/tools/sysreg/comp_factory.h
Normal file
|
@ -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 <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
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<class ElementType, class DerrivedType>
|
||||||
|
static ElementType * create ()
|
||||||
|
{
|
||||||
|
return new DerrivedType();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
template<typename ElementType, typename ElementId>
|
||||||
|
class ComponentFactoryTemplate
|
||||||
|
{
|
||||||
|
typedef ElementType * (*creation_function)();
|
||||||
|
typedef map<ElementId, creation_function> ElementMap;
|
||||||
|
typedef vector<ElementId> 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<<ids_[i]<<endl;
|
||||||
|
}
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
/// isComponentRegistered
|
||||||
|
///
|
||||||
|
/// Description: this function just checks if a component with a given
|
||||||
|
/// id has been registered or not. If it is it returns true else false
|
||||||
|
///
|
||||||
|
/// @return bool
|
||||||
|
/// @param element id of the component
|
||||||
|
|
||||||
|
bool isComponentRegistered(ElementId const & id)
|
||||||
|
{
|
||||||
|
typename ElementMap::const_iterator iter = elements_.find(id);
|
||||||
|
if(iter != elements_.end())
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
/// getNumOfComponents
|
||||||
|
///
|
||||||
|
/// Description: returns how many components have been registered
|
||||||
|
|
||||||
|
const unsigned getNumOfComponents()
|
||||||
|
{
|
||||||
|
return ids_.size ();
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
///
|
||||||
|
/// registerComponent
|
||||||
|
///
|
||||||
|
/// Description: this function is template function in a class template.
|
||||||
|
/// The purpose is that at compiletime for each of the derriving classes of
|
||||||
|
/// ElementType a registerComponent function is generated and then all classes
|
||||||
|
/// of that type are added at runtime to factory.
|
||||||
|
/// returns zero on success, nonzero on failure
|
||||||
|
///
|
||||||
|
/// @return bool
|
||||||
|
/// @param id the element id of the content type
|
||||||
|
template<typename ContentType>
|
||||||
|
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<ElementId, creation_function >(id, &create<ElementType, ContentType>));
|
||||||
|
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<typename ContentType>
|
||||||
|
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>
|
||||||
|
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
|
||||||
|
|
98
reactos/tools/sysreg/conf_parser.cpp
Normal file
98
reactos/tools/sysreg/conf_parser.cpp
Normal file
|
@ -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 <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
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 " <<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
while (!feof(file))
|
||||||
|
{
|
||||||
|
TCHAR buffer[500];
|
||||||
|
TCHAR * buf;
|
||||||
|
|
||||||
|
buf = _fgetts(buffer, sizeof(buffer) / sizeof(TCHAR), file);
|
||||||
|
if (buf)
|
||||||
|
{
|
||||||
|
if (buffer[0] != ';')
|
||||||
|
{
|
||||||
|
string s_buffer = string(buffer);
|
||||||
|
string::size_type ws_pos = s_buffer.find_first_of (_T("="));
|
||||||
|
|
||||||
|
if (ws_pos != string::npos && ws_pos > 0 && ws_pos < s_buffer.size())
|
||||||
|
{
|
||||||
|
string name = s_buffer.substr (0, ws_pos);
|
||||||
|
string value = s_buffer.substr (ws_pos + 1);
|
||||||
|
if (value[value.length () -1] == 0xA)
|
||||||
|
{
|
||||||
|
// remove newline char
|
||||||
|
value[value.length ()-1] = _T('\0');
|
||||||
|
}
|
||||||
|
m_Map[name] = value;
|
||||||
|
ret = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
bool ConfigParser::getStringValue(string &ConfVariable, string &ConfValue)
|
||||||
|
{
|
||||||
|
ConfigMap::iterator it = m_Map.find (ConfVariable);
|
||||||
|
if (it == m_Map.end ())
|
||||||
|
{
|
||||||
|
#ifdef NDEBUG
|
||||||
|
cerr << "ConfigParser::getValue failed to find " << ConfVariable << endl;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfValue = it->second;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // end of namespace Sysreg_
|
92
reactos/tools/sysreg/conf_parser.h
Normal file
92
reactos/tools/sysreg/conf_parser.h
Normal file
|
@ -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 <string>
|
||||||
|
#include <map>
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
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<TCHAR> string;
|
||||||
|
typedef std::basic_istringstream<TCHAR> istringstream;
|
||||||
|
typedef map<string, string> 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__ */
|
67
reactos/tools/sysreg/env_var.cpp
Normal file
67
reactos/tools/sysreg/env_var.cpp
Normal file
|
@ -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 <iostream>
|
||||||
|
|
||||||
|
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_
|
71
reactos/tools/sysreg/env_var.h
Normal file
71
reactos/tools/sysreg/env_var.h
Normal file
|
@ -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 <string>
|
||||||
|
#include <map>
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
namespace System_
|
||||||
|
{
|
||||||
|
|
||||||
|
using std::map;
|
||||||
|
typedef std::basic_string<TCHAR> 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<string, string> 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__ */
|
132
reactos/tools/sysreg/pipe_reader.cpp
Normal file
132
reactos/tools/sysreg/pipe_reader.cpp
Normal file
|
@ -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 <iostream>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
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 " <<endl;
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_File = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
bool PipeReader::isEof() const
|
||||||
|
{
|
||||||
|
return feof(m_File);
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
string::size_type PipeReader::readPipe(System_::string &Buffer)
|
||||||
|
{
|
||||||
|
|
||||||
|
TCHAR * buf = (TCHAR *)Buffer.c_str();
|
||||||
|
System_::string::size_type size = Buffer.capacity();
|
||||||
|
|
||||||
|
//#ifdef NDEBUG
|
||||||
|
memset(buf, 0x0, sizeof(TCHAR) * size);
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
TCHAR * res = _fgetts(buf, size, m_File);
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
#ifdef NDEBUG
|
||||||
|
cerr << "Error: PipeReader::readPipe failed" << endl;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NDEBUG
|
||||||
|
cerr << "PipeReader::readPipe> 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_
|
117
reactos/tools/sysreg/pipe_reader.h
Normal file
117
reactos/tools/sysreg/pipe_reader.h
Normal file
|
@ -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 <string>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
namespace System_
|
||||||
|
{
|
||||||
|
typedef std::basic_string<TCHAR> 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__ */
|
87
reactos/tools/sysreg/reg_test.h
Normal file
87
reactos/tools/sysreg/reg_test.h
Normal file
|
@ -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 <string>
|
||||||
|
#include <tchar.h>
|
||||||
|
|
||||||
|
namespace Sysreg_
|
||||||
|
{
|
||||||
|
using Sysreg_::ConfigParser;
|
||||||
|
|
||||||
|
typedef std::basic_string<TCHAR> 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
|
161
reactos/tools/sysreg/rosboot_test.cpp
Normal file
161
reactos/tools/sysreg/rosboot_test.cpp
Normal file
|
@ -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 <iostream>
|
||||||
|
|
||||||
|
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_
|
116
reactos/tools/sysreg/rosboot_test.h
Normal file
116
reactos/tools/sysreg/rosboot_test.h
Normal file
|
@ -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 <winsock2.h>
|
||||||
|
|
||||||
|
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__ */
|
144
reactos/tools/sysreg/sym_file.cpp
Normal file
144
reactos/tools/sysreg/sym_file.cpp
Normal file
|
@ -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 <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
|
||||||
|
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<string> 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" <<endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (strstr(c_file.name, ".nostrip."))
|
||||||
|
{
|
||||||
|
cerr << c_file.name << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}while(_findnext(hFile, &c_file) == 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
bool SymbolFile::resolveAddress(const string &module_name, const string &module_address, string &Buffer)
|
||||||
|
{
|
||||||
|
SymbolMap::const_iterator it = m_Map.find (module_name);
|
||||||
|
/*
|
||||||
|
if (it == m_Map.end ())
|
||||||
|
{
|
||||||
|
#ifdef NDEBUG
|
||||||
|
cerr << "SymbolFile::resolveAddress> 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" <<endl;
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // end of namespace System_
|
110
reactos/tools/sysreg/sym_file.h
Normal file
110
reactos/tools/sysreg/sym_file.h
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
#ifndef SYM_FILE_H__
|
||||||
|
#define SYM_FILE_H__
|
||||||
|
|
||||||
|
|
||||||
|
/* $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 <string>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace System_
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef std::basic_string<TCHAR> 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<string, string> 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__ */
|
82
reactos/tools/sysreg/sysreg.cpp
Normal file
82
reactos/tools/sysreg/sysreg.cpp
Normal file
|
@ -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<TCHAR> 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<RegressionTest, string> ComponentFactory;
|
||||||
|
|
||||||
|
static const TCHAR USAGE[] =
|
||||||
|
_T("sysreg.exe <conf_file> <testname>\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>(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;
|
||||||
|
}
|
34
reactos/tools/sysreg/sysreg.h
Normal file
34
reactos/tools/sysreg/sysreg.h
Normal file
|
@ -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 <tchar.h>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#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__ */
|
Loading…
Reference in a new issue