xref: /haiku/src/tests/kits/storage/FindDirectoryTest.cpp (revision 9642f7705b27e5c270c15fa526d14e1848c2c27d)
1 // FindDirectoryTest.cpp
2 
3 #include <errno.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <unistd.h>
7 
8 #include <string>
9 using std::string;
10 
11 #include "FindDirectoryTest.h"
12 
13 #include <FindDirectory.h>
14 #include <fs_info.h>
15 #include <Entry.h>
16 #include <Path.h>
17 #include <Volume.h>
18 
19 
20 
21 const directory_which directories[] = {
22 	B_DESKTOP_DIRECTORY,
23 	B_TRASH_DIRECTORY,
24 	// BeOS directories.  These are mostly accessed read-only.
25 	B_BEOS_DIRECTORY,
26 	B_BEOS_SYSTEM_DIRECTORY,
27 	B_BEOS_ADDONS_DIRECTORY,
28 	B_BEOS_BOOT_DIRECTORY,
29 	B_BEOS_FONTS_DIRECTORY,
30 	B_BEOS_LIB_DIRECTORY,
31  	B_BEOS_SERVERS_DIRECTORY,
32 	B_BEOS_APPS_DIRECTORY,
33 	B_BEOS_BIN_DIRECTORY,
34 	B_BEOS_ETC_DIRECTORY,
35 	B_BEOS_DOCUMENTATION_DIRECTORY,
36 	B_BEOS_PREFERENCES_DIRECTORY,
37 	B_BEOS_TRANSLATORS_DIRECTORY,
38 	B_BEOS_MEDIA_NODES_DIRECTORY,
39 	B_BEOS_SOUNDS_DIRECTORY,
40 	B_SYSTEM_ETC_DIRECTORY,
41 	B_SYSTEM_SETTINGS_DIRECTORY,
42 	B_SYSTEM_LOG_DIRECTORY,
43 	B_SYSTEM_SPOOL_DIRECTORY,
44 	B_SYSTEM_TEMP_DIRECTORY,
45 	B_SYSTEM_VAR_DIRECTORY,
46 	// User directories.  These are interpreted in the context
47 	// of the user making the find_directory call.
48 	B_USER_DIRECTORY,
49 	B_USER_CONFIG_DIRECTORY,
50 	B_USER_ADDONS_DIRECTORY,
51 	B_USER_BOOT_DIRECTORY,
52 	B_USER_FONTS_DIRECTORY,
53 	B_USER_LIB_DIRECTORY,
54 	B_USER_SETTINGS_DIRECTORY,
55 	B_USER_DESKBAR_DIRECTORY,
56 	B_USER_PRINTERS_DIRECTORY,
57 	B_USER_TRANSLATORS_DIRECTORY,
58 	B_USER_MEDIA_NODES_DIRECTORY,
59 	B_USER_SOUNDS_DIRECTORY,
60 	// Global directories.
61 	B_APPS_DIRECTORY,
62 	B_PREFERENCES_DIRECTORY,
63 	B_UTILITIES_DIRECTORY
64 };
65 
66 const int32 directoryCount = sizeof(directories) / sizeof(directory_which);
67 
68 const char *testFile		= "/tmp/testFile";
69 const char *testMountPoint	= "/non-existing-mount-point";
70 
71 
72 // Suite
73 CppUnit::Test*
74 FindDirectoryTest::Suite() {
75 	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
76 	typedef CppUnit::TestCaller<FindDirectoryTest> TC;
77 
78 	suite->addTest( new TC("find_directory() Test",
79 						   &FindDirectoryTest::Test) );
80 
81 	return suite;
82 }
83 
84 // setUp
85 void
86 FindDirectoryTest::setUp()
87 {
88 	BasicTest::setUp();
89 	createVolume(testFile, testMountPoint, 1);
90 }
91 
92 // tearDown
93 void
94 FindDirectoryTest::tearDown()
95 {
96 	deleteVolume(testFile, testMountPoint);
97 	BasicTest::tearDown();
98 }
99 
100 // print_directories
101 /*static
102 void
103 print_directories(dev_t device)
104 {
105 	printf("device id: %ld\n", device);
106 	BVolume volume;
107 	status_t error = volume.SetTo(device);
108 	if (error != B_OK)
109 		printf("Failed to init volume\n");
110 	for (int32 i = 0; error == B_OK && i < directoryCount; i++) {
111 		BPath path;
112 		error = find_directory(directories[i], &path, false, &volume);
113 		if (error == B_OK)
114 			printf("%4d: `%s'\n", directories[i], path.Path());
115 		else
116 			printf("Failed to find directory: %s\n", strerror(error));
117 	}
118 }*/
119 
120 // test_find_directory
121 static
122 status_t
123 test_find_directory(directory_which dir, BPath &path, dev_t device)
124 {
125 	status_t error = B_BAD_VALUE;
126 	switch (dir) {
127 		// volume relative dirs
128 		case B_DESKTOP_DIRECTORY:
129 		{
130 			if (device < 0)
131 				device = dev_for_path("/boot");
132 			fs_info info;
133 			if (fs_stat_dev(device, &info) == 0) {
134 				if (!strcmp(info.fsh_name, "bfs")) {
135 					entry_ref ref(device, info.root, "home");
136 					BPath homePath(&ref);
137 					error = homePath.InitCheck();
138 					if (error == B_OK)
139 						path.SetTo(homePath.Path(), "Desktop");
140 				} else
141 					error = B_ENTRY_NOT_FOUND;
142 			} else
143 				error = errno;
144 			break;
145 		}
146 		case B_TRASH_DIRECTORY:
147 		{
148 			if (device < 0)
149 				device = dev_for_path("/boot");
150 			fs_info info;
151 			if (fs_stat_dev(device, &info) == 0) {
152 				if (!strcmp(info.fsh_name, "bfs")) {
153 					entry_ref ref(device, info.root, "home");
154 					BPath homePath(&ref);
155 					error = homePath.InitCheck();
156 					if (error == B_OK)
157 						path.SetTo(homePath.Path(), "Desktop/Trash");
158 				} else if (!strcmp(info.fsh_name, "dos")) {
159 					entry_ref ref(device, info.root, "RECYCLED");
160 					BPath recycledPath(&ref);
161 					error = recycledPath.InitCheck();
162 					if (error == B_OK)
163 						path.SetTo(recycledPath.Path(), "_BEOS_");
164 				} else
165 					error = B_ENTRY_NOT_FOUND;
166 			} else
167 				error = errno;
168 			break;
169 		}
170 		// BeOS directories.  These are mostly accessed read-only.
171 		case B_BEOS_DIRECTORY:
172 			error = path.SetTo("/boot/beos");
173 			break;
174 		case B_BEOS_SYSTEM_DIRECTORY:
175 			error = path.SetTo("/boot/beos/system");
176 			break;
177 		case B_BEOS_ADDONS_DIRECTORY:
178 			error = path.SetTo("/boot/beos/system/add-ons");
179 			break;
180 		case B_BEOS_BOOT_DIRECTORY:
181 			error = path.SetTo("/boot/beos/system/boot");
182 			break;
183 		case B_BEOS_FONTS_DIRECTORY:
184 			error = path.SetTo("/boot/beos/etc/fonts");
185 			break;
186 		case B_BEOS_LIB_DIRECTORY:
187 			error = path.SetTo("/boot/beos/system/lib");
188 			break;
189  		case B_BEOS_SERVERS_DIRECTORY:
190 			error = path.SetTo("/boot/beos/system/servers");
191 			break;
192 		case B_BEOS_APPS_DIRECTORY:
193 			error = path.SetTo("/boot/beos/apps");
194 			break;
195 		case B_BEOS_BIN_DIRECTORY:
196 			error = path.SetTo("/boot/beos/bin");
197 			break;
198 		case B_BEOS_ETC_DIRECTORY:
199 			error = path.SetTo("/boot/beos/etc");
200 			break;
201 		case B_BEOS_DOCUMENTATION_DIRECTORY:
202 			error = path.SetTo("/boot/beos/documentation");
203 			break;
204 		case B_BEOS_PREFERENCES_DIRECTORY:
205 			error = path.SetTo("/boot/beos/preferences");
206 			break;
207 		case B_BEOS_TRANSLATORS_DIRECTORY:
208 			error = path.SetTo("/boot/beos/system/add-ons/Translators");
209 			break;
210 		case B_BEOS_MEDIA_NODES_DIRECTORY:
211 			error = path.SetTo("/boot/beos/system/add-ons/media");
212 			break;
213 		case B_BEOS_SOUNDS_DIRECTORY:
214 			error = path.SetTo("/boot/beos/etc/sounds");
215 			break;
216 		case B_SYSTEM_ETC_DIRECTORY:
217 			error = path.SetTo("/boot/home/config/etc");
218 			break;
219 		case B_SYSTEM_SETTINGS_DIRECTORY:
220 			error = path.SetTo("/boot/home/config/settings");
221 			break;
222 		case B_SYSTEM_LOG_DIRECTORY:
223 			error = path.SetTo("/boot/var/log");
224 			break;
225 		case B_SYSTEM_SPOOL_DIRECTORY:
226 			error = path.SetTo("/boot/var/spool");
227 			break;
228 		case B_SYSTEM_TEMP_DIRECTORY:
229 			error = path.SetTo("/boot/var/tmp");
230 			break;
231 		case B_SYSTEM_VAR_DIRECTORY:
232 			error = path.SetTo("/boot/var");
233 			break;
234 		// User directories.  These are interpreted in the context
235 		// of the user making the find_directory call.
236 		case B_USER_DIRECTORY:
237 			error = path.SetTo("/boot/home");
238 			break;
239 		case B_USER_CACHE_DIRECTORY:
240 			error = path.SetTo("/boot/common/cache");
241 			break;
242 		case B_USER_CONFIG_DIRECTORY:
243 			error = path.SetTo("/boot/home/config");
244 			break;
245 		case B_USER_ADDONS_DIRECTORY:
246 			error = path.SetTo("/boot/home/config/add-ons");
247 			break;
248 		case B_USER_BOOT_DIRECTORY:
249 			error = path.SetTo("/boot/home/config/boot");
250 			break;
251 		case B_USER_DATA_DIRECTORY:
252 			error = path.SetTo("/boot/home/config/data");
253 			break;
254 		case B_USER_FONTS_DIRECTORY:
255 			error = path.SetTo("/boot/home/config/fonts");
256 			break;
257 		case B_USER_LIB_DIRECTORY:
258 			error = path.SetTo("/boot/home/config/lib");
259 			break;
260 		case B_USER_SETTINGS_DIRECTORY:
261 			error = path.SetTo("/boot/home/config/settings");
262 			break;
263 		case B_USER_DESKBAR_DIRECTORY:
264 			error = path.SetTo("/boot/home/config/be");
265 			break;
266 		case B_USER_PRINTERS_DIRECTORY:
267 			error = path.SetTo("/boot/home/config/settings/printers");
268 			break;
269 		case B_USER_TRANSLATORS_DIRECTORY:
270 			error = path.SetTo("/boot/home/config/add-ons/Translators");
271 			break;
272 		case B_USER_MEDIA_NODES_DIRECTORY:
273 			error = path.SetTo("/boot/home/config/add-ons/media");
274 			break;
275 		case B_USER_SOUNDS_DIRECTORY:
276 			error = path.SetTo("/boot/home/config/sounds");
277 			break;
278 		case B_SYSTEM_DATA_DIRECTORY:
279 			error = path.SetTo("/boot/system/data");
280 			break;
281 		// Global directories.
282 		case B_APPS_DIRECTORY:
283 			error = path.SetTo("/boot/system/apps");
284 			break;
285 		case B_PREFERENCES_DIRECTORY:
286 			error = path.SetTo("/boot/system/preferences");
287 			break;
288 		case B_UTILITIES_DIRECTORY:
289 			error = path.SetTo("/boot/utilities");
290 			break;
291 	}
292 	return error;
293 }
294 
295 // TestDirectories
296 static
297 void
298 TestDirectories(dev_t device)
299 {
300 	BVolume volume;
301 	if (device >= 0)
302 		CPPUNIT_ASSERT( volume.SetTo(device) == B_OK );
303 	for (int32 i = 0; i < directoryCount; i++) {
304 		BPath path;
305 		BPath path2;
306 		char path3[B_PATH_NAME_LENGTH + 1];
307 		status_t result = test_find_directory(directories[i], path, device);
308 		status_t result2 = find_directory(directories[i], &path2, false,
309 										  &volume);
310 		status_t result3 = find_directory(directories[i], device, false,
311 										  path3, B_PATH_NAME_LENGTH + 1);
312 		CPPUNIT_ASSERT( result == result2 && result == result3 );
313 		if (result == B_OK)
314 			CPPUNIT_ASSERT( path == path2 && path == path3 );
315 	}
316 }
317 
318 // Test
319 void
320 FindDirectoryTest::Test()
321 {
322 	// /boot
323 	NextSubTest();
324 	dev_t device = dev_for_path("/boot");
325 	CPPUNIT_ASSERT( device > 0 );
326 	TestDirectories(device);
327 	// /dev
328 	NextSubTest();
329 	device = dev_for_path("/dev");
330 	CPPUNIT_ASSERT( device > 0 );
331 	TestDirectories(device);
332 	// /
333 	NextSubTest();
334 	device = dev_for_path("/");
335 	CPPUNIT_ASSERT( device > 0 );
336 	TestDirectories(device);
337 	// test image
338 	NextSubTest();
339 	device = dev_for_path(testMountPoint);
340 	CPPUNIT_ASSERT( device > 0 );
341 	TestDirectories(device);
342 	// invalid device ID
343 	NextSubTest();
344 	TestDirectories(-1);
345 	// NULL BVolume
346 	NextSubTest();
347 	for (int32 i = 0; i < directoryCount; i++) {
348 		BPath path;
349 		BPath path2;
350 		status_t result = test_find_directory(directories[i], path, -1);
351 		status_t result2 = find_directory(directories[i], &path2, false, NULL);
352 		CPPUNIT_ASSERT( result == result2 );
353 		if (result == B_OK)
354 			CPPUNIT_ASSERT( path == path2 );
355 	}
356 	// no such volume
357 	NextSubTest();
358 	device = 213;
359 	fs_info info;
360 	while (fs_stat_dev(device, &info) == 0)
361 		device++;
362 	for (int32 i = 0; i < directoryCount; i++) {
363 		BPath path;
364 		char path3[B_PATH_NAME_LENGTH + 1];
365 		status_t result = test_find_directory(directories[i], path, device);
366 		status_t result3 = find_directory(directories[i], device, false,
367 										  path3, B_PATH_NAME_LENGTH + 1);
368 		// Our test_find_directory() returns rather strange errors instead
369 		// of B_ENTRY_NOT_FOUND.
370 		CPPUNIT_ASSERT( result == B_OK && result3 == B_OK
371 						|| result != B_OK && result3 != B_OK );
372 		if (result == B_OK)
373 			CPPUNIT_ASSERT( path == path3 );
374 	}
375 	// bad args
376 	// R5: crashes
377 	NextSubTest();
378 	device = dev_for_path("/boot");
379 	CPPUNIT_ASSERT( device > 0 );
380 #if !TEST_R5
381 	CPPUNIT_ASSERT( find_directory(B_BEOS_DIRECTORY, NULL, false, NULL)
382 					== B_BAD_VALUE );
383 	CPPUNIT_ASSERT( find_directory(B_BEOS_DIRECTORY, device, false, NULL, 50)
384 					== B_BAD_VALUE );
385 #endif
386 	// small buffer
387 	NextSubTest();
388 	char path3[7];
389 	CPPUNIT_ASSERT( find_directory(B_BEOS_DIRECTORY, device, false, path3, 7)
390 					== E2BIG );
391 }
392 
393 
394 
395 
396 
397