|
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_CPosTp46.h" |
|
22 |
|
23 #include <EPos_CPosLandmarkDatabase.h> |
|
24 #include <EPos_CPosLandmarkDatabase.h> |
|
25 #include <EPos_CPosLandmarkEncoder.h> |
|
26 #include <EPos_CPosLandmarkParser.h> |
|
27 |
|
28 |
|
29 |
|
30 #include <LbsPosition.h> |
|
31 #include <e32std.h> |
|
32 #include <ss_std.h> |
|
33 |
|
34 const TInt KNoMultipleClients = 10; |
|
35 _LIT(KExportFileIndex, "c:\\TP46-ExportedFileFromThread%d.xml"); |
|
36 |
|
37 #ifdef __WINS__ |
|
38 _LIT(KImportFile, "z:\\system\\test\\testdata\\TP45-DefOptions.xml"); |
|
39 #else |
|
40 _LIT(KImportFile, "c:\\system\\test\\testdata\\TP45-DefOptions.xml"); |
|
41 #endif |
|
42 |
|
43 // ================= MEMBER FUNCTIONS ======================= |
|
44 |
|
45 // --------------------------------------------------------- |
|
46 // CPosTp46::GetName |
|
47 // |
|
48 // (other items were commented in a header). |
|
49 // --------------------------------------------------------- |
|
50 // |
|
51 void CPosTp46::GetName(TDes& aName) const |
|
52 { |
|
53 _LIT(KTestName, "TP46 - Multiple export operations"); |
|
54 aName = KTestName; |
|
55 } |
|
56 |
|
57 // --------------------------------------------------------- |
|
58 // CPosTp46::CloseTest |
|
59 // |
|
60 // (other items were commented in a header). |
|
61 // --------------------------------------------------------- |
|
62 // |
|
63 void CPosTp46::CloseTest() |
|
64 { |
|
65 for (TInt i=0; i<iThreads.Count(); i++) |
|
66 { |
|
67 iThreads[i].Close(); |
|
68 } |
|
69 |
|
70 iThreads.Close(); |
|
71 |
|
72 delete iDatabase; |
|
73 iDatabase=NULL; |
|
74 |
|
75 iUseLogFromThreadIsDisabled = EFalse; |
|
76 |
|
77 } |
|
78 |
|
79 // --------------------------------------------------------- |
|
80 // CPosTp46::StartL |
|
81 // |
|
82 // (other items were commented in a header). |
|
83 // --------------------------------------------------------- |
|
84 // |
|
85 void CPosTp46::StartL() |
|
86 { |
|
87 // Make sure no logging from thread (causes crash) |
|
88 iUseLogFromThreadIsDisabled = ETrue; |
|
89 |
|
90 MakeSurePanicDebugFileExistsL(); |
|
91 |
|
92 iDatabase = UseGeneratedDbFileL(); |
|
93 if (iDatabase->IsInitializingNeeded()) |
|
94 { |
|
95 ExecuteAndDeleteLD(iDatabase->InitializeL()); |
|
96 } |
|
97 |
|
98 RemoveFilesL(); |
|
99 |
|
100 iLog->Put(_L("Export landmarks syncronously simultaneously")); |
|
101 iTestStep=0; |
|
102 StartMultipleClientsL(KNoMultipleClients); |
|
103 |
|
104 iLog->Put(_L("Export landmarks incrementally simultaneously")); |
|
105 ++iTestStep; |
|
106 RemoveFilesL(); |
|
107 StartMultipleClientsL(KNoMultipleClients); |
|
108 |
|
109 iLog->Put(_L("Export landmarks after import operation has taken write lock")); |
|
110 ++iTestStep; |
|
111 RemoveFilesL(); |
|
112 CPosLandmarkParser* parser = CPosLandmarkParser::NewL(KMimeType); |
|
113 CleanupStack::PushL(parser); |
|
114 parser->SetInputFileL(KImportFile); |
|
115 // Take write lock |
|
116 CPosLmOperation* op = iDatabase->ImportLandmarksL(*parser, CPosLandmarkDatabase::EDefaultOptions); |
|
117 CleanupStack::PushL(op); |
|
118 // Try to export |
|
119 StartMultipleClientsL(KNoMultipleClients); |
|
120 CleanupStack::PopAndDestroy(2, parser); |
|
121 |
|
122 // ESLI-64LLU3 - read/write lock only affects the same database instance. |
|
123 parser = CPosLandmarkParser::NewL(KMimeType); |
|
124 CleanupStack::PushL(parser); |
|
125 parser->SetInputFileL(KImportFile); |
|
126 |
|
127 CPosLandmarkDatabase* lmd = CPosLandmarkDatabase::OpenL(); |
|
128 CleanupStack::PushL(lmd); |
|
129 |
|
130 if (lmd->IsInitializingNeeded()) |
|
131 { |
|
132 ExecuteAndDeleteLD(lmd->InitializeL()); |
|
133 } |
|
134 |
|
135 op = iDatabase->ImportLandmarksL(*parser, CPosLandmarkDatabase::EDefaultOptions); |
|
136 CleanupStack::PushL(op); |
|
137 |
|
138 TRAPD(err, CleanupStack::PopAndDestroy(lmd->ReadLandmarkLC(1))); |
|
139 AssertTrueSecL(err == KErrLocked, _L("Didn't get KErrLocked but %d"), err); |
|
140 |
|
141 TRAP(err, CleanupStack::PopAndDestroy(iDatabase->ReadLandmarkLC(1))); |
|
142 AssertTrueSecL(err == KErrLocked, _L("Didn't get KErrLocked but %d"), err); |
|
143 |
|
144 // Lock should prevent export threads to complete successfully |
|
145 StartMultipleClientsL(KNoMultipleClients); |
|
146 |
|
147 // Release lock - export threads should complete successfully |
|
148 CleanupStack::PopAndDestroy(op); |
|
149 iTestStep = ESync; |
|
150 StartMultipleClientsL(KNoMultipleClients); |
|
151 |
|
152 CleanupStack::PopAndDestroy(lmd); |
|
153 CleanupStack::PopAndDestroy(parser); |
|
154 } |
|
155 |
|
156 // --------------------------------------------------------- |
|
157 // CPosTp46::RemoveFiles |
|
158 // |
|
159 // (other items were commented in a header). |
|
160 // --------------------------------------------------------- |
|
161 // |
|
162 void CPosTp46::RemoveFilesL() |
|
163 { |
|
164 RFs fs; |
|
165 User::LeaveIfError(fs.Connect()); |
|
166 for (TInt i=1; i <= KNoMultipleClients; i++) |
|
167 { |
|
168 TBuf<100> fileName; |
|
169 fileName.Format(KExportFileIndex, i); |
|
170 fs.Delete(fileName); |
|
171 } |
|
172 fs.Close(); |
|
173 } |
|
174 |
|
175 // --------------------------------------------------------- |
|
176 // CPosTp46::StartMultipleClientsL |
|
177 // |
|
178 // (other items were commented in a header). |
|
179 // --------------------------------------------------------- |
|
180 // |
|
181 void CPosTp46::StartMultipleClientsL(const TUint aNoClients) |
|
182 { |
|
183 _LIT(KMultipleErr, "Error %d from thread %d"); |
|
184 _LIT(KPanicErr, "Thread %d has panicked or is alive"); |
|
185 |
|
186 _LIT(KSuccess, "Threads %d is successful"); |
|
187 |
|
188 CreateThreadsL(aNoClients); |
|
189 |
|
190 RArray<TRequestStatus> statuses; |
|
191 CleanupClosePushL(statuses); |
|
192 |
|
193 for (TUint j=0; j<aNoClients; j++) |
|
194 { |
|
195 TRequestStatus status; |
|
196 statuses.Append(status); |
|
197 } |
|
198 |
|
199 TUint i=0; |
|
200 for (i=0; i<aNoClients; i++) |
|
201 { |
|
202 iThreads[i].Logon(statuses[i]); |
|
203 iThreads[i].Resume(); |
|
204 } |
|
205 |
|
206 for (i=0; i<aNoClients; i++) |
|
207 { |
|
208 User::WaitForRequest(statuses[i]); |
|
209 } |
|
210 |
|
211 TUint errors=0; |
|
212 for (i=0; i<aNoClients; i++) |
|
213 { |
|
214 TInt exitReason = iThreads[i].ExitReason(); |
|
215 TBuf<100> info; |
|
216 |
|
217 if (exitReason != KErrNone) |
|
218 { |
|
219 errors++; |
|
220 info.Format(KMultipleErr, exitReason, i+1); |
|
221 } |
|
222 else |
|
223 { |
|
224 info.Format(KSuccess, i+1); |
|
225 } |
|
226 iLog->Put(info); |
|
227 |
|
228 AssertTrueSecL(iThreads[i].ExitType() == EExitKill, KPanicErr, i+1); |
|
229 AssertTrueSecL(exitReason == KErrNone || exitReason == KErrLocked, info); |
|
230 } |
|
231 |
|
232 if (iTestStep != EImportStarted) |
|
233 { |
|
234 AssertTrueSecL(errors == 0, _L("No thread should leave with error, all should be able to read from the db")); |
|
235 } |
|
236 else |
|
237 { |
|
238 AssertTrueSecL(errors == aNoClients, _L("All threads should leave with error, none should be able to read from the db")); |
|
239 } |
|
240 |
|
241 |
|
242 for (i=0; i<aNoClients; i++) |
|
243 { |
|
244 iThreads[i].Close(); |
|
245 } |
|
246 |
|
247 iThreadIndex=0; |
|
248 iThreads.Close(); |
|
249 CleanupStack::PopAndDestroy(&statuses); |
|
250 } |
|
251 |
|
252 // --------------------------------------------------------- |
|
253 // CPosTp46::RunTestL |
|
254 // |
|
255 // (other items were commented in a header). |
|
256 // --------------------------------------------------------- |
|
257 // |
|
258 void CPosTp46::RunTestL(TAny* aData) |
|
259 { |
|
260 CPosTp46* self = reinterpret_cast<CPosTp46*>(aData); |
|
261 TInt index = ++self->iThreadIndex; |
|
262 |
|
263 CPosLandmarkDatabase* lmd = CPosLandmarkDatabase::OpenL(); |
|
264 CleanupStack::PushL(lmd); |
|
265 |
|
266 if (lmd->IsInitializingNeeded()) |
|
267 { |
|
268 ExecuteAndDeleteLD(lmd->InitializeL()); |
|
269 } |
|
270 /* |
|
271 _LIT(KInfo, "Thread %d"); |
|
272 TBuf<100> info; |
|
273 info.Format(KInfo, index); |
|
274 RDebug::Print(info); |
|
275 */ |
|
276 |
|
277 CPosLandmarkEncoder* encoder = CPosLandmarkEncoder::NewL(KMimeType); |
|
278 CleanupStack::PushL(encoder); |
|
279 |
|
280 CPosLmItemIterator* iter = lmd->LandmarkIteratorL(); |
|
281 CleanupStack::PushL(iter); |
|
282 |
|
283 RArray<TPosLmItemId> arrayOfIds; |
|
284 CleanupClosePushL(arrayOfIds); |
|
285 |
|
286 TInt numberOfElements = iter->NumOfItemsL(); |
|
287 iter->GetItemIdsL(arrayOfIds, 0, (numberOfElements)); |
|
288 |
|
289 TBuf<100> fileName; |
|
290 fileName.Format(KExportFileIndex, index); |
|
291 encoder->SetOutputFileL(fileName); |
|
292 |
|
293 switch (self->iTestStep) |
|
294 { |
|
295 //case self->ESync: |
|
296 case 0: |
|
297 //case self->EImportStarted: |
|
298 case 2: |
|
299 { |
|
300 CPosLmOperation* op = lmd->ExportLandmarksL(*encoder, arrayOfIds, CPosLandmarkDatabase::EIncludeCategories); |
|
301 |
|
302 CleanupStack::PushL(op); |
|
303 op->ExecuteL(); |
|
304 CleanupStack::PopAndDestroy(op); |
|
305 |
|
306 op = encoder->FinalizeEncodingL(); |
|
307 CleanupStack::PushL(op); |
|
308 op->ExecuteL(); |
|
309 CleanupStack::PopAndDestroy(op); |
|
310 break; |
|
311 } |
|
312 //case self->EInc: |
|
313 case 1: |
|
314 { |
|
315 CPosLmOperation* op2 = lmd->ExportLandmarksL(*encoder, arrayOfIds, CPosLandmarkDatabase::EIncludeCategories); |
|
316 self->RunAsyncOperationLD(op2); |
|
317 |
|
318 op2 = encoder->FinalizeEncodingL(); |
|
319 self->RunAsyncOperationLD(op2); |
|
320 break; |
|
321 } |
|
322 } |
|
323 /* |
|
324 _LIT(KInfo3, "Thread %d after execute"); |
|
325 info.Format(KInfo3, index); |
|
326 RDebug::Print(info); |
|
327 */ |
|
328 CleanupStack::PopAndDestroy(4, lmd); |
|
329 } |
|
330 |
|
331 |
|
332 // --------------------------------------------------------- |
|
333 // ThreadFunction |
|
334 // |
|
335 // (other items were commented in a header). |
|
336 // --------------------------------------------------------- |
|
337 // |
|
338 LOCAL_C TInt ThreadFunction(TAny* aData) |
|
339 { |
|
340 CTrapCleanup* cleanup=CTrapCleanup::New(); |
|
341 |
|
342 CActiveScheduler* actSch = new (ELeave) CActiveScheduler; |
|
343 CActiveScheduler::Install(actSch); |
|
344 |
|
345 TRAPD(err, CPosTp46::RunTestL(aData)); |
|
346 |
|
347 delete actSch; |
|
348 delete cleanup; |
|
349 return err; |
|
350 } |
|
351 |
|
352 // --------------------------------------------------------- |
|
353 // CPosTp46::CreateThreadsL |
|
354 // |
|
355 // (other items were commented in a header). |
|
356 // --------------------------------------------------------- |
|
357 // |
|
358 void CPosTp46::CreateThreadsL(const TUint aNoThreads) |
|
359 { |
|
360 _LIT(KThreadName, "TP46 test thread%d"); |
|
361 _LIT(KCreateThreadErr, "Create thread failed with %d"); |
|
362 |
|
363 for (TUint i=0; i<aNoThreads; i++) |
|
364 { |
|
365 RThread thread; |
|
366 TBuf<32> name; |
|
367 name.Format(KThreadName, 1+iThreads.Count()); |
|
368 |
|
369 TInt err; |
|
370 err = thread.Create(name, ThreadFunction, KDefaultStackSize, KMinHeapSize, KMaxHeapSize, reinterpret_cast<TAny*>(this)); |
|
371 |
|
372 AssertTrueSecL(err == KErrNone, KCreateThreadErr, err); |
|
373 |
|
374 iThreads.Append(thread); |
|
375 } |
|
376 } |
|
377 |
|
378 // End of File |