Commit fcdedf09 authored by Chris Cantwell's avatar Chris Cantwell

Updated new regression tests to read in XML file, generate metric objects and

execute command.
parent c53c5ae6
......@@ -2,6 +2,7 @@ SET(TESTER_SOURCES
Metric.cpp
MetricL2.cpp
MetricRegex.cpp
TestData.cpp
Tester.cpp
)
......@@ -9,9 +10,12 @@ SET(TESTER_HEADERS
Metric.h
MetricL2.h
MetricRegex.h
TestData.h
Tester.h
)
ADD_DEFINITIONS(-DBUILD_PATH="${CMAKE_BINARY_DIR}" -DSOURCE_PATH="${CMAKE_SOURCE_DIR}")
ADD_EXECUTABLE(Tester ${TESTER_SOURCES} ${ARGN})
TARGET_LINK_LIBRARIES(Tester
${Boost_FILESYSTEM_LIBRARY}
......
......@@ -36,6 +36,8 @@
#include <Metric.h>
#include <loki/Singleton.h>
using namespace std;
namespace Nektar
{
MetricFactory& GetMetricFactory()
......@@ -49,9 +51,13 @@ namespace Nektar
/**
* @brief Constructor.
*/
Metric::Metric(int id) : m_id(id)
Metric::Metric(TiXmlElement *metric)
{
if (!metric->Attribute("id"))
{
cout << "Metric has no ID" << endl;
}
m_id = atoi(metric->Attribute("id"));
}
/**
......
......@@ -46,9 +46,8 @@ namespace Nektar
class Metric
{
public:
Metric(int id);
Metric(TiXmlElement *metric);
void Parse (TiXmlElement *metric);
bool TestLine (std::string line);
bool FinishTest();
......@@ -59,6 +58,9 @@ namespace Nektar
virtual void v_Parse (TiXmlElement *metric) = 0;
virtual bool v_TestLine (std::string line);
virtual bool v_FinishTest();
private:
void Parse (TiXmlElement *metric);
};
/// A shared pointer to an EquationSystem object
......@@ -66,8 +68,10 @@ namespace Nektar
/// Datatype of the NekFactory used to instantiate classes derived from the
/// Advection class.
typedef LibUtilities::NekFactory<std::string, Metric, int> MetricFactory;
typedef LibUtilities::NekFactory<std::string, Metric, TiXmlElement*> MetricFactory;
MetricFactory& GetMetricFactory();
}
#endif
......@@ -40,12 +40,7 @@ namespace Nektar
std::string MetricL2::type = GetMetricFactory().
RegisterCreatorFunction("l2", MetricL2::create);
MetricL2::MetricL2(int id) : MetricRegex(id)
{
}
void MetricL2::v_Parse(TiXmlElement *metric)
MetricL2::MetricL2(TiXmlElement *metric) : MetricRegex(metric)
{
// Set up the regular expression. This (optionally) matches a variable
// name if it exists: first field is variable name, second field is L2
......@@ -54,9 +49,9 @@ namespace Nektar
"^L 2 error\\s*(?:\\(variable (\\w+)\\))?\\s*:\\s*([+-]?\\d.+\\d).*";
// Find the L2 error to match against.
TiXmlElement *value;
TiXmlElement *value = metric->FirstChildElement("value");
while (value = metric->FirstChildElement("value"))
while (value)
{
// Find name of field.
std::string variable = value->Attribute("variable");
......@@ -71,6 +66,9 @@ namespace Nektar
// Indicate that the L2 error needs tolerance testing.
m_tolerance.insert(1);
value = value->NextSiblingElement("value");
}
}
}
......@@ -43,17 +43,16 @@ namespace Nektar
class MetricL2 : public MetricRegex
{
public:
static MetricSharedPtr create(int id)
static MetricSharedPtr create(TiXmlElement *metric)
{
return MetricSharedPtr(new MetricL2(id));
return MetricSharedPtr(new MetricL2(metric));
}
static std::string type;
protected:
MetricL2(int id);
MetricL2(TiXmlElement *metric);
virtual void v_Parse(TiXmlElement *metric);
};
}
......
......@@ -45,7 +45,7 @@ namespace Nektar
/**
* @brief Constructor.
*/
MetricRegex::MetricRegex(int id) : Metric(id)
MetricRegex::MetricRegex(TiXmlElement *metric) : Metric(metric)
{
}
......
......@@ -45,9 +45,9 @@ namespace Nektar
class MetricRegex : public Metric
{
public:
static MetricSharedPtr create(int id)
static MetricSharedPtr create(TiXmlElement *metric)
{
return MetricSharedPtr(new MetricRegex(id));
return MetricSharedPtr(new MetricRegex(metric));
}
static std::string type;
......@@ -60,7 +60,7 @@ namespace Nektar
/// Indicates which fields of a match need to be tested for tolerance.
std::set<int> m_tolerance;
MetricRegex(int id);
MetricRegex(TiXmlElement *metric);
virtual void v_Parse (TiXmlElement *metric);
virtual bool v_TestLine(std::string line);
......
/*
* TestData.cpp
*
* Created on: 18 Oct 2012
* Author: cc
*/
#include <boost/lexical_cast.hpp>
#include <LibUtilities/BasicUtils/ErrorUtil.hpp>
#include "TestData.h"
using namespace std;
namespace Nektar
{
namespace Test
{
TestData::TestData(const std::string& pFilename)
{
// Process test file format.
m_doc = new TiXmlDocument(pFilename.c_str());
bool loadOkay = m_doc->LoadFile();
ASSERTL0(loadOkay, "Failed to load file: " + string(m_doc->ErrorDesc()));
Parse(m_doc);
}
TestData::TestData(const TestData& pSrc)
{
}
const std::string& TestData::GetDescription() const
{
return m_description;
}
const std::string& TestData::GetExecutable() const
{
return m_executable;
}
const std::string& TestData::GetParameters() const
{
return m_parameters;
}
std::string TestData::GetMetricType(unsigned int pId) const
{
ASSERTL0(pId < m_metrics.size(), "Metric ID out of range.");
// read the property name
ASSERTL0(m_metrics[pId]->Attribute("type"),
"Missing 'type' attribute in metric "
+ boost::lexical_cast<string>(pId) + ").");
return string(m_metrics[pId]->Attribute("type"));
}
unsigned int TestData::GetNumMetrics() const
{
return m_metrics.size();
}
TiXmlElement* TestData::GetMetric(unsigned int pId)
{
ASSERTL0(pId < m_metrics.size(), "Metric index out of range.");
return m_metrics[pId];
}
DependentFile TestData::GetDependentFile(unsigned int pId) const
{
ASSERTL0(pId < m_files.size(), "File index out of range.");
return m_files[pId];
}
unsigned int TestData::GetNumDependentFiles() const
{
return m_files.size();
}
void TestData::Parse(TiXmlDocument* pDoc)
{
TiXmlHandle handle(m_doc);
TiXmlElement *testElement, *tmp, *metrics, *files;
testElement = handle.FirstChildElement("test").Element();
ASSERTL0(testElement, "Cannot find 'test' root element.");
// Find description tag.
tmp = testElement->FirstChildElement("description");
m_description = string(tmp->GetText());
ASSERTL0(tmp, "Cannot find 'description' for test.");
// Find solver tag.
tmp = testElement->FirstChildElement("executable");
m_executable = string(tmp->GetText());
ASSERTL0(tmp, "Cannot find 'executable' for test.");
// Find input tag.
tmp = testElement->FirstChildElement("parameters");
m_parameters = string(tmp->GetText());
ASSERTL0(tmp, "Cannot find 'parameters' for test.");
metrics = testElement->FirstChildElement("metrics");
ASSERTL0(metrics, "No metrics defined for test.");
tmp = metrics->FirstChildElement("metric");
while (tmp)
{
m_metrics.push_back(tmp);
tmp = tmp->NextSiblingElement("metric");
}
files = testElement->FirstChildElement("files");
if (files)
{
tmp = files->FirstChildElement("file");
while (tmp)
{
DependentFile f;
f.m_filename = string(tmp->GetText());
if (tmp->Attribute("description"))
{
f.m_description = string(tmp->Attribute("description"));
}
m_files.push_back(f);
tmp = tmp->NextSiblingElement("file");
}
}
}
}
}
/*
* TestData.h
*
* Created on: 18 Oct 2012
* Author: cc
*/
#ifndef TESTDATA_H_
#define TESTDATA_H_
#include <string>
#include <vector>
#include <tinyxml/tinyxml.h>
namespace Nektar
{
namespace Test
{
struct DependentFile
{
std::string m_description;
std::string m_filename;
};
class TestData
{
public:
TestData(const std::string& pFilename);
TestData(const TestData& pSrc);
const std::string& GetDescription() const;
const std::string& GetExecutable() const;
const std::string& GetParameters() const;
std::string GetMetricType(unsigned int pId) const;
unsigned int GetNumMetrics() const;
TiXmlElement* GetMetric(unsigned int pId);
DependentFile GetDependentFile(unsigned int pId) const;
unsigned int GetNumDependentFiles() const;
private:
std::string m_filename;
std::string m_description;
std::string m_executable;
std::string m_parameters;
TiXmlDocument* m_doc;
std::vector<TiXmlElement*> m_metrics;
std::vector<DependentFile> m_files;
void Parse(TiXmlDocument* pDoc);
};
}
}
#endif /* TESTDATA_H_ */
......@@ -39,6 +39,7 @@
#include <vector>
#include <sys/stat.h>
#include <TestData.h>
#include <MetricL2.h>
#include <MetricRegex.h>
......@@ -50,8 +51,12 @@
#ifdef _WINDOWS
#define COPY_COMMAND "copy "
#define MKDIR_COMMAND "mkdir "
#define DEL_COMMAND "del "
#else
#define COPY_COMMAND "cp "
#define MKDIR_COMMAND "mkdir "
#define DEL_COMMAND "rm -rf "
#endif
using namespace std;
......@@ -71,86 +76,30 @@ std::string PortablePath(const boost::filesystem::path& path)
int main(int argc, char *argv[])
{
// Process test file format.
TiXmlDocument *file = new TiXmlDocument(argv[1]);
bool loadOkay = file->LoadFile();
if (!loadOkay)
{
cout << file->ErrorDesc() << endl;
return 1;
}
TiXmlHandle handle(file);
TiXmlElement *testElement;
testElement = handle.FirstChildElement("test").Element();
// Find description tag.
TiXmlElement *descElement = handle.FirstChildElement("test").
FirstChildElement("description").Element();
string description(descElement->GetText());
// Find solver tag.
TiXmlElement *solverElement = handle.FirstChildElement("test").
FirstChildElement("executable").Element();
string executable(solverElement->GetText());
// Find input tag.
TiXmlElement *inputElement = handle.FirstChildElement("test").
FirstChildElement("parameters").Element();
string input(inputElement->GetText());
// Parse the test file
Test::TestData file("example.xml");
/*
* Process and set up metric tags.
*/
TiXmlElement *metrics = testElement->FirstChildElement("metrics");
if (!metrics)
{
cout << "Couldn't find metrics tag." << endl;
return 1;
}
// Construct vector of metrics.
TiXmlElement *metric = metrics->FirstChildElement("metric");
vector<MetricSharedPtr> metricList;
while (metric)
// Generate the metric objects
vector<MetricSharedPtr> metrics;
for (unsigned int i = 0; i < file.GetNumMetrics(); ++i)
{
string metricType = metric->Attribute("type");
int metricId = boost::lexical_cast<int>(metric->Attribute("id"));
boost::algorithm::to_lower(metricType);
MetricSharedPtr m = GetMetricFactory().CreateInstance(
metricType, metricId);
metricList.push_back(m);
cout << "Metric type: " << metricType << ", id = " << metricId << endl;
m->Parse(metric);
metric = metric->NextSiblingElement("metric");
metrics.push_back(GetMetricFactory().CreateInstance(file.GetMetricType(i), file.GetMetric(i)));
}
/*
* Copy required files for this test.
*/
TiXmlElement *required = handle.FirstChildElement("test").
FirstChildElement("required").Element();
TiXmlElement *reqfile = required->FirstChildElement("file");
// Copy required files for this test.
struct stat vFileInfo;
while (reqfile)
for (unsigned int i = 0; i < file.GetNumDependentFiles(); ++i)
{
string fname = reqfile->GetText();
string source = PortablePath(std::string(TEST_PATH)) + fname;
string command = std::string(COPY_COMMAND) + source + " .";
Test::DependentFile f = file.GetDependentFile(i);
string fname = file.GetDependentFile(i).m_filename;
string source = PortablePath(std::string(SOURCE_PATH) + "/" + fname);
string command = std::string(COPY_COMMAND)
+ source + " .";
int vNotPresent = stat(source.c_str(), &vFileInfo);
if (vNotPresent)
{
cerr << "Required file " << fname << " not found." << endl;
cerr << "Required file " << source << " not found." << endl;
return 1;
}
......@@ -158,19 +107,24 @@ int main(int argc, char *argv[])
if (status)
{
cerr << "Unable to copy file:" << source
cerr << "Unable to copy file:" << source
<< " to current location" << endl;
return 1;
}
reqfile = metric->NextSiblingElement("required");
}
/*
* Run executable and perform tests.
*/
string cmd = executable + " " + input;
// Construct command to run
std::string command;
command += PortablePath(std::string(BUILD_PATH) + "/" + file.GetExecutable());
//#if defined(NDEBUG)
command += "-g";
//#endif
command += " " + file.GetParameters();
command += " 1>output.out 2>output.err";
// Run executable and perform tests.
cout << "EXECUTING: " << command << endl;
int status=system(command.c_str());
/*
ifstream file(filename);
......
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