os/kernelhwsrv/kerneltest/f32test/server/t_localtime.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    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.
    17 // 
    18 //
    19 
    20 /**
    21  @file
    22  @test
    23 */
    24 #define __E32TEST_EXTENSION__
    25 #include <e32test.h>
    26 
    27 #include "t_localtime.h"
    28 #include "t_server.h"
    29 
    30 RTest test(KTestGroupName);
    31 
    32 /**
    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
    37 */
    38 CLocalTimeTest::CLocalTimeTest(RTest& aTest, const TDesC& aDriveLetter, TBuild aBuild) 
    39 	:iDriveLetter(aDriveLetter), iTest(aTest), iBuild(aBuild), iOriginalUseLocalTimeFlag(EFalse)
    40 	{
    41 	
    42 	}
    43 
    44 /**
    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
    49 @return A test object
    50 */
    51 CLocalTimeTest* CLocalTimeTest::NewLC(RTest& aTest, const TDesC& aDriveLetter, TBuild aBuild)
    52 	{
    53 	CLocalTimeTest* self = new(ELeave) CLocalTimeTest(aTest, aDriveLetter, aBuild);
    54 	CleanupStack::PushL(self);
    55 	self->ConstructL();
    56 	return self;
    57 	}
    58 
    59 /** 
    60 Connect the test to the File server
    61 */
    62 void CLocalTimeTest::ConstructL()
    63 	{
    64 	User::LeaveIfError(iRFs.Connect() );
    65 	iRFs.CharToDrive(iDriveLetter[0], iDrive);
    66 	
    67 	SetTestTypeL();
    68 	if(iTestType !=ENoTest)
    69 		{
    70 		MakeTestPathL();
    71 		
    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);
    78 		
    79 		if(iBuild==EUdeb)
    80 			iOriginalUseLocalTimeFlag=IsLocalTimeOnRemMediaL(); //store initial setting
    81 		}
    82 
    83 	if(iTestType==EPositive)
    84 		iExpectedTimeStampOffset=KTimeOffset;
    85 	else
    86 		iExpectedTimeStampOffset=KNullTimeOffset;
    87 	}
    88 
    89 
    90 
    91 
    92 CLocalTimeTest::~CLocalTimeTest()
    93 	{
    94 	if(iTestType!=ENoTest && iBuild==EUdeb) //restore flag to original value
    95 		{
    96 		TRAPD(err,
    97 			{
    98 			if(iOriginalUseLocalTimeFlag)
    99 				LocalTimeForRemMediaOnL();
   100 			else
   101 				LocalTimeForRemMediaOffL();
   102 			}
   103 		);
   104 		__ASSERT_ALWAYS(err==KErrNone, User::PanicUnexpectedLeave());
   105 		}
   106 
   107 	if(iTestFile)
   108 		delete iTestFile;
   109 	if(iTestFileRFs)
   110 		delete iTestFileRFs;
   111 	if(iTestDirectory)
   112 		delete iTestDirectory;
   113 	}
   114 
   115 /**
   116 Check that the test can read and modify the flag within
   117 the FAT or FAT32 plugin.
   118 */
   119 void CLocalTimeTest::TestDebugInterfaceL()
   120 	{
   121 	iTest.Start(_L("Checking debug interface"));
   122 		
   123 	TBool localTimeEnabled(EFalse);
   124 	localTimeEnabled = IsLocalTimeOnRemMediaL();
   125 	iTest.Printf(_L("Use localtime enable intially? %d\n"), localTimeEnabled);
   126 	
   127 	LocalTimeForRemMediaOffL();
   128 	localTimeEnabled=IsLocalTimeOnRemMediaL();
   129 	iTest.Next(_L("Disabling flag..."));
   130 	iTest(!localTimeEnabled);
   131 	
   132 	LocalTimeForRemMediaOnL();
   133 	localTimeEnabled=IsLocalTimeOnRemMediaL();
   134 	iTest.Next(_L("Enabling flag..."));
   135 	iTest(localTimeEnabled);
   136 	
   137 	iTest.End();
   138 	}
   139 
   140 /**
   141 Test that after creating a file or directory its creation time
   142 has been offset (or not) as expected.
   143 */
   144 void CLocalTimeTest::TestReadCreationTimeL(CFileSystemEntry* aFsEntry)
   145 	{
   146 	iTest.Next(_L("Read creation time"));
   147 	iTest.Printf(_L("Testing on %S"), &aFsEntry->Name());
   148 #if defined(_DEBUG)	
   149 	LocalTimeForRemMediaOnL();
   150 	TTime now;
   151 	test_KErrNone(aFsEntry->DeleteCreate());
   152 	now.UniversalTime(); //hopefuly "now" will be within the 2-second error allowed.
   153 				
   154 	aFsEntry->Close();
   155 	TTime creationTimeLocal = aFsEntry->CreationTimeL();
   156 	
   157 	PrintTimeL(_L("Current UTC time"), now);
   158 	PrintExpectedOffset();
   159 	
   160 	PrintTimeL(_L("creation time"), creationTimeLocal);
   161 	iTest(CLocalTimeTest::FuzzyTimeMatch(creationTimeLocal, now+iExpectedTimeStampOffset));
   162 
   163 #else
   164 	test.Printf(_L("Creation times cannot be accessed in release build\n"));
   165 
   166 #endif
   167 	}
   168 
   169 /**
   170 Test that when reading a modification time it has been translated (or not)
   171 as expected.
   172 @param aFsEntry A file or directory to be tested
   173 */ 
   174 void CLocalTimeTest::TestReadModificationTimeL(CFileSystemEntry* aFsEntry)
   175 	{
   176 	TInt r= KErrNone;
   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();
   181 	test_KErrNone(r);
   182 	TTime now;
   183 	now.UniversalTime();
   184 	PrintTimeL(_L("Current UTC time"), now);
   185 	//timestamp on disk will be UTC
   186 	r = aFsEntry->SetModificationTime(now);
   187 	test_KErrNone(r);
   188 	aFsEntry->Close();
   189 	LocalTimeForRemMediaOnL();
   190 	r = aFsEntry->Open();
   191 	test_KErrNone(r);
   192 	
   193 	TTime modTime = aFsEntry->ModificationTimeL();
   194 	test_KErrNone(r);
   195 	
   196 	PrintExpectedOffset();
   197 	PrintTimeL(_L("modification time"), modTime);
   198 	iTest(CLocalTimeTest::FuzzyTimeMatch(modTime, now - iExpectedTimeStampOffset));
   199 	aFsEntry->Close();
   200 	}
   201 
   202 /**
   203 Test that when setting a modification time it is modified as expected.
   204 @param aFsEntry A file or directory to be tested
   205 */
   206 void CLocalTimeTest::TestSetModificationTimeL(CFileSystemEntry* aFsEntry)
   207 	{
   208 	iTest.Next(_L("Setting modification time - offset should be added to timestamp"));
   209 	iTest.Printf(_L("Testing on %S \n"), &aFsEntry->Name());		
   210 	TTime now;
   211 	now.UniversalTime();
   212 	PrintTimeL(_L("Modification time set"), now);
   213 	LocalTimeForRemMediaOnL();
   214 	TInt r = KErrNone;
   215 	r = aFsEntry->DeleteCreate();
   216 	test_KErrNone(r);
   217 
   218 	//timestamp on disk will be local
   219 	r = aFsEntry->SetModificationTime(now);
   220 	test_KErrNone(r);
   221 	aFsEntry->Close();
   222 	
   223 	LocalTimeForRemMediaOffL();
   224 	aFsEntry->Open();
   225 	
   226 	TTime modTime = aFsEntry->ModificationTimeL();
   227 	
   228 	PrintExpectedOffset();
   229 	PrintTimeL(_L("Modification time read"), modTime);
   230 	iTest(CLocalTimeTest::FuzzyTimeMatch(modTime, now+iExpectedTimeStampOffset));
   231 	
   232 	aFsEntry->Close();
   233 	}
   234 /**
   235 Check that modification times of copied files are preserved
   236 @param aFsEntry A file or directory to be tested
   237 */
   238 void CLocalTimeTest::TestCopyL(CFileSystemEntry* aFsEntry)
   239 	{
   240 	LocalTimeForRemMediaOnL();
   241 		
   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);
   247 	
   248 	
   249 	CFileSystemEntry* file2 = aFsEntry->CopyL();
   250 	file2->Close();
   251 	CleanupStack::PushL(file2);
   252 	
   253 	file2->Open();
   254 	TTime mtime2 = file2->ModificationTimeL();
   255 	
   256 	
   257 	iTest.Printf(_L("Modification times should be preserved\n"));
   258 	
   259 	PrintTimeL(_L("Copy's mtime"), mtime2 );
   260 	iTest(FuzzyTimeMatch(mtime2, mtime) ); //mod time should always be preserved on copy
   261 	
   262 	CleanupStack::PopAndDestroy(file2);
   263 	aFsEntry->Close();
   264 	}
   265 
   266 /**
   267 Check that modification times of copied directories are preserved
   268 */
   269 void CLocalTimeTest::TestCopyDirL()
   270 	{
   271 	LocalTimeForRemMediaOnL();
   272 	
   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);
   278 	
   279 	TPath subDir(parentDir);
   280 	subDir.Append(KPathDelimiter);
   281 	subDir+=KSubDir;
   282 	
   283 	
   284 	TPath destDir(iTestPath);
   285 	destDir+=_L("copyDir");
   286 	destDir.Append(KPathDelimiter);
   287 		
   288 	iRFs.RmDir(subDir);
   289 	iRFs.MkDirAll(subDir);
   290 	
   291 	TPath destSubDir(destDir);
   292 	destSubDir+=KSubDir;
   293 	iRFs.RmDir(destSubDir);
   294 	
   295 	CFileMan* fMan = CFileMan::NewL(iRFs);
   296 	CleanupStack::PushL(fMan );
   297 	
   298 	
   299 	
   300 	fMan->Copy(parentDir, destDir , CFileMan::EOverWrite|CFileMan::ERecurse);
   301 	
   302 	TTime originalModtime;
   303 	TTime newDirModtime;
   304 	
   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);
   309 	
   310 	iRFs.RmDir(subDir);
   311 	iRFs.RmDir(destSubDir);
   312 	
   313 
   314 	iTest(FuzzyTimeMatch(originalModtime,newDirModtime) );
   315 	
   316 	CleanupStack::PopAndDestroy(fMan);
   317 	}
   318 
   319 /**
   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.
   324 */
   325 TBool CLocalTimeTest::FuzzyTimeMatch(const TTime& aTestTime, const TTime& aRefTime)
   326 	{
   327 	return(aTestTime>=(aRefTime-KModTimeThreshold) && aTestTime<=(aRefTime+KModTimeThreshold));
   328 	}
   329 
   330 /**
   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.
   334 */
   335 void CLocalTimeTest::LocalTimeForRemMediaOnL()
   336 	{
   337 #if defined(_DEBUG)
   338 	User::LeaveIfError(iRFs.ControlIo(iDrive, ELocalTimeForRemovableMediaOn,NULL ,NULL) );
   339 #else
   340 	User::SetUTCOffset(KTimeOffset);
   341 #endif
   342 	}
   343 
   344 /**
   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.
   349 */
   350 void CLocalTimeTest::LocalTimeForRemMediaOffL()
   351 	{
   352 
   353 #if defined(_DEBUG)
   354 	User::LeaveIfError(iRFs.ControlIo(iDrive, ELocalTimeForRemovableMediaOff,NULL ,NULL) );
   355 #else
   356 	User::SetUTCOffset(KNullTimeOffset);
   357 #endif
   358 	}
   359 
   360 TBool CLocalTimeTest::IsLocalTimeOnRemMediaL()
   361 	{
   362 #if defined(_DEBUG)
   363 	TBool flag(EFalse);
   364 	TPckg<TBool> flagPckg(flag);
   365 	User::LeaveIfError( iRFs.ControlIo(iDrive, ELocalTimeUsedOnRemovableMedia, flagPckg) );
   366 	return flagPckg();
   367 #else
   368 	return( User::UTCOffset()==KTimeOffset );
   369 #endif
   370 	}
   371 
   372 void CLocalTimeTest::SetTestTypeL()
   373 	{
   374 	TDriveInfo info;
   375 	
   376 	TFSName fileSystem;
   377 	TInt err;
   378 	err = iRFs.FileSystemName(fileSystem, iDrive);
   379 
   380 	User::LeaveIfError(err);
   381 	
   382 	//not currently testing on urel due to lack of support for configuration file/estart.txt  managment
   383 	if(iBuild==EUrel)
   384 		{
   385 		iTestType=ENoTest;
   386 		return;
   387 		}
   388 
   389 	if(fileSystem != KFatFileSystem)
   390 		{
   391 		iTestType=ENoTest;
   392 		return;
   393 		}
   394 	err = iRFs.Drive(info, iDrive);
   395 	User::LeaveIfError(err);
   396 
   397 	if(info.iDriveAtt&KDriveAttRemovable)
   398 		{
   399 		iTestType=EPositive;
   400 		}
   401 	else
   402 		{
   403 		iTestType=ENegative;
   404 		}
   405 	return;
   406 	}
   407 
   408 
   409 
   410 /**
   411 @return Drive letter being tested
   412 */
   413 const TDesC& CLocalTimeTest::DriveLetter() const
   414 	{
   415 	return iDriveLetter;
   416 	}
   417 /**
   418 @return Drive number of test.
   419 */
   420 TInt CLocalTimeTest::DriveNumber() const
   421 	{
   422 	return iDrive;
   423 	}
   424 
   425 /**
   426 Print the drive number and letter of the test to the RTest console.
   427 */
   428 void CLocalTimeTest::PrintDrive() const
   429 	{
   430 	TFSName fileSystem;
   431 	TInt err;
   432 	err = iRFs.FileSystemSubType(iDrive, fileSystem);
   433 	test_KErrNone(err);
   434 	test.Printf(_L("Using drive %d %S: Fs Type: %S\n"), DriveNumber(), &DriveLetter(), &fileSystem );
   435 	}
   436 
   437 void CLocalTimeTest::PrintExpectedOffset() const
   438 	{
   439 	iTest.Printf(_L("Expected offset: %d hours\n"), iExpectedTimeStampOffset.Int()/KSecondsPerHour);
   440 	}
   441 
   442 /**
   443 Create directories for the test if necessary.
   444 */
   445 void CLocalTimeTest::MakeTestPathL()
   446 	{
   447 	iTestPath.Append(iDriveLetter);
   448 	iTestPath.Append(KDriveDelimiter);
   449 	iTestPath.Append(KPathDelimiter);
   450 	iTestPath.Append(KTestDir);
   451 	iTestPath.Append(KPathDelimiter);
   452 		
   453 	TInt err=iRFs.MkDirAll(iTestPath);
   454 	if(err!=KErrNone && err!=KErrAlreadyExists)
   455 		User::Leave(err);
   456 	iRFs.SetSessionPath(iTestPath);
   457 	}
   458 
   459 void CLocalTimeTest::PrintTimeL(const TDesC& aMessg, const TTime& aTime) const
   460 	{
   461 	TBuf<32> timeBuf;
   462 	_LIT(KTimeFormat, "%F%H:%T:%S");
   463 	aTime.FormatL(timeBuf, KTimeFormat);
   464 
   465 	iTest.Printf(_L("%S: %S\n"), &aMessg, &timeBuf);
   466 	}
   467 
   468 
   469 /**
   470 A callback function passed into a TCleanupItem to restore the system's UTC offset at the end
   471 of the test.
   472 */
   473 void RestoreOffset(TAny* aOffset)
   474 	{
   475 	User::SetUTCOffset(*static_cast<TTimeIntervalSeconds*>(aOffset) );
   476 	}
   477 
   478 
   479 
   480 
   481 
   482 
   483 ////////////////////////////////////////////////
   484 //////////CFileSystemEntry/////////////////////
   485 ////////////////////////////////////////////////
   486 
   487 /**
   488 @param aPath Name or full path for entry.
   489 @param aFs the RFs handle to be used.
   490 */
   491 CFileSystemEntry::CFileSystemEntry(const TDesC& aPath, RFs* aFs )
   492 	: iRFs(aFs), iFullPath(aPath)
   493 	{
   494 	}
   495 
   496 CFileSystemEntry::~CFileSystemEntry()
   497 	{}
   498 
   499 /**
   500 Prepends a path to the existing name or path.
   501 @param aPath The path to use.
   502 */
   503 void CFileSystemEntry::SetPath(const TDesC& aPath)
   504 	{
   505 	iFullPath.Insert(0, aPath);
   506 	}
   507 
   508 void CFileSystemEntry::SetFileServer(RFs* aFs)
   509 	{
   510 	iRFs = aFs;	
   511 	}
   512 
   513 /**
   514 Close and delete the entry.
   515 @return An error code indicating success or failure.
   516 */
   517 TInt CFileSystemEntry::Delete()
   518 	{
   519 	Close();
   520 	return iRFs->Delete(iFullPath);
   521 	}
   522 
   523 /**
   524 Delete and then make a new file/directory of the same name
   525 @return An error code indicating success or failure.
   526 */
   527 TInt CFileSystemEntry::DeleteCreate()
   528 	{
   529 	Delete();
   530 	return Create();
   531 	}
   532 
   533 void CFileSystemEntry::Close()
   534 	{	
   535 	}
   536 
   537 /**
   538 @return The creation time of the entry.
   539 */
   540 TTime CFileSystemEntry::CreationTimeL()
   541 	{
   542 	TParsePtrC parse(iFullPath);
   543 	//check there is a drive specified
   544 	if(!parse.DrivePresent() )
   545 		User::Panic(KTestGroupName, KErrBadName);
   546 	
   547 	TInt driveNumber(0); 
   548 	User::LeaveIfError(iRFs->CharToDrive(parse.Drive()[0], driveNumber) );
   549 
   550 	TBuf8<KMaxPath> narrowPath;
   551 	narrowPath.Copy(parse.Path() );
   552 	narrowPath.Append(parse.NameAndExt() );
   553 	
   554 	//remove trailing slash if present
   555 	if(narrowPath[narrowPath.Length()-1]==KPathDelimiter)
   556 		narrowPath.Delete(narrowPath.Length()-1, 1);
   557 
   558 	TTime creationTime=0;
   559 	TPckg<TTime> timePckg(creationTime);
   560 
   561 	User::LeaveIfError(iRFs->ControlIo(driveNumber, ECreationTime, narrowPath, timePckg) );
   562 
   563 	return timePckg();
   564 	}
   565 
   566 const TDesC& CFileSystemEntry::Name() const
   567 	{
   568 	return iName;
   569 	}
   570 
   571 
   572 ////////////////////////////////////////////////
   573 //////////CTestDirectory////////////////////////
   574 ////////////////////////////////////////////////
   575 
   576 CTestDirectory::CTestDirectory(const TDesC& aPath, RFs* aFs)
   577 :CFileSystemEntry(aPath, aFs)
   578 	{
   579 	iName.Set(KTestDirectoryName);
   580 	}
   581 
   582 TInt CTestDirectory::Open()
   583 	{
   584 	return KErrNone; //directories can't be opened.
   585 	}
   586 
   587 TInt CTestDirectory::Create()
   588 	{
   589 	return iRFs->MkDir(iFullPath);
   590 	}
   591 
   592 TInt CTestDirectory::Delete()
   593 	{
   594 	return iRFs->RmDir(iFullPath );
   595 	}
   596 
   597 TTime CTestDirectory::ModificationTimeL()
   598 	{
   599 	TTime time;
   600 	User::LeaveIfError( iRFs->Modified(iFullPath, time) );
   601 	return time;
   602 	}
   603 TInt CTestDirectory::SetModificationTime(const TTime& aTime)
   604 	{
   605 	return iRFs->SetModified(iFullPath, aTime);
   606 	}
   607 CFileSystemEntry* CTestDirectory::CopyL()
   608 	{
   609 	return NULL;
   610 	}
   611 
   612 
   613 ////////////////////////////////////////////////
   614 //////////CTestFile/////////////////////////////
   615 ////////////////////////////////////////////////
   616 
   617 CTestFile::CTestFile(const TDesC& aPath, RFs* aFs)
   618 :CFileSystemEntry(aPath, aFs)
   619 	{
   620 	iName.Set(KTestFileRFile);
   621 	}
   622 
   623 CTestFile::~CTestFile()
   624 	{
   625 	Close();
   626 	}
   627 
   628 TInt CTestFile::Open()
   629 	{
   630 	return iRFile.Open(*iRFs, iFullPath, EFileShareExclusive|EFileWrite);
   631 	}
   632 
   633 TInt CTestFile::Create()
   634 	{
   635 	return iRFile.Replace(*iRFs, iFullPath, EFileShareExclusive|EFileWrite);	
   636 	}
   637 void CTestFile::Close()
   638 	{
   639 	iRFile.Close();
   640 	}
   641 
   642 TTime CTestFile::ModificationTimeL()
   643 	{
   644 	TTime time;
   645 	User::LeaveIfError(iRFile.Modified(time) );
   646 	return time;
   647 	}
   648 
   649 TInt CTestFile::SetModificationTime(const TTime& aTime)
   650 	{
   651 	return iRFile.SetModified(aTime);
   652 	}
   653 
   654 CFileSystemEntry* CTestFile::CopyL()
   655 	{
   656 	CFileMan* fMan = CFileMan::NewL(*iRFs);
   657 	CleanupStack::PushL(fMan);
   658 	
   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
   664 	Close();
   665 	User::LeaveIfError(fMan->Copy(iFullPath,newName) );
   666 	
   667 	CleanupStack::Pop(copy);
   668 	CleanupStack::PopAndDestroy(fMan);
   669 	return copy;
   670 	}
   671 
   672 ////////////////////////////////////////////////
   673 ////////////CTestFileRFs////////////////////////
   674 ////////////////////////////////////////////////
   675 CTestFileRFs::CTestFileRFs(const TDesC& aPath, RFs* aFs) : CTestFile(aPath, aFs)
   676 	{
   677 	iName.Set(KTestFileRFs);
   678 	}
   679 TTime CTestFileRFs::ModificationTimeL()
   680 	{
   681 	TBool isOpen=KErrNone;
   682 	test_KErrNone(iRFs->IsFileOpen(iFullPath, isOpen));
   683 	if(isOpen)
   684 		Close();
   685 	TTime time;
   686 	User::LeaveIfError(iRFs->Modified(iFullPath,time) );
   687 	if(isOpen)
   688 		Open();
   689 	return time;
   690 	
   691 	}
   692 
   693 TInt CTestFileRFs::SetModificationTime(const TTime& aTime)
   694 	{
   695 	TBool isOpen=KErrNone;
   696 	test_KErrNone(iRFs->IsFileOpen(iFullPath, isOpen));
   697 	if(isOpen)
   698 		Close();
   699 	TInt err = iRFs->SetModified(iFullPath, aTime);
   700 	if(isOpen)
   701 		Open();
   702 
   703 	return err;
   704 	}
   705 
   706 CTestFileRFs::~CTestFileRFs()
   707 	{
   708 	Close();
   709 	}
   710 
   711 
   712 ////////////////////////////////////////////////////
   713 //////////Entry point and main//////////////////////
   714 ////////////////////////////////////////////////////
   715 
   716 /**
   717 Construct and run the various tests.
   718 */
   719 void CallTestsL()
   720 	{
   721 	test.Start(KTestGroupName);
   722 #if defined(_DEBUG)
   723 	CLocalTimeTest::TBuild build = CLocalTimeTest::EUdeb;
   724 #else
   725 	CLocalTimeTest::TBuild build = CLocalTimeTest::EUrel;
   726 #endif
   727 	TPtrC drive((TUint16*)&gDriveToTest, 1);
   728 	
   729 	CLocalTimeTest* timeTest= CLocalTimeTest::NewLC(test, drive , build);
   730 	timeTest->RunTestsL();
   731 	CleanupStack::PopAndDestroy(timeTest);
   732 
   733 	test.End();
   734 	}
   735 
   736 void CLocalTimeTest::RunTestsL()
   737 	{
   738 	PrintDrive();
   739 	if(iTestType==ENoTest)
   740 		{
   741 		iTest.Printf(_L("Not runnning tests on this drive\n"));
   742 		return;
   743 		}
   744 	
   745 	iTest.Start(_L("Running tests")); 
   746 
   747 	//Be able to restore to original timezone after test
   748 	TTimeIntervalSeconds savedUTCOffset = User::UTCOffset();
   749 	TCleanupItem restoreOffset(RestoreOffset, &savedUTCOffset);
   750 	CleanupStack::PushL(restoreOffset);
   751 	
   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);
   755 	
   756 	if(iBuild==EUdeb)
   757 		iTest.Printf(_L("Testing on UDEB build\n"));
   758 	else if(iBuild==EUrel)
   759 		iTest.Printf(_L("Testing on UREL build\n"));
   760 
   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"));
   765 			
   766 	
   767 	if(iBuild==EUdeb) //these tests cannot be used without ControlIO
   768 		{
   769 		TestDebugInterfaceL();
   770 		TestReadCreationTimeL(iTestFile);
   771 		TestReadCreationTimeL(iTestFileRFs);
   772 		TestReadCreationTimeL(iTestDirectory);
   773 		}
   774 	
   775 	TestReadModificationTimeL(iTestFile);
   776 	TestReadModificationTimeL(iTestFileRFs);
   777 	TestReadModificationTimeL(iTestDirectory);
   778 
   779 	TestSetModificationTimeL(iTestFile);
   780 	TestSetModificationTimeL(iTestFileRFs);
   781 	TestSetModificationTimeL(iTestDirectory);
   782 	
   783 	TestCopyL(iTestFile);
   784 	TestCopyL(iTestFileRFs);
   785 	TestCopyDirL();
   786 
   787 	CleanupStack::PopAndDestroy(&savedUTCOffset);
   788 	iTest.End();
   789 	}