PostCloseFileRenamer_t.cc
Go to the documentation of this file.
1 #define BOOST_TEST_MODULE (PostCloseFileRenamer_t)
2 #include "boost/test/unit_test.hpp"
3 
6 #include "boost/filesystem.hpp"
7 
8 extern "C" {
9 #include <sys/stat.h> // mkdir().
10 #include <unistd.h> // chdir().
11 }
12 
13 #include <chrono>
14 #include <thread>
15 
18 using namespace std::chrono_literals;
19 using namespace std::string_literals;
20 
21 namespace {
22  struct TestFixture {
23  void simulateJob();
24 
25  FileStatsCollector fstats{"label", "DEVEL"};
26  };
27 
28  void
29  TestFixture::simulateJob()
30  {
31  fstats.recordFileOpen();
32  art::EventID const e1{1, 0, 7};
33  fstats.recordEvent(e1);
34  fstats.recordSubRun(e1.subRunID());
35  // Warning, this sleep is used for multiple tests below.
36  std::this_thread::sleep_for(1s);
37  art::EventID const e2{1, 1, 3};
38  fstats.recordEvent(e2);
39  fstats.recordSubRun(e2.subRunID());
40  fstats.recordRun(e2.runID());
41  art::SubRunID const sr{2, 3};
42  fstats.recordSubRun(sr);
43  fstats.recordRun(sr.runID());
44  fstats.recordFileClose();
45  }
46 
47 } // namespace
48 
49 BOOST_FIXTURE_TEST_SUITE(PostCloseFileRenamer_t, TestFixture)
50 
52 {
53  PostCloseFileRenamer fr{fstats};
54 }
55 
56 BOOST_AUTO_TEST_CASE(testSubstitutions)
57 {
58  std::vector<std::string> const patterns{"f/stem_%r_%s_%R_%S.root"s,
59  "f/stem_%l.root"s,
60  "f/stem_%p.root"s,
61  "f/stem_%5R_%2S.root"s};
62  std::vector<std::string> const answers{"f/stem_1_0_2_3.root"s,
63  "f/stem_label.root"s,
64  "f/stem_DEVEL.root"s,
65  "f/stem_00002_03.root"s};
66  simulateJob();
67  PostCloseFileRenamer fr{fstats};
68  for (size_t i{0}, e = patterns.size(); i != e; ++i) {
69  auto const ans = fr.applySubstitutions(patterns[i]);
70  auto const& cmp = answers[i];
71  BOOST_TEST(ans == cmp);
72  }
73 }
74 
75 BOOST_AUTO_TEST_CASE(resetFileOpen)
76 {
77  simulateJob();
78  PostCloseFileRenamer fr{fstats};
79  std::string const pattern{"%to"};
80  auto const before = fr.applySubstitutions(pattern);
81  std::this_thread::sleep_for(1s);
82  fstats.recordFileOpen();
83  fstats.recordFileClose();
84  auto const after = fr.applySubstitutions(pattern);
85  BOOST_TEST(before != after);
86 }
87 
89 {
90  PostCloseFileRenamer fr{fstats};
91  std::string const pattern{"%02r_%02s_%R_%S"};
92  auto const before = fr.applySubstitutions(pattern);
93  auto const cmp_before = "-_-_-_-"s;
94  BOOST_TEST(before == cmp_before);
95  simulateJob();
96  auto after = fr.applySubstitutions(pattern);
97  auto const cmp_after = "01_00_2_3"s;
98  BOOST_TEST(after == cmp_after);
99  fstats.recordFileOpen();
100  fstats.recordFileClose();
101  after = fr.applySubstitutions(pattern);
102  BOOST_TEST(after == cmp_before);
103 }
104 
105 BOOST_AUTO_TEST_CASE(Runs_subruns)
106 {
107  std::string const pattern{"%02r_%02s_%R_%S"};
108  PostCloseFileRenamer fr{fstats};
109  fstats.recordRun(art::RunID{7});
110  BOOST_TEST(fr.applySubstitutions(pattern) == "07_-_7_-"s);
111  fstats.recordSubRun(art::SubRunID{7, 0});
112  BOOST_TEST(fr.applySubstitutions(pattern) == "07_00_7_0"s);
113  fstats.recordSubRun(art::SubRunID{7, 5});
114  BOOST_TEST(fr.applySubstitutions(pattern) == "07_00_7_5"s);
115  fstats.recordRun(art::RunID{7});
116  BOOST_TEST(fr.applySubstitutions(pattern) == "07_00_7_5"s);
117  fstats.recordRun(art::RunID{9});
118  BOOST_TEST(fr.applySubstitutions(pattern) == "07_00_9_-"s);
119 }
120 
121 BOOST_AUTO_TEST_CASE(StartTimesRunsSubruns)
122 {
123  PostCloseFileRenamer fr{fstats};
124  BOOST_TEST(fr.applySubstitutions("%tr") == "-"s);
125  BOOST_TEST(fr.applySubstitutions("%ts") == "-"s);
126  BOOST_TEST(fr.applySubstitutions("%tR") == "-"s);
127  BOOST_TEST(fr.applySubstitutions("%tS") == "-"s);
128  simulateJob();
129  BOOST_TEST(fr.applySubstitutions("%tr") != "-"s);
130  BOOST_TEST(fr.applySubstitutions("%ts") != "-"s);
131  BOOST_TEST(fr.applySubstitutions("%tR") != "-"s);
132  BOOST_TEST(fr.applySubstitutions("%tS") != "-"s);
133 }
134 
136 {
137  std::string const pattern{"ethel-%02#-charlie"};
138  PostCloseFileRenamer fr{fstats};
139  BOOST_TEST(fr.applySubstitutions(pattern) == "ethel-00-charlie"s);
140  fstats.recordFileOpen();
141  BOOST_TEST(fr.applySubstitutions(pattern) == "ethel-00-charlie"s);
142  fstats.recordFileClose();
143  BOOST_TEST(fr.applySubstitutions(pattern) == "ethel-01-charlie"s);
144  fstats.recordFileOpen();
145  BOOST_TEST(fr.applySubstitutions(pattern) == "ethel-01-charlie"s);
146  fstats.recordFileClose();
147  BOOST_TEST(fr.applySubstitutions(pattern) == "ethel-02-charlie"s);
148 }
149 
151 {
152  std::string const pattern{"ethel-%02#-charlie-%#-bertha"};
153  PostCloseFileRenamer fr{fstats};
154  BOOST_TEST(fr.applySubstitutions(pattern) == "ethel-00-charlie-0-bertha"s);
155  fstats.recordFileOpen();
156  BOOST_TEST(fr.applySubstitutions(pattern) == "ethel-00-charlie-0-bertha"s);
157  fstats.recordFileClose();
158  BOOST_TEST(fr.applySubstitutions(pattern) == "ethel-01-charlie-1-bertha"s);
159 }
160 
161 BOOST_AUTO_TEST_CASE(SimpleFileNameSubs)
162 {
163  std::string const pattern{"silly_%ifb_%ifd_%ife_%ifn_%ifp.root"};
164  PostCloseFileRenamer fr{fstats};
165 
166  // Empty.
167  fstats.recordInputFile("");
168  BOOST_TEST(fr.applySubstitutions(pattern) == "silly_-_-_-_-_-.root"s);
169 
170  // Simple.
171  auto owd = boost::filesystem::current_path();
172  auto tmpdir =
173  boost::filesystem::canonical(boost::filesystem::temp_directory_path())
174  .native();
175  BOOST_TEST_REQUIRE(chdir(tmpdir.c_str()) == 0);
176 
177  fstats.recordInputFile("fileonlynoext");
178  BOOST_TEST(fr.applySubstitutions(pattern) ==
179  std::string{"silly_fileonlynoext_" + tmpdir + "__fileonlynoext_" +
180  tmpdir + "/fileonlynoext.root"});
181 
182  // Relative.
183  auto uniqueDir = boost::filesystem::unique_path("%%%%-%%%%-%%%%-%%%%");
184  BOOST_TEST_REQUIRE(mkdir(uniqueDir.native().c_str(), 0755) == 0);
185  auto absUniqueDir = boost::filesystem::canonical(uniqueDir).native();
186  fstats.recordInputFile((uniqueDir / "x.ext").native());
187  BOOST_TEST(fr.applySubstitutions(pattern) ==
188  std::string{"silly_x_" + absUniqueDir + "_.ext_x.ext_" +
189  absUniqueDir + "/x.ext.root"});
190  BOOST_TEST_REQUIRE(chdir(owd.native().c_str()) == 0);
191 
192  // Absolute.
193  fstats.recordInputFile("/usr/bin/y.ext");
194  BOOST_TEST(fr.applySubstitutions(pattern) ==
195  "silly_y_/usr/bin_.ext_y.ext_/usr/bin/y.ext.root"s);
196 }
197 
199 {
200  std::string const pattern{"%ifs%root%dat%%"};
201  PostCloseFileRenamer fr{fstats};
202  fstats.recordInputFile("/tmp/c.root");
203  BOOST_TEST(fr.applySubstitutions(pattern) == "/tmp/c.dat"s);
204 }
205 
206 BOOST_AUTO_TEST_CASE(EscapingRegex)
207 {
208  std::string const pattern{"%ifs%\\.root%.dat%%"};
209  PostCloseFileRenamer fr{fstats};
210  fstats.recordInputFile("/tmp/c.root");
211  BOOST_TEST(fr.applySubstitutions(pattern) == "/tmp/c.dat"s);
212 }
213 
215 {
216  std::string const pattern{"%ifs%ROOT%dat%i%"};
217  PostCloseFileRenamer fr{fstats};
218  fstats.recordInputFile("/tmp/c.root");
219  BOOST_TEST(fr.applySubstitutions(pattern) == "/tmp/c.dat"s);
220 }
221 
223 {
224  std::string const pattern{"%ifs%o%f%g%"};
225  PostCloseFileRenamer fr{fstats};
226  fstats.recordInputFile("/tmp/c.root");
227  BOOST_TEST(fr.applySubstitutions(pattern) == "/tmp/c.rfft"s);
228 }
229 
230 BOOST_AUTO_TEST_CASE(GroupingRegex)
231 {
232  std::string const pattern{"%ifd/d_%ifs%^.*?_([\\d]+).*$%${1}_charlie%%%ife"};
233  auto tmpdir = boost::filesystem::canonical("/tmp");
234  PostCloseFileRenamer fr{fstats};
235  fstats.recordInputFile("/tmp/c_27_ethel.root");
236  BOOST_TEST(fr.applySubstitutions(pattern) ==
237  (tmpdir / "d_27_charlie.root").native());
238 }
239 
240 BOOST_AUTO_TEST_SUITE_END()
def mkdir(path, mode=0o777)
std::string string
Definition: nybbler.cc:12
BOOST_TEST_REQUIRE(static_cast< bool >(inFile))
const double e
std::string pattern
Definition: regex_t.cc:35
std::string applySubstitutions(std::string const &filePattern)
static constexpr double sr
Definition: Units.h:166
BOOST_AUTO_TEST_CASE(constructor)
static QCString * s
Definition: config.cpp:1042