Switch license from Intranator license to GPLv2 + linking exception (ACKed by Steffen)
[libi2ncommon] / test / test_filefunc.cpp
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 */
20 /** @file
21  *
22  * tests for the modules "filefunc", "daemonfunc"
23  *
24  * (c) Copyright 2007-2008 by Intra2net AG
25  */
26
27 //#define NOISEDEBUG
28
29 #include <string>
30 #include <vector>
31 #include <list>
32 #include <set>
33 #include <iostream>
34 #include <iomanip>
35 #include <fstream>
36 #include <sstream>
37 #include <algorithm>
38
39 #define BOOST_TEST_DYN_LINK
40 #include <boost/test/unit_test.hpp>
41
42 #include <filefunc.hxx>
43 #include <daemonfunc.hpp>
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
51 using namespace std;
52 using namespace I2n;
53
54 class TestFileFuncFixture
55 {
56 protected:
57    typedef std::list< std::string > StringList;
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
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
84 public:
85     TestFileFuncFixture()
86     {
87     }
88
89     ~TestFileFuncFixture()
90     {
91         remove_check_files();
92     }
93 };
94
95 BOOST_FIXTURE_TEST_SUITE(TestFileFunc, TestFileFuncFixture)
96
97 BOOST_AUTO_TEST_CASE(StatTest1)
98 {
99     I2n::Stat stat("Makefile");
100
101     BOOST_CHECK_EQUAL( true, (bool)stat );
102     BOOST_CHECK_EQUAL( true, stat.is_regular_file() );
103     BOOST_CHECK_EQUAL( false, stat.is_directory() );
104
105     stat= Stat("/dev/null");
106
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
114
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 }
132
133 BOOST_AUTO_TEST_CASE(DirTest1)
134 {
135     typedef std::vector< std::string > StringVector;
136     StringVector names;
137
138     bool res= I2n::get_dir(".",names);
139
140     BOOST_CHECK_EQUAL( true, res );
141     BOOST_CHECK( ! names.empty() );
142
143     StringVector::iterator it = std::find( names.begin(), names.end(), "Makefile");
144     BOOST_CHECK( it != names.end() );
145
146     it = std::find( names.begin(), names.end(), "." );
147     BOOST_CHECK( it == names.end() );
148
149     names= get_dir(".",true);
150     BOOST_CHECK( ! names.empty() );
151
152     for (it= names.begin(); it!=names.end(); ++it)
153     {
154         DOUT("  \"" << *it << "\"");
155         BOOST_CHECK_EQUAL( false, it->empty() );
156     }
157
158     it = std::find( names.begin(), names.end(), "." );
159     BOOST_CHECK( it != names.end() );
160 } // eo DirTest1
161
162
163
164 BOOST_AUTO_TEST_CASE(PathCuts1)
165 {
166     std::string path1("/an/absolute/path");
167
168     BOOST_CHECK_EQUAL( std::string("/an/absolute"), dirname(path1) );
169     BOOST_CHECK_EQUAL( std::string("path"), basename(path1) );
170
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()
175
176
177
178 BOOST_AUTO_TEST_CASE(NormalizePath1)
179 {
180     std::string path;
181
182     path= normalize_path("/a/simple/path/");
183     BOOST_CHECK_EQUAL( std::string("/a/simple/path"), path );
184
185     path= normalize_path("//another///simple/.//path//");
186     BOOST_CHECK_EQUAL( std::string("/another/simple/path"), path );
187
188     path= normalize_path("//..//..//a/dummy///../././simple/././/path//");
189     BOOST_CHECK_EQUAL( std::string("/a/simple/path"), path );
190
191     path= normalize_path("../a/dummy//././..//simple//nice//absolute//.././..//relative/path//");
192     BOOST_CHECK_EQUAL( std::string("../a/simple/relative/path"), path );
193
194     path= normalize_path("../../a/dummy//././..//simple/../nice//absolute//../.x/..//relative/path//");
195     BOOST_CHECK_EQUAL( std::string("../../a/nice/relative/path"), path );
196
197 } // eo NormalizePath1
198
199 BOOST_AUTO_TEST_CASE(NormalizePath2)
200 {
201     std::string path;
202
203     path= normalize_path("/");
204     BOOST_CHECK_EQUAL( std::string("/"), path );
205
206     path= normalize_path("//");
207     BOOST_CHECK_EQUAL( std::string("/"), path );
208
209     path= normalize_path("/.//");
210     BOOST_CHECK_EQUAL( std::string("/"), path );
211
212     path= normalize_path(".");
213     BOOST_CHECK_EQUAL( std::string(""), path );
214
215     path= normalize_path("./");
216     BOOST_CHECK_EQUAL( std::string(""), path );
217
218     path= normalize_path(".///");
219     BOOST_CHECK_EQUAL( std::string(""), path );
220
221     path= normalize_path("/./data/files");
222     BOOST_CHECK_EQUAL( std::string("/data/files"), path );
223
224     path= normalize_path("./data/files/");
225     BOOST_CHECK_EQUAL( std::string("data/files"), path );
226 } // eo NormalizePath2
227
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 );
233
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 );
237
238     User user_root2("root");
239     BOOST_CHECK_EQUAL( true, user_root2.is_valid() );
240     BOOST_CHECK_EQUAL( true, (bool)user_root2 );
241
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 );
245
246     Group group_root("root");
247     BOOST_CHECK_EQUAL( true, group_root.is_valid() );
248     BOOST_CHECK_EQUAL( true, (bool)group_root );
249
250     BOOST_CHECK_EQUAL( std::string("root"), group_root.Name );
251     BOOST_CHECK_EQUAL( (gid_t)0, group_root.Gid );
252
253 } // TestUserAndGroupStuff1()
254
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() );
260
261     Group group_root;
262     BOOST_CHECK_EQUAL( false, group_root.is_valid() );
263 }
264
265 BOOST_AUTO_TEST_CASE(TestFileModes1)
266 {
267     std::string path= get_check_file_path("FileModes1");
268
269     write_file(path,"42");
270
271     Stat stat(path, false);
272     BOOST_CHECK_EQUAL( true, stat.is_valid() );
273
274     User user( stat.uid() );
275     Group group( stat.gid() );
276
277     BOOST_CHECK_EQUAL( true, user.is_valid() );
278     BOOST_CHECK_EQUAL( true, group.is_valid() );
279
280     bool res=chown( path, user.Name.c_str(), group.Gid );
281
282     BOOST_CHECK_EQUAL( true, res );
283 } // eo TestFileModes1()
284
285
286
287 BOOST_AUTO_TEST_CASE(TestPidOf1)
288 {
289     using I2n::Daemon::pid_of;
290
291     std::vector< pid_t > pid_list;
292
293     bool res= pid_of("init", pid_list);
294
295     BOOST_CHECK_EQUAL( true, res);
296     BOOST_CHECK_EQUAL( false, pid_list.empty() );
297
298     std::vector< pid_t >::const_iterator pos1 =
299         std::find( pid_list.begin(), pid_list.end(), 1);
300
301     BOOST_CHECK( pos1 != pid_list.end() );
302 } // eo TestPidOf1()
303
304 BOOST_AUTO_TEST_CASE(TestCopyFileSourceFail)
305 {
306     bool res = copy_file("does not exist", "destination");
307     BOOST_CHECK_EQUAL( false, res );
308 }
309
310 BOOST_AUTO_TEST_CASE(TestCopyFileDestFail)
311 {
312     bool res = copy_file("/etc/HOSTNAME", "/proc/not/writable");
313     BOOST_CHECK_EQUAL( false, res );
314 }
315
316 BOOST_AUTO_TEST_CASE(TestCopyFileOk)
317 {
318     string input = "copy_source";
319     string data = "test";
320
321     long input_size = 0;
322     ofstream finput(input.c_str());
323     if (finput)
324     {
325         finput << data;
326         finput.close();
327         input_size = file_size(input);
328     }
329
330     string output = "copy_dest";
331     long output_size = 0;
332     bool res = copy_file(input, output);
333     if (res)
334     {
335         output_size = file_size(output);
336     }
337     unlink(input);
338     unlink(output);
339
340     bool size_is_zero = output_size == 0 ? true : false;
341
342     BOOST_CHECK_EQUAL( true, res );
343     BOOST_CHECK_EQUAL( input_size, output_size );
344     BOOST_CHECK_EQUAL( false, size_is_zero );
345 }
346
347 BOOST_AUTO_TEST_SUITE_END()