1 /* |
|
2 * Copyright (c) 2008-2009 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 the License "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 * Implements the unit test steps for the SCR Data Layer. |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include "datalayersteps.h" |
|
21 |
|
22 |
|
23 CScrTestDataLayer::CScrTestDataLayer(CScrDataLayerTestServer&) |
|
24 // Constructor. |
|
25 : COomTestStep() |
|
26 { |
|
27 SetTestStepName(KScrDataLayerStep); |
|
28 } |
|
29 |
|
30 CScrTestDataLayer::~CScrTestDataLayer() |
|
31 // Destructor. |
|
32 { |
|
33 } |
|
34 |
|
35 void CScrTestDataLayer::ImplTestStepPreambleL() |
|
36 { |
|
37 } |
|
38 |
|
39 void CScrTestDataLayer::ImplTestStepPostambleL() |
|
40 { |
|
41 } |
|
42 |
|
43 static const TUint MAX_SCR_ERROR_MESSAGE_LENGTH = 512; |
|
44 |
|
45 void CScrTestDataLayer::PrintErrorL(const TDesC& aMsg, TInt aErrNum,...) |
|
46 { |
|
47 VA_LIST list; |
|
48 VA_START(list, aErrNum); |
|
49 |
|
50 RBuf msgBuf; |
|
51 msgBuf.CreateL(MAX_SCR_ERROR_MESSAGE_LENGTH); |
|
52 msgBuf.CleanupClosePushL(); |
|
53 msgBuf.AppendFormatList(aMsg, list); |
|
54 |
|
55 ERR_PRINTF1(msgBuf); |
|
56 SetTestStepResult(EFail); |
|
57 |
|
58 CleanupStack::PopAndDestroy(&msgBuf); |
|
59 User::Leave(aErrNum); |
|
60 } |
|
61 |
|
62 |
|
63 void CScrTestDataLayer::ImplTestStepL() |
|
64 { |
|
65 INFO_PRINTF1(_L("SCR Data Layer Unit Tests")); |
|
66 |
|
67 INFO_PRINTF1(_L(" SEC_SCR_DataLayer_0001: Open database file")); |
|
68 |
|
69 _LIT(KDbFilePath, "c:\\private\\1028634C\\scr.db"); |
|
70 _LIT(KJournalFilePath, "c:\\private\\1028634C\\scr.db-journal"); |
|
71 RFs fs; |
|
72 User::LeaveIfError(fs.Connect()); |
|
73 CleanupClosePushL(fs); |
|
74 RFile databaseFile; |
|
75 User::LeaveIfError(databaseFile.Open(fs, KDbFilePath, EFileShareAny|EFileWrite)); |
|
76 CleanupClosePushL(databaseFile); |
|
77 RFile journalFile; |
|
78 User::LeaveIfError(journalFile.Replace(fs, KJournalFilePath, EFileShareAny|EFileWrite)); |
|
79 CleanupClosePushL(journalFile); |
|
80 CDatabase *db = CDatabase::NewL(databaseFile, journalFile); |
|
81 CleanupStack::PushL(db); |
|
82 |
|
83 INFO_PRINTF1(_L(" SEC_SCR_DataLayer_0001.1: Negative test in LastInsertedIdL")); |
|
84 TRAPD(err, db->LastInsertedIdL()); |
|
85 if (err != KErrNotFound) |
|
86 PrintErrorL(_L("Unexpected error for LastInsertedIdL when nothing was inserted"), err); |
|
87 |
|
88 INFO_PRINTF1(_L(" SEC_SCR_DataLayer_0002: Insert records")); |
|
89 _LIT(KScrTestInsert, "INSERT INTO Components(SoftwareTypeId,InstalledDrivesRefCount,Version,InstallTime) VALUES(?,?,?,?);"); |
|
90 CStatement* stmt = db->PrepareStatementLC(KScrTestInsert()); |
|
91 // Insert first record |
|
92 const TInt KSoftTypeIdRow1 = 1; |
|
93 _LIT(KInstalledDrivesRow1, "123"); |
|
94 _LIT(KVersionRow1, "1.1.1"); |
|
95 InsertRecordL(*stmt, KSoftTypeIdRow1, KInstalledDrivesRow1(), KVersionRow1()); |
|
96 // Insert second record |
|
97 const TInt KSoftTypeIdRow2 = 2; |
|
98 _LIT(KInstalledDrivesRow2, "456"); |
|
99 _LIT(KVersionRow2, "1.1.2"); |
|
100 InsertRecordL(*stmt, KSoftTypeIdRow2, KInstalledDrivesRow2(), KVersionRow2()); |
|
101 CleanupStack::PopAndDestroy(stmt); |
|
102 |
|
103 INFO_PRINTF1(_L(" SEC_SCR_DataLayer_0003: Verify inserted records")); |
|
104 _LIT(KScrTestSelect, "SELECT SoftwareTypeId,InstalledDrivesRefCount,Version FROM Components;"); |
|
105 stmt = db->PrepareStatementLC(KScrTestSelect()); |
|
106 if(!stmt->ProcessNextRowL()) |
|
107 PrintErrorL(_L("Result row set contains unexpected number of records (0)!"), KErrGeneral); |
|
108 VerifyRecordL(*stmt, KSoftTypeIdRow1, KInstalledDrivesRow1, KVersionRow1); |
|
109 if(!stmt->ProcessNextRowL()) |
|
110 PrintErrorL(_L("Result row set contains unexpected number of records (1)!"), KErrGeneral); |
|
111 VerifyRecordL(*stmt, KSoftTypeIdRow2, KInstalledDrivesRow2(), KVersionRow2()); |
|
112 if(stmt->ProcessNextRowL()) |
|
113 PrintErrorL(_L("Result row set contains more records than expected ones (2)!"), KErrGeneral); |
|
114 CleanupStack::PopAndDestroy(stmt); |
|
115 |
|
116 INFO_PRINTF1(_L(" SEC_SCR_DataLayer_0004: Update a record")); |
|
117 _LIT(KScrTestUpdate, "UPDATE Components SET Version=? WHERE InstalledDrivesRefCount=?;"); |
|
118 stmt = db->PrepareStatementLC(KScrTestUpdate()); |
|
119 _LIT(KNewVersionRow2, "6.7.9"); |
|
120 stmt->BindStrL(1, KNewVersionRow2()); |
|
121 stmt->BindStrL(2, KInstalledDrivesRow2()); |
|
122 stmt->ExecuteStatementL(); |
|
123 CleanupStack::PopAndDestroy(stmt); |
|
124 |
|
125 INFO_PRINTF1(_L(" SEC_SCR_DataLayer_0005: Verify updated record")); |
|
126 _LIT(KScrTestSelectCond, "SELECT SoftwareTypeId,InstalledDrivesRefCount,Version FROM Components WHERE InstalledDrivesRefCount=?;"); |
|
127 stmt = db->PrepareStatementLC(KScrTestSelectCond()); |
|
128 stmt->BindStrL(1, KInstalledDrivesRow2()); |
|
129 if(!stmt->ProcessNextRowL()) |
|
130 PrintErrorL(_L("Updated record could not be found!"), KErrGeneral); |
|
131 VerifyRecordL(*stmt, KSoftTypeIdRow2, KInstalledDrivesRow2(), KNewVersionRow2()); |
|
132 CleanupStack::PopAndDestroy(stmt); |
|
133 |
|
134 INFO_PRINTF1(_L(" SEC_SCR_DataLayer_0006: Delete a record")); |
|
135 _LIT(KScrTestDelete, "DELETE FROM Components WHERE InstalledDrivesRefCount=?;"); |
|
136 stmt = db->PrepareStatementLC(KScrTestDelete()); |
|
137 stmt->BindStrL(1, KInstalledDrivesRow1()); |
|
138 stmt->ExecuteStatementL(); |
|
139 CleanupStack::PopAndDestroy(stmt); |
|
140 |
|
141 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0007: Verify deleted record")); |
|
142 _LIT(KScrTestSelectVerify, "SELECT * FROM Components WHERE InstalledDrivesRefCount=?;"); |
|
143 stmt = db->PrepareStatementLC(KScrTestSelectVerify()); |
|
144 stmt->BindStrL(1, KInstalledDrivesRow1()); |
|
145 if(stmt->ProcessNextRowL()) |
|
146 PrintErrorL(_L("Deleted record has been retrieved!"), KErrGeneral); |
|
147 CleanupStack::PopAndDestroy(stmt); |
|
148 |
|
149 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0008: Begin a transaction")); |
|
150 _LIT(KScrTestBegin, "BEGIN TRANSACTION SCRUnitTest;"); |
|
151 stmt = db->PrepareStatementLC(KScrTestBegin()); |
|
152 stmt->ExecuteStatementL(); |
|
153 CleanupStack::PopAndDestroy(stmt); |
|
154 |
|
155 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0009: Insert a record")); |
|
156 stmt = db->PrepareStatementLC(KScrTestInsert()); |
|
157 const TInt KSoftTypeIdRow3 = 1; |
|
158 _LIT(KInstalledDrivesRow3, "789"); |
|
159 _LIT(KVersionRow3, "1.1.3"); |
|
160 InsertRecordL(*stmt, KSoftTypeIdRow3, KInstalledDrivesRow3(), KVersionRow3()); |
|
161 CleanupStack::PopAndDestroy(stmt); |
|
162 |
|
163 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0010: Insert second record")); |
|
164 stmt = db->PrepareStatementLC(KScrTestInsert()); |
|
165 const TInt KSoftTypeIdRow4 = 3; |
|
166 _LIT(KInstalledDrivesRow4, "001"); |
|
167 _LIT(KVersionRow4, "0.0.7"); |
|
168 InsertRecordL(*stmt, KSoftTypeIdRow4, KInstalledDrivesRow4(), KVersionRow4()); |
|
169 CleanupStack::PopAndDestroy(stmt); |
|
170 |
|
171 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0011: Rollback the transaction")); |
|
172 _LIT(KScrTestRollback, "ROLLBACK TRANSACTION SCRUnitTest;"); |
|
173 stmt = db->PrepareStatementLC(KScrTestRollback()); |
|
174 stmt->ExecuteStatementL(); |
|
175 CleanupStack::PopAndDestroy(stmt); |
|
176 |
|
177 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0012: Verify rollback")); |
|
178 stmt = db->PrepareStatementLC(KScrTestSelectVerify()); |
|
179 stmt->BindStrL(1, KInstalledDrivesRow3()); |
|
180 if(stmt->ProcessNextRowL()) |
|
181 PrintErrorL(_L("First record inserted has been retrieved! It should have been rolled back!"), KErrGeneral); |
|
182 stmt->ResetL(); |
|
183 stmt->BindStrL(1, KInstalledDrivesRow4()); |
|
184 if(stmt->ProcessNextRowL()) |
|
185 PrintErrorL(_L("Second record inserted has been retrieved! It should have been rolled back!"), KErrGeneral); |
|
186 CleanupStack::PopAndDestroy(stmt); |
|
187 |
|
188 ExecuteBadStatementL(*db, 13, _L("INSERT INTO Components;")); |
|
189 ExecuteBadStatementL(*db, 14, _L(";")); |
|
190 ExecuteBadStatementL(*db, 15, _L("SELECT * FROM Components;SELECT * FROM Files;")); |
|
191 |
|
192 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0016: Bind to a column which does not exist")); |
|
193 stmt = db->PrepareStatementLC(KScrTestInsert()); |
|
194 TRAP(err, stmt->BindIntL(5, 1)); // There is no 5th column |
|
195 if(err != KErrArgument) |
|
196 PrintErrorL(_L("Unexpected error returned with binding to a non-existing column!"), err); |
|
197 CleanupStack::PopAndDestroy(stmt); |
|
198 |
|
199 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0017: Retrieve the value of a column which does not exist")); |
|
200 stmt = db->PrepareStatementLC(KScrTestSelect()); |
|
201 if(!stmt->ProcessNextRowL()) |
|
202 PrintErrorL(_L("The database is empty!"), KErrGeneral); |
|
203 TRAP(err,TPtrC ptrColX(stmt->StrColumnL(5))); // There is no 5th column |
|
204 if(err != KErrArgument) |
|
205 PrintErrorL(_L("Unexpected error returned with retrieving a non-existing column!"), err); |
|
206 |
|
207 TRAP(err,TPtrC ptrColX(stmt->StrColumnL(-1))); // Check negative value |
|
208 if(err != KErrArgument) |
|
209 PrintErrorL(_L("Unexpected error returned with retrieving a negative column!"), err); |
|
210 |
|
211 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0018: Retrieve the value of a column whose type doesn't match")); |
|
212 TRAP(err,TPtrC ptrCol0(stmt->StrColumnL(0))); // Column0 is integer |
|
213 if(err != KErrArgument) |
|
214 PrintErrorL(_L("Unexpected error returned with retrieving the type mismatched column!"), err); |
|
215 CleanupStack::PopAndDestroy(stmt); |
|
216 |
|
217 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0019: Insert a record - attempt injecting raw SQL in parameters")); |
|
218 stmt = db->PrepareStatementLC(KScrTestInsert()); |
|
219 const TInt KSoftTypeIdRowInject1 = 1; |
|
220 _LIT(KRowInject1, "a?b"); |
|
221 _LIT(KVersionRowInject1, "???"); |
|
222 InsertRecordL(*stmt, KSoftTypeIdRowInject1, KRowInject1(), KVersionRowInject1()); |
|
223 |
|
224 _LIT(KRowInject2, "';<>!?\\/.,~#:"); |
|
225 _LIT(KRowInject3, "\n\r\t\b"); |
|
226 InsertRecordL(*stmt, KSoftTypeIdRowInject1, KRowInject2(), KRowInject3()); |
|
227 |
|
228 CleanupStack::PopAndDestroy(stmt); |
|
229 |
|
230 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0020: Query - attempt injecting raw SQL")); |
|
231 _LIT(KScrInjectTestQuery, "SELECT * FROM Components WHERE ComponentId=?;"); |
|
232 stmt = db->PrepareStatementLC(KScrInjectTestQuery()); |
|
233 stmt->BindStrL(1, KRowInject1()); |
|
234 stmt->ProcessNextRowL(); |
|
235 CleanupStack::PopAndDestroy(stmt); |
|
236 |
|
237 stmt = db->PrepareStatementLC(KScrInjectTestQuery()); |
|
238 stmt->BindStrL(1, KRowInject2()); |
|
239 stmt->ProcessNextRowL(); |
|
240 CleanupStack::PopAndDestroy(stmt); |
|
241 |
|
242 stmt = db->PrepareStatementLC(KScrInjectTestQuery()); |
|
243 stmt->BindStrL(1, KRowInject3()); |
|
244 stmt->ProcessNextRowL(); |
|
245 CleanupStack::PopAndDestroy(stmt); |
|
246 |
|
247 _LIT8(K8BitInstalledDrives, "testInstalledDrives"); |
|
248 _LIT8(K8BitVersion, "testVersion"); |
|
249 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0021: Test 8-bit field support")); |
|
250 stmt = db->PrepareStatementLC(KScrTestInsert()); |
|
251 |
|
252 stmt->BindIntL(1, 1); |
|
253 stmt->BindBinaryL(2, K8BitInstalledDrives()); |
|
254 stmt->BindBinaryL(3, K8BitVersion()); |
|
255 stmt->BindIntL(4, 0); // install time |
|
256 stmt->ExecuteStatementL(); |
|
257 CleanupStack::PopAndDestroy(stmt); |
|
258 // Try and do a select by 8-bit values, followed by their retrieval |
|
259 _LIT(KScr8BitTestQuery, "SELECT InstalledDrivesRefCount, ComponentId FROM Components WHERE Version=?;"); |
|
260 stmt = db->PrepareStatementLC(KScr8BitTestQuery()); |
|
261 stmt->BindBinaryL(1, K8BitVersion()); |
|
262 if(!stmt->ProcessNextRowL()) |
|
263 PrintErrorL(_L("8-bit value SELECT did not match!"), KErrGeneral); |
|
264 TPtrC8 ptrCol(stmt->BinaryColumnL(0)); |
|
265 if (ptrCol != K8BitInstalledDrives) |
|
266 PrintErrorL(_L("8-bit values did not match!"), KErrGeneral); |
|
267 TRAP(err, stmt->BinaryColumnL(1)); |
|
268 if (err != KErrArgument) |
|
269 PrintErrorL(_L("Expected error on non-binary columnb did not match!"), KErrGeneral); |
|
270 |
|
271 CleanupStack::PopAndDestroy(stmt); |
|
272 |
|
273 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0022: Try binding huge parameters")); |
|
274 stmt = db->PrepareStatementLC(KScrInjectTestQuery()); |
|
275 static TUint charsCount = 1024; |
|
276 _LIT(KTestPrefix, "TestValuePrefix"); |
|
277 |
|
278 // Test large localizable property with negative values |
|
279 RBuf propertyValue; |
|
280 propertyValue.CreateL(charsCount * 2 + KTestPrefix().Length()); |
|
281 CleanupClosePushL(propertyValue); |
|
282 propertyValue.Copy(KTestPrefix); |
|
283 const TChar testChar(0xFFFD); |
|
284 propertyValue.AppendFill(testChar, charsCount); |
|
285 TRAP(err, stmt->BindStrL(2, propertyValue)); |
|
286 if (err != KErrArgument) |
|
287 PrintErrorL(_L("Expected error wasn't returned on large parameter!"), KErrGeneral); |
|
288 CleanupStack::PopAndDestroy(&propertyValue); |
|
289 |
|
290 CleanupStack::PopAndDestroy(4, &databaseFile); // databaseFile, journalFile, db, stmt |
|
291 |
|
292 INFO_PRINTF1(_L("SEC_SCR_DataLayer_0023: Open and work on a non-database file")); |
|
293 CDatabase* nondb(0); |
|
294 |
|
295 _LIT(KScrTestNonDbFile, "c:\\private\\1028634C\\nonscr.db"); |
|
296 _LIT(KScrTestNonDbFileJournal, "c:\\private\\1028634C\\nonscr.db-journal"); |
|
297 User::LeaveIfError(databaseFile.Open(fs, KScrTestNonDbFile, EFileShareAny|EFileRead)); |
|
298 CleanupClosePushL(databaseFile); |
|
299 User::LeaveIfError(journalFile.Replace(fs, KScrTestNonDbFileJournal, EFileShareAny|EFileWrite)); |
|
300 CleanupClosePushL(journalFile); |
|
301 nondb = CDatabase::NewL(databaseFile, journalFile); |
|
302 CleanupStack::PushL(nondb); |
|
303 stmt = NULL; |
|
304 TRAP(err, stmt = nondb->PrepareStatementLC(KScrTestSelect())); |
|
305 if (stmt) |
|
306 CleanupStack::PopAndDestroy(stmt); |
|
307 |
|
308 if(err == KErrNoMemory) |
|
309 User::Leave(err); |
|
310 else if(err != KErrNotFound) |
|
311 PrintErrorL(_L("Unexpected error returned with non-database file!"), err); |
|
312 |
|
313 CleanupStack::PopAndDestroy(4, &fs); // fs, databaseFile, journalFile, nondb |
|
314 } |
|
315 |
|
316 void CScrTestDataLayer::InsertRecordL(CStatement& aStmt, TInt aCol1, const TDesC& aCol2, const TDesC& aCol3) |
|
317 { |
|
318 aStmt.BindIntL(1, aCol1); |
|
319 aStmt.BindStrL(2, aCol2); |
|
320 aStmt.BindStrL(3, aCol3); |
|
321 aStmt.BindIntL(4, aCol1); // install time |
|
322 aStmt.ExecuteStatementL(); |
|
323 aStmt.ResetL(); |
|
324 } |
|
325 |
|
326 void CScrTestDataLayer::VerifyRecordL(CStatement& aStmt, TInt aCol1, const TDesC& aCol2, const TDesC& aCol3) |
|
327 { |
|
328 TInt intCol1 = aStmt.IntColumnL(0); |
|
329 TInt64 int64Col1 = aStmt.Int64ColumnL(0); // Due to coverage concerns |
|
330 if((intCol1 != aCol1) || (int64Col1 != aCol1)) |
|
331 { |
|
332 ERR_PRINTF1(_L("The integer column does not match with the returned one.")); |
|
333 SetTestStepResult(EFail); |
|
334 User::Leave(KErrGeneral); |
|
335 } |
|
336 TPtrC ptrCol2(aStmt.StrColumnL(1)); |
|
337 TPtrC ptrCol3(aStmt.StrColumnL(2)); |
|
338 if(ptrCol2.Compare(aCol2) || ptrCol3.Compare(aCol3)) |
|
339 { |
|
340 ERR_PRINTF1(_L("The string column does not match with the returned one.")); |
|
341 SetTestStepResult(EFail); |
|
342 User::Leave(KErrGeneral); |
|
343 } |
|
344 } |
|
345 |
|
346 void CScrTestDataLayer::ExecuteBadStatementL(CDatabase &aDb, TInt aTestNum, const TDesC& aStatement) |
|
347 { |
|
348 INFO_PRINTF3(_L("SEC_SCR_DataLayer_00%d: Run a badly constructed statement (%S)"), aTestNum, &aStatement); |
|
349 CStatement *stmt = NULL; |
|
350 TRAPD(err, stmt = aDb.PrepareStatementLC(aStatement); |
|
351 if(stmt) |
|
352 CleanupStack::PopAndDestroy(stmt););// end of TRAPD |
|
353 if(err != KErrArgument) |
|
354 PrintErrorL(_L("The badly constructed statement did not cause the expected err"), err); |
|
355 } |
|