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