ProteoWizard
FilesystemTest.cpp
Go to the documentation of this file.
1 //
2 // $Id$
3 //
4 //
5 // Original author: Matt Chambers <matt.chambers .@. vanderbilt.edu>
6 //
7 // Copyright 2008 Spielberg Family Center for Applied Proteomics
8 // Cedars Sinai Medical Center, Los Angeles, California 90048
9 // Copyright 2008 Vanderbilt University - Nashville, TN 37232
10 //
11 // Licensed under the Apache License, Version 2.0 (the "License");
12 // you may not use this file except in compliance with the License.
13 // You may obtain a copy of the License at
14 //
15 // http://www.apache.org/licenses/LICENSE-2.0
16 //
17 // Unless required by applicable law or agreed to in writing, software
18 // distributed under the License is distributed on an "AS IS" BASIS,
19 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 // See the License for the specific language governing permissions and
21 // limitations under the License.
22 //
23 
24 #include "Std.hpp"
25 #include "Filesystem.hpp"
26 #include "unit.hpp"
27 
28 
29 using namespace pwiz::util;
30 using boost::system::error_code;
31 using boost::system::system_category;
32 using boost::system::system_error;
33 
34 #if (BOOST_VERSION/100) >= 1044
35 # define SYSTEMCATEGORY system_category()
36 #else // exported library symbol used to be a global variable, now its a function. Okeedokee, then.
37 # define SYSTEMCATEGORY system_category
38 #endif
39 
40 
41 // platform-specific path elements
42 #ifdef WIN32
43 # define ABS "%SD%\\" // test at %SystemDrive% because FindFile behaves a little tricky there
44 # define REL ".\\relative"
45 # define A "\\" // both slash types should work
46 # define D ";" // path separator
47 #else
48 # define ABS "./" // POSIX filesystems don't have the same problem,
49 # define REL "./relative" // so all tests are relative (avoids permission issues)
50 # define A "/"
51 # define D ":"
52 #endif
53 
54 string systemDrive;
55 string setSystemDrive(const string& path)
56 {
57  return bal::replace_all_copy(path, "%SD%", systemDrive);
58 }
59 
60 const char* testPathContentPairArray[] =
61 {
62  // path content (empty indicates directory)
63  ABS "pwiz_foofoo_test", "root file",
64  ABS "pwiz_foo_test", "",
65  ABS "pwiz_foo_test" A "this file", "has content",
66  ABS "pwiz_foo_test" A "this dir has", "",
67  ABS "pwiz_foo_test" A "this dir has" A "a test file", "with content",
68  ABS "pwiz_bar_test", "",
69  ABS "pwiz_bar_test" A "some file", "12345",
70  ABS "pwiz_bar_test" A "some dir", "",
71 
72  REL "pwiz_foofoo_test", "root file",
73  REL "pwiz_foo_test", "",
74  REL "pwiz_foo_test" A "this file", "has content",
75  REL "pwiz_foo_test" A "this dir has", "",
76  REL "pwiz_foo_test" A "this dir has" A "a test file", "with content",
77  REL "pwiz_bar_test", "",
78  REL "pwiz_bar_test" A "some file", "12345",
79  REL "pwiz_bar_test" A "some dir", ""
80 };
81 
82 
83 const int testPathContentPairArraySize = sizeof(testPathContentPairArray) / sizeof(const char*);
84 
85 
87 {
88  const char* pathmask; // mask to be passed to expand_pathmask()
89  const char* pathnameArray; // paths that should match with expand_pathmask()
90 };
91 
92 
94 {
95  { ABS "pwiz_f??f??_test", ABS "pwiz_foofoo_test" },
96  { ABS "pwiz_???_test", ABS "pwiz_foo_test" D ABS "pwiz_bar_test" },
97  { ABS "pwiz_f*o_test", ABS "pwiz_foo_test" D ABS "pwiz_foofoo_test" },
98  { ABS "pwiz_foobar_test", "" },
99  { ABS "pwiz_foo_test" A "no*hit", "" },
100  { ABS "pwiz_foo_test" A "*", ABS "pwiz_foo_test" A "this file" D ABS "pwiz_foo_test" A "this dir has" },
101  { ABS"pwiz_foo_test" A "this *", ABS "pwiz_foo_test" A "this file" D ABS "pwiz_foo_test" A "this dir has" },
102 
103  { REL "pwiz_f??f??_test", REL "pwiz_foofoo_test" },
104  { REL "pwiz_???_test", REL "pwiz_foo_test" D REL "pwiz_bar_test" },
105  { REL "pwiz_f*o_test", REL "pwiz_foo_test" D REL "pwiz_foofoo_test" },
106  { REL "pwiz_foobar_test", "" },
107  { REL "pwiz_foo_test" A "no*hit", "" },
108  { REL "pwiz_foo_test" A "*", REL "pwiz_foo_test" A "this file" D REL "pwiz_foo_test" A "this dir has" },
109  { REL "pwiz_foo_test" A "this *", REL "pwiz_foo_test" A "this file" D REL "pwiz_foo_test" A "this dir has" }
110 };
111 
112 
114 
115 
116 void create_file(const bfs::path& ph, const string& contents)
117 {
118  ofstream f(ph.string().c_str());
119  if (!f)
120  throw bfs::filesystem_error("create_file", ph, error_code(errno, SYSTEMCATEGORY));
121  if (!contents.empty()) f << contents;
122 }
123 
124 
126 {
127  for (int i=0; i < testPathContentPairArraySize; i += 2)
128  {
129  auto testPath = setSystemDrive(testPathContentPairArray[i]);
130 
131  try
132  {
133  // if content is empty, create a directory
134  if (strlen(testPathContentPairArray[i + 1]) == 0)
135  bfs::create_directory(testPath);
136  else
137  create_file(testPath, testPathContentPairArray[i + 1]);
138  }
139  catch (exception&)
140  {
141  // the absolute path tests on Windows will fail if not run with administartor permissions; don't count these as test failures
142  if (string(ABS) != REL && bal::starts_with(testPath, setSystemDrive(ABS)))
143  {
144  cerr << "Test on \"" << testPath << "\" skipped; requires administrator permissions." << endl;
145  continue;
146  }
147  }
148 
149  // test that the directory/file was really created
150  unit_assert(bfs::exists(testPath));
151  }
152 }
153 
154 
156 {
157  for (int i=0; i < testPathContentPairArraySize; i += 2)
158  if (bfs::exists(setSystemDrive(testPathContentPairArray[i])))
159  bfs::remove_all(setSystemDrive(testPathContentPairArray[i]));
160 }
161 
162 
163 set<bfs::path> parsePathArray(const string& pathArray)
164 {
165  set<bfs::path> pathSet;
166  vector<string> tokens;
167  bal::split(tokens, pathArray, bal::is_any_of(D));
168  if (!tokens.empty() && !tokens[0].empty())
169  for (size_t i=0; i < tokens.size(); ++i)
170  pathSet.insert(setSystemDrive(tokens[i]));
171  return pathSet;
172 }
173 
174 
176 {
177  char* systemDriveEnv = ::getenv("SystemDrive"); // usually "C:" on Windows
178  if (systemDriveEnv)
179  systemDrive = systemDriveEnv;
180 
181  // create a filesystem tree for testing
182  createTestPath();
183 
184  int failedTests = 0;
185 
186  for (int i=0; i < testPathmaskArraySize; ++i)
187  {
188  try
189  {
190  vector<bfs::path> matchingPaths;
191  expand_pathmask(setSystemDrive(testPathmaskArray[i].pathmask), matchingPaths);
192 
193  set<bfs::path> targetPathSet = parsePathArray(testPathmaskArray[i].pathnameArray);
194  unit_assert(matchingPaths.size() == targetPathSet.size());
195 
196  set<bfs::path> matchingPathSet(matchingPaths.begin(), matchingPaths.end());
197  vector<bfs::path> xorSet;
198  std::set_symmetric_difference(targetPathSet.begin(), targetPathSet.end(),
199  matchingPathSet.begin(), matchingPathSet.end(),
200  xorSet.end());
201  unit_assert(xorSet.empty());
202  }
203  catch (exception& e)
204  {
205  // the absolute path tests on Windows will fail if not run with administartor permissions; don't count these as test failures
206  if (string(ABS) != REL && bal::starts_with(testPathmaskArray[i].pathmask, ABS))
207  continue;
208 
209  cout << "Unit test on pathmask \"" << setSystemDrive(testPathmaskArray[i].pathmask) << "\" failed:\n"
210  << e.what() << endl;
211  ++failedTests;
212  }
213  }
214 
215  unit_assert_operator_equal(0, failedTests);
216 
217  // special test of wildcard in the root (on Windows, if run with administrator permissions)
218  if (bfs::exists(setSystemDrive(ABS"pwiz_foofoo_test")))
219  {
220  vector<bfs::path> matchingPaths;
221  expand_pathmask(setSystemDrive(ABS"*"), matchingPaths);
222  unit_assert(find(matchingPaths.begin(), matchingPaths.end(), setSystemDrive(ABS"pwiz_foofoo_test")) != matchingPaths.end());
223  unit_assert(find(matchingPaths.begin(), matchingPaths.end(), setSystemDrive(ABS"pwiz_foo_test")) != matchingPaths.end());
224  unit_assert(find(matchingPaths.begin(), matchingPaths.end(), setSystemDrive(ABS"pwiz_bar_test")) != matchingPaths.end());
225  }
226 
227  // cleanup test tree
228  deleteTestPath();
229 }
230 
231 
233 {
234  unit_assert(abbreviate_byte_size(1) == "1 B");
235  unit_assert(abbreviate_byte_size(999) == "999 B");
236  unit_assert(abbreviate_byte_size(1000) == "1 KB");
237  unit_assert(abbreviate_byte_size(999999) == "999 KB");
238  unit_assert(abbreviate_byte_size(1000000) == "1 MB");
239  unit_assert(abbreviate_byte_size(999999999) == "999 MB");
240  unit_assert(abbreviate_byte_size(1000000000) == "1 GB");
241 
245  unit_assert(abbreviate_byte_size((1024 << 10)-1, ByteSizeAbbreviation_IEC) == "1023 KiB");
246  unit_assert(abbreviate_byte_size((1024 << 10), ByteSizeAbbreviation_IEC) == "1 MiB");
247  unit_assert(abbreviate_byte_size((1024 << 20)-1, ByteSizeAbbreviation_IEC) == "1023 MiB");
248  unit_assert(abbreviate_byte_size((1024 << 20), ByteSizeAbbreviation_IEC) == "1 GiB");
249 
253  unit_assert(abbreviate_byte_size((1024 << 10)-1, ByteSizeAbbreviation_JEDEC) == "1023 KB");
255  unit_assert(abbreviate_byte_size((1024 << 20)-1, ByteSizeAbbreviation_JEDEC) == "1023 MB");
257 }
258 
259 
260 int main(int argc, char* argv[])
261 {
262  TEST_PROLOG(argc, argv)
263 
264  try
265  {
268  }
269  catch (exception& e)
270  {
271  TEST_FAILED(e.what())
272  }
273  catch (...)
274  {
275  TEST_FAILED("Caught unknown exception.")
276  }
277 
278  deleteTestPath();
280 }
PWIZ_API_DECL int expand_pathmask(const bfs::path &pathmask, vector< bfs::path > &matchingPaths)
expands (aka globs) a pathmask to zero or more matching paths and returns the number of matching path...
const char * testPathContentPairArray[]
sizes are treated as multiples of 2; abbreviations are: GiB (Gibibyte), MiB (Mebibyte), KiB (Kibibyte), B (byte)
Definition: Filesystem.hpp:94
#define TEST_EPILOG
Definition: unit.hpp:183
const char * pathmask
#define SYSTEMCATEGORY
#define D
PWIZ_API_DECL std::string abbreviate_byte_size(boost::uintmax_t byteSize, ByteSizeAbbreviation abbreviationType=ByteSizeAbbreviation_SI)
abbreviates a byte size (file or RAM) as a readable string, using the specified notation ...
#define unit_assert_operator_equal(expected, actual)
Definition: unit.hpp:92
#define A
void testAbbreviateByteSize()
sizes are treated as multiples of 2; abbreviations are: GB (Gigabyte), MB (Megabyte), KB (Kilobyte), B (byte)
Definition: Filesystem.hpp:98
void deleteTestPath()
const int testPathmaskArraySize
#define TEST_FAILED(x)
Definition: unit.hpp:177
string systemDrive
string setSystemDrive(const string &path)
#define ABS
const int testPathContentPairArraySize
const TestPathmask testPathmaskArray[]
void createTestPath()
#define TEST_PROLOG(argc, argv)
Definition: unit.hpp:175
void create_file(const bfs::path &ph, const string &contents)
void testExpandPathmask()
#define REL
set< bfs::path > parsePathArray(const string &pathArray)
int main(int argc, char *argv[])
#define unit_assert(x)
Definition: unit.hpp:85
const char * pathnameArray