|
1 // Copyright (c) 2004-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 // __ACTION_INFO_BEGIN__ |
|
15 // [Action Name] |
|
16 // CorruptFile |
|
17 // [Action Parameters] |
|
18 // FilePath <input>: File path of the file to corrupt. |
|
19 // CorruptionType <input>: Type of corruption. |
|
20 // ErrorCode <output>: (Optional) Returned error code, if not requested then code will |
|
21 // leave if not KErrNone |
|
22 // [Action Description] |
|
23 // Corrupts the specified file, backing-up the original uncorrupted file. |
|
24 // [APIs Used] |
|
25 // BaflUtils::FileExists |
|
26 // RFile::Open |
|
27 // RFile::Read |
|
28 // RFile::Close |
|
29 // RFile::Write |
|
30 // RFile::Create |
|
31 // RFs::Delete |
|
32 // RFs::Rename |
|
33 // __ACTION_INFO_END__ |
|
34 // |
|
35 // |
|
36 |
|
37 |
|
38 #include "CMtfTestActionCorruptFile.h" |
|
39 #include "CMtfTestCase.h" |
|
40 #include "CMtfTestActionParameters.h" |
|
41 #include "MtfTestActionUtilsUser.h" |
|
42 |
|
43 #include "bautils.h" |
|
44 |
|
45 CMtfTestAction* CMtfTestActionCorruptFile::NewL(CMtfTestCase& aTestCase,CMtfTestActionParameters* aActionParameters) |
|
46 { |
|
47 CMtfTestActionCorruptFile* self = new(ELeave) CMtfTestActionCorruptFile(aTestCase); |
|
48 CleanupStack::PushL(self); |
|
49 self->ConstructL(aActionParameters); |
|
50 CleanupStack::Pop(self); |
|
51 return self; |
|
52 } |
|
53 |
|
54 |
|
55 CMtfTestActionCorruptFile::CMtfTestActionCorruptFile(CMtfTestCase& aTestCase) |
|
56 : CMtfSynchronousTestAction(aTestCase) |
|
57 { |
|
58 } |
|
59 |
|
60 |
|
61 CMtfTestActionCorruptFile::~CMtfTestActionCorruptFile() |
|
62 { |
|
63 } |
|
64 |
|
65 void CMtfTestActionCorruptFile::ExecuteActionL() |
|
66 { |
|
67 TestCase().INFO_PRINTF2(_L("Test Action %S start..."), &KTestActionCorruptFile); |
|
68 TRAPD(err, RunTestL()); |
|
69 |
|
70 TestCase().INFO_PRINTF2(_L("CMtfTestActionCorruptFile ended. Error = %d"), err); |
|
71 |
|
72 if (err != KErrNone) |
|
73 { |
|
74 TestCase().SetTestStepResult(EFail); |
|
75 } |
|
76 TestCase().INFO_PRINTF2(_L("Test Action %S completed."), &KTestActionCorruptFile); |
|
77 TestCase().ActionCompletedL(*this); |
|
78 } |
|
79 |
|
80 // This is used because file paths given in the ini file cannot have spaces |
|
81 #define KSpaceReplacement '%' |
|
82 _LIT(KSpace, " "); |
|
83 |
|
84 void CMtfTestActionCorruptFile::RunTestL() |
|
85 { |
|
86 TestCase().INFO_PRINTF1(_L("CMtfTestActionCorruptFile started")); |
|
87 |
|
88 HBufC* paramFilePath = ObtainParameterReferenceL<HBufC>(TestCase(),ActionParameters().Parameter(0)); |
|
89 |
|
90 TInt corruptionType = ObtainValueParameterL<TInt>(TestCase(),ActionParameters().Parameter(1)); |
|
91 |
|
92 TFileName aFilePath; |
|
93 aFilePath.Append(*paramFilePath); |
|
94 |
|
95 // Put any spaces that should be in the file path |
|
96 TInt temp = aFilePath.Locate(KSpaceReplacement); |
|
97 |
|
98 while (temp != KErrNotFound) |
|
99 { |
|
100 aFilePath.Replace(temp, 1, KSpace); |
|
101 temp = aFilePath.Locate(KSpaceReplacement); |
|
102 } |
|
103 |
|
104 TestCase().INFO_PRINTF1(aFilePath); |
|
105 TestCase().INFO_PRINTF2(_L("Corruption Type = %d"), corruptionType); |
|
106 |
|
107 *paramFilePath = aFilePath; |
|
108 |
|
109 RFs aFs; |
|
110 aFs.Connect(); |
|
111 CleanupClosePushL(aFs); |
|
112 |
|
113 // corrupt the file |
|
114 CorruptFileLC(aFs, *paramFilePath, corruptionType); |
|
115 |
|
116 // request file server to read the file as corrupted (for corruption type 1) |
|
117 UpdateCorruptionListLC(aFs, *paramFilePath, corruptionType); |
|
118 |
|
119 CleanupStack::PopAndDestroy(1, &aFs); // aFs |
|
120 } |
|
121 |
|
122 // This function edits a file called CorruptFileNames.lst which contains a list of files. |
|
123 // It is read by the file server on start-up and 'pretends' that each file listed is corrupt. |
|
124 // Note that the given file remains unaltered. |
|
125 // The CorruptFileNames.lst file will not be read by the file server until it is re-booted, so a re-boot must occur after calling this function. |
|
126 void CMtfTestActionCorruptFile::UpdateCorruptionListLC(RFs& aFs, const TDesC& aFilePathOld, const TInt& aCorruptionType) |
|
127 { |
|
128 // This is only for corruption types 1 (or 0 to de-corrupt the file) |
|
129 if (!((aCorruptionType == 0) || (aCorruptionType == 1))) |
|
130 { |
|
131 return; |
|
132 } |
|
133 |
|
134 TBuf8<KMaxFileName> aFilePath; |
|
135 aFilePath.Append(aFilePathOld); |
|
136 |
|
137 _LIT(KCorruptionListFilePath, "c:\\system\\data\\CorruptFileNames.lst"); |
|
138 |
|
139 // see if the file to corrupt exists |
|
140 TBool fileToCorruptExists = BaflUtils::FileExists(aFs, aFilePathOld); |
|
141 |
|
142 if (!fileToCorruptExists) |
|
143 { |
|
144 TestCase().INFO_PRINTF1(_L("File to corrupt does not exist")); |
|
145 } |
|
146 |
|
147 // see if the corruption list exists |
|
148 TBool corruptionListExists = BaflUtils::FileExists(aFs, KCorruptionListFilePath); |
|
149 |
|
150 TBuf8<512> newList; |
|
151 TInt error; |
|
152 TBool corruptionListChanged = false; |
|
153 RFile corruptionListFile; |
|
154 |
|
155 if (corruptionListExists) |
|
156 { |
|
157 error = corruptionListFile.Open(aFs,KCorruptionListFilePath,EFileRead); |
|
158 |
|
159 if (!(error==KErrNone)) |
|
160 { |
|
161 TestCase().INFO_PRINTF2(_L("Cannot open corruption list. Error = %d"), error); |
|
162 User::Leave(error); |
|
163 } |
|
164 |
|
165 // read the contents of corruption list |
|
166 TInt fileSize = 0; |
|
167 User::LeaveIfError(corruptionListFile.Size(fileSize)); |
|
168 |
|
169 HBufC8* dataBuffer = HBufC8::NewLC(fileSize); |
|
170 TPtr8 bufferPtr(dataBuffer->Des()); |
|
171 |
|
172 User::LeaveIfError(corruptionListFile.Read(bufferPtr)); |
|
173 |
|
174 TBool matchFound; |
|
175 |
|
176 TInt temp = bufferPtr.Locate('\n'); |
|
177 |
|
178 // read each line |
|
179 while (temp != KErrNotFound) |
|
180 { |
|
181 matchFound = false; |
|
182 |
|
183 TPtrC8 thisLine(bufferPtr.Left(temp+1)); |
|
184 |
|
185 // see if this line contains the given file path |
|
186 if (temp > aFilePath.Length()) |
|
187 { |
|
188 if (thisLine.Left(aFilePath.Length()).Match(aFilePath) != KErrNotFound) |
|
189 { |
|
190 matchFound = true; |
|
191 } |
|
192 } |
|
193 |
|
194 // remove the given file path from the list of files (it will be added again if corruption type is 1) |
|
195 if (!matchFound) |
|
196 { |
|
197 newList.Append(thisLine); |
|
198 } |
|
199 else if (aCorruptionType == 0) |
|
200 { |
|
201 corruptionListChanged = true; |
|
202 } |
|
203 |
|
204 bufferPtr.Delete(0, temp+1); |
|
205 temp = bufferPtr.Locate('\n'); |
|
206 } |
|
207 |
|
208 corruptionListFile.Close(); |
|
209 |
|
210 CleanupStack::Pop(1); // dataBuffer |
|
211 } |
|
212 |
|
213 // add given file to corruption list |
|
214 if (aCorruptionType == 1) |
|
215 { |
|
216 newList.Append(aFilePath); |
|
217 newList.Append(_L(", -20, every\r\n")); // the file will appear corrupted every time it is accessed |
|
218 // newList.Append(_L(", -20, ONCE\r\n")); |
|
219 corruptionListChanged = true; |
|
220 } |
|
221 |
|
222 if (corruptionListChanged) |
|
223 { |
|
224 // delete old list |
|
225 error = aFs.Delete(KCorruptionListFilePath); |
|
226 |
|
227 if (!((error==KErrNone) || (error==KErrNotFound))) |
|
228 { |
|
229 TestCase().INFO_PRINTF1(_L("Could not delete old corruption list")); |
|
230 User::Leave(error); |
|
231 } |
|
232 |
|
233 // create new list |
|
234 error = corruptionListFile.Create(aFs,KCorruptionListFilePath,EFileWrite); |
|
235 |
|
236 if (!(error==KErrNone)) |
|
237 { |
|
238 TestCase().INFO_PRINTF2(_L("Cannot create new corruption list. Error = %d"), error); |
|
239 User::Leave(error); |
|
240 } |
|
241 |
|
242 error = corruptionListFile.Write(newList); |
|
243 |
|
244 corruptionListFile.Close(); |
|
245 |
|
246 TestCase().INFO_PRINTF1(_L("Corruption list updated.")); |
|
247 } |
|
248 } |
|
249 |
|
250 // This function edits the given file to make it corrupted. |
|
251 // The original file is backed up first, and is restored if corruption type is 0. |
|
252 // corruption type 0: no corruption |
|
253 // corruption type 1: file server returns error KErrCorrupt |
|
254 // corruption type 2: file does not exist |
|
255 // corruption type 3: file contains zero-length data |
|
256 // corruption type 4: file contains random data |
|
257 void CMtfTestActionCorruptFile::CorruptFileLC(RFs& aFs, const TDesC& aFilePath, const TInt& aCorruptionType) |
|
258 { |
|
259 _LIT(KUncorruptedFileFolder, "c:\\msgtest\\TestFramework\\ScriptedTestCases\\Corruption\\"); |
|
260 |
|
261 // calculate a file path for the backed-up (original) version of the file |
|
262 TFileName uncorruptedFilePath; |
|
263 TParse parseFile; |
|
264 |
|
265 parseFile.Set(aFilePath, NULL, NULL); |
|
266 |
|
267 uncorruptedFilePath.Append(KUncorruptedFileFolder); |
|
268 uncorruptedFilePath.Append(parseFile.NameAndExt()); |
|
269 uncorruptedFilePath.Append(_L(".uncorrupted")); |
|
270 |
|
271 TInt error; |
|
272 |
|
273 // see if there is an uncorrupted version of this file |
|
274 TBool uncorruptedFileExists = BaflUtils::FileExists(aFs, uncorruptedFilePath); |
|
275 |
|
276 if (aCorruptionType == 0) // no corruption |
|
277 { |
|
278 if(uncorruptedFileExists) |
|
279 { |
|
280 // over-write corrupted file with uncorrupted version |
|
281 TestCase().INFO_PRINTF1(_L("Uncorrupted version of file exists")); |
|
282 |
|
283 // delete corrupted version of file |
|
284 error = aFs.Delete(aFilePath); |
|
285 |
|
286 if (!((error==KErrNone) || (error==KErrNotFound))) |
|
287 { |
|
288 TestCase().INFO_PRINTF1(_L("Could not delete corrupted version of file")); |
|
289 User::Leave(error); |
|
290 } |
|
291 |
|
292 // put back uncorrupted version of file |
|
293 error = aFs.Rename(uncorruptedFilePath, aFilePath); |
|
294 |
|
295 if (!(error==KErrNone)) |
|
296 { |
|
297 TestCase().INFO_PRINTF1(_L("Could not put back uncorrupted version of file")); |
|
298 User::Leave(error); |
|
299 } |
|
300 |
|
301 TestCase().INFO_PRINTF1(_L("File uncorrupted")); |
|
302 } |
|
303 else |
|
304 { |
|
305 TestCase().INFO_PRINTF1(_L("Uncorrupted version of file doesn't exist")); |
|
306 } |
|
307 } |
|
308 else if ((aCorruptionType == 2) || (aCorruptionType == 3) || (aCorruptionType == 4)) |
|
309 { |
|
310 if(uncorruptedFileExists) |
|
311 { |
|
312 TestCase().INFO_PRINTF1(_L("Uncorrupted version of file exists")); |
|
313 |
|
314 // delete uncorrupted version of file |
|
315 error = aFs.Delete(uncorruptedFilePath); |
|
316 |
|
317 if (!((error==KErrNone) || (error==KErrNotFound))) |
|
318 { |
|
319 TestCase().INFO_PRINTF1(_L("Could not delete uncorrupted version of file")); |
|
320 User::Leave(error); |
|
321 } |
|
322 } |
|
323 |
|
324 // move file to be corrupted |
|
325 error = aFs.Rename(aFilePath, uncorruptedFilePath); |
|
326 |
|
327 if (!((error==KErrNone) || (error==KErrNotFound))) |
|
328 { |
|
329 TestCase().INFO_PRINTF2(_L("Cannot move file to be corrupted. Error = %d"), error); |
|
330 User::Leave(error); |
|
331 } |
|
332 |
|
333 if (error==KErrNotFound) |
|
334 { |
|
335 TestCase().INFO_PRINTF1(_L("File to be corrupted does not exist")); |
|
336 } |
|
337 |
|
338 if ((aCorruptionType == 3) || (aCorruptionType == 4)) |
|
339 { |
|
340 RFile fileHandle; |
|
341 |
|
342 // need to create an empty file |
|
343 error = fileHandle.Create(aFs,aFilePath,EFileWrite); |
|
344 |
|
345 if (!(error==KErrNone)) |
|
346 { |
|
347 TestCase().INFO_PRINTF2(_L("Cannot create empty file. Error = %d"), error); |
|
348 User::Leave(error); |
|
349 } |
|
350 |
|
351 CleanupClosePushL(fileHandle); |
|
352 |
|
353 if (aCorruptionType == 4) |
|
354 { |
|
355 // need to add random data to file |
|
356 _LIT(KRandomDataFilePath, "c:\\msgtest\\TestFramework\\ScriptedTestCases\\Corruption\\data\\randomdata.txt"); |
|
357 |
|
358 RFile randomDataFile; |
|
359 |
|
360 error = randomDataFile.Open(aFs,KRandomDataFilePath,EFileRead); |
|
361 |
|
362 if (!(error==KErrNone)) |
|
363 { |
|
364 TestCase().INFO_PRINTF2(_L("Cannot open random data file. Error = %d"), error); |
|
365 User::Leave(error); |
|
366 } |
|
367 |
|
368 CleanupClosePushL(randomDataFile); |
|
369 |
|
370 // read in random data |
|
371 TInt fileSize = 0; |
|
372 User::LeaveIfError(randomDataFile.Size(fileSize)); |
|
373 |
|
374 HBufC8* dataBuffer = HBufC8::NewLC(fileSize); |
|
375 TPtr8 bufferPtr(dataBuffer->Des()); |
|
376 |
|
377 User::LeaveIfError(randomDataFile.Read(bufferPtr)); |
|
378 |
|
379 // write random data to file |
|
380 error = fileHandle.Write(bufferPtr); |
|
381 |
|
382 CleanupStack::PopAndDestroy(1, dataBuffer); // dataBuffer |
|
383 CleanupStack::PopAndDestroy(1, &randomDataFile); // randomDataFile |
|
384 |
|
385 if (!(error==KErrNone)) |
|
386 { |
|
387 TestCase().INFO_PRINTF2(_L("Cannot write random data to file. Error = %d"), error); |
|
388 User::Leave(error); |
|
389 } |
|
390 |
|
391 TestCase().INFO_PRINTF1(_L("File corrupted with random data")); |
|
392 } |
|
393 else |
|
394 { |
|
395 TestCase().INFO_PRINTF1(_L("File corrupted with zero-length data")); |
|
396 } |
|
397 |
|
398 CleanupStack::PopAndDestroy(1, &fileHandle); // fileHandle |
|
399 } |
|
400 else |
|
401 { |
|
402 TestCase().INFO_PRINTF1(_L("File corrupted by removing file")); |
|
403 } |
|
404 } |
|
405 } |