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 42namespace fs = utils::fs; 43namespace logging = utils::logging; 44namespace sqlite = utils::sqlite; 45 46 47ATF_TEST_CASE_WITHOUT_HEAD(detail__open_and_setup__ok); 48ATF_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 68ATF_TEST_CASE_WITHOUT_HEAD(detail__open_and_setup__missing_file); 69ATF_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 78ATF_TEST_CASE(read_backend__open_ro__ok); 79ATF_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} 84ATF_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 97ATF_TEST_CASE_WITHOUT_HEAD(read_backend__open_ro__missing_file); 98ATF_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 106ATF_TEST_CASE(read_backend__open_ro__integrity_error); 107ATF_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} 112ATF_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 125ATF_TEST_CASE(read_backend__close); 126ATF_TEST_CASE_HEAD(read_backend__close) 127{ 128 logging::set_inmemory(); 129 set_md_var("require.files", store::detail::schema_file().c_str()); 130} 131ATF_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 143ATF_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