|
1 // Copyright (c) 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 // Test wrapper for unit tests of the sELF lib |
|
15 |
|
16 /** |
|
17 * @file CSELFLibWrapper.cpp |
|
18 * @internalTechnology |
|
19 */ |
|
20 |
|
21 #include <f32file.h> |
|
22 #include <bautils.h> |
|
23 |
|
24 #include "CSELFLibWrapper.h" |
|
25 |
|
26 CSELFLibWrapper::CSELFLibWrapper() |
|
27 {} |
|
28 |
|
29 CSELFLibWrapper::~CSELFLibWrapper() |
|
30 { |
|
31 iFs.Close(); |
|
32 } |
|
33 |
|
34 /** |
|
35 * Two phase constructor for CFlashDataSourceWrapper |
|
36 * @return CFlashDataSourceWrapper object |
|
37 * @leave |
|
38 */ |
|
39 CSELFLibWrapper* CSELFLibWrapper::NewL() |
|
40 { |
|
41 CSELFLibWrapper* ret = new (ELeave) CSELFLibWrapper(); |
|
42 CleanupStack::PushL(ret); |
|
43 ret->ConstructL(); |
|
44 CleanupStack::Pop(ret); |
|
45 return ret; |
|
46 } |
|
47 |
|
48 /** |
|
49 * Safe construction |
|
50 * @leave |
|
51 */ |
|
52 void CSELFLibWrapper::ConstructL() |
|
53 { |
|
54 User::LeaveIfError(iFs.Connect()); |
|
55 } |
|
56 |
|
57 /** |
|
58 * Process command to see what test to run |
|
59 */ |
|
60 TBool CSELFLibWrapper::DoCommandL(const TTEFFunction& aCommand, const TTEFSectionName& aSection, const TInt aAsyncErrorIndex) |
|
61 { |
|
62 __UHEAP_MARK; |
|
63 |
|
64 (void)aSection; |
|
65 (void)aAsyncErrorIndex; |
|
66 |
|
67 RBuf8 name; |
|
68 name.CreateL(aCommand.Length()); |
|
69 name.Copy(aCommand); |
|
70 RDebug::Printf("\nNext Test Case... [%S]", &name); |
|
71 name.Close(); |
|
72 |
|
73 if(KSELFNewL() == aCommand) |
|
74 TestNewL_L(); |
|
75 else if(KSELFNewLC() == aCommand) |
|
76 TestNewLC_L(); |
|
77 else if(KSELF_InvalidSignature() == aCommand) |
|
78 TestConstruction_InvalidELF_SignatureL(); |
|
79 else if(KSELF_InvalidSize() == aCommand) |
|
80 TestConstruction_InvalidELF_SizeL(); |
|
81 else if(KSELF_NotSupported() == aCommand) |
|
82 TestConstruction_ValidELF_NotSupported(); |
|
83 else if(KSELF_TestConstruction_Inuse() == aCommand) |
|
84 TestConstruction_Inuse(); |
|
85 else if(KSELF_GetElfHeaderL() == aCommand) |
|
86 TestGetElfHeaderL(); |
|
87 else if(KSELF_InsertVariantSpecificData() == aCommand) |
|
88 TestInsertDataL(); |
|
89 else if(KSELF_InsertMultipleVariants() == aCommand) |
|
90 TestMultipleInsertionL(); |
|
91 else if(KSELF_InsertNothingAndUpdate() == aCommand) |
|
92 TestInsertNothingL(); |
|
93 else if(KSELF_TestPerformance() == aCommand) |
|
94 TestPerformanceL(); |
|
95 else if(KSELF_TestStress() == aCommand) |
|
96 TestStressL(); |
|
97 else if(KPrepareFiles() == aCommand) |
|
98 CopyFilesToWritablePlaceL(); |
|
99 else if(KTearDownFiles() == aCommand) |
|
100 TearDownFilesL(); |
|
101 |
|
102 __UHEAP_MARKEND; |
|
103 |
|
104 return ETrue; |
|
105 } |
|
106 |
|
107 /** |
|
108 * Unit test for: |
|
109 * CSELFEditor* CSELFEditor::NewL() |
|
110 * @see CSELFEditor |
|
111 */ |
|
112 void CSELFLibWrapper::TestNewL_L() |
|
113 { |
|
114 INFO_PRINTF1(_L("Testing CSELFEditor::NewL")); |
|
115 |
|
116 //Try a file we know does not exist |
|
117 CSELFEditor* editor = NULL; |
|
118 TRAPD(err, editor = CSELFEditor::NewL(KSELFFileNameNonExistant())); |
|
119 |
|
120 INFO_PRINTF3(_L("CSELFEditor::NewL(%S) returns [%d]"), &KSELFFileNameNonExistant, err); |
|
121 |
|
122 T_SELFLIB_ASSERT_TRUE(KErrNotFound == err, 0); |
|
123 T_SELFLIB_ASSERT_TRUE(editor == NULL, 0); |
|
124 |
|
125 //Try a file we know does exist |
|
126 TRAP(err, editor = CSELFEditor::NewL(KSELFFileName())); |
|
127 |
|
128 INFO_PRINTF3(_L("CSELFEditor::NewL(%S) returns [%d]"), &KSELFFileName, err); |
|
129 |
|
130 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 0); |
|
131 T_SELFLIB_ASSERT_TRUE(editor != NULL, 0); |
|
132 |
|
133 delete editor; |
|
134 editor = NULL; |
|
135 |
|
136 #ifdef _DEBUG //__UHEAP_FAILNEXT won't work on urel |
|
137 |
|
138 //Try with an allocation fail |
|
139 __UHEAP_FAILNEXT(1); |
|
140 TRAP(err, editor = CSELFEditor::NewL(KSELFFileName())); |
|
141 |
|
142 INFO_PRINTF3(_L("CSELFEditor::NewL(%S) returns [%d] (with __UHEAP_FAILNEXT)"), &KSELFFileName, err); |
|
143 |
|
144 T_SELFLIB_ASSERT_TRUE(KErrNoMemory == err, 0); |
|
145 T_SELFLIB_ASSERT_TRUE(editor == NULL, 0); |
|
146 |
|
147 #endif |
|
148 } |
|
149 |
|
150 /** |
|
151 * Unit test for: |
|
152 * CSELFEditor* CSELFEditor::NewLC() |
|
153 * @see CSELFEditor |
|
154 */ |
|
155 void CSELFLibWrapper::TestNewLC_L() |
|
156 { |
|
157 INFO_PRINTF1(_L("Testing CSELFEditor::NewLC")); |
|
158 |
|
159 //Try a file we know does not exist |
|
160 CSELFEditor* editor = NULL; |
|
161 TRAPD(err, editor = CSELFEditor::NewLC(KSELFFileNameNonExistant()); CleanupStack::Pop();); |
|
162 |
|
163 INFO_PRINTF3(_L("CSELFEditor::NewLC(%S) returns [%d]"), &KSELFFileNameNonExistant, err); |
|
164 |
|
165 T_SELFLIB_ASSERT_TRUE(KErrNotFound == err, 0); |
|
166 T_SELFLIB_ASSERT_TRUE(editor == NULL, 0); |
|
167 |
|
168 //Try a file we know does exist |
|
169 TRAP(err, editor = CSELFEditor::NewLC(KSELFFileName()); CleanupStack::Pop();); |
|
170 |
|
171 INFO_PRINTF3(_L("CSELFEditor::NewLC(%S) returns [%d]"), &KSELFFileName, err); |
|
172 |
|
173 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 0); |
|
174 T_SELFLIB_ASSERT_TRUE(editor != NULL, 0); |
|
175 |
|
176 delete editor; |
|
177 editor = NULL; |
|
178 |
|
179 #ifdef _DEBUG //__UHEAP_FAILNEXT won't work on urel |
|
180 |
|
181 //Try with an allocation fail |
|
182 __UHEAP_FAILNEXT(1); |
|
183 TRAP(err, editor = CSELFEditor::NewLC(KSELFFileName()); CleanupStack::Pop()); |
|
184 |
|
185 INFO_PRINTF3(_L("CSELFEditor::NewLC(%S) returns [%d] (with __UHEAP_FAILNEXT)"), &KSELFFileName, err); |
|
186 |
|
187 T_SELFLIB_ASSERT_TRUE(KErrNoMemory == err, 0); |
|
188 T_SELFLIB_ASSERT_TRUE(editor == NULL, 0); |
|
189 |
|
190 #endif |
|
191 } |
|
192 |
|
193 /** |
|
194 * Unit test for: |
|
195 * CSELFEditor::InsertVariantSpecificDataL() |
|
196 * @see CSELFEditor |
|
197 */ |
|
198 void CSELFLibWrapper::TestInsertDataL() |
|
199 { |
|
200 INFO_PRINTF1(_L("Testing CSELFEditor Insert Variant Sepcific data")); |
|
201 |
|
202 //Get the number of variant data segments there before |
|
203 TInt prenumsegments = GetNumberofVariantSegmentsL(KSELFFileName()); |
|
204 INFO_PRINTF2(_L("There are [0x%X] variant data segments before the test"), prenumsegments); |
|
205 |
|
206 CSELFEditor* editor = NULL; |
|
207 TRAPD(err, editor = CSELFEditor::NewL(KSELFFileName())); |
|
208 |
|
209 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 0); |
|
210 T_SELFLIB_ASSERT_TRUE(editor != NULL, 0); |
|
211 |
|
212 CleanupStack::PushL(editor); |
|
213 |
|
214 INFO_PRINTF1(_L("Inserting the variant specific")); |
|
215 TRAP(err, editor->InsertVariantSpecificDataL(KTestData1())); |
|
216 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 2); |
|
217 |
|
218 TRAP(err, editor->InsertVariantSpecificDataL(KTestData2())); |
|
219 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 2); |
|
220 |
|
221 TRAP(err, editor->InsertVariantSpecificDataL(KTestData3())); |
|
222 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 2); |
|
223 |
|
224 INFO_PRINTF1(_L("Updating the ELF file")); |
|
225 TRAP(err, editor->WriteELFUpdatesL()); |
|
226 |
|
227 INFO_PRINTF2(_L("ELF File updating returned [%d]"), err); |
|
228 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 2); |
|
229 |
|
230 CleanupStack::PopAndDestroy(editor); |
|
231 |
|
232 TInt postnumsegments = GetNumberofVariantSegmentsL(KSELFFileName()); |
|
233 INFO_PRINTF2(_L("There are [0x%X] variant data segments after the test"),postnumsegments); |
|
234 |
|
235 T_SELFLIB_ASSERT_TRUE(prenumsegments + 3 == postnumsegments, 0); |
|
236 |
|
237 TInt bufferRequired = GetVariantSegmentSizeL(postnumsegments - 1, KSELFFileName()); |
|
238 RBuf8 data; |
|
239 data.CreateL(bufferRequired); |
|
240 data.CleanupClosePushL(); |
|
241 |
|
242 TRAP(err, GetVariantSegmentDataL(postnumsegments - 1, data, KSELFFileName())); |
|
243 |
|
244 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 1); |
|
245 T_SELFLIB_ASSERT_TRUE(0 == KTestData3().Compare(data), 1); |
|
246 |
|
247 TRAP(err, GetVariantSegmentDataL(postnumsegments - 2, data, KSELFFileName())); |
|
248 |
|
249 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 1); |
|
250 T_SELFLIB_ASSERT_TRUE(0 == KTestData2().Compare(data), 1); |
|
251 |
|
252 TRAP(err, GetVariantSegmentDataL(postnumsegments - 3, data, KSELFFileName())); |
|
253 |
|
254 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 1); |
|
255 T_SELFLIB_ASSERT_TRUE(0 == KTestData1().Compare(data), 1); |
|
256 |
|
257 INFO_PRINTF1(_L("Data looks good")); |
|
258 |
|
259 CleanupStack::PopAndDestroy(&data); |
|
260 } |
|
261 |
|
262 /** |
|
263 * Tests that you can't have mutliple CSELFEditors open on the same ELF file |
|
264 * @see CSELFEditor |
|
265 */ |
|
266 void CSELFLibWrapper::TestConstruction_Inuse() |
|
267 { |
|
268 INFO_PRINTF1(_L("Testing CSELFEditor multiple handles")); |
|
269 |
|
270 CSELFEditor* handle1 = NULL; |
|
271 CSELFEditor* handle2 = NULL; |
|
272 |
|
273 //Open one handle |
|
274 TRAPD(err, handle1 = CSELFEditor::NewL(KSELFFileName())); |
|
275 |
|
276 INFO_PRINTF3(_L("CSELFEditor::NewL(%S) returns [%d]"), &KSELFFileName, err); |
|
277 |
|
278 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 0); |
|
279 T_SELFLIB_ASSERT_TRUE(handle1 != NULL, 0); |
|
280 |
|
281 //Try handle two |
|
282 TRAP(err, handle2 = CSELFEditor::NewL(KSELFFileName())); |
|
283 |
|
284 INFO_PRINTF3(_L("CSELFEditor::NewL(%S) returns [%d] (this is the second handle)"), &KSELFFileName, err); |
|
285 T_SELFLIB_ASSERT_TRUE(KErrInUse == err, 0); |
|
286 T_SELFLIB_ASSERT_TRUE(handle2 == NULL, 0); |
|
287 |
|
288 delete handle1; |
|
289 } |
|
290 |
|
291 /** |
|
292 * Unit test for: |
|
293 * CSELFEditor::NewL |
|
294 * Tests with an invalid ELF file. This is invalid due to its signature |
|
295 * @see CSELFEditor |
|
296 */ |
|
297 void CSELFLibWrapper::TestConstruction_InvalidELF_SignatureL() |
|
298 { |
|
299 INFO_PRINTF1(_L("Testing CSELFEditor construction with an invalid file - bad signature")); |
|
300 |
|
301 //Create an ELF file editor |
|
302 CSELFEditor* editor = NULL; |
|
303 TRAPD(err, editor = CSELFEditor::NewL(KSELFFileNameInvalidBySignature())); |
|
304 |
|
305 INFO_PRINTF3(_L("Opening [%S] returned [%d]"), &KSELFFileNameInvalidBySignature, err); |
|
306 |
|
307 T_SELFLIB_ASSERT_TRUE(KErrCorrupt == err, 0); |
|
308 T_SELFLIB_ASSERT_TRUE(editor == NULL, 0); |
|
309 |
|
310 #ifdef _DEBUG //__UHEAP_FAILNEXT won't work on urel |
|
311 |
|
312 //Try it again with a failed memory alloc |
|
313 __UHEAP_FAILNEXT(1); |
|
314 |
|
315 TRAP(err, editor = CSELFEditor::NewL(KSELFFileNameInvalidBySignature())); |
|
316 |
|
317 INFO_PRINTF3(_L("Opening [%S] returned [%d] (with __UHEAP_FAILNEXT)"), &KSELFFileNameInvalidBySignature, err); |
|
318 |
|
319 T_SELFLIB_ASSERT_TRUE(KErrNoMemory == err, 0); |
|
320 T_SELFLIB_ASSERT_TRUE(editor == NULL, 0); |
|
321 |
|
322 #endif |
|
323 } |
|
324 |
|
325 /** |
|
326 * There are valid ELF files that the ELF lib won't support (mainly) none Core files |
|
327 * This tests that it throws a KErrNotSupported. |
|
328 * @see CSELFEditor |
|
329 */ |
|
330 void CSELFLibWrapper::TestConstruction_ValidELF_NotSupported() |
|
331 { |
|
332 INFO_PRINTF1(_L("Testing CSELFEditor construction with an valid file but unsupported")); |
|
333 |
|
334 //Create an ELF file editor |
|
335 CSELFEditor* editor = NULL; |
|
336 TRAPD(err, editor = CSELFEditor::NewL(KSELFFileNameExe())); |
|
337 |
|
338 INFO_PRINTF3(_L("Opening [%S] returned [%d]"), &KSELFFileNameExe, err); |
|
339 |
|
340 T_SELFLIB_ASSERT_TRUE(KErrNotSupported == err, 0); |
|
341 T_SELFLIB_ASSERT_TRUE(editor == NULL, 0); |
|
342 } |
|
343 |
|
344 /** |
|
345 * Unit test for: |
|
346 * CSELFEditor::NewL |
|
347 * Tests with an invalid ELF file. This is invalid due to its size |
|
348 * @see CSELFEditor |
|
349 */ |
|
350 void CSELFLibWrapper::TestConstruction_InvalidELF_SizeL() |
|
351 { |
|
352 INFO_PRINTF1(_L("Testing CSELFEditor construction with an invalid file - bad size")); |
|
353 |
|
354 //Create an ELF file editor |
|
355 CSELFEditor* editor = NULL; |
|
356 TRAPD(err, editor = CSELFEditor::NewL(KSELFFileNameTiny())); |
|
357 |
|
358 INFO_PRINTF3(_L("Opening [%S] returned [%d]"), &KSELFFileNameTiny, err); |
|
359 |
|
360 T_SELFLIB_ASSERT_TRUE(KErrCorrupt == err, 0); |
|
361 T_SELFLIB_ASSERT_TRUE(editor == NULL, 0); |
|
362 |
|
363 #ifdef _DEBUG //__UHEAP_FAILNEXT won't work on urel |
|
364 |
|
365 //Try it again with a failed memory alloc |
|
366 __UHEAP_FAILNEXT(1); |
|
367 |
|
368 TRAP(err, editor = CSELFEditor::NewL(KSELFFileNameTiny())); |
|
369 |
|
370 INFO_PRINTF3(_L("Opening [%S] returned [%d] (with __UHEAP_FAILNEXT)"), &KSELFFileNameTiny, err); |
|
371 |
|
372 T_SELFLIB_ASSERT_TRUE(KErrNoMemory == err, 0); |
|
373 T_SELFLIB_ASSERT_TRUE(editor == NULL, 0); |
|
374 |
|
375 #endif |
|
376 } |
|
377 |
|
378 /** |
|
379 * Unit test for: |
|
380 * CSELFEditor::GetElfHeaderL() |
|
381 * @see CSELFEditor |
|
382 */ |
|
383 void CSELFLibWrapper::TestGetElfHeaderL() |
|
384 { |
|
385 INFO_PRINTF1(_L("Testing CSELFEditor::GetElfHeaderL()")); |
|
386 |
|
387 //Try a file we know does exist |
|
388 CSELFEditor* editor = NULL; |
|
389 TRAPD(err, editor = CSELFEditor::NewL(KSELFFileName())); |
|
390 |
|
391 INFO_PRINTF3(_L("CSELFEditor::NewL(%S) returns [%d]"), &KSELFFileName, err); |
|
392 |
|
393 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 0); |
|
394 T_SELFLIB_ASSERT_TRUE(editor != NULL, 0); |
|
395 |
|
396 CleanupStack::PushL(editor); |
|
397 |
|
398 Elf32_Ehdr header; |
|
399 editor->GetELFHeader(header); |
|
400 |
|
401 LogELFHeader(header); |
|
402 |
|
403 //Assert on the values we can be sure of to be sure potatoes |
|
404 T_SELFLIB_ASSERT_TRUE(header.e_type == ET_CORE, 1); |
|
405 T_SELFLIB_ASSERT_TRUE(header.e_version == EV_CURRENT, 1); |
|
406 T_SELFLIB_ASSERT_TRUE(header.e_machine == EM_ARM, 1); |
|
407 T_SELFLIB_ASSERT_TRUE(header.e_entry == 0, 1); |
|
408 T_SELFLIB_ASSERT_TRUE(header.e_ehsize == sizeof(Elf32_Ehdr), 1); |
|
409 T_SELFLIB_ASSERT_TRUE(header.e_phnum > 0, 1); |
|
410 |
|
411 CleanupStack::PopAndDestroy(editor); |
|
412 } |
|
413 |
|
414 /** |
|
415 * Test we can insert more than one variant specific segment |
|
416 * @leave One of the system wide codes |
|
417 */ |
|
418 void CSELFLibWrapper::TestMultipleInsertionL() |
|
419 { |
|
420 INFO_PRINTF1(_L("Testing CSELFEditor Insert Multiple Variant Sepcific data")); |
|
421 |
|
422 //Get the number of variant data segments there before |
|
423 TInt prenumsegments = GetNumberofVariantSegmentsL(KSELFFileName()); |
|
424 INFO_PRINTF2(_L("There are [0x%X] variant data segments before the test"), prenumsegments); |
|
425 |
|
426 CSELFEditor* editor = NULL; |
|
427 TRAPD(err, editor = CSELFEditor::NewL(KSELFFileName())); |
|
428 |
|
429 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 0); |
|
430 T_SELFLIB_ASSERT_TRUE(editor != NULL, 0); |
|
431 |
|
432 CleanupStack::PushL(editor); |
|
433 |
|
434 INFO_PRINTF1(_L("Inserting the variant specific data")); |
|
435 TRAP(err, editor->InsertVariantSpecificDataL(KTestData1())); |
|
436 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 2); |
|
437 |
|
438 INFO_PRINTF1(_L("Updating the ELF file")); |
|
439 TRAP(err, editor->WriteELFUpdatesL()); |
|
440 |
|
441 INFO_PRINTF2(_L("ELF File updating returned [%d]"), err); |
|
442 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 2); |
|
443 |
|
444 //Write a second time |
|
445 INFO_PRINTF1(_L("Inserting more variant specific data")); |
|
446 TRAP(err, editor->InsertVariantSpecificDataL(KTestData2())); |
|
447 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 2); |
|
448 |
|
449 INFO_PRINTF1(_L("Updating the ELF file")); |
|
450 TRAP(err, editor->WriteELFUpdatesL()); |
|
451 |
|
452 CleanupStack::PopAndDestroy(editor); |
|
453 |
|
454 TInt postnumsegments = GetNumberofVariantSegmentsL(KSELFFileName()); |
|
455 INFO_PRINTF2(_L("There are [0x%X] variant data segments after the test"),postnumsegments); |
|
456 |
|
457 T_SELFLIB_ASSERT_TRUE(prenumsegments + 2 == postnumsegments, 0); |
|
458 |
|
459 TInt bufferRequired = GetVariantSegmentSizeL(postnumsegments - 1, KSELFFileName()); |
|
460 RBuf8 data; |
|
461 data.CreateL(bufferRequired); |
|
462 data.CleanupClosePushL(); |
|
463 |
|
464 TRAP(err, GetVariantSegmentDataL(postnumsegments - 1, data, KSELFFileName())); |
|
465 |
|
466 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 1); |
|
467 T_SELFLIB_ASSERT_TRUE(0 == KTestData2().Compare(data), 1); |
|
468 |
|
469 TRAP(err, GetVariantSegmentDataL(postnumsegments - 2, data, KSELFFileName())); |
|
470 |
|
471 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 1); |
|
472 T_SELFLIB_ASSERT_TRUE(0 == KTestData1().Compare(data), 1); |
|
473 |
|
474 INFO_PRINTF1(_L("Data looks good")); |
|
475 |
|
476 CleanupStack::PopAndDestroy(&data); |
|
477 |
|
478 } |
|
479 |
|
480 /** |
|
481 * Adds nothing to the ELF file but calls the update function. Verifies that the |
|
482 * file remains the same |
|
483 * @leave One of the system wide codes |
|
484 */ |
|
485 void CSELFLibWrapper::TestInsertNothingL() |
|
486 { |
|
487 INFO_PRINTF1(_L("Testing Inserting nothing")); |
|
488 |
|
489 //Get size of file before |
|
490 RFile theFile; |
|
491 User::LeaveIfError(theFile.Open(iFs, KSELFFileName(), EFileRead)); |
|
492 CleanupClosePushL(theFile); |
|
493 |
|
494 TInt previousFileSize = 0; |
|
495 User::LeaveIfError(theFile.Size(previousFileSize)); |
|
496 CleanupStack::PopAndDestroy(&theFile); |
|
497 |
|
498 INFO_PRINTF2(_L("The test file before is [0x%X] bytes"), previousFileSize); |
|
499 |
|
500 CSELFEditor* editor = NULL; |
|
501 TRAPD(err, editor = CSELFEditor::NewL(KSELFFileName())); |
|
502 |
|
503 INFO_PRINTF3(_L("CSELFEditor::NewL(%S) returns [%d]"), &KSELFFileName, err); |
|
504 |
|
505 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 1); |
|
506 T_SELFLIB_ASSERT_TRUE(editor != NULL, 1); |
|
507 |
|
508 CleanupStack::PushL(editor); |
|
509 |
|
510 //Update having made no updates |
|
511 INFO_PRINTF1(_L("Updating the ELF file")); |
|
512 TRAP(err, editor->WriteELFUpdatesL()); |
|
513 |
|
514 CleanupStack::PopAndDestroy(editor); |
|
515 |
|
516 //Now get the file size again, should be the same |
|
517 TInt currentFileSize = 0; |
|
518 User::LeaveIfError(theFile.Open(iFs, KSELFFileName(), EFileRead)); |
|
519 CleanupClosePushL(theFile); |
|
520 |
|
521 User::LeaveIfError(theFile.Size(currentFileSize)); |
|
522 INFO_PRINTF2(_L("The test file after is [0x%X] bytes"), currentFileSize); |
|
523 |
|
524 CleanupStack::PopAndDestroy(&theFile); |
|
525 |
|
526 T_SELFLIB_ASSERT_TRUE(currentFileSize == previousFileSize, 0); |
|
527 } |
|
528 |
|
529 /** |
|
530 * Logs an ELF header to the test logs |
|
531 * @param aHeader Header to log |
|
532 */ |
|
533 void CSELFLibWrapper::LogELFHeader(const Elf32_Ehdr& aHeader) |
|
534 { |
|
535 INFO_PRINTF1(_L("The ELF Header looks like:")); |
|
536 INFO_PRINTF2(_L("\te_type:\t\t0x%X"), aHeader.e_type); |
|
537 INFO_PRINTF2(_L("\te_version:\t0x%X"), aHeader.e_version); |
|
538 INFO_PRINTF2(_L("\te_machine:\t0x%X"), aHeader.e_machine); |
|
539 INFO_PRINTF2(_L("\te_entry:\t0x%X"), aHeader.e_entry); |
|
540 INFO_PRINTF2(_L("\te_phoff:\t0x%X"), aHeader.e_phoff); |
|
541 INFO_PRINTF2(_L("\te_shoff:\t0x%X"), aHeader.e_shoff); |
|
542 INFO_PRINTF2(_L("\te_flags:\t0x%X"), aHeader.e_flags); |
|
543 INFO_PRINTF2(_L("\te_ehsize:\t0x%X"), aHeader.e_ehsize); |
|
544 INFO_PRINTF2(_L("\te_phentsize:\t0x%X"), aHeader.e_phentsize); |
|
545 INFO_PRINTF2(_L("\te_phnum:\t0x%X"), aHeader.e_phnum); |
|
546 INFO_PRINTF2(_L("\te_shentsize:\t0x%X"), aHeader.e_shentsize); |
|
547 INFO_PRINTF2(_L("\te_shnum:\t0x%X"), aHeader.e_shnum); |
|
548 INFO_PRINTF2(_L("\te_shstrndx:\t0x%X"), aHeader.e_shstrndx); |
|
549 } |
|
550 |
|
551 void CSELFLibWrapper::TestPerformanceL() |
|
552 { |
|
553 INFO_PRINTF1(_L("Testing performance")); |
|
554 |
|
555 //Use case 1: Normal use case, insert 1 variant specific data segment |
|
556 TUint startTick = User::NTickCount(); |
|
557 |
|
558 CSELFEditor* editor = NULL; |
|
559 editor = CSELFEditor::NewLC(KSELFFileName()); |
|
560 editor->InsertVariantSpecificDataL(KTestData1()); |
|
561 editor->WriteELFUpdatesL(); |
|
562 |
|
563 TUint stopTick = User::NTickCount(); |
|
564 TReal seconds = (TReal)(stopTick - startTick)/(TReal)HelpTicksPerSecond(); |
|
565 INFO_PRINTF2(_L("Inserting one segment takes %f seconds"), seconds); |
|
566 CleanupStack::PopAndDestroy(editor); |
|
567 |
|
568 //Use case 2: Lots of inserts |
|
569 //Get size of file before |
|
570 RFile theFile; |
|
571 User::LeaveIfError(theFile.Open(iFs, KSELFFileName(), EFileRead)); |
|
572 CleanupClosePushL(theFile); |
|
573 |
|
574 TInt startingFileSize = 0; |
|
575 User::LeaveIfError(theFile.Size(startingFileSize)); |
|
576 CleanupStack::PopAndDestroy(&theFile); |
|
577 |
|
578 TInt prenumsegments = GetNumberofVariantSegmentsL(KSELFFileName()); |
|
579 INFO_PRINTF2(_L("There are [0x%X] variant data segments before the test"), prenumsegments); |
|
580 |
|
581 editor = CSELFEditor::NewLC(KSELFFileName()); |
|
582 |
|
583 INFO_PRINTF1(_L("Inserting the variant specific data")); |
|
584 |
|
585 static const int numToTest = 50; |
|
586 startTick = User::NTickCount(); |
|
587 for(TUint i = 0; i < numToTest; i++) |
|
588 { |
|
589 editor->InsertVariantSpecificDataL(KTestData1()); |
|
590 } |
|
591 |
|
592 INFO_PRINTF1(_L("Updating the ELF file")); |
|
593 editor->WriteELFUpdatesL(); |
|
594 |
|
595 stopTick = User::NTickCount(); |
|
596 seconds = (TReal)(stopTick - startTick)/(TReal)HelpTicksPerSecond(); |
|
597 |
|
598 CleanupStack::PopAndDestroy(editor); |
|
599 |
|
600 TInt postnumsegments = GetNumberofVariantSegmentsL(KSELFFileName()); |
|
601 INFO_PRINTF2(_L("There are [0x%X] variant data segments after the test"), postnumsegments); |
|
602 |
|
603 T_SELFLIB_ASSERT_TRUE(prenumsegments + numToTest == postnumsegments, 0); |
|
604 INFO_PRINTF4(_L("Starting file size: 0x%X %d and took %f seconds"), startingFileSize, startingFileSize, seconds); |
|
605 |
|
606 } |
|
607 |
|
608 /** |
|
609 * Tests we can insert a large amount of data into the ELF file |
|
610 * @leave ONe of the system wide codes |
|
611 */ |
|
612 void CSELFLibWrapper::TestStressL() |
|
613 { |
|
614 INFO_PRINTF1(_L("Testing CSELFEditor Insert Large amount of Variant Sepcific data")); |
|
615 |
|
616 //Get the number of variant data segments there before |
|
617 TInt prenumsegments = GetNumberofVariantSegmentsL(KSELFFileName()); |
|
618 INFO_PRINTF2(_L("There are [0x%X] variant data segments before the test"), prenumsegments); |
|
619 |
|
620 RBuf8 largeData; |
|
621 largeData.CreateL(KLargeDataSize); |
|
622 largeData.CleanupClosePushL(); |
|
623 |
|
624 CSELFEditor* editor = NULL; |
|
625 TRAPD(err, editor = CSELFEditor::NewL(KSELFFileName())); |
|
626 |
|
627 INFO_PRINTF2(_L("getting %d"), err); |
|
628 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 1); |
|
629 T_SELFLIB_ASSERT_TRUE(editor != NULL, 1); |
|
630 |
|
631 CleanupStack::PushL(editor); |
|
632 |
|
633 INFO_PRINTF1(_L("Inserting the variant specific")); |
|
634 TRAP(err, editor->InsertVariantSpecificDataL(largeData)); |
|
635 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 2); |
|
636 |
|
637 INFO_PRINTF1(_L("Updating the ELF file")); |
|
638 TRAP(err, editor->WriteELFUpdatesL()); |
|
639 |
|
640 INFO_PRINTF2(_L("ELF File updating returned [%d]"), err); |
|
641 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 2); |
|
642 |
|
643 CleanupStack::PopAndDestroy(editor); |
|
644 |
|
645 TInt postnumsegments = GetNumberofVariantSegmentsL(KSELFFileName()); |
|
646 INFO_PRINTF2(_L("There are [0x%X] variant data segments after the test"),postnumsegments); |
|
647 |
|
648 T_SELFLIB_ASSERT_TRUE(prenumsegments + 1 == postnumsegments, 0); |
|
649 |
|
650 TInt bufferRequired = GetVariantSegmentSizeL(postnumsegments - 1, KSELFFileName()); |
|
651 RBuf8 data; |
|
652 data.CreateL(bufferRequired); |
|
653 data.CleanupClosePushL(); |
|
654 |
|
655 TRAP(err, GetVariantSegmentDataL(postnumsegments - 1, data, KSELFFileName())); |
|
656 |
|
657 T_SELFLIB_ASSERT_TRUE(KErrNone == err, 2); |
|
658 T_SELFLIB_ASSERT_TRUE(0 == largeData.Compare(data), 2); |
|
659 |
|
660 INFO_PRINTF1(_L("Data looks good")); |
|
661 CleanupStack::PopAndDestroy(&data); |
|
662 CleanupStack::PopAndDestroy(&largeData); |
|
663 } |
|
664 |
|
665 /** |
|
666 * Returns the number of nanokernel ticks in one second |
|
667 * @return Number of nanokernel ticks. 0 if unsuccesful |
|
668 */ |
|
669 TInt CSELFLibWrapper::HelpTicksPerSecond() |
|
670 { |
|
671 TInt nanokernel_tick_period; |
|
672 HAL::Get(HAL::ENanoTickPeriod, nanokernel_tick_period); |
|
673 static const TInt KOneMillion = 1000000; |
|
674 return KOneMillion/nanokernel_tick_period; |
|
675 } |
|
676 |
|
677 /** |
|
678 * Utility to get the number of variant data segments in the file |
|
679 * @leave One of the system wide codes |
|
680 */ |
|
681 TInt CSELFLibWrapper::GetNumberofVariantSegmentsL(const TDesC& aFilename) |
|
682 { |
|
683 RFile elfFile; |
|
684 User::LeaveIfError(elfFile.Open(iFs, aFilename, EFileRead)); |
|
685 CleanupClosePushL(elfFile); |
|
686 |
|
687 READ_STRUCTL(Elf32_Ehdr, ehdr, elfFile, 0); |
|
688 |
|
689 TUint count = 0; |
|
690 |
|
691 //Now go through program headers and count relevant dhdrs |
|
692 for(TUint i = 0; i < ehdr.e_phnum; i++) |
|
693 { |
|
694 READ_STRUCTL(Elf32_Phdr, phdr, elfFile, ehdr.e_phoff + (i * sizeof(Elf32_Phdr))); |
|
695 if(phdr.p_type == PT_NOTE) |
|
696 { |
|
697 READ_STRUCTL(Sym32_dhdr, dhdr, elfFile, phdr.p_offset); |
|
698 if(dhdr.d_type == ESYM_NOTE_VARIANT_DATA) |
|
699 ++count; |
|
700 } |
|
701 } |
|
702 |
|
703 CleanupStack::PopAndDestroy(&elfFile); |
|
704 |
|
705 return count; |
|
706 } |
|
707 |
|
708 /** |
|
709 * Gets the size of the aIndexth variant segment element we find |
|
710 * in the ELF file |
|
711 * @param aIndex Index of the segment of interest |
|
712 * @return The size required to read this data |
|
713 * @leave KErrNotFound if the index is wrong or one of the system wide codes |
|
714 */ |
|
715 TInt CSELFLibWrapper::GetVariantSegmentSizeL(const TUint aIndex, const TDesC& aFilename) |
|
716 { |
|
717 RFile elfFile; |
|
718 User::LeaveIfError(elfFile.Open(iFs, aFilename, EFileRead)); |
|
719 CleanupClosePushL(elfFile); |
|
720 |
|
721 READ_STRUCTL(Elf32_Ehdr, ehdr, elfFile, 0); |
|
722 |
|
723 TUint count = 0; |
|
724 |
|
725 //Now go through program headers and count relevant dhdrs |
|
726 for(TUint i = 0; i < ehdr.e_phnum; i++) |
|
727 { |
|
728 READ_STRUCTL(Elf32_Phdr, phdr, elfFile, ehdr.e_phoff + (i * sizeof(Elf32_Phdr))); |
|
729 if(phdr.p_type == PT_NOTE) |
|
730 { |
|
731 READ_STRUCTL(Sym32_dhdr, dhdr, elfFile, phdr.p_offset); |
|
732 if(dhdr.d_type == ESYM_NOTE_VARIANT_DATA) |
|
733 { |
|
734 if(count == aIndex) |
|
735 { |
|
736 READ_STRUCTL(Sym32_variant_spec_data, vdata, elfFile, phdr.p_offset + sizeof(Sym32_dhdr)); |
|
737 CleanupStack::PopAndDestroy(&elfFile); |
|
738 return vdata.es_size; |
|
739 } |
|
740 count++; |
|
741 } |
|
742 } |
|
743 } |
|
744 |
|
745 User::Leave(KErrNotFound); |
|
746 return 0; //avoid warnings |
|
747 } |
|
748 |
|
749 /** |
|
750 * Gets the data of the aIndexth variant segment element we find |
|
751 * in the ELF file |
|
752 * @param aIndex Index of the segment of interest |
|
753 * @param aData buffer to hold data |
|
754 * @leave KErrNotFound if the index is wrong or one of the system wide codes |
|
755 */ |
|
756 void CSELFLibWrapper::GetVariantSegmentDataL(TUint aIndex, TDes8& aData, const TDesC& aFilename) |
|
757 { |
|
758 RFile elfFile; |
|
759 User::LeaveIfError(elfFile.Open(iFs, aFilename, EFileRead)); |
|
760 CleanupClosePushL(elfFile); |
|
761 |
|
762 READ_STRUCTL(Elf32_Ehdr, ehdr, elfFile, 0); |
|
763 |
|
764 TUint count = 0; |
|
765 |
|
766 //Now go through program headers and count relevant dhdrs |
|
767 for(TUint i = 0; i < ehdr.e_phnum; i++) |
|
768 { |
|
769 READ_STRUCTL(Elf32_Phdr, phdr, elfFile, ehdr.e_phoff + (i * sizeof(Elf32_Phdr))); |
|
770 if(phdr.p_type == PT_NOTE) |
|
771 { |
|
772 READ_STRUCTL(Sym32_dhdr, dhdr, elfFile, phdr.p_offset); |
|
773 if(dhdr.d_type == ESYM_NOTE_VARIANT_DATA) |
|
774 { |
|
775 if(count == aIndex) |
|
776 { |
|
777 READ_STRUCTL(Sym32_variant_spec_data, vdata, elfFile, phdr.p_offset + sizeof(Sym32_dhdr)); |
|
778 if(aData.MaxLength() < vdata.es_size) |
|
779 { |
|
780 User::Leave(KErrTooBig); |
|
781 } |
|
782 //read the data |
|
783 elfFile.Read(vdata.es_data, aData); |
|
784 CleanupStack::PopAndDestroy(&elfFile); |
|
785 return; |
|
786 } |
|
787 count++; |
|
788 } |
|
789 } |
|
790 } |
|
791 |
|
792 User::Leave(KErrNotFound); |
|
793 } |
|
794 |
|
795 /** |
|
796 * Copies test files from not writable z:\ drive to writable place |
|
797 * @leave One of the system wide codes |
|
798 */ |
|
799 void CSELFLibWrapper::CopyFilesToWritablePlaceL() |
|
800 { |
|
801 INFO_PRINTF1(_L("Copying the files and setting correct attributes")); |
|
802 BaflUtils::EnsurePathExistsL(iFs, KSELFFileName); |
|
803 |
|
804 TUint attToRemove = KEntryAttReadOnly; |
|
805 TUint attToSet = 0; |
|
806 |
|
807 User::LeaveIfError(BaflUtils::CopyFile(iFs, KROMSELFFileName, KSELFFileName)); |
|
808 iFs.SetAtt(KSELFFileName, attToSet, attToRemove); |
|
809 |
|
810 User::LeaveIfError(BaflUtils::CopyFile(iFs, KROMSELFFileNameInvalidBySignature, KSELFFileNameInvalidBySignature)); |
|
811 iFs.SetAtt(KSELFFileNameInvalidBySignature, attToSet, attToRemove); |
|
812 |
|
813 User::LeaveIfError(BaflUtils::CopyFile(iFs, KROMSELFFileNameTiny, KSELFFileNameTiny)); |
|
814 iFs.SetAtt(KSELFFileNameTiny, attToSet, attToRemove); |
|
815 |
|
816 User::LeaveIfError(BaflUtils::CopyFile(iFs, KROMSELFFileNameExe, KSELFFileNameExe)); |
|
817 iFs.SetAtt(KSELFFileNameExe, attToSet, attToRemove); |
|
818 } |
|
819 |
|
820 /** |
|
821 * Cleans the files copied by CopyFilesToWritablePlaceL() to tidy up |
|
822 */ |
|
823 void CSELFLibWrapper::TearDownFilesL() |
|
824 { |
|
825 INFO_PRINTF1(_L("Deleting the files")); |
|
826 |
|
827 User::LeaveIfError(BaflUtils::DeleteFile(iFs, KSELFFileName)); |
|
828 User::LeaveIfError(BaflUtils::DeleteFile(iFs, KSELFFileNameInvalidBySignature)); |
|
829 User::LeaveIfError(BaflUtils::DeleteFile(iFs, KSELFFileNameTiny)); |
|
830 User::LeaveIfError(BaflUtils::DeleteFile(iFs, KSELFFileNameExe)); |
|
831 } |