FileUtils_T.cpp
Go to the documentation of this file.
1 //==============================================================================
2 //
3 // This file is part of GNSSTk, the ARL:UT GNSS Toolkit.
4 //
5 // The GNSSTk is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU Lesser General Public License as published
7 // by the Free Software Foundation; either version 3.0 of the License, or
8 // any later version.
9 //
10 // The GNSSTk is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with GNSSTk; if not, write to the Free Software Foundation,
17 // Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 //
19 // This software was developed by Applied Research Laboratories at the
20 // University of Texas at Austin.
21 // Copyright 2004-2022, The Board of Regents of The University of Texas System
22 //
23 //==============================================================================
24 
25 //==============================================================================
26 //
27 // This software was developed by Applied Research Laboratories at the
28 // University of Texas at Austin, under contract to an agency or agencies
29 // within the U.S. Department of Defense. The U.S. Government retains all
30 // rights to use, duplicate, distribute, disclose, or release this software.
31 //
32 // Pursuant to DoD Directive 523024
33 //
34 // DISTRIBUTION STATEMENT A: This software has been approved for public
35 // release, distribution is unlimited.
36 //
37 //==============================================================================
38 
39 #include "TestUtil.hpp"
40 #include "FileUtils.hpp"
41 #include <iostream>
42 #include <sys/stat.h>
43 #include <sys/types.h>
44 
45 // headers for directory searching interface
46 #ifndef WIN32
47 #include <unistd.h>
48 #else
49 #include <direct.h>
50 #include <io.h>
51 // Copied from linux libc sys/stat.h to keep code cross-platform:
52 #ifndef S_ISDIR
53 #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
54 #endif
55 #endif
56 
57 using namespace std;
58 using namespace gnsstk;
59 
61 {
62 public:
63 
64  // constructor, set the precision value
65  FileUtils_T() { init(); }
66 
67  // destructor
68  ~FileUtils_T() { cleanup(); }
69 
70  // initialize tests
71  void init();
72 
73  // test makeDir()
74  // @return number of failures, i.e., 0=PASS, !0=FAIL
75  int testMakeDir();
76 
77  // test fileAccessCheck()
78  // @return number of failures, i.e., 0=PASS, !0=FAIL
79  int testFileAccessCheck();
80 
81 private:
82 
83  // recursively remove a file system object
84  // @param path full path of the object to remove
85  void cleanup(string path);
86 
87  // recursively remove all FileUtil-related objects in tempFilePath
88  void cleanup();
89 
90  vector<string> dirsToRemove;
91  vector<string> filesToRemove;
92 
93  string tempFilePath;
94  string testPrefix;
95 
96 }; // class FileUtils_T
97 
98 
99 //---------------------------------------------------------------------------
101 {
102  TestUtil tester;
103 
104  tempFilePath = gnsstk::getPathTestTemp();
105 
106  testPrefix = "test_output_fileutils_";
107 }
108 
109 
110 //---------------------------------------------------------------------------
112 {
113  // remove files
114  vector<string>::reverse_iterator fileIter = filesToRemove.rbegin();
115  for ( ; fileIter != filesToRemove.rend(); ++fileIter)
116  {
117  #ifdef WIN32
118  _chmod(fileIter->c_str(), _S_IWRITE );
119  _unlink(fileIter->c_str() );
120 
121  #else
122  chmod(fileIter->c_str(), 0644);
123  unlink(fileIter->c_str() );
124  #endif
125 
126  }
127  // remove directories
128  vector<string>::reverse_iterator dirIter = dirsToRemove.rbegin();
129  for ( ; dirIter != dirsToRemove.rend(); ++dirIter)
130  {
131  #ifdef WIN32
132  _chmod(dirIter->c_str(), _S_IWRITE );
133  _rmdir(dirIter->c_str() );
134  #else
135  chmod(dirIter->c_str(), 0755);
136  rmdir(dirIter->c_str() );
137  #endif
138  }
139 }
140 
141 
142 //---------------------------------------------------------------------------
144 {
145  TestUtil tester( "FileUtils", "makeDir", __FILE__, __LINE__ );
146 
147  // @note - These tests are kinda odd because makeDir always returns 0
148  // regardless of success or failure.
149 
150  string dir;
151  cout << "-----------------" << endl;
152  try // empty path
153  {
154  tester.assert( (0 == FileUtils::makeDir(dir, 0755) ), "empty (return)", __LINE__ );
155  }
156  catch (...)
157  {
158  tester.assert( false, "unexpected exception", __LINE__ );
159  }
160 
161  // relative paths are not permitted according to FileUtils::makeDir documentation
162 
163  try // absolute path
164  {
165  struct stat statbuf;
166  dir = tempFilePath + getFileSep() + testPrefix + "dir2";
167  tester.assert( (0 == FileUtils::makeDir(dir, 0755) ), "absolute (return)", __LINE__ );
168  tester.assert( (0 == stat(dir.c_str(), &statbuf) ), "absolute (exists)", __LINE__ );
169  tester.assert( S_ISDIR(statbuf.st_mode), "absolute (dir)", __LINE__ );
170  #ifndef WIN32
171  tester.assert( ( (statbuf.st_mode & 0777) == 0755), "absolute (mode)", __LINE__ );
172  #endif
173 
174  }
175  catch (...)
176  {
177  tester.assert( false, "unexpected exception", __LINE__ );
178  }
179 
180  /*
181  try // invalid characters (I couldn't find any yet)
182  {
183  struct stat statbuf;
184  dir = tempFilePath + getFileSep() + testPrefix + "d|r<";
185  dirsToRemove.push_back(dir); // just in case this works somehow
186  tester.assert( (0 == FileUtils::makeDir(dir, 0666) ), "invalid (return)", __LINE__ );
187  tester.assert( (0 > stat(dir.c_str(), &statbuf) ), "invalid (exists)", __LINE__ );
188  }
189  catch (...)
190  {
191  tester.assert( false, "unexpected exception", __LINE__ );
192  }
193  */
194 
195  try // existing path
196  {
197  struct stat statbuf;
198  dir = tempFilePath + getFileSep() + testPrefix + "dir2";
199  dirsToRemove.push_back(dir); // just in case
200  tester.assert( (0 == FileUtils::makeDir(dir, 0755) ), "existing (return)", __LINE__ );
201  tester.assert( (0 == stat(dir.c_str(), &statbuf) ), "existing (exists)", __LINE__ );
202  tester.assert( S_ISDIR(statbuf.st_mode), "existing (dir)", __LINE__ );
203  #ifndef WIN32
204  tester.assert( ( (statbuf.st_mode & 0777) == 0755), "existing (mode)", __LINE__ );
205  #endif
206  }
207  catch (...)
208  {
209  tester.assert( false, "unexpected exception", __LINE__ );
210  }
211 
212  try // trailing separator
213  {
214  struct stat statbuf;
215  dir = tempFilePath + getFileSep() + testPrefix + "dir3" + getFileSep();
216  dirsToRemove.push_back(dir);
217  tester.assert( (0 == FileUtils::makeDir(dir, 0755) ), "trailing (return)", __LINE__ );
218  tester.assert( (0 == stat(dir.c_str(), &statbuf) ), "trailing (exists)", __LINE__ );
219  tester.assert( S_ISDIR(statbuf.st_mode), "trailing (dir)", __LINE__ );
220  #ifndef WIN32
221  tester.assert( ( (statbuf.st_mode & 0777) == 0755), "trailing (mode)", __LINE__ );
222  #endif
223  }
224  catch (...)
225  {
226  tester.assert( false, "unexpected exception", __LINE__ );
227  }
228 
229  try // recursion
230  {
231  struct stat statbuf;
232  dir = tempFilePath + getFileSep() + testPrefix + "dir4";
233  dirsToRemove.push_back(dir);
234  dir += getFileSep() + "derp";
235  dirsToRemove.push_back(dir);
236  dir += getFileSep() + "derp";
237  dirsToRemove.push_back(dir);
238  dir += getFileSep() + "derp";
239  dirsToRemove.push_back(dir);
240  dir += getFileSep() + "derp";
241  dirsToRemove.push_back(dir);
242  tester.assert( (0 == FileUtils::makeDir(dir, 0755) ), "recursion (return)", __LINE__ );
243  tester.assert( (0 == stat(dir.c_str(), &statbuf) ), "recursion (exists)", __LINE__ );
244  tester.assert( S_ISDIR(statbuf.st_mode), "recursion (dir)", __LINE__ );
245  #ifndef WIN32
246  tester.assert( ( (statbuf.st_mode & 0777) == 0755), "recursion (mode)", __LINE__ );
247  #endif
248  }
249  catch (...)
250  {
251  tester.assert( false, "unexpected exception", __LINE__ );
252  }
253 
254  return tester.countFails();
255 }
256 
257 
258 //---------------------------------------------------------------------------
260 {
261  TestUtil tester( "FileUtils", "fileAccessCheck", __FILE__, __LINE__ );
262 
263  string filename;
264 
265  try // missing file
266  {
267  filename = tempFilePath + getFileSep() + testPrefix + "missing_file";
268  filesToRemove.push_back(filename); // just in case
269  tester.assert( !FileUtils::fileAccessCheck(filename), "expected missing file failure", __LINE__ );
270  tester.assert( !FileUtils::fileAccessCheck(filename, ios::in), "expected missing file failure", __LINE__ );
271  // Opening a file for output in a directory the user has
272  // write access to will always succeed, so try to open a file
273  // in a directory that almost certainly won't exist.
274  filename = getFileSep() + "asdfasdflkj" + getFileSep() + "missing_dir";
275  tester.assert( !FileUtils::fileAccessCheck(filename, ios::out), "expected missing file failure", __LINE__ );
276  }
277  catch (...)
278  {
279  tester.assert( false, "unexpected exception", __LINE__ );
280  }
281 
282 
283  try // file read
284  {
285  filename = tempFilePath + getFileSep() + testPrefix + "readable_file";
286  ofstream ofs(filename.c_str() );
287  if ( !ofs )
288  {
289  tester.assert ( false, "test setup error (create)", __LINE__ );
290  }
291  else
292  {
293  ofs.flush();
294  ofs.close();
295 #ifdef WIN32
296  if (0 != _chmod(filename.c_str(), _S_IREAD ))
297  {
298  tester.assert ( false, "test setup error (chmod)", __LINE__ );
299  }
300  else
301  {
302  filesToRemove.push_back(filename);
303  tester.assert( FileUtils::fileAccessCheck(filename), "read access failed", __LINE__ );
304  tester.assert( FileUtils::fileAccessCheck(filename, ios::in), "mode test failed", __LINE__ );
305  tester.assert( !FileUtils::fileAccessCheck(filename, ios::out), "expected mode test failure", __LINE__ );
306  }
307 #else
308  if (0 != chmod(filename.c_str(), 0444) )
309  {
310  tester.assert ( false, "test setup error (chmod)", __LINE__ );
311  }
312  else
313  {
314  filesToRemove.push_back(filename);
315  tester.assert( FileUtils::fileAccessCheck(filename), "read access failed", __LINE__ );
316  tester.assert( FileUtils::fileAccessCheck(filename, ios::in), "mode test failed", __LINE__ );
319  if ((getuid() != 0) && (geteuid() != 0))
320  {
321  tester.assert( !FileUtils::fileAccessCheck(filename, ios::out), "expected mode test failure", __LINE__ );
322  }
323  }
324 #endif
325 
326  }
327  }
328  catch (...)
329  {
330  tester.assert( false, "unexpected exception", __LINE__ );
331  }
332 
333  try // file write
334  {
335  filename = tempFilePath + getFileSep() + testPrefix + "writeable_file";
336  ofstream ofs(filename.c_str() );
337  if ( !ofs )
338  {
339  tester.assert ( false, "test setup error (create)", __LINE__ );
340  }
341  else
342  {
343  ofs.flush();
344  ofs.close();
345  #ifdef WIN32
346  if (0 != _chmod(filename.c_str(), _S_IWRITE ))
347 
348  {
349  tester.assert ( false, "test setup error (chmod)", __LINE__ );
350  }
351  else
352  {
353  filesToRemove.push_back(filename);
354  tester.assert( FileUtils::fileAccessCheck(filename), "write access failed", __LINE__ );
355  tester.assert( FileUtils::fileAccessCheck(filename, ios::in), "mode test failed", __LINE__ );
356  tester.assert( FileUtils::fileAccessCheck(filename, ios::out), "mode test failed", __LINE__ );
357  }
358  #else
359  if (0 != chmod(filename.c_str(), 0666) )
360  {
361  tester.assert ( false, "test setup error (chmod)", __LINE__ );
362  }
363  else
364  {
365  filesToRemove.push_back(filename);
366  tester.assert( FileUtils::fileAccessCheck(filename), "write access failed", __LINE__ );
367  tester.assert( FileUtils::fileAccessCheck(filename, ios::in), "mode test failed", __LINE__ );
368  tester.assert( FileUtils::fileAccessCheck(filename, ios::out), "mode test failed", __LINE__ );
369  }
370  #endif
371  }
372  }
373  catch (...)
374  {
375  tester.assert( false, "unexpected exception", __LINE__ );
376  }
377 
378  return tester.countFails();
379 }
380 
381 
382 //---------------------------------------------------------------------------
383 int main(int argc, char *argv[])
384 {
385  int errorTotal = 0;
386 
387  FileUtils_T testClass;
388 
389  errorTotal += testClass.testMakeDir();
390  errorTotal += testClass.testFileAccessCheck();
391 
392  cout << "Total Failures for " << __FILE__ << ": " << errorTotal << endl;
393 
394  return errorTotal;
395 }
gnsstk::TestUtil::countFails
int countFails(void)
Definition: TestUtil.hpp:771
gnsstk::TestUtil::assert
void assert(bool testExpression, const std::string &testMsg, const int lineNumber)
Definition: TestUtil.hpp:607
FileUtils_T::cleanup
void cleanup()
Definition: FileUtils_T.cpp:111
FileUtils_T::dirsToRemove
vector< string > dirsToRemove
Definition: FileUtils_T.cpp:90
FileUtils_T::tempFilePath
string tempFilePath
Definition: FileUtils_T.cpp:93
FileUtils_T::FileUtils_T
FileUtils_T()
Definition: FileUtils_T.cpp:65
FileUtils_T::testFileAccessCheck
int testFileAccessCheck()
Definition: FileUtils_T.cpp:259
FileUtils_T::filesToRemove
vector< string > filesToRemove
Definition: FileUtils_T.cpp:91
gnsstk
For Sinex::InputHistory.
Definition: BasicFramework.cpp:50
FileUtils_T::testPrefix
string testPrefix
Definition: FileUtils_T.cpp:94
TestUtil.hpp
main
int main(int argc, char *argv[])
Definition: FileUtils_T.cpp:383
FileUtils.hpp
FileUtils_T
Definition: FileUtils_T.cpp:60
FileUtils_T::testMakeDir
int testMakeDir()
Definition: FileUtils_T.cpp:143
gnsstk::FileUtils::makeDir
int makeDir(const std::string &path, unsigned mode)
Definition: FileUtils.hpp:106
std
Definition: Angle.hpp:142
FileUtils_T::init
void init()
Definition: FileUtils_T.cpp:100
FileUtils_T::~FileUtils_T
~FileUtils_T()
Definition: FileUtils_T.cpp:68
gnsstk::TestUtil
Definition: TestUtil.hpp:265
tempFilePath
string tempFilePath
Definition: Rinex3Obs_FromScratch_T.cpp:50
gnsstk::FileUtils::fileAccessCheck
bool fileAccessCheck(const char *fname, std::ios::openmode mode=std::ios::in)
Definition: FileUtils.hpp:151


gnsstk
Author(s):
autogenerated on Wed Oct 25 2023 02:40:39