kerneltest/f32test/server/t_localtime.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 	}