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