xref: /haiku/src/tests/kits/storage/FindDirectoryTest.cpp (revision a629567a9001547736cfe892cdf992be16868fed)
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_CONFIG_DIRECTORY:
240 			error = path.SetTo("/boot/home/config");
241 			break;
242 		case B_USER_ADDONS_DIRECTORY:
243 			error = path.SetTo("/boot/home/config/add-ons");
244 			break;
245 		case B_USER_BOOT_DIRECTORY:
246 			error = path.SetTo("/boot/home/config/boot");
247 			break;
248 		case B_USER_FONTS_DIRECTORY:
249 			error = path.SetTo("/boot/home/config/fonts");
250 			break;
251 		case B_USER_LIB_DIRECTORY:
252 			error = path.SetTo("/boot/home/config/lib");
253 			break;
254 		case B_USER_SETTINGS_DIRECTORY:
255 			error = path.SetTo("/boot/home/config/settings");
256 			break;
257 		case B_USER_DESKBAR_DIRECTORY:
258 			error = path.SetTo("/boot/home/config/be");
259 			break;
260 		case B_USER_PRINTERS_DIRECTORY:
261 			error = path.SetTo("/boot/home/config/settings/printers");
262 			break;
263 		case B_USER_TRANSLATORS_DIRECTORY:
264 			error = path.SetTo("/boot/home/config/add-ons/Translators");
265 			break;
266 		case B_USER_MEDIA_NODES_DIRECTORY:
267 			error = path.SetTo("/boot/home/config/add-ons/media");
268 			break;
269 		case B_USER_SOUNDS_DIRECTORY:
270 			error = path.SetTo("/boot/home/config/sounds");
271 			break;
272 		// Global directories.
273 		case B_APPS_DIRECTORY:
274 			error = path.SetTo("/boot/system/apps");
275 			break;
276 		case B_PREFERENCES_DIRECTORY:
277 			error = path.SetTo("/boot/system/preferences");
278 			break;
279 		case B_UTILITIES_DIRECTORY:
280 			error = path.SetTo("/boot/utilities");
281 			break;
282 	}
283 	return error;
284 }
285 
286 // TestDirectories
287 static
288 void
289 TestDirectories(dev_t device)
290 {
291 	BVolume volume;
292 	if (device >= 0)
293 		CPPUNIT_ASSERT( volume.SetTo(device) == B_OK );
294 	for (int32 i = 0; i < directoryCount; i++) {
295 		BPath path;
296 		BPath path2;
297 		char path3[B_PATH_NAME_LENGTH + 1];
298 		status_t result = test_find_directory(directories[i], path, device);
299 		status_t result2 = find_directory(directories[i], &path2, false,
300 										  &volume);
301 		status_t result3 = find_directory(directories[i], device, false,
302 										  path3, B_PATH_NAME_LENGTH + 1);
303 		CPPUNIT_ASSERT( result == result2 && result == result3 );
304 		if (result == B_OK)
305 			CPPUNIT_ASSERT( path == path2 && path == path3 );
306 	}
307 }
308 
309 // Test
310 void
311 FindDirectoryTest::Test()
312 {
313 	// /boot
314 	NextSubTest();
315 	dev_t device = dev_for_path("/boot");
316 	CPPUNIT_ASSERT( device > 0 );
317 	TestDirectories(device);
318 	// /dev
319 	NextSubTest();
320 	device = dev_for_path("/dev");
321 	CPPUNIT_ASSERT( device > 0 );
322 	TestDirectories(device);
323 	// /
324 	NextSubTest();
325 	device = dev_for_path("/");
326 	CPPUNIT_ASSERT( device > 0 );
327 	TestDirectories(device);
328 	// test image
329 	NextSubTest();
330 	device = dev_for_path(testMountPoint);
331 	CPPUNIT_ASSERT( device > 0 );
332 	TestDirectories(device);
333 	// invalid device ID
334 	NextSubTest();
335 	TestDirectories(-1);
336 	// NULL BVolume
337 	NextSubTest();
338 	for (int32 i = 0; i < directoryCount; i++) {
339 		BPath path;
340 		BPath path2;
341 		status_t result = test_find_directory(directories[i], path, -1);
342 		status_t result2 = find_directory(directories[i], &path2, false, NULL);
343 		CPPUNIT_ASSERT( result == result2 );
344 		if (result == B_OK)
345 			CPPUNIT_ASSERT( path == path2 );
346 	}
347 	// no such volume
348 	NextSubTest();
349 	device = 213;
350 	fs_info info;
351 	while (fs_stat_dev(device, &info) == 0)
352 		device++;
353 	for (int32 i = 0; i < directoryCount; i++) {
354 		BPath path;
355 		char path3[B_PATH_NAME_LENGTH + 1];
356 		status_t result = test_find_directory(directories[i], path, device);
357 		status_t result3 = find_directory(directories[i], device, false,
358 										  path3, B_PATH_NAME_LENGTH + 1);
359 		// Our test_find_directory() returns rather strange errors instead
360 		// of B_ENTRY_NOT_FOUND.
361 		CPPUNIT_ASSERT( result == B_OK && result3 == B_OK
362 						|| result != B_OK && result3 != B_OK );
363 		if (result == B_OK)
364 			CPPUNIT_ASSERT( path == path3 );
365 	}
366 	// bad args
367 	// R5: crashes
368 	NextSubTest();
369 	device = dev_for_path("/boot");
370 	CPPUNIT_ASSERT( device > 0 );
371 #if !TEST_R5
372 	CPPUNIT_ASSERT( find_directory(B_BEOS_DIRECTORY, NULL, false, NULL)
373 					== B_BAD_VALUE );
374 	CPPUNIT_ASSERT( find_directory(B_BEOS_DIRECTORY, device, false, NULL, 50)
375 					== B_BAD_VALUE );
376 #endif
377 	// small buffer
378 	NextSubTest();
379 	char path3[7];
380 	CPPUNIT_ASSERT( find_directory(B_BEOS_DIRECTORY, device, false, path3, 7)
381 					== E2BIG );
382 }
383 
384 
385 
386 
387 
388