Commit | Line | Data |
---|---|---|
0e23f538 TJ |
1 | /* |
2 | The software in this package is distributed under the GNU General | |
3 | Public License version 2 (with a special exception described below). | |
4 | ||
5 | A copy of GNU General Public License (GPL) is included in this distribution, | |
6 | in the file COPYING.GPL. | |
7 | ||
8 | As a special exception, if other files instantiate templates or use macros | |
9 | or inline functions from this file, or you compile this file and link it | |
10 | with other works to produce a work based on this file, this file | |
11 | does not by itself cause the resulting work to be covered | |
12 | by the GNU General Public License. | |
13 | ||
14 | However the source code for this file must still be made available | |
15 | in accordance with section (3) of the GNU General Public License. | |
16 | ||
17 | This exception does not invalidate any other reasons why a work based | |
18 | on this file might be covered by the GNU General Public License. | |
19 | */ | |
5de0c58a RP |
20 | /** @file |
21 | * | |
22 | * tests for the modules "filefunc", "daemonfunc" | |
23 | * | |
24 | * (c) Copyright 2007-2008 by Intra2net AG | |
5de0c58a RP |
25 | */ |
26 | ||
27 | //#define NOISEDEBUG | |
28 | ||
29 | #include <string> | |
30 | #include <vector> | |
31 | #include <list> | |
9fe0853b | 32 | #include <set> |
5de0c58a RP |
33 | #include <iostream> |
34 | #include <iomanip> | |
1a2fc4e8 | 35 | #include <fstream> |
5de0c58a RP |
36 | #include <sstream> |
37 | #include <algorithm> | |
38 | ||
9fe0853b TJ |
39 | #define BOOST_TEST_DYN_LINK |
40 | #include <boost/test/unit_test.hpp> | |
5de0c58a RP |
41 | |
42 | #include <filefunc.hxx> | |
90246b4a | 43 | #include <daemonfunc.hpp> |
5de0c58a RP |
44 | |
45 | #ifdef NOISEDEBUG | |
46 | #define DOUT(msg) std::cout << msg << std::endl | |
47 | #else | |
48 | #define DOUT(msg) do {} while (0) | |
49 | #endif | |
50 | ||
1a2fc4e8 | 51 | using namespace std; |
5de0c58a RP |
52 | using namespace I2n; |
53 | ||
9fe0853b | 54 | class TestFileFuncFixture |
48d97d6c | 55 | { |
48d97d6c | 56 | protected: |
48d97d6c | 57 | typedef std::list< std::string > StringList; |
48d97d6c TJ |
58 | std::set<std::string> used_check_files; |
59 | ||
60 | std::string get_check_file_path(std::string tag) | |
61 | { | |
62 | std::string result; | |
63 | result= "__unittest__" + tag + ".dat"; | |
64 | used_check_files.insert(result); | |
65 | return result; | |
66 | } // eo get_check_file_path | |
67 | ||
48d97d6c TJ |
68 | void remove_check_files() |
69 | { | |
70 | for (std::set<std::string>::iterator it= used_check_files.begin(); | |
71 | it != used_check_files.end(); | |
72 | ++it) | |
73 | { | |
74 | std::string filepath(*it); | |
75 | if (path_exists(filepath)) | |
76 | { | |
77 | unlink(filepath); | |
78 | } | |
79 | //TODO | |
80 | } | |
81 | used_check_files.clear(); | |
82 | } // eo remove_check_files | |
83 | ||
48d97d6c | 84 | public: |
9fe0853b TJ |
85 | TestFileFuncFixture() |
86 | { | |
87 | } | |
48d97d6c | 88 | |
9fe0853b TJ |
89 | ~TestFileFuncFixture() |
90 | { | |
91 | remove_check_files(); | |
92 | } | |
93 | }; | |
48d97d6c | 94 | |
9fe0853b | 95 | BOOST_FIXTURE_TEST_SUITE(TestFileFunc, TestFileFuncFixture) |
48d97d6c | 96 | |
9fe0853b TJ |
97 | BOOST_AUTO_TEST_CASE(StatTest1) |
98 | { | |
263b5807 | 99 | I2n::Stat stat("Makefile"); |
48d97d6c | 100 | |
9fe0853b TJ |
101 | BOOST_CHECK_EQUAL( true, (bool)stat ); |
102 | BOOST_CHECK_EQUAL( true, stat.is_regular_file() ); | |
103 | BOOST_CHECK_EQUAL( false, stat.is_directory() ); | |
48d97d6c | 104 | |
9fe0853b | 105 | stat= Stat("/dev/null"); |
48d97d6c | 106 | |
9fe0853b TJ |
107 | BOOST_CHECK_EQUAL( true, (bool)stat ); |
108 | BOOST_CHECK_EQUAL( false, stat.is_regular_file() ); | |
109 | BOOST_CHECK_EQUAL( false, stat.is_directory() ); | |
110 | BOOST_CHECK_EQUAL( true, stat.is_device() ); | |
111 | BOOST_CHECK_EQUAL( true, stat.is_character_device() ); | |
112 | BOOST_CHECK_EQUAL( false, stat.is_block_device() ); | |
113 | } // eo StatTest1 | |
48d97d6c | 114 | |
96fe2dc5 GE |
115 | BOOST_AUTO_TEST_CASE(StatRecheck) |
116 | { | |
117 | // just to be sure | |
118 | unlink(".foobar"); | |
119 | ||
120 | I2n::Stat stat(".foobar"); | |
121 | BOOST_CHECK_EQUAL( false, (bool)stat ); | |
122 | ||
123 | write_file(".foobar","hello world"); | |
124 | ||
125 | stat.recheck(); | |
126 | ||
127 | BOOST_CHECK_EQUAL( true, (bool)stat ); | |
128 | BOOST_CHECK_EQUAL( true, stat.size() > 0 ); | |
129 | ||
130 | unlink(".foobar"); | |
131 | } | |
48d97d6c | 132 | |
9fe0853b TJ |
133 | BOOST_AUTO_TEST_CASE(DirTest1) |
134 | { | |
135 | typedef std::vector< std::string > StringVector; | |
136 | StringVector names; | |
48d97d6c | 137 | |
9fe0853b | 138 | bool res= I2n::get_dir(".",names); |
48d97d6c | 139 | |
9fe0853b TJ |
140 | BOOST_CHECK_EQUAL( true, res ); |
141 | BOOST_CHECK( ! names.empty() ); | |
48d97d6c | 142 | |
263b5807 | 143 | StringVector::iterator it = std::find( names.begin(), names.end(), "Makefile"); |
9fe0853b | 144 | BOOST_CHECK( it != names.end() ); |
48d97d6c | 145 | |
9fe0853b TJ |
146 | it = std::find( names.begin(), names.end(), "." ); |
147 | BOOST_CHECK( it == names.end() ); | |
48d97d6c | 148 | |
9fe0853b TJ |
149 | names= get_dir(".",true); |
150 | BOOST_CHECK( ! names.empty() ); | |
48d97d6c | 151 | |
9fe0853b TJ |
152 | for (it= names.begin(); it!=names.end(); ++it) |
153 | { | |
154 | DOUT(" \"" << *it << "\""); | |
155 | BOOST_CHECK_EQUAL( false, it->empty() ); | |
156 | } | |
48d97d6c | 157 | |
9fe0853b TJ |
158 | it = std::find( names.begin(), names.end(), "." ); |
159 | BOOST_CHECK( it != names.end() ); | |
160 | } // eo DirTest1 | |
48d97d6c TJ |
161 | |
162 | ||
163 | ||
9fe0853b TJ |
164 | BOOST_AUTO_TEST_CASE(PathCuts1) |
165 | { | |
166 | std::string path1("/an/absolute/path"); | |
48d97d6c | 167 | |
9fe0853b TJ |
168 | BOOST_CHECK_EQUAL( std::string("/an/absolute"), dirname(path1) ); |
169 | BOOST_CHECK_EQUAL( std::string("path"), basename(path1) ); | |
48d97d6c | 170 | |
9fe0853b TJ |
171 | std::string path2("just.a.name"); |
172 | BOOST_CHECK_EQUAL( std::string("just.a.name"), basename(path2) ); | |
173 | BOOST_CHECK_EQUAL( std::string("."), dirname(path2) ); | |
174 | } // eo PathCuts1() | |
48d97d6c | 175 | |
48d97d6c | 176 | |
48d97d6c | 177 | |
9fe0853b TJ |
178 | BOOST_AUTO_TEST_CASE(NormalizePath1) |
179 | { | |
180 | std::string path; | |
48d97d6c | 181 | |
9fe0853b TJ |
182 | path= normalize_path("/a/simple/path/"); |
183 | BOOST_CHECK_EQUAL( std::string("/a/simple/path"), path ); | |
48d97d6c | 184 | |
9fe0853b TJ |
185 | path= normalize_path("//another///simple/.//path//"); |
186 | BOOST_CHECK_EQUAL( std::string("/another/simple/path"), path ); | |
19166500 | 187 | |
9fe0853b TJ |
188 | path= normalize_path("//..//..//a/dummy///../././simple/././/path//"); |
189 | BOOST_CHECK_EQUAL( std::string("/a/simple/path"), path ); | |
19166500 | 190 | |
9fe0853b TJ |
191 | path= normalize_path("../a/dummy//././..//simple//nice//absolute//.././..//relative/path//"); |
192 | BOOST_CHECK_EQUAL( std::string("../a/simple/relative/path"), path ); | |
19166500 | 193 | |
9fe0853b TJ |
194 | path= normalize_path("../../a/dummy//././..//simple/../nice//absolute//../.x/..//relative/path//"); |
195 | BOOST_CHECK_EQUAL( std::string("../../a/nice/relative/path"), path ); | |
19166500 | 196 | |
9fe0853b | 197 | } // eo NormalizePath1 |
19166500 | 198 | |
9fe0853b TJ |
199 | BOOST_AUTO_TEST_CASE(NormalizePath2) |
200 | { | |
201 | std::string path; | |
19166500 | 202 | |
9fe0853b TJ |
203 | path= normalize_path("/"); |
204 | BOOST_CHECK_EQUAL( std::string("/"), path ); | |
19166500 | 205 | |
9fe0853b TJ |
206 | path= normalize_path("//"); |
207 | BOOST_CHECK_EQUAL( std::string("/"), path ); | |
48d97d6c | 208 | |
9fe0853b TJ |
209 | path= normalize_path("/.//"); |
210 | BOOST_CHECK_EQUAL( std::string("/"), path ); | |
48d97d6c | 211 | |
9fe0853b TJ |
212 | path= normalize_path("."); |
213 | BOOST_CHECK_EQUAL( std::string(""), path ); | |
48d97d6c | 214 | |
9fe0853b TJ |
215 | path= normalize_path("./"); |
216 | BOOST_CHECK_EQUAL( std::string(""), path ); | |
48d97d6c | 217 | |
9fe0853b TJ |
218 | path= normalize_path(".///"); |
219 | BOOST_CHECK_EQUAL( std::string(""), path ); | |
48d97d6c | 220 | |
9fe0853b TJ |
221 | path= normalize_path("/./data/files"); |
222 | BOOST_CHECK_EQUAL( std::string("/data/files"), path ); | |
48d97d6c | 223 | |
9fe0853b TJ |
224 | path= normalize_path("./data/files/"); |
225 | BOOST_CHECK_EQUAL( std::string("data/files"), path ); | |
226 | } // eo NormalizePath2 | |
48d97d6c | 227 | |
9fe0853b TJ |
228 | BOOST_AUTO_TEST_CASE(TestUserAndGroupStuff1) |
229 | { | |
230 | User user_root((uid_t)0); | |
231 | BOOST_CHECK_EQUAL( true, user_root.is_valid() ); | |
232 | BOOST_CHECK_EQUAL( true, (bool)user_root ); | |
48d97d6c | 233 | |
9fe0853b TJ |
234 | BOOST_CHECK_EQUAL( std::string("root"), user_root.Name ); |
235 | BOOST_CHECK_EQUAL( (uid_t)0, user_root.Uid ); | |
236 | BOOST_CHECK_EQUAL( (gid_t)0, user_root.Gid ); | |
48d97d6c | 237 | |
9fe0853b TJ |
238 | User user_root2("root"); |
239 | BOOST_CHECK_EQUAL( true, user_root2.is_valid() ); | |
240 | BOOST_CHECK_EQUAL( true, (bool)user_root2 ); | |
48d97d6c | 241 | |
9fe0853b TJ |
242 | BOOST_CHECK_EQUAL( std::string("root"), user_root2.Name ); |
243 | BOOST_CHECK_EQUAL( (uid_t)0, user_root2.Uid ); | |
244 | BOOST_CHECK_EQUAL( (gid_t)0, user_root2.Gid ); | |
48d97d6c | 245 | |
9fe0853b TJ |
246 | Group group_root("root"); |
247 | BOOST_CHECK_EQUAL( true, group_root.is_valid() ); | |
248 | BOOST_CHECK_EQUAL( true, (bool)group_root ); | |
48d97d6c | 249 | |
9fe0853b TJ |
250 | BOOST_CHECK_EQUAL( std::string("root"), group_root.Name ); |
251 | BOOST_CHECK_EQUAL( (gid_t)0, group_root.Gid ); | |
48d97d6c | 252 | |
9fe0853b | 253 | } // TestUserAndGroupStuff1() |
48d97d6c | 254 | |
9fe0853b TJ |
255 | BOOST_AUTO_TEST_CASE(TestUserAndGroupStuff2) |
256 | { | |
257 | // Test if is_valid() works correctly | |
258 | User user_root; | |
259 | BOOST_CHECK_EQUAL( false, user_root.is_valid() ); | |
48d97d6c | 260 | |
9fe0853b TJ |
261 | Group group_root; |
262 | BOOST_CHECK_EQUAL( false, group_root.is_valid() ); | |
263 | } | |
48d97d6c | 264 | |
9fe0853b TJ |
265 | BOOST_AUTO_TEST_CASE(TestFileModes1) |
266 | { | |
267 | std::string path= get_check_file_path("FileModes1"); | |
48d97d6c | 268 | |
9fe0853b | 269 | write_file(path,"42"); |
48d97d6c | 270 | |
9fe0853b TJ |
271 | Stat stat(path, false); |
272 | BOOST_CHECK_EQUAL( true, stat.is_valid() ); | |
48d97d6c | 273 | |
9fe0853b TJ |
274 | User user( stat.uid() ); |
275 | Group group( stat.gid() ); | |
48d97d6c | 276 | |
9fe0853b TJ |
277 | BOOST_CHECK_EQUAL( true, user.is_valid() ); |
278 | BOOST_CHECK_EQUAL( true, group.is_valid() ); | |
48d97d6c | 279 | |
9fe0853b | 280 | bool res=chown( path, user.Name.c_str(), group.Gid ); |
48d97d6c | 281 | |
9fe0853b TJ |
282 | BOOST_CHECK_EQUAL( true, res ); |
283 | } // eo TestFileModes1() | |
48d97d6c | 284 | |
48d97d6c | 285 | |
48d97d6c | 286 | |
9fe0853b TJ |
287 | BOOST_AUTO_TEST_CASE(TestPidOf1) |
288 | { | |
289 | using I2n::Daemon::pid_of; | |
48d97d6c | 290 | |
9fe0853b | 291 | std::vector< pid_t > pid_list; |
1a2fc4e8 | 292 | |
9fe0853b | 293 | bool res= pid_of("init", pid_list); |
9fe0853b | 294 | BOOST_CHECK_EQUAL( true, res); |
246bcd58 GE |
295 | |
296 | if (pid_list.empty()) | |
297 | { | |
298 | res= pid_of("systemd", pid_list); | |
299 | BOOST_CHECK_EQUAL( true, res); | |
300 | } | |
301 | ||
9fe0853b | 302 | BOOST_CHECK_EQUAL( false, pid_list.empty() ); |
1a2fc4e8 | 303 | |
9fe0853b TJ |
304 | std::vector< pid_t >::const_iterator pos1 = |
305 | std::find( pid_list.begin(), pid_list.end(), 1); | |
48d97d6c | 306 | |
9fe0853b TJ |
307 | BOOST_CHECK( pos1 != pid_list.end() ); |
308 | } // eo TestPidOf1() | |
1a2fc4e8 | 309 | |
9fe0853b TJ |
310 | BOOST_AUTO_TEST_CASE(TestCopyFileSourceFail) |
311 | { | |
312 | bool res = copy_file("does not exist", "destination"); | |
313 | BOOST_CHECK_EQUAL( false, res ); | |
314 | } | |
48d97d6c | 315 | |
9fe0853b TJ |
316 | BOOST_AUTO_TEST_CASE(TestCopyFileDestFail) |
317 | { | |
318 | bool res = copy_file("/etc/HOSTNAME", "/proc/not/writable"); | |
319 | BOOST_CHECK_EQUAL( false, res ); | |
320 | } | |
5de0c58a | 321 | |
9fe0853b TJ |
322 | BOOST_AUTO_TEST_CASE(TestCopyFileOk) |
323 | { | |
324 | string input = "copy_source"; | |
325 | string data = "test"; | |
326 | ||
327 | long input_size = 0; | |
328 | ofstream finput(input.c_str()); | |
329 | if (finput) | |
330 | { | |
331 | finput << data; | |
332 | finput.close(); | |
333 | input_size = file_size(input); | |
334 | } | |
335 | ||
336 | string output = "copy_dest"; | |
337 | long output_size = 0; | |
338 | bool res = copy_file(input, output); | |
339 | if (res) | |
340 | { | |
341 | output_size = file_size(output); | |
342 | } | |
343 | unlink(input); | |
344 | unlink(output); | |
345 | ||
346 | bool size_is_zero = output_size == 0 ? true : false; | |
347 | ||
348 | BOOST_CHECK_EQUAL( true, res ); | |
349 | BOOST_CHECK_EQUAL( input_size, output_size ); | |
350 | BOOST_CHECK_EQUAL( false, size_is_zero ); | |
351 | } | |
352 | ||
faf8475b TJ |
353 | BOOST_AUTO_TEST_CASE(TestMkdtemp) |
354 | { | |
355 | // Create unique directory | |
356 | string unique_dir = I2n::mkdtemp("foobar.XXXXXX"); | |
357 | BOOST_REQUIRE(unique_dir.size() > 0); | |
358 | ||
359 | // Test if it's really a directory | |
360 | BOOST_CHECK_EQUAL(true, Stat(unique_dir).is_directory()); | |
361 | ||
362 | // Unlink it | |
363 | BOOST_CHECK_EQUAL(true, I2n::recursive_delete(unique_dir)); | |
364 | } | |
365 | ||
366 | BOOST_AUTO_TEST_CASE(TestMkdtempBrokenTemplate) | |
367 | { | |
368 | // Broken directory template -> fail | |
369 | string unique_dir = I2n::mkdtemp("foobar.XXX"); | |
370 | BOOST_CHECK_EQUAL("", unique_dir); | |
371 | } | |
372 | ||
44725532 TJ |
373 | BOOST_AUTO_TEST_CASE(DirectoryCreation) |
374 | { | |
375 | string dirname = "test_directory"; | |
376 | ||
377 | I2n::rmdir (dirname); | |
378 | ||
379 | BOOST_CHECK_EQUAL(true, I2n::mkdir(dirname)); | |
380 | BOOST_CHECK_EQUAL(true, Stat(dirname).is_directory()); | |
381 | // Verify default permissions | |
382 | BOOST_CHECK_EQUAL(0700, Stat(dirname).mode()); | |
383 | ||
384 | BOOST_CHECK_EQUAL(true, I2n::rmdir(dirname)); | |
385 | ||
386 | // Second call must fail: Directory already deleted | |
387 | BOOST_CHECK_EQUAL(false, I2n::rmdir(dirname)); | |
388 | } | |
389 | ||
390 | BOOST_AUTO_TEST_CASE(DirectoryCreatePermission) | |
391 | { | |
392 | string dirname = "test_directory"; | |
393 | ||
901e2943 TJ |
394 | // Save and fix umask |
395 | mode_t previous_mask = I2n::umask(0); | |
44725532 TJ |
396 | |
397 | I2n::rmdir (dirname); | |
398 | BOOST_CHECK_EQUAL(true, I2n::mkdir(dirname, 0770)); | |
901e2943 | 399 | BOOST_CHECK_EQUAL(0770, Stat(dirname).mode()); |
44725532 TJ |
400 | I2n::rmdir (dirname); |
401 | ||
901e2943 TJ |
402 | // Restore umask |
403 | I2n::umask(previous_mask); | |
44725532 TJ |
404 | } |
405 | ||
406 | BOOST_AUTO_TEST_CASE(ChangeDirectory) | |
407 | { | |
408 | string current_directory = I2n::getcwd(); | |
409 | BOOST_REQUIRE(!current_directory.empty()); | |
410 | ||
411 | BOOST_CHECK_EQUAL(true, I2n::chdir("/")); | |
412 | BOOST_CHECK_EQUAL("/", I2n::getcwd()); | |
413 | ||
414 | BOOST_CHECK_EQUAL(true, I2n::chdir(current_directory)); | |
415 | BOOST_REQUIRE_EQUAL(current_directory, I2n::getcwd()); | |
416 | } | |
417 | ||
c5935370 TJ |
418 | BOOST_AUTO_TEST_CASE(WriteFileEmptyData) |
419 | { | |
420 | // just to be sure | |
421 | unlink(".foobar"); | |
422 | ||
423 | I2n::Stat stat(".foobar"); | |
424 | BOOST_CHECK_EQUAL( false, (bool)stat ); | |
425 | ||
426 | // Call write_file() with empty data. Should still create the file. | |
427 | write_file(".foobar",""); | |
428 | ||
429 | stat.recheck(); | |
430 | ||
431 | BOOST_CHECK_EQUAL( true, (bool)stat ); | |
432 | BOOST_CHECK_EQUAL( true, stat.size() == 0 ); | |
433 | ||
434 | unlink(".foobar"); | |
435 | } | |
436 | ||
9fe0853b | 437 | BOOST_AUTO_TEST_SUITE_END() |