xref: /4.0.0/platform/tests/dirutils_test.cc (revision 877ba0c5)
1#include <iostream>
2#include <platform/dirutils.h>
3#include <cstdlib>
4#include <list>
5#include <string>
6#include <cerrno>
7#include <cstring>
8#include <sys/stat.h>
9#include <sys/types.h>
10#include <stdio.h>
11
12#ifdef WIN32
13#include <windows.h>
14#include <direct.h>
15static bool CreateDirectory(const std::string &dir) {
16    if (_mkdir(dir.c_str()) != 0) {
17        return false;
18    }
19    return true;
20}
21
22#define PATH_SEPARATOR "\\"
23
24#else
25static bool CreateDirectory(const std::string &dir) {
26   if (mkdir(dir.c_str(), S_IXUSR | S_IWUSR | S_IRUSR) != 0) {
27      return false;
28   }
29   return true;
30}
31
32#define PATH_SEPARATOR "/"
33
34#endif
35
36#undef NDEBUG
37#include <cassert>
38
39int exit_value = EXIT_SUCCESS;
40
41static void expect(const bool exp, const bool val) {
42    if (exp != val) {
43        std::cerr << "Expected " << exp << " got [" << val << "]" << std::endl;
44        exit_value = EXIT_FAILURE;
45    }
46}
47
48static void expect(const std::string &exp, const std::string &val) {
49   if (exp != val) {
50      std::cerr << "Expected " << exp << " got [" << val << "]" << std::endl;
51      exit_value = EXIT_FAILURE;
52   }
53}
54
55static void expect(size_t size, const std::vector<std::string> &vec) {
56   if (vec.size() != size) {
57      std::cerr << "Expected vector of " << size
58                << " elements got [" << vec.size() << "]" << std::endl;
59      exit_value = EXIT_FAILURE;
60   }
61}
62
63static void contains(const std::string &val, const std::vector<std::string> &vec) {
64   std::vector<std::string>::const_iterator ii;
65   for (ii = vec.begin(); ii != vec.end(); ++ii) {
66      if (val == *ii) {
67         return ;
68      }
69   }
70
71   std::cerr << "Expected vector to contain [" << val << "]" << std::endl;
72   for (ii = vec.begin(); ii != vec.end(); ++ii) {
73      std::cerr << "  -> " << *ii << std::endl;
74   }
75   std::cerr << std::endl;
76   exit_value = EXIT_FAILURE;
77}
78
79static std::list<std::string> vfs;
80
81static bool exists(const std::string &path) {
82   struct stat st;
83   return stat(path.c_str(), &st) == 0;
84}
85
86static void testDirname(void) {
87   // Check the simple case
88   expect("foo", CouchbaseDirectoryUtilities::dirname("foo\\bar"));
89   expect("foo", CouchbaseDirectoryUtilities::dirname("foo/bar"));
90
91   // Make sure that we remove double an empty chunk
92   expect("foo", CouchbaseDirectoryUtilities::dirname("foo\\\\bar"));
93   expect("foo", CouchbaseDirectoryUtilities::dirname("foo//bar"));
94
95   // Make sure that we handle the case without a directory
96   expect(".", CouchbaseDirectoryUtilities::dirname("bar"));
97   expect(".", CouchbaseDirectoryUtilities::dirname(""));
98
99   // Absolute directories
100   expect("\\", CouchbaseDirectoryUtilities::dirname("\\bar"));
101   expect("\\", CouchbaseDirectoryUtilities::dirname("\\\\bar"));
102   expect("/", CouchbaseDirectoryUtilities::dirname("/bar"));
103   expect("/", CouchbaseDirectoryUtilities::dirname("//bar"));
104
105   // Test that we work with multiple directories
106   expect("1/2/3/4/5", CouchbaseDirectoryUtilities::dirname("1/2/3/4/5/6"));
107   expect("1\\2\\3\\4\\5", CouchbaseDirectoryUtilities::dirname("1\\2\\3\\4\\5\\6"));
108   expect("1/2\\4/5", CouchbaseDirectoryUtilities::dirname("1/2\\4/5\\6"));
109}
110
111static void testBasename(void) {
112   expect("bar", CouchbaseDirectoryUtilities::basename("foo\\bar"));
113   expect("bar", CouchbaseDirectoryUtilities::basename("foo/bar"));
114   expect("bar", CouchbaseDirectoryUtilities::basename("foo\\\\bar"));
115   expect("bar", CouchbaseDirectoryUtilities::basename("foo//bar"));
116   expect("bar", CouchbaseDirectoryUtilities::basename("bar"));
117   expect("", CouchbaseDirectoryUtilities::basename(""));
118   expect("bar", CouchbaseDirectoryUtilities::basename("\\bar"));
119   expect("bar", CouchbaseDirectoryUtilities::basename("\\\\bar"));
120   expect("bar", CouchbaseDirectoryUtilities::basename("/bar"));
121   expect("bar", CouchbaseDirectoryUtilities::basename("//bar"));
122   expect("6", CouchbaseDirectoryUtilities::basename("1/2/3/4/5/6"));
123   expect("6", CouchbaseDirectoryUtilities::basename("1\\2\\3\\4\\5\\6"));
124   expect("6", CouchbaseDirectoryUtilities::basename("1/2\\4/5\\6"));
125}
126
127static void testFindFilesWithPrefix(void) {
128   using namespace CouchbaseDirectoryUtilities;
129
130   std::vector<std::string> vec = findFilesWithPrefix("fs");
131   expect(1, vec);
132   contains("." PATH_SEPARATOR "fs", vec);
133
134   vec = findFilesWithPrefix("fs", "d");
135   expect(3, vec);
136   contains("fs" PATH_SEPARATOR "d1", vec);
137   contains("fs" PATH_SEPARATOR "d2", vec);
138   contains("fs" PATH_SEPARATOR "d3", vec);
139   vec = findFilesWithPrefix("fs", "1");
140   expect(1, vec);
141   contains("fs" PATH_SEPARATOR "1", vec);
142
143   vec = findFilesWithPrefix("fs", "");
144   expect(vfs.size() - 1, vec);
145
146}
147
148static void testFindFilesContaining(void) {
149   using namespace CouchbaseDirectoryUtilities;
150   std::vector<std::string> vec = findFilesContaining("fs", "");
151   expect(vfs.size() - 1, vec);
152
153   vec = findFilesContaining("fs", "2");
154   expect(7, vec);
155   contains("fs" PATH_SEPARATOR "d2", vec);
156   contains("fs" PATH_SEPARATOR "e2", vec);
157   contains("fs" PATH_SEPARATOR "f2c", vec);
158   contains("fs" PATH_SEPARATOR "g2", vec);
159   contains("fs" PATH_SEPARATOR "2", vec);
160   contains("fs" PATH_SEPARATOR "2c", vec);
161   contains("fs" PATH_SEPARATOR "2d", vec);
162}
163
164static void testRemove(void) {
165   fclose(fopen("test-file", "w"));
166   if (!CouchbaseDirectoryUtilities::rmrf("test-file")) {
167      std::cerr << "expected to delete existing file" << std::endl;
168   }
169   if (CouchbaseDirectoryUtilities::rmrf("test-file")) {
170      std::cerr << "Didn't expected to delete non-existing file" << std::endl;
171   }
172
173   if (!CouchbaseDirectoryUtilities::rmrf("fs")) {
174      std::cerr << "Expected to nuke the entire fs directory recursively" << std::endl;
175   }
176}
177
178static void testIsDirectory(void) {
179    using namespace CouchbaseDirectoryUtilities;
180#ifdef WIN32
181    expect(true, isDirectory("c:\\"));
182#else
183    expect(true, isDirectory("/"));
184#endif
185    expect(true, isDirectory("."));
186    expect(false, isDirectory("/it/would/suck/if/this/exists"));
187    FILE *fp = fopen("isDirectoryTest", "w");
188    if (fp == NULL) {
189        std::cerr << "Failed to create test file" << std::endl;
190        exit_value = EXIT_FAILURE;
191    } else {
192        using namespace std;
193        fclose(fp);
194        expect(false, isDirectory("isDirectoryTest"));
195        remove("isDirectoryTest");
196    }
197}
198
199int main(int argc, char **argv)
200{
201   testDirname();
202   testBasename();
203
204
205   vfs.push_back("fs");
206   vfs.push_back("fs/d1");
207   vfs.push_back("fs/d2");
208   vfs.push_back("fs/e2");
209   vfs.push_back("fs/f2c");
210   vfs.push_back("fs/g2");
211   vfs.push_back("fs/d3");
212   vfs.push_back("fs/1");
213   vfs.push_back("fs/2");
214   vfs.push_back("fs/2c");
215   vfs.push_back("fs/2d");
216   vfs.push_back("fs/3");
217
218   std::list<std::string>::iterator ii;
219   for (ii = vfs.begin(); ii != vfs.end(); ++ii) {
220      if (!CreateDirectory(*ii)) {
221         if (!exists(*ii)) {
222            std::cerr << "Fatal: failed to setup test directory: "
223                      << *ii << std::endl;
224            exit(EXIT_FAILURE);
225         }
226      }
227   }
228
229   testFindFilesWithPrefix();
230   testFindFilesContaining();
231   testRemove();
232
233   testIsDirectory();
234
235   return exit_value;
236}
237