1// SymLinkTest.cpp
2
3#include <stdio.h>
4#include <string>
5
6#include <Directory.h>
7#include <Entry.h>
8#include <Path.h>
9#include <SymLink.h>
10
11#include "SymLinkTest.h"
12
13// Suite
14SymLinkTest::Test*
15SymLinkTest::Suite()
16{
17	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
18	typedef CppUnit::TestCaller<SymLinkTest> TC;
19
20	NodeTest::AddBaseClassTests<SymLinkTest>("BSymLink::", suite);
21
22	suite->addTest( new TC("BSymLink::Init Test 1", &SymLinkTest::InitTest1) );
23	suite->addTest( new TC("BSymLink::Init Test 2", &SymLinkTest::InitTest2) );
24	suite->addTest( new TC("BSymLink::ReadLink Test",
25						   &SymLinkTest::ReadLinkTest) );
26	suite->addTest( new TC("BSymLink::MakeLinkedPath Test",
27						   &SymLinkTest::MakeLinkedPathTest) );
28	suite->addTest( new TC("BSymLink::IsAbsolute Test",
29						   &SymLinkTest::IsAbsoluteTest) );
30	suite->addTest( new TC("BSymLink::Assignment Test",
31						   &SymLinkTest::AssignmentTest) );
32
33	return suite;
34}
35
36// CreateRONodes
37void
38SymLinkTest::CreateRONodes(TestNodes& testEntries)
39{
40	testEntries.clear();
41	const char *filename;
42	filename = "/tmp";
43	testEntries.add(new BSymLink(filename), filename);
44	filename = dirLinkname;
45	testEntries.add(new BSymLink(filename), filename);
46	filename = fileLinkname;
47	testEntries.add(new BSymLink(filename), filename);
48	filename = badLinkname;
49	testEntries.add(new BSymLink(filename), filename);
50	filename = cyclicLinkname1;
51	testEntries.add(new BSymLink(filename), filename);
52}
53
54// CreateRWNodes
55void
56SymLinkTest::CreateRWNodes(TestNodes& testEntries)
57{
58	testEntries.clear();
59	const char *filename;
60	filename = dirLinkname;
61	testEntries.add(new BSymLink(filename), filename);
62	filename = fileLinkname;
63	testEntries.add(new BSymLink(filename), filename);
64}
65
66// CreateUninitializedNodes
67void
68SymLinkTest::CreateUninitializedNodes(TestNodes& testEntries)
69{
70	testEntries.clear();
71	testEntries.add(new BSymLink, "");
72}
73
74// setUp
75void SymLinkTest::setUp()
76{
77	NodeTest::setUp();
78}
79
80// tearDown
81void SymLinkTest::tearDown()
82{
83	NodeTest::tearDown();
84}
85
86// InitTest1
87void
88SymLinkTest::InitTest1()
89{
90	const char *dirLink = dirLinkname;
91	const char *dirSuperLink = dirSuperLinkname;
92	const char *dirRelLink = dirRelLinkname;
93	const char *fileLink = fileLinkname;
94	const char *existingDir = existingDirname;
95	const char *existingSuperDir = existingSuperDirname;
96	const char *existingRelDir = existingRelDirname;
97	const char *existingFile = existingFilename;
98	const char *existingSuperFile = existingSuperFilename;
99	const char *existingRelFile = existingRelFilename;
100	const char *nonExisting = nonExistingDirname;
101	const char *nonExistingSuper = nonExistingSuperDirname;
102	const char *nonExistingRel = nonExistingRelDirname;
103	// 1. default constructor
104	NextSubTest();
105	{
106		BSymLink link;
107		CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
108	}
109
110	// 2. BSymLink(const char*)
111	NextSubTest();
112	{
113		BSymLink link(fileLink);
114		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
115	}
116	NextSubTest();
117	{
118		BSymLink link(nonExisting);
119		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
120	}
121	NextSubTest();
122	{
123		BSymLink link((const char *)NULL);
124		CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
125	}
126	NextSubTest();
127	{
128		BSymLink link("");
129		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
130	}
131	NextSubTest();
132	{
133		BSymLink link(existingFile);
134		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
135	}
136	NextSubTest();
137	{
138		BSymLink link(existingDir);
139		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
140	}
141	NextSubTest();
142	{
143		BSymLink link(tooLongEntryname);
144		CPPUNIT_ASSERT( link.InitCheck() == B_NAME_TOO_LONG );
145	}
146
147	// 3. BSymLink(const BEntry*)
148	NextSubTest();
149	{
150		BEntry entry(dirLink);
151		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
152		BSymLink link(&entry);
153		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
154	}
155	NextSubTest();
156	{
157		BEntry entry(nonExisting);
158		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
159		BSymLink link(&entry);
160		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
161	}
162	NextSubTest();
163	{
164		BSymLink link((BEntry *)NULL);
165		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
166	}
167	NextSubTest();
168	{
169		BEntry entry;
170		BSymLink link(&entry);
171		CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
172	}
173	NextSubTest();
174	{
175		BEntry entry(existingFile);
176		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
177		BSymLink link(&entry);
178		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
179
180	}
181	NextSubTest();
182	{
183		BEntry entry(existingDir);
184		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
185		BSymLink link(&entry);
186		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
187
188	}
189	NextSubTest();
190	{
191		BEntry entry(tooLongEntryname);
192		// R5 returns E2BIG instead of B_NAME_TOO_LONG
193		CPPUNIT_ASSERT( equals(entry.InitCheck(), E2BIG, B_NAME_TOO_LONG) );
194		BSymLink link(&entry);
195		CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
196	}
197
198	// 4. BSymLink(const entry_ref*)
199	NextSubTest();
200	{
201		BEntry entry(dirLink);
202		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
203		entry_ref ref;
204		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
205		BSymLink link(&ref);
206		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
207	}
208	NextSubTest();
209	{
210		BEntry entry(nonExisting);
211		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
212		entry_ref ref;
213		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
214		BSymLink link(&ref);
215		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
216	}
217	NextSubTest();
218	{
219		BSymLink link((entry_ref *)NULL);
220		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
221	}
222	NextSubTest();
223	{
224		BEntry entry(existingFile);
225		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
226		entry_ref ref;
227		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
228		BSymLink link(&ref);
229		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
230	}
231	NextSubTest();
232	{
233		BEntry entry(existingDir);
234		CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
235		entry_ref ref;
236		CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
237		BSymLink link(&ref);
238		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
239	}
240
241	// 5. BSymLink(const BDirectory*, const char*)
242	NextSubTest();
243	{
244		BDirectory pathDir(dirSuperLink);
245		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
246		BSymLink link(&pathDir, dirRelLink);
247		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
248	}
249	NextSubTest();
250	{
251		BDirectory pathDir(dirSuperLink);
252		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
253		BSymLink link(&pathDir, dirLink);
254		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
255	}
256	NextSubTest();
257	{
258		BDirectory pathDir(nonExistingSuper);
259		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
260		BSymLink link(&pathDir, nonExistingRel);
261		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
262	}
263	NextSubTest();
264	{
265		BSymLink link((BDirectory *)NULL, (const char *)NULL);
266		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
267	}
268	NextSubTest();
269	{
270		BSymLink link((BDirectory *)NULL, dirLink);
271		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
272	}
273	NextSubTest();
274	{
275		BDirectory pathDir(dirSuperLink);
276		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
277		BSymLink link(&pathDir, (const char *)NULL);
278		CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
279	}
280	NextSubTest();
281	{
282		BDirectory pathDir(dirSuperLink);
283		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
284		BSymLink link(&pathDir, "");
285		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
286	}
287	NextSubTest();
288	{
289		BDirectory pathDir(existingSuperFile);
290		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
291		BSymLink link(&pathDir, existingRelFile);
292		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
293	}
294	NextSubTest();
295	{
296		BDirectory pathDir(existingSuperDir);
297		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
298		BSymLink link(&pathDir, existingRelDir);
299		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
300	}
301	NextSubTest();
302	{
303		BDirectory pathDir(tooLongSuperEntryname);
304		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
305		BSymLink link(&pathDir, tooLongRelEntryname);
306		CPPUNIT_ASSERT( link.InitCheck() == B_NAME_TOO_LONG );
307	}
308	NextSubTest();
309	{
310		BDirectory pathDir(fileSuperDirname);
311		CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
312		BSymLink link(&pathDir, fileRelDirname);
313		CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
314	}
315}
316
317// InitTest2
318void
319SymLinkTest::InitTest2()
320{
321	const char *dirLink = dirLinkname;
322	const char *dirSuperLink = dirSuperLinkname;
323	const char *dirRelLink = dirRelLinkname;
324	const char *fileLink = fileLinkname;
325	const char *existingDir = existingDirname;
326	const char *existingSuperDir = existingSuperDirname;
327	const char *existingRelDir = existingRelDirname;
328	const char *existingFile = existingFilename;
329	const char *existingSuperFile = existingSuperFilename;
330	const char *existingRelFile = existingRelFilename;
331	const char *nonExisting = nonExistingDirname;
332	const char *nonExistingSuper = nonExistingSuperDirname;
333	const char *nonExistingRel = nonExistingRelDirname;
334	BSymLink link;
335	// 2. BSymLink(const char*)
336	NextSubTest();
337	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
338	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
339	//
340	NextSubTest();
341	CPPUNIT_ASSERT( link.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
342	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
343	//
344	NextSubTest();
345	CPPUNIT_ASSERT( equals(link.SetTo((const char *)NULL), B_BAD_VALUE,
346						   B_NO_INIT) );
347	CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
348	//
349	NextSubTest();
350	CPPUNIT_ASSERT( link.SetTo("") == B_ENTRY_NOT_FOUND );
351	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
352	//
353	NextSubTest();
354	CPPUNIT_ASSERT( link.SetTo(existingFile) == B_OK );
355	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
356	//
357	NextSubTest();
358	CPPUNIT_ASSERT( link.SetTo(existingDir) == B_OK );
359	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
360	//
361	NextSubTest();
362	CPPUNIT_ASSERT( link.SetTo(tooLongEntryname) == B_NAME_TOO_LONG );
363	CPPUNIT_ASSERT( link.InitCheck() == B_NAME_TOO_LONG );
364
365	// 3. BSymLink(const BEntry*)
366	NextSubTest();
367	BEntry entry(dirLink);
368	CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
369	CPPUNIT_ASSERT( link.SetTo(&entry) == B_OK );
370	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
371	//
372	NextSubTest();
373	CPPUNIT_ASSERT( entry.SetTo(nonExisting) == B_OK );
374	CPPUNIT_ASSERT( link.SetTo(&entry) == B_ENTRY_NOT_FOUND );
375	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
376	//
377	NextSubTest();
378	CPPUNIT_ASSERT( link.SetTo((BEntry *)NULL) == B_BAD_VALUE );
379	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
380	//
381	NextSubTest();
382	entry.Unset();
383	CPPUNIT_ASSERT( entry.InitCheck() == B_NO_INIT );
384	CPPUNIT_ASSERT( equals(link.SetTo(&entry), B_BAD_ADDRESS, B_BAD_VALUE) );
385	CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
386	//
387	NextSubTest();
388	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
389	CPPUNIT_ASSERT( link.SetTo(&entry) == B_OK );
390	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
391	//
392	NextSubTest();
393	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
394	CPPUNIT_ASSERT( link.SetTo(&entry) == B_OK );
395	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
396	//
397	NextSubTest();
398	// R5 returns E2BIG instead of B_NAME_TOO_LONG
399	CPPUNIT_ASSERT( equals(entry.SetTo(tooLongEntryname), E2BIG,
400						   B_NAME_TOO_LONG) );
401	CPPUNIT_ASSERT( equals(link.SetTo(&entry), B_BAD_ADDRESS, B_BAD_VALUE) );
402	CPPUNIT_ASSERT( equals(link.InitCheck(), B_BAD_ADDRESS, B_BAD_VALUE) );
403
404	// 4. BSymLink(const entry_ref*)
405	NextSubTest();
406	CPPUNIT_ASSERT( entry.SetTo(dirLink) == B_OK );
407	entry_ref ref;
408	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
409	CPPUNIT_ASSERT( link.SetTo(&ref) == B_OK );
410	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
411	//
412	NextSubTest();
413	CPPUNIT_ASSERT( entry.SetTo(nonExisting) == B_OK );
414	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
415	CPPUNIT_ASSERT( link.SetTo(&ref) == B_ENTRY_NOT_FOUND );
416	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
417	//
418	NextSubTest();
419	CPPUNIT_ASSERT( link.SetTo((entry_ref *)NULL) == B_BAD_VALUE );
420	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
421	//
422	NextSubTest();
423	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
424	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
425	CPPUNIT_ASSERT( link.SetTo(&ref) == B_OK );
426	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
427	//
428	NextSubTest();
429	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
430	CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
431	CPPUNIT_ASSERT( link.SetTo(&ref) == B_OK );
432	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
433
434	// 5. BSymLink(const BDirectory*, const char*)
435	NextSubTest();
436	BDirectory pathDir(dirSuperLink);
437	CPPUNIT_ASSERT( pathDir.InitCheck() == B_OK );
438	CPPUNIT_ASSERT( link.SetTo(&pathDir, dirRelLink) == B_OK );
439	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
440	//
441	NextSubTest();
442	CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK );
443	CPPUNIT_ASSERT( link.SetTo(&pathDir, dirLink) == B_BAD_VALUE );
444	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
445	//
446	NextSubTest();
447	CPPUNIT_ASSERT( pathDir.SetTo(nonExistingSuper) == B_OK );
448	CPPUNIT_ASSERT( link.SetTo(&pathDir, nonExistingRel) == B_ENTRY_NOT_FOUND );
449	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
450	//
451	NextSubTest();
452	CPPUNIT_ASSERT( link.SetTo((BDirectory *)NULL, (const char *)NULL)
453					== B_BAD_VALUE );
454	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
455	//
456	NextSubTest();
457	CPPUNIT_ASSERT( link.SetTo((BDirectory *)NULL, dirLink) == B_BAD_VALUE );
458	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
459	//
460	NextSubTest();
461	CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK );
462	CPPUNIT_ASSERT( link.SetTo(&pathDir, (const char *)NULL) == B_BAD_VALUE );
463	CPPUNIT_ASSERT( link.InitCheck() == B_BAD_VALUE );
464	//
465	NextSubTest();
466	CPPUNIT_ASSERT( pathDir.SetTo(dirSuperLink) == B_OK );
467	CPPUNIT_ASSERT( link.SetTo(&pathDir, "") == B_OK );
468	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
469	//
470	NextSubTest();
471	CPPUNIT_ASSERT( pathDir.SetTo(existingSuperFile) == B_OK );
472	CPPUNIT_ASSERT( link.SetTo(&pathDir, existingRelFile) == B_OK );
473	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
474	//
475	NextSubTest();
476	CPPUNIT_ASSERT( pathDir.SetTo(existingSuperDir) == B_OK );
477	CPPUNIT_ASSERT( link.SetTo(&pathDir, existingRelDir) == B_OK );
478	CPPUNIT_ASSERT( link.InitCheck() == B_OK );
479	//
480	NextSubTest();
481	CPPUNIT_ASSERT( pathDir.SetTo(tooLongSuperEntryname) == B_OK );
482	CPPUNIT_ASSERT( link.SetTo(&pathDir, tooLongRelEntryname)
483					== B_NAME_TOO_LONG );
484	CPPUNIT_ASSERT( link.InitCheck() == B_NAME_TOO_LONG );
485	//
486	NextSubTest();
487	CPPUNIT_ASSERT( pathDir.SetTo(fileSuperDirname) == B_OK );
488	CPPUNIT_ASSERT( link.SetTo(&pathDir, fileRelDirname) == B_ENTRY_NOT_FOUND );
489	CPPUNIT_ASSERT( link.InitCheck() == B_ENTRY_NOT_FOUND );
490}
491
492// ReadLinkTest
493void
494SymLinkTest::ReadLinkTest()
495{
496	const char *dirLink = dirLinkname;
497	const char *fileLink = fileLinkname;
498	const char *badLink = badLinkname;
499	const char *cyclicLink1 = cyclicLinkname1;
500	const char *cyclicLink2 = cyclicLinkname2;
501	const char *existingDir = existingDirname;
502	const char *existingFile = existingFilename;
503	const char *nonExisting = nonExistingDirname;
504	BSymLink link;
505	char buffer[B_PATH_NAME_LENGTH + 1];
506	// uninitialized
507	// R5: returns B_BAD_ADDRESS instead of (as doc'ed) B_FILE_ERROR
508	NextSubTest();
509	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
510	CPPUNIT_ASSERT( equals(link.ReadLink(buffer, sizeof(buffer)),
511						   B_BAD_ADDRESS, B_FILE_ERROR) );
512	// existing dir link
513	NextSubTest();
514	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
515	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
516					== (ssize_t)strlen(existingDir) );
517	CPPUNIT_ASSERT( strcmp(buffer, existingDir) == 0 );
518	// existing file link
519	NextSubTest();
520	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
521	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
522					== (ssize_t)strlen(existingFile) );
523	CPPUNIT_ASSERT( strcmp(buffer, existingFile) == 0 );
524	// existing cyclic link
525	NextSubTest();
526	CPPUNIT_ASSERT( link.SetTo(cyclicLink1) == B_OK );
527	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
528					== (ssize_t)strlen(cyclicLink2) );
529	CPPUNIT_ASSERT( strcmp(buffer, cyclicLink2) == 0 );
530	// existing link to non-existing entry
531	NextSubTest();
532	CPPUNIT_ASSERT( link.SetTo(badLink) == B_OK );
533	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer))
534					== (ssize_t)strlen(nonExisting) );
535	CPPUNIT_ASSERT( strcmp(buffer, nonExisting) == 0 );
536	// non-existing link
537	// R5: returns B_BAD_ADDRESS instead of (as doc'ed) B_FILE_ERROR
538	NextSubTest();
539	CPPUNIT_ASSERT( link.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
540	CPPUNIT_ASSERT( equals(link.ReadLink(buffer, sizeof(buffer)),
541						   B_BAD_ADDRESS, B_FILE_ERROR) );
542	// dir
543	NextSubTest();
544	CPPUNIT_ASSERT( link.SetTo(existingDir) == B_OK );
545	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer)) == B_BAD_VALUE );
546	// file
547	NextSubTest();
548	CPPUNIT_ASSERT( link.SetTo(existingFile) == B_OK );
549	CPPUNIT_ASSERT( link.ReadLink(buffer, sizeof(buffer)) == B_BAD_VALUE );
550	// small buffer
551	// R5: returns the size of the contents, not the number of bytes copied
552	// OBOS: ... so do we
553	NextSubTest();
554	char smallBuffer[2];
555	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
556	CPPUNIT_ASSERT( link.ReadLink(smallBuffer, sizeof(smallBuffer))
557					== (ssize_t)strlen(dirLink) );
558	CPPUNIT_ASSERT( strncmp(smallBuffer, existingDir, sizeof(smallBuffer)) == 0 );
559	// bad args
560	NextSubTest();
561	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
562	CPPUNIT_ASSERT( equals(link.ReadLink(NULL, sizeof(buffer)), B_BAD_ADDRESS,
563						   B_BAD_VALUE) );
564}
565
566// MakeLinkedPathTest
567void
568SymLinkTest::MakeLinkedPathTest()
569{
570	const char *dirLink = dirLinkname;
571	const char *fileLink = fileLinkname;
572	const char *relDirLink = relDirLinkname;
573	const char *relFileLink = relFileLinkname;
574	const char *cyclicLink1 = cyclicLinkname1;
575	const char *cyclicLink2 = cyclicLinkname2;
576	const char *existingDir = existingDirname;
577	const char *existingSuperDir = existingSuperDirname;
578	const char *existingFile = existingFilename;
579	const char *existingSuperFile = existingSuperFilename;
580	const char *nonExisting = nonExistingDirname;
581	BSymLink link;
582	BPath path;
583	// 1. MakeLinkedPath(const char*, BPath*)
584	// uninitialized
585	NextSubTest();
586	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
587	CPPUNIT_ASSERT( equals(link.MakeLinkedPath("/boot", &path), B_BAD_ADDRESS,
588						   B_FILE_ERROR) );
589	link.Unset();
590	path.Unset();
591	// existing absolute dir link
592	NextSubTest();
593	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
594	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
595					== (ssize_t)strlen(existingDir) );
596	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
597	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
598	link.Unset();
599	path.Unset();
600	// existing absolute file link
601	NextSubTest();
602	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
603	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
604					== (ssize_t)strlen(existingFile) );
605	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
606	CPPUNIT_ASSERT( string(existingFile) == path.Path() );
607	link.Unset();
608	path.Unset();
609	// existing absolute cyclic link
610	NextSubTest();
611	CPPUNIT_ASSERT( link.SetTo(cyclicLink1) == B_OK );
612	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", &path)
613					== (ssize_t)strlen(cyclicLink2) );
614	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
615	CPPUNIT_ASSERT( string(cyclicLink2) == path.Path() );
616	link.Unset();
617	path.Unset();
618	// existing relative dir link
619	NextSubTest();
620	BEntry entry;
621	BPath entryPath;
622	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
623	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
624	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
625	CPPUNIT_ASSERT( link.MakeLinkedPath(existingSuperDir, &path)
626					== (ssize_t)strlen(entryPath.Path()) );
627	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
628	CPPUNIT_ASSERT( entryPath == path );
629	link.Unset();
630	path.Unset();
631	entry.Unset();
632	entryPath.Unset();
633	// existing relative file link
634	NextSubTest();
635	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
636	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
637	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
638	CPPUNIT_ASSERT( link.MakeLinkedPath(existingSuperFile, &path)
639					== (ssize_t)strlen(entryPath.Path()) );
640	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
641	CPPUNIT_ASSERT( entryPath == path );
642	link.Unset();
643	path.Unset();
644	entry.Unset();
645	entryPath.Unset();
646	// bad args
647	NextSubTest();
648	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
649// R5: crashs, when passing a NULL path
650#if !TEST_R5
651	CPPUNIT_ASSERT( link.MakeLinkedPath("/boot", NULL) == B_BAD_VALUE );
652#endif
653	CPPUNIT_ASSERT( link.MakeLinkedPath((const char*)NULL, &path)
654					== B_BAD_VALUE );
655// R5: crashs, when passing a NULL path
656#if !TEST_R5
657	CPPUNIT_ASSERT( link.MakeLinkedPath((const char*)NULL, NULL)
658					== B_BAD_VALUE );
659#endif
660	link.Unset();
661	path.Unset();
662
663	// 2. MakeLinkedPath(const BDirectory*, BPath*)
664	// uninitialized
665	NextSubTest();
666	link.Unset();
667	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
668	BDirectory dir;
669	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
670	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_BAD_ADDRESS,
671						   B_FILE_ERROR) );
672	link.Unset();
673	path.Unset();
674	dir.Unset();
675	// existing absolute dir link
676	NextSubTest();
677	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
678	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
679	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
680					== (ssize_t)strlen(existingDir) );
681	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
682	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
683	link.Unset();
684	path.Unset();
685	dir.Unset();
686	// existing absolute file link
687	NextSubTest();
688	CPPUNIT_ASSERT( link.SetTo(fileLink) == B_OK );
689	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
690	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
691					== (ssize_t)strlen(existingFile) );
692	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
693	CPPUNIT_ASSERT( string(existingFile) == path.Path() );
694	link.Unset();
695	path.Unset();
696	dir.Unset();
697	// existing absolute cyclic link
698	NextSubTest();
699	CPPUNIT_ASSERT( link.SetTo(cyclicLink1) == B_OK );
700	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
701	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
702					== (ssize_t)strlen(cyclicLink2) );
703	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
704	CPPUNIT_ASSERT( string(cyclicLink2) == path.Path() );
705	link.Unset();
706	path.Unset();
707	dir.Unset();
708	// existing relative dir link
709	NextSubTest();
710	CPPUNIT_ASSERT( entry.SetTo(existingDir) == B_OK );
711	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
712	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
713	CPPUNIT_ASSERT( dir.SetTo(existingSuperDir) == B_OK);
714	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
715					== (ssize_t)strlen(entryPath.Path()) );
716	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
717	CPPUNIT_ASSERT( entryPath == path );
718	link.Unset();
719	path.Unset();
720	dir.Unset();
721	entry.Unset();
722	entryPath.Unset();
723	// existing relative file link
724	NextSubTest();
725	CPPUNIT_ASSERT( entry.SetTo(existingFile) == B_OK );
726	CPPUNIT_ASSERT( entry.GetPath(&entryPath) == B_OK );
727	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
728	CPPUNIT_ASSERT( dir.SetTo(existingSuperFile) == B_OK);
729	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
730					== (ssize_t)strlen(entryPath.Path()) );
731	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
732	CPPUNIT_ASSERT( entryPath == path );
733	link.Unset();
734	path.Unset();
735	dir.Unset();
736	entry.Unset();
737	entryPath.Unset();
738	// absolute link, uninitialized dir
739	NextSubTest();
740	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
741	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT);
742	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
743					== (ssize_t)strlen(existingDir) );
744	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
745	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
746	// absolute link, badly initialized dir
747	NextSubTest();
748	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
749	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND);
750	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, &path)
751					== (ssize_t)strlen(existingDir) );
752	CPPUNIT_ASSERT( path.InitCheck() == B_OK );
753	CPPUNIT_ASSERT( string(existingDir) == path.Path() );
754	link.Unset();
755	path.Unset();
756	dir.Unset();
757	// relative link, uninitialized dir
758	NextSubTest();
759	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
760	CPPUNIT_ASSERT( dir.InitCheck() == B_NO_INIT);
761	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_NO_INIT,
762						   B_BAD_VALUE) );
763	link.Unset();
764	// relative link, badly initialized dir
765	NextSubTest();
766	CPPUNIT_ASSERT( link.SetTo(relDirLink) == B_OK );
767	CPPUNIT_ASSERT( dir.SetTo(nonExisting) == B_ENTRY_NOT_FOUND);
768	CPPUNIT_ASSERT( equals(link.MakeLinkedPath(&dir, &path), B_NO_INIT,
769						   B_BAD_VALUE) );
770	link.Unset();
771	path.Unset();
772	dir.Unset();
773	// bad args
774	NextSubTest();
775	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
776	CPPUNIT_ASSERT( dir.SetTo("/boot") == B_OK);
777// R5: crashs, when passing a NULL path
778#if !TEST_R5
779	CPPUNIT_ASSERT( link.MakeLinkedPath(&dir, NULL) == B_BAD_VALUE );
780#endif
781
782	CPPUNIT_ASSERT( link.MakeLinkedPath((const BDirectory*)NULL, &path)
783					== B_BAD_VALUE );
784// R5: crashs, when passing a NULL path
785#if !TEST_R5
786	CPPUNIT_ASSERT( link.MakeLinkedPath((const BDirectory*)NULL, NULL)
787					== B_BAD_VALUE );
788#endif
789	link.Unset();
790	path.Unset();
791	dir.Unset();
792}
793
794// IsAbsoluteTest
795void
796SymLinkTest::IsAbsoluteTest()
797{
798	const char *dirLink = dirLinkname;
799	const char *relFileLink = relFileLinkname;
800	const char *existingDir = existingDirname;
801	const char *existingFile = existingFilename;
802	const char *nonExisting = nonExistingDirname;
803	BSymLink link;
804	// uninitialized
805	NextSubTest();
806	CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
807	CPPUNIT_ASSERT( link.IsAbsolute() == false );
808	link.Unset();
809	// existing absolute dir link
810	NextSubTest();
811	CPPUNIT_ASSERT( link.SetTo(dirLink) == B_OK );
812	CPPUNIT_ASSERT( link.IsAbsolute() == true );
813	link.Unset();
814	// existing relative file link
815	NextSubTest();
816	CPPUNIT_ASSERT( link.SetTo(relFileLink) == B_OK );
817	CPPUNIT_ASSERT( link.IsAbsolute() == false );
818	link.Unset();
819	// non-existing link
820	NextSubTest();
821	CPPUNIT_ASSERT( link.SetTo(nonExisting) == B_ENTRY_NOT_FOUND );
822	CPPUNIT_ASSERT( link.IsAbsolute() == false );
823	link.Unset();
824	// dir
825	NextSubTest();
826	CPPUNIT_ASSERT( link.SetTo(existingDir) == B_OK );
827	CPPUNIT_ASSERT( link.IsAbsolute() == false );
828	link.Unset();
829	// file
830	NextSubTest();
831	CPPUNIT_ASSERT( link.SetTo(existingFile) == B_OK );
832	CPPUNIT_ASSERT( link.IsAbsolute() == false );
833	link.Unset();
834}
835
836// AssignmentTest
837void
838SymLinkTest::AssignmentTest()
839{
840	const char *dirLink = dirLinkname;
841	const char *fileLink = fileLinkname;
842	// 1. copy constructor
843	// uninitialized
844	NextSubTest();
845	{
846		BSymLink link;
847		CPPUNIT_ASSERT( link.InitCheck() == B_NO_INIT );
848		BSymLink link2(link);
849		// R5 returns B_BAD_VALUE instead of B_NO_INIT
850		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
851	}
852	// existing dir link
853	NextSubTest();
854	{
855		BSymLink link(dirLink);
856		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
857		BSymLink link2(link);
858		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
859	}
860	// existing file link
861	NextSubTest();
862	{
863		BSymLink link(fileLink);
864		CPPUNIT_ASSERT( link.InitCheck() == B_OK );
865		BSymLink link2(link);
866		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
867	}
868
869	// 2. assignment operator
870	// uninitialized
871	NextSubTest();
872	{
873		BSymLink link;
874		BSymLink link2;
875		link2 = link;
876		// R5 returns B_BAD_VALUE instead of B_NO_INIT
877		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
878	}
879	NextSubTest();
880	{
881		BSymLink link;
882		BSymLink link2(dirLink);
883		link2 = link;
884		// R5 returns B_BAD_VALUE instead of B_NO_INIT
885		CPPUNIT_ASSERT( equals(link2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
886	}
887	// existing dir link
888	NextSubTest();
889	{
890		BSymLink link(dirLink);
891		BSymLink link2;
892		link2 = link;
893		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
894	}
895	// existing file link
896	NextSubTest();
897	{
898		BSymLink link(fileLink);
899		BSymLink link2;
900		link2 = link;
901		CPPUNIT_ASSERT( link2.InitCheck() == B_OK );
902	}
903}
904
905