From: Mark Abraham Date: Mon, 27 Jan 2014 19:43:04 +0000 (+0100) Subject: Extend TestFileManager X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=commitdiff_plain;h=501f7c95736dc745502b65d08ac33f498ffa82a4;p=alexxy%2Fgromacs.git Extend TestFileManager A test fixture may wish to change the output temporary directory, and should be able to do so without perturbing the global state from which the test TestFileManager object is initialized. The only client of this feature (the setup code) is updated accordingly. Minor fixes to existing documentation. Change-Id: I7ba7a82964c05f12de107710655b6320d42ae99c --- diff --git a/src/testutils/testfilemanager.cpp b/src/testutils/testfilemanager.cpp index 0a7027ec5f..3d6f251975 100644 --- a/src/testutils/testfilemanager.cpp +++ b/src/testutils/testfilemanager.cpp @@ -75,12 +75,23 @@ class TestFileManager::Impl //! Global test input data path set with setDataInputDirectory(). static const char *s_inputDirectory; - //! Global temporary output directory for tests, set with setOutputTempDirectory(). - static const char *s_outputTempDirectory; + //! Global temporary output directory for tests, set with setGlobalOutputTempDirectory(). + static const char *s_globalOutputTempDirectory; //! Container type for names of temporary files. typedef std::set FileNameList; + /*! \brief Constructor + * + * \param path Value for the outputTempDirectory, typically + * set by default from s_globalOutputTempDirectory */ + explicit Impl(const char *path) + : outputTempDirectory_(path) + { + GMX_RELEASE_ASSERT(Directory::exists(outputTempDirectory_), + "Directory for tests' temporary files does not exist"); + } + /*! \brief * Try to remove all temporary files. * @@ -90,10 +101,15 @@ class TestFileManager::Impl //! List of unique paths returned by getTemporaryFilePath(). FileNameList files_; + + /*! \brief Temporary output directory local to the current + * test, set by a test with setOutputTempDirectory() if the + * global default is inappropriate. */ + std::string outputTempDirectory_; }; -const char *TestFileManager::Impl::s_inputDirectory = NULL; -const char *TestFileManager::Impl::s_outputTempDirectory = NULL; +const char *TestFileManager::Impl::s_inputDirectory = NULL; +const char *TestFileManager::Impl::s_globalOutputTempDirectory = NULL; /** Controls whether TestFileManager should delete temporary files after the test finishes. */ static bool g_bDeleteFilesAfterTest = true; @@ -122,7 +138,7 @@ void TestFileManager::Impl::removeFiles() */ TestFileManager::TestFileManager() - : impl_(new Impl()) + : impl_(new Impl(Impl::s_globalOutputTempDirectory)) { } @@ -174,10 +190,15 @@ const char *TestFileManager::getInputDataDirectory() return Impl::s_inputDirectory; } -const char *TestFileManager::getOutputTempDirectory() +const char *TestFileManager::getGlobalOutputTempDirectory() +{ + GMX_RELEASE_ASSERT(Impl::s_globalOutputTempDirectory != NULL, "Global path for temporary output files from tests is not set"); + return Impl::s_globalOutputTempDirectory; +} + +const char *TestFileManager::getOutputTempDirectory() const { - GMX_RELEASE_ASSERT(Impl::s_outputTempDirectory != NULL, "Path for temporary output files from tests is not set"); - return Impl::s_outputTempDirectory; + return impl_->outputTempDirectory_.c_str(); } void TestFileManager::setInputDataDirectory(const char *path) @@ -189,13 +210,22 @@ void TestFileManager::setInputDataDirectory(const char *path) Impl::s_inputDirectory = path; } -void TestFileManager::setOutputTempDirectory(const char *path) +void TestFileManager::setGlobalOutputTempDirectory(const char *path) { // There is no need to protect this by a mutex, as this is called in early // initialization of the tests. GMX_RELEASE_ASSERT(Directory::exists(path), "Directory for tests' temporary files does not exist"); - Impl::s_outputTempDirectory = path; + Impl::s_globalOutputTempDirectory = path; +} + +void TestFileManager::setOutputTempDirectory(const std::string &path) +{ + // There could be a need to protect this with a mutex, since it is + // intended to be used in test fixtures, not just during setup. + GMX_RELEASE_ASSERT(Directory::exists(path), + "Directory for tests' temporary files does not exist"); + impl_->outputTempDirectory_ = path; } } // namespace test diff --git a/src/testutils/testfilemanager.h b/src/testutils/testfilemanager.h index 62c3314824..ea88776e4b 100644 --- a/src/testutils/testfilemanager.h +++ b/src/testutils/testfilemanager.h @@ -1,7 +1,7 @@ /* * This file is part of the GROMACS molecular simulation package. * - * Copyright (c) 2012,2013, by the GROMACS development team, led by + * Copyright (c) 2012,2013,2014, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -67,7 +67,7 @@ namespace test { /*! \libinternal \brief - * Helper for tests that need output files. + * Helper for tests that need input and output files. * * To be used as a member in a test fixture class, this class provides * getTemporaryFilePath() method that returns a path for creating file names @@ -77,10 +77,18 @@ namespace test * getTemporaryFilePath()) at test teardown (i.e., when the * TestFileManager is destructed). * - * Functions getInputFilePath() and getInputDataDirectory() provide means to + * In addition, class-level static accessors provide means to * access data files that are located in the test source directory. - * This is used to provide input files for the tests, and also to store test - * reference data persistently (see TestReferenceData). + * This is used to provide input files for the tests, and also to + * store test reference data persistently (see TestReferenceData). + * + * Note that setInputDataDirectory() and + * setGlobalOutputTempDirectory() must be called in setup code, before + * creating any objects of this class that are used for accessing the + * paths for these respective directories. Code in tests should avoid + * calling setGlobalOutputTempDirectory(), and instead instantiate an + * object and use setOutputTempDirectory(), so that the global state + * is not changed. * * \inlibraryapi * \ingroup module_testutils @@ -112,6 +120,27 @@ class TestFileManager */ std::string getTemporaryFilePath(const char *suffix); + /*! \brief Returns the path to the output temporary directory + * for tests which use this TestFileManager object. + * + * \returns Path to output temporary directory + */ + const char *getOutputTempDirectory() const; + + /*! \brief Sets the output temporary directory for tests which + * use this TestFileManager object. + * + * \param[in] path Path at which test should write temporary files + * + * \p path must name an existing directory. An internal copy + * of path is made. The caller is responsible for holding a + * valid mutex on the object before calling this member + * function. + */ + void setOutputTempDirectory(const std::string &path); + + // static functions follow + /*! \brief * Creates a file name for use within a single unit test. * @@ -143,13 +172,6 @@ class TestFileManager */ static const char *getInputDataDirectory(); - /*! \brief - * Returns the path to the test output temporary directory. - * - * \returns Path to output temporary directory for the test executable. - */ - static const char *getOutputTempDirectory(); - /*! \brief * Sets the test input directory. * @@ -162,17 +184,26 @@ class TestFileManager */ static void setInputDataDirectory(const char *path); - /*! \brief - * Sets the test output temporary directory. + /*! \brief Returns the path to the global test output + * temporary directory for future TestFileManager objects. * - * \param[in] path Path at which test should write temporary files + * \returns Path to default output temporary directory for the test executable. + */ + static const char *getGlobalOutputTempDirectory(); + + /*! \brief Sets the default global test output temporary + * directory for future TestFileManager objects. + * + * \param[in] path Path at which tests should write temporary files * * \p path must name an existing directory. * - * This function is automatically called by unittest_main.cpp through - * initTestUtils(). + * This function is automatically called by unittest_main.cpp + * through initTestUtils(). Test fixtures should call + * setOutputTempDirectory(), rather than change the global + * state. */ - static void setOutputTempDirectory(const char *path); + static void setGlobalOutputTempDirectory(const char *path); private: class Impl; diff --git a/src/testutils/testoptions.cpp b/src/testutils/testoptions.cpp index cf7f3bcee9..0b5e1c8951 100644 --- a/src/testutils/testoptions.cpp +++ b/src/testutils/testoptions.cpp @@ -153,7 +153,7 @@ void initTestUtils(const char *dataPath, const char *tempPath, int *argc, char * } if (tempPath != NULL) { - TestFileManager::setOutputTempDirectory(tempPath); + TestFileManager::setGlobalOutputTempDirectory(tempPath); } bool bHelp = false; Options options(NULL, NULL);