comparison UnitTestsSources/SQLiteChromiumTests.cpp @ 967:dfc076546821

add suffix Tests to unit test sources
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 27 Jun 2014 15:36:38 +0200
parents UnitTestsSources/SQLiteChromium.cpp@84513f2ee1f3
children 6e7e5ed91c2d
comparison
equal deleted inserted replaced
966:886652370ff2 967:dfc076546821
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege,
4 * Belgium
5 *
6 * This program is free software: you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, either version 3 of the
9 * License, or (at your option) any later version.
10 *
11 * In addition, as a special exception, the copyright holders of this
12 * program give permission to link the code of its release with the
13 * OpenSSL project's "OpenSSL" library (or with modified versions of it
14 * that use the same license as the "OpenSSL" library), and distribute
15 * the linked executables. You must obey the GNU General Public License
16 * in all respects for all of the code used other than "OpenSSL". If you
17 * modify file(s) with this exception, you may extend this exception to
18 * your version of the file(s), but you are not obligated to do so. If
19 * you do not wish to do so, delete this exception statement from your
20 * version. If you delete this exception statement from all source files
21 * in the program, then also delete it here.
22 *
23 * This program is distributed in the hope that it will be useful, but
24 * WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program. If not, see <http://www.gnu.org/licenses/>.
30 **/
31
32
33 #include "PrecompiledHeadersUnitTests.h"
34 #include "gtest/gtest.h"
35
36 #include "../Core/Toolbox.h"
37 #include "../Core/SQLite/Connection.h"
38 #include "../Core/SQLite/Statement.h"
39 #include "../Core/SQLite/Transaction.h"
40
41 #include <sqlite3.h>
42
43
44 using namespace Orthanc;
45 using namespace Orthanc::SQLite;
46
47
48 /********************************************************************
49 ** Tests from
50 ** http://src.chromium.org/viewvc/chrome/trunk/src/sql/connection_unittest.cc
51 ********************************************************************/
52
53 class SQLConnectionTest : public testing::Test
54 {
55 public:
56 SQLConnectionTest()
57 {
58 }
59
60 virtual ~SQLConnectionTest()
61 {
62 }
63
64 virtual void SetUp()
65 {
66 db_.OpenInMemory();
67 }
68
69 virtual void TearDown()
70 {
71 db_.Close();
72 }
73
74 Connection& db()
75 {
76 return db_;
77 }
78
79 private:
80 Connection db_;
81 };
82
83
84
85 TEST_F(SQLConnectionTest, Execute)
86 {
87 // Valid statement should return true.
88 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
89 EXPECT_EQ(SQLITE_OK, db().GetErrorCode());
90
91 // Invalid statement should fail.
92 ASSERT_EQ(SQLITE_ERROR,
93 db().ExecuteAndReturnErrorCode("CREATE TAB foo (a, b"));
94 EXPECT_EQ(SQLITE_ERROR, db().GetErrorCode());
95 }
96
97 TEST_F(SQLConnectionTest, ExecuteWithErrorCode) {
98 ASSERT_EQ(SQLITE_OK,
99 db().ExecuteAndReturnErrorCode("CREATE TABLE foo (a, b)"));
100 ASSERT_EQ(SQLITE_ERROR,
101 db().ExecuteAndReturnErrorCode("CREATE TABLE TABLE"));
102 ASSERT_EQ(SQLITE_ERROR,
103 db().ExecuteAndReturnErrorCode(
104 "INSERT INTO foo(a, b) VALUES (1, 2, 3, 4)"));
105 }
106
107 TEST_F(SQLConnectionTest, CachedStatement) {
108 StatementId id1("foo", 12);
109 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
110 ASSERT_TRUE(db().Execute("INSERT INTO foo(a, b) VALUES (12, 13)"));
111
112 // Create a new cached statement.
113 {
114 Statement s(db(), id1, "SELECT a FROM foo");
115 ASSERT_TRUE(s.Step());
116 EXPECT_EQ(12, s.ColumnInt(0));
117 }
118
119 // The statement should be cached still.
120 EXPECT_TRUE(db().HasCachedStatement(id1));
121
122 {
123 // Get the same statement using different SQL. This should ignore our
124 // SQL and use the cached one (so it will be valid).
125 Statement s(db(), id1, "something invalid(");
126 ASSERT_TRUE(s.Step());
127 EXPECT_EQ(12, s.ColumnInt(0));
128 }
129
130 // Make sure other statements aren't marked as cached.
131 EXPECT_FALSE(db().HasCachedStatement(SQLITE_FROM_HERE));
132 }
133
134 TEST_F(SQLConnectionTest, IsSQLValidTest) {
135 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
136 ASSERT_TRUE(db().IsSQLValid("SELECT a FROM foo"));
137 ASSERT_FALSE(db().IsSQLValid("SELECT no_exist FROM foo"));
138 }
139
140
141
142 TEST_F(SQLConnectionTest, DoesStuffExist) {
143 // Test DoesTableExist.
144 EXPECT_FALSE(db().DoesTableExist("foo"));
145 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
146 EXPECT_TRUE(db().DoesTableExist("foo"));
147
148 // Should be case sensitive.
149 EXPECT_FALSE(db().DoesTableExist("FOO"));
150
151 // Test DoesColumnExist.
152 EXPECT_FALSE(db().DoesColumnExist("foo", "bar"));
153 EXPECT_TRUE(db().DoesColumnExist("foo", "a"));
154
155 // Testing for a column on a nonexistent table.
156 EXPECT_FALSE(db().DoesColumnExist("bar", "b"));
157 }
158
159 TEST_F(SQLConnectionTest, GetLastInsertRowId) {
160 ASSERT_TRUE(db().Execute("CREATE TABLE foo (id INTEGER PRIMARY KEY, value)"));
161
162 ASSERT_TRUE(db().Execute("INSERT INTO foo (value) VALUES (12)"));
163
164 // Last insert row ID should be valid.
165 int64_t row = db().GetLastInsertRowId();
166 EXPECT_LT(0, row);
167
168 // It should be the primary key of the row we just inserted.
169 Statement s(db(), "SELECT value FROM foo WHERE id=?");
170 s.BindInt64(0, row);
171 ASSERT_TRUE(s.Step());
172 EXPECT_EQ(12, s.ColumnInt(0));
173 }
174
175 TEST_F(SQLConnectionTest, Rollback) {
176 ASSERT_TRUE(db().BeginTransaction());
177 ASSERT_TRUE(db().BeginTransaction());
178 EXPECT_EQ(2, db().GetTransactionNesting());
179 db().RollbackTransaction();
180 EXPECT_FALSE(db().CommitTransaction());
181 EXPECT_TRUE(db().BeginTransaction());
182 }
183
184
185
186
187 /********************************************************************
188 ** Tests from
189 ** http://src.chromium.org/viewvc/chrome/trunk/src/sql/statement_unittest.cc
190 ********************************************************************/
191
192 namespace Orthanc
193 {
194 namespace SQLite
195 {
196 class SQLStatementTest : public SQLConnectionTest
197 {
198 };
199
200 TEST_F(SQLStatementTest, Run) {
201 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
202 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)"));
203
204 Statement s(db(), "SELECT b FROM foo WHERE a=?");
205 // Stepping it won't work since we haven't bound the value.
206 EXPECT_FALSE(s.Step());
207
208 // Run should fail since this produces output, and we should use Step(). This
209 // gets a bit wonky since sqlite says this is OK so succeeded is set.
210 s.Reset(true);
211 s.BindInt(0, 3);
212 EXPECT_FALSE(s.Run());
213 EXPECT_EQ(SQLITE_ROW, db().GetErrorCode());
214
215 // Resetting it should put it back to the previous state (not runnable).
216 s.Reset(true);
217
218 // Binding and stepping should produce one row.
219 s.BindInt(0, 3);
220 EXPECT_TRUE(s.Step());
221 EXPECT_EQ(12, s.ColumnInt(0));
222 EXPECT_FALSE(s.Step());
223 }
224
225 TEST_F(SQLStatementTest, BasicErrorCallback) {
226 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a INTEGER PRIMARY KEY, b)"));
227 // Insert in the foo table the primary key. It is an error to insert
228 // something other than an number. This error causes the error callback
229 // handler to be called with SQLITE_MISMATCH as error code.
230 Statement s(db(), "INSERT INTO foo (a) VALUES (?)");
231 s.BindCString(0, "bad bad");
232 EXPECT_THROW(s.Run(), OrthancException);
233 }
234
235 TEST_F(SQLStatementTest, Reset) {
236 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
237 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (3, 12)"));
238 ASSERT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (4, 13)"));
239
240 Statement s(db(), "SELECT b FROM foo WHERE a = ? ");
241 s.BindInt(0, 3);
242 ASSERT_TRUE(s.Step());
243 EXPECT_EQ(12, s.ColumnInt(0));
244 ASSERT_FALSE(s.Step());
245
246 s.Reset(false);
247 // Verify that we can get all rows again.
248 ASSERT_TRUE(s.Step());
249 EXPECT_EQ(12, s.ColumnInt(0));
250 EXPECT_FALSE(s.Step());
251
252 s.Reset(true);
253 ASSERT_FALSE(s.Step());
254 }
255 }
256 }
257
258
259
260
261
262
263 /********************************************************************
264 ** Tests from
265 ** http://src.chromium.org/viewvc/chrome/trunk/src/sql/transaction_unittest.cc
266 ********************************************************************/
267
268 class SQLTransactionTest : public SQLConnectionTest
269 {
270 public:
271 virtual void SetUp()
272 {
273 SQLConnectionTest::SetUp();
274 ASSERT_TRUE(db().Execute("CREATE TABLE foo (a, b)"));
275 }
276
277 // Returns the number of rows in table "foo".
278 int CountFoo()
279 {
280 Statement count(db(), "SELECT count(*) FROM foo");
281 count.Step();
282 return count.ColumnInt(0);
283 }
284 };
285
286
287 TEST_F(SQLTransactionTest, Commit) {
288 {
289 Transaction t(db());
290 EXPECT_FALSE(t.IsOpen());
291 t.Begin();
292 EXPECT_TRUE(t.IsOpen());
293
294 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
295
296 t.Commit();
297 EXPECT_FALSE(t.IsOpen());
298 }
299
300 EXPECT_EQ(1, CountFoo());
301 }
302
303 TEST_F(SQLTransactionTest, Rollback) {
304 // Test some basic initialization, and that rollback runs when you exit the
305 // scope.
306 {
307 Transaction t(db());
308 EXPECT_FALSE(t.IsOpen());
309 t.Begin();
310 EXPECT_TRUE(t.IsOpen());
311
312 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
313 }
314
315 // Nothing should have been committed since it was implicitly rolled back.
316 EXPECT_EQ(0, CountFoo());
317
318 // Test explicit rollback.
319 Transaction t2(db());
320 EXPECT_FALSE(t2.IsOpen());
321 t2.Begin();
322
323 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
324 t2.Rollback();
325 EXPECT_FALSE(t2.IsOpen());
326
327 // Nothing should have been committed since it was explicitly rolled back.
328 EXPECT_EQ(0, CountFoo());
329 }
330
331 // Rolling back any part of a transaction should roll back all of them.
332 TEST_F(SQLTransactionTest, NestedRollback) {
333 EXPECT_EQ(0, db().GetTransactionNesting());
334
335 // Outermost transaction.
336 {
337 Transaction outer(db());
338 outer.Begin();
339 EXPECT_EQ(1, db().GetTransactionNesting());
340
341 // The first inner one gets committed.
342 {
343 Transaction inner1(db());
344 inner1.Begin();
345 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
346 EXPECT_EQ(2, db().GetTransactionNesting());
347
348 inner1.Commit();
349 EXPECT_EQ(1, db().GetTransactionNesting());
350 }
351
352 // One row should have gotten inserted.
353 EXPECT_EQ(1, CountFoo());
354
355 // The second inner one gets rolled back.
356 {
357 Transaction inner2(db());
358 inner2.Begin();
359 EXPECT_TRUE(db().Execute("INSERT INTO foo (a, b) VALUES (1, 2)"));
360 EXPECT_EQ(2, db().GetTransactionNesting());
361
362 inner2.Rollback();
363 EXPECT_EQ(1, db().GetTransactionNesting());
364 }
365
366 // A third inner one will fail in Begin since one has already been rolled
367 // back.
368 EXPECT_EQ(1, db().GetTransactionNesting());
369 {
370 Transaction inner3(db());
371 EXPECT_THROW(inner3.Begin(), OrthancException);
372 EXPECT_EQ(1, db().GetTransactionNesting());
373 }
374 }
375 EXPECT_EQ(0, db().GetTransactionNesting());
376 EXPECT_EQ(0, CountFoo());
377 }