diff -r 000000000000 -r 08ec8eefde2f persistentstorage/centralrepository/test/t_cenrep_defects.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/persistentstorage/centralrepository/test/t_cenrep_defects.cpp Fri Jan 22 11:06:30 2010 +0200 @@ -0,0 +1,2913 @@ +// Copyright (c) 2004-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 +#include +#include +#include +#include +#include + +#include "e32math.h" +#include "srvparams.h" +#include "srvreqs.h" +#include "srvdefs.h" +#include "transstate.h" +#include "obsrvr_noc.h" +#include "shrepos.h" +#include "install.h" + +using namespace NCentralRepositoryConstants; + +RTest TheTest(_L("Central Repository Defect Tests")); + +_LIT( KCentralRepositoryServerName, "Centralrepositorysrv"); + +const TUid KUidDEF060843LRepository1 = { 0x00000001 }; +const TUid KUidRep1 = { 0x00000100 }; +const TUid KUidDEF053500LTestRepository = { 0x00000102 }; +const TUid KUidDEF054368TestRepository = { 0x00000103 }; +const TUid KUidINC054688TestRepository = { 0x100058db }; +const TUid KUidDEF054632TestRepository = { 0x10054632 }; +const TUid KUidDEF054633TestRepository = { 0x10054633 }; +const TUid KUidLargeRepository = { 0xCCCCCC01 }; +const TUid KUidDEF055661TestRepository = { 0x10055661 }; +const TUid KUidINC056194TestRepository = { 0x00056194 }; +const TUid KUidDEF057778TestRepository = { 0x00057778 }; +const TUid KUidDEF057470TestRepository = { 0x10057470 }; +const TUid KUidDEF058900TestRepository = { 0x10058900 }; +const TUid KUidINC069013TestRepository = { 0x00000104 }; +const TUid KUidPDEF098500LRepository = { 0x10098500 }; + +const TUint32 KRangeDeletePartialKey = 0x04010000 ; +const TUint32 KDeleteKeyDoesntExist = 0x07000000 ; +const TUint32 KDeleteForbidden = 0x03010000 ; +const TUint32 KTransactionRangeDeletePartialKey = 0x02010000 ; +const TUint32 KRangeDeleteMask = 0x0F0F0000 ; +const TUint32 KNullKey = 0x00000000 ; + +const TUint32 KNotifyBannedKey = static_cast(KRequestPending) ; +const TUint32 KNotificationKey1 = 0x80000101; +const TUint32 KNotificationKey2 = 0x80000201; +const TUint32 KNotificationKey3 = 0x80000301; +const TUint32 KNotificationKey4 = 0x80000401; + +// +// Repository A +// + +const TUint32 KNewInt = 1000; +const TInt KIntValue = 1234; + + +// Definitions for test DEF116629L() +// The structure to construct a TServerSetting object with a TInt value. +struct ServerSettingStruct + { + TUint32 key; + TUint32 meta; + TInt value; + }; +// The merge types to be tested +const TMergeType KMergerTypes[] = {ETransactionMerge,ERestoreMerge, ESWIUpgradeMerge, ESWIDowngradeMerge, ERomFlash}; + + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// +//Test macroses and functions +LOCAL_C void CheckL(TInt aValue, TInt aLine) + { + if(!aValue) + { + CleanupCDriveL(); + TheTest(EFalse, aLine); + } + } +LOCAL_C void CheckL(TInt aValue, TInt aExpected, TInt aLine) + { + if(aValue != aExpected) + { + RDebug::Print(_L("*** Expected error: %d, got: %d\r\n"), aExpected, aValue); + CleanupCDriveL(); + TheTest(EFalse, aLine); + } + } + +#define TEST(arg) ::CheckL((arg), __LINE__) +#define TEST2(aValue, aExpected) ::CheckL(aValue, aExpected, __LINE__) + +/////////////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////// + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-4015 +@SYMTestCaseDesc When having multiple connections to a particular repository, starting a +transaction and then killing that connection, should not cause a reset. +@SYMTestPriority High +@SYMTestActions + Essentially - this deals with multiple connections, the lack of cancelling a transaction, + either by shutting the sub-session to the CR server directly (or by a crashing application + where all open sub-sessions to CR from that application are closed) and the cache manager + inside CR. + + Previously, CR's cache manager would reclaim repository memory regardless of the state + of the repository (in transaction or not). However, if a repository is closed and its + no longer an open repository (cache manager reclaimed the memory), it would not remove + references to the sub-session for this repository in the transaction queue. Simply put, + the sub-session's data would be deleted but there would still be references to that + deleted data. When you established a new connection (any operation would cause this) you'd + walk down an invalid pointer. Most of the time this would cause the server to crash. + + Now, if you're in an active transaction, the cache manager does not reclaim the data. + Which means that there will always be valid references in the transaction queue. + + ThreadA CR CR Cache Manager + Connection 1. + CRepository::NewLC(X) ---------------> EInitialize + + Connection 2. + CRepository::NewLC(X) ---------------> EInitialize + + Connection 2, Start Transaction + StartTransaction ----------------> ETransactionStart + + Before + ---------------------------------------------------------------------------------- + Wait 10 seconds + + <--------------------------- Evict(X) + + Connection 2. Close + delete connection2 ------------------> EClose (would leave invalid references) + + Connection 1. + GetInt ------------------> EGetInt (would attach to repository, derefence + invalid pointer, CR would crash) + + ----------------------------------------------------------------------------------- + Now + + Wait 10 seconds + + Reschedule + (CR cache manager sees that Repository X + is in a transaction and just reschedules + it) + Connection 2. Close + delete connection2 --------------------> EClose (memory is now available so it cancels + the active transaction) + + GetInt --------------------> EGetInt (attaches to the open repository, all is + fine) + delete connection2 --------------------> EClose (repository X has no more observers so + it is scheduled to have its memory reclaimed + by CR cache manager) + +@SYMTestExpectedResults The test must not fail. +@SYMDEF DEF111734 +*/ + +LOCAL_C void DEF111734L() + { + /* first establish a connection. this is important because if there are no observers + * on a repository, the repository's shared data is deleted directly */ + CRepository* rep; + User::LeaveIfNull(rep = CRepository::NewLC(KUidDEF054368TestRepository)); + + /* second establish a second connection. this will be used to start a transaction */ + CRepository* rep2; + User::LeaveIfNull(rep2 = CRepository::NewLC(KUidDEF054368TestRepository)); + + /* establish a transaction, this manipulates the transaction queue for this repository */ + rep2->StartTransaction(CRepository::EConcurrentReadWriteTransaction); + + /* now wait. this should be plenty of time to allow cache manager in CR to reclaim + * the data for this repository */ + User::After(5050000 + 9500000); + + TInt i = 0; + const TInt KInt1_InitialValue = 100; + const TUint32 KInt1 = 0x1; + + /* destory the connection - this will cause a "close" operation in CR */ + CleanupStack::PopAndDestroy(rep2); + + /* attempt to reconnect to the repository. */ + TInt r = rep->Get(KInt1, i); + + /* if the fix is not in the build, then CR will crash. + * Errcode will be KErrServerTerminated */ + TEST2(r, KErrNone); + + /* just for completion's sake, check the return value */ + TEST(i == KInt1_InitialValue); + + // Close repository + + CleanupStack::PopAndDestroy(rep); + } + + +LOCAL_C void DEF053500L() + { + CRepository* rep; + // Open repository with hex key value setting + User::LeaveIfNull(rep = CRepository::NewLC(KUidDEF053500LTestRepository)); + // Close repository + CleanupStack::PopAndDestroy(rep); + } + +LOCAL_C void DEF054368L() + { + CRepository* rep; + User::LeaveIfNull(rep = CRepository::NewLC(KUidDEF054368TestRepository)); + + TInt i = 0; + const TInt KInt1_InitialValue = 100; + const TInt KInt2_InitialValue = 200; + const TInt KInt3_InitialValue = -100; + const TInt KInt4_InitialValue = -200; + const TInt KInt5_InitialValue = 0xc8; + + const TUint32 KInt1 = 0x1; + const TUint32 KInt2 = 0x2; + const TUint32 KInt3 = 0x3; + const TUint32 KInt4 = 0x4; + const TUint32 KInt5 = 0x5; + + TInt r = rep->Get(KInt1, i); + TEST2(r, KErrNone); + TEST(i==KInt1_InitialValue); + + r = rep->Get(KInt2, i); + TEST2(r, KErrNone); + TEST(i==KInt2_InitialValue); + + r = rep->Get(KInt3, i); + TEST2(r, KErrNone); + TEST(i==KInt3_InitialValue); + + r = rep->Get(KInt4, i); + TEST2(r, KErrNone); + TEST(i==KInt4_InitialValue); + + r = rep->Get(KInt5, i); + TEST2(r, KErrNone); + TEST(i==KInt5_InitialValue); + + // Close repository + CleanupStack::PopAndDestroy(rep); + } + +LOCAL_C void DEF055680L() + { + CRepository* rep; + // Open repository + User::LeaveIfNull(rep = CRepository::NewLC(KUidLargeRepository)); + + // Find setting whose value the test doesn't have permission to look at + RArray foundIds; + TInt r = KErrNone; + r = rep->FindL(0x810100, 0xFFFFFFFF, foundIds); + TEST2(r, KErrNone); + TEST2(foundIds.Count(), 1); + + TInt val; + r = rep->Get(foundIds[0], val); + TEST2(r, KErrPermissionDenied); + foundIds.Reset(); + + r = rep->Create(KNewInt, KIntValue); + TEST2(r, KErrNone); + + //Reset repository to remove any changes made during this test + r = rep->Reset(); + TEST2(r, KErrNone); + + // Close repository + CleanupStack::PopAndDestroy(rep); + + } + +LOCAL_C void DEF054632L() + { + CRepository* rep; + + //----------Testing for correct default policy behaviour--------------- + /*---------------------10054632.txt------------------------------------ + [platsec] + cap_rd=ReadDeviceData cap_wr=WriteDeviceData + 0x3 0x4 cap_wr=NetworkServices + [Main] + 0x1 int 1 0 cap_rd=CommDD + 0x2 int 2 1 cap_wr=CommDD + 0x3 int 3 0 + 0x4 int 4 0 + 0x5 int 5 0 cap_rd=CommDD + ---------------------------------------------------------------------*/ + User::LeaveIfNull(rep = CRepository::NewLC(KUidDEF054632TestRepository)); + + //testing single policies + TInt err=KErrNone; + const TInt key_2=2; + const TInt key_1=1; + TInt value=0; + + err=rep->Get(key_2,value); + TEST2(err,KErrNone); + + err=rep->Set(key_1,value); + TEST2(err,KErrNone); + + //testing range policies + const TInt key_3=3; + err=rep->Get(key_3,value); + TEST2(err,KErrNone); + + CleanupStack::PopAndDestroy(rep); + + //------Testing for correct policy behaviour with no default policies----- + /*--------------------------10054633.txt---------------------------------- + [platsec] + 0x3 0x4 cap_rd=CommDD + [Main] + 0x1 int 1 0 cap_rd=CommDD + 0x2 int 2 1 cap_wr=CommDD + 0x3 int 3 0 + 0x4 int 4 0 + ------------------------------------------------------------------------*/ + User::LeaveIfNull(rep=CRepository::NewLC(KUidDEF054633TestRepository)); + + //testing single policies + err=rep->Get(key_1,value); + TEST2(err,KErrPermissionDenied); + err=rep->Set(key_1,value); + TEST2(err,KErrPermissionDenied); + + err=rep->Set(key_2,value); + TEST2(err,KErrPermissionDenied); + err=rep->Get(key_2,value); + TEST2(err,KErrPermissionDenied); + + //testing range policies + err=rep->Get(key_3,value); + TEST2(err,KErrPermissionDenied); + const TInt key_4=4; + err=rep->Set(key_4,value); + TEST2(err,KErrPermissionDenied); + err=rep->Get(key_4,value); + TEST2(err,KErrPermissionDenied); + + CleanupStack::PopAndDestroy(rep); + } + +/** +This test will be checking the robustness of the modified array structure +for the single policies, range policies. +*/ +LOCAL_C void INC054688L() + { + CRepository* rep; + User::LeaveIfNull(rep = CRepository::NewLC(KUidINC054688TestRepository)); + + //--------------CHECKING THE SINGLE POLICIES ARRAY---------------------- + //The ini file has been structured so that the key will be equal to the + //key value so we can test it using a loop. + //and also to check some policy checking, we set all the even entries to + //be non accessible due to insufficient capabilities + //The key tested for the single policies are from 1 to 24 + const TInt KMaxKeyEntry=24; + TInt err=KErrNone; + TInt key_value=0; + for (TInt i=1;i<=KMaxKeyEntry;i++) + { + err=rep->Get(i,key_value); + //even entries alway not accessible due to insufficient caps + if (i%2==0) + TEST2(err,KErrPermissionDenied); + else + { + TEST2(err,KErrNone); + TEST2(i,key_value); + } + } + + //--------------CHECKING THE RANGE POLICIES ARRAY---------------------- + //The range policies in the [platsec] section are arranged in key pairs + //e.g 25-26,27-28.For testing purpose, the odd pairs(e.g 25-26 is the + //first pair) will require capabilities that the test lacks off hence + //causing KErrPermissionDenied when trying to read those range. + //The key tested for the arary policies are from 25-38 and the value + //matches the key + + const TInt startRangeKey=25; + const TInt KMaxRangeKey=38; + TInt numberOfPairs=(KMaxRangeKey-startRangeKey+1)/2; + TInt key_value1=0; + TInt err1=KErrNone; + for (TInt j=0;jGet(startRangeKey+(2*j),key_value); + //Get second key of the pair + err1=rep->Get(startRangeKey+(2*j)+1,key_value1); + //start from j=0(first pair) + if ((j+1)%2==0) + { + TEST2(err,KErrNone); + TEST2(err1,KErrNone); + TEST2(startRangeKey+(2*j),key_value); + TEST2(startRangeKey+(2*j)+1,key_value1); + } + //only odd pairs are non-accessible due to insufficient caps + else + { + TEST2(err,KErrPermissionDenied); + TEST2(err1,KErrPermissionDenied); + } + } + + //Before closing the repository, modify one of the key to see whether + //the policy array behaves similarly after a rewrite of the ini file + const TInt keyToChange=3; + const TInt modifiedValue=3; + err=rep->Set(keyToChange,modifiedValue); + TEST2(err,KErrNone); + + // Close repository + CleanupStack::PopAndDestroy(rep); + User::After(KGeneralDelay); + + //Reopen the repository again after that minor update which will cause + //all the entry in the ini file to be reversed + User::LeaveIfNull(rep = CRepository::NewLC(KUidINC054688TestRepository)); + + //---------RECHECKING THE POLICY ARRAY AFTER UPDATE-------------------- + for (TInt i=1;i<=KMaxKeyEntry;i++) + { + err=rep->Get(i,key_value); + //even entries alway not accessible due to insufficient caps + if (i%2==0) + TEST2(err,KErrPermissionDenied); + else + { + TEST2(err,KErrNone); + TEST2(i,key_value); + } + } + + + //---------RECHECKING THE RANGE POLICY ARRAY AFTER UPDATE------------- + for (TInt j=0;jGet(startRangeKey+(2*j),key_value); + //Get second key of the pair + err1=rep->Get(startRangeKey+(2*j)+1,key_value1); + //start from j=0(first pair) + if ((j+1)%2==0) + { + TEST2(err,KErrNone); + TEST2(err1,KErrNone); + TEST2(startRangeKey+(2*j),key_value); + TEST2(startRangeKey+(2*j)+1,key_value1); + } + //only odd pairs are non-accessible due to insufficient caps + else + { + TEST2(err,KErrPermissionDenied); + TEST2(err1,KErrPermissionDenied); + } + } + + CleanupStack::PopAndDestroy(rep); + } + +LOCAL_C void DEF055661L() + { + /*--------------------10055661.txt---------------------------------------- + [platsec] + cap_rd=ReadDeviceData cap_wr=AlwaysFail + 0x3 0x4 cap_wr=NetworkServices + [Main] + 0x1 int 1 0 cap_rd=AlwaysPass + 0x2 int 2 1 cap_rd=AlwaysFail + 0x3 int 3 0 + 0x4 int 4 0 cap_rd=AlwaysFail + 0x5 int 5 0 cap_wr=AlwaysPass + -------------------------------------------------------------------------*/ + CRepository* rep; + User::LeaveIfNull(rep = CRepository::NewLC(KUidDEF055661TestRepository)); + + TInt err=KErrNone; + TInt keyValue=0; + + //Key 1 + err=rep->Get(1,keyValue); + TEST2(err,KErrNone); + TEST2(keyValue,1); + err=rep->Set(1,keyValue); + TEST2(err,KErrPermissionDenied); + + //Key 2 + err=rep->Get(2,keyValue); + TEST2(err,KErrPermissionDenied); + err=rep->Set(2,keyValue); + TEST2(err,KErrPermissionDenied); + + //Key 3 + err=rep->Get(3,keyValue); + TEST2(err,KErrNone); + TEST2(keyValue,3); + err=rep->Set(3,keyValue); + TEST2(err,KErrPermissionDenied); + + //Key 4 + err=rep->Get(4,keyValue); + TEST2(err,KErrPermissionDenied); + err=rep->Set(4,keyValue); + TEST2(err,KErrPermissionDenied); + + //Key 5 + err=rep->Get(5,keyValue); + TEST2(err,KErrNone); + err=rep->Set(5,keyValue); + TEST2(err,KErrNone); + + CleanupStack::PopAndDestroy(rep); + } + +LOCAL_C void DEF055267L() + { + CRepository* rep; + // Open repository + User::LeaveIfNull(rep = CRepository::NewLC(KUidLargeRepository)); + + TInt r; + TUint32 errorId; + // The following loop creates enough settings to blow the server heap + // when it's 1 M. If it passes it proves that the server heap is > 1M + // Increasing the server heap allows the messaging test to pass + _LIT(KString, "Long test string !!!!!!!!!!!"); + const TInt KNumTransactions=25; + const TInt KNumSettingsInTrans=100; + for(TInt numTransactions=0; numTransactionsStartTransaction(CRepository::EReadWriteTransaction); + TEST2(r, KErrNone); + for(TInt numSettingsInTrans=0; numSettingsInTransCreate((numTransactions*KNumSettingsInTrans)+numSettingsInTrans, KString); + TEST2(r, KErrNone); + } + r = rep->CommitTransaction(errorId); + TEST2(r, KErrNone); + } + + //Reset repository to remove any changes made during this test + r = rep->Reset(); + TEST2(r, KErrNone); + + // Close repository + CleanupStack::PopAndDestroy(rep); + } + +LOCAL_C void INC056194L() + { + CRepository* repository; + // Open repository + User::LeaveIfNull(repository = CRepository::NewLC(KUidINC056194TestRepository)); + + const TUint32 KInt1 = 1; + TRequestStatus intStatus; + + TInt r = repository->NotifyRequest(KInt1, intStatus); + TEST2(r, KErrNone); + r = repository->NotifyCancel(KInt1); + TEST2(r, KErrNone); + User::WaitForAnyRequest(); + TEST(intStatus==KUnspecifiedKey); + + r = repository->NotifyRequest(KInt1, intStatus); + TEST2(r, KErrNone); + r = repository->NotifyCancelAll(); + TEST2(r, KErrNone); + User::WaitForAnyRequest(); + TEST(intStatus==KUnspecifiedKey); + + r = repository->NotifyRequest(0, KInt1, intStatus); + TEST2(r, KErrNone); + r = repository->NotifyCancel(0, KInt1); + TEST2(r, KErrNone); + User::WaitForAnyRequest(); + TEST(intStatus==KUnspecifiedKey); + + RThread thisThread; + TEST(thisThread.RequestCount()==0); + + // Close repository + CleanupStack::PopAndDestroy(repository); + } + +LOCAL_C void DEF057145L() + { + TInt err=KErrNone; + const TUid testUid={0x10057145}; + RArray idArray; + CRepository* repository; + User::LeaveIfNull(repository = CRepository::NewLC(testUid)); + + //Start Transaction + err=repository->StartTransaction(CRepository::EReadWriteTransaction); + TEST2(err,KErrNone); + + //Before creating new entries get the number of persistent settings + err=repository->FindL(0,0xFFFFF000,idArray); + TEST2(err,KErrNone); + TInt persistentSettingsCount=idArray.Count(); + idArray.Close(); + + //Try creating new entries during transaction between the two extreme points + //ROM persistent file has low key of 1 and high key of 201 + //We try creating new entries in between during transaction + for (TInt i=100;i<150;i++) + { + err=repository->Create(i,i); + TEST2(err,KErrNone); + } + + //Now check the merge with the persistent settings is fine by checking + //the array count after the merge. + err=repository->FindL(0x000,0xFFFFF000,idArray); + TEST2(err,KErrNone); + TEST(idArray.Count()==(persistentSettingsCount+50)); + idArray.Close(); + + TUint32 errId; + err=repository->CommitTransaction(errId); + TEST2(err,KErrNone); + + idArray.Close(); + CleanupStack::PopAndDestroy(repository); + } + + +LOCAL_C void DEF057778L() + { + TInt r; + CRepository* repository; + // Open repository + User::LeaveIfNull(repository = CRepository::NewLC(KUidDEF057778TestRepository)); + + const TUint32 KInt14=14; + const TInt KInt14NewValue=0; + + r=repository->Set(KInt14,KInt14NewValue); + TEST2(r, KErrNone); + + // Reset setting that has a single policy + r=repository->Reset(KInt14); + TEST2(r, KErrNone); + + // Attempt to access and write setting + r=repository->Set(KInt14,KInt14NewValue); + TEST2(r, KErrNone); + + // Reset entire repository + r=repository->Reset(); + TEST2(r, KErrNone); + + // Attempt to access and write setting + r=repository->Set(KInt14,KInt14NewValue); + TEST2(r, KErrNone); + + // Reset entire repository + r=repository->Reset(); + TEST2(r, KErrNone); + + // Close repository + CleanupStack::PopAndDestroy(repository); + } + + +LOCAL_C void DEF057999L() + { + + TInt err=KErrNone; + TInt retValue=0; + const TUid testUid={0x10057145}; + RArray idArray; + + CRepository* repository; + User::LeaveIfNull(repository = CRepository::NewLC(testUid)); + + //--------------Start Transaction------------------------------------ + err=repository->StartTransaction(CRepository::EReadWriteTransaction); + TEST2(err,KErrNone); + + //--------------Create follow by delete----------------------------- + err=repository->Create(3400,3400); + TEST2(err,KErrNone); + err=repository->Delete(3400); + TEST2(err,KErrNone); + err=repository->Delete(3400); + TEST2(err,KErrNotFound); + + //--------------Deleting existing romkey----------------------------- + err=repository->Delete(200); + TEST2(err,KErrNone); + + err=repository->FindL(200,0xFFFFFFFF,idArray); + TEST2(err,KErrNotFound); + + //--------------Commit Transaction------------------------------------ + TUint32 errId; + err=repository->CommitTransaction(errId); + TEST2(err,KErrNone); + + idArray.Close(); + CleanupStack::PopAndDestroy(repository); + + //--------------Reopen and check the deleted keys are gone------------- + User::LeaveIfNull(repository = CRepository::NewLC(testUid)); + + //Check for the key created and deleted during transaction + err=repository->FindL(3400,0xFFFFFFFF,idArray); + TEST2(err,KErrNotFound); + + //Check for the rom key deleted during transaction + err=repository->Get(200,retValue); + TEST2(err,KErrNotFound); + + //--------------Start Transaction------------------------------------ + err=repository->StartTransaction(CRepository::EReadWriteTransaction); + TEST2(err,KErrNone); + + //--------------Delete follow by create----------------------------- + err=repository->Delete(201); + TEST2(err,KErrNone); + err=repository->Create(201, 201); + TEST2(err,KErrNone); + + //--------------Commit Transaction------------------------------------ + err=repository->CommitTransaction(errId); + TEST2(err,KErrNone); + + err=repository->Get(201,retValue); + TEST2(err,KErrNone); + TEST2(retValue, 201); + + CleanupStack::PopAndDestroy(repository); + } + +LOCAL_C void DEF057522L() + { + TInt r=KErrNone; + CRepository* repository; + TUid testUidRepository={0x10057522}; + + //Opening a repository with Max number of capabilities supported should not return KErrCorrupt + User::LeaveIfNull(repository = CRepository::NewLC(testUidRepository)); + + //Test reading some of the settings with the max capabilities defined + TInt retVal=0; + r=repository->Get(17,retVal); + TEST2(r,KErrNone); + r=repository->Set(17,retVal); + TEST2(r,KErrNone); + + r=repository->Get(18,retVal); + TEST2(r,KErrPermissionDenied); + r=repository->Set(18,retVal); + TEST2(r,KErrNone); + + //Test that AlwaysPass and AlwaysFail behave as expected when not followed by sid + r=repository->Get(21,retVal); + TEST2(r,KErrPermissionDenied); + r=repository->Set(21,retVal); + TEST2(r,KErrPermissionDenied); + r=repository->Get(22,retVal); + TEST2(r,KErrNone); + r=repository->Set(22,retVal); + TEST2(r,KErrNone); + + + //Test that AlwaysPass and AlwaysFail behave as expected when followed by sid + r=repository->Get(19,retVal); + TEST2(r,KErrPermissionDenied); + r=repository->Set(19,retVal); + TEST2(r,KErrNone); + + //Additional test cases + //Test single policies with max 3 caps for both read and write + r=repository->Get(28,retVal); + TEST2(r,KErrPermissionDenied); + r=repository->Set(28,retVal); + TEST2(r,KErrNone); + + //Test single policies with max 7 caps for both read and write + r=repository->Get(33,retVal); + TEST2(r,KErrPermissionDenied); + r=repository->Set(33,retVal); + TEST2(r,KErrPermissionDenied); + + //Test range policies with max 3 caps when followed by sid + r=repository->Get(201,retVal); + TEST2(r,KErrPermissionDenied); + r=repository->Set(201,retVal); + TEST2(r,KErrNone); + + //Test range policies with max 7 caps not with sid + r=repository->Get(300,retVal); + TEST2(r,KErrPermissionDenied); + r=repository->Set(300,retVal); + TEST2(r,KErrPermissionDenied); + + //Test behaviour when single policies are specified with just sid + r=repository->Get(400,retVal); + TEST2(r,KErrNone); + r=repository->Set(400,retVal); + TEST2(r,KErrPermissionDenied); // default read cap for sid 0 is AlwaysFail + + r=repository->Get(401,retVal); + TEST2(r,KErrNone); // default write cap for sid 0 is AlwaysPass + r=repository->Set(401,retVal); + TEST2(r,KErrNone); + + //Test that default policies are picked up when no policies are specified + r=repository->Get(500,retVal); + TEST2(r,KErrNone); + + r=repository->Set(500,retVal); + TEST2(r,KErrPermissionDenied); + + CleanupStack::PopAndDestroy(repository); + } + +LOCAL_C void DEF057470L() + { + + TInt r=KErrNone; + TUint32 errId=0; + CRepository* repository; + + User::LeaveIfNull(repository = CRepository::NewLC(KUidDEF057470TestRepository)); + + //-------------- 1. Simple Range Delete Operation----------------------------- + // Confirm that keys exist + RArray foundIds; + r = repository->FindL(KRangeDeletePartialKey, KRangeDeleteMask, foundIds); + TEST2(r, KErrNone); + TEST(foundIds.Count()==5); + foundIds.Reset(); + // Delete a set of keys + r = repository->Delete(KRangeDeletePartialKey, KRangeDeleteMask, errId) ; + TEST2(r, KErrNone); + // Confirm that deleted keys do not exist + r = repository->FindL(KRangeDeletePartialKey, KRangeDeleteMask, foundIds); + TEST2(r, KErrNotFound); + TEST(foundIds.Count()==0); + foundIds.Reset(); + CleanupStack::PopAndDestroy(repository); + // Try to find keys again just to double check whether the changes have persisted + User::LeaveIfNull(repository = CRepository::NewLC(KUidDEF057470TestRepository)); + r = repository->FindL(KRangeDeletePartialKey, KRangeDeleteMask, foundIds); + TEST2(r, KErrNotFound); + TEST(foundIds.Count()==0); + foundIds.Reset(); + + + //--------------- 2. Range Delete Operation where keys don't exist-------------- + // Confirm that keys don't exist. + r = repository->FindL(KDeleteKeyDoesntExist, KRangeDeleteMask, foundIds); + TEST2(r, KErrNotFound); + TEST(foundIds.Count()==0); + foundIds.Reset(); + // Attempt delete and check result + r = repository->Delete(KDeleteKeyDoesntExist, KRangeDeleteMask, errId) ; + TEST2(r, KErrNotFound); + errId &= KRangeDeleteMask ; + TEST2(errId, KDeleteKeyDoesntExist) ; + + + //-------3. Range Delete Operation where client doesn't have write capabilities for key range.---- + // Attempt delete and check result + r = repository->Delete(KDeleteForbidden, KRangeDeleteMask, errId) ; + TEST2(r, KErrPermissionDenied); + errId &= KRangeDeleteMask ; + TEST2(errId, KDeleteForbidden) ; + // Close repository + CleanupStack::PopAndDestroy(repository); + + //------ 4. Range Delete Operation which deletes all the keys and Resets the entire repository back its original state. + TInt numberOfIds; + User::LeaveIfNull(repository = CRepository::NewLC(KUidLargeRepository)); + // Find how many keys are originally present + r = repository->FindL(KNullKey, KNullKey, foundIds); + TEST2(r, KErrNone); + numberOfIds = foundIds.Count(); + TEST(foundIds.Count()!=0); + foundIds.Reset(); + // Range delete all the keys in the repository + r = repository->Delete(KNullKey, KNullKey, errId); + TEST2(r, KErrNone); + // Check all the keys have been deleted from cache + r = repository->FindL(KNullKey, KNullKey, foundIds); + TEST2(r, KErrNotFound); + TEST(foundIds.Count()==0); + foundIds.Reset(); + // Close and re-open the repository to check if the deleted keys have persisted. + CleanupStack::PopAndDestroy(repository); + // Existance of caching functionality invalidates some tests and + // makes them fail, so kill the server to force clearing the cache + r = KillProcess(KCentralRepositoryServerName); + TEST2(r,KErrNone); + User::LeaveIfNull(repository = CRepository::NewLC(KUidLargeRepository)); + // Check all the deleted keys have persisted. + r = repository->FindL(KNullKey, KNullKey, foundIds); + TEST2(r, KErrNotFound); + TEST(foundIds.Count()==0); + foundIds.Reset(); + // Reset repository back to its original state from ROM + r = repository->Reset(); + TEST2(r, KErrNone); + // Check that number of keys is same as when we started. + r = repository->FindL(KNullKey, KNullKey, foundIds); + TEST2(r, KErrNone); + TEST(foundIds.Count()==numberOfIds); + foundIds.Reset(); + // Close the repository + CleanupStack::PopAndDestroy(repository); + + //**********************Delete Range within Transacrions********************** + //--------- 5. Range Delete within a transaction where key's don't exist.------------ + User::LeaveIfNull(repository = CRepository::NewLC(KUidDEF057470TestRepository)); + // Begin read write transaction. + r = repository->StartTransaction(CRepository::EReadWriteTransaction); + TEST2(r, KErrNone); + r = TransactionState(repository); + TEST2(r, EReadWriteTransaction); + r = repository->Delete(KDeleteKeyDoesntExist, KRangeDeleteMask, errId) ; + TEST2(r, KErrNotFound); + // Check that transaction hasn't failed. + r = TransactionState(repository); + TEST2(r, EReadWriteTransaction); + // Fail transaction. + repository->FailTransaction(); + r = TransactionState(repository); + TEST2(r, EReadWriteTransaction | EFailedBit); + repository->RollbackTransaction(); + r = TransactionState(repository); + TEST2(r, ENoTransaction); + + + //---------- 6. Range delete within a transaction where client doesn't have capabilities to write to key range. + // Begin read write transaction. + r = repository->StartTransaction(CRepository::EReadWriteTransaction); + TEST2(r, KErrNone); + r = repository->Delete(KDeleteForbidden, KRangeDeleteMask, errId) ; + TEST2(r, KErrPermissionDenied); + errId &= KRangeDeleteMask ; + TEST2(errId, KDeleteForbidden) ; + // check that transaction has failed. + r = TransactionState(repository); + TEST2(r, EReadWriteTransaction | EFailedBit); + // Rollback the failed transaction. + repository->RollbackTransaction(); + r = TransactionState(repository); + TEST2(r, ENoTransaction); + + + //---------- 7. Range delete while not in transaction fails other session's transaction with KErrLocked. + // Open another repository + CRepository* repository2; + User::LeaveIfNull(repository2 = CRepository::NewLC(KUidDEF057470TestRepository)); + // Begin read write transaction + r = repository->StartTransaction(CRepository::EReadWriteTransaction); + TEST2(r, KErrNone); + r = TransactionState(repository); + TEST2(r, EReadWriteTransaction); + // Delete keys in the first session. + r = repository->Delete(KTransactionRangeDeletePartialKey, KRangeDeleteMask, errId) ; + TEST2(r, KErrNone); + // Delete keys in the second session. + r = repository2->Delete(KTransactionRangeDeletePartialKey, KRangeDeleteMask, errId) ; + TEST2(r, KErrNone); + // first session's transaction should have failed with KErrLocked + TInt state = TransactionState(repository); + TEST2(state, EReadWriteTransaction | EFailedBit); + // Commit transaction should report failure reason: + TUint32 keyInfo; + r = repository->CommitTransaction(keyInfo); + TEST2(r, KErrLocked); + TEST(keyInfo == KUnspecifiedKey); + r = TransactionState(repository); + TEST2(r, ENoTransaction); + // Close the repositories + CleanupStack::PopAndDestroy(repository2); + + + //----------- 8. Range Delete within a Transaction and Commit.----------------------- + //Before doing this we need to reset from the ROM first to restore the deleted keys in + //non transaction test earlier + r=repository->Reset(); + TEST2(r,KErrNone); + r = repository->FindL(KRangeDeletePartialKey, KRangeDeleteMask, foundIds); + TEST2(r,KErrNone); + TEST(foundIds.Count()==5); + foundIds.Reset(); + // Begin read write transaction + r = repository->StartTransaction(CRepository::EReadWriteTransaction); + TEST2(r, KErrNone); + r = repository->Delete(KTransactionRangeDeletePartialKey, KRangeDeleteMask, errId) ; + TEST2(r, KErrNone); + // Commit transaction + r = repository->CommitTransaction(errId); + TEST2(r, KErrNone); + //The number of keys changed should be equal to the number of keys deleted + TEST(errId==5); + + //Reset repository to remove any changes made during this test + r=repository->Reset(); + TEST2(r, KErrNone); + + // Close the repositories + CleanupStack::PopAndDestroy(repository); + } + +LOCAL_C void INC058229L() + { + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + CFileMan* fm = CFileMan::NewL(fs); + CleanupStack::PushL(fm); + + // Open repository to ensure server is running + CRepository* rep; + User::LeaveIfNull(rep = CRepository::NewLC(KUidLargeRepository)); + // Close repository + CleanupStack::PopAndDestroy(rep); + + // Remove install dir + TInt r = fm->RmDir(KCInstallDir); + if(r!=KErrNone && r!=KErrNotFound && r!=KErrPathNotFound) + User::Leave(r); + // Wait so that watcher will see directory is gone + User::After(KGeneralDelay); + + // Kill server so that next test will reconnect and recreate resources + r=KillProcess(KCentralRepositoryServerName); + TEST2(r,KErrNone); + + // Open repository to ensure directories are restored + User::LeaveIfNull(rep = CRepository::NewLC(KUidLargeRepository)); + // Close repository + CleanupStack::PopAndDestroy(3); // rep, fs, fm + } + +LOCAL_C void DEF058900L() + { + + CRepository* repository; + User::LeaveIfNull(repository = CRepository::NewLC(KUidDEF058900TestRepository)); + TRequestStatus intStatus; + RThread thisThread; + + // + // Basic notification to test notification for one banned key + // + TInt r = repository->NotifyRequest(KNotifyBannedKey, intStatus); + TEST2(r, KErrNone); + TEST(intStatus == KRequestPending); + + // First change to setting should cause notification + r = repository->Set(KNotifyBannedKey, 100); + TEST2(r, KErrNone); + User::WaitForAnyRequest(); + TEST(intStatus==KUnspecifiedKey); + + // + // Group notification to test notification when the banned key is in a range + // + r = repository->NotifyRequest(KNullKey, KNullKey, intStatus); + TEST2(r, KErrNone); + + r = repository->Set(KNotifyBannedKey, 50); + TEST2(r, KErrNone); + User::WaitForAnyRequest(); + TEST(intStatus==KUnspecifiedKey); + TEST(thisThread.RequestCount()==0); + + // + // Group notification to test notification when many keys including the banned key change + // i.e. a repository wide reset + // + // First change values for alot of the keys before a reset. + r = repository->Set(KNotificationKey1, 80); + TEST2(r, KErrNone); + r = repository->Set(KNotifyBannedKey, 50); + TEST2(r, KErrNone); + r = repository->Set(KNotificationKey2, 70); + TEST2(r, KErrNone); + r = repository->Set(KNotificationKey3, 60); + TEST2(r, KErrNone); + r = repository->Set(KNotificationKey4, 30); + TEST2(r, KErrNone); + + r = repository->NotifyRequest(KNullKey, KNullKey, intStatus); // Request notification + // for all keys in repository. + TEST2(r, KErrNone); + + //Reset the whole repository to original settings + r = repository->Reset(); + TEST2(r, KErrNone); + + User::WaitForAnyRequest(); + TEST(intStatus==KUnspecifiedKey); + TEST(thisThread.RequestCount()==0); + + + CleanupStack::PopAndDestroy(repository); + } + +LOCAL_C void DEF061087L() + { + TInt r=KErrNone; + TUid testUid={0x10061087}; + CRepository* repository; + User::LeaveIfNull(repository = CRepository::NewLC(testUid)); + + /*--------------Scenario 1--------------------- + 100 300 cap_wr=ReadDeviceData + 100 200 cap_wr=TCB */ + r=repository->Create(150,100); + TEST2(r,KErrPermissionDenied); + r=repository->Create(201,201); + TEST2(r,KErrNone); + + /*--------------Scenario 2--------------------- + 400 500 cap_wr=ReadDeviceData + 400 500 cap_wr=TCB */ + r=repository->Create(500,100); + TEST2(r,KErrPermissionDenied); + + /*--------------Scenario 3--------------------- + 0x600 0x700 cap_wr=ReadDeviceData + # Odd entry from 600-700 + 0x601 mask=0xF01 cap_wr=TCB*/ + r=repository->Create(0x601,601); + TEST2(r,KErrPermissionDenied); + r=repository->Create(0x657,647); + TEST2(r,KErrPermissionDenied); + //0x602 will be even so it will check agains the next matched range policies + //which is 0x600 0x700 cap_wr=ReadDeviceData + r=repository->Create(0x602,600); + TEST2(r,KErrNone); + + /*--------------Scenario 4--------------------- + # protected data + 0x00000100 mask=0x00000100 cap_wr=NetworkControl + # private data + 0x000000F0 mask=0x00000080 cap_rd=ReadDeviceData */ + r=repository->Create(0x01000100,123); + TEST2(r,KErrPermissionDenied); + r=repository->Create(0x03450700,123); + TEST2(r,KErrPermissionDenied); + r=repository->Create(0x00450080,123); + TEST2(r,KErrNone); + r=repository->Create(0x06450081,123); + TEST2(r,KErrNone); + + + CleanupStack::PopAndDestroy(repository); + } + + +LOCAL_C void DEF060843L() + { + CRepository* repository; + User::LeaveIfNull(repository = CRepository::NewLC(KUidDEF060843LRepository1)); + + _LIT8(KString12_InitialValue, "string"); + TPtrC8 p8(KString12_InitialValue); + TInt len8 = p8.Length(); + + _LIT(KString11_InitialValue, "string"); + TPtrC p16(KString11_InitialValue); + TInt len16 = p16.Length(); + + //setting ids in a test repository + const TUint32 KReal1 = 2; + const TUint32 KString11 = 11; + const TUint32 KString12 = 12; + + TInt r; + TInt i(0); + + TBuf<15> str; + TInt strLen; + + TBuf8<15> str8; + TInt strLen8; + + //================read real using int ======================== + r = repository->Get(KReal1, i); + TEST2(r, KErrArgument); + TEST(i==0); + + //================read TDes16 using TDes8===================== + r = repository->Get(KString11, str8); + TEST2(r, KErrNone); + + //8-bit descriptor holding the same data as 16-bit descriptor + //should twice as long as 16-bit des. + strLen8 = str8.Length(); + TEST2(strLen8,len16*2); + + const TUint16* p16a = (TUint16*)str8.Ptr(); + const TUint16* p16b = p16.Ptr(); + //compares content of descriptors byte by byte + r = Mem::Compare(p16a,strLen8/2,p16b,len16); + TEST2(r,KErrNone); + + //=================read TDes8 using TDes16===================== + r = repository->Get(KString12, str); + TEST2(r, KErrNone); + + //16-bit descriptor holding the same data as 8-bit descriptor + //should be half a length of a 8-bit desc + strLen = str.Length(); + TEST2(strLen,len8/2); + + const TUint8* p8a = (TUint8*)str.Ptr(); + const TUint8* p8b = p8.Ptr(); + //compares content of descriptors byte by byte + r = Mem::Compare(p8a,strLen*2,p8b,len8); + TEST2(r,KErrNone); + + //================writting to TDes16 using TDes8=============== + r = repository->Set(KString11,KString12_InitialValue); + TEST2(r, KErrNone); + CleanupStack::PopAndDestroy(repository); + User::LeaveIfNull(repository = CRepository::NewLC(KUidDEF060843LRepository1)); + r = repository->Get(KString11, str8); + strLen8 = str8.Length(); + TEST2(strLen8,len8); + TEST(str8==KString12_InitialValue); + + //================writting to TDes8 using TDes16=============== + r = repository->Set(KString12,KString11_InitialValue); + TEST2(r, KErrNone); + CleanupStack::PopAndDestroy(repository); + User::LeaveIfNull(repository = CRepository::NewLC(KUidDEF060843LRepository1)); + r = repository->Get(KString12, str); + strLen = str.Length(); + TEST2(strLen,len16); + TEST(str==KString11_InitialValue); + CleanupStack::PopAndDestroy(repository); + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-1433 +@SYMTestCaseDesc Central repository panics the client when trying to read 8-bit descriptor with uneven length +@SYMTestPriority High +@SYMTestActions Read 8-bit descriptor with uneven length +@SYMTestExpectedResults The test must not fail or panic . +@SYMDEF INC069013 +*/ +LOCAL_C void INC069013L() + { + CRepository* repository; + User::LeaveIfNull(repository = CRepository::NewLC(KUidINC069013TestRepository)); + + _LIT(KString16, "16BitString"); + _LIT8(KString8Odd, "8BitOddString"); + _LIT8(KString8Even, "8BitEvenString"); + + const TUint32 KString16ID = 1; + const TUint32 KString8OddID = 2; + const TUint32 KString8EvenID = 3; + + TBuf<20> buf; + TInt r = KErrNone; + TInt actualLength = 0; + + //test for string stored as 16 bit + r = repository->Get(KString16ID, buf); + TEST2(r, KErrNone); + + r = repository->Get(KString16ID, buf, actualLength); + TEST2(r, KErrNone); + TEST2(actualLength, KString16().Length()); + + //test for string stored as 8 bit with odd length + r = repository->Get(KString8OddID, buf); + TEST2(r, KErrNone); + + r = repository->Get(KString8OddID, buf, actualLength); + TEST2(r, KErrNone); + TEST2(actualLength, (KString8Odd().Length() + 1) / 2); + + //test for string stored as 8 bit with even length + r = repository->Get(KString8EvenID, buf); + TEST2(r, KErrNone); + + r = repository->Get(KString8EvenID, buf, actualLength); + TEST2(r, KErrNone); + TEST2(actualLength, (KString8Even().Length() + 1) / 2); + + CleanupStack::PopAndDestroy(repository); + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-1434 +@SYMTestCaseDesc Central repository doesn't handle corrupt .cre files correctly. +@SYMTestPriority High +@SYMTestActions Open corrupt files from ROM and persists +@SYMTestExpectedResults The test must not fail. +@SYMDEF DEF070731 +*/ +const TUid KUidCorruptEOF = { 0x00000e0f }; +const TUid KUidCorrupt = { 0x00000bad }; + +_LIT(KCRep1File, "c:\\private\\10202BE9\\persists\\00000100.cre"); +_LIT(KZCorruptEOFFile, "z:\\private\\10202BE9\\00000e0f.cre"); +_LIT(KZCorruptFile, "z:\\private\\10202BE9\\00000bad.cre"); + +LOCAL_C void DEF070731L() + { + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + CFileMan* fm = CFileMan::NewL(fs); + CleanupStack::PushL(fm); + + CRepository* rep; + + // Open ROM cre file with EOF corruption + TheTest.Printf(_L("\nOpen ROM cre file with EOF corruption\n")); + TRAPD(errH, rep=CRepository::NewLC(KUidCorruptEOF)); + TEST2(errH, KErrCorrupt); + + // Open corrupt ROM file + TheTest.Printf(_L("\nOpen corrupt ROM file\n")); + TRAPD(errS,rep=CRepository::NewLC(KUidCorrupt)); + TEST2(errS, KErrCorrupt); + + // Edit repos with new setting + TheTest.Printf(_L("\nEdit repos with new setting\n")); + User::LeaveIfNull(rep = CRepository::NewLC(KUidRep1)); + TInt r = rep->Create(KNewInt, KIntValue); + TEST2(r, KErrNone); + CleanupStack::PopAndDestroy(rep); + + // Reopen repos to read from persists file + User::LeaveIfNull(rep = CRepository::NewLC(KUidRep1)); + TInt newInt; + r=rep->Get(KNewInt, newInt); + TEST2(r, KErrNone); + CleanupStack::PopAndDestroy(rep); + + // Existance of caching functionality invalidates some tests and + // makes them fail, so kill the server to force clearing the cache + r=KillProcess(KCentralRepositoryServerName); + TEST2(r,KErrNone); + + // Copy corrupt EOF file into persists + TheTest.Printf(_L("\nCopy corrupt EOF file into persists dir\n")); + User::LeaveIfError(fm->Copy(KZCorruptEOFFile, KCRep1File)); + // Reset read-only bit + User::LeaveIfError(fm->Attribs(KCRep1File,0,KEntryAttReadOnly,TTime(0))); + User::After(KGeneralDelay); + // Open repos, should find corrupt file and use ROM file + User::LeaveIfNull(rep = CRepository::NewLC(KUidRep1)); + // If we can't find KNewInt, this proves that we are using ROM file + r=rep->Get(KNewInt, newInt); + TEST2(r, KErrNotFound); + // Test that persists file is deleted + TheTest.Printf(_L("\nCheck corrupt EOF file deleted from persists dir\n")); + TEST2 (BaflUtils::FileExists (fs, KCRep1File), EFalse); + // Close repository + CleanupStack::PopAndDestroy(rep); + + // Existance of caching functionality invalidates some tests and + // makes them fail, so kill the server to force clearing the cache + r=KillProcess(KCentralRepositoryServerName); + TEST2(r,KErrNone); + + // Copy corrupt file into persists + TheTest.Printf(_L("\nCopy corrupt file into persists dir\n")); + User::LeaveIfError(fm->Copy(KZCorruptFile, KCRep1File)); + // Reset read-only bit + User::LeaveIfError(fm->Attribs(KCRep1File,0,KEntryAttReadOnly,TTime(0))); + User::After(KGeneralDelay); + // Open repos, should find corrupt file and use ROM file + User::LeaveIfNull(rep = CRepository::NewLC(KUidRep1)); + // Test that file is deleted + TheTest.Printf(_L("\nCheck corrupt file deleted from persists dir\n")); + TEST2 (BaflUtils::FileExists (fs, KCRep1File), EFalse); + + // Close repository + CleanupStack::PopAndDestroy(3);// rep, fs,fm + + } + +// Helper function for DEF084700L +LOCAL_C void ConnectAndCommitSuicideL(void) + { + CRepository* repository; + User::LeaveIfNull(repository = CRepository::NewLC(KUidDEF060843LRepository1)); + + RThread currentThread; + currentThread.Kill(KErrDied); + + // Should never get executed + CleanupStack::PopAndDestroy(repository); + } + +// Helper function for DEF084700L +LOCAL_C TInt SuicidalThread(TAny*) + { + CTrapCleanup* cleanup = CTrapCleanup::New(); + if(!cleanup) + return KErrNoMemory; + + TRAP_IGNORE(ConnectAndCommitSuicideL()); + + // Should never get executed + delete cleanup; + return KErrNone; + } + +// Helper function for DEF084700L +LOCAL_C void ConnectAndDisconnectL(void) + { + CRepository* repository; + User::LeaveIfNull(repository = CRepository::NewLC(KUidDEF060843LRepository1)); + + CleanupStack::PopAndDestroy(repository); + } + +// Helper function for DEF084700L +LOCAL_C TInt WellBehavedThread(TAny*) + { + CTrapCleanup* cleanup = CTrapCleanup::New(); + if(!cleanup) + return KErrNoMemory; + + TRAP_IGNORE(ConnectAndDisconnectL()); + + delete cleanup; + return KErrNone; + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-1683 +@SYMTestCaseDesc UIF automated tests crash H4 board +@SYMTestPriority High +@SYMTestActions Open a repository, create a thread, open same repository from that thread, kill the thread + before closing repository, update a setting from main body (trigger notifications). Do the same + thing for a thread which terminates normally for making sure the previous behaviour is maintained +@SYMTestExpectedResults The test must not panic or fail. +@SYMDEF DEF084700 +*/ +LOCAL_C void DEF084700L() + { + CRepository* repository; + User::LeaveIfNull(repository = CRepository::NewLC(KUidDEF060843LRepository1)); + + RThread testThread; + _LIT(KThreadName1, "SuicidalTestThread"); + + testThread.Create(KThreadName1, SuicidalThread, KDefaultStackSize, KMinHeapSize, 0x100000, NULL); + + TRequestStatus requestStatus; + // Request notification when the thread kills itself + testThread.Logon(requestStatus); + // Let the thread execute + testThread.Resume(); + + // Wait for suicide + User::WaitForRequest(requestStatus); + // Make sure it's dead + TEST2(requestStatus.Int(), KErrDied); + + const TUint32 KInt1 = 0x1; + TInt i, r = KErrNone; + + r = repository->Get(KInt1, i); + TEST2(r, KErrNone); + r = repository->Set(KInt1, i+1); + // Fails here with KErrServerTerminated before fix because server crashes + TEST2(r, KErrNone); + + // Create another thread which accesses the repository but terminates normally + _LIT(KThreadName2, "WellBehavedTestThread"); + + testThread.Create(KThreadName2, WellBehavedThread, KDefaultStackSize, KMinHeapSize, 0x100000, NULL); + + // Request notification when the thread terminates normally + testThread.Logon(requestStatus); + // Let the thread execute + testThread.Resume(); + + // Wait for old age + User::WaitForRequest(requestStatus); + // Make sure the cause of death is natural + TEST2(requestStatus.Int(), KErrNone); + + r = repository->Get(KInt1, i); + TEST2(r, KErrNone); + r = repository->Set(KInt1, i+1); + + TEST2(r, KErrNone); + + //Reset repository to remove any changes made during this test + r = repository->Reset(); + TEST2(r, KErrNone); + + CleanupStack::PopAndDestroy(repository); + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-1862 +@SYMTestCaseDesc [AQP] CommitTransaction returns incorrect error code if Find~L methods run OOM +@SYMTestPriority High +@SYMTestActions Open a repository, start a transaction, then simulate a OOM failure in a TRAPPED + FindL, this will result in client side error and this error should be the returned + error of CommitTransaction. +@SYMTestExpectedResults The test must not panic or fail. +@SYMDEF DEF089945 +*/ +LOCAL_C void DEF089945L() + { + TInt err=KErrNone; + const TUid testUid={0x10057145}; + RArray idArray; + + CRepository* repository; + User::LeaveIfNull(repository = CRepository::NewLC(testUid)); + + //-----------SIMULATE CLIENT SIDE TRANSACTION ERROR------------------------------ + err=repository->StartTransaction(CRepository::EReadWriteTransaction); + TEST2(err,KErrNone); + + //set the next allocation to fail in the FindL method + __UHEAP_FAILNEXT(1); + TRAP(err,repository->FindL(1,0xFFFFFFFF,idArray)); + __UHEAP_TOTAL_RESET; + //uheap failure only happens in debug build +#ifdef _DEBUG + TEST2(err,KErrNoMemory); +#else + TEST2(err,KErrNone); +#endif + + TUint32 errId; + //ensure that the returned code from Commit is same as the last failure error in client + err=repository->CommitTransaction(errId); +#ifdef _DEBUG + TEST2(err,KErrNoMemory); + TEST2(errId,KUnspecifiedKey); +#else + TEST2(err,KErrNone); +#endif + idArray.Reset(); + + //----------SIMULATE CLIENT SIDE TRANSACTION ERROR FOLLOWED BY ADDITIONAL OPERATION----- + err=repository->StartTransaction(CRepository::EReadWriteTransaction); + TEST2(err,KErrNone); + //set the next allocation to fail in the FindL method + __UHEAP_FAILNEXT(1); + TRAP(err,repository->FindL(1,0xFFFFFFFF,idArray)); + __UHEAP_TOTAL_RESET; +#ifdef _DEBUG + TEST2(err,KErrNoMemory); +#else + TEST2(err,KErrNone); +#endif + + //now try to execute another operation following the failure + TReal realValue; + err=repository->Set(1,realValue); +#ifdef _DEBUG + TEST2(err,KErrAbort); +#else + TEST2(err,KErrArgument); +#endif + + err=repository->CommitTransaction(errId); + //confirms that the error returned is the last failure in client side +#ifdef _DEBUG + TEST2(err,KErrNoMemory); + TEST2(errId,KUnspecifiedKey); +#else + TEST2(err,KErrArgument); +#endif + idArray.Reset(); + + //---------SIMULATE SERVER SIDE ERROR FOLLOWED BY CLIENT SIDE ERROR------------------- + err=repository->StartTransaction(CRepository::EReadWriteTransaction); + TEST2(err,KErrNone); + + //server error + err=repository->Set(1,realValue); + TEST2(err,KErrArgument); + + //client error + __UHEAP_FAILNEXT(1); + TInt ret=KErrNone; + TRAP(err,ret=repository->FindL(1,0xFFFFFFFF,idArray)); + __UHEAP_TOTAL_RESET; + TEST2(ret,KErrAbort); + + err=repository->CommitTransaction(errId); + //confirms that the error returned is the last failure in server side + TEST2(err,KErrArgument); + TEST2(errId,1); + idArray.Reset(); + + //clean up stuff + idArray.Close(); + CleanupStack::PopAndDestroy(repository); + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-3242 +@SYMTestCaseDesc Memory card: Backup to memory card causes phone freeze. +@SYMTestPriority High +@SYMTestActions Open a repository with a corrupt ini file and check that + the call to CRepository::NewLC leaves with KErrCorrupt and does not panic. +@SYMTestExpectedResults The call to CRepository::NewLC should return with KErrCorrupt and + the test must not panic or fail. +@SYMDEF PDEF098500 +*/ +LOCAL_C void PDEF098500() + { + CRepository* repository = NULL; + + TRAPD(err,repository = CRepository::NewLC(KUidPDEF098500LRepository)); + + //We expect the above call to leave with KErrCorrupt so repository should be NULL + TEST(repository == NULL); + TEST2(err, KErrCorrupt); + + //No PopAndDestroy required as above call is expected to leave + + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-1884 +@SYMTestCaseDesc DEF093855: CenRep cancels transactions if they exceed 5 seconds... +@SYMTestPriority High +@SYMTestActions Open a repository, start a transaction, then wait more than default cache timeout + to let the normal eviction clean out the cache, call a function to reload the repository, + check that the transaction is still valid, rollback the transaction to check the + repository unload/reload during an open transaction doesn't cause a panic when transaction is rolled back. +@SYMTestExpectedResults The test must not panic or fail. +@SYMDEF DEF093855 +*/ +LOCAL_C void DEF093855L() + { + TInt err=KErrNone; + + // make sure no items are in the cache + KillProcess(KCentralRepositoryServerName); + + // connect + CRepository* repository; + User::LeaveIfNull(repository = CRepository::NewLC(KUidRep1)); + + // Begin concurrent read write transaction + err = repository->StartTransaction(CRepository::EConcurrentReadWriteTransaction); + TEST2(err, KErrNone); + + TInt val; + const TInt KIntTestValue = 10; + // get test value, make sure it is KIntTestValue + err = repository->Get(0x02010100,val); + TEST2(err, KErrNone); + TEST2(val, KIntTestValue); + + // change the value in transaction + TInt r = repository->Set(0x02010100, KIntValue); + TEST2(r, KErrNone); + + // wait for the repository to be removed from memory + CleanupRepositoryCache(); + + // check that the transaction is not aborted, still in memory and keeps the value set during the transaction + err = repository->Get(0x02010100,val); + TEST2(err, KErrNone); + TEST2(val, KIntValue); + + // rollback to check if RollbackTransaction works, and to reset the value to KIntTestValue + repository->RollbackTransaction(); + + // Begin another transaction + err = repository->StartTransaction(CRepository::EConcurrentReadWriteTransaction); + TEST2(err, KErrNone); + + // get test value, make sure it is still KIntTestValue (successfully rolled back) + err = repository->Get(0x02010100,val); + TEST2(err, KErrNone); + TEST2(val, KIntTestValue); + + // change the value in transaction + r = repository->Set(0x02010100, KIntValue); + TEST2(r, KErrNone); + + // wait for the repository to be removed from memory + CleanupRepositoryCache(); + + // check that the transaction is not aborted, still in memory and keeps the value set during the transaction + err = repository->Get(0x02010100,val); + TEST2(err, KErrNone); + TEST2(val, KIntValue); + + // commit to check if CommitTransaction works + TUint32 keyInfo; + repository->CommitTransaction(keyInfo); + TEST2(err, KErrNone); + TEST2(keyInfo, 1); + + // check that the value is set during the transaction (in shared rep settings) + err = repository->Get(0x02010100,val); + TEST2(err, KErrNone); + TEST2(val, KIntValue); + + // close repository + CleanupStack::PopAndDestroy(repository); + + // make sure the repository is unloaded from cache + KillProcess(KCentralRepositoryServerName); + + // reopen the repository + User::LeaveIfNull(repository = CRepository::NewLC(KUidRep1)); + + // get test value, to check if it had been successfully persisted + err = repository->Get(0x02010100,val); + TEST2(err, KErrNone); + TEST2(val, KIntValue); + + // reset the setting back to the original value + r = repository->Set(0x02010100, KIntTestValue); + TEST2(r, KErrNone); + + //Reset repository to remove any changes made during this test + r = repository->Reset(); + TEST2(r, KErrNone); + + // close repository + CleanupStack::PopAndDestroy(repository); + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-3477 +@SYMTestCaseDesc PDEF106507: Central repository doesn't handle corruption of the installdir.bin file properly +@SYMTestPriority High +@SYMTestActions Replaces installdir.bin file with a corrupted version, then shuts down the server and restarts it (with CRepository::NewL) This causes the file to be re-read, and as it is corrupt it should get deleted and re-created. The test checks that the server does not panic. +@SYMTestExpectedResults The Server should not panic when trying to read the corrupt file, and should return KErrNone +@SYMDEF PDEF106507 +*/ +LOCAL_C void PDEF106507L() + { + _LIT(KInstallDirFile, "C:\\private\\10202be9\\persists\\installdir.bin"); + _LIT(KInstallDirFileBad1, "Z:\\private\\10202be9\\installdir_corrupt1.bin"); + _LIT(KInstallDirFileBad2, "Z:\\private\\10202be9\\installdir_corrupt2.bin"); + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + CFileMan* fm = CFileMan::NewL(fs); + CleanupStack::PushL(fm); + + // copy first corrupt file into centrep private directory (this file has data area corrupted) + TheTest.Printf(_L("\nCopy first corrupt installdir.bin file into persists dir\n")); + User::LeaveIfError(fm->Copy(KInstallDirFileBad1, KInstallDirFile)); + // Reset read-only bit + User::LeaveIfError(fm->Attribs(KInstallDirFile,0,KEntryAttReadOnly,TTime(0))); + + // Kill server so that next test will restart and internalize file + TInt error = KillProcess(KCentralRepositoryServerName); + TEST2(error, KErrNone); + + // Start server and check it does not panic + CRepository* repository = NULL; + TRAP(error, repository = CRepository::NewL(KUidRep1)); + TEST2(error, KErrNone); + delete repository; + + // test the second corrupted file (this file has header information corrupted) + TheTest.Printf(_L("\nCopy second corrupt installdir.bin file into persists dir\n")); + User::LeaveIfError(fm->Copy(KInstallDirFileBad2, KInstallDirFile)); + // Reset read-only bit + User::LeaveIfError(fm->Attribs(KInstallDirFile,0,KEntryAttReadOnly,TTime(0))); + + // Kill server so that next test will reconnect and recreate resources + error = KillProcess(KCentralRepositoryServerName); + TEST2(error, KErrNone); + + // Start server and check it does not panic + TRAP(error, repository = CRepository::NewL(KUidRep1)); + TEST2(error, KErrNone); + delete repository; + + CleanupStack::PopAndDestroy(2); //fs, fm + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-3517 +@SYMTestCaseDesc R3.2 stability problems: CentralRepositorySrv crash +@SYMTestPriority High +@SYMTestActions Attempt to open a .cre file which has a corrupt UID. Ensure that + the error is dealt with properly. +@SYMTestExpectedResults The test must not fail. +@SYMDEF INC108803 +*/ + +_LIT(KZCorruptFile1, "z:\\private\\10202BE9\\101f8764.cre"); +_LIT(KCCorruptFile1, "c:\\private\\10202BE9\\persists\\101f8764.cre"); +_LIT(KCCorruptFile2, "c:\\private\\10202BE9\\persists\\101f8765.cre"); + +const TUid KUidCorruptUid1 = { 0x101f8764 }; +const TUid KUidCorruptUid2 = { 0x101f8765 }; + +LOCAL_C void INC108803L() + { + + TInt err = KErrNone; + + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + CFileMan* fm = CFileMan::NewL(fs); + CleanupStack::PushL(fm); + + CRepository* rep = NULL; + + // Attempt to open a repository from a .cre file which has a corrupt UID + // The .cre file exists on the Z drive only. This test ensures that + // the corruption of the .cre file is detected and that the correct error + // code, KErrCorrupt, is returned to the client. + // This test will + // 1. Look on c drive, be unable to find the file + // 2. Look in z drive, find the file with the specified UID, + // determine that the file is corrupt and return KErrCorupt. + + TheTest.Printf(_L("\nAttempt to open ROM cre file with UID corruption\n")); + TRAP(err, rep = CRepository::NewLC(KUidCorruptUid1); CleanupStack::Pop(rep);); + TEST2(err, KErrCorrupt); + + // Copy the corrupt .cre file into the persists directory for the next test + User::LeaveIfError(fm->Copy(KZCorruptFile1, KCCorruptFile1 )); + // Reset read-only bit + User::LeaveIfError(fm->Attribs(KCCorruptFile1,0,KEntryAttReadOnly,TTime(0))); + User::After(KGeneralDelay); + + // Attempt to open a repository which has a .cre file with a corrupt UID. + // The .cre file exists on the C and Z drives. (This test ensures that the + // corrupt .cre file on the C Drive is deleted). + // This test will + // 1.Look in the C Drive, find the file with the specified UID + // determine that the file is corrupt and delete the file + // 2. Look in the Z Drive, find the file with the specified UID, + // determine that the file is corrupt and return KErrCorupt. + + TheTest.Printf(_L("\nAttempt to open persists cre file with UID corruption\n")); + TRAP (err, rep = CRepository::NewLC(KUidCorruptUid1); CleanupStack::Pop(rep);); + TEST2(err, KErrCorrupt); + TheTest.Printf(_L("\nCheck corrupt file deleted from persists dir\n")); + TEST2 (BaflUtils::FileExists (fs, KCCorruptFile1), EFalse); + + // Copy a second corrupt .cre file into the persists directory + // (Note that an associated ini file + // z:\\private\\10202BE9\\101f8765.txt exists and is not corrupt) + + User::LeaveIfError(fm->Copy(KZCorruptFile1, KCCorruptFile2)); + TEST2 (BaflUtils::FileExists (fs, KCCorruptFile2), ETrue); + // Reset read-only bit + User::LeaveIfError(fm->Attribs(KCCorruptFile2,0,KEntryAttReadOnly,TTime(0))); + User::After(KGeneralDelay); + + // Attempt to open a corrupt repository. This will fail and the .cre file on the + // C Drive will be deleted. Fall-back to the Z drive occurs. The associated ini file + // is found. + // Attempt to use the resulting repository by using a Reset operation. No panics should + // occur. + TheTest.Printf(_L("\nAttempt to open corrupt persists cre file, re-create from txt file\n")); + TRAP (err, rep = CRepository::NewLC(KUidCorruptUid2); CleanupStack::Pop(rep);); + TEST2 (BaflUtils::FileExists (fs, KCCorruptFile2), EFalse); + TEST2(err, KErrNone); + ASSERT(rep != NULL); + rep->Reset(); + + // Clean up any files created on the C Drive + CleanupFileFromCDriveL(KUidCorruptUid1); + CleanupFileFromCDriveL(KUidCorruptUid2); + + delete rep; + CleanupStack::PopAndDestroy(2, &fs); // fm, fs + } + + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-3545 +@SYMTestCaseDesc The corrupted Cache ini file should cause CentralRepositorySrv panic in debug mode + but keep running with the default values in release mode. +@SYMTestPriority High +@SYMTestActions Kill CentralRepositorySrv and restart it with the corrupted Cache ini file. + Ensure that: + . in debug mode, the client will fail to create a CRepository pointer because + the server has panicked. + . in release mode, the client will be able to create a CRepository pointer because + the server keeps running with the default values. +@SYMTestExpectedResults The test must not fail. +@SYMDEF DEF109390 +*/ + +_LIT(KZCorruptIniFile, "z:\\private\\10202BE9\\cache_corrupt.ini"); +_LIT(KCCorruptIniFile, "c:\\private\\10202BE9\\centrep.ini"); +_LIT(KZRepFile, "z:\\private\\10202BE9\\00000001.txt"); +_LIT(KCRepFile, "c:\\private\\10202BE9\\persists\\00000001.txt"); + +const TUid KTestRepUid = { 0x00000001}; + +LOCAL_C void DEF109390L() + { + TInt err(KErrNone); + + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + CFileMan* fm = CFileMan::NewL(fs); + CleanupStack::PushL(fm); + + // Copy the corrupted Cache ini file to install directory. + TheTest.Printf(_L("\nCopy the corrupted Cache ini file to install directory.\n")); + User::LeaveIfError(fm->Copy(KZCorruptIniFile, KCCorruptIniFile)); + // Reset read-only bit + User::LeaveIfError(fm->Attribs(KCCorruptIniFile,0,KEntryAttReadOnly,TTime(0))); + + // Copy a good repository file to persist directory to verify whether the cenrep server is + // able to start up. + TheTest.Printf(_L("\nCopy the repository file to persist directory.\n")); + User::LeaveIfError(fm->Copy(KZRepFile, KCRepFile)); + // Reset read-only bit + User::LeaveIfError(fm->Attribs(KCRepFile,0,KEntryAttReadOnly,TTime(0))); + + // Kill server so that next test will restart it. + err=KillProcess(KCentralRepositoryServerName); + TEST2(err,KErrNone); + + User::After(KGeneralDelay); + + CRepository* rep = NULL; + TRAP(err, rep = CRepository::NewLC(KTestRepUid); CleanupStack::PopAndDestroy(rep);); + + #ifdef _DEBUG + // in debug mode, CRepository::NewLC should leave with leave code KErrGeneral. + TheTest.Printf(_L("Debug mode err = %d.\n"),err); + TEST2(err, KErrGeneral); + #else + // in release mode, CRepository::NewLC should return a valid CRepository pointer successfully. + TheTest.Printf(_L("Release mode err = %d.\n"),err); + TEST2(err, KErrNone); + #endif + + // Clean up the repository files created on the C Drive + CleanupFileFromCDriveL(KTestRepUid); + + // Clean up the corrupted ini file on the C Drive + User::LeaveIfError(fm->Delete(KCCorruptIniFile)); + + // pop the cleanup stack for fm & fs + CleanupStack::PopAndDestroy(2, &fs); + + // Kill the Cenrep server so that it can it can be restarted by the client + // without the corrupted Cache ini file. + err=KillProcess(KCentralRepositoryServerName); + TEST2(err,KErrNone); + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-UT-4024 +@SYMTestCaseDesc +Test that the UID compare function works properly with large UID's. Since +CObservable::CompareTUidValues() is a private function and cannot be accessed +directly, CObservable::AddObserverL()and CObservable::FindConnectedRepository() +are used to infer the correct operation. +@SYMTestPriority High +@SYMTestActions +-Compare a large positive UID and a very negative UID +-Compare a large positive UID and a large positive UID +-Compare a very negative UID and a very negative UID +-Compare two very large but equivalent UID's. +@SYMTestExpectedResults All UID's added to a sorted list can be found later, regardless of size and sign. +@SYMDEF DEF116043 +@SYMUnit CObservable::CompareTUidValues() +*/ +LOCAL_C void DEF116043L() + { + const TUid KLargePositive1 = {0x7FFFFFFF}; + const TUid KLargePositive2 = {0x7FFFFFFE}; + const TUid KLargeNegative = {0x8FFFFFFF}; + + CObservable* ob = CObservable::NewLC(); + + // Add a variety of UID's to work with, including large positives, a very negative, + // and duplicates + ob->AddObserverL(KLargePositive1, NULL); + ob->AddObserverL(KLargeNegative, NULL); + ob->AddObserverL(KLargePositive2, NULL); + ob->AddObserverL(KLargePositive1, NULL); + + // Look for a large positive and expect a non-negative index + TEST(ob->FindConnectedRepository(KLargePositive1) >= 0); + + // Look for another large positive and expect a non-negative index + TEST(ob->FindConnectedRepository(KLargePositive2) >= 0); + + // Look for a very negative and expect a non-negative index. + // This will fail under 'UID1 - UID2' implementations. + TEST(ob->FindConnectedRepository(KLargeNegative) >= 0); + + CleanupStack::PopAndDestroy(ob); + } + +/** +@SYMTestCaseID PDS-CENTRALREPOSITORY-UT-4081 +@SYMTestCaseDesc +Test that the Observer compare function works properly with large UID's +@SYMTestPriority High +@SYMTestActions The test will insert a set of pointers with very big and small unsigned address +and ensure that the correct order is inserted in the list +@SYMTestExpectedResults the pointer is inserted in the correct order +@SYMDEF DEF132807 +*/ +LOCAL_C void DEF132807L() + { + CObservable* ob = CObservable::NewLC(); + + const TUid KReposUid={0x87654321}; + + ob->AddObserverL(KReposUid,(CServerRepository*)0x7FFFFFFF); + ob->AddObserverL(KReposUid,(CServerRepository*)0x7FFFFFFE); + ob->AddObserverL(KReposUid,(CServerRepository*)0x8FFFFFFF); + ob->AddObserverL(KReposUid,(CServerRepository*)0x00000001); + + TEST(ob->iObservers.Count()==4); + CObservable::TRepositoryObserverInfo pos1=ob->iObservers[0]; + TEST(pos1.iRepositoryPointer==(CServerRepository*)0x00000001); + CObservable::TRepositoryObserverInfo pos2=ob->iObservers[1]; + TEST(pos2.iRepositoryPointer==(CServerRepository*)0x7FFFFFFE); + CObservable::TRepositoryObserverInfo pos3=ob->iObservers[2]; + TEST(pos3.iRepositoryPointer==(CServerRepository*)0x7FFFFFFF); + CObservable::TRepositoryObserverInfo pos4=ob->iObservers[3]; + TEST(pos4.iRepositoryPointer==(CServerRepository*)0x8FFFFFFF); + CleanupStack::PopAndDestroy(ob); + } + +//a test class notify handler +//the notify handler will check the value for different test case +static TInt currentTestCaseID=0; + +class CTestNotifyHandler : public CBase, public MCenRepNotifyHandlerCallback + { +public: + static CTestNotifyHandler* NewL() + { + return new (ELeave)CTestNotifyHandler; + } + ~CTestNotifyHandler(){} + // Notification handlers + void HandleNotifyInt(TUint32 aId, TInt aNewValue) + { + if (currentTestCaseID==0) + return; + else if(currentTestCaseID==1) + TEST(aId==1 && aNewValue==208); + } + void HandleNotifyReal(TUint32 aId, TReal /*aNewValue*/) + { + if (currentTestCaseID==2) + { + TEST(aId==1); + CActiveScheduler::Stop(); + } + } + void HandleNotifyString(TUint32 /*aId*/, const TDesC16& /*aNewValue*/) + { + } + void HandleNotifyBinary(TUint32 /*aId*/, const TDesC8& /*aNewValue*/) + { + } + void HandleNotifyGeneric(TUint32 /*aId*/) + { + } + void HandleNotifyError(TUint32 aId, TInt error, CCenRepNotifyHandler* /*aHandler*/) + { + if (currentTestCaseID==0) + return; + else if (currentTestCaseID==1) + TEST((TInt)aId==-11 && error==KErrArgument); + else if (currentTestCaseID==2) + TEST(aId==1 && error==KErrArgument); + else if (currentTestCaseID==3) + TEST(aId== 10000 && error==KErrPermissionDenied); + + CActiveScheduler::Stop(); + } +private: + CTestNotifyHandler(){} + }; + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-4035 +@SYMTestCaseDesc Notify Handling in centralrepository under different error conditions +@SYMTestPriority High +@SYMTestActions Testing the CRepository::NotifyRequest under different error condition + Testing the CCenrepNotifierHandler under different error condition +@SYMTestExpectedResults Test should pass and exhibit the expected behaviour +@SYMDEF DEF117987 +*/ +LOCAL_C void DEF117987L() + { + __UHEAP_MARK; + + CActiveScheduler* s=new(ELeave) CActiveScheduler; + CleanupStack::PushL(s); + CActiveScheduler::Install(s); + + const TUid KCDUid = {0xF0000001}; + CRepository* rep=CRepository::NewL(KCDUid); + + TRequestStatus ts,ts1; + + //-----------------single notification test----------------------- + //Negative testing for Double notification on same setting + TInt ret=rep->NotifyRequest(1,ts); + TEST(ret==KErrNone); + ret=rep->NotifyRequest(1,ts1); + TEST(ret==KErrNone); + ret=rep->Set(1,123); + User::WaitForRequest(ts); + User::WaitForRequest(ts1); + TEST(ts==1); + TEST(ts1==KErrAlreadyExists); + + //Negative testing for non-existent key--------------------------- + ts=KRequestPending; + ret=rep->NotifyRequest(10303,ts); + TEST(ret==KErrNotFound); + TEST(ts==KRequestPending); + + //Negative testing for key we dont have permission---------------- + ret=rep->NotifyRequest(10000,ts); + TEST(ret==KErrPermissionDenied); + TEST(ts==KRequestPending); + + //---------------------group notification test-------------------------- + ts=KRequestPending; + ts1=KRequestPending; + + //Negative testing for double notification on the same setting range + //set partial key 0 and mask 0xFFFFFF00 to filter only 0-255 + ret=rep->NotifyRequest(0,0xFFFFFF00,ts); + TEST(ret==KErrNone); + //second notification request on the same partial key and mask should not fail + ret=rep->NotifyRequest(0,0xFFFFFF00,ts1); + TEST(ret==KErrNone); + ret=rep->Set(1,246); + User::WaitForRequest(ts); + User::WaitForRequest(ts1); + TEST(ts==1); + TEST(ts1==1); + + //Negative testing for unknown range------------------------------ + //this will not return error code for range notification as it is intended for + //to cover keys created later in the future. + ts=KRequestPending; + ret=rep->NotifyRequest(100000,0xFFFFFFFF,ts); + TEST(ret==KErrNone); + ret=rep->NotifyCancel(100000,0xFFFFFFFF); + User::WaitForAnyRequest(); + TEST(ret==KErrNone); + TEST(ts==KUnspecifiedKey); + + //Negative testing for key we dont have permission------------------------------ + ts=KRequestPending; + ret=rep->NotifyRequest(10000,0xFFFFFFFF,ts); + TEST(ret==KErrNone); + User::WaitForRequest(ts); + TEST(ts==KErrPermissionDenied); + + delete rep; + + //----------------single notification using cenrepnotifhandler----------- + currentTestCaseID=1; + rep=CRepository::NewL(KCDUid); + //create the handler callback + CTestNotifyHandler* callback=CTestNotifyHandler::NewL(); + + //now setup the handler + CCenRepNotifyHandler* handler=CCenRepNotifyHandler::NewLC(*callback,*rep,CCenRepNotifyHandler::EIntKey,1); + CCenRepNotifyHandler* handler2=CCenRepNotifyHandler::NewLC(*callback,*rep,CCenRepNotifyHandler::EIntKey,1); + + handler->StartListeningL(); + handler2->StartListeningL(); + + ret=rep->Set(1,208); + TEST(ret==KErrNone); + + CActiveScheduler::Start(); + + User::After(1000000); + CleanupStack::PopAndDestroy(2); + + delete callback; + delete rep; + + CleanupStack::PopAndDestroy(); + + __UHEAP_MARKEND; + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-4034 +@SYMTestCaseDesc Centrep notifier handler does not check return codes +@SYMTestPriority High +@SYMTestActions Test that error code encountered during handling of notification + results in the HandleNotifyError being invoked +@SYMTestExpectedResults Test should pass and exhibit the expected behaviour +@SYMDEF DEF117848 +*/ +LOCAL_C void DEF117848L() + { + __UHEAP_MARK; + + CActiveScheduler* s=new(ELeave) CActiveScheduler; + CleanupStack::PushL(s); + CActiveScheduler::Install(s); + + const TUid KCDUid = {0xF0000001}; + + //create the handler callback + CTestNotifyHandler* callback=CTestNotifyHandler::NewL(); + + //----------------notify handle error test case------------------------------ + currentTestCaseID=2; + CRepository* rep=CRepository::NewL(KCDUid); + + //purposely set the notify handler for a key but specifying the wrong type + //this will only be detected during the notification + CCenRepNotifyHandler* handler=CCenRepNotifyHandler::NewLC(*callback,*rep,CCenRepNotifyHandler::ERealKey,1); + handler->StartListeningL(); + TInt ret=rep->Set(1,199); + TEST(ret==KErrNone); + + CActiveScheduler::Start(); + //handlenotify error will be called and validate the error code and then stop the scheduler + handler->StopListening(); + + CleanupStack::PopAndDestroy(); + + //test for other type of settings + handler=CCenRepNotifyHandler::NewLC(*callback,*rep,CCenRepNotifyHandler::EStringKey,1); + handler->StartListeningL(); + ret=rep->Set(1,209); + TEST(ret==KErrNone); + CActiveScheduler::Start(); + handler->StopListening(); + CleanupStack::PopAndDestroy(); + + //test for other type of settings + handler=CCenRepNotifyHandler::NewLC(*callback,*rep,CCenRepNotifyHandler::EBinaryKey,1); + handler->StartListeningL(); + ret=rep->Set(1,309); + TEST(ret==KErrNone); + + CActiveScheduler::Start(); + handler->StopListening(); + CleanupStack::PopAndDestroy(); + + delete callback; + delete rep; + + CleanupStack::PopAndDestroy(); + + __UHEAP_MARKEND; + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-4036 +@SYMTestCaseDesc Central Repository Notification Handler flooded with notifications +@SYMTestPriority High +@SYMTestActions Testing the CCenrepNotifierHandler when the client does not have + enough permission when setting up the whole repository notifier. +@SYMTestExpectedResults Test should pass and exhibit the expected behaviour +@SYMDEF DEF118107 +*/ +LOCAL_C void DEF118107L() + { + __UHEAP_MARK; + + currentTestCaseID = 3; + CActiveScheduler* s=new(ELeave) CActiveScheduler; + CleanupStack::PushL(s); + CActiveScheduler::Install(s); + + const TUid KCDUid = {0xF0000001}; + CRepository* rep=CRepository::NewL(KCDUid); + + //create the handler callback + CTestNotifyHandler* callback=CTestNotifyHandler::NewL(); + + //create a handler to listen to the whole repository + CCenRepNotifyHandler* handler=CCenRepNotifyHandler::NewLC(*callback,*rep); + + //Start listening as a fail should occur as one of repository entries does not + //have the correct capabilities + handler->StartListeningL(); + + //This causes the handlenotifyerror to be called which checks that + //KErrPermissionDenied has occured and stops the scheduler. + CActiveScheduler::Start(); + handler->StopListening(); + + //Cleanup + CleanupStack::PopAndDestroy(); + + delete callback; + delete rep; + + CleanupStack::PopAndDestroy(); + + __UHEAP_MARKEND; + } + + +// This function creates TServerSetting objects with the data in the ServerSettingStruct array and then +// appends them to the specified RSettingsArray object. +LOCAL_C void SetupSettingsArrayL(RSettingsArray& aSettingsArray,const ServerSettingStruct aSettingStructArr[], TInt aSettingStructArrSize) + { + for(TInt i = 0; i < aSettingStructArrSize; i++) + { + TServerSetting newSetting(aSettingStructArr[i].key); + TInt error; + newSetting.SetIntValue(aSettingStructArr[i].value); + newSetting.SetType(aSettingStructArr[i].meta); + newSetting.SetMeta(aSettingStructArr[i].meta); + + error = aSettingsArray.OrderedInsert(newSetting); + + if(KErrNone != error) + { + newSetting.Reset(); // for safety in case of newSetting is not TInt type. + User::Leave(error); + } + } + } + +// This function compares 2 RSettingsArray arrays. Panics if they are not identical +LOCAL_C void CompareSettingsArrays(const RSettingsArray& aArr1, const RSettingsArray& aArr2) + { + TEST2(aArr1.Count(), aArr2.Count()); + for(TInt i = 0; i < aArr2.Count(); i++) + { + if(aArr1[i].IsDeleted()) + { + TEST(aArr2[i].IsDeleted()); + } + else + { + TEST(aArr1[i] == aArr2[i]); + } + } + } + +// This function compares 2 RArray arrays. Panics if they are not identical +LOCAL_C void CompareUint32Arrays(const RArray& aArr1, const RArray& aArr2) + { + TEST2(aArr1.Count(), aArr2.Count()); + for(TInt i = 0; i < aArr2.Count(); i++) + { + TEST(aArr1[i] == aArr2[i]); + } + } + +// This function calls MergerArray() with the pre-set parameters for each merge type and compares the results to +// the reference arrays. +// Also used as the OOM test if aOOMMode is ETrue. +LOCAL_C void MergerArrayTestL(const RSettingsArray aPersistRef[], const RSettingsArray aChangeRef[], const RArray aDeletedRef[], TBool aOOMMode) + + { + // Data used to construct the persistence array for all merge types + static const ServerSettingStruct settingStructPersist[] = {{1,0,1}, {3,KMetaBackup,3}, {5,0,5}, {7,0,7}, {9,KMetaDefaultValue,9}, {11,0,11}, {13,KMetaDefaultValue,13}}; + + // Data used to construct the changes array for merge type: ETransactionMerge. Some are marked as deleted. + static const ServerSettingStruct settingStructChangeTrans[] = {{1,TServerSetting::EDeleted,1}, {2,TServerSetting::EDeleted,2}, \ + {3,TServerSetting::EDeleted,3}, {4,0,4}, {5,0,5}, {6,0,6}, {7,0,8}, {9,0,10}}; + + // Data used to construct the changes array for all other merge types than ETransactionMerge. No deleted items. + static const ServerSettingStruct settingStructChange[] = {{1,0,1}, {2,0,2}, {3,0,3}, {4,0,4}, {5,0,5}, {6,0,6}, {7,0,8}, {9,0,10}}; + + for(TInt i = 0; i < sizeof(KMergerTypes) / sizeof(TMergeType); i++) + { + RSettingsArray persist; + RSettingsArray change; + RArray deleted; + TInt error = KErrNone ; + TInt count = 0; + + do + { + __UHEAP_MARK; + + // Sets up arrays passed into MergeArray() + SetupSettingsArrayL(persist,settingStructPersist, sizeof(settingStructPersist)/sizeof(ServerSettingStruct)); + if( ETransactionMerge == KMergerTypes[i] ) + { + SetupSettingsArrayL(change,settingStructChangeTrans, sizeof(settingStructChangeTrans)/sizeof(ServerSettingStruct)); + } + else + { + SetupSettingsArrayL(change,settingStructChange, sizeof(settingStructChange)/sizeof(ServerSettingStruct)); + } + + deleted.InsertInUnsignedKeyOrderL(4); + + if(aOOMMode) + { + __UHEAP_SETFAIL(RHeap::EFailNext, ++count); + } + + error = persist.MergeArray(change, deleted, KMergerTypes[i]); + + if (aOOMMode) + { + TEST(KErrNone == error || KErrNoMemory == error); + __UHEAP_SETFAIL(RHeap::ENone, 0); + } + else + { + TEST(KErrNone == error); + // Verifies affected arrays. + CompareSettingsArrays(persist, aPersistRef[i]); + CompareSettingsArrays(change, aChangeRef[i]); + CompareUint32Arrays(deleted, aDeletedRef[i]); + } + + // Resets the arrays. + persist.Reset(); + change.Reset(); + deleted.Reset(); + + __UHEAP_MARKEND; + } while(KErrNoMemory == error); + if (aOOMMode) + { + TheTest.Printf(_L("- MergeArray for type %d succeeded at heap failure rate of %i\n"), KMergerTypes[i], count); + } + } + } + +/** +@SYMTestCaseID SYSLIB-CENTRALREPOSITORY-UT-4037 +@SYMTestCaseDesc This test case verifies the re-factored CentralRepository internal merge function (MergeArray). +@SYMTestPriority High +@SYMTestActions For each merger type, calls MergeArray() with the pre-defined arrays: this, aChanges, aDeleted, + which would be changed by the function. Verifies these 3 arrays with the reference arrays as well as + the return code after MergeArray() returns. + This case also carries out the OOM test for function MergeArray(). +@SYMTestExpectedResults MergeArray() should return no error and these 3 arrays should be identical with the reference + arrays. In OOM mode, only KErrNoMemory or KErrNone should be returned. +@SYMDEF DEF116629 +*/ +LOCAL_C void DEF116629L() + { + + // Data used to construct the reference arrays of each merge type: + // ETransactionMerge + const ServerSettingStruct settingStructPersistAfterTrans[] = {{4,0,4}, {5,0,5}, {6,0,6}, {7,0,8}, {9,0,10}, {11,0,11}, {13,0,13}}; + const ServerSettingStruct settingStructChangeAfterTrans[] = {{1,TServerSetting::EDeleted,1}, + {3,TServerSetting::EDeleted,3}, {4,0,4}, {6,0,6}, {7,0,8}, {9,0,10}}; + + // ERestoreMerge + const ServerSettingStruct settingStructPersistAfterRest[] = {{1,0,1}, {2,0,2}, {3,KMetaBackup,3}, {4,0,4}, {5,0,5}, {6,0,6}, {7,0,8}, {9,0,10}, {11,0,11}, {13,0,13}}; + const ServerSettingStruct settingStructChangeAfterRest[] = {{2,0,2}, {4,0,4}, {6,0,6}, {7,0,8}, {9,0,10}}; + + // ESWIUpgradeMerge + const ServerSettingStruct settingStructPersistAfterSWIUp[] = {{1,0,1}, {2,0,2}, {3,KMetaBackup,3}, {4,0,4}, {5,0,5}, {6,0,6}, {7,0,7}, {9,0,10}, {11,0,11}, {13,0,13}}; + const ServerSettingStruct settingStructChangeAfterSWIUp[] = {{2,0,2}, {4,0,4}, {6,0,6}, {9,0,10}}; + + // ESWIDowngradeMerge + const ServerSettingStruct settingStructPersistAfterSWIDown[] = {{1,0,1}, {2,0,2}, {3,KMetaBackup,3}, {4,0,4}, {5,0,5}, {6,0,6}, {7,0,7}, {9,0,10}, {11,0,11}}; + const ServerSettingStruct settingStructChangeAfterSWIDown[] = {{2,0,2}, {4,0,4}, {6,0,6}, {9,0,10}, {13,0,0}}; + + // ERomFlash + const ServerSettingStruct settingStructPersistAfterRomFlash[] = {{1,0,1}, {2,0,2}, {3,KMetaBackup,3}, {4,0,4}, {5,0,5}, {6,0,6}, {7,0,7}, {9,0,10}, {11,0,11}}; + const ServerSettingStruct settingStructChangeAfterRomFlash[] = {{1,0,1}, {2,0,2}, {3,0,3}, {4,0,4}, {5,0,5}, {6,0,6}, {7,0,8}, {9,0,10}}; + + // Reference arrays + RSettingsArray persistAfter[5]; + RSettingsArray changeAfter[5]; + RArray deletedAfter[5]; + + // Sets up the reference arrays for each merge type: + // ETransactionMerge + SetupSettingsArrayL(persistAfter[0],settingStructPersistAfterTrans, sizeof(settingStructPersistAfterTrans)/sizeof(ServerSettingStruct)); + SetupSettingsArrayL(changeAfter[0],settingStructChangeAfterTrans, sizeof(settingStructChangeAfterTrans)/sizeof(ServerSettingStruct)); + deletedAfter[0].InsertInUnsignedKeyOrderL(3); + + // ERestoreMerge + SetupSettingsArrayL(persistAfter[1],settingStructPersistAfterRest, sizeof(settingStructPersistAfterRest)/sizeof(ServerSettingStruct)); + SetupSettingsArrayL(changeAfter[1],settingStructChangeAfterRest, sizeof(settingStructChangeAfterRest)/sizeof(ServerSettingStruct)); + //deletedAfter[1] should be empty because Restore Merge should not delete any setting. + + // ESWIUpgradeMerge + SetupSettingsArrayL(persistAfter[2],settingStructPersistAfterSWIUp, sizeof(settingStructPersistAfterSWIUp)/sizeof(ServerSettingStruct)); + SetupSettingsArrayL(changeAfter[2],settingStructChangeAfterSWIUp, sizeof(settingStructChangeAfterSWIUp)/sizeof(ServerSettingStruct)); + //deletedAfter[2] should be empty because SWIUpgrade Merge should not delete any setting. + + // ESWIDowngradeMerge + SetupSettingsArrayL(persistAfter[3],settingStructPersistAfterSWIDown, sizeof(settingStructPersistAfterSWIDown)/sizeof(ServerSettingStruct)); + SetupSettingsArrayL(changeAfter[3],settingStructChangeAfterSWIDown, sizeof(settingStructChangeAfterSWIDown)/sizeof(ServerSettingStruct)); + //deletedAfter[3] should be empty because settings deleted by SWIDowngrade Merge are recorded in aChanges. + + // ERomFlash + SetupSettingsArrayL(persistAfter[4],settingStructPersistAfterRomFlash, sizeof(settingStructPersistAfterRomFlash)/sizeof(ServerSettingStruct)); + SetupSettingsArrayL(changeAfter[4],settingStructChangeAfterRomFlash, sizeof(settingStructChangeAfterRomFlash)/sizeof(ServerSettingStruct)); + //deletedAfter[4] should be empty because settings deleted by RomFlash Merge are recorded in aChanges. + + TheTest.Printf(_L("- Verification test for MergeArray.\n")); + MergerArrayTestL(persistAfter, changeAfter, deletedAfter, EFalse); + + TheTest.Printf(_L("- OOM test for MergeArray.\n")); + MergerArrayTestL(persistAfter, changeAfter, deletedAfter, ETrue); + + // Resets the reference arrays. + for(TInt i = 0; i < sizeof(KMergerTypes) / sizeof(TMergeType); i++) + { + persistAfter[i].Reset(); + changeAfter[i].Reset(); + deletedAfter[i].Reset(); + } + } +/** +@SYMTestCaseID PDS-CENTRALREPOSITORY-UT-4046 +@SYMTestCaseDesc The centrep server panics when it reads a repository text file where + the value of a binary settings is missing. +@SYMTestPriority Medium +@SYMTestActions - Provide a repository text file for this test which have a binary + setting which value is missing. + - Open the repository text file, + this should return KErrCorrupt when parsing the repository text file. +@SYMTestExpectedResults The test must not fail. +@SYMDEF PDEF126904 +*/ +LOCAL_C void PDEF126904L() + { + const TUid KUidBinaryValueRepositoryFile ={0x1020506B}; + const TInt KBinaryValueRepKey = 0xA; + TInt binaryValue = 0; + CRepository* repository = NULL; + + TRAPD(res, repository = CRepository::NewL(KUidBinaryValueRepositoryFile)); + if (res == KErrNone) + { + TInt err = KErrNone; + CleanupStack::PushL(repository); + err = repository->Get(KBinaryValueRepKey, binaryValue); + User::LeaveIfError(err); + CleanupStack::PopAndDestroy(repository); + } + else if (res == KErrCorrupt) + { + //This is just to confirm that the err should be KErrCorrupt. + TheTest.Printf(_L("The error is KErrCorrupt as expected.\n")); + } + else + { + User::Leave(res); + } +} + +/** +@SYMTestCaseID PDS-CENTRALREPOSITORY-UT-4084 +@SYMTestCaseDesc Ensure that the timestamp in a TXT file is always zero when not specified + instead of arbitrary value +@SYMTestPriority Medium +@SYMTestActions Create the CHeapRepository object from a TXT keyspace file where no timestamp(legacy) + section is specified. The timestamp should be set to zero +@SYMTestExpectedResults The test must not fail. +@SYMDEF DEF136161 +*/ +LOCAL_C void DEF136161L() + { + RFs fs; + User::LeaveIfError(fs.Connect()); + + //this is a TXT based ROM keyspace + const TUid KTestUid={0x00000001}; + + CHeapRepository* repos=CHeapRepository::NewL(KTestUid); + CIniFileIn* iniFile; + TInt ret=CIniFileIn::NewLC(fs,iniFile,_L("z:\\private\\10202be9\\00000001.txt")); + User::LeaveIfError(ret); + repos->ReloadContentL(*iniFile); + + //check the timestamp is always set to zero + TEST(repos->TimeStamp()==TTime(0)); + + CleanupStack::PopAndDestroy(iniFile); + delete repos; + + fs.Close(); + } + +/** +@SYMTestCaseID PDS-CENTRALREPOSITORY-UT-4085 +@SYMTestCaseDesc Central Repository: Trying to configure Central Repository cache with centrep.in +@SYMTestPriority High +@SYMTestActions Testing that the SWIWatcher does nto leave when the cache configuration exists within +the private data cate +@SYMTestExpectedResults Test should pass and exhibit the expected behaviour +@SYMDEF PDEF139979 +*/ +LOCAL_C void PDEF139979L() + { + __UHEAP_MARK; + CActiveScheduler* s=new(ELeave) CActiveScheduler; + CleanupStack::PushL(s); + CActiveScheduler::Install(s); + + RFs fs; + User::LeaveIfError(fs.Connect()); + CleanupClosePushL(fs); + + CFileMan* fm = CFileMan::NewL(fs); + CleanupStack::PushL(fm); + + TRAPD(err,TServerResources::InitialiseL()); + TEST2(err,KErrNone); + + delete TServerResources::iInstallDirectory; + _LIT(KInstallFolder,"c:\\private\\12345678\\"); + TServerResources::iInstallDirectory=(KInstallFolder()).AllocL(); + TInt erro=fm->Delete(_L("c:\\private\\12345678\\*.*")); + //copy centrep.ini file to the install folder + _LIT(KSource,"z:\\private\\10202be9\\centrepcache.ini0"); + _LIT(KDestination,"c:\\private\\12345678\\centrep.ini"); + TRAP(err,CopyTestFilesL(*fm,KSource(),KDestination())); + + CCentRepSWIWatcher* swi=CCentRepSWIWatcher::NewL(fs); + TRAP(err,swi->FindChangedEntriesL(EFalse)); + TEST2(err,KErrNone); + + delete swi; + TServerResources::Close(); + + //delete the c file before we exit + fm->Delete(KDestination()); + + CleanupStack::PopAndDestroy(3); + __UHEAP_MARKEND; + } + +/** +@SYMTestCaseID PDS-CENTRALREPOSITORY-UT-4086 +@SYMTestCaseDesc centralrepositorysrv.exe crashes and phone doesn't boot up +@SYMTestPriority High +@SYMTestActions Test merging two settings of different type, one type exist for +persist and one type for the new rom, when the type differes, we expect the +persist setting to be completely replaced by the rom. +@SYMTestExpectedResults The test must not panic or fail. +@SYMDEF PDEF141519 +*/ +LOCAL_C void PDEF141519L() + { + __UHEAP_MARK; + + RSettingsArray persist; + RSettingsArray newRom; + RArray deletedSettings; + //persist setting + TServerSetting a(0x10); + a.SetType(TServerSetting::EInt); + a.SetIntValue(100); + persist.OrderedInsertL(a); + + //new rom setting + TServerSetting b(0x10); + b.SetType(TServerSetting::EString); + TBuf8<5> buffer(_L8("abc")); + HBufC8* hbuf=buffer.AllocL(); + b.SetStrValue(hbuf); + newRom.OrderedInsertL(b); + + User::LeaveIfError(persist.MergeArray(newRom,deletedSettings,ERomFlash)); + TServerSetting* persistEntry=persist.Find(0x10); + TEST2(persistEntry->Key(),0x10); + TEST2(persistEntry->Type(),TServerSetting::EString); + const HBufC8* val=persistEntry->GetStrValue(); + TEST2(val->Compare(buffer),0); + + persist.Close(); + newRom.Close(); + + __UHEAP_MARKEND; + } + + +LOCAL_C void FuncTestsL() + { + + TheTest.Start(_L("DEF053500 - Central repository integer type key entries cannot handle hex values")); + + DEF053500L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-4015 DEF111734 - Central repository crashes when accessing a closed repository with active transaction ")); + DEF111734L(); + + TheTest.Next(_L("DEF054368 - MetaData value in CentRep setting is not optional")); + DEF054368L(); + + TheTest.Next(_L("DEF055680 - Central repository find performance could be improved ")); + DEF055680L(); + + TheTest.Next(_L("INC054688 - Key based capabilities in ini-file crashes cenrep server ")); + INC054688L(); + + TheTest.Next(_L("DEF054632 - CenRep Initialisation default data does not work as expected")); + DEF054632L(); + + TheTest.Next(_L("DEF055661 - Central Repository does not allow AlwaysFail to be set for access control. ")); + DEF055661L(); + + TheTest.Next(_L("DEF055267 - Can not insert more than 71 records into WapAccessPoint Table ")); + DEF055267L(); + + TheTest.Next(_L("INC056194 - NTT - Central Repository checks DefaultWriteAccessPolicy when cancelling notif ")); + INC056194L(); + + TheTest.Next(_L("DEF057145 - CenRepSrv KERN-EXEC3 when running CommDB test harness ")); + DEF057145L(); + + TheTest.Next(_L("DEF057778 - Central repository ResetAll can cause user Panic 190 ")); + DEF057778L(); + + TheTest.Next(_L("DEF057522 - Centralrepository security policy incorrect behaviour ")); + DEF057522L(); + + TheTest.Next(_L("DEF057999 - Creating and deleting the same setting in a transaction doesn't work ")); + DEF057999L(); + + TheTest.Next(_L("DEF057470 - Central repository lacks a range delete method ")); + DEF057470L(); + + TheTest.Next(_L("INC058229 - CInstallFileWatcher::ReadInstallDirL contains insufficient error handling ")); + INC058229L(); + + TheTest.Next(_L("DEF058900 - CentralRepository Notification section document needs update ")); + DEF058900L(); + + TheTest.Next(_L("DEF061087 - Central repository cannot handle more than one range policy ")); + DEF061087L(); + + TheTest.Next(_L("DEF060843 - [PSAudit] Lack of centralrep. data type checking could cause instability & bugs ")); + DEF060843L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-1433 INC069013 - Central repository panics the client when trying to read 8-bit descriptor with uneven length ")); + INC069013L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-1434 DEF070731 - Central repository doesn't handle corrupt .cre files correctly. ")); + DEF070731L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-1683 DEF084700 - UIF automated tests crash H4 board. ")); + DEF084700L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-1862 DEF089945: [AQP] CommitTransaction returns incorrect error code if Find~L methods run OOM ")); + DEF089945L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-3242 PDEF098500 - Backup to memory card causes phone freeze ")); + PDEF098500(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-1884 DEF093855: CenRep cancels transactions if they exceed 5 seconds... ")); + DEF093855L(); + + +// When adding a new defect test, if you decide to reuse a repository that has already been used +// in another defect test, make sure you modify the existing test which uses the repository and +// add the cache delay after that test closes the repository. e.g. DEF055680L + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-3477 PDEF106507 - Currupt installdir.bin file causes server to crash ")); + PDEF106507L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-3517 INC108803 - R3.2 stability problems: CentralRepositorySrv crash ")); + INC108803L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-3545 DEF109390: Centrep cache ini file corruption should not cause server crash. ")); + DEF109390L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-UT-4024 DEF116043: Cenrep doesn't protect against overflows in sorting ")); + DEF116043L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-4035 DEF117987: CenrepNotify handler does not leave/return error ")); + DEF117987L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-CT-4034 DEF117848: Centrep notifier handler does not check return codes ")); + DEF117848L(); + + TheTest.Next(_L(" @SYMTestCaseID SYSLIB-CENTRALREPOSITORY-CT-4036 DEF118107: Central Repository Notification Handler flooded with notifications ")); + DEF118107L(); + + TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-CENTRALREPOSITORY-UT-4037 DEF116629: CentralRepository internal merge function need to be refactored and documented")); + DEF116629L(); + + TheTest.Next(_L(" @SYMTestCaseID:PDS-CENTRALREPOSITORY-UT-4046 PDEF126904 - Ini-file parsing of Symbian provided central repository server crashes")); + PDEF126904L(); + TheTest.Next(_L(" @SYMTestCaseID:PDS-CENTRALREPOSITORY-UT-4081 DEF132807 - CObservable::ObserverSortOrder ordering algorithm is wrong ")); + DEF132807L(); + + TheTest.Next(_L("@SYMTestCaseID:PDS-CENTRALREPOSITORY-UT-4084 DEF136161: CenRep file timestamp is never intialised ")); + DEF136161L(); + + TheTest.Next(_L("@SYMTestCaseID:PDS-CENTRALREPOSITORY-UT-4085 PDEF139979: Central Repository: Trying to configure Central Repository cache with centrep.in ")); + PDEF139979L(); + + TheTest.Next(_L("@SYMTestCaseID:PDS-CENTRALREPOSITORY-UT-4086 PDEF141518: centralrepositorysrv.exe crashes and phone doesn't boot up ")); + PDEF141519L(); + + TheTest.End(); + } + +LOCAL_C void MainL() + { + TheTest.Start(_L("Defect tests")); + CleanupCDriveL(); + + FuncTestsL(); + + TheTest.Next(_L("Clean out C: files")); + CleanupCDriveL(); + + TheTest.End(); + TheTest.Close(); + } + +TInt E32Main() + { + // + // For the tests to work we need SID policing enforced plus the specific + // capabilities listed below. + // + // These are dependent on the capabilities set in the platform security + // repository test initialisation file 87654321.txt. If the content + // of that file changes then the following clauses may need to be + // updated. + // + if(!PlatSec::ConfigSetting(PlatSec::EPlatSecEnforcement) || + !PlatSec::IsCapabilityEnforced(ECapabilityNetworkServices) || + !PlatSec::IsCapabilityEnforced(ECapabilityDRM) || + !PlatSec::IsCapabilityEnforced(ECapabilityLocalServices) || + !PlatSec::IsCapabilityEnforced(ECapabilityCommDD)) + { + TheTest.Start(_L("NOTE: Skipping tests due to incompatible PlatSec enforcement settings")); + TheTest.End(); + TheTest.Close(); + return 0; + } + + __UHEAP_MARK; + CTrapCleanup* cleanup = CTrapCleanup::New(); + if(!cleanup) + return KErrNoMemory; + + TRAPD(err, MainL()); + if (err != KErrNone) + User::Panic(_L("Testing failed: "), err); + + delete cleanup; + __UHEAP_MARKEND; + + return 0; + }