xref: /haiku/src/tests/kits/storage/FileTest.cpp (revision 820dca4df6c7bf955c46e8f6521b9408f50b2900)
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
15 FileTest::Test*
16 FileTest::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
36 void
37 FileTest::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
46 void
47 FileTest::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
56 void
57 FileTest::CreateUninitializedNodes(TestNodes& testEntries)
58 {
59 	testEntries.clear();
60 	testEntries.add(new BFile, "");
61 }
62 
63 // setUp
64 void FileTest::setUp()
65 {
66 	NodeTest::setUp();
67 }
68 
69 // tearDown
70 void FileTest::tearDown()
71 {
72 	NodeTest::tearDown();
73 }
74 
75 // InitTest1
76 void
77 FileTest::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("[%ld]", 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
191 void
192 FileTest::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("[%ld]", 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
310 void
311 FileTest::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
346 void
347 FileTest::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
505 void
506 FileTest::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
552 void
553 FileTest::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
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( file.SetSize(100) == B_OK );
568 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
569 	CPPUNIT_ASSERT( size == 100 );
570 	file.Unset();
571 	// shorten existing file
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( size == 100 );
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 (read only)
592 	NextSubTest();
593 	file.SetTo(testFilename1, B_READ_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(132) == B_OK );
598 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
599 	CPPUNIT_ASSERT( size == 132 );
600 	file.Unset();
601 	// erase existing file (write only)
602 	NextSubTest();
603 	file.SetTo(testFilename1, B_WRITE_ONLY | B_ERASE_FILE);
604 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
605 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
606 	CPPUNIT_ASSERT( size == 0 );
607 	CPPUNIT_ASSERT( file.SetSize(93) == B_OK );
608 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
609 	CPPUNIT_ASSERT( size == 93 );
610 	file.Unset();
611 	// erase existing file using SetSize()
612 	NextSubTest();
613 	file.SetTo(testFilename1, B_READ_WRITE);
614 	CPPUNIT_ASSERT( file.InitCheck() == B_OK );
615 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
616 	CPPUNIT_ASSERT( size == 93 );
617 	CPPUNIT_ASSERT( file.SetSize(0) == B_OK );
618 	CPPUNIT_ASSERT( file.GetSize(&size) == B_OK );
619 	CPPUNIT_ASSERT( size == 0 );
620 	file.Unset();
621 	execCommand(string("rm -f ") + testFilename1);
622 }
623 
624 // AssignmentTest
625 void
626 FileTest::AssignmentTest()
627 {
628 	// copy constructor
629 	// uninitialized
630 	NextSubTest();
631 	{
632 		BFile file;
633 		CPPUNIT_ASSERT( file.InitCheck() == B_NO_INIT );
634 		BFile file2(file);
635 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
636 		CPPUNIT_ASSERT( equals(file2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
637 	}
638 	// existing file, different open modes
639 	NextSubTest();
640 	{
641 		BFile file(existingFilename, B_READ_ONLY);
642 		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
643 		BFile file2(file);
644 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
645 		CPPUNIT_ASSERT( file2.IsReadable() == true );
646 		CPPUNIT_ASSERT( file2.IsWritable() == false );
647 	}
648 	NextSubTest();
649 	{
650 		BFile file(existingFilename, B_WRITE_ONLY);
651 		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
652 		BFile file2(file);
653 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
654 		CPPUNIT_ASSERT( file2.IsReadable() == false );
655 		CPPUNIT_ASSERT( file2.IsWritable() == true );
656 	}
657 	NextSubTest();
658 	{
659 		BFile file(existingFilename, B_READ_WRITE);
660 		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
661 		BFile file2(file);
662 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
663 		CPPUNIT_ASSERT( file2.IsReadable() == true );
664 		CPPUNIT_ASSERT( file2.IsWritable() == true );
665 	}
666 	// assignment operator
667 	// uninitialized
668 	NextSubTest();
669 	{
670 		BFile file;
671 		BFile file2;
672 		file2 = file;
673 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
674 		CPPUNIT_ASSERT( equals(file2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
675 	}
676 	NextSubTest();
677 	{
678 		BFile file;
679 		BFile file2(existingFilename, B_READ_ONLY);
680 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
681 		file2 = file;
682 		// R5 returns B_BAD_VALUE instead of B_NO_INIT
683 		CPPUNIT_ASSERT( equals(file2.InitCheck(), B_BAD_VALUE, B_NO_INIT) );
684 	}
685 	// existing file, different open modes
686 	NextSubTest();
687 	{
688 		BFile file(existingFilename, B_READ_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() == true );
694 		CPPUNIT_ASSERT( file2.IsWritable() == false );
695 	}
696 	NextSubTest();
697 	{
698 		BFile file(existingFilename, B_WRITE_ONLY);
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() == false );
704 		CPPUNIT_ASSERT( file2.IsWritable() == true );
705 	}
706 	NextSubTest();
707 	{
708 		BFile file(existingFilename, B_READ_WRITE);
709 		CPPUNIT_ASSERT( file.InitCheck() == B_OK );
710 		BFile file2;
711 		file2 = file;
712 		CPPUNIT_ASSERT( file2.InitCheck() == B_OK );
713 		CPPUNIT_ASSERT( file2.IsReadable() == true );
714 		CPPUNIT_ASSERT( file2.IsWritable() == true );
715 	}
716 }
717 
718 
719 
720 // test cases for the init tests
721 const FileTest::InitTestCase FileTest::initTestCases[] = {
722 	{ existingFilename	 , B_READ_ONLY , 0, 0, 0, false, B_OK				},
723 	{ existingFilename	 , B_WRITE_ONLY, 0, 0, 0, false, B_OK				},
724 	{ existingFilename	 , B_READ_WRITE, 0, 0, 0, false, B_OK				},
725 	{ existingFilename	 , B_READ_ONLY , 1, 0, 0, false, B_OK				},
726 	{ existingFilename	 , B_WRITE_ONLY, 1, 0, 0, false, B_OK				},
727 	{ existingFilename	 , B_READ_WRITE, 1, 0, 0, false, B_OK				},
728 	{ existingFilename	 , B_READ_ONLY , 0, 1, 0, false, B_OK				},
729 	{ existingFilename	 , B_WRITE_ONLY, 0, 1, 0, false, B_OK				},
730 	{ existingFilename	 , B_READ_WRITE, 0, 1, 0, false, B_OK				},
731 	{ existingFilename	 , B_READ_ONLY , 0, 0, 1, false, B_OK				},
732 	{ existingFilename	 , B_WRITE_ONLY, 0, 0, 1, false, B_OK				},
733 	{ existingFilename	 , B_READ_WRITE, 0, 0, 1, false, B_OK				},
734 	{ existingFilename	 , B_READ_ONLY , 1, 1, 0, false, B_FILE_EXISTS		},
735 	{ existingFilename	 , B_WRITE_ONLY, 1, 1, 0, false, B_FILE_EXISTS		},
736 	{ existingFilename	 , B_READ_WRITE, 1, 1, 0, false, B_FILE_EXISTS		},
737 	{ existingFilename	 , B_READ_ONLY , 1, 0, 1, false, B_OK				},
738 	{ existingFilename	 , B_WRITE_ONLY, 1, 0, 1, false, B_OK				},
739 	{ existingFilename	 , B_READ_WRITE, 1, 0, 1, false, B_OK				},
740 	{ existingFilename	 , B_READ_ONLY , 1, 1, 1, false, B_FILE_EXISTS		},
741 	{ existingFilename	 , B_WRITE_ONLY, 1, 1, 1, false, B_FILE_EXISTS		},
742 	{ existingFilename	 , B_READ_WRITE, 1, 1, 1, false, B_FILE_EXISTS		},
743 	{ nonExistingFilename, B_READ_ONLY , 0, 0, 0, false, B_ENTRY_NOT_FOUND	},
744 	{ nonExistingFilename, B_WRITE_ONLY, 0, 0, 0, false, B_ENTRY_NOT_FOUND	},
745 	{ nonExistingFilename, B_READ_WRITE, 0, 0, 0, false, B_ENTRY_NOT_FOUND	},
746 	{ nonExistingFilename, B_READ_ONLY , 1, 0, 0, true , B_OK				},
747 	{ nonExistingFilename, B_WRITE_ONLY, 1, 0, 0, true , B_OK				},
748 	{ nonExistingFilename, B_READ_WRITE, 1, 0, 0, true , B_OK				},
749 	{ nonExistingFilename, B_READ_ONLY , 0, 1, 0, false, B_ENTRY_NOT_FOUND	},
750 	{ nonExistingFilename, B_WRITE_ONLY, 0, 1, 0, false, B_ENTRY_NOT_FOUND	},
751 	{ nonExistingFilename, B_READ_WRITE, 0, 1, 0, false, B_ENTRY_NOT_FOUND	},
752 	{ nonExistingFilename, B_READ_ONLY , 0, 0, 1, false, B_ENTRY_NOT_FOUND	},
753 	{ nonExistingFilename, B_WRITE_ONLY, 0, 0, 1, false, B_ENTRY_NOT_FOUND	},
754 	{ nonExistingFilename, B_READ_WRITE, 0, 0, 1, false, B_ENTRY_NOT_FOUND	},
755 	{ nonExistingFilename, B_READ_ONLY , 1, 1, 0, true , B_OK				},
756 	{ nonExistingFilename, B_WRITE_ONLY, 1, 1, 0, true , B_OK				},
757 	{ nonExistingFilename, B_READ_WRITE, 1, 1, 0, true , B_OK				},
758 	{ nonExistingFilename, B_READ_ONLY , 1, 0, 1, true , B_OK				},
759 	{ nonExistingFilename, B_WRITE_ONLY, 1, 0, 1, true , B_OK				},
760 	{ nonExistingFilename, B_READ_WRITE, 1, 0, 1, true , B_OK				},
761 	{ nonExistingFilename, B_READ_ONLY , 1, 1, 1, true , B_OK				},
762 	{ nonExistingFilename, B_WRITE_ONLY, 1, 1, 1, true , B_OK				},
763 	{ nonExistingFilename, B_READ_WRITE, 1, 1, 1, true , B_OK				},
764 	{ NULL,				   B_READ_ONLY , 1, 1, 1, false, B_BAD_VALUE		},
765 };
766 const int32 FileTest::initTestCasesCount
767 	= sizeof(FileTest::initTestCases) / sizeof(FileTest::InitTestCase);
768 
769 
770 
771 
772 
773 
774 
775 
776 
777 
778 
779