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