20#include <gtest/gtest.h>
61 auto result = backend_.
initialize(test_config_);
62 EXPECT_TRUE(result.is_ok());
63 EXPECT_TRUE(backend_.is_initialized());
68 backend_.initialize(test_config_);
69 auto conn_str = backend_.get_connection_string();
70 EXPECT_FALSE(conn_str.empty());
71 EXPECT_NE(conn_str.find(
"localhost"), std::string::npos);
72 EXPECT_NE(conn_str.find(
"test_db"), std::string::npos);
77 backend_.simulate_initialization_failure(
"Custom error");
78 auto result = backend_.initialize(test_config_);
79 EXPECT_FALSE(result.is_ok());
80 EXPECT_FALSE(backend_.is_initialized());
85 backend_.simulate_initialization_failure();
86 auto result = backend_.initialize(test_config_);
87 EXPECT_FALSE(result.is_ok());
88 EXPECT_EQ(backend_.last_error(),
"Mock initialization failed");
93 backend_.initialize(test_config_);
94 EXPECT_TRUE(backend_.is_initialized());
96 auto result = backend_.shutdown();
97 EXPECT_TRUE(result.is_ok());
98 EXPECT_FALSE(backend_.is_initialized());
103 backend_.initialize(test_config_);
104 backend_.simulate_shutdown();
105 EXPECT_FALSE(backend_.is_initialized());
114 backend_.set_database_type(database_types::sqlite);
115 EXPECT_EQ(backend_.type(), database_types::sqlite);
121 EXPECT_EQ(fresh_backend.
type(), database_types::none);
130 auto result = backend_.execute_query(
"INSERT INTO users (name) VALUES ('John')");
136 backend_.expect_query(
"INSERT INTO users (name) VALUES ('John')")
137 .will_fail(
"Duplicate key violation");
139 auto result = backend_.execute_query(
"INSERT INTO users (name) VALUES ('John')");
140 EXPECT_FALSE(result.is_ok());
145 auto result = backend_.execute_query(
"UPDATE users SET name = 'Jane' WHERE id = 1");
151 auto result = backend_.execute_query(
"DELETE FROM users WHERE id = 1");
162 {{
"id", int64_t(1)}, {
"name", std::string(
"Alice")}},
163 {{
"id", int64_t(2)}, {
"name", std::string(
"Bob")}}
166 backend_.expect_query(
"SELECT * FROM users")
167 .will_return(expected_data);
169 auto result = backend_.select_query(
"SELECT * FROM users");
171 EXPECT_EQ(result.value().size(), 2u);
173 auto& row0 = result.value()[0];
174 EXPECT_EQ(std::get<int64_t>(row0.at(
"id")), 1);
175 EXPECT_EQ(std::get<std::string>(row0.at(
"name")),
"Alice");
180 backend_.expect_query(
"SELECT * FROM empty_table")
183 auto result = backend_.select_query(
"SELECT * FROM empty_table");
185 EXPECT_TRUE(result.value().empty());
191 {{
"count", int64_t(42)}}
193 backend_.set_default_select_result(default_data);
195 auto result = backend_.select_query(
"SELECT COUNT(*) FROM anything");
197 EXPECT_EQ(result.value().size(), 1u);
198 EXPECT_EQ(std::get<int64_t>(result.value()[0].at(
"count")), 42);
207 auto result = backend_.execute_query(
"CREATE TABLE test (id INTEGER)");
208 EXPECT_TRUE(result.is_ok());
213 backend_.expect_query(
"DROP TABLE nonexistent")
214 .will_fail(
"Table does not exist");
216 auto result = backend_.execute_query(
"DROP TABLE nonexistent");
217 EXPECT_FALSE(result.is_ok());
226 EXPECT_FALSE(backend_.in_transaction());
231 EXPECT_TRUE(backend_.begin_transaction().is_ok());
232 EXPECT_TRUE(backend_.in_transaction());
237 backend_.begin_transaction();
238 EXPECT_TRUE(backend_.commit_transaction().is_ok());
239 EXPECT_FALSE(backend_.in_transaction());
244 backend_.begin_transaction();
245 EXPECT_TRUE(backend_.rollback_transaction().is_ok());
246 EXPECT_FALSE(backend_.in_transaction());
251 backend_.begin_transaction();
252 auto result = backend_.begin_transaction();
253 EXPECT_FALSE(result.is_ok());
255 EXPECT_TRUE(backend_.in_transaction());
260 auto result = backend_.commit_transaction();
261 EXPECT_FALSE(result.is_ok());
266 auto result = backend_.rollback_transaction();
267 EXPECT_FALSE(result.is_ok());
273 EXPECT_TRUE(backend_.begin_transaction().is_ok());
274 EXPECT_TRUE(backend_.in_transaction());
275 EXPECT_TRUE(backend_.commit_transaction().is_ok());
276 EXPECT_FALSE(backend_.in_transaction());
279 EXPECT_TRUE(backend_.begin_transaction().is_ok());
280 EXPECT_TRUE(backend_.in_transaction());
281 EXPECT_TRUE(backend_.rollback_transaction().is_ok());
282 EXPECT_FALSE(backend_.in_transaction());
287 backend_.initialize(test_config_);
288 backend_.begin_transaction();
289 EXPECT_TRUE(backend_.in_transaction());
292 EXPECT_FALSE(backend_.in_transaction());
302 {{
"id", int64_t(1)}, {
"name", std::string(
"Test")}}
305 backend_.expect_pattern(
"SELECT.*FROM users.*")
306 .will_return(expected);
308 auto result = backend_.select_query(
"SELECT id, name FROM users WHERE id = 1");
310 EXPECT_EQ(result.value().size(), 1u);
315 auto r1 = backend_.execute_query(
"INSERT INTO a VALUES (1)");
316 auto r2 = backend_.execute_query(
"UPDATE b SET x = 1");
317 auto r3 = backend_.execute_query(
"DELETE FROM c WHERE id = 1");
319 EXPECT_TRUE(r1.is_ok());
320 EXPECT_TRUE(r2.is_ok());
321 EXPECT_TRUE(r3.is_ok());
330 backend_.execute_query(
"INSERT INTO t1 VALUES (1)");
331 backend_.select_query(
"SELECT * FROM t1");
332 backend_.execute_query(
"UPDATE t1 SET x = 2");
334 auto queries = backend_.get_executed_queries();
335 EXPECT_EQ(queries.size(), 3u);
336 EXPECT_EQ(queries[0],
"INSERT INTO t1 VALUES (1)");
337 EXPECT_EQ(queries[1],
"SELECT * FROM t1");
338 EXPECT_EQ(queries[2],
"UPDATE t1 SET x = 2");
343 backend_.execute_query(
"q1");
344 backend_.execute_query(
"q2");
345 backend_.select_query(
"q3");
347 EXPECT_EQ(backend_.get_query_count(), 3u);
352 backend_.execute_query(
"INSERT INTO users VALUES (1)");
353 backend_.execute_query(
"INSERT INTO orders VALUES (1)");
354 backend_.select_query(
"SELECT * FROM users");
356 EXPECT_EQ(backend_.get_query_count(
"INSERT"), 2u);
357 EXPECT_EQ(backend_.get_query_count(
"users"), 2u);
358 EXPECT_EQ(backend_.get_query_count(
"orders"), 1u);
363 backend_.execute_query(
"q1");
364 backend_.clear_history();
365 EXPECT_EQ(backend_.get_query_count(), 0u);
366 EXPECT_TRUE(backend_.get_executed_queries().empty());
371 backend_.expect_query(
"q1").will_return_rows(10);
372 backend_.clear_expectations();
375 auto result = backend_.execute_query(
"q1");
381 backend_.initialize(test_config_);
382 backend_.begin_transaction();
383 backend_.execute_query(
"q1");
384 backend_.expect_query(
"q2").will_return_rows(5);
388 EXPECT_FALSE(backend_.is_initialized());
389 EXPECT_FALSE(backend_.in_transaction());
390 EXPECT_EQ(backend_.get_query_count(), 0u);
391 EXPECT_TRUE(backend_.get_connection_string().empty());
400 backend_.expect_query(
"q1").will_return_rows(1).once();
401 backend_.execute_query(
"q1");
402 EXPECT_TRUE(backend_.verify_all_expectations());
407 backend_.expect_query(
"q1").will_return_rows(1).once();
409 EXPECT_FALSE(backend_.verify_all_expectations());
418 backend_.initialize(test_config_);
419 auto info = backend_.connection_info();
421 EXPECT_FALSE(info.empty());
422 EXPECT_EQ(info.at(
"type"),
"mock");
423 EXPECT_EQ(info.at(
"initialized"),
"true");
428 EXPECT_TRUE(backend_.last_error().empty());
438 auto result = db.select_query(
"SELECT * FROM anything");
440 EXPECT_TRUE(result.value().empty());
446 {{
"id", int64_t(1)}, {
"name", std::string(
"Test")}}
450 auto result = db.select_query(
"SELECT * FROM users WHERE id = 1");
452 EXPECT_EQ(result.value().size(), 1u);
458 auto result = db.select_query(
"SELECT * FROM users");
459 EXPECT_FALSE(result.is_ok());
469 {
"string_col", std::string(
"hello")},
470 {
"int_col", int64_t(42)},
471 {
"double_col", double(3.14)},
473 {
"null_col",
nullptr}
476 backend_.expect_query(
"SELECT *").will_return(data);
477 auto result = backend_.select_query(
"SELECT *");
481 auto& row = result.value()[0];
482 EXPECT_EQ(std::get<std::string>(row.at(
"string_col")),
"hello");
483 EXPECT_EQ(std::get<int64_t>(row.at(
"int_col")), 42);
484 EXPECT_DOUBLE_EQ(std::get<double>(row.at(
"double_col")), 3.14);
485 EXPECT_EQ(std::get<bool>(row.at(
"bool_col")),
true);
486 EXPECT_EQ(std::get<std::nullptr_t>(row.at(
"null_col")),
nullptr);
495 constexpr int num_threads = 10;
496 constexpr int queries_per_thread = 50;
497 std::vector<std::thread> threads;
499 for (
int t = 0; t < num_threads; ++t) {
500 threads.emplace_back([
this, t]() {
501 for (
int q = 0; q < queries_per_thread; ++q) {
502 std::string query =
"INSERT INTO t" + std::to_string(t) +
503 " VALUES (" + std::to_string(q) +
")";
504 backend_.execute_query(query);
509 for (
auto& t : threads) {
513 EXPECT_EQ(backend_.get_query_count(),
514 static_cast<size_t>(num_threads * queries_per_thread));
523 backend_.initialize(test_config_);
524 backend_.set_database_type(database_types::sqlite);
525 backend_.execute_query(
"q1");
530 EXPECT_EQ(moved.
type(), database_types::sqlite);
536 backend_.initialize(test_config_);
537 backend_.execute_query(
"q1");
540 target = std::move(backend_);
548 ::testing::InitGoogleTest(&argc, argv);
549 return RUN_ALL_TESTS();
TEST_F(BackendContractTest, InitializeSucceeds)
connection_config test_config_
static mock_backend failing_database(const std::string &error="Mock database error")
static mock_backend with_data(const std::string &table_name, const core::database_result &data)
static mock_backend empty_database()
Configurable mock for database_backend interface.
size_t get_query_count() const
bool is_initialized() const override
Check if backend is initialized and ready.
kcenon::common::VoidResult initialize(const core::connection_config &config) override
Initialize the database backend.
mock_backend & set_database_type(database_types type)
database_types type() const override
Get the database type of this backend.
Abstract interface for database backends.
std::vector< database_row > database_result
Configuration for database connection.
#define ASSERT_EQ(expected, actual, message)
#define ASSERT_TRUE(condition, message)