diff -r 000000000000 -r 2e3d3ce01487 tzservices/tzserver/test/component/tz_userdata.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tzservices/tzserver/test/component/tz_userdata.cpp Tue Feb 02 10:12:00 2010 +0200 @@ -0,0 +1,1799 @@ +// Copyright (c) 2008-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 +#include +#include +#include +#include +#include "testserver.h" +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include +#include +#endif +#include +#include +#include "tzidinternal.h" + + +_LIT(KTzUserDataDb, "c:\\private\\1020383e\\SQLite__tzuserdata.db"); + +const TInt KPrintFreq=500; + +static RPIMTestServer Serv; +// Forward class references. +class CTzUserDataTest; + + +_LIT(KTestName,"User-Defined TZ Data Test Suite"); +RTest test(KTestName); + + +_LIT8(KTzLondon, "Europe/London"); + + +typedef void (CTzUserDataTest::*OOMTestFunction)(); + + +class CTzUserDataTest : public CBase + { +public: + enum TOOMTest + { + EClientOOM, + EServerOOM + }; + + enum TTest + { + ETimeConversion, + EDayLightSave, + EDeleteCurrentUserRule, + EUpdateCachedTz, + EDeleteCachedTz, + EPersistence + }; + + static CTzUserDataTest* NewLC(); + ~CTzUserDataTest(); + + // Basic test - client operations on user-defined time zones. + void TestBasicUserDataL(); + void TestOutOfMemoryBehaviourL(TOOMTest aOOMTest); + void TestTimeZoneRulesL(TTest aWhatToTest); + void TestServerResponseToChangesL(); + void TestReadIdsL(RTz& aRTz); + void TestIdsL(RTz& aRTz); + void TestTimeConversionL(); + void TestDaylightSaveL(); + void TestDeleteCurrentTimeZoneL(RTz& aTz); + void TestCurrentTimeZonePersistenceL(RTz& aTz); + void TestUpdateCachedUserTimeZoneL(RTz& aTz); + void TestDeletedCachedUserTimeZoneL(RTz& aTz); + void BoundaryTestL(); + void TestTzIdReusabilityL(); + void NullTestL(); + void TestShortTzId(RTz& aRTz); + +private: + CTzUserDataTest(); + + // Basic operations. + void TestCreateUserDefinedTzL(); + void TestUpdateUserDefinedTzL(); + void TestDeleteUserDefinedTzL(); + void ReadIdsAndTestL(RTz& aRTz, TBool aCheckId); + + // Create user-defined time zone. + void CreateTzAndCheckL(TInt aOldOffset, TInt aNewOffset, RTz& aRTz, TTest aWhatToTest); + CTzId* CreateUserDefinedTzL(TInt16 aStandardOffset,TInt16 aDSTOffset, TBool aCheck); + void CreateUserTzBasedOnLondonRuleL(RTz& aRTz, TTest aWhatToTest); + void CreateUserTzBasedOnShanghaiRuleL(RTz& aRTz, TTest aWhatToTest); + CTzUserNames* CreateUserDefinedTzNamesLC(); + CTzRules* CreateUserDefinedTzLC(TInt16 aStandardOffset,TInt16 aDSTOffset); + + // OOM tests. + void CreateOOML(); + void ReadOOML(); + void GetIdsOOML(); + void UpdateOOML(); + void DeleteOOML(); + void OOMTestL(OOMTestFunction aFunction, TOOMTest aOOMTest); + + // TZ Server response to changes. + void DeleteCurrentTzL(RTz& aTz); + void UpdateCurrentTzL(RTz& aTz,TInt aOldOffSet, TInt aNewOffSet); + void DeleteCurrentUserTzL(RTz& aTz, TTest aWhatToTest); + void UpdateCurrentUserTzL(RTz& aTz); + void CreateUserTzAndSetCurrentTimeToL(RTz& aTz, TInt aStandardOffSet, TInt aDSTOffset); + void CachedUserTimeZoneL(RTz& aRTz, TTest aWhatToTest); + + // Utility methods. + void CreateString(TDes& aString); + TBool CompareArray(const RPointerArray& aIds1, const RPointerArray& aIds2); + TBool CompareNames(const CTzUserNames& aName1, const CTzUserNames& aNames); + void TestDaylightSavingStateL(CTzId& aTzId, const RArray& times, TBool aIsOn, RTz& aRTz); + void TestUtcOffsetL(CTzId& aTzId,const CTzRules& rules, const RArray& times, TInt aOffset, RTz& aRTz); + void CheckTimeZoneL(const CTzId& aId, const CTzRules& aRules, const CTzUserNames& aNames); + + void ResetTzUserDataL(); + +private: + RPointerArray iTzIds; //Used for transfering time zone IDs in delete and update test. + CTzUserData* iUserData; + TInt64 iSeed; + }; + + +CTzUserDataTest* CTzUserDataTest::NewLC() + { + CTzUserDataTest* self = new (ELeave) CTzUserDataTest(); + CleanupStack::PushL(self); + return (self); + } + + +CTzUserDataTest::CTzUserDataTest() + :iSeed(100) + { + } + + +CTzUserDataTest::~CTzUserDataTest() + { + TRAP_IGNORE(ResetTzUserDataL()); + delete iUserData; + } + + +LOCAL_D void ResetTimeZoneToLondonL() + { + RTz tz; + User::LeaveIfError(tz.Connect()); + CleanupClosePushL(tz); + + CTzId* id = CTzId::NewL(KTzLondon); + CleanupStack::PushL(id); + tz.SetTimeZoneL(*id); + CleanupStack::PopAndDestroy(2, &tz); + } + + +LOCAL_D void ResetAndDestroyTzIdArray(TAny* aPtr) + { + RPointerArray* ids = static_cast*>(aPtr); + if (ids) + { + ids->ResetAndDestroy(); + } + } + + +void CTzUserDataTest::CreateString(TDes& aString) + { + for (TInt i(0) ; i < 10 ; ++i) + { + // Add random upper and lower case letters + aString.Append( 'A' + (Math::Rand(iSeed) % 26) ); + } + } + + +TBool CTzUserDataTest::CompareArray(const RPointerArray& aIds1, const RPointerArray& aIds2) + { + TInt count1 = aIds1.Count(); + TInt count2 = aIds2.Count(); + test(count1 == count2); + + TBool isEqual = ETrue; + TInt ii=0; + + while(ii& times, TInt aOffset, RTz& aRTz ) + { + aRTz.SetTimeZoneL(aTzId); + + TInt count = times.Count(); + + for(TInt ii=0; ii& times, TBool aIsOn, RTz& aRTz) + { + aRTz.SetTimeZoneL(aTzId); + TInt count = times.Count(); + for(TInt ii=0; iiGetTzIdsL(iTzIds); + TInt count = iTzIds.Count(); + for (TInt ii=0; iiDeleteL(*iTzIds[ii]); + } + CleanupStack::PopAndDestroy(2, &tz); + + iTzIds.ResetAndDestroy(); + } + + +CTzId* CTzUserDataTest::CreateUserDefinedTzL(TInt16 aStandardOffset,TInt16 aDSTOffset, TBool aCheck) + { + CTzRules* rules = CreateUserDefinedTzLC(aStandardOffset, aDSTOffset); + CTzUserNames* names = CreateUserDefinedTzNamesLC(); + CTzId* id = iUserData->CreateL(*rules, *names); + CleanupStack::PushL(id); + if(aCheck) + { + CheckTimeZoneL(*id, *rules, *names); + } + CleanupStack::Pop(id); + CleanupStack::PopAndDestroy(2, rules); + return id; + } + + +void CTzUserDataTest::CheckTimeZoneL(const CTzId& aId, const CTzRules& aRules, const CTzUserNames& aNames) + { + CTzRules* rulesGet = iUserData->ReadRulesL(aId); + CleanupStack::PushL(rulesGet); + test(aRules.IsEqualTo(*rulesGet)); + CleanupStack::PopAndDestroy(rulesGet); + + CTzUserNames* namesGet = iUserData->ReadNamesL(aId); + CleanupStack::PushL(namesGet); + test (CompareNames(aNames, *namesGet)); + CleanupStack::PopAndDestroy(namesGet); + } + + +void CTzUserDataTest::CreateUserTzBasedOnLondonRuleL(RTz& aRTz, TTest aWhatToTest) + { + test.Next(_L("Test Creation user-defined time zone based on London rules")); + //create a new rule which doesn't have DST saving. + TTime start (TDateTime(2010, ESeptember, 0, 0, 0, 0, 0)); + TInt year = start.DateTime().Year(); + TMonth month = start.DateTime().Month(); + TInt day = start.DateTime().Day(); + TTzRule newrule(year, 9999, 0, 0, month, ETzFixedDate, day, 0, ETzWallTimeReference, 120); + + //Get the existing london rule + _LIT8(KTimeNone, "Europe/London"); + + CTzId* londonId = CTzId::NewL(KTimeNone()); + CleanupStack::PushL(londonId); + CTzRules* userrule = aRTz.GetTimeZoneRulesL(*londonId, 0, 9999, ETzUtcTimeReference); + CleanupStack::PopAndDestroy(londonId); + + //Use London rule to create a new user-defined rule + TInt count = userrule->Count(); + + //Since the last two rules (TTzRule objects one for summer rule one for winter rule) in existing database covers the years in which a new rule starts. + //The client has to amend the ending years of those two rules before adding a new rule. + //We set the ending year for last two rules to 2009 since the new rule starts on 2010 + + TTzRule lastRule = (*userrule)[count-1]; + TDateTime dateTimeLast = lastRule.iTo.iTime.DateTime(); + dateTimeLast.SetYear(2009); + lastRule.iTo.iTime = dateTimeLast; + + TTzRule lastSecondRule = (*userrule)[count-2]; + TDateTime dateTimeLastSecond = lastSecondRule.iTo.iTime.DateTime(); + dateTimeLastSecond.SetYear(2009); + lastSecondRule.iTo.iTime = dateTimeLastSecond; + + CleanupStack::PushL(userrule); + //Remove last two existing rules + userrule->RemoveRule(count-1); + userrule->RemoveRule(count-2); + + //Add two rules whoes ending years have been amended + userrule->AddRuleL(lastRule); + userrule->AddRuleL(lastSecondRule); + + //Add the new rule + userrule->AddRuleL(newrule); + //userrule->AddRuleL(newrule);//add the new rule which doesn't have DST + + CTzUserNames* newRuleNames = CreateUserDefinedTzNamesLC(); + CTzId* id = iUserData->CreateL(*userrule, *newRuleNames); + CleanupStack::PushL(id); + iTzIds.AppendL(id); + CleanupStack::Pop(id); + CheckTimeZoneL(*id, *userrule, *newRuleNames); + CleanupStack::PopAndDestroy(newRuleNames); + + RArray timesOn; + CleanupClosePushL(timesOn); + RArray timesOff; + CleanupClosePushL(timesOff); + + // Check UTC offset and DST. + TTime check = TDateTime(1998, ESeptember, 0, 0, 0, 0, 0); + timesOn.AppendL(check); + check = TDateTime(2005, ESeptember, 0, 0, 0, 0, 0); + timesOn.AppendL(check); + check = TDateTime(2009, ESeptember, 0, 0, 0, 0, 0); + timesOn.AppendL(check); + + check = TDateTime(2010, ESeptember, 0, 3, 0, 0, 0); + timesOff.AppendL(check); + check = TDateTime(2015, ESeptember, 0, 3, 0, 0, 0); + timesOff.AppendL(check); + check = TDateTime(2020, ESeptember, 0, 3, 0, 0, 0); + timesOff.AppendL(check); + + if(aWhatToTest==ETimeConversion) + { + TestUtcOffsetL(*id,*userrule, timesOn, 60, aRTz); + TestUtcOffsetL(*id,*userrule, timesOff, 0, aRTz); + } + else if(aWhatToTest==EDayLightSave) + { + TestDaylightSavingStateL(*id, timesOn, ETrue, aRTz); + TestDaylightSavingStateL(*id, timesOff, EFalse, aRTz); + } + + CleanupStack::PopAndDestroy(3, userrule); + } + + +void CTzUserDataTest::CreateUserTzBasedOnShanghaiRuleL(RTz& aRTz, TTest aWhatToTest) + { + _LIT8(KTimeNone, "Asia/Shanghai"); + + CTzId* shanghaiId = CTzId::NewL(KTimeNone()); + CleanupStack::PushL(shanghaiId); + + CTzRules* shanghaiRule = aRTz.GetTimeZoneRulesL(*shanghaiId, 0, 9999, ETzUtcTimeReference); + CleanupStack::PopAndDestroy(shanghaiId); + + // Last rule: 00:00:000 Date:1/01/1987 Time: 23:59:59:000 Date:31/12/1991 Old=480 New=540 Ch=0 + TTime dston (TDateTime(2010, EMarch, 0, 0, 0, 0, 0)); + TTime dstoff (TDateTime(2010, ESeptember, 0, 0, 0, 0, 0)); + TMonth monthOn = dston.DateTime().Month(); + TInt dayOn = dston.DateTime().Day(); + TMonth monthOff = dstoff.DateTime().Month(); + TInt dayOff = dstoff.DateTime().Day(); + + test.Next(_L("Test Creation user-defined time zone based on Shanghai rules")); + + TTzRule dstOn(2010, 9999, 480, 540, monthOn, ETzFixedDate, dayOn, 0, ETzWallTimeReference, 120); + TTzRule dstOff (2010, 9999, 540, 480, monthOff, ETzFixedDate, dayOff, 0, ETzWallTimeReference, 120); + + CleanupStack::PushL(shanghaiRule); + shanghaiRule->AddRuleL(dstOff);//add the new rule which have DST + shanghaiRule->AddRuleL(dstOn); + CTzUserNames* newRuleNames = CreateUserDefinedTzNamesLC(); + + CTzId* id = iUserData->CreateL(*shanghaiRule, *newRuleNames); + CleanupStack::PushL(id); + iTzIds.AppendL(id); + CleanupStack::Pop(id); + + CheckTimeZoneL(*id, *shanghaiRule, *newRuleNames); + + // Check UTC offset and DST. + RArray timesOn; + CleanupClosePushL(timesOn); + RArray timesOff; + CleanupClosePushL(timesOff); + + TTime check = TDateTime(1998, ESeptember, 0, 3, 0, 0, 0); + timesOff.AppendL(check); + check = TDateTime(2005, ESeptember, 0, 3, 0, 0, 0); + timesOff.AppendL(check); + check = TDateTime(2020, ESeptember, 0, 3, 0, 0, 0); + timesOff.AppendL(check); + + check = TDateTime(2011, EAugust, 0, 0, 0, 0, 0); + timesOn.AppendL(check); + check = TDateTime(2015, EAugust, 0, 0, 0, 0, 0); + timesOn.AppendL(check); + check = TDateTime(2020, EAugust, 0, 0, 0, 0, 0); + timesOn.AppendL(check); + + if(aWhatToTest==ETimeConversion) + { + TestUtcOffsetL(*id,*shanghaiRule, timesOn, 540, aRTz); + TestUtcOffsetL(*id,*shanghaiRule, timesOff, 480, aRTz); + } + else if(aWhatToTest==EDayLightSave) + { + TestDaylightSavingStateL(*id, timesOn, ETrue, aRTz); + TestDaylightSavingStateL(*id, timesOff, EFalse, aRTz); + } + + CleanupStack::PopAndDestroy(4, shanghaiRule); + } + + +CTzRules* CTzUserDataTest::CreateUserDefinedTzLC(TInt16 aStandardOffset,TInt16 aDSTOffset) + { + TTime dston (TDateTime(2005, EMarch, 0, 0, 0, 0, 0)); + TTime dstoff (TDateTime(2005, ESeptember, 0, 0, 0, 0, 0)); + TMonth monthOn = dston.DateTime().Month(); + TInt dayOn = dston.DateTime().Day(); + TMonth monthOff = dstoff.DateTime().Month(); + TInt dayOff = dstoff.DateTime().Day(); + + TTzRule dstOff(0, 9999, aStandardOffset, aDSTOffset, monthOn, ETzFixedDate, dayOn, 0, ETzWallTimeReference, 120); + TTzRule dstOn (0, 9999, aDSTOffset, aStandardOffset, monthOff, ETzFixedDate, dayOff, 0, ETzWallTimeReference, 120); + + CTzRules* rules = CTzRules::NewL(0, 9999); + CleanupStack::PushL(rules); + rules->AddRuleL(dstOff); + rules->AddRuleL(dstOn); + return rules; + } + + +CTzUserNames* CTzUserDataTest::CreateUserDefinedTzNamesLC() + { + TBuf<10> standardName; + CreateString(standardName); + + TBuf<10> shortStandardName; + CreateString(shortStandardName); + + TBuf<10> dayLightSaveName; + CreateString(dayLightSaveName); + + TBuf<10> shortDayLightSaveName; + CreateString(shortDayLightSaveName); + + TBuf<10> cityName; + CreateString(cityName); + + TBuf<10> regionName; + CreateString(regionName); + + return CTzUserNames::NewLC(standardName, shortStandardName, dayLightSaveName, shortDayLightSaveName, cityName, regionName); + } + + +void CTzUserDataTest::CreateTzAndCheckL(TInt aOldOffset, TInt aNewOffset, RTz& aRTz, TTest aWhatToTest) + { +/* On the day: + + TTime dston (TDateTime(2005, EMarch, 0, 0, 0, 0, 0)); + TTime dstoff (TDateTime(2005, ESeptember, 0, 0, 0, 0, 0)); + +After two hours DST changes which should be repeated every year +*/ + RArray timesOn; + CleanupClosePushL(timesOn); + RArray timesOff; + CleanupClosePushL(timesOff); + + TTime check = TDateTime(1920, EMarch, 0, 0, 0, 0, 0); + timesOff.AppendL(check); + check = TDateTime(2005, EMarch, 0, 0, 0, 0, 0); + timesOff.AppendL(check); + check = TDateTime(2020, EMarch, 0, 0, 0, 0, 0); + timesOff.AppendL(check); + + check = TDateTime(1920, EMarch, 0, 3, 0, 0, 0); + timesOn.AppendL(check); + check = TDateTime(2005, EMarch, 0, 3, 0, 0, 0); + timesOn.AppendL(check); + check = TDateTime(2020, EMarch, 0, 3, 0, 0, 0); + timesOn.AppendL(check); + + CTzId* id = CreateUserDefinedTzL(aOldOffset, aNewOffset, ETrue); + CleanupStack::PushL(id); + CTzRules* rules = iUserData->ReadRulesL(*id); + CleanupStack::PushL(rules); + + if (aWhatToTest==ETimeConversion) + { + TestUtcOffsetL(*id,*rules, timesOn, aNewOffset, aRTz); + TestUtcOffsetL(*id,*rules, timesOff, aOldOffset, aRTz); + } + else if (aWhatToTest==EDayLightSave) + { + TBool isDSTon = aOldOffset != aNewOffset; + TestDaylightSavingStateL(*id, timesOn, isDSTon, aRTz); + TestDaylightSavingStateL(*id, timesOff, EFalse, aRTz); + } + + CleanupStack::PopAndDestroy(4, ×On); + } + + +void CTzUserDataTest::CreateOOML() + { + CTzId* id = CreateUserDefinedTzL(60, 60, EFalse); + delete id; + } + + +void CTzUserDataTest::ReadOOML() + { + CTzRules* rule = iUserData->ReadRulesL(*iTzIds[0]); + CleanupStack::PushL(rule); + CTzUserNames* newNames = iUserData->ReadNamesL(*iTzIds[0]); + CleanupStack::PopAndDestroy(rule); + delete newNames; + } + + +void CTzUserDataTest::GetIdsOOML() + { + RPointerArray ids; + CleanupStack::PushL(TCleanupItem(ResetAndDestroyTzIdArray, &ids)); + iUserData->GetTzIdsL(ids); + CleanupStack::PopAndDestroy(&ids); + } + + +void CTzUserDataTest::UpdateOOML() + { + CTzRules* rules = CreateUserDefinedTzLC(0, 0); + CTzUserNames* newNames = CreateUserDefinedTzNamesLC(); + iUserData->UpdateL(*(iTzIds[0]), *rules, *newNames); + CleanupStack::PopAndDestroy(2, rules); + } + + +void CTzUserDataTest::DeleteOOML() + { + for(TInt ii=iTzIds.Count()-1; ii>=0; --ii) + { + //Delete the user-defined time zone as the last element in the array. + iUserData->DeleteL(*(iTzIds[ii])); + } + } + + +void CTzUserDataTest::OOMTestL(OOMTestFunction aFunction, TOOMTest aOOMTest) + { + TInt tryCount = 1; + + RTz tz; + User::LeaveIfError(tz.Connect()); + CleanupClosePushL(tz); + iUserData = CTzUserData::NewL(tz); + + TInt cellsBefore = 0; + + for (;;) + { + test.Printf(_L("Heap memory allocation set to fail at allocation #%d.\n"), + tryCount); + + if(aOOMTest == EClientOOM) + { + __UHEAP_SETFAIL(RAllocator::EDeterministic, tryCount); + __UHEAP_MARK; + } + else + { + TInt heapSize = 0; + tz.__dbgSetHeapFailL(RAllocator::EDeterministic, tryCount); + cellsBefore = tz.__dbgRequestAllocatedCellsL(heapSize); + } + + TRAPD(err, (this->*aFunction)()); + + if(err == KErrNone) + { + test.Printf(_L("OOM test complete.\n")); + break; + } + + test(err == KErrNoMemory); + + if(aOOMTest == EClientOOM) + { + __UHEAP_MARKEND; + } + else + { + tz.__dbgResetHeapL(); + TInt heapSize = 0; + TInt cellsAfter = tz.__dbgRequestAllocatedCellsL(heapSize); + if(cellsBefore != cellsAfter) + { + test.Printf(_L("ERROR: Memory leak. Heap cells: %d before, %d after.\n"), + cellsBefore, cellsAfter); + test(EFalse); + } + } + + tryCount++; + } + + __UHEAP_RESET; + tz.__dbgResetHeapL(); + + delete iUserData; + iUserData = NULL; + + CleanupStack::PopAndDestroy(&tz); + } + + +/** +Create and read user-defined time zones. + +@SYMTestCaseID PIM-APPSERV-TZS-CO-0001 + +@SYMTestCaseDesc + The purpose of this test is to verify that user-defined time zone rules and + names can be created and read back. + +@SYMTestActions + 1. Create a few user-defined time zone with different offset. + 2. Read the rules and names for the user-defined time zone created in action + 1. + +@SYMTestExpectedResults + The following information is the same as the information used to created + the user-defined time zone in action 1: + + - Time zone rules + - Standard time name + - Daylight saving time name + - Short standard time name + - Short daylight saving time name + - City name + - Region name + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ + + +void CTzUserDataTest::TestCreateUserDefinedTzL() + { + test.Next(_L("@SYMTestCaseID PIM-APPSERV-TZS-CO-0001 Create user-defined Time Zone")); + + // Offset 60 There is no DST + test.Printf(_L("Offset 60 There is no DST\n")); + + CTzId* id = CreateUserDefinedTzL(60, 60, ETrue); + CleanupStack::PushL(id); + iTzIds.AppendL(id); + CleanupStack::Pop(id); + + // Offset - 60 There is no DST + test.Printf(_L("Offset -60 There is no DST\n")); + id = CreateUserDefinedTzL(-60, -60, ETrue); + CleanupStack::PushL(id); + iTzIds.AppendL(id); + CleanupStack::Pop(id); + + // Offset 60 There is DST of 60 + id = CreateUserDefinedTzL(60, 120, ETrue); + CleanupStack::PushL(id); + iTzIds.AppendL(id); + CleanupStack::Pop(id); + + // Offset - 60 There is DST of 60 + test.Printf(_L("Offset - 60 There is DST of 60\n")); + id = CreateUserDefinedTzL(-60, 0, ETrue); + CleanupStack::PushL(id); + iTzIds.AppendL(id); + CleanupStack::Pop(id); + } + + +/** +Update user-defined time zone. + +@SYMTestCaseID PIM-APPSERV-TZS-CO-0002 + +@SYMTestCaseDesc + The purpose of this test is to verify that user-defined time zone time rules + and names can be updated. + +@SYMTestActions + 1. Create a user-defined time zone (rules and names). + 2. Get all existing user-defined time zones and update them with the rules + and names created in action 1. + 3. Read the new user-defined time zone rules and names updated in action 2. + +@SYMTestExpectedResults + The following information is the same as the information used to update the + user-defined time zone in action 3: + + - Time zone rules + - Standard time name + - Daylight saving time name + - Short standard time name + - Short daylight saving time name + - City name + - Region name + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ +void CTzUserDataTest::TestUpdateUserDefinedTzL() + { + test.Next(_L("@SYMTestCaseID PIM-APPSERV-TZS-CO-0002 ")); + CTzRules* newRule = CreateUserDefinedTzLC(0,0); + CTzUserNames* newNames = CreateUserDefinedTzNamesLC(); + + for(TInt ii=0; iiUpdateL(*(iTzIds[ii]), *newRule, *newNames); + + //Get and Compare + CTzRules* userRuleGet = iUserData->ReadRulesL(*(iTzIds[ii])); + test (userRuleGet->IsEqualTo(*newRule)); + delete userRuleGet; + + CTzUserNames* userNamesGet = iUserData->ReadNamesL(*(iTzIds[ii])); + test(CompareNames(*userNamesGet, *newNames)); + delete userNamesGet; + } + + CleanupStack::PopAndDestroy(2, newRule); + } + + +/** +Delete user-defined time zones. + +@SYMTestCaseID PIM-APPSERV-TZS-CO-0003 + +@SYMTestCaseDesc + The purpose of this test is to verify that user-defined time zones can be + deleted. + +@SYMTestActions + 1. Get all existing user-defined time zones. + 2. Delete the user-defined time zone as the last element in the array one + by one. + 3. Try to read the user-defined time zone deleted in action 2. + +@SYMTestExpectedResults + The user-defined time zone does not exist. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ +void CTzUserDataTest::TestDeleteUserDefinedTzL() + { + test.Next(_L("@SYMTestCaseID PIM-APPSERV-TZS-CO-0003")); + RPointerArray ids; + CleanupStack::PushL(TCleanupItem(ResetAndDestroyTzIdArray, &ids)); + + for(TInt ii=iTzIds.Count()-1; ii>=0; --ii) + { + iUserData->GetTzIdsL(ids); + + // The array obtained should be same as expected who elements is deleted + // one by one in each loop. + CompareArray(ids,iTzIds); + ids.ResetAndDestroy(); + + // Delete the user-defined time zone as the last element in the array. + iUserData->DeleteL(*(iTzIds[ii])); + + // The rule and names of the last element in the array should not be + // found since it has been deleted. + TRAPD(err, iUserData->ReadRulesL(*(iTzIds[ii]))); + test(err == KErrNotFound); + TRAP(err, iUserData->ReadNamesL(*(iTzIds[ii]))); + test(err == KErrNotFound); + + delete iTzIds[ii]; + iTzIds.Remove(ii); + } + + CleanupStack::PopAndDestroy(&ids); + } + + +/** +All user-defined time zone identifiers. + +@SYMTestCaseID PIM-APPSERV-TZS-CO-0004 + +@SYMTestCaseDesc + The purpose of this test is to verify that time zone identifiers for user- + defined time zones can be queried. + +@SYMTestActions + 1. Get all existing user-defined time zones. + +@SYMTestExpectedResults + The time zone identifiers obtained should be same as those existing ones. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ + + +void CTzUserDataTest::TestReadIdsL(RTz& aRTz) + { + test.Next(_L("@SYMTestCaseID PIM-APPSERV-TZS-CO-0004 Read time zone IDs")); + ReadIdsAndTestL(aRTz, EFalse); + } + + +/** +Check time zone identifier is a user-defined time zone identifier. + +@SYMTestCaseID PIM-APPSERV-TZS-CO-0005 + +@SYMTestCaseDesc + The purpose of this test is to verify that a time zone identifier is or is + not a user-defined time zone identifier. + +@SYMTestActions + 1. Get all existing user-defined time zones. + 2. Obtain a time zone identifier for a non-user-defined time zone + +@SYMTestExpectedResults + - Check that the time zone identifier is a user-defined time zone + identifier. + - Check that the time zone identifier is not a user-defined time zone + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ + + +void CTzUserDataTest::TestIdsL(RTz& aRTz) + { + test.Next(_L("@SYMTestCaseID PIM-APPSERV-TZS-CO-0005 Check time zone IDs")); + ReadIdsAndTestL(aRTz, ETrue); + } + + +void CTzUserDataTest::TestShortTzId(RTz& aRTz) + { + test.Next(_L("test short TzId behaviour")); + TInt KGreaterThanExpectedVal = 65536; //a value greater than 0xffff i.e. 16 bits + TUint8 groupId = 8; //make up some random value + TUint resourceId = 123; //make up some random value + TRAPD(err, aRTz.LocalizationWriteCityL(_L("myCity"), KGreaterThanExpectedVal, groupId, resourceId)); + test(err == KErrArgument); + TRAPD(err1, aRTz.LocalizationDeleteCityL(_L("myCity"), KGreaterThanExpectedVal)); + test(err1 == KErrArgument); + + TRAPD(err2, aRTz.LocalizationDeleteCityL(_L("myCity"), KGreaterThanExpectedVal - 1)); + test(err2 == KErrNotFound); + + TRAPD(err3, CTzLocalizedTimeZoneRecord::NewLC(KGreaterThanExpectedVal, _L("standardName"), _L("daylightName"), _L("shortStandardName"), _L("shortDaylighName"), 0)); + test(err3 == KErrArgument); + + TRAPD(err4, CTzLocalizedCityRecord::NewLC(_L("aCity"), 0, 0, KGreaterThanExpectedVal, 0)); + test(err4 == KErrArgument); + } + + + +void CTzUserDataTest::ReadIdsAndTestL(RTz& aRTz, TBool aCheckId) + { + test.Next(_L("Read time zone IDs")); + RPointerArray ids; + CleanupStack::PushL(TCleanupItem(ResetAndDestroyTzIdArray, &ids)); + iUserData->GetTzIdsL(ids); + test(iTzIds.Count() == ids.Count()); + if(aCheckId) + { + TInt count = ids.Count(); + for(TInt ii = 0; iiIsUserTzId()); + } + //Current time zone is default time zone Europe/London which is not the user-defined time zone. + CTzId* currentId = aRTz.GetTimeZoneIdL(); + test (!currentId->IsUserTzId()); + delete currentId; + } + + CleanupStack::PopAndDestroy(&ids); + } + + +void CTzUserDataTest::TestBasicUserDataL() + { + ResetTzUserDataL(); + RTz tz; + User::LeaveIfError(tz.Connect()); + CleanupClosePushL(tz); + iUserData = CTzUserData::NewL(tz); + TestCreateUserDefinedTzL(); + TestReadIdsL(tz); + TestIdsL(tz); + TestUpdateUserDefinedTzL(); + TestDeleteUserDefinedTzL(); + TestShortTzId(tz); + delete iUserData; + iUserData = NULL; + CleanupStack::PopAndDestroy(&tz); + } + + +/** +Out of memory behaviour. + +@SYMTestCaseID PIM-APPSERV-TZS-CO-0006 + +@SYMTestCaseDesc + The purpose of this test is to verify that user-defined time zone operations + are robust and result in no memory leaks under OOM conditions. + +@SYMTestActions + Create, Read, Update and Delete a user-defined time zone rule under OOM + conditions. + +@SYMTestExpectedResults + Each operation leaves with KErrNoMemory until eventually the operation + completes successfully. Once the operation completes successfully the + client process (for client-side OOM testing) or TZ Server process (for + server-side OOM testing) is terminated and does not report a memory leak. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ +void CTzUserDataTest::TestOutOfMemoryBehaviourL(TOOMTest aOOMTest) + { + ResetTzUserDataL(); + + + test.Start(_L("@SYMTestCaseID PIM-APPSERV-TZS-CO-0006 Test Create User-Defined Time Zone OOM")); + OOMTestL(&CreateOOML,aOOMTest); + + // Ensure that a tz ID is saved in iTzIds which is used to fetch a time zone + // in ReadOOML(). + RTz tz; + User::LeaveIfError(tz.Connect()); + CleanupClosePushL(tz); + iUserData = CTzUserData::NewL(tz); + iUserData->GetTzIdsL(iTzIds); + delete iUserData; + iUserData = NULL; + CleanupStack::PopAndDestroy(&tz); + + test.Next(_L("Test Read User-Defined Time Zone OOM")); + OOMTestL(&ReadOOML,aOOMTest); + + test.Next(_L("Test Get User-Defined Time Zone IDs OOM")); + OOMTestL(&GetIdsOOML,aOOMTest); + + test.Next(_L("Test Update User-Defined Time Zone OOM")); + OOMTestL(&UpdateOOML,aOOMTest); + + test.Next(_L("Test Delete User-Defined Time Zone OOM")); + OOMTestL(&DeleteOOML,aOOMTest); + + test.End(); + + ResetTzUserDataL(); + } + + +/** +Boundary tests. + +@SYMTestCaseID PIM-APPSERV-TZUSERDATA-0013 + +@SYMTestCaseDesc + The purpose of this test is to test behaviour under various boundary + conditions. + +@SYMTestActions + 1. Get TZ Ids of user-defined time zone when the database is empty. + 2. Get the user-defined rule for a valid TZ Id when the database is empty. + 3. Get the user-defined rule names when the database is empty. + 4. Create a user time zone with all named KNullDesC + 5. Get rules, names and try to update and delete using a non-user-defined + TZID. + +@SYMTestExpectedResults + Array obtained in action 1 has 0 count. Leaving code KErrNotFound is + expected in action 2 and 3. A user time zone with all named KNullDesC + should be allowed. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ + +void CTzUserDataTest::BoundaryTestL() + { + test.Next(_L("@SYMTestCaseID PIM-APPSERV-TZUSERDATA-0013 Boundary Test")); + ResetTzUserDataL(); + + RTz tz; + User::LeaveIfError(tz.Connect()); + CleanupClosePushL(tz); + iUserData = CTzUserData::NewL(tz); + + // Empty user time zone database. + iUserData->GetTzIdsL(iTzIds); + test (iTzIds.Count() == 0); + + CTzId * id = CTzId::NewL(KUserTzIdMin); + CleanupStack::PushL(id); + CTzRules* rulesGet = NULL; + TRAPD(err, rulesGet = iUserData->ReadRulesL(*id)); + test (!rulesGet); + test (err==KErrNotFound); + + CTzUserNames* namesGet = NULL; + TRAP(err, namesGet = iUserData->ReadNamesL(*id)); + test (!namesGet); + test (err==KErrNotFound); + iUserData->DeleteL(*id); + CleanupStack::PopAndDestroy(id); + + // Create a user time zone with all named KNullDesC. + CTzRules* rules = CreateUserDefinedTzLC(0, 0); + CTzUserNames* names = CTzUserNames::NewLC(KNullDesC , KNullDesC, KNullDesC, KNullDesC, KNullDesC, KNullDesC); + id = iUserData->CreateL(*rules, *names); + CleanupStack::PushL(id); + CheckTimeZoneL(*id, *rules, *names); + + // Create a non-user-defined TZID object and reuse it in the following + // tests. + CTzId* nonUserDefinedTzId = CTzId::NewL(KUserTzIdMin - 1); + CleanupStack::PushL(nonUserDefinedTzId); + + // Attempt to update user-defined TZ data using a TZID which is not a user- + // defined TZID. + TRAP(err, iUserData->UpdateL(*nonUserDefinedTzId, *rules, *names)); + test(err == KErrArgument); + + // Attempt to read rules from user-defined TZ data using a TZID which is + // not a user-defined TZID. + TRAP(err, rulesGet = iUserData->ReadRulesL(*nonUserDefinedTzId)); + test(err == KErrArgument); + + // Attempt to read names from user-defined TZ data using a TZID which is + // not a user-defined TZID. + TRAP(err, namesGet = iUserData->ReadNamesL(*nonUserDefinedTzId)); + test(err == KErrArgument); + + // Attempt to delete from user-defined TZ data using a TZID which is not + // a user-defined TZID. + TRAP(err, iUserData->DeleteL(*nonUserDefinedTzId)); + test(err == KErrArgument); + + CleanupStack::PopAndDestroy(4, rules); + + delete iUserData; + CleanupStack::PopAndDestroy(&tz); + ResetTzUserDataL(); + } + + +/** +Convert time using user-defined time zone. + +@SYMTestCaseID PIM-APPSERV-TZS-TZR-0001 + +@SYMTestCaseDesc + The purpose of this test is to verify the behaviour of time conversion using + a user-defined time zone. + +@SYMTestActions + 1. Create a few user-defined time zone with different UTC offsets and store + them in the database. + 2. Get the UTC offset of each time zone created. + 3. Set the current time zone to each user-defined time zone created in + action 1. + 4. Convert the system time from UTC to local. + 5. Verify the UTC offset for each user-defined time zone. + +@SYMTestExpectedResults + The UTC offset for the given time zone created is correct. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ +void CTzUserDataTest::TestTimeConversionL() + { + TestTimeZoneRulesL(ETimeConversion); + } + + +/** +Daylight saving observation using user-defined time zone. + +@SYMTestCaseID PIM-APPSERV-TZS-TZR-0002 + +@SYMTestCaseDesc + The purpose of this test is to verify the behaviour of daylight saving time + zone rules for a user-defined time zone. + +@SYMTestActions + 1. Create a user-defined time zone. + 2. Set the current time zone to the user-defined time zone created in + action 1. + 3. Check if the daylight saving is on to a time that is inside the time + interval during which DST is observed. [1] + 4. Check if the daylight saving is on to a time that is outside the time + interval during which DST is not observed. [2] + +@SYMTestExpectedResults + [1] The system indicates that DST is currently being observed. + [2] The system indicates that DST is not currently being observed. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ +void CTzUserDataTest::TestDaylightSaveL() + { + TestTimeZoneRulesL(EDayLightSave); + } + + +/** +Check that CTzUserData can work with creating a CTzUserData with KUserTzIdMin +id and with a KNullDesC8 name as expected. +*/ +void CTzUserDataTest::NullTestL() + { + CTzId* minId = CTzId::NewL(KUserTzIdMin); + test (minId->IsUserTzId()); + delete minId; + + CTzId* nullId = CTzId::NewL(KNullDesC8()); + test (nullId->IsUserTzId() == EFalse); + delete nullId; + } + +void CTzUserDataTest::TestTimeZoneRulesL(TTest aWhatToTest) + { + ResetTzUserDataL(); + + test.Next(_L("Time Zone Rules")); + RTz tz; + User::LeaveIfError(tz.Connect()); + CleanupClosePushL(tz); + tz.SetAutoUpdateBehaviorL(RTz::ETZAutoDSTUpdateOn); + iUserData = CTzUserData::NewL(tz); + + test.Next(_L("Create user-defined Time Zone")); + + // Offset 60 There is no DST + test.Printf(_L("Offset 60 There is no DST\n")); + CreateTzAndCheckL(60, 60, tz, aWhatToTest); + + // Offset - 60 There is no DST + test.Printf(_L("Offset -60 There is no DST\n")); + CreateTzAndCheckL(-60, -60, tz, aWhatToTest); + + // Offset 60 There is DST of 60 + CreateTzAndCheckL(60, 120, tz, aWhatToTest); + + // Offset - 60 There is DST of 60 + test.Printf(_L("Offset - 60 There is DST of 60\n")); + CreateTzAndCheckL(-60, 0, tz, aWhatToTest); + + // Create user time zone based on London TZ rules + test.Printf(_L("Create User Tz Based On London Rule\n")); + CreateUserTzBasedOnLondonRuleL(tz, aWhatToTest); + + // Create user time zone based on Shanghai TZ rules + test.Printf(_L("Create User Tz Based On Shanghai Rule\n")); + CreateUserTzBasedOnShanghaiRuleL(tz, aWhatToTest); + + delete iUserData; + iUserData= NULL; + CleanupStack::PopAndDestroy(&tz); + ResetTzUserDataL(); + } + + +void CTzUserDataTest::UpdateCurrentTzL(RTz& aTz,TInt aOldOffSet, TInt aNewOffSet ) + { + CTzRules* newrules = CreateUserDefinedTzLC(aOldOffSet, aNewOffSet); + CTzUserNames* newnames = CreateUserDefinedTzNamesLC(); + CTzId* currentTzid = aTz.GetTimeZoneIdL(); + CleanupStack::PushL(currentTzid); + iUserData->UpdateL(*currentTzid,*newrules, *newnames); + CleanupStack::PopAndDestroy(currentTzid); + CTzRules* currentRules = aTz.GetTimeZoneRulesL(0, 9999,ETzUtcTimeReference ); + CleanupStack::PushL(currentRules); + test(newrules->IsEqualTo(*currentRules)); + CleanupStack::PopAndDestroy(3, newrules); + } + + +void CTzUserDataTest::DeleteCurrentTzL(RTz& aTz) + { + CTzId* currentTzid = aTz.GetTimeZoneIdL(); + CleanupStack::PushL(currentTzid); + iUserData->DeleteL(*currentTzid); + CleanupStack::PopAndDestroy(currentTzid); + CTzId* tzGot = aTz.GetTimeZoneIdL(); + test(KTzLondon()==tzGot->TimeZoneNameID()); + delete tzGot; + } + + +/** +User-defined time zone is current time zone. + +@SYMTestCaseID PIM-APPSERV-TZS-RC-0001 + +@SYMTestCaseDesc + The purpose of this test is to verify that the current time zone can be set + to a user-defined time zone. + +@SYMTestActions + 1. Create a user-defined time zone and store the returned time zone + identifier. + 2. Set the current time zone using the time zone identifier stored in + action 1. + 3. Get the time zone identifier for the current time zone. + +@SYMTestExpectedResults + The time zone identifier obtained in action 1 is the same as the time zone + identifier obtained in action 3. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ + + +void CTzUserDataTest::CreateUserTzAndSetCurrentTimeToL(RTz& aTz, TInt aStandardOffSet, TInt aDSTOffset) + { + test.Next(_L("@SYMTestCaseID PIM-APPSERV-TZS-RC-0001 Test user-defined time zone is current time zone")); + CTzId* usertzid = CreateUserDefinedTzL(aStandardOffSet, aDSTOffset, ETrue); + CleanupStack::PushL(usertzid); + aTz.SetTimeZoneL(*usertzid); + CTzId* tzGot = aTz.GetTimeZoneIdL(); + test (*tzGot == *usertzid); + delete tzGot; + CleanupStack::PopAndDestroy(usertzid); + } + + +/** +Update user-defined time zone whose rules are being cached by TZ Server in the +current time zone rules cache. + +@SYMTestCaseID PIM-APPSERV-TZS-RC-0002 + +@SYMTestCaseDesc + The purpose of this test is to verify that expected behaviour when a time + zone rule for a user-defined time zone, which is also the current time zone, + is updated. + +@SYMTestActions + 1. Create a user-defined time zone. + 2. Set the current time zone to the user-defined time zone created in + action 1. + 3. Update the first time zone rule for the user-defined zone created in + action 1. + 4. Get the first time zone rule for the current time zone. + +@SYMTestExpectedResults + The rule used to update the user-defined time zone in action 2 is the same + as the rule obtained in action 4, implying that the current time zone rules + cache in the TZ Server has been updated. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ + + +void CTzUserDataTest::UpdateCurrentUserTzL(RTz& aTz) + { + test.Next(_L("@SYMTestCaseID PIM-APPSERV-TZS-RC-0002 Update Current TZ rules - Server Response to Changes")); + TInt standardOffset = 60; + TInt dstOffset = 60; + CreateUserTzAndSetCurrentTimeToL(aTz,standardOffset,dstOffset); + standardOffset = 120; + dstOffset = 120; + UpdateCurrentTzL(aTz,standardOffset, dstOffset); + } + + +/** +Delete user-defined time zone whose rules are being cached by TZ Server in the +current time zone rules cache. + +@SYMTestCaseID PIM-APPSERV-TZS-RC-0003 + +@SYMTestCaseDesc + The purpose of this test is to verify the expected behaviour when a user- + defined time zone, which is also the current time zone, is deleted. + +@SYMTestActions + 1. Set the current time zone to the default time zone for the system TZ + database. + 2. Get the time zone identifier for the current time zone. + 3. Create a user-defined time zone. + 4. Set the current time zone to the user-defined time zone created in + action 3. + 5. Delete the user-defined time zone created in action 3. + 6. Get the time zone identifier for the current time zone. + +@SYMTestExpectedResults + The time zone identifier obtained in action 2 is the same as the time zone + identifier obtained in action 6, implying that the current time zone has + reverted to the default time zone for the system TZ database. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ +void CTzUserDataTest::TestDeleteCurrentTimeZoneL(RTz& aTz) + { + DeleteCurrentUserTzL(aTz, EDeleteCurrentUserRule); + } + + +void CTzUserDataTest::DeleteCurrentUserTzL(RTz& aTz, TTest aWhatToTest) + { + test.Next(_L("Delete Current TZ rules - Server Response to Changes")); + + // Set system to default time zone + ResetTimeZoneToLondonL(); + CTzId* defaulteTzid = aTz.GetTimeZoneIdL(); + test(KTzLondon()==defaulteTzid->TimeZoneNameID()); + delete defaulteTzid; + + // Set system to a newly created user time zone + const TInt KStandardOffset = 60; + const TInt KDSTOffset = 120; + CreateUserTzAndSetCurrentTimeToL(aTz,KStandardOffset,KDSTOffset); + + //Delete the user time zone + DeleteCurrentTzL(aTz); + + if(aWhatToTest == EPersistence) + { + aTz.Close(); + User::After(1000000); + User::LeaveIfError(aTz.Connect()); + } + CTzId* tzGot = aTz.GetTimeZoneIdL(); + test(KTzLondon()==tzGot->TimeZoneNameID()); + delete tzGot; + } + + +/** +Current time zone persistence. + +@SYMTestCaseID PIM-APPSERV-TZS-RC-0006 + +@SYMTestCaseDesc + The purpose of this test is to ensure the home time zone identifier in the + Central Repository is not defined when it is deleted. + +@SYMTestActions + 1. Set the current time zone to the default time zone for the system TZ + database. + 2. Get the time zone identifier for the current time zone. + 3. Create a user-defined time zone. + 4. Set the current time zone to the user-defined time zone created in + action 3. + 5. Delete the user-defined time zone created in action 3. + 6. Get the time zone identifier for the current time zone. + 7. Close session with TZ Server so that TZ Server process is terminated. + 8. Get the time zone identifier for the current time zone. + 9. The expected result is same as 8. + +@SYMTestExpectedResults + The time zone identifier obtained in action 2 is the same as the time zone + identifier obtained in action 8, implying that the current time zone has + been established by the TZ Server when the server is started using the + current time zone value persisted to the Central Repository. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ +void CTzUserDataTest::TestCurrentTimeZonePersistenceL(RTz& aTz) + { + DeleteCurrentUserTzL(aTz, EPersistence); + } + + +/** +Update user-defined time zone whose rules are being cached by TZ Server in the +foreign time zone rules cache. + +@SYMTestCaseID PIM-APPSERV-TZS-RC-0004 + +@SYMTestCaseDesc + The purpose of this test is to verify that time conversion to/from a foreign + (i.e. not current) time zone behaves correctly when the time zone rules + cached by the TZ Server for the foreign time zone are time zone rules from a + user-defined time zone that is subsequently updated. + +@SYMTestActions + 1. Create a user-defined time zone. + 2. Convert a given time from UTC to local time using the user-defined time + zone. + 3. Update the user-defined time zone created in action 1. + 4. Convert a given time from UTC to local time using an existing time zone. + +@SYMTestExpectedResults + The local time is correctly converted, implying that the foreign time zone + rules cache in the TZ Server is invalidated and recreated. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ +void CTzUserDataTest::TestUpdateCachedUserTimeZoneL(RTz& aRTz) + { + CachedUserTimeZoneL(aRTz, EUpdateCachedTz); + } + + +/** +Delete user-defined time zone whose rules are being cached by TZ Server in the +foreign time zone rules cache. + +@SYMTestCaseID PIM-APPSERV-TZS-RC-0005 + +@SYMTestCaseDesc + The purpose of this test is to verify that time conversion to/from a foreign + (i.e. not current) time zone behaves correctly when the time zone rules + cached by the TZ Server for the foreign time zone are time zone rules from a + user-defined time zone that is subsequently deleted. + +@SYMTestActions + 1. Create a user-defined time zone. + 2. Convert a given time from UTC to local time using the user-defined time + zone. + 3. Delete the user-defined time zone created in action 1. + 4. Convert a given time from UTC to local time using an existing time zone. + +@SYMTestExpectedResults + The local time is correctly converted, implying that the foreign time zone + rules cache in the TZ Server is invalidated and recreated. + +@SYMTestType + CT + +@SYMTestPriority + 1 +*/ +void CTzUserDataTest::TestDeletedCachedUserTimeZoneL(RTz& aRTz) + { + CachedUserTimeZoneL(aRTz, EDeleteCachedTz); + } + + +void CTzUserDataTest::CachedUserTimeZoneL(RTz& aRTz, TTest aWhatToTest) + { + test.Next(_L("Conver times - Server Response to Changes")); + TInt offset = 60; + TTime utctime (TDateTime(2000, EMay, 0, 0, 0, 0, 0)); + + //Convert a given time from UTC to local time using the user-defined time zone + TTime localtime = utctime ; + CreateUserTzAndSetCurrentTimeToL(aRTz, offset, offset); + aRTz.ConvertToLocalTime(localtime); + TTimeIntervalMinutes minutes; + localtime.MinutesFrom(utctime, minutes); + test (minutes == TTimeIntervalMinutes(offset)); + + localtime = utctime; + + //Convert a given time from UTC to local time when the corrent tz rule is updated + if(aWhatToTest==EUpdateCachedTz) + { + offset = 120; + UpdateCurrentTzL(aRTz, offset, offset); + } + else if(aWhatToTest==EDeleteCachedTz) + { + //Delete the current tz rule which result in system time reverting to the default time zone. + DeleteCurrentTzL(aRTz); + //Convert a given time from UTC to local time using an existing time zone which is the defaut time zone. + CTzRules* currentRules = aRTz.GetTimeZoneRulesL(0, 9999,ETzUtcTimeReference ); + CleanupStack::PushL(currentRules); + offset = currentRules->GetOffsetL(utctime, ETzUtcTimeReference); + CleanupStack::PopAndDestroy(currentRules); + } + + aRTz.ConvertToLocalTime(localtime); + localtime.MinutesFrom(utctime, minutes); + test (minutes == TTimeIntervalMinutes(offset)); + } + + +/** +The purpose of the following test cases is to verify the behaviour of the TZ +Server component’s response to changes in user-defined time zones, specifically +the rules associated with user-defined time zones. + +The TZ Server maintains a cache of certain time zone rules data and persists the +time zone identifier for the current time zone. + +If either this cache or the persisted setting relates to user-defined time zones +and those time zones are modified then the TZ Server must respond to the change +appropriately. +*/ + +// @SYMTestCaseID PIM-APPSERV-TZS-RC-0003-TO-0006 + +void CTzUserDataTest::TestServerResponseToChangesL() + { + ResetTzUserDataL(); + + test.Next(_L("@SYMTestCaseID PIM-APPSERV-TZS-RC-0003-TO-0006 Server Response To Changes")); + + RTz tz; + User::LeaveIfError(tz.Connect()); + CleanupClosePushL(tz); + + iUserData = CTzUserData::NewL(tz); + + const TInt KStandardOffset = 60; + const TInt KDSTOffset = 60; + CreateUserTzAndSetCurrentTimeToL(tz,KStandardOffset,KDSTOffset); + + UpdateCurrentUserTzL(tz); + + TestUpdateCachedUserTimeZoneL(tz); + TestDeletedCachedUserTimeZoneL(tz); + TestDeleteCurrentTimeZoneL(tz); + TestCurrentTimeZonePersistenceL(tz); + + delete iUserData; + iUserData= NULL; + + CleanupStack::PopAndDestroy(&tz); + } + + +/** +The purpose of the follwing test case is to verify the behaviour of +reuse of Tz Ids in case all the 4095 ids have been used. +*/ +void CTzUserDataTest::TestTzIdReusabilityL() + { + ResetTzUserDataL(); + RTz tz; + CleanupClosePushL(tz); + User::LeaveIfError(tz.Connect()); + iUserData = CTzUserData::NewL(tz); + const TInt maxTzIds = 4095; + for(TInt i=0; i<= maxTzIds; i++) + { + CTzId* tzid = NULL; + TRAPD(err, tzid = CreateUserDefinedTzL(0,0, EFalse)); + if(i%KPrintFreq == 0 || i == maxTzIds) + { + test.Printf(_L("Added %d rules to the database\n"), i); + } + + if(err != KErrNone) + { + test.Printf(_L("Error while creating rules. Error is %d\n"), err); + } + delete tzid; + } + const TUint KFirstReusedTzId = 16400; + CTzId* tzId = CTzId::NewL(KFirstReusedTzId); + CleanupStack::PushL(tzId); + iUserData->DeleteL(*tzId); + CleanupStack::PopAndDestroy(tzId); + + const TUint KSecondReusedTzId = 16500; + CTzId* tzId1 = CTzId::NewL(KSecondReusedTzId); + CleanupStack::PushL(tzId1); + iUserData->DeleteL(*tzId1); + CleanupStack::PopAndDestroy(tzId1); + + CTzId* reusedId = CreateUserDefinedTzL(0, 0, EFalse); + test(reusedId->TimeZoneNumericID() == KFirstReusedTzId); + test.Printf(_L("The first re-used id is %d\n"), reusedId->TimeZoneNumericID()); + delete reusedId; + + CTzId* secondReusedId = CreateUserDefinedTzL(0, 0, EFalse); + test(secondReusedId->TimeZoneNumericID() == KSecondReusedTzId); + test.Printf(_L("The second re-used id is %d\n"), secondReusedId->TimeZoneNumericID()); + delete secondReusedId; + + TRAPD(err, CreateUserDefinedTzL(0, 0, EFalse)); + test(err == KErrOverflow); + + delete iUserData; + iUserData = NULL; + CleanupStack::PopAndDestroy(&tz); + } + +static void DoTestsL() + { + User::LeaveIfError(Serv.Connect()); + + test.Title(); + + ResetTimeZoneToLondonL(); + + CTzUserDataTest* userDataTest = CTzUserDataTest::NewLC(); + + test.Start(_L("Test Basic User Data")); + userDataTest->TestBasicUserDataL(); + + test.Next(_L("Test Out Of Memory Behaviour (Client)")); + userDataTest->TestOutOfMemoryBehaviourL(CTzUserDataTest::EClientOOM); + + test.Next(_L("Test Out Of Memory Behaviour (Server)")); + userDataTest->TestOutOfMemoryBehaviourL(CTzUserDataTest::EServerOOM ); + + test.Next(_L("@SYMTestCaseID PIM-APPSERV-TZS-TZR-0001 Test Time Conversion")); + userDataTest->TestTimeConversionL(); + + test.Next(_L("@SYMTestCaseID PIM-APPSERV-TZS-TZR-0002 Test Daylight Save")); + userDataTest->TestDaylightSaveL(); + + test.Next(_L("Test Boundary Test")); + userDataTest->BoundaryTestL(); + + test.Next(_L("Test Server Response To Changes")); + userDataTest->TestServerResponseToChangesL(); + + // Delete the user-defined TZ database before the next test case. + Serv.CloseTzSession(); + Serv.DeleteFileL(KTzUserDataDb); + + test.Next(_L("Test Reusability Of TZ IDs")); + userDataTest->TestTzIdReusabilityL(); + + // Delete the user defined TZ database. + Serv.CloseTzSession(); + Serv.DeleteFileL(KTzUserDataDb); + + test.Next(_L("Null Test")); + userDataTest->NullTestL(); + + ResetTimeZoneToLondonL(); + + CleanupStack::PopAndDestroy(userDataTest); + + test.End(); + + Serv.Close(); + } + + +TInt E32Main() + { + __UHEAP_MARK; + + CTrapCleanup* trapCleanup = CTrapCleanup::New(); + if(!trapCleanup) + { + return KErrNoMemory; + } + + CActiveScheduler* scheduler = new CActiveScheduler; + if(!scheduler) + { + return KErrNoMemory; + } + CActiveScheduler::Install(scheduler); + + TRAPD(ret, DoTestsL()); + test.Printf(_L("Trapped return value from DoTestsL(): %d\n"), ret); + test(ret == KErrNone); + + test.Close(); + + delete scheduler; + delete trapCleanup; + + __UHEAP_MARKEND; + + return (KErrNone); + }