Update contrib.
1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // Implementation of the t_localtime test. This tests functionality introduced
15 // in CR1084 ie. That removable (in practice this means FAT) file systems
16 // can be made to use local time for timestamps.
24 #define __E32TEST_EXTENSION__
27 #include "t_localtime.h"
30 RTest test(KTestGroupName);
33 Constructor for generic test.
34 @param aTest The RTest handle to use.
35 @param aDriveLetter The drive to be tested.
36 @param aBuild Specifies whether tests or being run under UDEB or UREL
38 CLocalTimeTest::CLocalTimeTest(RTest& aTest, const TDesC& aDriveLetter, TBuild aBuild)
39 :iDriveLetter(aDriveLetter), iTest(aTest), iBuild(aBuild), iOriginalUseLocalTimeFlag(EFalse)
45 Factory function for test.
46 @param aTest The RTest handle to use.
47 @param aDriveLetter The drive to be tested.
48 @param aBuild Specifies whether tests or being run under UDEB or UREL
51 CLocalTimeTest* CLocalTimeTest::NewLC(RTest& aTest, const TDesC& aDriveLetter, TBuild aBuild)
53 CLocalTimeTest* self = new(ELeave) CLocalTimeTest(aTest, aDriveLetter, aBuild);
54 CleanupStack::PushL(self);
60 Connect the test to the File server
62 void CLocalTimeTest::ConstructL()
64 User::LeaveIfError(iRFs.Connect() );
65 iRFs.CharToDrive(iDriveLetter[0], iDrive);
68 if(iTestType !=ENoTest)
72 iTestFile = new (ELeave) CTestFile(KFile, &iRFs);
73 iTestFile->SetPath(iTestPath);
74 iTestFileRFs = new (ELeave) CTestFileRFs(KFile, &iRFs );
75 iTestFileRFs->SetPath(iTestPath);
76 iTestDirectory = new (ELeave) CTestDirectory(KDirectory, &iRFs);
77 iTestDirectory->SetPath(iTestPath);
80 iOriginalUseLocalTimeFlag=IsLocalTimeOnRemMediaL(); //store initial setting
83 if(iTestType==EPositive)
84 iExpectedTimeStampOffset=KTimeOffset;
86 iExpectedTimeStampOffset=KNullTimeOffset;
92 CLocalTimeTest::~CLocalTimeTest()
94 if(iTestType!=ENoTest && iBuild==EUdeb) //restore flag to original value
98 if(iOriginalUseLocalTimeFlag)
99 LocalTimeForRemMediaOnL();
101 LocalTimeForRemMediaOffL();
104 __ASSERT_ALWAYS(err==KErrNone, User::PanicUnexpectedLeave());
112 delete iTestDirectory;
116 Check that the test can read and modify the flag within
117 the FAT or FAT32 plugin.
119 void CLocalTimeTest::TestDebugInterfaceL()
121 iTest.Start(_L("Checking debug interface"));
123 TBool localTimeEnabled(EFalse);
124 localTimeEnabled = IsLocalTimeOnRemMediaL();
125 iTest.Printf(_L("Use localtime enable intially? %d\n"), localTimeEnabled);
127 LocalTimeForRemMediaOffL();
128 localTimeEnabled=IsLocalTimeOnRemMediaL();
129 iTest.Next(_L("Disabling flag..."));
130 iTest(!localTimeEnabled);
132 LocalTimeForRemMediaOnL();
133 localTimeEnabled=IsLocalTimeOnRemMediaL();
134 iTest.Next(_L("Enabling flag..."));
135 iTest(localTimeEnabled);
141 Test that after creating a file or directory its creation time
142 has been offset (or not) as expected.
144 void CLocalTimeTest::TestReadCreationTimeL(CFileSystemEntry* aFsEntry)
146 iTest.Next(_L("Read creation time"));
147 iTest.Printf(_L("Testing on %S"), &aFsEntry->Name());
149 LocalTimeForRemMediaOnL();
151 test_KErrNone(aFsEntry->DeleteCreate());
152 now.UniversalTime(); //hopefuly "now" will be within the 2-second error allowed.
155 TTime creationTimeLocal = aFsEntry->CreationTimeL();
157 PrintTimeL(_L("Current UTC time"), now);
158 PrintExpectedOffset();
160 PrintTimeL(_L("creation time"), creationTimeLocal);
161 iTest(CLocalTimeTest::FuzzyTimeMatch(creationTimeLocal, now+iExpectedTimeStampOffset));
164 test.Printf(_L("Creation times cannot be accessed in release build\n"));
170 Test that when reading a modification time it has been translated (or not)
172 @param aFsEntry A file or directory to be tested
174 void CLocalTimeTest::TestReadModificationTimeL(CFileSystemEntry* aFsEntry)
177 iTest.Next(_L("Reading modification time - offset should be subtracted from timestamp "));
178 iTest.Printf(_L("Testing on %S \n"), &aFsEntry->Name());
179 LocalTimeForRemMediaOffL();
180 r = aFsEntry->DeleteCreate();
184 PrintTimeL(_L("Current UTC time"), now);
185 //timestamp on disk will be UTC
186 r = aFsEntry->SetModificationTime(now);
189 LocalTimeForRemMediaOnL();
190 r = aFsEntry->Open();
193 TTime modTime = aFsEntry->ModificationTimeL();
196 PrintExpectedOffset();
197 PrintTimeL(_L("modification time"), modTime);
198 iTest(CLocalTimeTest::FuzzyTimeMatch(modTime, now - iExpectedTimeStampOffset));
203 Test that when setting a modification time it is modified as expected.
204 @param aFsEntry A file or directory to be tested
206 void CLocalTimeTest::TestSetModificationTimeL(CFileSystemEntry* aFsEntry)
208 iTest.Next(_L("Setting modification time - offset should be added to timestamp"));
209 iTest.Printf(_L("Testing on %S \n"), &aFsEntry->Name());
212 PrintTimeL(_L("Modification time set"), now);
213 LocalTimeForRemMediaOnL();
215 r = aFsEntry->DeleteCreate();
218 //timestamp on disk will be local
219 r = aFsEntry->SetModificationTime(now);
223 LocalTimeForRemMediaOffL();
226 TTime modTime = aFsEntry->ModificationTimeL();
228 PrintExpectedOffset();
229 PrintTimeL(_L("Modification time read"), modTime);
230 iTest(CLocalTimeTest::FuzzyTimeMatch(modTime, now+iExpectedTimeStampOffset));
235 Check that modification times of copied files are preserved
236 @param aFsEntry A file or directory to be tested
238 void CLocalTimeTest::TestCopyL(CFileSystemEntry* aFsEntry)
240 LocalTimeForRemMediaOnL();
242 iTest.Next(_L("Test copying"));
243 iTest.Printf(_L("Testing on %S \n"), &aFsEntry->Name());
244 aFsEntry->DeleteCreate();
245 TTime mtime = aFsEntry->ModificationTimeL();
246 PrintTimeL(_L("Original mtime"), mtime);
249 CFileSystemEntry* file2 = aFsEntry->CopyL();
251 CleanupStack::PushL(file2);
254 TTime mtime2 = file2->ModificationTimeL();
257 iTest.Printf(_L("Modification times should be preserved\n"));
259 PrintTimeL(_L("Copy's mtime"), mtime2 );
260 iTest(FuzzyTimeMatch(mtime2, mtime) ); //mod time should always be preserved on copy
262 CleanupStack::PopAndDestroy(file2);
267 Check that modification times of copied directories are preserved
269 void CLocalTimeTest::TestCopyDirL()
271 LocalTimeForRemMediaOnL();
273 iTest.Next(_L("Test copying directory - modtimes should be preserved"));
274 _LIT(KSubDir, "SubDir\\");
275 TPath parentDir(iTestPath);
276 parentDir+=KDirectory;
277 parentDir.Delete(parentDir.Length()-1, 1);
279 TPath subDir(parentDir);
280 subDir.Append(KPathDelimiter);
284 TPath destDir(iTestPath);
285 destDir+=_L("copyDir");
286 destDir.Append(KPathDelimiter);
289 iRFs.MkDirAll(subDir);
291 TPath destSubDir(destDir);
293 iRFs.RmDir(destSubDir);
295 CFileMan* fMan = CFileMan::NewL(iRFs);
296 CleanupStack::PushL(fMan );
300 fMan->Copy(parentDir, destDir , CFileMan::EOverWrite|CFileMan::ERecurse);
302 TTime originalModtime;
305 test_KErrNone(iRFs.Modified(subDir, originalModtime) );
306 test_KErrNone(iRFs.Modified(destSubDir, newDirModtime));
307 PrintTimeL(_L("Orginal modtime"), originalModtime);
308 PrintTimeL(_L("Copy's modtime"), newDirModtime);
311 iRFs.RmDir(destSubDir);
314 iTest(FuzzyTimeMatch(originalModtime,newDirModtime) );
316 CleanupStack::PopAndDestroy(fMan);
320 Checks whether two times match, to a certain tolerance. By default allow for a 2 second error.
321 @param aTestTime One time
322 @param aRefTime Second time.
323 @return Whether the times matched.
325 TBool CLocalTimeTest::FuzzyTimeMatch(const TTime& aTestTime, const TTime& aRefTime)
327 return(aTestTime>=(aRefTime-KModTimeThreshold) && aTestTime<=(aRefTime+KModTimeThreshold));
331 If on UDEB will switch on the flag held in the CFatMountCB object to
332 use localtimes on removable media.
333 If on UREL will just set the UTC offset on.
335 void CLocalTimeTest::LocalTimeForRemMediaOnL()
338 User::LeaveIfError(iRFs.ControlIo(iDrive, ELocalTimeForRemovableMediaOn,NULL ,NULL) );
340 User::SetUTCOffset(KTimeOffset);
345 If on UDEB will switch off the flag held in the CFatMountCB object to
346 use localtimes on removable media.
347 If on UREL will just set the UTC offset to nothing,
348 so that no time conversions are carried out.
350 void CLocalTimeTest::LocalTimeForRemMediaOffL()
354 User::LeaveIfError(iRFs.ControlIo(iDrive, ELocalTimeForRemovableMediaOff,NULL ,NULL) );
356 User::SetUTCOffset(KNullTimeOffset);
360 TBool CLocalTimeTest::IsLocalTimeOnRemMediaL()
364 TPckg<TBool> flagPckg(flag);
365 User::LeaveIfError( iRFs.ControlIo(iDrive, ELocalTimeUsedOnRemovableMedia, flagPckg) );
368 return( User::UTCOffset()==KTimeOffset );
372 void CLocalTimeTest::SetTestTypeL()
378 err = iRFs.FileSystemName(fileSystem, iDrive);
380 User::LeaveIfError(err);
382 //not currently testing on urel due to lack of support for configuration file/estart.txt managment
389 if(fileSystem != KFatFileSystem)
394 err = iRFs.Drive(info, iDrive);
395 User::LeaveIfError(err);
397 if(info.iDriveAtt&KDriveAttRemovable)
411 @return Drive letter being tested
413 const TDesC& CLocalTimeTest::DriveLetter() const
418 @return Drive number of test.
420 TInt CLocalTimeTest::DriveNumber() const
426 Print the drive number and letter of the test to the RTest console.
428 void CLocalTimeTest::PrintDrive() const
432 err = iRFs.FileSystemSubType(iDrive, fileSystem);
434 test.Printf(_L("Using drive %d %S: Fs Type: %S\n"), DriveNumber(), &DriveLetter(), &fileSystem );
437 void CLocalTimeTest::PrintExpectedOffset() const
439 iTest.Printf(_L("Expected offset: %d hours\n"), iExpectedTimeStampOffset.Int()/KSecondsPerHour);
443 Create directories for the test if necessary.
445 void CLocalTimeTest::MakeTestPathL()
447 iTestPath.Append(iDriveLetter);
448 iTestPath.Append(KDriveDelimiter);
449 iTestPath.Append(KPathDelimiter);
450 iTestPath.Append(KTestDir);
451 iTestPath.Append(KPathDelimiter);
453 TInt err=iRFs.MkDirAll(iTestPath);
454 if(err!=KErrNone && err!=KErrAlreadyExists)
456 iRFs.SetSessionPath(iTestPath);
459 void CLocalTimeTest::PrintTimeL(const TDesC& aMessg, const TTime& aTime) const
462 _LIT(KTimeFormat, "%F%H:%T:%S");
463 aTime.FormatL(timeBuf, KTimeFormat);
465 iTest.Printf(_L("%S: %S\n"), &aMessg, &timeBuf);
470 A callback function passed into a TCleanupItem to restore the system's UTC offset at the end
473 void RestoreOffset(TAny* aOffset)
475 User::SetUTCOffset(*static_cast<TTimeIntervalSeconds*>(aOffset) );
483 ////////////////////////////////////////////////
484 //////////CFileSystemEntry/////////////////////
485 ////////////////////////////////////////////////
488 @param aPath Name or full path for entry.
489 @param aFs the RFs handle to be used.
491 CFileSystemEntry::CFileSystemEntry(const TDesC& aPath, RFs* aFs )
492 : iRFs(aFs), iFullPath(aPath)
496 CFileSystemEntry::~CFileSystemEntry()
500 Prepends a path to the existing name or path.
501 @param aPath The path to use.
503 void CFileSystemEntry::SetPath(const TDesC& aPath)
505 iFullPath.Insert(0, aPath);
508 void CFileSystemEntry::SetFileServer(RFs* aFs)
514 Close and delete the entry.
515 @return An error code indicating success or failure.
517 TInt CFileSystemEntry::Delete()
520 return iRFs->Delete(iFullPath);
524 Delete and then make a new file/directory of the same name
525 @return An error code indicating success or failure.
527 TInt CFileSystemEntry::DeleteCreate()
533 void CFileSystemEntry::Close()
538 @return The creation time of the entry.
540 TTime CFileSystemEntry::CreationTimeL()
542 TParsePtrC parse(iFullPath);
543 //check there is a drive specified
544 if(!parse.DrivePresent() )
545 User::Panic(KTestGroupName, KErrBadName);
548 User::LeaveIfError(iRFs->CharToDrive(parse.Drive()[0], driveNumber) );
550 TBuf8<KMaxPath> narrowPath;
551 narrowPath.Copy(parse.Path() );
552 narrowPath.Append(parse.NameAndExt() );
554 //remove trailing slash if present
555 if(narrowPath[narrowPath.Length()-1]==KPathDelimiter)
556 narrowPath.Delete(narrowPath.Length()-1, 1);
558 TTime creationTime=0;
559 TPckg<TTime> timePckg(creationTime);
561 User::LeaveIfError(iRFs->ControlIo(driveNumber, ECreationTime, narrowPath, timePckg) );
566 const TDesC& CFileSystemEntry::Name() const
572 ////////////////////////////////////////////////
573 //////////CTestDirectory////////////////////////
574 ////////////////////////////////////////////////
576 CTestDirectory::CTestDirectory(const TDesC& aPath, RFs* aFs)
577 :CFileSystemEntry(aPath, aFs)
579 iName.Set(KTestDirectoryName);
582 TInt CTestDirectory::Open()
584 return KErrNone; //directories can't be opened.
587 TInt CTestDirectory::Create()
589 return iRFs->MkDir(iFullPath);
592 TInt CTestDirectory::Delete()
594 return iRFs->RmDir(iFullPath );
597 TTime CTestDirectory::ModificationTimeL()
600 User::LeaveIfError( iRFs->Modified(iFullPath, time) );
603 TInt CTestDirectory::SetModificationTime(const TTime& aTime)
605 return iRFs->SetModified(iFullPath, aTime);
607 CFileSystemEntry* CTestDirectory::CopyL()
613 ////////////////////////////////////////////////
614 //////////CTestFile/////////////////////////////
615 ////////////////////////////////////////////////
617 CTestFile::CTestFile(const TDesC& aPath, RFs* aFs)
618 :CFileSystemEntry(aPath, aFs)
620 iName.Set(KTestFileRFile);
623 CTestFile::~CTestFile()
628 TInt CTestFile::Open()
630 return iRFile.Open(*iRFs, iFullPath, EFileShareExclusive|EFileWrite);
633 TInt CTestFile::Create()
635 return iRFile.Replace(*iRFs, iFullPath, EFileShareExclusive|EFileWrite);
637 void CTestFile::Close()
642 TTime CTestFile::ModificationTimeL()
645 User::LeaveIfError(iRFile.Modified(time) );
649 TInt CTestFile::SetModificationTime(const TTime& aTime)
651 return iRFile.SetModified(aTime);
654 CFileSystemEntry* CTestFile::CopyL()
656 CFileMan* fMan = CFileMan::NewL(*iRFs);
657 CleanupStack::PushL(fMan);
659 TFileName newName(iFullPath);
660 newName.Append(_L("~"));
661 CFileSystemEntry* copy= new(ELeave) CTestFile(newName, iRFs);
662 CleanupStack::PushL(copy);
663 copy->Delete(); //delete anything at the path already
665 User::LeaveIfError(fMan->Copy(iFullPath,newName) );
667 CleanupStack::Pop(copy);
668 CleanupStack::PopAndDestroy(fMan);
672 ////////////////////////////////////////////////
673 ////////////CTestFileRFs////////////////////////
674 ////////////////////////////////////////////////
675 CTestFileRFs::CTestFileRFs(const TDesC& aPath, RFs* aFs) : CTestFile(aPath, aFs)
677 iName.Set(KTestFileRFs);
679 TTime CTestFileRFs::ModificationTimeL()
681 TBool isOpen=KErrNone;
682 test_KErrNone(iRFs->IsFileOpen(iFullPath, isOpen));
686 User::LeaveIfError(iRFs->Modified(iFullPath,time) );
693 TInt CTestFileRFs::SetModificationTime(const TTime& aTime)
695 TBool isOpen=KErrNone;
696 test_KErrNone(iRFs->IsFileOpen(iFullPath, isOpen));
699 TInt err = iRFs->SetModified(iFullPath, aTime);
706 CTestFileRFs::~CTestFileRFs()
712 ////////////////////////////////////////////////////
713 //////////Entry point and main//////////////////////
714 ////////////////////////////////////////////////////
717 Construct and run the various tests.
721 test.Start(KTestGroupName);
723 CLocalTimeTest::TBuild build = CLocalTimeTest::EUdeb;
725 CLocalTimeTest::TBuild build = CLocalTimeTest::EUrel;
727 TPtrC drive((TUint16*)&gDriveToTest, 1);
729 CLocalTimeTest* timeTest= CLocalTimeTest::NewLC(test, drive , build);
730 timeTest->RunTestsL();
731 CleanupStack::PopAndDestroy(timeTest);
736 void CLocalTimeTest::RunTestsL()
739 if(iTestType==ENoTest)
741 iTest.Printf(_L("Not runnning tests on this drive\n"));
745 iTest.Start(_L("Running tests"));
747 //Be able to restore to original timezone after test
748 TTimeIntervalSeconds savedUTCOffset = User::UTCOffset();
749 TCleanupItem restoreOffset(RestoreOffset, &savedUTCOffset);
750 CleanupStack::PushL(restoreOffset);
752 //This functionallity must be tested with a non-zero GMT offset.
753 test.Printf(_L("Setting UTC offset to %d hours\n"), KHoursOffset);
754 User::SetUTCOffset(KTimeOffset);
757 iTest.Printf(_L("Testing on UDEB build\n"));
758 else if(iBuild==EUrel)
759 iTest.Printf(_L("Testing on UREL build\n"));
761 if(iTestType==EPositive)
762 iTest.Printf(_L("Drive is removable, running positive tests\n"));
763 else if(iTestType==ENegative)
764 iTest.Printf(_L("Drive is non-removable, running negative tests\n"));
767 if(iBuild==EUdeb) //these tests cannot be used without ControlIO
769 TestDebugInterfaceL();
770 TestReadCreationTimeL(iTestFile);
771 TestReadCreationTimeL(iTestFileRFs);
772 TestReadCreationTimeL(iTestDirectory);
775 TestReadModificationTimeL(iTestFile);
776 TestReadModificationTimeL(iTestFileRFs);
777 TestReadModificationTimeL(iTestDirectory);
779 TestSetModificationTimeL(iTestFile);
780 TestSetModificationTimeL(iTestFileRFs);
781 TestSetModificationTimeL(iTestDirectory);
783 TestCopyL(iTestFile);
784 TestCopyL(iTestFileRFs);
787 CleanupStack::PopAndDestroy(&savedUTCOffset);