persistentstorage/centralrepository/test/T_CenRepTrans.cpp
changeset 0 08ec8eefde2f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/persistentstorage/centralrepository/test/T_CenRepTrans.cpp	Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,705 @@
+// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#include "t_cenrep_helper.h"
+#include <e32test.h>
+#include <f32file.h>
+#include "srvrepos_noc.h"
+#include "srvres.h"
+#include "cachemgr.h"
+#include <bautils.h>
+#include "setting.h"
+
+//Forward declarations
+class CTestObserver;
+
+///////////////////////////////////////////////////////////////////////////////////////
+// Globals
+
+static RTest TheTest(_L("T_CenRepTrans"));
+const TUid KTestRepositoryId = {0x00000010};
+//CentralRepository server UID
+static const TUid KCenRepServerUID = {0x10202BE9};
+
+static CTestObserver* TheObserver = NULL;
+static CServerRepository* TheServerRepository = NULL;
+
+static const TUint32 KIntSettingID = 843;
+static const TInt KIntSettingVal = 25;
+
+static const TUint32 KRealSettingID = 844;
+static const TReal KRealSettingVal = 8.76;
+static const TReal KRealSettingVal2 = 19.234;
+
+static const TUint32 KStringSettingID = 845;
+_LIT8(KStringSettingVal, "a test string");
+_LIT8(KStringSettingVal2, "another string");
+_LIT8(KEmptyString, "");
+
+_LIT(KTestFile1,	"C:\\PRIVATE\\10202BE9\\PERSISTS\\00000010.TXT");
+_LIT(KCreTestFile1,	"C:\\PRIVATE\\10202BE9\\PERSISTS\\00000010.CRE");
+_LIT(KTmpTestFile1,	"C:\\PRIVATE\\10202BE9\\PERSISTS\\00000010.TMP");
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+//
+
+//Delete file function.
+//Used by the test application to cleanup the C drive at the end of the test.
+static void DeleteFile(const TDesC& aFullName)
+	{
+	RFs fsSession;
+	TInt err = fsSession.Connect();
+	if(err == KErrNone)
+		{
+		TEntry entry;
+		if(fsSession.Entry(aFullName, entry) == KErrNone)
+			{
+			RDebug::Print(_L("Deleting \"%S\" file.\n"), &aFullName);
+			err = fsSession.SetAtt(aFullName, 0, KEntryAttReadOnly);
+			if(err != KErrNone)
+				{
+				RDebug::Print(_L("Error %d changing \"%S\" file attributes.\n"), err, &aFullName);
+				}
+			err = fsSession.Delete(aFullName);
+			if(err != KErrNone)
+				{
+				RDebug::Print(_L("Error %d deleting \"%S\" file.\n"), err, &aFullName);
+				}
+			}
+		fsSession.Close();
+		}
+	else
+		{
+		RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
+		}
+	}
+
+static void DeleteFiles()
+	{
+	::DeleteFile(KTestFile1);
+	::DeleteFile(KCreTestFile1);
+	::DeleteFile(KTmpTestFile1);
+	}
+
+static TInt GetFileTimeStamp(const TDesC& aFullName, TTime& aTime)
+	{
+	RFs fsSession;
+	TInt err = fsSession.Connect();
+	if(err == KErrNone)
+		{
+		TEntry entry;
+		if(fsSession.Entry(aFullName, entry) == KErrNone)
+			{
+			aTime=entry.iModified;
+			}
+		fsSession.Close();
+		}
+	else
+		{
+		RDebug::Print(_L("Error %d connecting file session. File: %S.\n"), err, &aFullName);
+		}
+	return err;
+	}
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+// Test macros and functions.
+
+static void Check(TInt aValue, TInt aLine)
+	{
+	if(!aValue)
+		{
+		::DeleteFiles();
+		TheTest(EFalse, aLine);
+		}
+	}
+static  void Check(TInt aValue, TInt aExpected, TInt aLine)
+	{
+	if(aValue != aExpected)
+		{
+		::DeleteFiles();
+		RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue);
+		TheTest(EFalse, aLine);
+		}
+	}
+#define TEST(arg) ::Check((arg), __LINE__)
+#define TEST2(aValue, aExpected) ::Check(aValue, aExpected, __LINE__)
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+static void CheckTmpFileDeleted()
+	{
+	RFs fsSession;
+	TInt err = fsSession.Connect();
+	if(err == KErrNone)
+		{
+		// Allow time for file to be deleted
+		User::After(500*1000);
+		TEST2 (BaflUtils::FileExists (fsSession, KTmpTestFile1), EFalse);
+		fsSession.Close();
+		}
+	else
+		{
+		RDebug::Print(_L("Error %d connecting file session.\n"), err);
+		}
+	}
+
+
+///////////////////////////////////////////////////////////////////////////////////////
+// CTestObserver class
+
+//It is needed for the creation of CServerRepository object.
+//Used also to track Get/Set/Create/Delete setting notifications, received
+//from CServerRepository object.
+class CTestObserver : public CBase, public MObserver
+	{
+public:
+	CTestObserver();
+	void Notify(TUint32 aId);
+
+public:
+	TBool iAssertNotification;
+
+	};
+
+CTestObserver::CTestObserver() :
+	iAssertNotification(EFalse)
+	{
+	}
+
+void CTestObserver::Notify(TUint32 aId)
+	{
+	RDebug::Print(_L("Notification! Id=%d.\n"), aId);
+	if(iAssertNotification)
+		{
+		TEST(0);
+		}
+	}
+
+///////////////////////////////////////////////////////////////////////////////////////
+//
+
+//Deletes the global TheObserver object. Sets it to NULL.
+static void ReleaseObserver(TAny*)
+	{
+	delete TheObserver;
+	TheObserver = NULL;
+	}
+
+//Deletes the global TheServerRepository object. Sets it to NULL.
+static void ReleaseRepository(TAny*)
+	{
+	TheServerRepository->Close();
+	delete TheServerRepository;
+	TheServerRepository = NULL;
+	TServerResources::iCacheManager->DisableCache(ETrue);
+	TServerResources::iObserver->CloseiOpenRepositories();
+	TServerResources::iCacheManager->EnableCache();
+	}
+
+//This function is called from CreateSetting_OOMtestL().
+//It creates an integer, real or string setting in the repository
+//with ID=KTestRepositoryId. All this is done in an OOM loop.
+//The output from this test is: the repository file with ID = KTestRepositoryId
+//will be copied from Z to C drive;
+// An integer, real or string setting will be created in that repository.
+//Changes in the repository will be stored on C drive (in the related repository file)
+static void DoCreateSettingL(TBool aTrapping,TServerSetting::TType aSettingType)
+	{
+	TheObserver = new (ELeave) CTestObserver;
+	TCleanupItem clnItem1(&ReleaseObserver, NULL);
+	CleanupStack::PushL(clnItem1);
+
+	TheServerRepository = new (ELeave) CServerRepository;
+	TCleanupItem clnItem2(&ReleaseRepository, NULL);
+	CleanupStack::PushL(clnItem2);
+
+	// Turn OOM trapping on Repository Open on/off for testing purposes.
+	TServerResources::iObserver->iTrapOOMOnOpen=aTrapping;
+	// Open the repository
+	TheServerRepository->OpenL(KTestRepositoryId, *TheObserver);
+
+	// All write operations, including CreateL must be done in a transaction
+	TheServerRepository->StartTransaction(CRepository::EConcurrentReadWriteTransaction);
+	TheServerRepository->CleanupCancelTransactionPushL();
+
+	//Create the appropriate setting based on aValueType
+	switch(aSettingType)
+		{
+		case TServerSetting::EInt:
+			{
+			// Create setting - fails if value already there (it must not be)
+			User::LeaveIfError(TheServerRepository->TransactionCreateL(KIntSettingID, KIntSettingVal, NULL));
+
+			// Try to get the value from the transaction cache
+			TInt val = 0;
+			User::LeaveIfError(TheServerRepository->Get(KIntSettingID, val));
+			TEST2(val,KIntSettingVal);
+			break;
+			}
+
+		case TServerSetting::EReal:
+			{
+			// Create setting - fails if value already there (it must not be)
+			User::LeaveIfError(TheServerRepository->TransactionCreateL(KRealSettingID, KRealSettingVal, NULL));
+
+			// Try to get the value from the transaction cache
+			TReal val = 0;
+			User::LeaveIfError(TheServerRepository->Get(KRealSettingID, val));
+			TEST(val == KRealSettingVal);
+			break;
+			}
+
+		case TServerSetting::EString:
+			{
+			// Create setting - fails if value already there (it must not be)
+			User::LeaveIfError(TheServerRepository->TransactionCreateL(KStringSettingID, KStringSettingVal, NULL));
+
+			// Try to get the value from the transaction cache
+			TBuf8<16> bufVal(KEmptyString);
+			User::LeaveIfError(TheServerRepository->Get(KStringSettingID, bufVal));
+			TEST(bufVal == KStringSettingVal);
+			break;
+			}
+		default:
+			break;
+		}
+
+	// Commit the changes
+	CleanupStack::Pop();
+	TUint32 keyInfo;
+	User::LeaveIfError(TheServerRepository->CommitTransaction(keyInfo));
+
+	TServerResources::iObserver->iTrapOOMOnOpen=EFalse;
+	// Close the repository
+	TheServerRepository->Close();
+
+	CleanupStack::PopAndDestroy(2);//TheObserver & TheServerRepository
+	}
+
+//This function is called from SetSetting_OOMtest().
+//It expects that the previous test (CreateSetting_OOMtestL()) had completed successfully
+//and there is a repository file (ID=0x10) on drive C and there is an integer setting
+//in that repository (ID=KIntSettingID, Value=KIntSettingVal).
+//The test will try to change the setting value in a transaction. Because the test is
+//executed in an OOM loop, CommitChangesL() - will fail when called by SetL, leaving the
+//repository content inconsistent - the in-memory repository content will be deleted
+//(no settings), but in  the file the setting will exist and its value will still be KIntSettingVal.
+static void DoSetIntSettingL()
+	{
+	TEST(TheObserver != NULL);
+	TEST(TheServerRepository != NULL);
+	// Check if the setting is there - and has (or is restored to) the original value
+	TInt val = 0;
+	User::LeaveIfError(TheServerRepository->Get(KIntSettingID, val));
+	TEST2(val,KIntSettingVal);
+
+	// Change the setting value
+	// All write operations, including CreateL must be done in a transaction
+	TheServerRepository->StartTransaction(CRepository::EConcurrentReadWriteTransaction);
+	TheServerRepository->CleanupCancelTransactionPushL();
+	// Change the setting value
+	User::LeaveIfError(TheServerRepository->TransactionSetL(KIntSettingID, KIntSettingVal + 1));
+
+	// Check if the setting is there - it should be in transaction cache now
+	User::LeaveIfError(TheServerRepository->Get(KIntSettingID, val));
+	TEST2(val,(KIntSettingVal + 1));
+
+	// Commit the changes
+	CleanupStack::Pop();
+	TUint32 keyInfo;
+	User::LeaveIfError(TheServerRepository->CommitTransaction(keyInfo));
+
+	// Check if the setting is there. The transaction was successful so the new value
+	// should be returned.
+	val = 0;
+	User::LeaveIfError(TheServerRepository->Get(KIntSettingID, val));
+	TEST2(val,(KIntSettingVal + 1));
+	}
+
+//This function is called from SetSetting_OOMtest().
+//It expects that the previous test (CreateSetting_OOMtestL()) had completed successfully
+//and there is a repository file (ID=0x10) on drive C and there is an rea; setting
+//in that repository (ID=KRealSettingID, Value=KRealSettingVal).
+//The test will try to change the setting value in a transaction. Because the test is
+//executed in an OOM loop, CommitChangesL() - will fail when called by SetL, leaving the
+//repository content inconsistent - the in-memory repository content will be deleted
+//(no settings), but in  the file the setting will exist and its value will still be KRealSettingVal.
+static void DoSetRealSettingL()
+	{
+	TEST(TheObserver != NULL);
+	TEST(TheServerRepository != NULL);
+	// Check if the setting is there - and has (or is restored to) the original value
+	TReal val = 0;
+	User::LeaveIfError(TheServerRepository->Get(KRealSettingID, val));
+	TEST(val == KRealSettingVal);
+
+	// Change the setting value
+	// All write operations, including CreateL must be done in a transaction
+	TheServerRepository->StartTransaction(CRepository::EConcurrentReadWriteTransaction);
+	TheServerRepository->CleanupCancelTransactionPushL();
+	// Change the setting value
+	User::LeaveIfError(TheServerRepository->TransactionSetL(KRealSettingID, KRealSettingVal2));
+
+	// Check if the setting is there - it should be in transaction cache now
+	User::LeaveIfError(TheServerRepository->Get(KRealSettingID, val));
+	TEST(val == KRealSettingVal2);
+
+	// Commit the changes
+	CleanupStack::Pop();
+	TUint32 keyInfo;
+	User::LeaveIfError(TheServerRepository->CommitTransaction(keyInfo));
+
+	// Check if the setting is there. The transaction was successful so the new value
+	// should be returned.
+	val = 0;
+	User::LeaveIfError(TheServerRepository->Get(KRealSettingID, val));
+	TEST(val == KRealSettingVal2);
+	}
+
+//This function is called from SetSetting_OOMtest().
+//It expects that the previous test (CreateSetting_OOMtestL()) had completed successfully
+//and there is a repository file (ID=0x10) on drive C and there is an string setting
+//in that repository (ID=KStringSettingID, Value=KStringSettingVal).
+//The test will try to change the setting value in a transaction. Because the test is
+//executed in an OOM loop, CommitChangesL() - will fail when called by SetL, leaving the
+//repository content inconsistent - the in-memory repository content will be deleted
+//(no settings), but in  the file the setting will exist and its value will still
+//be KStringSettingVal.
+static void DoSetStringSettingL()
+	{
+	TEST(TheObserver != NULL);
+	TEST(TheServerRepository != NULL);
+
+	// Check if the setting is there - and has (or is restored to) the original value
+	TBuf8<16> bufVal(KEmptyString);
+	User::LeaveIfError(TheServerRepository->Get(KStringSettingID, bufVal));
+	TEST(bufVal == KStringSettingVal);
+
+	// Change the setting value
+	// All write operations, including CreateL must be done in a transaction
+	TheServerRepository->StartTransaction(CRepository::EConcurrentReadWriteTransaction);
+	TheServerRepository->CleanupCancelTransactionPushL();
+
+	// Change the setting value
+	User::LeaveIfError(TheServerRepository->TransactionSetL(KStringSettingID, KStringSettingVal2));
+
+	// Check if the setting is there - it should be in transaction cache now
+	User::LeaveIfError(TheServerRepository->Get(KStringSettingID, bufVal));
+	TEST(bufVal == KStringSettingVal2);
+	// Commit the changes
+	CleanupStack::Pop();
+	TUint32 keyInfo;
+	User::LeaveIfError(TheServerRepository->CommitTransaction(keyInfo));
+
+	// Check if the setting is there. The transaction was successful so the new value
+	// should be returned.
+	bufVal = KEmptyString;
+	User::LeaveIfError(TheServerRepository->Get(KStringSettingID, bufVal));
+	TEST(bufVal == KStringSettingVal2);
+	}
+
+//This function is called from SetSetting_OOMtest()in the case where previous
+//DoSetSettingL() call failed with KErrNoMemory, leaving the repository object
+//in inconsisten state - the in-memory presentation of the repository differs from
+//the repository file content. The function will try to repair the repository,
+//as it would have to happen in a real situation. Then it will check that
+//the repository content is consistent, which means the tested setting value should
+//be the same as it was before DoSetSettingL() call.
+static void DoRecoverRepositoryL(TServerSetting::TType aSettingType)
+	{
+	//Repair the repository as it happens in a real situation
+	//AccessL calls RestoreConsistencyL() indirectly
+	//RestoreConsistencyL() is called in the production code from the session object,
+	//ServiceL() implementation. So, it will be called before any other repository call
+	//and it should restore the repository content - it should repair the repository
+	//consitency.
+	TServerResources::iObserver->AccessL(KTestRepositoryId);
+	//Check if the setting is there - the old, pre-transactional value should be
+	//in-memory now.
+	switch(aSettingType)
+		{
+		case TServerSetting::EInt:
+			{
+			TInt val = 0;
+			User::LeaveIfError(TheServerRepository->Get(KIntSettingID, val));
+			TEST2(val,KIntSettingVal);
+			break;
+			}
+
+		case TServerSetting::EReal:
+			{
+			TReal val = 0;
+			User::LeaveIfError(TheServerRepository->Get(KRealSettingID, val));
+			TEST(val == KRealSettingVal);
+			break;
+			}
+
+		case TServerSetting::EString:
+			{
+			TBuf8<16> bufVal(KEmptyString);
+			User::LeaveIfError(TheServerRepository->Get(KStringSettingID, bufVal));
+			TEST(bufVal == KStringSettingVal);
+			break;
+			}
+		default:
+			break;
+		}
+	}
+
+//Inits TServerResources object.
+//It should be called once, before the creation of CServerRepository object.
+static void InitEnvL()
+	{
+	TServerResources::InitialiseL();
+
+	delete TServerResources::iDataDirectory; TServerResources::iDataDirectory = NULL;
+	delete TServerResources::iRomDirectory; TServerResources::iRomDirectory = NULL;
+	delete TServerResources::iInstallDirectory; TServerResources::iInstallDirectory = NULL;
+
+	TServerResources::iDataDirectory = HBufC::NewL(KMaxFileName);
+	TServerResources::iRomDirectory = HBufC::NewL(KMaxFileName);
+	TServerResources::iInstallDirectory = HBufC::NewL(KMaxFileName);
+
+	TBuf<32> uidName;
+	uidName.Format(_L("%08X"), KCenRepServerUID.iUid);
+
+	TPtr ptr1(TServerResources::iDataDirectory->Des());
+	ptr1.Append(_L("C:\\PRIVATE\\"));
+	ptr1.Append(uidName);
+	ptr1.Append(_L("\\PERSISTS\\"));
+
+	TPtr ptr2(TServerResources::iRomDirectory->Des());
+	ptr2.Append(_L("Z:\\PRIVATE\\"));
+	ptr2.Append(uidName);
+	ptr2.Append(_L("\\"));
+
+	TPtr ptr3(TServerResources::iInstallDirectory->Des());
+	ptr3.Append(_L("C:\\PRIVATE\\"));
+	ptr3.Append(uidName);
+	ptr3.Append(_L("\\"));
+	}
+
+//Destroys TServerResources object.
+//It should be called after the CServerRepository object was destroyed.
+static void ReleaseEnv()
+	{
+	TServerResources::Close();
+	}
+
+//Creates global TheServerRepository and TheObserver objects
+//It is used in SetSetting_OOMtest()
+static void InitEnv2L()
+	{
+	TheObserver = new CTestObserver;
+	TEST(TheObserver != NULL);
+
+	TheServerRepository = new CServerRepository;
+	TEST(TheServerRepository != NULL);
+
+	TheServerRepository->OpenL(KTestRepositoryId, *TheObserver);
+	}
+
+//Destroys global TheServerRepository and TheObserver objects
+//It is used in SetSetting_OOMtest()
+static void ReleaseEnv2()
+	{
+	::ReleaseRepository(NULL);
+	::ReleaseObserver(NULL);
+	}
+
+//Central repository test: it creates a setting in OOM conditions.
+static void CreateSetting_OOMtestL(TBool aTrapping,TServerSetting::TType aSettingType)
+	{
+	TInt err;
+	TRAP(err, ::InitEnvL());
+	TEST2(err, KErrNone);
+	for(TInt count=1;;++count)
+		{
+		CleanupCDriveL();
+		__UHEAP_FAILNEXT(count);
+		__UHEAP_MARK;
+
+		TRAP(err, ::DoCreateSettingL(aTrapping,aSettingType));
+
+		TServerResources::iOwnerIdLookUpTable.Reset();
+		TServerResources::iObserver->Reset();
+
+		__UHEAP_MARKEND;
+
+		if(err == KErrNone)
+			{
+			RDebug::Print(_L("The test succeeded at heap failure rate=%d.\n"), count);
+			break;
+			}
+		else if(err != KErrNoMemory)
+			{
+			TEST2(err, KErrNone);
+			}
+		}
+
+	::ReleaseEnv();
+	__UHEAP_RESET;
+	}
+
+//Central repository test: it sets new setting value in OOM conditions.
+//Then ComitChangesL() is called to store the new setting's value in the repository
+//file. Because of the simulated OOM conditions ComitChangesL() can fail, leaving the
+//repository in inconsistent state.
+//DoRecoverRepositoryL() is called to repair the repository and restore the consistency.
+static void SetSetting_OOMtest(TServerSetting::TType aSettingType)
+	{
+	TTime before;
+	TTime after;
+	// Check that cre file exists and get modification time
+	TEST2 (GetFileTimeStamp(KCreTestFile1, before), KErrNone);
+	after=before;
+
+	TInt err;
+	TRAP(err, ::InitEnvL());
+	TEST2(err, KErrNone);
+	TRAP(err, ::InitEnv2L());
+	TEST2(err, KErrNone);	
+	for(TInt count=1;;++count)
+		{
+		__UHEAP_FAILNEXT(count);
+		__UHEAP_MARK;
+
+	switch(aSettingType)
+		{
+		case TServerSetting::EInt:
+			{
+			TRAP(err, ::DoSetIntSettingL());
+			break;
+			}
+		case TServerSetting::EReal:
+			{
+			TRAP(err, ::DoSetRealSettingL());
+			break;
+			}
+		case TServerSetting::EString:
+			{
+			TRAP(err, ::DoSetStringSettingL());
+			break;
+			}
+		default:
+			break;
+		}
+
+		// Get timestamp of cre file. It is now possible for the commit to
+		// fail with KErrNoMemory after a successful write. If filestamp
+		// changes, the cre file has been written and the test is complete
+		TEST2 (GetFileTimeStamp(KCreTestFile1, after), KErrNone);
+		if(before!=after)
+			{
+			err=KErrNone;
+			}
+
+		if(err == KErrNoMemory)
+			{
+			__UHEAP_MARKEND;
+			//DoSetSettingL() call failed (so the transaction). Try to recover.
+			TInt err2;
+			TRAP(err2, ::DoRecoverRepositoryL(aSettingType));
+			TEST2(err2, KErrNone);
+			}
+		else if(err == KErrNone)
+			{
+			//The heap cannot be checked at this point because memory may have been
+			//allocated which must be freed by a call to ReleaseEnv2.
+			//It is checked outside the loop instead
+			RDebug::Print(_L("The test succeeded at heap failure rate=%d.\n"), count);
+			break;
+			}
+		else
+			{
+			__UHEAP_MARKEND;
+			TEST2(err, KErrNone);
+			}
+		// Check that tmp file generated by attempted commit is deleted
+		// by RestoreConsistencyL() in DoRecoverRepositoryL().
+		::CheckTmpFileDeleted();
+		}
+	// Check that no tmp file is left over
+	::ReleaseEnv2();
+	::ReleaseEnv();
+	//This __UHEAP_MARKEND checks the heap after the call to DoSetxSettings
+	//succeeds as calls to CommitTRansactions can allocate memory which must be freed
+	//by calling ReleaseEnv2
+	__UHEAP_MARKEND;
+	__UHEAP_RESET;
+	}
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+void RunTestsL(TServerSetting::TType aSettingType)
+	{
+
+	TheTest.Next(_L("Create setting - OOM test - OOM Trapping off"));
+	::CreateSetting_OOMtestL(EFalse,aSettingType);
+
+	TheTest.Next(_L("Create setting - OOM test - OOM Trapping on"));
+	::CreateSetting_OOMtestL(ETrue,aSettingType);
+
+	TheTest.Next(_L("Set setting - transaction - OOM test"));
+	::SetSetting_OOMtest(aSettingType);
+
+	}
+
+static void MainL()
+	{
+	// create and install the active scheduler we need for the cache manager in TServerResources::InitialiseL
+	CActiveScheduler* cacheManagerAS=new(ELeave) CActiveScheduler;
+	CleanupStack::PushL(cacheManagerAS);
+	CActiveScheduler::Install(cacheManagerAS);
+
+	::DeleteFiles();
+
+	TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-LEGACY-T_CENREPTRANS-0001 Int Setting Tests "));
+	RunTestsL(TServerSetting::EInt);
+
+	TheTest.Next(_L("Real Setting Tests"));
+	RunTestsL(TServerSetting::EReal);
+
+	TheTest.Next(_L("String Setting Tests"));
+	RunTestsL(TServerSetting::EString);
+
+	TheTest.End();
+	TheTest.Close();
+
+	CleanupStack::PopAndDestroy(cacheManagerAS);
+	}
+
+TInt E32Main()
+	{
+	__UHEAP_MARK;
+
+	CTrapCleanup* tc = CTrapCleanup::New();
+	TEST(tc != NULL);
+
+	TheTest.Title();
+	TRAPD(err, ::MainL());
+	TEST2(err, KErrNone);
+
+	::DeleteFiles();
+
+	delete tc;
+
+	__UHEAP_MARKEND;
+
+	User::Heap().Check();
+	return KErrNone;
+	}