utilize creation of working copies for tests
This commit is contained in:
parent
9abe04ce06
commit
af5b879506
|
@ -18,10 +18,6 @@ using namespace IoUtilities;
|
|||
|
||||
using namespace CPPUNIT_NS;
|
||||
|
||||
namespace UnitTests {
|
||||
extern string testFilesPath;
|
||||
}
|
||||
|
||||
class IoTests : public TestFixture
|
||||
{
|
||||
CPPUNIT_TEST_SUITE(IoTests);
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace ApplicationUtilities;
|
||||
|
||||
|
@ -16,7 +18,7 @@ TestApplication *TestApplication::m_instance = nullptr;
|
|||
|
||||
/*!
|
||||
* \class TestApplication
|
||||
* \brief The TestApplication class simplifies writing test applications.
|
||||
* \brief The TestApplication class simplifies writing test applications that require opening test files.
|
||||
* \remarks Only one instance is allowed at a time (singletone class).
|
||||
*/
|
||||
|
||||
|
@ -26,12 +28,16 @@ TestApplication *TestApplication::m_instance = nullptr;
|
|||
*/
|
||||
TestApplication::TestApplication(int argc, char **argv) :
|
||||
m_helpArg(m_parser),
|
||||
m_testFilesPathArg("test-files-path", "p", "specifies the path of the directory with test files")
|
||||
m_testFilesPathArg("test-files-path", "p", "specifies the path of the directory with test files"),
|
||||
m_workingDirArg("working-dir", "w", "specifies the directory to store working copies of test files")
|
||||
{
|
||||
// check whether there is already an instance
|
||||
if(m_instance) {
|
||||
throw runtime_error("only one TestApplication instance allowed at a time");
|
||||
}
|
||||
m_instance = this;
|
||||
|
||||
// read TEST_FILE_PATH environment variable
|
||||
if(const char *testFilesPathEnv = getenv("TEST_FILE_PATH")) {
|
||||
if(const auto len = strlen(testFilesPathEnv)) {
|
||||
m_testFilesPathEnvValue.reserve(len + 1);
|
||||
|
@ -39,10 +45,17 @@ TestApplication::TestApplication(int argc, char **argv) :
|
|||
m_testFilesPathEnvValue += '/';
|
||||
}
|
||||
}
|
||||
|
||||
// setup argument parser
|
||||
m_testFilesPathArg.setRequiredValueCount(1);
|
||||
m_testFilesPathArg.setValueNames({"path"});
|
||||
m_testFilesPathArg.setCombinable(true);
|
||||
m_parser.setMainArguments({&m_testFilesPathArg, &m_helpArg});
|
||||
m_workingDirArg.setRequiredValueCount(1);
|
||||
m_workingDirArg.setValueNames({"path"});
|
||||
m_workingDirArg.setCombinable(true);
|
||||
m_parser.setMainArguments({&m_testFilesPathArg, &m_workingDirArg, &m_helpArg});
|
||||
|
||||
// parse arguments
|
||||
try {
|
||||
m_parser.parseArgs(argc, argv);
|
||||
cerr << "Directories used to search for testfiles:" << endl;
|
||||
|
@ -57,6 +70,30 @@ TestApplication::TestApplication(int argc, char **argv) :
|
|||
cerr << m_testFilesPathEnvValue << endl;
|
||||
}
|
||||
cerr << "./testfiles/" << endl << endl;
|
||||
cerr << "Directory used to store working copies:" << endl;
|
||||
if(m_workingDirArg.isPresent()) {
|
||||
if(!m_workingDirArg.values().front().empty()) {
|
||||
m_workingDir = m_workingDirArg.values().front() + '/';
|
||||
} else {
|
||||
m_workingDir = "./";
|
||||
}
|
||||
} else if(const char *workingDirEnv = getenv("WORKING_DIR")) {
|
||||
if(const auto len = strlen(workingDirEnv)) {
|
||||
m_workingDir.reserve(len + 1);
|
||||
m_workingDir += workingDirEnv;
|
||||
m_workingDir += '/';
|
||||
}
|
||||
} else {
|
||||
if(m_testFilesPathArg.isPresent()) {
|
||||
m_workingDir = m_testFilesPathArgValue + "workingdir/";
|
||||
} else if(!m_testFilesPathEnvValue.empty()) {
|
||||
m_workingDir = m_testFilesPathEnvValue + "workingdir/";
|
||||
} else {
|
||||
m_workingDir = "./testfiles/workingdir/";
|
||||
}
|
||||
}
|
||||
cerr << m_workingDir << endl << endl;
|
||||
|
||||
m_valid = true;
|
||||
cerr << "Executing test cases ..." << endl;
|
||||
} catch(const Failure &failure) {
|
||||
|
@ -74,18 +111,22 @@ TestApplication::~TestApplication()
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the full path of tbe test file with the specified \a name.
|
||||
* \brief Returns the full path of the test file with the specified \a name.
|
||||
*/
|
||||
string TestApplication::testFilePath(const string &name) const
|
||||
{
|
||||
string path;
|
||||
fstream file;
|
||||
fstream file; // used to check whether the file is present
|
||||
|
||||
// check the path specified by command line argument
|
||||
if(m_testFilesPathArg.isPresent()) {
|
||||
file.open(path = m_testFilesPathArgValue + name, ios_base::in);
|
||||
if(file.good()) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// check the path specified by environment variable
|
||||
if(!m_testFilesPathEnvValue.empty()) {
|
||||
file.clear();
|
||||
file.open(path = m_testFilesPathEnvValue + name, ios_base::in);
|
||||
|
@ -93,7 +134,41 @@ string TestApplication::testFilePath(const string &name) const
|
|||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// file still not found -> return default path
|
||||
return "./testfiles/" + name;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the full path to a working copy of the test file with the specified \a name.
|
||||
*/
|
||||
string TestApplication::workingCopyPath(const string &name) const
|
||||
{
|
||||
// create file streams
|
||||
fstream origFile, workingCopy;
|
||||
origFile.exceptions(ios_base::badbit | ios_base::failbit);
|
||||
workingCopy.exceptions(ios_base::badbit | ios_base::failbit);
|
||||
|
||||
// ensure working directory is present
|
||||
struct stat currentStat;
|
||||
if(stat(m_workingDir.c_str(), ¤tStat) || !S_ISDIR(currentStat.st_mode)) {
|
||||
if(mkdir(m_workingDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) {
|
||||
cerr << "Unable to create working copy for \"" << name << "\": can't create working directory." << endl;
|
||||
return string();
|
||||
}
|
||||
}
|
||||
|
||||
// copy file
|
||||
try {
|
||||
origFile.open(testFilePath(name), ios_base::in | ios_base::binary);
|
||||
string path = m_workingDir + name;
|
||||
workingCopy.open(path, ios_base::out | ios_base::binary | ios_base::trunc);
|
||||
workingCopy << origFile.rdbuf();
|
||||
return path;
|
||||
} catch(const ios_base::failure &) {
|
||||
cerr << "Unable to create working copy for \"" << name << "\": an IO error occured." << endl;
|
||||
}
|
||||
return string();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,20 +15,26 @@ public:
|
|||
|
||||
operator bool() const;
|
||||
std::string testFilePath(const std::string &name) const;
|
||||
std::string workingCopyPath(const std::string &name) const;
|
||||
static const TestApplication *instance();
|
||||
|
||||
private:
|
||||
ApplicationUtilities::ArgumentParser m_parser;
|
||||
ApplicationUtilities::HelpArgument m_helpArg;
|
||||
ApplicationUtilities::Argument m_testFilesPathArg;
|
||||
ApplicationUtilities::Argument m_workingDirArg;
|
||||
std::string m_testFilesPathArgValue;
|
||||
std::string m_testFilesPathEnvValue;
|
||||
std::string m_workingDir;
|
||||
bool m_valid;
|
||||
static TestApplication *m_instance;
|
||||
};
|
||||
|
||||
/*!
|
||||
* \brief Returns whether the TestApplication instance is valid.
|
||||
*
|
||||
* An instance is considered invalid if an error occured when
|
||||
* parsing the command line arguments.
|
||||
*/
|
||||
inline TestApplication::operator bool() const
|
||||
{
|
||||
|
@ -52,6 +58,15 @@ inline LIB_EXPORT std::string testFilePath(const std::string &name)
|
|||
return TestApplication::instance()->testFilePath(name);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Convenience function which returns the full path to a working copy of the test file with the specified \a name.
|
||||
* \remarks A TestApplication must be present.
|
||||
*/
|
||||
inline LIB_EXPORT std::string workingCopyPath(const std::string &name)
|
||||
{
|
||||
return TestApplication::instance()->workingCopyPath(name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TESTUTILS_H
|
||||
|
|
Loading…
Reference in New Issue