// 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 <connect/sbeclient.h>
#include <e32test.h>
#include "tzuserdata.h"
#include <tzlocalizer.h>
#include "testserver.h"
#include <tzlocalizedcityrecord.h>
#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
#include <tzusernames.h>
#include <tzuserdefineddata.h>
#endif
#include "tzidinternal.h"
_LIT(KBackupTest, "Tz Backup");
RTest test(KBackupTest);
// Literal constants
_LIT(KTzTestBackupFile, "C:\\Backup__tzuserdata.db");
_LIT(KTzBackupFileFullPath, "C:\\private\\1020383e\\SQLite__tzuserdata.db");
_LIT(KTzTestBackupLocDb, "C:\\Backup__TzLocalization.db");
_LIT(KTzBackupLocDbFullPath, "C:\\private\\100012a5\\DBS_10206A8B_TzLocalization.db");
_LIT(KTimeZoneBackupRegistrationFullPath, "Z:\\private\\1020383E\\backup_registration.xml");
_LIT(KPerFile1,"c:\\private\\100012a5\\DBS_2000836D_DBS_DSC.db");
_LIT(KPerFile2,"c:\\private\\100012a5\\DBS_10206A8B_TzLocalization.db");
_LIT(KStandardName1, "UserTzName1");
_LIT(KShortStandardName1, "UserTzSh1");
_LIT(KDaylightSaveName1, "UserDLSaveName1");
_LIT(KShortDaylightSaveName1, "UserShDLS1");
_LIT(KCityNameName1, "UserCityName1");
_LIT(KRegionName1, "UserRegionName1");
_LIT(KStandardName2, "UserTzName2");
_LIT(KShortStandardName2, "UserTzSh2");
_LIT(KDaylightSaveName2, "UserDLSaveName2");
_LIT(KShortDaylightSaveName2, "UserShDLS2");
_LIT(KCityNameName2, "UserCityName2");
_LIT(KRegionName2, "UserRegionName2");
_LIT(KUserAddedCityName1, "UserAddedCity1");
_LIT(KUserAddedCityName2, "UserAddedCity2");
const TInt KLondonTzId = 2592;
const TInt KParisTzId = 2656;
static conn::CSBEClient* BackupClient;
static TDriveList DriveList;
class CTestUserDefinedBackupRestore : public CBase
{
public:
static CTestUserDefinedBackupRestore* NewL();
~CTestUserDefinedBackupRestore();
enum TTest
{
EBackupTest,
ERestoreTest
};
void RunTestsL();
void TestBackupAndRestoreUserDbL(TTest aTest);
void TestFrequentlyUsedZonesUpdateAfterRestoreDeleteL();
void TestFrequentlyUsedZonesUpdateAfterRestoreUpdateL();
void TestUserCitiesUpdateAfterRestoreL();
void TestFrequentlyUsedCurrentZonesUpdateAfterRestoreUpdateL();
void TestSystemRulesUpdateAfterRestoreL();
void TestBackupAndRestoreLocDbL();
private:
CTestUserDefinedBackupRestore();
TBool CheckXMLRegistrationFileL();
TBool SimulateTzBackup(const TDesC& aSrcfile, const TDesC& aDestfile);
TBool SimulateTzRestore(const TDesC& aSrcfile, const TDesC& aDestfile);
void ConstructL();
void ResetTzUserDataL();
TBool TestSystemRulesUpdateAfterRestoreL(TUint aExpectedTzId, TBool aRestoreEmptyFile);
TBool LocDbWriteFunctionL(CTzLocalizer& aTzLocalizer, TInt aExpectedErr);
TBool CompareFrequentlyUsedCity(const CTzLocalizedCity& aCity, const CTzLocalizedCity& aCityToCompare);
TBool CompareFrequentlyUsedZone(const CTzLocalizedTimeZone& aZone, const CTzLocalizedTimeZone& aZoneToCompare);
TBool CompareFrequentlyUsedCityAfterUpdate(TInt aId, const CTzLocalizedCity& aCity);
TBool CompareFrequentlyUsedCityRestoredAfterUpdate(TInt aId, const CTzLocalizedCity& aCity);
TBool CompareFrequentlyUsedZoneAfterUpdate(TInt aId, const CTzLocalizedTimeZone& aZone);
//Member
public:
CTzUserData* iUserData;
RFs iFs;
RPIMTestServer iServ;
RTz iTz;
};
// building block test backup and restore functions
static void StartBackupL()
{
/* Use the Secure Backup Engine API to "start" a backup. The backup
happens indirectly through CTzUserDataDb::BackupBeginningL()/
BackupCompletedL()/RestoreBeginningL()/RestoreCompletedL() methods.
These methods are implementations for MBackupRestoreNotificatioObserver
which monitors changes in the P&S property conn::KUidBackupRestoreKey.
This P&S property is changed by calling the Secure Backup Engine API
below.
*/
test.Printf(_L("Starting Backup\n"));
BackupClient->SetBURModeL(DriveList, conn::EBURBackupFull, conn::EBackupBase);
User::After(3000000);// Wait a bit to allow the server to close the database
}
static void EndBackupL()
{
/* Use the Secure Backup Engine API to "end" a backup. The backup ends
indirectly through CTzUserDataDb::BackupBeginningL()/
BackupCompletedL()/RestoreBeginningL()/RestoreCompletedL() methods.
These methods are implementations for MBackupRestoreNotificatioObserver
which monitors changes in the P&S property conn::KUidBackupRestoreKey.
This P&S property is changed by calling the Secure Backup Engine API
below.
*/
test.Printf(_L("Finishing Backup\n"));
BackupClient->SetBURModeL(DriveList, conn::EBURNormal, conn::ENoBackup);
User::After(3000000);// Wait a bit to allow the server to open the database
}
static void StartRestoreL()
{
/* Use the Secure Backup Engine API to "start" a restore.
This happens indirectly through CTzUserDataDb::BackupBeginningL()/
BackupCompletedL()/RestoreBeginningL()/RestoreCompletedL() methods.
These methods are implementations for MBackupRestoreNotificatioObserver
which monitors changes in the P&S property conn::KUidBackupRestoreKey.
This P&S property is changed by calling the Secure Backup Engine API
below.
*/
test.Printf(_L("Starting restore\n"));
BackupClient->SetBURModeL(DriveList, conn::EBURRestoreFull, conn::EBackupBase);
User::After(3000000);// Wait a bit to allow the server to close the database
}
static void EndRestoreL()
{
/* Use the Secure Backup Engine API to "end" a restore.
This happens indirectly through CTzUserDataDb::BackupBeginningL()/
BackupCompletedL()/RestoreBeginningL()/RestoreCompletedL() methods.
These methods are implementations for MBackupRestoreNotificatioObserver
which monitors changes in the P&S property conn::KUidBackupRestoreKey.
This P&S property is changed by calling the Secure Backup Engine API
below.
*/
test.Printf(_L("Finishing restore\n"));
BackupClient->SetBURModeL(DriveList, conn::EBURNormal, conn::ENoBackup);
User::After(3000000);// Wait a bit to allow the server to open and update the database
}
LOCAL_D void ResetAndDestroyTzIdArray(TAny* aPtr)
{
RPointerArray<CTzId>* ids = static_cast<RPointerArray<CTzId>*>(aPtr);
if (ids)
{
ids->ResetAndDestroy();
}
}
LOCAL_D void CleanupCityPointerArray(TAny* aPtr)
{
RPointerArray<CTzLocalizedCityRecord>* ids = static_cast<RPointerArray<CTzLocalizedCityRecord>*>(aPtr);
if (ids)
{
ids->ResetAndDestroy();
}
}
/** Access to user defined time zone data during backup or restore operation
@SYMTestCaseID PIM-TTZBACKUP-TZS-BR-0001
@SYMTestCaseDesc The purpose of this test is to verify the behaviour of the
client APIs that access user defined time zones during a backup or restore operation.
@SYMTestActions
1. Create a user defined time zone.
2. Simulate start of backup or restore operation.
3. Access (read, update, delete) the user defined time zone created in action 1. 1
4. Create a user defined time zone. 2
5. Simulate end of backup or restore operation.
6. Access (read, update, delete) the user defined time zone created in action 1. 3
7. Create a user defined time zone. 4
@SYMTestExpectedResults In step 3 and 4, operation leaves with KErrLocked
In step 6 and 7, operation completes without error
@SYMTestType CT
@SYMTestPriority 1
*/
CTestUserDefinedBackupRestore::CTestUserDefinedBackupRestore()
{
}
CTestUserDefinedBackupRestore* CTestUserDefinedBackupRestore::NewL()
{
CTestUserDefinedBackupRestore* self = new(ELeave) CTestUserDefinedBackupRestore();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
void CTestUserDefinedBackupRestore::ConstructL()
{
User::LeaveIfError(iFs.Connect());
User::LeaveIfError(iServ.Connect());
iServ.CloseTzSession();
}
CTestUserDefinedBackupRestore::~CTestUserDefinedBackupRestore()
{
delete iUserData;
iFs.Delete(KTzTestBackupFile);
// delete database file
iFs.Delete(KTzBackupFileFullPath);
iFs.Close();
iServ.Close();
}
void CTestUserDefinedBackupRestore::ResetTzUserDataL()
{
RPointerArray<CTzId> ids;
CleanupStack::PushL(TCleanupItem(ResetAndDestroyTzIdArray, &ids));
iUserData->GetTzIdsL(ids);
TInt count = ids.Count();
for (TInt ii=0; ii<count; ++ii)
{
iUserData->DeleteL(*ids[ii]);
}
CleanupStack::PopAndDestroy(&ids);
}
TBool CTestUserDefinedBackupRestore::CheckXMLRegistrationFileL()
{
TEntry entry;
TInt error = iFs.Entry(KTimeZoneBackupRegistrationFullPath, entry);
if (error == KErrNotFound)
{
return EFalse;
}
User::LeaveIfError(error);
if(entry.iSize == 0)
{
// file is present but is empty
User::Leave(KErrCorrupt);
}
// found the registration file
return ETrue;
}
TBool CTestUserDefinedBackupRestore::SimulateTzBackup(const TDesC& aSrcfile, const TDesC& aDestfile)
{
TRAPD(error, iServ.CopyFileL(aSrcfile, aDestfile));
if (error != KErrNone)
{
test.Printf(_L("Copy failed with error %i"), error);
return EFalse;
}
return ETrue;
}
TBool CTestUserDefinedBackupRestore::SimulateTzRestore(const TDesC& aSrcfile, const TDesC& aDestfile)
{
// Backup tz user-defined database file.
TRAPD(error, iServ.CopyFileL(aSrcfile ,aDestfile));
if (error != KErrNone)
{
test.Printf(_L("Copy failed with error %i"), error);
return EFalse;
}
return ETrue;
}
TBool CTestUserDefinedBackupRestore::CompareFrequentlyUsedCity(const CTzLocalizedCity& aCity, const CTzLocalizedCity& aCityToCompare)
{
if(aCity.TimeZoneId() != aCityToCompare.TimeZoneId())
{
return EFalse;
}
if(aCity.GroupId() != aCityToCompare.GroupId())
{
return EFalse;
}
if(aCity.Name() != aCityToCompare.Name())
{
return EFalse;
}
return ETrue;
}
TBool CTestUserDefinedBackupRestore::CompareFrequentlyUsedZone(const CTzLocalizedTimeZone& aZone, const CTzLocalizedTimeZone& aZoneToCompare)
{
if(aZone.TimeZoneId() != aZoneToCompare.TimeZoneId())
{
return EFalse;
}
if(aZone.StandardName() != aZoneToCompare.StandardName())
{
return EFalse;
}
if(aZone.ShortStandardName() != aZoneToCompare.ShortStandardName())
{
return EFalse;
}
if(aZone.DaylightName() != aZoneToCompare.DaylightName())
{
return EFalse;
}
if(aZone.ShortDaylightName() != aZoneToCompare.ShortDaylightName())
{
return EFalse;
}
return ETrue;
}
TBool CTestUserDefinedBackupRestore::CompareFrequentlyUsedCityAfterUpdate(TInt aId, const CTzLocalizedCity& aCity)
{
if(aCity.TimeZoneId() != aId)
{
return EFalse;
}
if(aCity.GroupId() != 0)
{
return EFalse;
}
if(aCity.Name() != KCityNameName2)
{
return EFalse;
}
return ETrue;
}
TBool CTestUserDefinedBackupRestore::CompareFrequentlyUsedCityRestoredAfterUpdate(TInt aId, const CTzLocalizedCity& aCity)
{
if(aCity.TimeZoneId() != aId)
{
return EFalse;
}
if(aCity.GroupId() != 0)
{
return EFalse;
}
if(aCity.Name() != KCityNameName1)
{
return EFalse;
}
return ETrue;
}
TBool CTestUserDefinedBackupRestore::CompareFrequentlyUsedZoneAfterUpdate(TInt aId, const CTzLocalizedTimeZone& aZone)
{
if(aZone.TimeZoneId() != aId)
{
return EFalse;
}
if(aZone.StandardName() != KStandardName1)
{
return EFalse;
}
if(aZone.ShortStandardName() != KShortStandardName1)
{
return EFalse;
}
if(aZone.DaylightName() != KDaylightSaveName1)
{
return EFalse;
}
if(aZone.ShortDaylightName() != KShortDaylightSaveName1)
{
return EFalse;
}
return ETrue;
}
void CTestUserDefinedBackupRestore::TestBackupAndRestoreUserDbL(TTest aTest)
{
TTzRule rule1(0, KMaxTUint16, 60, 0, EAugust, ETzFixedDate, 0, 0, ETzWallTimeReference, 120);
TTzRule rule2(0,KMaxTUint16,0,60,EJanuary,ETzFixedDate,0,0,ETzWallTimeReference,120);
CTzRules* rules = CTzRules::NewL(0, KMaxTUint);
CleanupStack::PushL(rules);
rules->AddRuleL(rule1);
rules->AddRuleL(rule2);
TBuf<20> stdName;
stdName.Format(_L("StdName1"));
TBuf<20> shortStdName;
shortStdName.Format(_L("ShortStd1"));
TBuf<20> dstName;
dstName.Format(_L("DstName1"));
TBuf<20> shortDstName;
shortDstName.Format(_L("ShortDst1"));
TBuf<20> cityName;
cityName.Format(_L("CityName1"));
TBuf<20> regionName;
regionName.Format(_L("RegionName1"));
CTzUserNames* names = CTzUserNames::NewLC(stdName, shortStdName, dstName, shortDstName, cityName, regionName);
CTzId* id = NULL;
id = iUserData->CreateL(*rules, *names);
CleanupStack::PopAndDestroy(2, rules);
CleanupStack::PushL(id);
TBool file = CheckXMLRegistrationFileL();
test(file);
if(aTest == EBackupTest)
{
TRAPD(err, StartBackupL());
test(err==KErrNone);
TBool result = SimulateTzBackup(KTzBackupFileFullPath, KTzTestBackupFile);
test(result);
}
else
{
TRAPD(err, StartRestoreL());
test(err == KErrNone);
TBool result = SimulateTzRestore(KTzTestBackupFile, KTzBackupFileFullPath) ;
test(result);
CleanupStack::PopAndDestroy(id);
// Setting back to initial id as the database
// copied during restore will not have all the changes
// that happened afterwards
id = CTzId::NewL(KUserTzIdMin);
CleanupStack::PushL(id);
}
test.Printf(_L("Now try reading the names of the created zone\n"));
CTzUserNames* readNames = NULL;
TRAPD(err, readNames = iUserData->ReadNamesL(*id));
delete readNames;
test(err == KErrLocked);
test.Printf(_L("Could not read names as backup/restore is in progress\n"));
test.Printf(_L("Now try reading the rules of the created zone\n"));
CTzRules* readRules = NULL;
TRAP(err, readRules = iUserData->ReadRulesL(*id));
delete readRules;
test(err == KErrLocked);
test.Printf(_L("Could not read rules as backup/restore is in progress\n"));
test.Printf(_L(" @SYMTestCaseID PIM-TTZBACKUP-TZS-BR-0001 Now try reading the TZIDs of all user-defined time zone data\n"));
RPointerArray<CTzId> tzIds;
TRAP(err, iUserData->GetTzIdsL(tzIds));
tzIds.ResetAndDestroy();
tzIds.Close();
test(err == KErrLocked);
test.Printf(_L("Could not read TZIDs as backup/restore is in progress\n"));
TTzRule rule3(1981,1996,0,60,EMarch,ETzDayInLastWeekOfMonth,0,ESunday,ETzUtcTimeReference,60);
TTzRule rule4(1981,1996,60,0,EOctober,ETzDayInLastWeekOfMonth,0,ESunday,ETzUtcTimeReference,60);
CTzRules* rulesAdd = CTzRules::NewL(0, KMaxTUint);
CleanupStack::PushL(rulesAdd);
rulesAdd->AddRuleL(rule3);
rulesAdd->AddRuleL(rule4);
stdName.Format(_L("StdName2"));
shortStdName.Format(_L("ShortStd2"));
dstName.Format(_L("DstName2"));
shortDstName.Format(_L("ShortDst2"));
cityName.Format(_L("CityName2"));
regionName.Format(_L("RegionName2"));
CTzUserNames* namesAdd = CTzUserNames::NewLC(stdName, shortStdName, dstName, shortDstName, cityName, regionName);
CTzId* tzId = NULL;
TRAP(err, tzId = iUserData->CreateL(*rulesAdd, *namesAdd));
delete tzId;
test(err == KErrLocked);
TRAP(err, iUserData->UpdateL(*id, *rulesAdd, *namesAdd));
test(err == KErrLocked);
test.Printf(_L("Could not update user-defined rules as backup/restore is in progress\n"));
TRAP(err, iUserData->DeleteL((*id)));
test(err == KErrLocked);
test.Printf(_L("Could not delete user-defined rules as backup/restore is in progress\n"));
CleanupStack::PopAndDestroy(namesAdd);
CleanupStack::PopAndDestroy(rulesAdd);
if(aTest == EBackupTest)
{
// backup complete
TRAP(err, EndBackupL());
test(err == KErrNone);
}
else
{
// restore complete
TRAP(err, EndRestoreL());
test(err == KErrNone);
}
test.Printf(_L("Check if we can perform CRUD operations on user-defined rules\n"));
CTzUserNames* readNamesAgain = NULL;
TRAPD(ret, readNamesAgain = iUserData->ReadNamesL(*(id)));
test(ret == KErrNone);
test.Printf(_L("Successfully read user-defined rules after backup/restore has completed\n"));
delete readNamesAgain;
CleanupStack::PopAndDestroy();
CTzRules* newRules = CTzRules::NewL(0, KMaxTUint);
CleanupStack::PushL(newRules);
newRules->AddRuleL(rule3);
newRules->AddRuleL(rule4);
stdName.Format(_L("StdName3"));
shortStdName.Format(_L("ShortStd3"));
dstName.Format(_L("DstName3"));
shortDstName.Format(_L("ShortDst3"));
cityName.Format(_L("CityName3"));
regionName.Format(_L("RegionName3"));
CTzUserNames* newNames = CTzUserNames::NewLC(stdName, shortStdName, dstName, shortDstName, cityName, regionName);
CTzId* newId = NULL;
TRAP(err, newId = iUserData->CreateL(*newRules, *newNames));
test(err == KErrNone);
test.Printf(_L("Successfully created user-defined rules after backup/restore has completed\n"));
TRAP(err, iUserData->UpdateL(*newId, *newRules, *newNames));
test(err == KErrNone);
test.Printf(_L("Successfully updated user-defined rules after backup/restore has completed\n"));
TRAP(err, iUserData->DeleteL(*newId));
test(err == KErrNone);
test.Printf(_L("Successfully deleted user-defined rules after backup/restore has completed\n"));
CleanupStack::PopAndDestroy(newNames);
CleanupStack::PopAndDestroy(newRules);
delete newId;
}
void CTestUserDefinedBackupRestore::TestBackupAndRestoreLocDbL()
{
test.Printf(_L("Start to backup or restore localization DB which should lock the file\n"));
CTzLocalizer* localizer = NULL;
//Make sure the localization DB exists
localizer = CTzLocalizer::NewL();
delete localizer;
localizer = NULL;
//Verify that the client can not create an object of CTzLocalizer when backup or restroe starts
StartBackupL();
test(SimulateTzBackup(KTzBackupLocDbFullPath, KTzTestBackupLocDb));
TRAPD(err, localizer = CTzLocalizer::NewL());
test (err == KErrLocked);
test (!localizer);
EndBackupL();
StartRestoreL();
test(SimulateTzRestore(KTzTestBackupLocDb, KTzBackupLocDbFullPath) );
TRAP(err, localizer = CTzLocalizer::NewL());
test(err == KErrLocked);
test (!localizer);
EndRestoreL();
localizer = CTzLocalizer::NewL();
CleanupStack::PushL(localizer);
//Verify that functions which requires writing to the localization file are locked when backup or restore starts
StartBackupL();
test(SimulateTzBackup(KTzBackupLocDbFullPath, KTzTestBackupLocDb));
test(LocDbWriteFunctionL(*localizer, KErrLocked));
EndBackupL();
test(LocDbWriteFunctionL(*localizer, KErrNone));
StartRestoreL();
test(SimulateTzRestore(KTzTestBackupLocDb, KTzBackupLocDbFullPath) );
test(LocDbWriteFunctionL(*localizer, KErrLocked));
EndRestoreL();
test(LocDbWriteFunctionL(*localizer, KErrNone));
CleanupStack::PopAndDestroy(localizer);
}
TBool CTestUserDefinedBackupRestore::LocDbWriteFunctionL(CTzLocalizer& aTzLocalizer, TInt aExpectedErr)
{
TRAPD(err, aTzLocalizer.SetFrequentlyUsedZoneL(KLondonTzId,CTzLocalizedTimeZone::EHomeZone));
if(aExpectedErr != err)
{
return EFalse;
}
return ETrue;
}
void CTestUserDefinedBackupRestore::TestFrequentlyUsedZonesUpdateAfterRestoreDeleteL()
{
// Backup the file before we added the user defined time zones
test.Printf(_L("Backup the file without any user-defined zones\n"));
_LIT8(KLondon, "Europe/London");
CTzId* tzid = CTzId::NewL(KLondon);
iTz.SetTimeZoneL(*tzid);
delete tzid;
TRAPD(err, StartBackupL());
test(err==KErrNone);
TBool result = SimulateTzBackup(KTzBackupFileFullPath, KTzTestBackupFile);
test(result);
TRAP(err, EndBackupL());
test(err == KErrNone);
// Add a user defined time zone
test.Printf(_L("Add a user-defined zone\n"));
TTzRule rule1(0, KMaxTUint16, 60, 0, EAugust, ETzFixedDate, 0, 0, ETzWallTimeReference, 120);
TTzRule rule2(0,KMaxTUint16,0,60,EJanuary,ETzFixedDate,0,0,ETzWallTimeReference,120);
CTzRules* rules = CTzRules::NewL(0, KMaxTUint);
CleanupStack::PushL(rules);
rules->AddRuleL(rule1);
rules->AddRuleL(rule2);
CTzUserNames* names = CTzUserNames::NewLC(KStandardName1(), KShortStandardName1(), KDaylightSaveName1(),
KShortDaylightSaveName1(), KCityNameName1(), KRegionName1());
CTzId* id = iUserData->CreateL(*rules, *names);
CleanupStack::PopAndDestroy(2, rules);
CleanupStack::PushL(id);
// Add this time zone in the frequently used zone table
CTzLocalizer* localizer = CTzLocalizer::NewL();
test.Printf(_L("Set the user-defined zone as the frequently used zone\n"));
localizer->SetFrequentlyUsedZoneL(id->TimeZoneNumericID(), CTzLocalizedTimeZone::EHomeZone);
CleanupStack::PopAndDestroy(id);
// Restore the file
test.Printf(_L("Restore the backed up file\n"));
TRAP(err, StartRestoreL());
test(err == KErrNone);
result = SimulateTzRestore(KTzTestBackupFile, KTzBackupFileFullPath) ;
test(result);
TRAP(err, EndRestoreL());
test(err == KErrNone);
CTzLocalizedCity* cityToCompareWith = localizer->GetDefaultCityL(KLondonTzId);
CleanupStack::PushL(cityToCompareWith);
test.Printf(_L("Fetch the frequently used city and check if it is the expected one\n"));
CTzLocalizedCity* city = localizer->GetFrequentlyUsedZoneCityL(CTzLocalizedTimeZone::EHomeZone);
test(CompareFrequentlyUsedCity(*city, *cityToCompareWith));
delete city;
CTzLocalizedTimeZone* zoneToCompareWith = localizer->GetLocalizedTimeZoneL(KLondonTzId);
CleanupStack::PushL(zoneToCompareWith);
CTzLocalizedTimeZone* timeZone = localizer->GetFrequentlyUsedZoneL(CTzLocalizedTimeZone::EHomeZone);
test.Printf(_L("Fetch the frequently used zone and check if it is the expected one\n"));
test(CompareFrequentlyUsedZone(*timeZone, *zoneToCompareWith));
delete timeZone;
delete localizer;
CleanupStack::PopAndDestroy(2, cityToCompareWith);
}
void CTestUserDefinedBackupRestore::TestFrequentlyUsedZonesUpdateAfterRestoreUpdateL()
{
// Add a user defined time zone
test.Printf(_L("Create a user-defined zone\n"));
TTzRule rule1(0, KMaxTUint16, 60, 0, EAugust, ETzFixedDate, 0, 0, ETzWallTimeReference, 120);
TTzRule rule2(0,KMaxTUint16,0,60,EJanuary,ETzFixedDate,0,0,ETzWallTimeReference,120);
CTzRules* rules = CTzRules::NewL(0, KMaxTUint);
CleanupStack::PushL(rules);
rules->AddRuleL(rule1);
rules->AddRuleL(rule2);
CTzUserNames* names = CTzUserNames::NewLC(KStandardName1(), KShortStandardName1(), KDaylightSaveName1(),
KShortDaylightSaveName1(), KCityNameName1(), KRegionName1());
CTzId* id = iUserData->CreateL(*rules, *names);
CleanupStack::PopAndDestroy(2, rules);
CleanupStack::PushL(id);
// Backup the file before we added the user defined time zones
test.Printf(_L("Backup the user-defined database\n"));
TRAPD(err, StartBackupL());
test(err==KErrNone);
TBool result = SimulateTzBackup(KTzBackupFileFullPath, KTzTestBackupFile);
test(result);
TRAP(err, EndBackupL());
test(err == KErrNone);
// Update the user defined time zone
test.Printf(_L("Update the user-defined rule\n"));
CTzRules* newRules = CTzRules::NewL(0, KMaxTUint);
CleanupStack::PushL(newRules);
newRules->AddRuleL(rule1);
newRules->AddRuleL(rule2);
//Create a user defined rule names for update
CTzUserNames* newNames = CTzUserNames::NewLC(KStandardName2(), KShortStandardName2(),
KDaylightSaveName2(), KShortDaylightSaveName2(), KCityNameName2(), KRegionName2());
iUserData->UpdateL(*id, *newRules, *newNames);
CleanupStack::PopAndDestroy(2, newRules);
// Add this time zone in the frequently used zone table
CTzLocalizer* localizer = CTzLocalizer::NewL();
test.Printf(_L("Set the new zone as the frequently used zone\n"));
localizer->SetFrequentlyUsedZoneL(id->TimeZoneNumericID(), CTzLocalizedTimeZone::EHomeZone);
test.Printf(_L("Fetch the frequently used city and check if it is the expected one\n"));
CTzLocalizedCity* city = localizer->GetFrequentlyUsedZoneCityL(CTzLocalizedTimeZone::EHomeZone);
test(CompareFrequentlyUsedCityAfterUpdate(id->TimeZoneNumericID(), *city));
delete city;
// Restore the file
test.Printf(_L("Restore the backed up file\n"));
TRAP(err, StartRestoreL());
test(err == KErrNone);
result = SimulateTzRestore(KTzTestBackupFile, KTzBackupFileFullPath) ;
test(result);
TRAP(err, EndRestoreL());
test(err == KErrNone);
test.Printf(_L("Get the frequently used city and check if it is the expected one\n"));
CTzLocalizedCity* updatedCity = localizer->GetFrequentlyUsedZoneCityL(CTzLocalizedTimeZone::EHomeZone);
test(CompareFrequentlyUsedCityRestoredAfterUpdate(id->TimeZoneNumericID(), *updatedCity));
delete updatedCity;
test.Printf(_L("Get the frequently used zone and check if it is the expected one\n"));
CTzLocalizedTimeZone* timeZone = localizer->GetFrequentlyUsedZoneL(CTzLocalizedTimeZone::EHomeZone);
test(CompareFrequentlyUsedZoneAfterUpdate(id->TimeZoneNumericID(), *timeZone));
delete timeZone;
CleanupStack::PopAndDestroy(id);
delete localizer;
}
void CTestUserDefinedBackupRestore::TestFrequentlyUsedCurrentZonesUpdateAfterRestoreUpdateL()
{
// Add a user defined time zone
test.Printf(_L("Create a user-defined zone\n"));
TTzRule rule1(0, KMaxTUint16, 60, 0, EAugust, ETzFixedDate, 0, 0, ETzWallTimeReference, 120);
TTzRule rule2(0,KMaxTUint16,0,60,EJanuary,ETzFixedDate,0,0,ETzWallTimeReference,120);
CTzRules* rules = CTzRules::NewL(0, KMaxTUint);
CleanupStack::PushL(rules);
rules->AddRuleL(rule1);
rules->AddRuleL(rule2);
CTzUserNames* names = CTzUserNames::NewLC(KStandardName1(), KShortStandardName1(), KDaylightSaveName1(),
KShortDaylightSaveName1(), KCityNameName1(), KRegionName1());
CTzId* id = iUserData->CreateL(*rules, *names);
TInt tzid = id->TimeZoneNumericID();
delete id;
CleanupStack::PopAndDestroy(2, rules);
// Backup the file before we added the user defined time zones
test.Printf(_L("Start the database backup\n"));
TRAPD(err, StartBackupL());
test(err==KErrNone);
TBool result = SimulateTzBackup(KTzBackupFileFullPath, KTzTestBackupFile);
test(result);
TRAP(err, EndBackupL());
test(err == KErrNone);
// Add user-defined rules
test.Printf(_L("Update the rule in the database\n"));
CTzRules* newRules = CTzRules::NewL(0, KMaxTUint);
CleanupStack::PushL(newRules);
newRules->AddRuleL(rule1);
newRules->AddRuleL(rule2);
//Create a user defined rule names- CTzUserNames.
CTzUserNames* names2 = CTzUserNames::NewLC(KStandardName2(), KShortStandardName2(),
KDaylightSaveName2(), KShortDaylightSaveName2(), KCityNameName2(), KRegionName2());
CTzId* tzId = CTzId::NewL(tzid);
CleanupStack::PushL(tzId);
iUserData->UpdateL(*tzId, *rules, *names2);
CleanupStack::PopAndDestroy(tzId);
CleanupStack::PopAndDestroy(2, newRules);
// Set the time zone to Paris
test.Printf(_L("Set the time zone to Paris\n"));
CTzLocalizer* localizer = CTzLocalizer::NewL();
localizer->SetTimeZoneL(KParisTzId);
CTzLocalizedCity* cityToCompareWith = localizer->GetDefaultCityL(KParisTzId);
CleanupStack::PushL(cityToCompareWith);
// Read the frequently used city and compare with the expected one
test.Printf(_L("Get the frequently used city and check if it is the expected one\n"));
CTzLocalizedCity* city = localizer->GetFrequentlyUsedZoneCityL(CTzLocalizedTimeZone::ECurrentZone);
test(CompareFrequentlyUsedCity(*city, *cityToCompareWith));
delete city;
CTzLocalizedTimeZone* zoneToCompareWith = localizer->GetLocalizedTimeZoneL(KParisTzId);
CleanupStack::PushL(zoneToCompareWith);
test.Printf(_L("Get the frequently used zone and check if it is the expected one\n"));
CTzLocalizedTimeZone* timeZone = localizer->GetFrequentlyUsedZoneL(CTzLocalizedTimeZone::ECurrentZone);
test(CompareFrequentlyUsedZone(*timeZone, *zoneToCompareWith));
delete timeZone;
// Restore the file
test.Printf(_L("Restore the backed up file\n"));
TRAP(err, StartRestoreL());
test(err == KErrNone);
result = SimulateTzRestore(KTzTestBackupFile, KTzBackupFileFullPath) ;
test(result);
TRAP(err, EndRestoreL());
test(err == KErrNone);
test.Printf(_L("Again, get the frequently used city and check if it is the expected one\n"));
CTzLocalizedCity* updatedCity = localizer->GetFrequentlyUsedZoneCityL(CTzLocalizedTimeZone::ECurrentZone);
test(CompareFrequentlyUsedCity(*updatedCity, *cityToCompareWith));
delete updatedCity;
test.Printf(_L("Again, get the frequently used zone and check if it is the expected one\n"));
CTzLocalizedTimeZone* updatedTimeZone = localizer->GetFrequentlyUsedZoneL(CTzLocalizedTimeZone::ECurrentZone);
test(CompareFrequentlyUsedZone(*updatedTimeZone, *zoneToCompareWith));
delete updatedTimeZone;
delete localizer;
CleanupStack::PopAndDestroy(2, cityToCompareWith);
}
void CTestUserDefinedBackupRestore::TestUserCitiesUpdateAfterRestoreL()
{
// Backup the file before we add the user defined time zones
test.Printf(_L("Start the backup of the user-defined database\n"));
TRAPD(err, StartBackupL());
test(err==KErrNone);
TBool result = SimulateTzBackup(KTzBackupFileFullPath, KTzTestBackupFile);
test(result);
TRAP(err, EndBackupL());
test(err == KErrNone);
// Add a user defined time zone
test.Printf(_L("Create a user-defined zone\n"));
TTzRule rule1(0, KMaxTUint16, 60, 0, EAugust, ETzFixedDate, 0, 0, ETzWallTimeReference, 120);
TTzRule rule2(0,KMaxTUint16,0,60,EJanuary,ETzFixedDate,0,0,ETzWallTimeReference,120);
CTzRules* rules = CTzRules::NewL(0, KMaxTUint);
CleanupStack::PushL(rules);
rules->AddRuleL(rule1);
rules->AddRuleL(rule2);
CTzUserNames* names = CTzUserNames::NewLC(KStandardName1(), KShortStandardName1(), KDaylightSaveName1(),
KShortDaylightSaveName1(), KCityNameName1(), KRegionName1());
CTzId* id = iUserData->CreateL(*rules, *names);
TInt tzid = id->TimeZoneNumericID();
delete id;
CleanupStack::PopAndDestroy(2, rules);
CTzLocalizer* localizer = CTzLocalizer::NewL();
// Add a city that uses this time zone
test.Printf(_L("Add a user-defined city to the zone\n"));
CTzLocalizedCity* userCity = localizer->AddCityL(tzid, KUserAddedCityName1);
delete userCity;
// Add a user defined time zone
test.Printf(_L("Add another rule to the database\n"));
CTzRules* newRules = CTzRules::NewL(0, KMaxTUint);
CleanupStack::PushL(newRules);
newRules->AddRuleL(rule1);
newRules->AddRuleL(rule2);
CTzUserNames* newNames = CTzUserNames::NewLC(KStandardName2(), KShortStandardName2(), KDaylightSaveName2(),
KShortDaylightSaveName2(), KCityNameName2(), KRegionName2());
CTzId* newId = iUserData->CreateL(*newRules, *newNames);
tzid = newId->TimeZoneNumericID();
delete newId;
CleanupStack::PopAndDestroy(2, newRules);
// Add a city to the new zone
test.Printf(_L("Add a city to the zone\n"));
CTzLocalizedCity* city = localizer->AddCityL(tzid, KUserAddedCityName2);
delete city;
delete localizer;
// Fetch the cities and check the count
test.Printf(_L("Compare the cities retrieved from the table against the number expected\n"));
RPointerArray<CTzLocalizedCityRecord> cityRecords;
CleanupStack::PushL(TCleanupItem(CleanupCityPointerArray, &cityRecords));
iTz.LocalizationReadCitiesL(cityRecords);
test(cityRecords.Count() == 2);
CleanupStack::PopAndDestroy(&cityRecords);
// Restore the file
test.Printf(_L("Restore the backed up file\n"));
TRAP(err, StartRestoreL());
test(err == KErrNone);
result = SimulateTzRestore(KTzTestBackupFile, KTzBackupFileFullPath) ;
test(result);
TRAP(err, EndRestoreL());
test(err == KErrNone);
// Fetch the cities from the backed up file and check the count
test.Printf(_L("Again, compare the cities retrieved from the table against the number expected\n"));
RPointerArray<CTzLocalizedCityRecord> cityRecords2;
CleanupStack::PushL(TCleanupItem(CleanupCityPointerArray, &cityRecords2));
iTz.LocalizationReadCitiesL(cityRecords2);
test(cityRecords2.Count() == 0);
CleanupStack::PopAndDestroy(&cityRecords2);
}
/* Test the update of the cached system time zone rules in Tz server after restore the user defined tz DB
* There are three scenarios are to be tested:
* case 1. Set the Shanghai, which is in the existing database, as the current time zone
* The current time zone should be not be affected after restore the user defined tz DB.
* case 2. Set the current time zone to a user defined time zone.
* The current time zone should be reset to the same time zone after restore the user defined tz DB which have the current time zone rules.
* case 3. Set the current time zone to a user defined time zone.
* The current time zone should be reset to the default time zone London after restore the user defined tz DB which doesn't have the current time zone rules.
*/
void CTestUserDefinedBackupRestore::TestSystemRulesUpdateAfterRestoreL()
{
CTzId* tzid = NULL;
TUint tzNumId = 0;
_LIT8(KTzShangHai, "Asia/Shanghai");
tzid = CTzId::NewL(KTzShangHai);
iTz.SetTimeZoneL(*tzid);
tzNumId = tzid->TimeZoneNumericID();
delete tzid;
//case 1
test(TestSystemRulesUpdateAfterRestoreL(tzNumId, EFalse));
test.Printf(_L("Add a user-defined zone\n"));
TTzRule rule1(0, KMaxTUint16, 60, 0, EAugust, ETzFixedDate, 0, 0, ETzWallTimeReference, 120);
TTzRule rule2(0,KMaxTUint16,0,60,EJanuary,ETzFixedDate,0,0,ETzWallTimeReference,120);
CTzRules* rules = CTzRules::NewL(0, KMaxTUint);
CleanupStack::PushL(rules);
rules->AddRuleL(rule1);
rules->AddRuleL(rule2);
CTzUserNames* names = CTzUserNames::NewLC(KStandardName1(), KShortStandardName1(), KDaylightSaveName1(),
KShortDaylightSaveName1(), KCityNameName1(), KRegionName1());
tzid = iUserData->CreateL(*rules, *names);
CleanupStack::PopAndDestroy(2, rules);
CleanupStack::PushL(tzid);
iTz.SetTimeZoneL(*tzid);
tzNumId = tzid->TimeZoneNumericID();
CleanupStack::PopAndDestroy(tzid);
//case 2
test(TestSystemRulesUpdateAfterRestoreL(tzNumId, EFalse));
//case 3
test(TestSystemRulesUpdateAfterRestoreL(KLondonTzId, ETrue));
}
TBool CTestUserDefinedBackupRestore::TestSystemRulesUpdateAfterRestoreL(TUint aExpectedTzId, TBool aRestoreEmptyFile)
{
test.Next(_L("Test that the system cached rules updated correctly after a restore"));
// Backup the user defined data file
test.Printf(_L("Backup the user defined data file\n"));
TRAPD(err, StartBackupL());
test(err==KErrNone);
TBool result = SimulateTzBackup(KTzBackupFileFullPath, KTzTestBackupFile);
test(result);
TRAP(err, EndBackupL());
test(err == KErrNone);
// Restore the file
test.Printf(_L("Restore the backed up file\n"));
TRAP(err, StartRestoreL());
test(err == KErrNone);
if(aRestoreEmptyFile)
{
//Copy a empty user database to be restored
_LIT(KTzUserDataEmptyFile, "z:\\testresourcefiles\\tz_userdata_empty.db");
iServ.CopyFileL(KTzUserDataEmptyFile, KTzTestBackupFile);
}
result = SimulateTzRestore(KTzTestBackupFile, KTzBackupFileFullPath) ;
test(result);
TRAP(err, EndRestoreL());
test(err == KErrNone);
test.Printf(_L("Get the current time zone and check if it is the expected one\n"));
CTzId* tzid = iTz.GetTimeZoneIdL();
TUint numId = tzid->TimeZoneNumericID();
delete tzid;
return numId == aExpectedTzId;
}
void CTestUserDefinedBackupRestore::RunTestsL()
{
_LIT(KTzServer,"Tzserver*");
TRAP_IGNORE(iServ.KillProcessL(KTzServer));
iServ.DeleteFileL(KTzBackupFileFullPath);
User::LeaveIfError(iTz.Connect());
iUserData = CTzUserData::NewL(iTz);
test.Title();
test.Start(_L("Test Access To User Defined Data During Backup"));
ResetTzUserDataL();
TestBackupAndRestoreUserDbL(EBackupTest);
test.Next(_L("Test Access To User Defined Data During Restore"));
TestBackupAndRestoreUserDbL(ERestoreTest);
test.Next(_L("Test Frequently Used Zones Update After Restore With Delete"));
TestFrequentlyUsedZonesUpdateAfterRestoreDeleteL();
test.Next(_L("Test Frequently Used Zones Update After Restore With Update"));
TestFrequentlyUsedZonesUpdateAfterRestoreUpdateL();
test.Next(_L("Test Frequently Used Current Zones Update After Restore With Update"));
TestFrequentlyUsedCurrentZonesUpdateAfterRestoreUpdateL();
test.Next(_L("Test User Cities Update After Restore"));
TestUserCitiesUpdateAfterRestoreL();
test.Next(_L("Test Update system Cached rules After Restore"));
TestSystemRulesUpdateAfterRestoreL();
test.Next(_L("Test Access To Localization DB During Backup and Restore"));
TestBackupAndRestoreLocDbL();
ResetTzUserDataL();
test.End();
iTz.Close();
TRAP_IGNORE(iServ.KillProcessL(KTzServer));
iServ.DeleteFileL(KTzBackupFileFullPath);
iServ.DeleteFileL(KPerFile1);
iServ.DeleteFileL(KPerFile2);
}
static void DoTestsL()
{
BackupClient = conn::CSBEClient::NewL();
CleanupStack::PushL(BackupClient);
CActiveScheduler* scheduler = new (ELeave) CActiveScheduler;
CleanupStack::PushL(scheduler);
CActiveScheduler::Install(scheduler);
CTestUserDefinedBackupRestore* backupRestore = CTestUserDefinedBackupRestore::NewL();
CleanupStack::PushL(backupRestore);
backupRestore->RunTestsL();
// cleanup
CleanupStack::PopAndDestroy(backupRestore);
CleanupStack::PopAndDestroy(scheduler);
CleanupStack::PopAndDestroy(BackupClient);
}
GLDEF_C TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* cleanup = CTrapCleanup::New();
if (!cleanup)
{
return KErrNoMemory;
}
TRAPD(ret, DoTestsL());
test.Printf(_L("Trapped return value from DoTestsL(): %d\n"), ret);
test(ret == KErrNone);
test.Close();
delete cleanup;
__UHEAP_MARKEND;
return KErrNone;
}