|
1 /* |
|
2 * Copyright (c) 2005 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * ?description_line |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 // INCLUDES |
|
21 #include "FT_CPosTp50.h" |
|
22 |
|
23 #include <EPos_CPosLandmarkDatabase.h> |
|
24 #include <EPos_CPosLandmark.h> |
|
25 #include <EPos_CPosLandmarkDatabase.h> |
|
26 #include <EPos_CPosLandmarkEncoder.h> |
|
27 #include <EPos_CPosLandmarkParser.h> |
|
28 #include <EPos_CPosLandmarkSearch.h> |
|
29 #include <EPos_CPosLmTextCriteria.h> |
|
30 #include <LbsPosition.h> |
|
31 #include <e32std.h> |
|
32 #include <ss_std.h> |
|
33 |
|
34 |
|
35 const TInt KNoMultipleClients = 5; |
|
36 _LIT(KExportFile, "c:\\TP50-ExportedFile.xml"); |
|
37 |
|
38 _LIT(KAllLandmarks, "c:\\TP50-AllLandmarks.xml"); |
|
39 |
|
40 _LIT(KAllLandmarksIndex, "c:\\TP50-AllLandmarks%d.xml"); |
|
41 |
|
42 // ================= MEMBER FUNCTIONS ======================= |
|
43 |
|
44 // --------------------------------------------------------- |
|
45 // CPosTp50::GetName |
|
46 // |
|
47 // (other items were commented in a header). |
|
48 // --------------------------------------------------------- |
|
49 // |
|
50 void CPosTp50::GetName(TDes& aName) const |
|
51 { |
|
52 _LIT(KTestName, "TP50 - Multiple import operations"); |
|
53 aName = KTestName; |
|
54 } |
|
55 |
|
56 // --------------------------------------------------------- |
|
57 // CPosTp50::CloseTest |
|
58 // |
|
59 // (other items were commented in a header). |
|
60 // --------------------------------------------------------- |
|
61 // |
|
62 void CPosTp50::CloseTest() |
|
63 { |
|
64 for (TInt i=0; i<iThreads.Count(); i++) |
|
65 { |
|
66 iThreads[i].Close(); |
|
67 } |
|
68 |
|
69 iThreads.Close(); |
|
70 |
|
71 delete iDatabase; |
|
72 iDatabase=NULL; |
|
73 |
|
74 iUseLogFromThreadIsDisabled = EFalse; |
|
75 |
|
76 } |
|
77 |
|
78 // --------------------------------------------------------- |
|
79 // CPosTp50::StartL |
|
80 // |
|
81 // (other items were commented in a header). |
|
82 // --------------------------------------------------------- |
|
83 // |
|
84 void CPosTp50::StartL() |
|
85 { |
|
86 MakeSurePanicDebugFileExistsL(); |
|
87 |
|
88 iDatabase = UseGeneratedDbFileL(); |
|
89 if (iDatabase->IsInitializingNeeded()) |
|
90 { |
|
91 ExecuteAndDeleteLD(iDatabase->InitializeL()); |
|
92 } |
|
93 |
|
94 ExportLandmarksL(); |
|
95 |
|
96 delete iDatabase; |
|
97 iDatabase=NULL; |
|
98 |
|
99 // We want an empty database |
|
100 RemoveDefaultDbL(); |
|
101 |
|
102 iDatabase = CPosLandmarkDatabase::OpenL(); |
|
103 |
|
104 if (iDatabase->IsInitializingNeeded()) |
|
105 { |
|
106 ExecuteAndDeleteLD(iDatabase->InitializeL()); |
|
107 } |
|
108 |
|
109 iUseLogFromThreadIsDisabled = ETrue; |
|
110 |
|
111 iLog->Put(_L("Imports landmarks syncronously simultaneously")); |
|
112 iTestStep=0; |
|
113 StartMultipleClientsL(KNoMultipleClients); |
|
114 |
|
115 iLog->Put(_L("Imports landmarks incrementally simultaneously")); |
|
116 ++iTestStep; |
|
117 StartMultipleClientsL(KNoMultipleClients); |
|
118 |
|
119 iLog->Put(_L("A search is started but no step is executed")); |
|
120 ++iTestStep; |
|
121 |
|
122 CPosLmTextCriteria* textCriteria = CPosLmTextCriteria::NewLC(); |
|
123 textCriteria->SetTextL(_L("kalle")); |
|
124 |
|
125 CPosLandmarkSearch* landmarkSearch = CPosLandmarkSearch::NewL(*iDatabase); |
|
126 CleanupStack::PushL(landmarkSearch); |
|
127 |
|
128 CPosLmOperation* op = landmarkSearch->StartLandmarkSearchL(*textCriteria); |
|
129 CleanupStack::PushL(op); |
|
130 |
|
131 iLog->Put(_L("Imports landmarks syncronously simultaneously (all should fail)")); |
|
132 StartMultipleClientsL(KNoMultipleClients); |
|
133 |
|
134 iLog->Put(_L("The search is cancelled")); |
|
135 CleanupStack::PopAndDestroy(op); |
|
136 |
|
137 iLog->Put(_L("Imports landmarks syncronously simultaneously (at least one should succed)")); |
|
138 ++iTestStep; |
|
139 StartMultipleClientsL(KNoMultipleClients); |
|
140 |
|
141 CleanupStack::PopAndDestroy(2, textCriteria); |
|
142 |
|
143 TestESLI_64LLU3L(); |
|
144 } |
|
145 |
|
146 // --------------------------------------------------------- |
|
147 // CPosTp50::StartMultipleClientsL |
|
148 // |
|
149 // (other items were commented in a header). |
|
150 // --------------------------------------------------------- |
|
151 // |
|
152 void CPosTp50::StartMultipleClientsL(const TUint aNoClients) |
|
153 { |
|
154 _LIT(KMultipleErr, "Error %d from thread %d"); |
|
155 _LIT(KPanicErr, "Thread %d has panicked or is alive"); |
|
156 _LIT(KAllErr, "Wrong number of threads left with error"); |
|
157 _LIT(KSuccess, "Threads %d is successful"); |
|
158 _LIT(KAllNotFailedErr, "All imports haven't failed"); |
|
159 |
|
160 CreateThreadsL(aNoClients); |
|
161 |
|
162 RArray<TRequestStatus> statuses; |
|
163 CleanupClosePushL(statuses); |
|
164 |
|
165 for (TUint j=0; j<aNoClients; j++) |
|
166 { |
|
167 TRequestStatus status; |
|
168 statuses.Append(status); |
|
169 } |
|
170 |
|
171 TInt i=0; |
|
172 for (i=0; i<iThreads.Count(); i++) |
|
173 { |
|
174 iThreads[i].Logon(statuses[i]); |
|
175 iThreads[i].Resume(); |
|
176 } |
|
177 |
|
178 for (i=0; i<iThreads.Count(); i++) |
|
179 { |
|
180 User::WaitForRequest(statuses[i]); |
|
181 } |
|
182 |
|
183 TInt errors=0; |
|
184 for (i=0; i<iThreads.Count(); i++) |
|
185 { |
|
186 TInt exitReason = iThreads[i].ExitReason(); |
|
187 TBuf<100> info; |
|
188 |
|
189 if (exitReason != KErrNone) |
|
190 { |
|
191 errors++; |
|
192 info.Format(KMultipleErr, exitReason, i+1); |
|
193 } |
|
194 else |
|
195 { |
|
196 info.Format(KSuccess, i+1); |
|
197 } |
|
198 iLog->Put(info); |
|
199 |
|
200 AssertTrueSecL(iThreads[i].ExitType() == EExitKill, KPanicErr, i+1); |
|
201 AssertTrueSecL(exitReason == KErrNone || exitReason == KErrLocked, info); |
|
202 } |
|
203 |
|
204 if (iTestStep != EReadLockTaken) |
|
205 { |
|
206 AssertTrueSecL(errors == KNoMultipleClients - 1, KAllErr); |
|
207 } |
|
208 else |
|
209 { |
|
210 // All imports should have failed since the started search should have taken a read lock |
|
211 AssertTrueSecL(errors == KNoMultipleClients, KAllNotFailedErr); |
|
212 } |
|
213 |
|
214 for (i=0; i<iThreads.Count(); i++) |
|
215 { |
|
216 iThreads[i].Close(); |
|
217 } |
|
218 |
|
219 iThreadIndex=0; |
|
220 iThreads.Close(); |
|
221 CleanupStack::PopAndDestroy(&statuses); |
|
222 } |
|
223 |
|
224 // --------------------------------------------------------- |
|
225 // CPosTp50::RunTestL |
|
226 // |
|
227 // (other items were commented in a header). |
|
228 // --------------------------------------------------------- |
|
229 // |
|
230 void CPosTp50::RunTestL(TAny* aData) |
|
231 { |
|
232 CPosTp50* self = reinterpret_cast<CPosTp50*>(aData); |
|
233 TInt index = ++self->iThreadIndex; |
|
234 |
|
235 CPosLandmarkDatabase* lmd = CPosLandmarkDatabase::OpenL(); |
|
236 CleanupStack::PushL(lmd); |
|
237 |
|
238 if (lmd->IsInitializingNeeded()) |
|
239 { |
|
240 ExecuteAndDeleteLD(lmd->InitializeL()); |
|
241 } |
|
242 |
|
243 CPosLandmarkParser* parser = CPosLandmarkParser::NewL(KMimeType); |
|
244 CleanupStack::PushL(parser); |
|
245 |
|
246 |
|
247 TBuf<100> fileName; |
|
248 fileName.Format(KAllLandmarksIndex, index); |
|
249 |
|
250 parser->SetInputFileL(fileName); |
|
251 |
|
252 _LIT(KInfo, "Thread %d"); |
|
253 TBuf<100> info; |
|
254 info.Format(KInfo, index); |
|
255 RDebug::Print(info); |
|
256 |
|
257 CPosLmOperation* op = lmd->ImportLandmarksL(*parser, CPosLandmarkDatabase::EDefaultOptions); |
|
258 |
|
259 _LIT(KInfo2, "Thread %d before execute"); |
|
260 info.Format(KInfo2, index); |
|
261 RDebug::Print(info); |
|
262 |
|
263 switch (self->iTestStep) |
|
264 { |
|
265 //case self->ESync: |
|
266 case ESync: |
|
267 //case self->EReadLockTaken: |
|
268 case EReadLockTaken: |
|
269 //case self->ESearchCancelled: |
|
270 case ESearchCancelled: |
|
271 CleanupStack::PushL(op); |
|
272 op->ExecuteL(); |
|
273 CleanupStack::PopAndDestroy(op); |
|
274 break; |
|
275 //case self->EInc: |
|
276 case EInc: |
|
277 self->RunAsyncOperationLD(op); |
|
278 break; |
|
279 } |
|
280 |
|
281 _LIT(KInfo3, "Thread %d after execute"); |
|
282 info.Format(KInfo3, index); |
|
283 RDebug::Print(info); |
|
284 |
|
285 CleanupStack::PopAndDestroy(parser); |
|
286 CleanupStack::PopAndDestroy(lmd); |
|
287 } |
|
288 |
|
289 |
|
290 // --------------------------------------------------------- |
|
291 // ThreadFunction |
|
292 // |
|
293 // (other items were commented in a header). |
|
294 // --------------------------------------------------------- |
|
295 // |
|
296 LOCAL_C TInt ThreadFunction(TAny* aData) |
|
297 { |
|
298 CTrapCleanup* cleanup=CTrapCleanup::New(); |
|
299 |
|
300 CActiveScheduler* actSch = new (ELeave) CActiveScheduler; |
|
301 CActiveScheduler::Install(actSch); |
|
302 |
|
303 TRAPD(err, CPosTp50::RunTestL(aData)); |
|
304 |
|
305 delete actSch; |
|
306 delete cleanup; |
|
307 return err; |
|
308 } |
|
309 |
|
310 // --------------------------------------------------------- |
|
311 // CPosTp50::CreateThreadsL |
|
312 // |
|
313 // (other items were commented in a header). |
|
314 // --------------------------------------------------------- |
|
315 // |
|
316 void CPosTp50::CreateThreadsL(const TUint aNoThreads) |
|
317 { |
|
318 _LIT(KThreadName, "TP50 test thread%d"); |
|
319 _LIT(KCreateThreadErr, "Create thread failed with %d"); |
|
320 |
|
321 for (TUint i=0; i<aNoThreads; i++) |
|
322 { |
|
323 RThread thread; |
|
324 TBuf<32> name; |
|
325 name.Format(KThreadName, 1+iThreads.Count()); |
|
326 |
|
327 TInt err; |
|
328 err = thread.Create(name, ThreadFunction, KDefaultStackSize, KMinHeapSize, KMaxHeapSize, reinterpret_cast<TAny*>(this)); |
|
329 |
|
330 AssertTrueSecL(err == KErrNone, KCreateThreadErr, err); |
|
331 |
|
332 iThreads.Append(thread); |
|
333 } |
|
334 } |
|
335 |
|
336 // --------------------------------------------------------- |
|
337 // CPosTp50::ExportAllLandmarksL |
|
338 // |
|
339 // (other items were commented in a header). |
|
340 // --------------------------------------------------------- |
|
341 // |
|
342 void CPosTp50::ExportLandmarksL() |
|
343 { |
|
344 RFs fs; |
|
345 User::LeaveIfError(fs.Connect()); |
|
346 CleanupClosePushL(fs); |
|
347 |
|
348 fs.Delete(KAllLandmarks); |
|
349 |
|
350 CPosLmItemIterator* iter = iDatabase->LandmarkIteratorL(); |
|
351 CleanupStack::PushL(iter); |
|
352 |
|
353 RArray<TPosLmItemId> arrayOfIds; |
|
354 CleanupClosePushL(arrayOfIds); |
|
355 |
|
356 TInt numberOfElements = iter->NumOfItemsL(); |
|
357 iter->GetItemIdsL(arrayOfIds, 0, (numberOfElements)); |
|
358 |
|
359 CPosLandmarkEncoder* encoder = CPosLandmarkEncoder::NewL(KMimeType); |
|
360 CleanupStack::PushL(encoder); |
|
361 |
|
362 encoder->SetOutputFileL(KAllLandmarks); |
|
363 |
|
364 CPosLmOperation* op = iDatabase->ExportLandmarksL(*encoder, arrayOfIds, CPosLandmarkDatabase::EDefaultOptions); |
|
365 CleanupStack::PushL(op); |
|
366 op->ExecuteL(); |
|
367 CleanupStack::PopAndDestroy(op); |
|
368 |
|
369 op = encoder->FinalizeEncodingL(); |
|
370 CleanupStack::PushL(op); |
|
371 op->ExecuteL(); |
|
372 |
|
373 // Create a file to be used from each thread |
|
374 CFileMan* fileMan = CFileMan::NewL(fs); |
|
375 CleanupStack::PushL(fileMan); |
|
376 |
|
377 for (TInt i=0; i<KNoMultipleClients; i++) |
|
378 { |
|
379 TBuf<100> fileName; |
|
380 fileName.Format(KAllLandmarksIndex, i+1); |
|
381 fs.Delete(fileName); |
|
382 |
|
383 User::LeaveIfError(fileMan->Copy(KAllLandmarks, fileName, CFileMan::EOverWrite)); |
|
384 } |
|
385 |
|
386 CleanupStack::PopAndDestroy(6, &fs); |
|
387 } |
|
388 |
|
389 // --------------------------------------------------------- |
|
390 // CPosTp50::TestESLI_64LLU3L |
|
391 // ESLI-64LLU3 - read/write lock only affects the same database instance. |
|
392 // |
|
393 // (other items were commented in a header). |
|
394 // --------------------------------------------------------- |
|
395 // |
|
396 void CPosTp50::TestESLI_64LLU3L() |
|
397 { |
|
398 RFs fs; |
|
399 User::LeaveIfError(fs.Connect()); |
|
400 fs.Delete(KExportFile); |
|
401 fs.Close(); |
|
402 |
|
403 // Create encoder that will take read lock |
|
404 CPosLandmarkEncoder* encoder = CPosLandmarkEncoder::NewL(KMimeType); |
|
405 CleanupStack::PushL(encoder); |
|
406 encoder->SetOutputFileL(KExportFile); |
|
407 |
|
408 // Create another db handle |
|
409 CPosLandmarkDatabase* lmd = CPosLandmarkDatabase::OpenL(); |
|
410 CleanupStack::PushL(lmd); |
|
411 if (lmd->IsInitializingNeeded()) |
|
412 { |
|
413 ExecuteAndDeleteLD(lmd->InitializeL()); |
|
414 } |
|
415 |
|
416 // Create array of ids to export |
|
417 RArray<TPosLmItemId> arrayOfIds; |
|
418 CleanupClosePushL(arrayOfIds); |
|
419 User::LeaveIfError(arrayOfIds.Append(1)); |
|
420 User::LeaveIfError(arrayOfIds.Append(2)); |
|
421 User::LeaveIfError(arrayOfIds.Append(3)); |
|
422 |
|
423 // Take read lock by starting exporting |
|
424 CPosLmOperation* op = lmd->ExportLandmarksL(*encoder, arrayOfIds, CPosLandmarkDatabase::EDefaultOptions); |
|
425 CleanupStack::PushL(op); |
|
426 |
|
427 // Verify take write lock fails on db instance 2 |
|
428 TRAPD(err, lmd->RemoveLandmarkL(1)); |
|
429 AssertTrueSecL(err == KErrLocked, _L("Didn't get KErrLocked but %d"), err); |
|
430 |
|
431 // Verify take write lock fails on db instance 1 |
|
432 TRAP(err, iDatabase->RemoveLandmarkL(1)); |
|
433 AssertTrueSecL(err == KErrLocked, _L("Didn't get KErrLocked but %d"), err); |
|
434 |
|
435 // Lock should prevent import threads to complete successfully |
|
436 iTestStep = EReadLockTaken; |
|
437 StartMultipleClientsL(KNoMultipleClients); |
|
438 |
|
439 // Release lock - import threads should complete successfully |
|
440 CleanupStack::PopAndDestroy(op); |
|
441 iTestStep = ESync; |
|
442 StartMultipleClientsL(KNoMultipleClients); |
|
443 |
|
444 CleanupStack::PopAndDestroy(&arrayOfIds); |
|
445 CleanupStack::PopAndDestroy(lmd); |
|
446 CleanupStack::PopAndDestroy(encoder); |
|
447 } |
|
448 |
|
449 // End of File |