tzservices/tzserver/test/component/t_tzlocalizationdbcreationtests.cpp
author William Roberts <williamr@symbian.org>
Fri, 23 Apr 2010 14:37:17 +0100
branchRCL_3
changeset 22 c82a39b81a38
parent 0 2e3d3ce01487
permissions -rw-r--r--
Rework addition of Symbian splash screen to reduce the source impact (uses SVG from Bug 2414) Notes: by using the OPTION SOURCEDIR parameter in the mifconv extension instructions, I can arrange to use the same source file name in sfimage, without having to export over the original Nokia file. This means that the name inside splashscreen.mbg is the same, which removes the need for the conditional compilation in SplashScreen.cpp, and gets rid of sf_splashscreen.mmp.

// 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 <e32base.h>
#include <e32test.h>
#include <d32dbms.h>
#include "testserver.h"
#include <tzlocalizationdatatypes.h>
#include <tzlocalizer.h>

// These literals are copied from the product code as we don't want to export them
_LIT(KTzLocalizationDbName, "c:TzLocalization.db");
_LIT(KTzLocalizationDbSecurityPolicy,"secure[10206A8B]");
_LIT(KlocDbStart_test_source, "z:\\testresourcefiles\\locDbStart_test.db");
_LIT(KlocDbStart_test_destination, "c:\\private\\100012a5\\DBS_10206A8B_TzLocalization.db");
_LIT(KTimeStamp, "c:\\private\\1020383e\\timestamps");

/**
This is a series of tests that check that the frequently used timezones table and
the user-defined cities table stored in the c:TzLocalization.db DBMS database are
created correctly when they don't exist, are corrupted or need to be upgraded from
an old format to a new format.
*/
class CTzLocalizationDbCreationTests : public CBase
	{
public:
	static CTzLocalizationDbCreationTests* NewLC(RTest& aTest);
	~CTzLocalizationDbCreationTests();
	
private:
	CTzLocalizationDbCreationTests(RTest& aTest);
	void ConstructL();
	
public:
	void RunL();
	
private:
	void RunTzLocalizationDbSchemaUpgradeTestL();
	void RunTzLocalizationDbStartUpdateTestL();
	
private:
	void CheckTzServerNotRunningL();
	void EnsureTzServerNotRunning();
	void EnsureAgendaServerNotRunning();
	void DeleteTzLocalizationDbL();
	void CreateTzLocalizationDbUsingOldSchemaL();
	void CreateFrequentlyUsedTimeZonesTableUsingOldSchemaL(RDbNamedDatabase& aDatabase);
	void CreateUserAddedCitiesTableL(RDbNamedDatabase& aDatabase);
	
private:
	RTest& iTest;
	RPIMTestServer iPIMTestServer;
	RDbs iDbsSession;
	};


CTzLocalizationDbCreationTests* CTzLocalizationDbCreationTests::NewLC(RTest& aTest)
	{
	CTzLocalizationDbCreationTests* self = new(ELeave) CTzLocalizationDbCreationTests(aTest);
	CleanupStack::PushL(self);
	self->ConstructL();
	return self;
	}

CTzLocalizationDbCreationTests::~CTzLocalizationDbCreationTests()
	{
	iDbsSession.Close();
	iPIMTestServer.Close();
	}

CTzLocalizationDbCreationTests::CTzLocalizationDbCreationTests(RTest& aTest)
	: iTest(aTest)
	{
	}

void CTzLocalizationDbCreationTests::ConstructL()
	{
	User::LeaveIfError(iPIMTestServer.Connect());
	iPIMTestServer.CloseTzSession();
	User::LeaveIfError(iDbsSession.Connect());
	}

void CTzLocalizationDbCreationTests::RunL()
	{
	_LIT(KTestName, "@SYMTestCaseID:PIM-APPSERV-tzlocalizationdbcreationtests-0001 TzLocalizationDbSchemaUpgradeTest");
	
	iTest.Start(KTestName);
	TRAPD(err, RunTzLocalizationDbSchemaUpgradeTestL())
	if (err != KErrNone)
		{
		_LIT(KErrorMsg, "RunTzLocalizationDbSchemaUpgradeTestL with error code: %d\n");
		iTest.Printf(KErrorMsg, err);
		User::Leave(err);
		}

	_LIT(KTestName1, "RunTzLocalizationDbStartUpdateTestL");
	
	iTest.Next(KTestName1);
	TRAP(err, RunTzLocalizationDbStartUpdateTestL());
	if (err != KErrNone)
		{
		_LIT(KErrorMsg1, "RunTzLocalizationDbStartUpdateTestL with error code: %d\n");
		iTest.Printf(KErrorMsg1, err);
		User::Leave(err);
		}
	iTest.End();
	}

void CTzLocalizationDbCreationTests::RunTzLocalizationDbSchemaUpgradeTestL()
	{
	// Delete the current database and replace it with an old version
	DeleteTzLocalizationDbL();
	CreateTzLocalizationDbUsingOldSchemaL();
	
	// Create a CTzLocalizer object and check that the database
	// is upgraded correctly
	CTzLocalizer* localizer = 0;
	TRAPD(err, localizer = CTzLocalizer::NewL());
	if (err != KErrNone)
		{
		_LIT(KErrorMsg, "CTzLocalizer creation failed with error code: %d\n");
		iTest.Printf(KErrorMsg, err);
		User::Leave(err);
		}
	delete localizer;
	
	// Creation of the CTzLocalizer should have caused a database upgrade
	RDbNamedDatabase tzLocalizationDb;
	User::LeaveIfError(tzLocalizationDb.Open(iDbsSession,KTzLocalizationDbName,KTzLocalizationDbSecurityPolicy));
	CleanupClosePushL(tzLocalizationDb);
	RDbView zoneView;
	CleanupClosePushL(zoneView);
	_LIT(KReadZoneView,"SELECT * FROM FrequentlyUsedZones");
	User::LeaveIfError(zoneView.Prepare(tzLocalizationDb, TDbQuery(KReadZoneView), zoneView.EUpdatable));
	User::LeaveIfError(zoneView.EvaluateAll());
	zoneView.Reset();
	const TInt KExpectedNumberOfColumns = 9;
	_LIT(KMsg1, "Expected number of columns: %d\n");
	iTest.Printf(KMsg1, KExpectedNumberOfColumns);
	const TInt colCount = zoneView.ColCount();
	_LIT(KMsg2, "Actual number of columns: %d\n");
	iTest.Printf(KMsg2, colCount);
	if (colCount != KExpectedNumberOfColumns)
		{
		iTest(EFalse);
		}
	CleanupStack::PopAndDestroy(&zoneView);
	CleanupStack::PopAndDestroy(&tzLocalizationDb);
	
	// Cleanup database file
	DeleteTzLocalizationDbL();
	}
/* Localization Database start up
 * Verify that the localization database start-up copes well when it contains some
 * time zone infomation whose Tz ID no longer exists in the TZ database.
 */
void CTzLocalizationDbCreationTests::RunTzLocalizationDbStartUpdateTestL()
	{
	//Make sure the Tz server is not running.
	EnsureTzServerNotRunning();
	//Copy a localization DB contained few frequently used Tz zones which do not exist in the current Tz database.
	iTest.Printf(_L("Copy test file DBS_10206A8B_TzLocalization.db"));
	iPIMTestServer.CopyFileL(KlocDbStart_test_source ,KlocDbStart_test_destination);
	iPIMTestServer.DeleteFileL(KTimeStamp);
	
	//Connect to the Tz server which result in the localization DB updating its tables.
	iTest.Printf(_L("Connect to the Tz server"));
	RTz tz;
	CleanupClosePushL(tz);
	User::LeaveIfError(tz.Connect());
	CTzId* tzid = tz.GetTimeZoneIdL();
	TUint id = tzid->TimeZoneNumericID();
	delete tzid;
	
	//Carry some basic operations which access to the localization DB.
	iTest.Printf(_L("Access to the localization DB"));
	CTzLocalizer* localizer = CTzLocalizer::NewL();
	CleanupStack::PushL(localizer);
	
	CTzLocalizedTimeZone* locTzId = localizer->GetFrequentlyUsedZoneL(CTzLocalizedTimeZone::ECurrentZone);
	iTest (locTzId->TimeZoneId() == id);
	delete locTzId;
	
	CTzLocalizedCity* locCity = localizer->GetFrequentlyUsedZoneCityL(CTzLocalizedTimeZone::ECurrentZone);
	iTest (locCity->TimeZoneId() == id);
	delete locCity;

	//Disconnect to the Tz server and delete the localization DB
	CleanupStack::PopAndDestroy(2, &tz);
	iPIMTestServer.DeleteFileL(KlocDbStart_test_destination);
	}

void CTzLocalizationDbCreationTests::CheckTzServerNotRunningL()
	{
	_LIT(KTzServerProcessPattern, "tzserver.exe*");
	TFindProcess finder(KTzServerProcessPattern);
	TFileName foundName;
	while (finder.Next(foundName) == KErrNone)
		{
		RProcess proc;
		TInt err = proc.Open(foundName);
		if (err == KErrNone)
			{
			if (proc.ExitType() == EExitPending)
				{
				_LIT(KErrorMsg, "TzServer must not be running\n");
				iTest.Printf(KErrorMsg);
				User::Leave(KErrNotReady);
				}
			}
		}
	}


void CTzLocalizationDbCreationTests::EnsureAgendaServerNotRunning()
	{
	_LIT(KAgendaServerProcessPattern, "agsvexe.exe*");
	TFindProcess finder(KAgendaServerProcessPattern);
	TFileName foundName;
	while (finder.Next(foundName) == KErrNone)
		{
		RProcess proc;
		TInt err = proc.Open(foundName);
		if (err == KErrNone)
			{
			if (proc.ExitType() == EExitPending)
				{
				_LIT(KInfoMsg, "INFO: Agenda server must not be running - killing it now.\n");
				iTest.Printf(KInfoMsg);
				TRAP_IGNORE(iPIMTestServer.KillProcessL(KAgendaServerProcessPattern));
				}
			}
		}
	}

void CTzLocalizationDbCreationTests::EnsureTzServerNotRunning()
	{
	_LIT(KTzServerProcessPattern, "tzserver.exe*");
	TFindProcess finder(KTzServerProcessPattern);
	TFileName foundName;
	while (finder.Next(foundName) == KErrNone)
		{
		RProcess proc;
		TInt err = proc.Open(foundName);
		if (err == KErrNone)
			{
			if (proc.ExitType() == EExitPending)
				{
				_LIT(KInfoMsg, "INFO: TzServer must not be running - killing it now.\n");
				iTest.Printf(KInfoMsg);
				TRAP_IGNORE(iPIMTestServer.KillProcessL(KTzServerProcessPattern));
				}
			}
		}
	}

void CTzLocalizationDbCreationTests::DeleteTzLocalizationDbL()
	{
	EnsureAgendaServerNotRunning();
	EnsureTzServerNotRunning();
	
	_LIT(KTzLocalizationDbFilePath, "c:\\private\\100012a5\\DBS_10206A8B_TzLocalization.db");
	TRAPD(err, iPIMTestServer.DeleteFileL(KTzLocalizationDbFilePath));
	if (err != KErrNone)
		{
		_LIT(KErrorMsg, "Database deletion failed with error code: %d\n");
		iTest.Printf(KErrorMsg, err);
		User::Leave(err);
		}
	}

void CTzLocalizationDbCreationTests::CreateTzLocalizationDbUsingOldSchemaL()
	{
	EnsureAgendaServerNotRunning();
	EnsureTzServerNotRunning();
	
	RDbNamedDatabase tzLocalizationDb;
	CleanupClosePushL(tzLocalizationDb);
	TInt err = tzLocalizationDb.Create(iDbsSession, KTzLocalizationDbName, KTzLocalizationDbSecurityPolicy);
	if (err != KErrNone)
		{
		_LIT(KErrorMsg, "Database creation failed with error code: %d\n");
		iTest.Printf(KErrorMsg, err);
		User::Leave(err);
		}
	CreateFrequentlyUsedTimeZonesTableUsingOldSchemaL(tzLocalizationDb);
	CreateUserAddedCitiesTableL(tzLocalizationDb);
	CleanupStack::PopAndDestroy(&tzLocalizationDb);
	}

/**
This is mostly a copy/paste of CTzLocalizationDb::CreateFrequentlyUsedTimeZonesTableL() but 
modified so that it creates a database without the city index column.
*/
void CTzLocalizationDbCreationTests::CreateFrequentlyUsedTimeZonesTableUsingOldSchemaL(RDbNamedDatabase& aDatabase)
	{
	//Table and Column names for Cached Time Zone Table
	//These text strings are never visible and do not need localizing
	_LIT(KCZTableName, "FrequentlyUsedZones");
	_LIT(KCZTableTzIdCol, "TzId");
	_LIT(KCZTableStdCol, "StandardName");
	_LIT(KCZTableDSTCol, "DSTName");
	_LIT(KCZTableShortStdCol, "ShortStandardName");
	_LIT(KCZTableShortDSTCol, "ShortDSTName");
	_LIT(KCZTableCityCol, "City");
	_LIT(KCZTableCityGroupCol, "GroupId");
	_LIT(KCZTableResourceIdCol, "ResourceId");
	
	// Create the columns for the cached zones table
	RArray<TDbCol> cachedTableCols;
	CleanupClosePushL(cachedTableCols);
	cachedTableCols.AppendL(TDbCol(KCZTableTzIdCol,			EDbColUint16));
	cachedTableCols.AppendL(TDbCol(KCZTableStdCol, 			EDbColText));
	cachedTableCols.AppendL(TDbCol(KCZTableDSTCol, 			EDbColText));
	cachedTableCols.AppendL(TDbCol(KCZTableShortStdCol, 	EDbColText));
	cachedTableCols.AppendL(TDbCol(KCZTableShortDSTCol, 	EDbColText));
	cachedTableCols.AppendL(TDbCol(KCZTableCityCol, 		EDbColText));
	cachedTableCols.AppendL(TDbCol(KCZTableCityGroupCol, 	EDbColUint8));
	cachedTableCols.AppendL(TDbCol(KCZTableResourceIdCol, 	EDbColUint32));
	// We do not add the city index column as we want to create a database using
	// the old schema
    
	// Create the columnset - add the columns
	// Columns MUST be added in the same order they appear in TTzZoneColumn
	CDbColSet* frequentlyUsedTimeZonesColSet = CDbColSet::NewLC();
	TInt numCols = cachedTableCols.Count();
	for(TInt i = 0; i < numCols; ++i)
		{
		frequentlyUsedTimeZonesColSet->AddL(cachedTableCols[i]);
		}

	// Create the Cached Time Zone table
	User::LeaveIfError(aDatabase.CreateTable(KCZTableName, *frequentlyUsedTimeZonesColSet));

	//Open the newly created table
	RDbView zoneView;
	CleanupClosePushL(zoneView);
	_LIT(KReadZoneView,"SELECT * FROM FrequentlyUsedZones");
	User::LeaveIfError(zoneView.Prepare(aDatabase, TDbQuery(KReadZoneView), zoneView.EUpdatable));
	User::LeaveIfError(zoneView.EvaluateAll());
	zoneView.Reset();
	//Populate with initial (blank) data.

	_LIT(KEmptyString," ");

	enum TTzOldSchemaZoneColumn
		{
		// Enum will used as a DB column index, so it must start at 1
		ETzZoneId = 1,
		ETzZoneStdName,
		ETzZoneDSTName,
		ETzZoneShortStdName,
		ETzZoneShortDSTName,
		ETzZoneCity,
		ETzZoneGroupId,
		ETzZoneResourceId,
		};
	
	for (TInt x = 0; x < CTzLocalizedTimeZone::ECachedTimeZones; ++x)
		{
		// Insert empty row
		zoneView.InsertL();
		// Fill the table with blank data
		zoneView.SetColL(ETzZoneId,			0);
		zoneView.SetColL(ETzZoneStdName,		KEmptyString);
		zoneView.SetColL(ETzZoneDSTName,		KEmptyString);
		zoneView.SetColL(ETzZoneShortStdName,	KEmptyString);
		zoneView.SetColL(ETzZoneShortDSTName,	KEmptyString);
		zoneView.SetColL(ETzZoneCity,			KEmptyString);
		zoneView.SetColL(ETzZoneGroupId,		0);
		zoneView.SetColL(ETzZoneResourceId,	0);
		zoneView.PutL(); // Complete insertion
		}
	
	CleanupStack::PopAndDestroy(&zoneView);
	CleanupStack::PopAndDestroy(frequentlyUsedTimeZonesColSet);
	CleanupStack::PopAndDestroy(&cachedTableCols);
	}

/**
This is a copy/paste of CTzLocalizationDb::CreateUserAddedCitiesTableL() that 
we can't use as it is not exported.
*/
void CTzLocalizationDbCreationTests::CreateUserAddedCitiesTableL(RDbNamedDatabase& aDatabase)
	{
	//Table and Column names for User Added Cities Table
	//These text strings are never visible and do not need localizing
	_LIT(KUCTableName, "UserCities");
	_LIT(KUCTableTzId, "TzId");
	_LIT(KUCTableCity, "City");
	_LIT(KUCTableGroup, "GroupId");
	_LIT(KUCTableResourceId, "ResourceId");
	
	//Create the columns for the user aded cities table
	RArray<TDbCol> cityTableCols;
	CleanupClosePushL(cityTableCols);
	cityTableCols.AppendL(TDbCol(KUCTableTzId,			EDbColUint16));
	cityTableCols.AppendL(TDbCol(KUCTableCity,			EDbColText));
	cityTableCols.AppendL(TDbCol(KUCTableGroup,			EDbColUint8));
	cityTableCols.AppendL(TDbCol(KUCTableResourceId,	EDbColUint32));

	// Create the columnset - add the columns
	// Columns MUST be added in the same order they appear in TTzCityColumn
	CDbColSet* userAddedCitiesColSet = CDbColSet::NewLC();
	TInt numCols = cityTableCols.Count();
	for(TInt i = 0; i < numCols; ++i)
		{
		userAddedCitiesColSet->AddL(cityTableCols[i]);
		}

	// Create the User City table
	User::LeaveIfError(aDatabase.CreateTable(KUCTableName, *userAddedCitiesColSet));
	
	CleanupStack::PopAndDestroy(userAddedCitiesColSet);
	CleanupStack::PopAndDestroy(&cityTableCols);
	}

static void DoTestsL(RTest& aTest)
	{
	CTzLocalizationDbCreationTests* tests = CTzLocalizationDbCreationTests::NewLC(aTest);
	tests->RunL();
	CleanupStack::PopAndDestroy(tests);
	}

/**

@SYMTestCaseID	PIM-APPSERV-tzlocalizationdbcreationtests-0001

*/

TInt E32Main()
    {
	__UHEAP_MARK;

	CTrapCleanup* trapCleanup = CTrapCleanup::New();
	if(!trapCleanup)
		{
		return KErrNoMemory;
		}

	CActiveScheduler* scheduler = new CActiveScheduler;
	if(!scheduler)
		{
		return KErrNoMemory;
		}
	CActiveScheduler::Install(scheduler);	

	_LIT(KTestName, "t_tzlocalizationdbcreationtests");
	RTest test(KTestName);
	TRAPD(ret, DoTestsL(test));
	test.Printf(_L("Trapped return value from DoTestsL(): %d\n"), ret);
	test(ret == KErrNone);
	test.Close();
	
	delete scheduler;
	delete trapCleanup;	

	__UHEAP_MARKEND;

	return (KErrNone);
    }