Commit 139472c5 authored by Dave Moxey's avatar Dave Moxey

Changing namespace to Nektar and adding factory for metrics.

git-svn-id: https://gforge.sci.utah.edu/svn/nektar/branches/new-tests@4078 305cdda6-5ce1-45b3-a98d-dfc68c8b3305
parent 615a0992
......@@ -34,46 +34,58 @@
///////////////////////////////////////////////////////////////////////////////
#include <Metric.h>
#include <loki/Singleton.h>
/**
* @brief Constructor.
*/
Metric::Metric(int id) : m_id(id)
namespace Nektar
{
MetricFactory& GetMetricFactory()
{
typedef Loki::SingletonHolder<MetricFactory,
Loki::CreateUsingNew,
Loki::NoDestroy > Type;
return Type::Instance();
}
/**
* @brief Constructor.
*/
Metric::Metric(int id) : m_id(id)
{
}
/**
* @brief Parse the contents of a metric tag. This function is implemented by
* subclasses.
*/
void Metric::Parse(TiXmlElement *metric)
{
v_Parse(metric);
}
}
/**
* @brief Parse the contents of a metric tag. This function is implemented by
* subclasses.
*/
void Metric::Parse(TiXmlElement *metric)
{
v_Parse(metric);
}
/**
* @brief Test a line of output from an executible.
*/
bool Metric::TestLine(std::string line)
{
return v_TestLine(line);
}
/**
* @brief Test which is run after the executible has finished.
*/
bool Metric::FinishTest()
{
return v_FinishTest();
}
bool Metric::v_TestLine(std::string line)
{
return true;
}
bool Metric::v_FinishTest()
{
return true;
/**
* @brief Test a line of output from an executible.
*/
bool Metric::TestLine(std::string line)
{
return v_TestLine(line);
}
/**
* @brief Test which is run after the executible has finished.
*/
bool Metric::FinishTest()
{
return v_FinishTest();
}
bool Metric::v_TestLine(std::string line)
{
return true;
}
bool Metric::v_FinishTest()
{
return true;
}
}
......@@ -39,22 +39,35 @@
#include <tinyxml/tinyxml.h>
#include <string>
class Metric
#include <LibUtilities/BasicUtils/NekFactory.hpp>
namespace Nektar
{
public:
Metric(int id);
void Parse (TiXmlElement *metric);
bool TestLine (std::string line);
bool FinishTest();
protected:
// Stores the ID of this metric.
int m_id;
class Metric
{
public:
Metric(int id);
void Parse (TiXmlElement *metric);
bool TestLine (std::string line);
bool FinishTest();
protected:
// Stores the ID of this metric.
int m_id;
virtual void v_Parse (TiXmlElement *metric) = 0;
virtual bool v_TestLine (std::string line);
virtual bool v_FinishTest();
};
/// A shared pointer to an EquationSystem object
typedef boost::shared_ptr<Metric> MetricSharedPtr;
virtual void v_Parse (TiXmlElement *metric) = 0;
virtual bool v_TestLine (std::string line);
virtual bool v_FinishTest();
};
/// Datatype of the NekFactory used to instantiate classes derived from the
/// Advection class.
typedef LibUtilities::NekFactory<std::string, Metric, int> MetricFactory;
MetricFactory& GetMetricFactory();
}
#endif
......@@ -35,35 +35,42 @@
#include <MetricL2.h>
MetricL2::MetricL2(int id) : MetricRegex(id)
namespace Nektar
{
std::string MetricL2::type = GetMetricFactory().
RegisterCreatorFunction("l2", MetricL2::create);
}
MetricL2::MetricL2(int id) : MetricRegex(id)
{
}
void MetricL2::v_Parse(TiXmlElement *metric)
{
// Set up the regular expression. This (optionally) matches a variable
// name if it exists: first field is variable name, second field is L2
// error.
m_regex = "^L 2 error\\s*(?:\\(variable (\\w+)\\))?\\s*:\\s*([+-]?\\d.+\\d).*";
void MetricL2::v_Parse(TiXmlElement *metric)
{
// Set up the regular expression. This (optionally) matches a variable
// name if it exists: first field is variable name, second field is L2
// error.
m_regex =
"^L 2 error\\s*(?:\\(variable (\\w+)\\))?\\s*:\\s*([+-]?\\d.+\\d).*";
// Find the L2 error to match against.
TiXmlElement *value;
// Find the L2 error to match against.
TiXmlElement *value;
while (value = metric->FirstChildElement("value"))
{
// Find name of field.
std::string variable = value->Attribute("variable");
while (value = metric->FirstChildElement("value"))
{
// Find name of field.
std::string variable = value->Attribute("variable");
// Set up a match with two fields which correspond with the
// subexpression above. The first is the variable name, second is
// the L2 error.
std::vector<std::string> tmp(2);
tmp[0] = variable;
tmp[1] = value->GetText();
m_matches.push_back(tmp);
// Set up a match with two fields which correspond with the
// subexpression above. The first is the variable name, second is
// the L2 error.
std::vector<std::string> tmp(2);
tmp[0] = variable;
tmp[1] = value->GetText();
m_matches.push_back(tmp);
// Indicate that the L2 error needs tolerance testing.
m_tolerance.insert(1);
// Indicate that the L2 error needs tolerance testing.
m_tolerance.insert(1);
}
}
}
......@@ -38,13 +38,23 @@
#include <MetricRegex.h>
class MetricL2 : public MetricRegex
namespace Nektar
{
public:
MetricL2(int id);
protected:
virtual void v_Parse(TiXmlElement *metric);
};
class MetricL2 : public MetricRegex
{
public:
static MetricSharedPtr create(int id)
{
return MetricSharedPtr(new MetricL2(id));
}
static std::string type;
protected:
MetricL2(int id);
virtual void v_Parse(TiXmlElement *metric);
};
}
#endif
......@@ -37,60 +37,65 @@
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
/**
* @brief Constructor.
*/
MetricRegex::MetricRegex(int id) : Metric(id)
namespace Nektar
{
std::string MetricRegex::type = GetMetricFactory().
RegisterCreatorFunction("regex", MetricRegex::create);
}
void MetricRegex::v_Parse(TiXmlElement *metric)
{
// Parse a regex <METRIC> tag. This would populate m_regex, m_matches
// and m_tolerance below.
}
/**
* @brief Constructor.
*/
MetricRegex::MetricRegex(int id) : Metric(id)
{
}
bool MetricRegex::v_TestLine(std::string line)
{
// If we have matched everything, nothing to do.
if (m_matches.size() == 0)
void MetricRegex::v_Parse(TiXmlElement *metric)
{
return true;
// Parse a regex <METRIC> tag. This would populate m_regex, m_matches
// and m_tolerance below.
}
boost::cmatch matches;
std::vector<std::string> &okValues = m_matches[0];
// Test to see if we have a match.
if (boost::regex_match(line.c_str(), matches, m_regex))
bool MetricRegex::v_TestLine(std::string line)
{
for (int i = 0; i < matches.size(); ++i)
// If we have matched everything, nothing to do.
if (m_matches.size() == 0)
{
std::string match(matches[i].first, matches[i].second);
return true;
}
boost::cmatch matches;
std::vector<std::string> &okValues = m_matches[0];
if (m_tolerance.count(i) > 0)
// Test to see if we have a match.
if (boost::regex_match(line.c_str(), matches, m_regex))
{
for (int i = 0; i < matches.size(); ++i)
{
// If the okValues are not within tolerance, failed the
// test.
if (fabs(boost::lexical_cast<int>(okValues[i]) -
boost::lexical_cast<int>(match)) > 1e-6)
std::string match(matches[i].first, matches[i].second);
if (m_tolerance.count(i) > 0)
{
return false;
// If the okValues are not within tolerance, failed the
// test.
if (fabs(boost::lexical_cast<int>(okValues[i]) -
boost::lexical_cast<int>(match)) > 1e-6)
{
return false;
}
}
}
else
{
// Case insensitive match.
if (!boost::iequals(match, okValues[i]))
else
{
return false;
// Case insensitive match.
if (!boost::iequals(match, okValues[i]))
{
return false;
}
}
}
}
// Remove this match from the list of matches.
m_matches.erase(m_matches.begin());
// Remove this match from the list of matches.
m_matches.erase(m_matches.begin());
}
}
}
......@@ -40,21 +40,31 @@
#include <boost/regex.hpp>
#include <vector>
class MetricRegex : public Metric
namespace Nektar
{
public:
MetricRegex(int id);
class MetricRegex : public Metric
{
public:
static MetricSharedPtr create(int id)
{
return MetricSharedPtr(new MetricRegex(id));
}
static std::string type;
protected:
// Storage for the boost regex.
boost::regex m_regex;
// Stores the multiple matches defined in each <MATCH> tag.
std::vector<std::vector<std::string> > m_matches;
// Indicates which fields of a match need to be tested for tolerance.
std::set<int> m_tolerance;
protected:
/// Storage for the boost regex.
boost::regex m_regex;
/// Stores the multiple matches defined in each <MATCH> tag.
std::vector<std::vector<std::string> > m_matches;
/// Indicates which fields of a match need to be tested for tolerance.
std::set<int> m_tolerance;
MetricRegex(int id);
virtual void v_Parse (TiXmlElement *metric);
virtual bool v_TestLine(std::string line);
};
virtual void v_Parse (TiXmlElement *metric);
virtual bool v_TestLine(std::string line);
};
}
#endif
......@@ -37,18 +37,41 @@
#include <iostream>
#include <string>
#include <vector>
#include <sys/stat.h>
#include <MetricL2.h>
#include <MetricRegex.h>
#include <boost/filesystem.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/version.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/program_options.hpp>
#ifdef _WINDOWS
#define COPY_COMMAND "copy "
#else
#define COPY_COMMAND "cp "
#endif
using namespace std;
using namespace Nektar;
namespace po = boost::program_options;
std::string PortablePath(const boost::filesystem::path& path)
{
boost::filesystem::path temp = path;
#if BOOST_VERSION > 104200
temp.make_preferred();
return temp.string();
#else
return temp.file_string();
#endif
}
int main(int argc, char *argv[])
{
// Open file.
// Process test file format.
TiXmlDocument *file = new TiXmlDocument(argv[1]);
bool loadOkay = file->LoadFile();
......@@ -65,23 +88,21 @@ int main(int argc, char *argv[])
// Find description tag.
TiXmlElement *descElement = handle.FirstChildElement("test").
FirstChildElement("description").Element();
string description(descElement->GetText());
cout << description << endl;
// Find solver tag.
TiXmlElement *solverElement = handle.FirstChildElement("test").
FirstChildElement("executable").Element();
string executable(solverElement->GetText());
cout << executable << endl;
// Find input tag.
TiXmlElement *inputElement = handle.FirstChildElement("test").
FirstChildElement("parameters").Element();
string input(inputElement->GetText());
cout << input << endl;
// Iterate through metric tags.
/*
* Process and set up metric tags.
*/
TiXmlElement *metrics = testElement->FirstChildElement("metrics");
if (!metrics)
......@@ -91,33 +112,70 @@ int main(int argc, char *argv[])
}
// Construct vector of metrics.
TiXmlElement *metric = metrics->FirstChildElement("metric");
vector<Metric*> metricList;
TiXmlElement *metric = metrics->FirstChildElement("metric");
vector<MetricSharedPtr> metricList;
while (metric)
{
string metricType = metric->Attribute("type");
int metricId = boost::lexical_cast<int>(metric->Attribute("id"));
Metric *m;
boost::algorithm::to_lower(metricType);
MetricSharedPtr m = GetMetricFactory().CreateInstance(
metricType, metricId);
metricList.push_back(m);
cout << "Metric type: " << metricType << ", id = " << metricId << endl;
if (metricType == "L2")
m->Parse(metric);
metric = metric->NextSiblingElement("metric");
}
/*
* Copy required files for this test.
*/
TiXmlElement *required = handle.FirstChildElement("test").
FirstChildElement("required").Element();
TiXmlElement *reqfile = required->FirstChildElement("file");
struct stat vFileInfo;
while (reqfile)
{
string fname = reqfile->GetText();
string source = PortablePath(std::string(TEST_PATH)) + fname;
string command = std::string(COPY_COMMAND) + source + " .";
int vNotPresent = stat(source.c_str(), &vFileInfo);
if (vNotPresent)
{
m = new MetricL2(metricId);
cerr << "Required file " << fname << " not found." << endl;
return 1;
}
else if (metricType == "Regex")
int status = system(command.c_str());
if (status)
{
m = new MetricRegex(metricId);
cerr << "Unable to copy file:" << source
<< " to current location" << endl;
return 1;
}
m->Parse(metric);
metric = metric->NextSiblingElement("metric");
reqfile = metric->NextSiblingElement("required");
}
/*
* Run executable and perform tests.
*/
string cmd = executable + " " + input;
/*
while (getline(fpstream, line))
ifstream file(filename);
while (getline(file, line))
{
for (int i = 0; i < metricList.size(); ++i)
{
......@@ -127,7 +185,7 @@ int main(int argc, char *argv[])
}
}
}
for (int i = 0; i < metricList.size(); ++i)
{
if (!metricList[i]->FinishTest())
......@@ -136,7 +194,6 @@ int main(int argc, char *argv[])
}
}
*/
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment