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 "utils/sqlite/exceptions.hpp" 30 31 extern "C" { 32 #include <sqlite3.h> 33 } 34 35 #include <cstring> 36 #include <string> 37 38 #include <atf-c++.hpp> 39 40 #include "utils/fs/path.hpp" 41 #include "utils/optional.ipp" 42 #include "utils/sqlite/c_gate.hpp" 43 #include "utils/sqlite/database.hpp" 44 45 namespace fs = utils::fs; 46 namespace sqlite = utils::sqlite; 47 48 using utils::none; 49 50 51 ATF_TEST_CASE_WITHOUT_HEAD(error__no_filename); 52 ATF_TEST_CASE_BODY(error__no_filename) 53 { 54 const sqlite::database db = sqlite::database::in_memory(); 55 const sqlite::error e(db.db_filename(), "Some text"); 56 ATF_REQUIRE_EQ("Some text (sqlite db: in-memory or temporary)", 57 std::string(e.what())); 58 ATF_REQUIRE_EQ(db.db_filename(), e.db_filename()); 59 } 60 61 62 ATF_TEST_CASE_WITHOUT_HEAD(error__with_filename); 63 ATF_TEST_CASE_BODY(error__with_filename) 64 { 65 const sqlite::database db = sqlite::database::open( 66 fs::path("test.db"), sqlite::open_readwrite | sqlite::open_create); 67 const sqlite::error e(db.db_filename(), "Some text"); 68 ATF_REQUIRE_EQ("Some text (sqlite db: test.db)", std::string(e.what())); 69 ATF_REQUIRE_EQ(db.db_filename(), e.db_filename()); 70 } 71 72 73 ATF_TEST_CASE_WITHOUT_HEAD(api_error__explicit); 74 ATF_TEST_CASE_BODY(api_error__explicit) 75 { 76 const sqlite::api_error e(none, "some_function", "Some text"); 77 ATF_REQUIRE_EQ( 78 "Some text (sqlite op: some_function) " 79 "(sqlite db: in-memory or temporary)", 80 std::string(e.what())); 81 ATF_REQUIRE_EQ("some_function", e.api_function()); 82 } 83 84 85 ATF_TEST_CASE_WITHOUT_HEAD(api_error__from_database); 86 ATF_TEST_CASE_BODY(api_error__from_database) 87 { 88 sqlite::database db = sqlite::database::open( 89 fs::path("test.db"), sqlite::open_readwrite | sqlite::open_create); 90 91 // Use the raw sqlite3 API to cause an error. Our C++ wrappers catch all 92 // errors and reraise them as exceptions, but here we want to handle the raw 93 // error directly for testing purposes. 94 sqlite::database_c_gate gate(db); 95 ::sqlite3_stmt* dummy_stmt; 96 const char* query = "ABCDE INVALID QUERY"; 97 (void)::sqlite3_prepare_v2(gate.c_database(), query, std::strlen(query), 98 &dummy_stmt, NULL); 99 100 const sqlite::api_error e = sqlite::api_error::from_database( 101 db, "real_function"); 102 ATF_REQUIRE_MATCH( 103 ".*ABCDE.*\\(sqlite op: real_function\\) \\(sqlite db: test.db\\)", 104 std::string(e.what())); 105 ATF_REQUIRE_EQ("real_function", e.api_function()); 106 } 107 108 109 ATF_TEST_CASE_WITHOUT_HEAD(invalid_column_error); 110 ATF_TEST_CASE_BODY(invalid_column_error) 111 { 112 const sqlite::invalid_column_error e(none, "some_name"); 113 ATF_REQUIRE_EQ("Unknown column 'some_name' " 114 "(sqlite db: in-memory or temporary)", 115 std::string(e.what())); 116 ATF_REQUIRE_EQ("some_name", e.column_name()); 117 } 118 119 120 ATF_INIT_TEST_CASES(tcs) 121 { 122 ATF_ADD_TEST_CASE(tcs, error__no_filename); 123 ATF_ADD_TEST_CASE(tcs, error__with_filename); 124 125 ATF_ADD_TEST_CASE(tcs, api_error__explicit); 126 ATF_ADD_TEST_CASE(tcs, api_error__from_database); 127 128 ATF_ADD_TEST_CASE(tcs, invalid_column_error); 129 } 130