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 31extern "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 45namespace fs = utils::fs; 46namespace sqlite = utils::sqlite; 47 48using utils::none; 49 50 51ATF_TEST_CASE_WITHOUT_HEAD(error__no_filename); 52ATF_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 62ATF_TEST_CASE_WITHOUT_HEAD(error__with_filename); 63ATF_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 73ATF_TEST_CASE_WITHOUT_HEAD(api_error__explicit); 74ATF_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 85ATF_TEST_CASE_WITHOUT_HEAD(api_error__from_database); 86ATF_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 109ATF_TEST_CASE_WITHOUT_HEAD(invalid_column_error); 110ATF_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 120ATF_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