|
1 // Copyright (c) 2006-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 // |
|
15 |
|
16 #include <e32test.h> |
|
17 #include <f32file.h> |
|
18 #include <sqldb.h> |
|
19 |
|
20 /////////////////////////////////////////////////////////////////////////////////////// |
|
21 |
|
22 static RFs TheFs; |
|
23 static RTest TheTest(_L("t_sqldefect2 test")); |
|
24 static RSqlDatabase TheDb1; |
|
25 static RSqlDatabase TheDb2; |
|
26 |
|
27 _LIT(KTestDir, "c:\\test\\"); |
|
28 _LIT(KTestDatabase1, "c:\\test\\t_sqldefect2.db"); |
|
29 _LIT(KTestDatabaseJournal1, "c:\\test\\t_sqldefect2.db-journal"); |
|
30 |
|
31 |
|
32 /////////////////////////////////////////////////////////////////////////////////////// |
|
33 |
|
34 //Deletes all created test files. |
|
35 void DestroyTestEnv() |
|
36 { |
|
37 TheDb2.Close(); |
|
38 TheDb1.Close(); |
|
39 (void)RSqlDatabase::Delete(KTestDatabase1); |
|
40 TheFs.Close(); |
|
41 } |
|
42 |
|
43 /////////////////////////////////////////////////////////////////////////////////////// |
|
44 /////////////////////////////////////////////////////////////////////////////////////// |
|
45 //Test macros and functions |
|
46 void Check1(TInt aValue, TInt aLine) |
|
47 { |
|
48 if(!aValue) |
|
49 { |
|
50 DestroyTestEnv(); |
|
51 RDebug::Print(_L("*** Line %d\r\n"), aLine); |
|
52 TheTest(EFalse, aLine); |
|
53 } |
|
54 } |
|
55 void Check2(TInt aValue, TInt aExpected, TInt aLine) |
|
56 { |
|
57 if(aValue != aExpected) |
|
58 { |
|
59 DestroyTestEnv(); |
|
60 RDebug::Print(_L("*** Line %d, Expected error: %d, got: %d\r\n"), aLine, aExpected, aValue); |
|
61 TheTest(EFalse, aLine); |
|
62 } |
|
63 } |
|
64 #define TEST(arg) ::Check1((arg), __LINE__) |
|
65 #define TEST2(aValue, aExpected) ::Check2(aValue, aExpected, __LINE__) |
|
66 |
|
67 /////////////////////////////////////////////////////////////////////////////////////// |
|
68 |
|
69 //Creates file session instance and the test directory |
|
70 void CreateTestEnv() |
|
71 { |
|
72 TInt err = TheFs.Connect(); |
|
73 TEST2(err, KErrNone); |
|
74 |
|
75 err = TheFs.MkDir(KTestDir); |
|
76 TEST(err == KErrNone || err == KErrAlreadyExists); |
|
77 } |
|
78 |
|
79 /** |
|
80 @SYMTestCaseID PDS-SQL-CT-4154 |
|
81 @SYMTestCaseDesc Test for DEF143062: SQL, "CREATE INDEX" sql crashes SQL server. |
|
82 The test creates a database with one empty table and establishes two connections |
|
83 to that database. Then, while the first connection is at the middle of a read |
|
84 transaction, the second connection attempts to create an index. |
|
85 If the defect is not fixed, the SQL server will crash. |
|
86 @SYMTestPriority High |
|
87 @SYMTestActions DEF143062: SQL, "CREATE INDEX" sql crashes SQL server. |
|
88 @SYMTestExpectedResults Test must not fail |
|
89 @SYMDEF DEF143062 |
|
90 */ |
|
91 void DEF143062() |
|
92 { |
|
93 (void)RSqlDatabase::Delete(KTestDatabase1); |
|
94 TInt err = TheDb1.Create(KTestDatabase1); |
|
95 TEST2(err, KErrNone); |
|
96 err = TheDb1.Exec(_L("CREATE TABLE T0(Thread INTEGER, LocalIndex INTEGER, Inserts INTEGER, Updates INTEGER, IndexMod8 INTEGER)")); |
|
97 TEST(err >= 0); |
|
98 |
|
99 err = TheDb2.Open(KTestDatabase1); |
|
100 TEST2(err, KErrNone); |
|
101 |
|
102 RSqlStatement stmt; |
|
103 err = stmt.Prepare(TheDb1, _L8("SELECT COUNT(Thread) FROM T0 WHERE Thread = 0")); |
|
104 TEST2(err, KErrNone); |
|
105 err = stmt.Next(); |
|
106 TEST2(err, KSqlAtRow); |
|
107 |
|
108 err = TheDb2.Exec(_L8("CREATE INDEX T0INDEX ON T0(Thread,IndexMod8)"));//crashes the SQL server if the defect is not fixed |
|
109 TEST2(err, KSqlErrLocked); |
|
110 |
|
111 stmt.Close(); |
|
112 |
|
113 TheDb2.Close(); |
|
114 TheDb1.Close(); |
|
115 err = RSqlDatabase::Delete(KTestDatabase1); |
|
116 TEST2(err, KErrNone); |
|
117 } |
|
118 |
|
119 /** |
|
120 @SYMTestCaseID PDS-SQL-CT-4155 |
|
121 @SYMTestCaseDesc Test for DEF143061: SQL, SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT value is too big. |
|
122 The test verifies that after comitting a big transaction, the journal file size is made equal the |
|
123 max journal file size limit of 64Kb. |
|
124 @SYMTestPriority High |
|
125 @SYMTestActions DEF143061: SQL, SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT value is too big.. |
|
126 @SYMTestExpectedResults Test must not fail |
|
127 @SYMDEF DEF143061 |
|
128 */ |
|
129 void DEF143061() |
|
130 { |
|
131 (void)RSqlDatabase::Delete(KTestDatabase1); |
|
132 //"Auto" compaction is used in order to see how the journal file is immediatelly used. |
|
133 _LIT8(KConfig, "compaction=auto"); |
|
134 TInt err = TheDb1.Create(KTestDatabase1, &KConfig); |
|
135 TEST2(err, KErrNone); |
|
136 err = TheDb1.Exec(_L("CREATE TABLE A(I INTEGER, B BLOB)")); |
|
137 TEST(err >= 0); |
|
138 |
|
139 const TInt KBlobSize = 100000;//bigger than the journal size limit |
|
140 HBufC8* buf = HBufC8::New(KBlobSize); |
|
141 TEST(buf != NULL); |
|
142 TPtr8 ptr = buf->Des(); |
|
143 ptr.SetLength(KBlobSize); |
|
144 |
|
145 RSqlStatement stmt; |
|
146 err = stmt.Prepare(TheDb1, _L("INSERT INTO A VALUES(1, :Prm)")); |
|
147 TEST2(err, KErrNone); |
|
148 ptr.Fill(TChar('N')); |
|
149 err = stmt.BindBinary(0, ptr); |
|
150 TEST2(err, KErrNone); |
|
151 err = stmt.Exec(); |
|
152 TEST2(err, 1); |
|
153 stmt.Close(); |
|
154 |
|
155 //Try to update the BLOB in the record that was just inserted. This operation should create a big journal file. |
|
156 err = stmt.Prepare(TheDb1, _L("UPDATE A SET B=:Prm WHERE I=1")); |
|
157 TEST2(err, KErrNone); |
|
158 ptr.Fill(TChar('Y')); |
|
159 err = stmt.BindBinary(0, ptr); |
|
160 TEST2(err, KErrNone); |
|
161 err = stmt.Exec(); |
|
162 TEST2(err, 1); |
|
163 stmt.Close(); |
|
164 |
|
165 //Check the journal file size. It should be less than the 64Kb limit defined in sqlite_macro.mmh file. |
|
166 TEntry entry; |
|
167 err = TheFs.Entry(KTestDatabaseJournal1, entry); |
|
168 TEST2(err, KErrNone); |
|
169 TInt64 fsize = entry.FileSize(); |
|
170 TEST(fsize <= SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT); |
|
171 |
|
172 delete buf; |
|
173 TheDb1.Close(); |
|
174 err = RSqlDatabase::Delete(KTestDatabase1); |
|
175 TEST2(err, KErrNone); |
|
176 } |
|
177 |
|
178 /** |
|
179 @SYMTestCaseID PDS-SQL-CT-4156 |
|
180 @SYMTestCaseDesc Test for DEF143150: SQL, strftime() returns incorrect result. |
|
181 The test takes the current universal time (using TTime) |
|
182 and the current time retrieved from the SQL server. |
|
183 The test compares the times and expects the difference to be no more than |
|
184 1 second. |
|
185 @SYMTestPriority High |
|
186 @SYMTestActions DEF143150: SQL, strftime() returns incorrect result |
|
187 @SYMTestExpectedResults Test must not fail |
|
188 @SYMDEF DEF143150 |
|
189 */ |
|
190 void DEF143150() |
|
191 { |
|
192 (void)RSqlDatabase::Delete(KTestDatabase1); |
|
193 TInt err = TheDb1.Create(KTestDatabase1); |
|
194 TEST2(err, KErrNone); |
|
195 |
|
196 //Home date & time |
|
197 TBuf<50> dtstr1; |
|
198 TTime time; |
|
199 time.UniversalTime(); |
|
200 TDateTime dt = time.DateTime(); |
|
201 |
|
202 RSqlStatement stmt; |
|
203 err = stmt.Prepare(TheDb1, _L("SELECT strftime('%Y-%m-%d,%H:%M:%S','now')")); |
|
204 TEST2(err, KErrNone); |
|
205 err = stmt.Next(); |
|
206 TEST2(err, KSqlAtRow); |
|
207 |
|
208 //SQLite date & time |
|
209 TBuf<50> dtstr2; |
|
210 err = stmt.ColumnText(0, dtstr2); |
|
211 TEST2(err, KErrNone); |
|
212 stmt.Close(); |
|
213 |
|
214 TheDb1.Close(); |
|
215 err = RSqlDatabase::Delete(KTestDatabase1); |
|
216 TEST2(err, KErrNone); |
|
217 |
|
218 dtstr1.Format(_L("%04d-%02d-%02d,%02d:%02d:%02d"), dt.Year(), dt.Month() + 1, dt.Day() + 1, dt.Hour(), dt.Minute(), dt.Second()); |
|
219 TheTest.Printf(_L("Universal date&time=\"%S\"\n"), &dtstr1); |
|
220 TheTest.Printf(_L("SQLite date&time=\"%S\"\n"), &dtstr2); |
|
221 |
|
222 //Comapare and fail if dates are not equal (+- 1 second) |
|
223 TLex lex; |
|
224 lex = dtstr2.Mid(0, 4); |
|
225 TInt sqlyear; |
|
226 err = lex.Val(sqlyear); |
|
227 TEST2(err, KErrNone); |
|
228 |
|
229 lex = dtstr2.Mid(5, 2); |
|
230 TInt sqlmonth; |
|
231 err = lex.Val(sqlmonth); |
|
232 TEST2(err, KErrNone); |
|
233 |
|
234 lex = dtstr2.Mid(8, 2); |
|
235 TInt sqlday; |
|
236 err = lex.Val(sqlday); |
|
237 TEST2(err, KErrNone); |
|
238 |
|
239 lex = dtstr2.Mid(11, 2); |
|
240 TInt sqlhour; |
|
241 err = lex.Val(sqlhour); |
|
242 TEST2(err, KErrNone); |
|
243 |
|
244 lex = dtstr2.Mid(14, 2); |
|
245 TInt sqlminute; |
|
246 err = lex.Val(sqlminute); |
|
247 TEST2(err, KErrNone); |
|
248 |
|
249 lex = dtstr2.Mid(17, 2); |
|
250 TInt sqlsecond; |
|
251 err = lex.Val(sqlsecond); |
|
252 TEST2(err, KErrNone); |
|
253 |
|
254 TDateTime sqldt(sqlyear, (TMonth)(sqlmonth - 1), sqlday - 1, sqlhour, sqlminute, sqlsecond, 0); |
|
255 TTime sqltime(sqldt); |
|
256 TTimeIntervalSeconds diff; |
|
257 err = sqltime.SecondsFrom(time, diff); |
|
258 TEST2(err, KErrNone); |
|
259 TEST(diff.Int() <= 1); |
|
260 } |
|
261 |
|
262 void DoTestsL() |
|
263 { |
|
264 TheTest.Start(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-4154 DEF143062: SQL, \"CREATE INDEX\" sql crashes SQL server")); |
|
265 DEF143062(); |
|
266 |
|
267 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-4155 DEF143061: SQL, SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT value is too big")); |
|
268 DEF143061(); |
|
269 |
|
270 TheTest.Next(_L(" @SYMTestCaseID:SYSLIB-SQL-CT-4156 DEF143150: SQL, strftime() returns incorrect result")); |
|
271 DEF143150(); |
|
272 } |
|
273 |
|
274 TInt E32Main() |
|
275 { |
|
276 TheTest.Title(); |
|
277 |
|
278 CTrapCleanup* tc = CTrapCleanup::New(); |
|
279 |
|
280 __UHEAP_MARK; |
|
281 |
|
282 CreateTestEnv(); |
|
283 TRAPD(err, DoTestsL()); |
|
284 DestroyTestEnv(); |
|
285 TEST2(err, KErrNone); |
|
286 |
|
287 __UHEAP_MARKEND; |
|
288 |
|
289 TheTest.End(); |
|
290 TheTest.Close(); |
|
291 |
|
292 delete tc; |
|
293 |
|
294 User::Heap().Check(); |
|
295 return KErrNone; |
|
296 } |