1// FileTest.cpp
2
3#include <Directory.h>
4#include <Entry.h>
5#include <File.h>
6#include <Path.h>
7
8#include <cppunit/TestCaller.h>
9#include <cppunit/TestSuite.h>
10#include <TestShell.h>
11
12#include "FileTest.h"
13
14// Suite
15FileTest::Test*
16FileTest::Suite()
17{
18	CppUnit::TestSuite *suite = new CppUnit::TestSuite();
19	typedef CppUnit::TestCaller<FileTest> TC;
20
21	NodeTest::AddBaseClassTests<FileTest>("BFile::", suite);
22
23	suite->addTest( new TC("BFile::Init Test 1", &FileTest::InitTest1) );
24	suite->addTest( new TC("BFile::Init Test 2", &FileTest::InitTest2) );
25	suite->addTest( new TC("BFile::IsRead-/IsWriteable Test",
26						   &FileTest::RWAbleTest) );
27	suite->addTest( new TC("BFile::Read/Write Test", &FileTest::RWTest) );
28	suite->addTest( new TC("BFile::Position Test", &FileTest::PositionTest) );
29	suite->addTest( new TC("BFile::Size Test", &FileTest::SizeTest) );
30	suite->addTest( new TC("BFile::Assignment Test",
31						   &FileTest::AssignmentTest) );
32	return suite;
33}
34
35// CreateRONodes
36void
37FileTest::CreateRONodes(TestNodes& testEntries)
38{
39	testEntries.clear();
40	const char *filename;
41	filename = existingFilename;
42	testEntries.add(new BFile(filename, B_READ_ONLY), filename);
43}
44
45// CreateRWNodes
46void
47FileTest::CreateRWNodes(TestNodes& testEntries)
48{
49	testEntries.clear();
50	const char *filename;
51	filename = existingFilename;
52	testEntries.add(new BFile(filename, B_READ_WRITE), filename);
53}
54
55// CreateUninitializedNodes
56void
57FileTest::CreateUninitializedNodes(TestNodes& testEntries)
58{
59	testEntries.clear();
60	testEntries.add(new BFile, "");
61}
62
63// setUp
64void FileTest::setUp()
65{
66	NodeTest::setUp();
67}
68
69// tearDown
70void FileTest::tearDown()
71{
72	NodeTest::tearDown();
73}
74
75// InitTest1
76void
77FileTest::InitTest1()
78{
79	// 1. default constructor
80	{
81		BFile file;
82		CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
83	}
84
85	// helper class for the testing the different constructors versions
86	struct Tester {
87		void testAll() const
88		{
89			for (int32 i = 0; i < initTestCasesCount; i++) {
90				if (BTestShell::GlobalBeVerbose()) {
91					printf("[%" B_PRId32 "]", i);
92					fflush(stdout);
93				}
94				test(initTestCases[i]);
95			}
96			if (BTestShell::GlobalBeVerbose())
97				printf("\n");
98		}
99
100		virtual void test(const InitTestCase& tc) const = 0;
101
102		static void testInit(const InitTestCase& tc, BFile& file)
103		{
104			CPPUNIT_ASSERT( file.InitCheck() == tc.initCheck );
105			if (tc.removeAfterTest)
106				execCommand(string("rm ") + tc.filename);
107		}
108	};
109
110	// 2. BFile(const char *, uint32)
111	struct Tester1 : public Tester {
112		virtual void test(const InitTestCase& tc) const
113		{
114			BFile file(tc.filename,
115					   tc.rwmode
116					   | (tc.createFile * B_CREATE_FILE)
117					   | (tc.failIfExists * B_FAIL_IF_EXISTS)
118					   | (tc.eraseFile * B_ERASE_FILE));
119			testInit(tc, file);
120		}
121	};
122
123	// 3. BFile(entry_ref *, uint32)
124	struct Tester2 : public Tester {
125		virtual void test(const InitTestCase& tc) const
126		{
127			entry_ref ref;
128			BEntry entry(tc.filename);
129			entry_ref *refToPass = &ref;
130			if (tc.filename)
131				CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
132			else
133				refToPass = NULL;
134			BFile file(refToPass,
135					   tc.rwmode
136					   | (tc.createFile * B_CREATE_FILE)
137					   | (tc.failIfExists * B_FAIL_IF_EXISTS)
138					   | (tc.eraseFile * B_ERASE_FILE));
139			testInit(tc, file);
140		}
141	};
142
143	// 4. BFile(BEntry *, uint32)
144	struct Tester3 : public Tester {
145		virtual void test(const InitTestCase& tc) const
146		{
147			entry_ref ref;
148			BEntry entry(tc.filename);
149			BEntry *entryToPass = &entry;
150			if (tc.filename)
151				CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
152			else
153				entryToPass = NULL;
154			BFile file(entryToPass,
155					   tc.rwmode
156					   | (tc.createFile * B_CREATE_FILE)
157					   | (tc.failIfExists * B_FAIL_IF_EXISTS)
158					   | (tc.eraseFile * B_ERASE_FILE));
159			testInit(tc, file);
160		}
161	};
162
163	// 5. BFile(BEntry *, uint32)
164	struct Tester4 : public Tester {
165		virtual void test(const InitTestCase& tc) const
166		{
167			if (tc.filename) {
168				BPath path(tc.filename);
169				CPPUNIT_ASSERT( path.InitCheck() == B_OK );
170				BPath dirPath;
171				CPPUNIT_ASSERT( path.GetParent(&dirPath) == B_OK );
172				BDirectory dir(dirPath.Path());
173				CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
174				BFile file(&dir, path.Leaf(),
175						   tc.rwmode
176						   | (tc.createFile * B_CREATE_FILE)
177						   | (tc.failIfExists * B_FAIL_IF_EXISTS)
178						   | (tc.eraseFile * B_ERASE_FILE));
179				testInit(tc, file);
180			}
181		}
182	};
183
184	Tester1().testAll();
185	Tester2().testAll();
186	Tester3().testAll();
187	Tester4().testAll();
188}
189
190// InitTest2
191void
192FileTest::InitTest2()
193{
194	// helper class for the testing the different SetTo() versions
195	struct Tester {
196		void testAll() const
197		{
198			for (int32 i = 0; i < initTestCasesCount; i++) {
199				if (BTestShell::GlobalBeVerbose()) {
200					printf("[%" B_PRId32 "]", i);
201					fflush(stdout);
202				}
203				test(initTestCases[i]);
204			}
205			if (BTestShell::GlobalBeVerbose())
206				printf("\n");
207		}
208
209		virtual void test(const InitTestCase& tc) const = 0;
210
211		static void testInit(const InitTestCase& tc, BFile& file)
212		{
213			CPPUNIT_ASSERT( file.InitCheck() == tc.initCheck );
214			file.Unset();
215			CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
216			if (tc.removeAfterTest)
217				execCommand(string("rm ") + tc.filename);
218		}
219	};
220
221	// 2. BFile(const char *, uint32)
222	struct Tester1 : public Tester {
223		virtual void test(const InitTestCase& tc) const
224		{
225			BFile file;
226			status_t result = file.SetTo(tc.filename,
227				tc.rwmode
228				| (tc.createFile * B_CREATE_FILE)
229				| (tc.failIfExists * B_FAIL_IF_EXISTS)
230				| (tc.eraseFile * B_ERASE_FILE));
231			CPPUNIT_ASSERT( result == tc.initCheck );
232			testInit(tc, file);
233		}
234	};
235
236	// 3. BFile(entry_ref *, uint32)
237	struct Tester2 : public Tester {
238		virtual void test(const InitTestCase& tc) const
239		{
240			entry_ref ref;
241			BEntry entry(tc.filename);
242			entry_ref *refToPass = &ref;
243			if (tc.filename)
244				CPPUNIT_ASSERT( entry.GetRef(&ref) == B_OK );
245			else
246				refToPass = NULL;
247			BFile file;
248			status_t result = file.SetTo(refToPass,
249				tc.rwmode
250				| (tc.createFile * B_CREATE_FILE)
251				| (tc.failIfExists * B_FAIL_IF_EXISTS)
252				| (tc.eraseFile * B_ERASE_FILE));
253			CPPUNIT_ASSERT( result == tc.initCheck );
254			testInit(tc, file);
255		}
256	};
257
258	// 4. BFile(BEntry *, uint32)
259	struct Tester3 : public Tester {
260		virtual void test(const InitTestCase& tc) const
261		{
262			entry_ref ref;
263			BEntry entry(tc.filename);
264			BEntry *entryToPass = &entry;
265			if (tc.filename)
266				CPPUNIT_ASSERT( entry.InitCheck() == B_OK );
267			else
268				entryToPass = NULL;
269			BFile file;
270			status_t result = file.SetTo(entryToPass,
271				tc.rwmode
272				| (tc.createFile * B_CREATE_FILE)
273				| (tc.failIfExists * B_FAIL_IF_EXISTS)
274				| (tc.eraseFile * B_ERASE_FILE));
275			CPPUNIT_ASSERT( result == tc.initCheck );
276			testInit(tc, file);
277		}
278	};
279
280	// 5. BFile(BEntry *, uint32)
281	struct Tester4 : public Tester {
282		virtual void test(const InitTestCase& tc) const
283		{
284			if (tc.filename) {
285				BPath path(tc.filename);
286				CPPUNIT_ASSERT( path.InitCheck() == B_OK );
287				BPath dirPath;
288				CPPUNIT_ASSERT( path.GetParent(&dirPath) == B_OK );
289				BDirectory dir(dirPath.Path());
290				CPPUNIT_ASSERT( dir.InitCheck() == B_OK );
291				BFile file;
292				status_t result = file.SetTo(&dir, path.Leaf(),
293					tc.rwmode
294					| (tc.createFile * B_CREATE_FILE)
295					| (tc.failIfExists * B_FAIL_IF_EXISTS)
296					| (tc.eraseFile * B_ERASE_FILE));
297				CPPUNIT_ASSERT( result == tc.initCheck );
298				testInit(tc, file);
299			}
300		}
301	};
302
303	Tester1().testAll();
304	Tester2().testAll();
305	Tester3().testAll();
306	Tester4().testAll();
307}
308
309// RWAbleTest
310void
311FileTest::RWAbleTest()
312{
313	NextSubTest();
314	{
315		BFile file;
316		CPPUNIT_ASSERT( file.IsReadable() == false );
317		CPPUNIT_ASSERT( file.IsWritable() == false );
318	}
319	NextSubTest();
320	{
321		BFile file(existingFilename, B_READ_ONLY);
322		CPPUNIT_ASSERT( file.IsReadable() == true );
323		CPPUNIT_ASSERT( file.IsWritable() == false );
324	}
325	NextSubTest();
326	{
327		BFile file(existingFilename, B_WRITE_ONLY);
328		CPPUNIT_ASSERT( file.IsReadable() == false );
329		CPPUNIT_ASSERT( file.IsWritable() == true );
330	}
331	NextSubTest();
332	{
333		BFile file(existingFilename, B_READ_WRITE);
334		CPPUNIT_ASSERT( file.IsReadable() == true );
335		CPPUNIT_ASSERT( file.IsWritable() == true );
336	}
337	NextSubTest();
338	{
339		BFile file(nonExistingFilename, B_READ_WRITE);
340		CPPUNIT_ASSERT( file.IsReadable() == false );
341		CPPUNIT_ASSERT( file.IsWritable() == false );
342	}
343}
344
345// RWTest
346void
347FileTest::RWTest()
348{
349	// read/write an uninitialized BFile
350	NextSubTest();
351	BFile file;
352	char buffer[10];
353	CPPUNIT_ASSERT( file.Read(buffer, sizeof(buffer)) < 0 );
354	CPPUNIT_ASSERT( file.ReadAt(0, buffer, sizeof(buffer)) < 0 );
355	CPPUNIT_ASSERT( file.Write(buffer, sizeof(buffer)) < 0 );
356	CPPUNIT_ASSERT( file.WriteAt(0, buffer, sizeof(buffer)) < 0 );
357	file.Unset();
358	// read/write an file opened for writing/reading only
359	NextSubTest();
360	file.SetTo(existingFilename, B_WRITE_ONLY);
361	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
362	CPPUNIT_ASSERT( file.Read(buffer, sizeof(buffer)) < 0 );
363	CPPUNIT_ASSERT( file.ReadAt(0, buffer, sizeof(buffer)) < 0 );
364	file.SetTo(existingFilename, B_READ_ONLY);
365	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
366	CPPUNIT_ASSERT( file.Write(buffer, sizeof(buffer)) < 0 );
367	CPPUNIT_ASSERT( file.WriteAt(0, buffer, sizeof(buffer)) < 0 );
368	file.Unset();
369	// read from an empty file
370	NextSubTest();
371	file.SetTo(existingFilename, B_READ_ONLY);
372	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
373	CPPUNIT_ASSERT( file.Read(buffer, sizeof(buffer)) == 0 );
374	CPPUNIT_ASSERT( file.ReadAt(0, buffer, sizeof(buffer)) == 0 );
375	file.Unset();
376	// read from past an empty file
377	NextSubTest();
378	file.SetTo(existingFilename, B_READ_ONLY);
379	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
380	CPPUNIT_ASSERT( file.Seek(10, SEEK_SET) == 10 );
381	CPPUNIT_ASSERT( file.Read(buffer, sizeof(buffer)) == 0 );
382	CPPUNIT_ASSERT( file.ReadAt(10, buffer, sizeof(buffer)) == 0 );
383	file.Unset();
384	// create a new empty file and write some data into it, then
385	// read the file and check the data
386	NextSubTest();
387	file.SetTo(testFilename1, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
388	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
389	char writeBuffer[256];
390	for (int32 i = 0; i < 256; i++)
391		writeBuffer[i] = (char)i;
392	CPPUNIT_ASSERT( file.Write(writeBuffer, 128) == 128 );
393	CPPUNIT_ASSERT( file.Position() == 128 );
394	CPPUNIT_ASSERT( file.Write(writeBuffer + 128, 128) == 128 );
395	CPPUNIT_ASSERT( file.Position() == 256 );
396	file.Unset();
397	file.SetTo(testFilename1, B_READ_ONLY);
398	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
399	char readBuffer[256];
400	CPPUNIT_ASSERT( file.Read(readBuffer, 42) == 42 );
401	CPPUNIT_ASSERT( file.Position() == 42 );
402	CPPUNIT_ASSERT( file.Read(readBuffer + 42, 400) == 214 );
403	CPPUNIT_ASSERT( file.Position() == 256 );
404	for (int32 i = 0; i < 256; i++)
405		CPPUNIT_ASSERT( readBuffer[i] == (char)i );
406	file.Unset();
407	execCommand(string("rm -f ") + testFilename1);
408	// same procedure, just using ReadAt()/WriteAt()
409	NextSubTest();
410	file.SetTo(testFilename1, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
411	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
412	CPPUNIT_ASSERT( file.WriteAt(80, writeBuffer + 80, 50) == 50 );
413	CPPUNIT_ASSERT( file.Position() == 0 );
414	CPPUNIT_ASSERT( file.WriteAt(0, writeBuffer, 80) == 80 );
415	CPPUNIT_ASSERT( file.Position() == 0 );
416	CPPUNIT_ASSERT( file.WriteAt(130, writeBuffer + 130, 126) == 126 );
417	CPPUNIT_ASSERT( file.Position() == 0 );
418	file.Unset();
419	file.SetTo(testFilename1, B_READ_ONLY);
420	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
421	for (int32 i = 0; i < 256; i++)
422		readBuffer[i] = 0;
423	CPPUNIT_ASSERT( file.ReadAt(42, readBuffer + 42, 84) == 84 );
424	CPPUNIT_ASSERT( file.Position() == 0 );
425	CPPUNIT_ASSERT( file.ReadAt(0, readBuffer, 42) == 42 );
426	CPPUNIT_ASSERT( file.Position() == 0 );
427	CPPUNIT_ASSERT( file.ReadAt(126, readBuffer + 126, 130) == 130 );
428	CPPUNIT_ASSERT( file.Position() == 0 );
429	for (int32 i = 0; i < 256; i++)
430		CPPUNIT_ASSERT( readBuffer[i] == (char)i );
431	file.Unset();
432	execCommand(string("rm -f ") + testFilename1);
433	// write past the end of a file
434	NextSubTest();
435	file.SetTo(testFilename1, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
436	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
437	CPPUNIT_ASSERT( file.Seek(128, SEEK_SET) == 128 );
438	CPPUNIT_ASSERT( file.Write(writeBuffer, 128) == 128 );
439	CPPUNIT_ASSERT( file.Position() == 256 );
440	file.Unset();
441	// open the file with B_OPEN_AT_END flag, Write() some data to it, close
442	// and re-open it to check the file
443	NextSubTest();
444	file.SetTo(testFilename1, B_WRITE_ONLY | B_OPEN_AT_END);
445	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
446	for (int32 i = 0; i < 256; i++)
447		writeBuffer[i] = (char)7;
448	CPPUNIT_ASSERT( file.Write(writeBuffer, 50) == 50 );
449	file.Seek(0, SEEK_SET);	// might fail -- don't check the return value
450	CPPUNIT_ASSERT( file.Write(writeBuffer, 40) == 40 );
451	file.Unset();
452	file.SetTo(testFilename1, B_READ_ONLY);
453	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
454	CPPUNIT_ASSERT( file.ReadAt(256, readBuffer, 90) == 90 );
455	for (int32 i = 0; i < 90; i++)
456		CPPUNIT_ASSERT( readBuffer[i] == 7 );
457	file.Unset();
458	// open the file with B_OPEN_AT_END flag, WriteAt() some data to it, close
459	// and re-open it to check the file
460	NextSubTest();
461	file.SetTo(testFilename1, B_WRITE_ONLY | B_OPEN_AT_END);
462	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
463	for (int32 i = 0; i < 256; i++)
464		writeBuffer[i] = (char)42;
465	CPPUNIT_ASSERT( file.WriteAt(0, writeBuffer, 30) == 30 );
466	file.Unset();
467	file.SetTo(testFilename1, B_READ_ONLY);
468	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
469	CPPUNIT_ASSERT( file.ReadAt(346, readBuffer, 30) == 30 );
470	for (int32 i = 0; i < 30; i++)
471		CPPUNIT_ASSERT( readBuffer[i] == 42 );
472	file.Unset();
473	// open the file with B_OPEN_AT_END flag, ReadAt() some data
474	NextSubTest();
475	file.SetTo(testFilename1, B_READ_ONLY | B_OPEN_AT_END);
476	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
477	for (int32 i = 0; i < 256; i++)
478		readBuffer[i] = 0;
479	CPPUNIT_ASSERT( file.ReadAt(256, readBuffer, 90) == 90 );
480	for (int32 i = 0; i < 90; i++)
481		CPPUNIT_ASSERT( readBuffer[i] == 7 );
482	CPPUNIT_ASSERT( file.ReadAt(346, readBuffer, 30) == 30 );
483	for (int32 i = 0; i < 30; i++)
484		CPPUNIT_ASSERT( readBuffer[i] == 42 );
485	file.Unset();
486	// same procedure, just using Seek() and Read()
487	NextSubTest();
488	file.SetTo(testFilename1, B_READ_ONLY | B_OPEN_AT_END);
489	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
490	for (int32 i = 0; i < 256; i++)
491		readBuffer[i] = 0;
492	file.Seek(256, SEEK_SET);	// might fail -- don't check the return value
493	CPPUNIT_ASSERT( file.Read(readBuffer, 90) == 90 );
494	for (int32 i = 0; i < 90; i++)
495		CPPUNIT_ASSERT( readBuffer[i] == 7 );
496	CPPUNIT_ASSERT( file.ReadAt(346, readBuffer, 30) == 30 );
497	for (int32 i = 0; i < 30; i++)
498		CPPUNIT_ASSERT( readBuffer[i] == 42 );
499	file.Unset();
500
501	execCommand(string("rm -f ") + testFilename1);
502}
503
504// PositionTest
505void
506FileTest::PositionTest()
507{
508	// unitialized file
509	NextSubTest();
510	BFile file;
511	CPPUNIT_ASSERT( file.Position() == B_FILE_ERROR );
512	CPPUNIT_ASSERT( file.Seek(10, SEEK_SET) == B_FILE_ERROR );
513	CPPUNIT_ASSERT( file.Seek(10, SEEK_END) == B_FILE_ERROR );
514	CPPUNIT_ASSERT( file.Seek(10, SEEK_CUR) == B_FILE_ERROR );
515	// open new file, write some bytes to it and seek a bit around
516	NextSubTest();
517	file.SetTo(testFilename1, B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
518	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
519	CPPUNIT_ASSERT( file.Position() == 0 );
520	char writeBuffer[256];
521	CPPUNIT_ASSERT( file.Write(writeBuffer, 256) == 256 );
522	CPPUNIT_ASSERT( file.Position() == 256 );
523	CPPUNIT_ASSERT( file.Seek(10, SEEK_SET) == 10 );
524	CPPUNIT_ASSERT( file.Position() == 10 );
525	CPPUNIT_ASSERT( file.Seek(-20, SEEK_END) == 236 );
526	CPPUNIT_ASSERT( file.Position() == 236 );
527	CPPUNIT_ASSERT( file.Seek(-70, SEEK_CUR) == 166 );
528	CPPUNIT_ASSERT( file.Position() == 166 );
529	file.Unset();
530	// re-open the file at the end and seek a bit around once more
531	// The BeBook is a bit unspecific about the B_OPEN_AT_END flag:
532	// It has probably the same meaning as the POSIX flag O_APPEND, which
533	// means, that all write()s append their data at the end. The behavior
534	// of Seek() and Position() is a bit unclear for this case.
535/*
536	NextSubTest();
537	file.SetTo(testFilename1, B_READ_ONLY | B_OPEN_AT_END);
538	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
539	CPPUNIT_ASSERT( file.Position() == 256 );
540	CPPUNIT_ASSERT( file.Seek(10, SEEK_SET) == 10 );
541	CPPUNIT_ASSERT( file.Position() == 10 );			// fails with R5
542	CPPUNIT_ASSERT( file.Seek(-20, SEEK_END) == 236 );
543	CPPUNIT_ASSERT( file.Position() == 236 );			// fails with R5
544	CPPUNIT_ASSERT( file.Seek(-70, SEEK_CUR) == 166 );	// fails with R5
545	CPPUNIT_ASSERT( file.Position() == 166 );			// fails with R5
546*/
547	file.Unset();
548	execCommand(string("rm -f ") + testFilename1);
549}
550
551// SizeTest
552void
553FileTest::SizeTest()
554{
555	// unitialized file
556	NextSubTest();
557	BFile file;
558	off_t size;
559	CPPUNIT_ASSERT( file.GetSize(&size) != B_OK );
560	CPPUNIT_ASSERT( file.SetSize(100) != B_OK );
561	// read only file, SetSize will not succeed
562	NextSubTest();
563	file.SetTo(testFilename1, B_READ_ONLY | B_CREATE_FILE);
564	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
565	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
566	CPPUNIT_ASSERT( size == 0 );
567	CPPUNIT_ASSERT_EQUAL(file.SetSize(100), B_BAD_VALUE);
568	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
569	CPPUNIT_ASSERT_EQUAL(size, 0);
570	file.Unset();
571	// successfully set size of file with appropriate flags
572	NextSubTest();
573	file.SetTo(testFilename1, B_WRITE_ONLY);
574	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
575	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
576	CPPUNIT_ASSERT_EQUAL(size, 0);
577	CPPUNIT_ASSERT( file.SetSize(73) == B_OK );
578	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
579	CPPUNIT_ASSERT( size == 73 );
580	file.Unset();
581	// enlarge existing file
582	NextSubTest();
583	file.SetTo(testFilename1, B_READ_WRITE);
584	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
585	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
586	CPPUNIT_ASSERT( size == 73 );
587	CPPUNIT_ASSERT( file.SetSize(147) == B_OK );
588	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
589	CPPUNIT_ASSERT( size == 147 );
590	file.Unset();
591	// erase existing file (write only)
592	NextSubTest();
593	file.SetTo(testFilename1, B_WRITE_ONLY | B_ERASE_FILE);
594	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
595	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
596	CPPUNIT_ASSERT( size == 0 );
597	CPPUNIT_ASSERT( file.SetSize(93) == B_OK );
598	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
599	CPPUNIT_ASSERT( size == 93 );
600	file.Unset();
601	// erase existing file using SetSize()
602	NextSubTest();
603	file.SetTo(testFilename1, B_READ_WRITE);
604	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
605	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
606	CPPUNIT_ASSERT( size == 93 );
607	CPPUNIT_ASSERT( file.SetSize(0) == B_OK );
608	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
609	CPPUNIT_ASSERT( size == 0 );
610	file.Unset();
611	execCommand(string("rm -f ") + testFilename1);
612}
613
614// AssignmentTest
615void
616FileTest::AssignmentTest()
617{
618	// copy constructor
619	// uninitialized
620	NextSubTest();
621	{
622		BFile file;
623		CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
624		BFile file2(file);
625		// R5 returns B_BAD_VALUE instead of B_NO_INIT
626		CPPUNIT_ASSERT( equals(file2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
627	}
628	// existing file, different open modes
629	NextSubTest();
630	{
631		BFile file(existingFilename, B_READ_ONLY);
632		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
633		BFile file2(file);
634		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
635		CPPUNIT_ASSERT( file2.IsReadable() == true );
636		CPPUNIT_ASSERT( file2.IsWritable() == false );
637	}
638	NextSubTest();
639	{
640		BFile file(existingFilename, B_WRITE_ONLY);
641		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
642		BFile file2(file);
643		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
644		CPPUNIT_ASSERT( file2.IsReadable() == false );
645		CPPUNIT_ASSERT( file2.IsWritable() == true );
646	}
647	NextSubTest();
648	{
649		BFile file(existingFilename, B_READ_WRITE);
650		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
651		BFile file2(file);
652		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
653		CPPUNIT_ASSERT( file2.IsReadable() == true );
654		CPPUNIT_ASSERT( file2.IsWritable() == true );
655	}
656	// assignment operator
657	// uninitialized
658	NextSubTest();
659	{
660		BFile file;
661		BFile file2;
662		file2 = file;
663		// R5 returns B_BAD_VALUE instead of B_NO_INIT
664		CPPUNIT_ASSERT( equals(file2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
665	}
666	NextSubTest();
667	{
668		BFile file;
669		BFile file2(existingFilename, B_READ_ONLY);
670		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
671		file2 = file;
672		// R5 returns B_BAD_VALUE instead of B_NO_INIT
673		CPPUNIT_ASSERT( equals(file2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
674	}
675	// existing file, different open modes
676	NextSubTest();
677	{
678		BFile file(existingFilename, B_READ_ONLY);
679		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
680		BFile file2;
681		file2 = file;
682		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
683		CPPUNIT_ASSERT( file2.IsReadable() == true );
684		CPPUNIT_ASSERT( file2.IsWritable() == false );
685	}
686	NextSubTest();
687	{
688		BFile file(existingFilename, B_WRITE_ONLY);
689		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
690		BFile file2;
691		file2 = file;
692		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
693		CPPUNIT_ASSERT( file2.IsReadable() == false );
694		CPPUNIT_ASSERT( file2.IsWritable() == true );
695	}
696	NextSubTest();
697	{
698		BFile file(existingFilename, B_READ_WRITE);
699		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
700		BFile file2;
701		file2 = file;
702		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
703		CPPUNIT_ASSERT( file2.IsReadable() == true );
704		CPPUNIT_ASSERT( file2.IsWritable() == true );
705	}
706}
707
708
709
710// test cases for the init tests
711const FileTest::InitTestCase FileTest::initTestCases[] = {
712	{ existingFilename	 , B_READ_ONLY , 0, 0, 0, false, B_OK				},
713	{ existingFilename	 , B_WRITE_ONLY, 0, 0, 0, false, B_OK				},
714	{ existingFilename	 , B_READ_WRITE, 0, 0, 0, false, B_OK				},
715	{ existingFilename	 , B_READ_ONLY , 1, 0, 0, false, B_OK				},
716	{ existingFilename	 , B_WRITE_ONLY, 1, 0, 0, false, B_OK				},
717	{ existingFilename	 , B_READ_WRITE, 1, 0, 0, false, B_OK				},
718	{ existingFilename	 , B_READ_ONLY , 0, 1, 0, false, B_OK				},
719	{ existingFilename	 , B_WRITE_ONLY, 0, 1, 0, false, B_OK				},
720	{ existingFilename	 , B_READ_WRITE, 0, 1, 0, false, B_OK				},
721	{ existingFilename	 , B_READ_ONLY , 0, 0, 1, false, B_NOT_ALLOWED		},
722	{ existingFilename	 , B_WRITE_ONLY, 0, 0, 1, false, B_OK				},
723	{ existingFilename	 , B_READ_WRITE, 0, 0, 1, false, B_OK				},
724	{ existingFilename	 , B_READ_ONLY , 1, 1, 0, false, B_FILE_EXISTS		},
725	{ existingFilename	 , B_WRITE_ONLY, 1, 1, 0, false, B_FILE_EXISTS		},
726	{ existingFilename	 , B_READ_WRITE, 1, 1, 0, false, B_FILE_EXISTS		},
727	{ existingFilename	 , B_READ_ONLY , 1, 0, 1, false, B_NOT_ALLOWED		},
728	{ existingFilename	 , B_WRITE_ONLY, 1, 0, 1, false, B_OK				},
729	{ existingFilename	 , B_READ_WRITE, 1, 0, 1, false, B_OK				},
730	{ existingFilename	 , B_READ_ONLY , 1, 1, 1, false, B_FILE_EXISTS		},
731	{ existingFilename	 , B_WRITE_ONLY, 1, 1, 1, false, B_FILE_EXISTS		},
732	{ existingFilename	 , B_READ_WRITE, 1, 1, 1, false, B_FILE_EXISTS		},
733	{ nonExistingFilename, B_READ_ONLY , 0, 0, 0, false, B_ENTRY_NOT_FOUND	},
734	{ nonExistingFilename, B_WRITE_ONLY, 0, 0, 0, false, B_ENTRY_NOT_FOUND	},
735	{ nonExistingFilename, B_READ_WRITE, 0, 0, 0, false, B_ENTRY_NOT_FOUND	},
736	{ nonExistingFilename, B_READ_ONLY , 1, 0, 0, true , B_OK				},
737	{ nonExistingFilename, B_WRITE_ONLY, 1, 0, 0, true , B_OK				},
738	{ nonExistingFilename, B_READ_WRITE, 1, 0, 0, true , B_OK				},
739	{ nonExistingFilename, B_READ_ONLY , 0, 1, 0, false, B_ENTRY_NOT_FOUND	},
740	{ nonExistingFilename, B_WRITE_ONLY, 0, 1, 0, false, B_ENTRY_NOT_FOUND	},
741	{ nonExistingFilename, B_READ_WRITE, 0, 1, 0, false, B_ENTRY_NOT_FOUND	},
742	{ nonExistingFilename, B_READ_ONLY , 0, 0, 1, false, B_ENTRY_NOT_FOUND	},
743	{ nonExistingFilename, B_WRITE_ONLY, 0, 0, 1, false, B_ENTRY_NOT_FOUND	},
744	{ nonExistingFilename, B_READ_WRITE, 0, 0, 1, false, B_ENTRY_NOT_FOUND	},
745	{ nonExistingFilename, B_READ_ONLY , 1, 1, 0, true , B_OK				},
746	{ nonExistingFilename, B_WRITE_ONLY, 1, 1, 0, true , B_OK				},
747	{ nonExistingFilename, B_READ_WRITE, 1, 1, 0, true , B_OK				},
748	{ nonExistingFilename, B_READ_ONLY , 1, 0, 1, true , B_OK				},
749	{ nonExistingFilename, B_WRITE_ONLY, 1, 0, 1, true , B_OK				},
750	{ nonExistingFilename, B_READ_WRITE, 1, 0, 1, true , B_OK				},
751	{ nonExistingFilename, B_READ_ONLY , 1, 1, 1, true , B_OK				},
752	{ nonExistingFilename, B_WRITE_ONLY, 1, 1, 1, true , B_OK				},
753	{ nonExistingFilename, B_READ_WRITE, 1, 1, 1, true , B_OK				},
754	{ NULL,				   B_READ_ONLY , 1, 1, 1, false, B_BAD_VALUE		},
755};
756const int32 FileTest::initTestCasesCount
757	= sizeof(FileTest::initTestCases) / sizeof(FileTest::InitTestCase);
758
759
760
761
762
763
764
765
766
767
768
769