1/**
2 * @file file_manip_tests.cpp
3 *
4 * @remark Copyright 2003 OProfile authors
5 * @remark Read the file COPYING
6 *
7 * @author John Levon
8 * @author Philippe Elie
9 */
10
11#include <unistd.h>
12#include <stdlib.h>
13
14#include <string>
15#include <iostream>
16#include <list>
17
18#include "file_manip.h"
19
20using namespace std;
21
22template <typename Input, typename Output>
23struct input_output {
24	Input input;
25	Output output;
26};
27
28
29template <typename Input, typename Output, typename Result>
30static void check_result(char const * fct_name, Input const & input,
31		  Output const & output, Result const & result)
32{
33	if (result != output) {
34		cerr << fct_name << " "
35		     << "for:\n\"" << input << "\"\n"
36		     << "expect:\n\"" << output << "\"\n"
37		     << "found:\n\"" << result << "\"\n";
38		exit(EXIT_FAILURE);
39	}
40}
41
42template <typename Input, typename Output, typename Result>
43static void check_result(char const * fct_name, Input const & input1,
44	Input input2, Output const & output, Result const & result)
45{
46	if (result != output) {
47		cerr << fct_name << ": \n"
48		     << "for:\n\"" << input1 << "\"\n"
49		     << "\"" << input2 << "\"\n"
50		     << "expect:\n\"" << output << "\"\n"
51		     << "found:\n\"" << result << "\"\n";
52		exit(EXIT_FAILURE);
53	}
54}
55
56
57static input_output<char const *, char const *> expect_dirname[] =
58{
59	{ "/", "/" },
60	{ "//////", "/" },
61	{ "/usr", "/" },
62	{ "///usr", "/" },
63	// suprising but conform to dirname(1)
64	{ "///usr/dir", "///usr" },
65	{ "usr/dir", "usr" },
66	{ "usr", "." },
67	{ "n", "." },
68	{ "../..", ".." },
69	{ "/../..", "/.." },
70	{ "./..", "." },
71	{ "./.", "." },
72	{ "..", "." },
73	{ ".", "." },
74	{ "", "." },
75	{ 0, 0 }
76};
77
78static void dirname_tests()
79{
80	input_output<char const *, char const *> const * cur;
81	for (cur = expect_dirname; cur->input; ++cur) {
82		string result = op_dirname(cur->input);
83		check_result("dirname", cur->input, cur->output, result);
84	}
85}
86
87
88static input_output<char const *, char const*> expect_basename[] =
89{
90	{ "/", "/" },
91	{ "//////", "/" },
92	{ "/usr", "usr" },
93	{ "///usr", "usr" },
94	{ "///usr/dir", "dir" },
95	{ "///usr//dir", "dir" },
96	{ "usr/dir", "dir" },
97	{ "usr", "usr" },
98	{ "../..", ".." },
99	{ "/../..", ".." },
100	{ "./..", ".." },
101	{ "./.", "." },
102	{ ".", "." },
103	{ 0, 0 }
104};
105
106static void basename_tests()
107{
108	input_output<char const *, char const *> const * cur;
109	for (cur = expect_basename; cur->input; ++cur) {
110		string result = op_basename(cur->input);
111		check_result("basename", cur->input, cur->output, result);
112	}
113}
114
115
116static input_output<char const *, bool> expect_is_directory[] =
117{
118	{ ".", true },
119	{ "/.", true },
120	{ "./", true },
121	{ "/", true },
122	{ "../", true },
123	{ "../.", true },
124	{ "non_existing_dir", false },
125	{ 0, 0 }
126};
127
128static void is_directory_tests()
129{
130	input_output<char const *, bool> const * cur;
131	for (cur = expect_is_directory; cur->input; ++cur) {
132		bool result = is_directory(cur->input);
133		check_result("is_directory", cur->input, cur->output, result);
134	}
135}
136
137
138static input_output<pair<string, string>, bool>
139expect_is_files_identical[] = {
140#define MAKE_PAIR(a, b) make_pair(string(a), string(b))
141	{ MAKE_PAIR(__FILE__, __FILE__), true },
142	{ MAKE_PAIR(__FILE__, "not_existing"), false },
143	{ MAKE_PAIR("not_exisiting", __FILE__), false },
144	{ MAKE_PAIR("not_exisiting", "not_existing"), false },
145	{ MAKE_PAIR("", ""), false }
146#undef MAKE_PAIR
147};
148
149void is_files_identical_tests(char const * prog_name)
150{
151	check_result("is_files_identical", prog_name, prog_name,
152	             is_files_identical(prog_name, prog_name), true);
153
154	input_output<pair<string, string>, bool> const * cur;
155	for (cur = expect_is_files_identical; !cur->input.first.empty(); ++cur) {
156		bool result = is_files_identical(cur->input.first,
157		                                 cur->input.second);
158		check_result("is_files_identical", cur->input.first,
159		             cur->input.second, cur->output, result);
160	}
161}
162
163
164static input_output<char const *, bool> expect_op_file_readable[] =
165{
166	{ __FILE__, true },
167	{ "./" __FILE__, true },
168	{ ".", false },
169	{ "/.", false },
170	{ "./", false },
171	{ "/", false },
172	{ "../", false },
173	{ "../.", false },
174	{ "non_existing_file", false },
175	{ 0, 0 }
176};
177
178static void op_file_readable_tests()
179{
180	input_output<char const *, bool> const * cur;
181	for (cur = expect_op_file_readable; cur->input; ++cur) {
182		bool result = op_file_readable(cur->input);
183		check_result("op_file_readable", cur->input, cur->output, result);
184	}
185}
186
187
188static input_output<string, string> expect_realpath[] =
189{
190	// realpath() file argument must exists.
191	{ "file_manip_tests.o", "file_manip_tests.o" },
192	{ "../tests/" "file_manip_tests.o", "file_manip_tests.o" },
193	{ ".//.//" "file_manip_tests.o", "file_manip_tests.o" },
194	// POSIX namespaces ignored by realpath(3)
195	{ "//", "/" },
196	{ "//usr", "/usr" },
197	{ "///", "/" },
198	{ "", "" }
199};
200
201
202// FIXME: useful to test symlinks too
203static void realpath_tests()
204{
205	input_output<string, string> const * cur;
206	for (cur = expect_realpath; !cur->input.empty(); ++cur) {
207		string result = op_realpath(cur->input);
208		string expect = cur->output;
209		if (cur->input[0] != '/')
210			expect = SRCDIR + expect;
211		check_result("op_realpath", cur->input,
212		            expect, result);
213	}
214}
215
216
217void create_file_list_tests()
218{
219	list<string> result;
220	if (!create_file_list(result, ".")) {
221		cerr << "create_file_list() fail\n";
222		exit(EXIT_FAILURE);
223	}
224	if (result.empty()) {
225		cerr << "create_file_list(); empty result\n";
226		exit(EXIT_FAILURE);
227	}
228}
229
230
231int main(int, char * argv[])
232{
233	dirname_tests();
234	basename_tests();
235	is_directory_tests();
236	is_files_identical_tests(argv[0]);
237	op_file_readable_tests();
238	realpath_tests();
239	create_file_list_tests();
240	return EXIT_SUCCESS;
241}
242