|
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include <e32base.h> |
|
17 #include <e32test.h> |
|
18 #include <d32dbms.h> |
|
19 #include "testserver.h" |
|
20 #include <tzlocalizationdatatypes.h> |
|
21 #include <tzlocalizer.h> |
|
22 |
|
23 // These literals are copied from the product code as we don't want to export them |
|
24 _LIT(KTzLocalizationDbName, "c:TzLocalization.db"); |
|
25 _LIT(KTzLocalizationDbSecurityPolicy,"secure[10206A8B]"); |
|
26 _LIT(KlocDbStart_test_source, "z:\\testresourcefiles\\locDbStart_test.db"); |
|
27 _LIT(KlocDbStart_test_destination, "c:\\private\\100012a5\\DBS_10206A8B_TzLocalization.db"); |
|
28 _LIT(KTimeStamp, "c:\\private\\1020383e\\timestamps"); |
|
29 |
|
30 /** |
|
31 This is a series of tests that check that the frequently used timezones table and |
|
32 the user-defined cities table stored in the c:TzLocalization.db DBMS database are |
|
33 created correctly when they don't exist, are corrupted or need to be upgraded from |
|
34 an old format to a new format. |
|
35 */ |
|
36 class CTzLocalizationDbCreationTests : public CBase |
|
37 { |
|
38 public: |
|
39 static CTzLocalizationDbCreationTests* NewLC(RTest& aTest); |
|
40 ~CTzLocalizationDbCreationTests(); |
|
41 |
|
42 private: |
|
43 CTzLocalizationDbCreationTests(RTest& aTest); |
|
44 void ConstructL(); |
|
45 |
|
46 public: |
|
47 void RunL(); |
|
48 |
|
49 private: |
|
50 void RunTzLocalizationDbSchemaUpgradeTestL(); |
|
51 void RunTzLocalizationDbStartUpdateTestL(); |
|
52 |
|
53 private: |
|
54 void CheckTzServerNotRunningL(); |
|
55 void EnsureTzServerNotRunning(); |
|
56 void EnsureAgendaServerNotRunning(); |
|
57 void DeleteTzLocalizationDbL(); |
|
58 void CreateTzLocalizationDbUsingOldSchemaL(); |
|
59 void CreateFrequentlyUsedTimeZonesTableUsingOldSchemaL(RDbNamedDatabase& aDatabase); |
|
60 void CreateUserAddedCitiesTableL(RDbNamedDatabase& aDatabase); |
|
61 |
|
62 private: |
|
63 RTest& iTest; |
|
64 RPIMTestServer iPIMTestServer; |
|
65 RDbs iDbsSession; |
|
66 }; |
|
67 |
|
68 |
|
69 CTzLocalizationDbCreationTests* CTzLocalizationDbCreationTests::NewLC(RTest& aTest) |
|
70 { |
|
71 CTzLocalizationDbCreationTests* self = new(ELeave) CTzLocalizationDbCreationTests(aTest); |
|
72 CleanupStack::PushL(self); |
|
73 self->ConstructL(); |
|
74 return self; |
|
75 } |
|
76 |
|
77 CTzLocalizationDbCreationTests::~CTzLocalizationDbCreationTests() |
|
78 { |
|
79 iDbsSession.Close(); |
|
80 iPIMTestServer.Close(); |
|
81 } |
|
82 |
|
83 CTzLocalizationDbCreationTests::CTzLocalizationDbCreationTests(RTest& aTest) |
|
84 : iTest(aTest) |
|
85 { |
|
86 } |
|
87 |
|
88 void CTzLocalizationDbCreationTests::ConstructL() |
|
89 { |
|
90 User::LeaveIfError(iPIMTestServer.Connect()); |
|
91 iPIMTestServer.CloseTzSession(); |
|
92 User::LeaveIfError(iDbsSession.Connect()); |
|
93 } |
|
94 |
|
95 void CTzLocalizationDbCreationTests::RunL() |
|
96 { |
|
97 _LIT(KTestName, "@SYMTestCaseID:PIM-APPSERV-tzlocalizationdbcreationtests-0001 TzLocalizationDbSchemaUpgradeTest"); |
|
98 |
|
99 iTest.Start(KTestName); |
|
100 TRAPD(err, RunTzLocalizationDbSchemaUpgradeTestL()) |
|
101 if (err != KErrNone) |
|
102 { |
|
103 _LIT(KErrorMsg, "RunTzLocalizationDbSchemaUpgradeTestL with error code: %d\n"); |
|
104 iTest.Printf(KErrorMsg, err); |
|
105 User::Leave(err); |
|
106 } |
|
107 |
|
108 _LIT(KTestName1, "RunTzLocalizationDbStartUpdateTestL"); |
|
109 |
|
110 iTest.Next(KTestName1); |
|
111 TRAP(err, RunTzLocalizationDbStartUpdateTestL()); |
|
112 if (err != KErrNone) |
|
113 { |
|
114 _LIT(KErrorMsg1, "RunTzLocalizationDbStartUpdateTestL with error code: %d\n"); |
|
115 iTest.Printf(KErrorMsg1, err); |
|
116 User::Leave(err); |
|
117 } |
|
118 iTest.End(); |
|
119 } |
|
120 |
|
121 void CTzLocalizationDbCreationTests::RunTzLocalizationDbSchemaUpgradeTestL() |
|
122 { |
|
123 // Delete the current database and replace it with an old version |
|
124 DeleteTzLocalizationDbL(); |
|
125 CreateTzLocalizationDbUsingOldSchemaL(); |
|
126 |
|
127 // Create a CTzLocalizer object and check that the database |
|
128 // is upgraded correctly |
|
129 CTzLocalizer* localizer = 0; |
|
130 TRAPD(err, localizer = CTzLocalizer::NewL()); |
|
131 if (err != KErrNone) |
|
132 { |
|
133 _LIT(KErrorMsg, "CTzLocalizer creation failed with error code: %d\n"); |
|
134 iTest.Printf(KErrorMsg, err); |
|
135 User::Leave(err); |
|
136 } |
|
137 delete localizer; |
|
138 |
|
139 // Creation of the CTzLocalizer should have caused a database upgrade |
|
140 RDbNamedDatabase tzLocalizationDb; |
|
141 User::LeaveIfError(tzLocalizationDb.Open(iDbsSession,KTzLocalizationDbName,KTzLocalizationDbSecurityPolicy)); |
|
142 CleanupClosePushL(tzLocalizationDb); |
|
143 RDbView zoneView; |
|
144 CleanupClosePushL(zoneView); |
|
145 _LIT(KReadZoneView,"SELECT * FROM FrequentlyUsedZones"); |
|
146 User::LeaveIfError(zoneView.Prepare(tzLocalizationDb, TDbQuery(KReadZoneView), zoneView.EUpdatable)); |
|
147 User::LeaveIfError(zoneView.EvaluateAll()); |
|
148 zoneView.Reset(); |
|
149 const TInt KExpectedNumberOfColumns = 9; |
|
150 _LIT(KMsg1, "Expected number of columns: %d\n"); |
|
151 iTest.Printf(KMsg1, KExpectedNumberOfColumns); |
|
152 const TInt colCount = zoneView.ColCount(); |
|
153 _LIT(KMsg2, "Actual number of columns: %d\n"); |
|
154 iTest.Printf(KMsg2, colCount); |
|
155 if (colCount != KExpectedNumberOfColumns) |
|
156 { |
|
157 iTest(EFalse); |
|
158 } |
|
159 CleanupStack::PopAndDestroy(&zoneView); |
|
160 CleanupStack::PopAndDestroy(&tzLocalizationDb); |
|
161 |
|
162 // Cleanup database file |
|
163 DeleteTzLocalizationDbL(); |
|
164 } |
|
165 /* Localization Database start up |
|
166 * Verify that the localization database start-up copes well when it contains some |
|
167 * time zone infomation whose Tz ID no longer exists in the TZ database. |
|
168 */ |
|
169 void CTzLocalizationDbCreationTests::RunTzLocalizationDbStartUpdateTestL() |
|
170 { |
|
171 //Make sure the Tz server is not running. |
|
172 EnsureTzServerNotRunning(); |
|
173 //Copy a localization DB contained few frequently used Tz zones which do not exist in the current Tz database. |
|
174 iTest.Printf(_L("Copy test file DBS_10206A8B_TzLocalization.db")); |
|
175 iPIMTestServer.CopyFileL(KlocDbStart_test_source ,KlocDbStart_test_destination); |
|
176 iPIMTestServer.DeleteFileL(KTimeStamp); |
|
177 |
|
178 //Connect to the Tz server which result in the localization DB updating its tables. |
|
179 iTest.Printf(_L("Connect to the Tz server")); |
|
180 RTz tz; |
|
181 CleanupClosePushL(tz); |
|
182 User::LeaveIfError(tz.Connect()); |
|
183 CTzId* tzid = tz.GetTimeZoneIdL(); |
|
184 TUint id = tzid->TimeZoneNumericID(); |
|
185 delete tzid; |
|
186 |
|
187 //Carry some basic operations which access to the localization DB. |
|
188 iTest.Printf(_L("Access to the localization DB")); |
|
189 CTzLocalizer* localizer = CTzLocalizer::NewL(); |
|
190 CleanupStack::PushL(localizer); |
|
191 |
|
192 CTzLocalizedTimeZone* locTzId = localizer->GetFrequentlyUsedZoneL(CTzLocalizedTimeZone::ECurrentZone); |
|
193 iTest (locTzId->TimeZoneId() == id); |
|
194 delete locTzId; |
|
195 |
|
196 CTzLocalizedCity* locCity = localizer->GetFrequentlyUsedZoneCityL(CTzLocalizedTimeZone::ECurrentZone); |
|
197 iTest (locCity->TimeZoneId() == id); |
|
198 delete locCity; |
|
199 |
|
200 //Disconnect to the Tz server and delete the localization DB |
|
201 CleanupStack::PopAndDestroy(2, &tz); |
|
202 iPIMTestServer.DeleteFileL(KlocDbStart_test_destination); |
|
203 } |
|
204 |
|
205 void CTzLocalizationDbCreationTests::CheckTzServerNotRunningL() |
|
206 { |
|
207 _LIT(KTzServerProcessPattern, "tzserver.exe*"); |
|
208 TFindProcess finder(KTzServerProcessPattern); |
|
209 TFileName foundName; |
|
210 while (finder.Next(foundName) == KErrNone) |
|
211 { |
|
212 RProcess proc; |
|
213 TInt err = proc.Open(foundName); |
|
214 if (err == KErrNone) |
|
215 { |
|
216 if (proc.ExitType() == EExitPending) |
|
217 { |
|
218 _LIT(KErrorMsg, "TzServer must not be running\n"); |
|
219 iTest.Printf(KErrorMsg); |
|
220 User::Leave(KErrNotReady); |
|
221 } |
|
222 } |
|
223 } |
|
224 } |
|
225 |
|
226 |
|
227 void CTzLocalizationDbCreationTests::EnsureAgendaServerNotRunning() |
|
228 { |
|
229 _LIT(KAgendaServerProcessPattern, "agsvexe.exe*"); |
|
230 TFindProcess finder(KAgendaServerProcessPattern); |
|
231 TFileName foundName; |
|
232 while (finder.Next(foundName) == KErrNone) |
|
233 { |
|
234 RProcess proc; |
|
235 TInt err = proc.Open(foundName); |
|
236 if (err == KErrNone) |
|
237 { |
|
238 if (proc.ExitType() == EExitPending) |
|
239 { |
|
240 _LIT(KInfoMsg, "INFO: Agenda server must not be running - killing it now.\n"); |
|
241 iTest.Printf(KInfoMsg); |
|
242 TRAP_IGNORE(iPIMTestServer.KillProcessL(KAgendaServerProcessPattern)); |
|
243 } |
|
244 } |
|
245 } |
|
246 } |
|
247 |
|
248 void CTzLocalizationDbCreationTests::EnsureTzServerNotRunning() |
|
249 { |
|
250 _LIT(KTzServerProcessPattern, "tzserver.exe*"); |
|
251 TFindProcess finder(KTzServerProcessPattern); |
|
252 TFileName foundName; |
|
253 while (finder.Next(foundName) == KErrNone) |
|
254 { |
|
255 RProcess proc; |
|
256 TInt err = proc.Open(foundName); |
|
257 if (err == KErrNone) |
|
258 { |
|
259 if (proc.ExitType() == EExitPending) |
|
260 { |
|
261 _LIT(KInfoMsg, "INFO: TzServer must not be running - killing it now.\n"); |
|
262 iTest.Printf(KInfoMsg); |
|
263 TRAP_IGNORE(iPIMTestServer.KillProcessL(KTzServerProcessPattern)); |
|
264 } |
|
265 } |
|
266 } |
|
267 } |
|
268 |
|
269 void CTzLocalizationDbCreationTests::DeleteTzLocalizationDbL() |
|
270 { |
|
271 EnsureAgendaServerNotRunning(); |
|
272 EnsureTzServerNotRunning(); |
|
273 |
|
274 _LIT(KTzLocalizationDbFilePath, "c:\\private\\100012a5\\DBS_10206A8B_TzLocalization.db"); |
|
275 TRAPD(err, iPIMTestServer.DeleteFileL(KTzLocalizationDbFilePath)); |
|
276 if (err != KErrNone) |
|
277 { |
|
278 _LIT(KErrorMsg, "Database deletion failed with error code: %d\n"); |
|
279 iTest.Printf(KErrorMsg, err); |
|
280 User::Leave(err); |
|
281 } |
|
282 } |
|
283 |
|
284 void CTzLocalizationDbCreationTests::CreateTzLocalizationDbUsingOldSchemaL() |
|
285 { |
|
286 EnsureAgendaServerNotRunning(); |
|
287 EnsureTzServerNotRunning(); |
|
288 |
|
289 RDbNamedDatabase tzLocalizationDb; |
|
290 CleanupClosePushL(tzLocalizationDb); |
|
291 TInt err = tzLocalizationDb.Create(iDbsSession, KTzLocalizationDbName, KTzLocalizationDbSecurityPolicy); |
|
292 if (err != KErrNone) |
|
293 { |
|
294 _LIT(KErrorMsg, "Database creation failed with error code: %d\n"); |
|
295 iTest.Printf(KErrorMsg, err); |
|
296 User::Leave(err); |
|
297 } |
|
298 CreateFrequentlyUsedTimeZonesTableUsingOldSchemaL(tzLocalizationDb); |
|
299 CreateUserAddedCitiesTableL(tzLocalizationDb); |
|
300 CleanupStack::PopAndDestroy(&tzLocalizationDb); |
|
301 } |
|
302 |
|
303 /** |
|
304 This is mostly a copy/paste of CTzLocalizationDb::CreateFrequentlyUsedTimeZonesTableL() but |
|
305 modified so that it creates a database without the city index column. |
|
306 */ |
|
307 void CTzLocalizationDbCreationTests::CreateFrequentlyUsedTimeZonesTableUsingOldSchemaL(RDbNamedDatabase& aDatabase) |
|
308 { |
|
309 //Table and Column names for Cached Time Zone Table |
|
310 //These text strings are never visible and do not need localizing |
|
311 _LIT(KCZTableName, "FrequentlyUsedZones"); |
|
312 _LIT(KCZTableTzIdCol, "TzId"); |
|
313 _LIT(KCZTableStdCol, "StandardName"); |
|
314 _LIT(KCZTableDSTCol, "DSTName"); |
|
315 _LIT(KCZTableShortStdCol, "ShortStandardName"); |
|
316 _LIT(KCZTableShortDSTCol, "ShortDSTName"); |
|
317 _LIT(KCZTableCityCol, "City"); |
|
318 _LIT(KCZTableCityGroupCol, "GroupId"); |
|
319 _LIT(KCZTableResourceIdCol, "ResourceId"); |
|
320 |
|
321 // Create the columns for the cached zones table |
|
322 RArray<TDbCol> cachedTableCols; |
|
323 CleanupClosePushL(cachedTableCols); |
|
324 cachedTableCols.AppendL(TDbCol(KCZTableTzIdCol, EDbColUint16)); |
|
325 cachedTableCols.AppendL(TDbCol(KCZTableStdCol, EDbColText)); |
|
326 cachedTableCols.AppendL(TDbCol(KCZTableDSTCol, EDbColText)); |
|
327 cachedTableCols.AppendL(TDbCol(KCZTableShortStdCol, EDbColText)); |
|
328 cachedTableCols.AppendL(TDbCol(KCZTableShortDSTCol, EDbColText)); |
|
329 cachedTableCols.AppendL(TDbCol(KCZTableCityCol, EDbColText)); |
|
330 cachedTableCols.AppendL(TDbCol(KCZTableCityGroupCol, EDbColUint8)); |
|
331 cachedTableCols.AppendL(TDbCol(KCZTableResourceIdCol, EDbColUint32)); |
|
332 // We do not add the city index column as we want to create a database using |
|
333 // the old schema |
|
334 |
|
335 // Create the columnset - add the columns |
|
336 // Columns MUST be added in the same order they appear in TTzZoneColumn |
|
337 CDbColSet* frequentlyUsedTimeZonesColSet = CDbColSet::NewLC(); |
|
338 TInt numCols = cachedTableCols.Count(); |
|
339 for(TInt i = 0; i < numCols; ++i) |
|
340 { |
|
341 frequentlyUsedTimeZonesColSet->AddL(cachedTableCols[i]); |
|
342 } |
|
343 |
|
344 // Create the Cached Time Zone table |
|
345 User::LeaveIfError(aDatabase.CreateTable(KCZTableName, *frequentlyUsedTimeZonesColSet)); |
|
346 |
|
347 //Open the newly created table |
|
348 RDbView zoneView; |
|
349 CleanupClosePushL(zoneView); |
|
350 _LIT(KReadZoneView,"SELECT * FROM FrequentlyUsedZones"); |
|
351 User::LeaveIfError(zoneView.Prepare(aDatabase, TDbQuery(KReadZoneView), zoneView.EUpdatable)); |
|
352 User::LeaveIfError(zoneView.EvaluateAll()); |
|
353 zoneView.Reset(); |
|
354 //Populate with initial (blank) data. |
|
355 |
|
356 _LIT(KEmptyString," "); |
|
357 |
|
358 enum TTzOldSchemaZoneColumn |
|
359 { |
|
360 // Enum will used as a DB column index, so it must start at 1 |
|
361 ETzZoneId = 1, |
|
362 ETzZoneStdName, |
|
363 ETzZoneDSTName, |
|
364 ETzZoneShortStdName, |
|
365 ETzZoneShortDSTName, |
|
366 ETzZoneCity, |
|
367 ETzZoneGroupId, |
|
368 ETzZoneResourceId, |
|
369 }; |
|
370 |
|
371 for (TInt x = 0; x < CTzLocalizedTimeZone::ECachedTimeZones; ++x) |
|
372 { |
|
373 // Insert empty row |
|
374 zoneView.InsertL(); |
|
375 // Fill the table with blank data |
|
376 zoneView.SetColL(ETzZoneId, 0); |
|
377 zoneView.SetColL(ETzZoneStdName, KEmptyString); |
|
378 zoneView.SetColL(ETzZoneDSTName, KEmptyString); |
|
379 zoneView.SetColL(ETzZoneShortStdName, KEmptyString); |
|
380 zoneView.SetColL(ETzZoneShortDSTName, KEmptyString); |
|
381 zoneView.SetColL(ETzZoneCity, KEmptyString); |
|
382 zoneView.SetColL(ETzZoneGroupId, 0); |
|
383 zoneView.SetColL(ETzZoneResourceId, 0); |
|
384 zoneView.PutL(); // Complete insertion |
|
385 } |
|
386 |
|
387 CleanupStack::PopAndDestroy(&zoneView); |
|
388 CleanupStack::PopAndDestroy(frequentlyUsedTimeZonesColSet); |
|
389 CleanupStack::PopAndDestroy(&cachedTableCols); |
|
390 } |
|
391 |
|
392 /** |
|
393 This is a copy/paste of CTzLocalizationDb::CreateUserAddedCitiesTableL() that |
|
394 we can't use as it is not exported. |
|
395 */ |
|
396 void CTzLocalizationDbCreationTests::CreateUserAddedCitiesTableL(RDbNamedDatabase& aDatabase) |
|
397 { |
|
398 //Table and Column names for User Added Cities Table |
|
399 //These text strings are never visible and do not need localizing |
|
400 _LIT(KUCTableName, "UserCities"); |
|
401 _LIT(KUCTableTzId, "TzId"); |
|
402 _LIT(KUCTableCity, "City"); |
|
403 _LIT(KUCTableGroup, "GroupId"); |
|
404 _LIT(KUCTableResourceId, "ResourceId"); |
|
405 |
|
406 //Create the columns for the user aded cities table |
|
407 RArray<TDbCol> cityTableCols; |
|
408 CleanupClosePushL(cityTableCols); |
|
409 cityTableCols.AppendL(TDbCol(KUCTableTzId, EDbColUint16)); |
|
410 cityTableCols.AppendL(TDbCol(KUCTableCity, EDbColText)); |
|
411 cityTableCols.AppendL(TDbCol(KUCTableGroup, EDbColUint8)); |
|
412 cityTableCols.AppendL(TDbCol(KUCTableResourceId, EDbColUint32)); |
|
413 |
|
414 // Create the columnset - add the columns |
|
415 // Columns MUST be added in the same order they appear in TTzCityColumn |
|
416 CDbColSet* userAddedCitiesColSet = CDbColSet::NewLC(); |
|
417 TInt numCols = cityTableCols.Count(); |
|
418 for(TInt i = 0; i < numCols; ++i) |
|
419 { |
|
420 userAddedCitiesColSet->AddL(cityTableCols[i]); |
|
421 } |
|
422 |
|
423 // Create the User City table |
|
424 User::LeaveIfError(aDatabase.CreateTable(KUCTableName, *userAddedCitiesColSet)); |
|
425 |
|
426 CleanupStack::PopAndDestroy(userAddedCitiesColSet); |
|
427 CleanupStack::PopAndDestroy(&cityTableCols); |
|
428 } |
|
429 |
|
430 static void DoTestsL(RTest& aTest) |
|
431 { |
|
432 CTzLocalizationDbCreationTests* tests = CTzLocalizationDbCreationTests::NewLC(aTest); |
|
433 tests->RunL(); |
|
434 CleanupStack::PopAndDestroy(tests); |
|
435 } |
|
436 |
|
437 /** |
|
438 |
|
439 @SYMTestCaseID PIM-APPSERV-tzlocalizationdbcreationtests-0001 |
|
440 |
|
441 */ |
|
442 |
|
443 TInt E32Main() |
|
444 { |
|
445 __UHEAP_MARK; |
|
446 |
|
447 CTrapCleanup* trapCleanup = CTrapCleanup::New(); |
|
448 if(!trapCleanup) |
|
449 { |
|
450 return KErrNoMemory; |
|
451 } |
|
452 |
|
453 CActiveScheduler* scheduler = new CActiveScheduler; |
|
454 if(!scheduler) |
|
455 { |
|
456 return KErrNoMemory; |
|
457 } |
|
458 CActiveScheduler::Install(scheduler); |
|
459 |
|
460 _LIT(KTestName, "t_tzlocalizationdbcreationtests"); |
|
461 RTest test(KTestName); |
|
462 TRAPD(ret, DoTestsL(test)); |
|
463 test.Printf(_L("Trapped return value from DoTestsL(): %d\n"), ret); |
|
464 test(ret == KErrNone); |
|
465 test.Close(); |
|
466 |
|
467 delete scheduler; |
|
468 delete trapCleanup; |
|
469 |
|
470 __UHEAP_MARKEND; |
|
471 |
|
472 return (KErrNone); |
|
473 } |