tzservices/tzserver/test/component/t_tzlocalizationdbcreationtests.cpp
changeset 0 2e3d3ce01487
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tzservices/tzserver/test/component/t_tzlocalizationdbcreationtests.cpp	Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,473 @@
+// 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);
+    }