Database System 0.1.0
Advanced C++20 Database System with Multi-Backend Support
Loading...
Searching...
No Matches
redis_backend_test.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
16#include <gtest/gtest.h>
17#include <memory>
18#include <string>
19
22
23using namespace database;
24using namespace database::backends;
25using namespace database::core;
26
27// =============================================================================
28// Test Fixture
29// =============================================================================
30
31class RedisBackendTest : public ::testing::Test {
32protected:
33 std::unique_ptr<redis_backend> backend_;
35
36 void SetUp() override
37 {
38 backend_ = std::make_unique<redis_backend>();
39 test_config_.host = "localhost";
40 test_config_.port = 6379;
44 }
45
46 void TearDown() override
47 {
48 if (backend_ && backend_->is_initialized()) {
49 backend_->shutdown();
50 }
51 }
52};
53
54// =============================================================================
55// Type Identification Tests
56// =============================================================================
57
58TEST_F(RedisBackendTest, TypeReturnsRedis)
59{
60 EXPECT_EQ(backend_->type(), database_types::redis);
61}
62
63TEST_F(RedisBackendTest, BackendNameIsCorrect)
64{
65 EXPECT_STREQ(redis_backend::backend_name(), "redis_backend");
66}
67
68// =============================================================================
69// Initial State Tests
70// =============================================================================
71
72TEST_F(RedisBackendTest, InitiallyNotInitialized)
73{
74 EXPECT_FALSE(backend_->is_initialized());
75}
76
77TEST_F(RedisBackendTest, InitiallyNotInTransaction)
78{
79 EXPECT_FALSE(backend_->in_transaction());
80}
81
82// =============================================================================
83// Operations Without Initialization Tests
84// =============================================================================
85
86TEST_F(RedisBackendTest, ExecuteQueryFailsWithoutInit)
87{
88 auto result = backend_->execute_query("mykey:myvalue");
89 EXPECT_FALSE(result.is_ok());
90}
91
92TEST_F(RedisBackendTest, SelectQueryFailsWithoutInit)
93{
94 auto result = backend_->select_query("mykey");
95 EXPECT_FALSE(result.is_ok());
96}
97
98TEST_F(RedisBackendTest, BeginTransactionFailsWithoutInit)
99{
100 auto result = backend_->begin_transaction();
101 EXPECT_FALSE(result.is_ok());
102}
103
104TEST_F(RedisBackendTest, CommitTransactionFailsWithoutInit)
105{
106 auto result = backend_->commit_transaction();
107 EXPECT_FALSE(result.is_ok());
108}
109
110TEST_F(RedisBackendTest, RollbackTransactionFailsWithoutInit)
111{
112 auto result = backend_->rollback_transaction();
113 EXPECT_FALSE(result.is_ok());
114}
115
116// =============================================================================
117// Lifecycle Guard Tests (via backend_base)
118// =============================================================================
119
120TEST_F(RedisBackendTest, ShutdownWithoutInitIsNoOp)
121{
122 auto result = backend_->shutdown();
123 EXPECT_TRUE(result.is_ok());
124}
125
126// =============================================================================
127// Factory Method Tests
128// =============================================================================
129
130TEST_F(RedisBackendTest, CreateReturnsValidBackend)
131{
132 auto backend = redis_backend::create();
133 ASSERT_NE(backend, nullptr);
134 EXPECT_EQ(backend->type(), database_types::redis);
135 EXPECT_FALSE(backend->is_initialized());
136}
137
138// =============================================================================
139// Connection Info Tests
140// =============================================================================
141
142TEST_F(RedisBackendTest, ConnectionInfoBeforeInit)
143{
144 auto info = backend_->connection_info();
145 SUCCEED();
146}
147
148TEST_F(RedisBackendTest, LastErrorBeforeInit)
149{
150 auto error = backend_->last_error();
151 SUCCEED();
152}
153
154// =============================================================================
155// Real Connection Tests (conditional on USE_REDIS)
156// =============================================================================
157
158#ifdef USE_REDIS
159
160TEST_F(RedisBackendTest, ConnectToLocalRedis)
161{
162 connection_config config;
163 config.host = "localhost";
164 config.port = 6379;
165
166 auto result = backend_->initialize(config);
167 if (!result.is_ok()) {
168 GTEST_SKIP() << "Local Redis not available: " << backend_->last_error();
169 }
170
171 EXPECT_TRUE(backend_->is_initialized());
172}
173
174TEST_F(RedisBackendTest, KeyValueOperationsOnRedis)
175{
176 connection_config config;
177 config.host = "localhost";
178 config.port = 6379;
179
180 if (!backend_->initialize(config).is_ok()) {
181 GTEST_SKIP() << "Local Redis not available";
182 }
183
184 // SET (insert)
185 auto insert_result = backend_->execute_query("redis_test_key:test_value");
186 EXPECT_TRUE(insert_result.is_ok());
187
188 // GET (select)
189 auto select_result = backend_->select_query("redis_test_key");
190 ASSERT_TRUE(select_result.is_ok());
191 EXPECT_FALSE(select_result.value().empty());
192
193 // SET (update - same key, new value)
194 auto update_result = backend_->execute_query("redis_test_key:updated_value");
195 EXPECT_TRUE(update_result.is_ok());
196
197 // DEL (delete)
198 auto delete_result = backend_->execute_query("redis_test_key");
199 EXPECT_TRUE(delete_result.is_ok());
200
201 // Verify deletion
202 auto verify_result = backend_->select_query("redis_test_key");
203 if (verify_result.is_ok()) {
204 EXPECT_TRUE(verify_result.value().empty());
205 }
206}
207
208TEST_F(RedisBackendTest, TransactionsOnRedis)
209{
210 connection_config config;
211 config.host = "localhost";
212 config.port = 6379;
213
214 if (!backend_->initialize(config).is_ok()) {
215 GTEST_SKIP() << "Local Redis not available";
216 }
217
218 // Redis MULTI/EXEC
219 EXPECT_TRUE(backend_->begin_transaction().is_ok());
220 EXPECT_TRUE(backend_->in_transaction());
221
222 backend_->execute_query("redis_tx_key:tx_value");
223
224 EXPECT_TRUE(backend_->commit_transaction().is_ok());
225 EXPECT_FALSE(backend_->in_transaction());
226
227 // Cleanup
228 backend_->execute_query("redis_tx_key");
229}
230
231TEST_F(RedisBackendTest, TransactionRollbackOnRedis)
232{
233 connection_config config;
234 config.host = "localhost";
235 config.port = 6379;
236
237 if (!backend_->initialize(config).is_ok()) {
238 GTEST_SKIP() << "Local Redis not available";
239 }
240
241 // Redis DISCARD
242 EXPECT_TRUE(backend_->begin_transaction().is_ok());
243 backend_->execute_query("redis_discard_key:value");
244 EXPECT_TRUE(backend_->rollback_transaction().is_ok());
245 EXPECT_FALSE(backend_->in_transaction());
246}
247
248#endif // USE_REDIS
249
250int main(int argc, char** argv)
251{
252 ::testing::InitGoogleTest(&argc, argv);
253 return RUN_ALL_TESTS();
254}
connection_config test_config_
std::unique_ptr< redis_backend > backend_
void SetUp() override
void TearDown() override
static constexpr const char * backend_name()
Backend name for error messages.
Abstract interface for database backends.
Redis database backend plugin implementation.
TEST_F(RedisBackendTest, TypeReturnsRedis)
Configuration for database connection.
#define ASSERT_TRUE(condition, message)