1 // Copyright 2011 Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 #include "utils/sqlite/database.hpp"
30
31 #include <atf-c++.hpp>
32
33 #include "utils/fs/operations.hpp"
34 #include "utils/fs/path.hpp"
35 #include "utils/sqlite/statement.ipp"
36 #include "utils/sqlite/test_utils.hpp"
37 #include "utils/sqlite/transaction.hpp"
38
39 namespace fs = utils::fs;
40 namespace sqlite = utils::sqlite;
41
42
43 ATF_TEST_CASE_WITHOUT_HEAD(in_memory);
ATF_TEST_CASE_BODY(in_memory)44 ATF_TEST_CASE_BODY(in_memory)
45 {
46 sqlite::database db = sqlite::database::in_memory();
47 create_test_table(raw(db));
48 verify_test_table(raw(db));
49
50 ATF_REQUIRE(!fs::exists(fs::path(":memory:")));
51 }
52
53
54 ATF_TEST_CASE_WITHOUT_HEAD(open__readonly__ok);
ATF_TEST_CASE_BODY(open__readonly__ok)55 ATF_TEST_CASE_BODY(open__readonly__ok)
56 {
57 {
58 ::sqlite3* db;
59 ATF_REQUIRE_EQ(SQLITE_OK, ::sqlite3_open_v2("test.db", &db,
60 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL));
61 create_test_table(db);
62 ::sqlite3_close(db);
63 }
64 {
65 sqlite::database db = sqlite::database::open(fs::path("test.db"),
66 sqlite::open_readonly);
67 verify_test_table(raw(db));
68 }
69 }
70
71
72 ATF_TEST_CASE_WITHOUT_HEAD(open__readonly__fail);
ATF_TEST_CASE_BODY(open__readonly__fail)73 ATF_TEST_CASE_BODY(open__readonly__fail)
74 {
75 REQUIRE_API_ERROR("sqlite3_open_v2",
76 sqlite::database::open(fs::path("missing.db"), sqlite::open_readonly));
77 ATF_REQUIRE(!fs::exists(fs::path("missing.db")));
78 }
79
80
81 ATF_TEST_CASE_WITHOUT_HEAD(open__create__ok);
ATF_TEST_CASE_BODY(open__create__ok)82 ATF_TEST_CASE_BODY(open__create__ok)
83 {
84 {
85 sqlite::database db = sqlite::database::open(fs::path("test.db"),
86 sqlite::open_readwrite | sqlite::open_create);
87 ATF_REQUIRE(fs::exists(fs::path("test.db")));
88 create_test_table(raw(db));
89 }
90 {
91 ::sqlite3* db;
92 ATF_REQUIRE_EQ(SQLITE_OK, ::sqlite3_open_v2("test.db", &db,
93 SQLITE_OPEN_READONLY, NULL));
94 verify_test_table(db);
95 ::sqlite3_close(db);
96 }
97 }
98
99
100 ATF_TEST_CASE(open__create__fail);
ATF_TEST_CASE_HEAD(open__create__fail)101 ATF_TEST_CASE_HEAD(open__create__fail)
102 {
103 set_md_var("require.user", "unprivileged");
104 }
ATF_TEST_CASE_BODY(open__create__fail)105 ATF_TEST_CASE_BODY(open__create__fail)
106 {
107 fs::mkdir(fs::path("protected"), 0555);
108 REQUIRE_API_ERROR("sqlite3_open_v2",
109 sqlite::database::open(fs::path("protected/test.db"),
110 sqlite::open_readwrite | sqlite::open_create));
111 }
112
113
114 ATF_TEST_CASE_WITHOUT_HEAD(temporary);
ATF_TEST_CASE_BODY(temporary)115 ATF_TEST_CASE_BODY(temporary)
116 {
117 // We could validate if files go to disk by setting the temp_store_directory
118 // PRAGMA to a subdirectory of pwd, and then ensuring the subdirectory is
119 // not empty. However, there does not seem to be a way to force SQLite to
120 // unconditionally write the temporary database to disk (even with
121 // temp_store = FILE), so this scenary is hard to reproduce.
122 sqlite::database db = sqlite::database::temporary();
123 create_test_table(raw(db));
124 verify_test_table(raw(db));
125 }
126
127
128 ATF_TEST_CASE_WITHOUT_HEAD(close);
ATF_TEST_CASE_BODY(close)129 ATF_TEST_CASE_BODY(close)
130 {
131 sqlite::database db = sqlite::database::in_memory();
132 db.close();
133 // The destructor for the database will run now. If it does a second close,
134 // we may crash, so let's see if we don't.
135 }
136
137
138 ATF_TEST_CASE_WITHOUT_HEAD(copy);
ATF_TEST_CASE_BODY(copy)139 ATF_TEST_CASE_BODY(copy)
140 {
141 sqlite::database db1 = sqlite::database::in_memory();
142 {
143 sqlite::database db2 = sqlite::database::in_memory();
144 create_test_table(raw(db2));
145 db1 = db2;
146 verify_test_table(raw(db1));
147 }
148 // db2 went out of scope. If the destruction is not properly managed, the
149 // memory of db1 may have been invalidated and this would not work.
150 verify_test_table(raw(db1));
151 }
152
153
154 ATF_TEST_CASE_WITHOUT_HEAD(exec__ok);
ATF_TEST_CASE_BODY(exec__ok)155 ATF_TEST_CASE_BODY(exec__ok)
156 {
157 sqlite::database db = sqlite::database::in_memory();
158 db.exec(create_test_table_sql);
159 verify_test_table(raw(db));
160 }
161
162
163 ATF_TEST_CASE_WITHOUT_HEAD(exec__fail);
ATF_TEST_CASE_BODY(exec__fail)164 ATF_TEST_CASE_BODY(exec__fail)
165 {
166 sqlite::database db = sqlite::database::in_memory();
167 REQUIRE_API_ERROR("sqlite3_exec",
168 db.exec("SELECT * FROM test"));
169 REQUIRE_API_ERROR("sqlite3_exec",
170 db.exec("CREATE TABLE test (col INTEGER PRIMARY KEY);"
171 "FOO BAR"));
172 db.exec("SELECT * FROM test");
173 }
174
175
176 ATF_TEST_CASE_WITHOUT_HEAD(create_statement__ok);
ATF_TEST_CASE_BODY(create_statement__ok)177 ATF_TEST_CASE_BODY(create_statement__ok)
178 {
179 sqlite::database db = sqlite::database::in_memory();
180 sqlite::statement stmt = db.create_statement("SELECT 3");
181 // Statement testing happens in statement_test. We are only interested here
182 // in ensuring that the API call exists and runs.
183 }
184
185
186 ATF_TEST_CASE_WITHOUT_HEAD(begin_transaction);
ATF_TEST_CASE_BODY(begin_transaction)187 ATF_TEST_CASE_BODY(begin_transaction)
188 {
189 sqlite::database db = sqlite::database::in_memory();
190 sqlite::transaction stmt = db.begin_transaction();
191 // Transaction testing happens in transaction_test. We are only interested
192 // here in ensuring that the API call exists and runs.
193 }
194
195
196 ATF_TEST_CASE_WITHOUT_HEAD(create_statement__fail);
ATF_TEST_CASE_BODY(create_statement__fail)197 ATF_TEST_CASE_BODY(create_statement__fail)
198 {
199 sqlite::database db = sqlite::database::in_memory();
200 REQUIRE_API_ERROR("sqlite3_prepare_v2",
201 db.create_statement("SELECT * FROM missing"));
202 }
203
204
205 ATF_TEST_CASE_WITHOUT_HEAD(last_insert_rowid);
ATF_TEST_CASE_BODY(last_insert_rowid)206 ATF_TEST_CASE_BODY(last_insert_rowid)
207 {
208 sqlite::database db = sqlite::database::in_memory();
209 db.exec("CREATE TABLE test (a INTEGER PRIMARY KEY, b INTEGER)");
210 db.exec("INSERT INTO test VALUES (723, 5)");
211 ATF_REQUIRE_EQ(723, db.last_insert_rowid());
212 db.exec("INSERT INTO test VALUES (145, 20)");
213 ATF_REQUIRE_EQ(145, db.last_insert_rowid());
214 }
215
216
ATF_INIT_TEST_CASES(tcs)217 ATF_INIT_TEST_CASES(tcs)
218 {
219 ATF_ADD_TEST_CASE(tcs, in_memory);
220
221 ATF_ADD_TEST_CASE(tcs, open__readonly__ok);
222 ATF_ADD_TEST_CASE(tcs, open__readonly__fail);
223 ATF_ADD_TEST_CASE(tcs, open__create__ok);
224 ATF_ADD_TEST_CASE(tcs, open__create__fail);
225
226 ATF_ADD_TEST_CASE(tcs, temporary);
227
228 ATF_ADD_TEST_CASE(tcs, close);
229
230 ATF_ADD_TEST_CASE(tcs, copy);
231
232 ATF_ADD_TEST_CASE(tcs, exec__ok);
233 ATF_ADD_TEST_CASE(tcs, exec__fail);
234
235 ATF_ADD_TEST_CASE(tcs, begin_transaction);
236
237 ATF_ADD_TEST_CASE(tcs, create_statement__ok);
238 ATF_ADD_TEST_CASE(tcs, create_statement__fail);
239
240 ATF_ADD_TEST_CASE(tcs, last_insert_rowid);
241 }
242