1 // Copyright 2011 The Kyua Authors. 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 "store/read_backend.hpp" 30 31 #include <atf-c++.hpp> 32 33 #include "store/exceptions.hpp" 34 #include "store/metadata.hpp" 35 #include "store/write_backend.hpp" 36 #include "utils/fs/operations.hpp" 37 #include "utils/fs/path.hpp" 38 #include "utils/logging/operations.hpp" 39 #include "utils/sqlite/database.hpp" 40 #include "utils/sqlite/exceptions.hpp" 41 42 namespace fs = utils::fs; 43 namespace logging = utils::logging; 44 namespace sqlite = utils::sqlite; 45 46 47 ATF_TEST_CASE_WITHOUT_HEAD(detail__open_and_setup__ok); 48 ATF_TEST_CASE_BODY(detail__open_and_setup__ok) 49 { 50 { 51 sqlite::database db = sqlite::database::open( 52 fs::path("test.db"), sqlite::open_readwrite | sqlite::open_create); 53 db.exec("CREATE TABLE one (foo INTEGER PRIMARY KEY AUTOINCREMENT);"); 54 db.exec("CREATE TABLE two (foo INTEGER REFERENCES one);"); 55 db.close(); 56 } 57 58 sqlite::database db = store::detail::open_and_setup( 59 fs::path("test.db"), sqlite::open_readwrite); 60 db.exec("INSERT INTO one (foo) VALUES (12);"); 61 // Ensure foreign keys have been enabled. 62 db.exec("INSERT INTO two (foo) VALUES (12);"); 63 ATF_REQUIRE_THROW(sqlite::error, 64 db.exec("INSERT INTO two (foo) VALUES (34);")); 65 } 66 67 68 ATF_TEST_CASE_WITHOUT_HEAD(detail__open_and_setup__missing_file); 69 ATF_TEST_CASE_BODY(detail__open_and_setup__missing_file) 70 { 71 ATF_REQUIRE_THROW_RE(store::error, "Cannot open 'missing.db': ", 72 store::detail::open_and_setup(fs::path("missing.db"), 73 sqlite::open_readonly)); 74 ATF_REQUIRE(!fs::exists(fs::path("missing.db"))); 75 } 76 77 78 ATF_TEST_CASE(read_backend__open_ro__ok); 79 ATF_TEST_CASE_HEAD(read_backend__open_ro__ok) 80 { 81 logging::set_inmemory(); 82 set_md_var("require.files", store::detail::schema_file().c_str()); 83 } 84 ATF_TEST_CASE_BODY(read_backend__open_ro__ok) 85 { 86 { 87 sqlite::database db = sqlite::database::open( 88 fs::path("test.db"), sqlite::open_readwrite | sqlite::open_create); 89 store::detail::initialize(db); 90 } 91 store::read_backend backend = store::read_backend::open_ro( 92 fs::path("test.db")); 93 backend.database().exec("SELECT * FROM metadata"); 94 } 95 96 97 ATF_TEST_CASE_WITHOUT_HEAD(read_backend__open_ro__missing_file); 98 ATF_TEST_CASE_BODY(read_backend__open_ro__missing_file) 99 { 100 ATF_REQUIRE_THROW_RE(store::error, "Cannot open 'missing.db': ", 101 store::read_backend::open_ro(fs::path("missing.db"))); 102 ATF_REQUIRE(!fs::exists(fs::path("missing.db"))); 103 } 104 105 106 ATF_TEST_CASE(read_backend__open_ro__integrity_error); 107 ATF_TEST_CASE_HEAD(read_backend__open_ro__integrity_error) 108 { 109 logging::set_inmemory(); 110 set_md_var("require.files", store::detail::schema_file().c_str()); 111 } 112 ATF_TEST_CASE_BODY(read_backend__open_ro__integrity_error) 113 { 114 { 115 sqlite::database db = sqlite::database::open( 116 fs::path("test.db"), sqlite::open_readwrite | sqlite::open_create); 117 store::detail::initialize(db); 118 db.exec("DELETE FROM metadata"); 119 } 120 ATF_REQUIRE_THROW_RE(store::integrity_error, "metadata.*empty", 121 store::read_backend::open_ro(fs::path("test.db"))); 122 } 123 124 125 ATF_TEST_CASE(read_backend__close); 126 ATF_TEST_CASE_HEAD(read_backend__close) 127 { 128 logging::set_inmemory(); 129 set_md_var("require.files", store::detail::schema_file().c_str()); 130 } 131 ATF_TEST_CASE_BODY(read_backend__close) 132 { 133 store::write_backend::open_rw(fs::path("test.db")); // Create database. 134 store::read_backend backend = store::read_backend::open_ro( 135 fs::path("test.db")); 136 backend.database().exec("SELECT * FROM metadata"); 137 backend.close(); 138 ATF_REQUIRE_THROW(utils::sqlite::error, 139 backend.database().exec("SELECT * FROM metadata")); 140 } 141 142 143 ATF_INIT_TEST_CASES(tcs) 144 { 145 ATF_ADD_TEST_CASE(tcs, detail__open_and_setup__ok); 146 ATF_ADD_TEST_CASE(tcs, detail__open_and_setup__missing_file); 147 148 ATF_ADD_TEST_CASE(tcs, read_backend__open_ro__ok); 149 ATF_ADD_TEST_CASE(tcs, read_backend__open_ro__missing_file); 150 ATF_ADD_TEST_CASE(tcs, read_backend__open_ro__integrity_error); 151 ATF_ADD_TEST_CASE(tcs, read_backend__close); 152 } 153