rippled
FileDirGuard.h
1 //------------------------------------------------------------------------------
2 /*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2018 Ripple Labs Inc.
5 
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9 
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef TEST_UNIT_TEST_DIRGUARD_H
21 #define TEST_UNIT_TEST_DIRGUARD_H
22 
23 #include <ripple/basics/contract.h>
24 #include <boost/filesystem.hpp>
25 #include <test/jtx/TestSuite.h>
26 
27 namespace ripple {
28 namespace test {
29 namespace detail {
30 
34 class DirGuard
35 {
36 protected:
37  using path = boost::filesystem::path;
38 
39 private:
41  bool rmSubDir_{false};
42 
43 protected:
44  beast::unit_test::suite& test_;
45 
46  auto
47  rmDir(path const& toRm)
48  {
49  if (is_directory(toRm) && is_empty(toRm))
50  remove(toRm);
51  else
52  test_.log << "Expected " << toRm.string()
53  << " to be an empty existing directory." << std::endl;
54  }
55 
56 public:
57  DirGuard(beast::unit_test::suite& test, path subDir, bool useCounter = true)
58  : subDir_(std::move(subDir)), test_(test)
59  {
60  using namespace boost::filesystem;
61 
62  static auto subDirCounter = 0;
63  if (useCounter)
64  subDir_ += std::to_string(++subDirCounter);
65  if (!exists(subDir_))
66  {
67  create_directory(subDir_);
68  rmSubDir_ = true;
69  }
70  else if (is_directory(subDir_))
71  rmSubDir_ = false;
72  else
73  {
74  // Cannot run the test. Someone created a file where we want to
75  // put our directory
76  Throw<std::runtime_error>(
77  "Cannot create directory: " + subDir_.string());
78  }
79  }
80 
82  {
83  try
84  {
85  using namespace boost::filesystem;
86 
87  if (rmSubDir_)
88  rmDir(subDir_);
89  }
90  catch (std::exception& e)
91  {
92  // if we throw here, just let it die.
93  test_.log << "Error in ~DirGuard: " << e.what() << std::endl;
94  };
95  }
96 
97  path const&
98  subdir() const
99  {
100  return subDir_;
101  }
102 };
103 
107 class FileDirGuard : public DirGuard
108 {
109 protected:
110  path const file_;
111  bool created_ = false;
112 
113 public:
115  beast::unit_test::suite& test,
116  path subDir,
117  path file,
118  std::string const& contents,
119  bool useCounter = true,
120  bool create = true)
121  : DirGuard(test, subDir, useCounter)
122  , file_(file.is_absolute() ? file : subdir() / file)
123  {
124  if (!exists(file_))
125  {
126  if (create)
127  {
128  std::ofstream o(file_.string());
129  o << contents;
130  created_ = true;
131  }
132  }
133  else
134  {
135  Throw<std::runtime_error>(
136  "Refusing to overwrite existing file: " + file_.string());
137  }
138  }
139 
141  {
142  try
143  {
144  using namespace boost::filesystem;
145  if (exists(file_))
146  {
147  remove(file_);
148  }
149  else
150  {
151  if (created_)
152  test_.log << "Expected " << file_.string()
153  << " to be an existing file." << std::endl;
154  }
155  }
156  catch (std::exception& e)
157  {
158  // if we throw here, just let it die.
159  test_.log << "Error in ~FileGuard: " << e.what() << std::endl;
160  };
161  }
162 
163  path const&
164  file() const
165  {
166  return file_;
167  }
168 
169  bool
170  fileExists() const
171  {
172  return boost::filesystem::exists(file_);
173  }
174 };
175 
176 } // namespace detail
177 } // namespace test
178 } // namespace ripple
179 
180 #endif // TEST_UNIT_TEST_DIRGUARD_H
std::string
STL class.
std::exception
STL class.
ripple::test::detail::DirGuard
Create a directory and remove it when it's done.
Definition: FileDirGuard.h:34
ripple::test::detail::DirGuard::~DirGuard
~DirGuard()
Definition: FileDirGuard.h:81
ripple::test::detail::DirGuard::subdir
path const & subdir() const
Definition: FileDirGuard.h:98
ripple::test::detail::FileDirGuard::file
path const & file() const
Definition: FileDirGuard.h:164
std::ofstream
STL class.
std::to_string
T to_string(T... args)
ripple::test::jtx::path
Add a path.
Definition: paths.h:55
ripple::test::detail::DirGuard::test_
beast::unit_test::suite & test_
Definition: FileDirGuard.h:44
ripple::test::detail::FileDirGuard::~FileDirGuard
~FileDirGuard()
Definition: FileDirGuard.h:140
ripple::test::detail::DirGuard::subDir_
path subDir_
Definition: FileDirGuard.h:40
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::detail::FileDirGuard::FileDirGuard
FileDirGuard(beast::unit_test::suite &test, path subDir, path file, std::string const &contents, bool useCounter=true, bool create=true)
Definition: FileDirGuard.h:114
std::endl
T endl(T... args)
std
STL namespace.
ripple::test::detail::DirGuard::rmSubDir_
bool rmSubDir_
Definition: FileDirGuard.h:41
ripple::test::detail::FileDirGuard::fileExists
bool fileExists() const
Definition: FileDirGuard.h:170
ripple::test::detail::FileDirGuard
Write a file in a directory and remove when done.
Definition: FileDirGuard.h:107
ripple::test::detail::DirGuard::rmDir
auto rmDir(path const &toRm)
Definition: FileDirGuard.h:47
ripple::test::detail::FileDirGuard::file_
const path file_
Definition: FileDirGuard.h:110
ripple::test::detail::DirGuard::path
boost::filesystem::path path
Definition: FileDirGuard.h:37
std::exception::what
T what(T... args)
ripple::test::detail::DirGuard::DirGuard
DirGuard(beast::unit_test::suite &test, path subDir, bool useCounter=true)
Definition: FileDirGuard.h:57