Database System 0.1.0
Advanced C++20 Database System with Multi-Backend Support
Loading...
Searching...
No Matches
backend_registry_test.cpp File Reference
#include <algorithm>
#include <atomic>
#include <gtest/gtest.h>
#include <memory>
#include <string>
#include <thread>
#include <vector>
#include "database/core/backend_base.h"
#include "database/core/backend_registry.h"
#include "database/core/database_backend.h"
Include dependency graph for backend_registry_test.cpp:

Go to the source code of this file.

Classes

class  BackendRegistryTest
 

Functions

 TEST_F (BackendRegistryTest, RegisterBackendSucceeds)
 
 TEST_F (BackendRegistryTest, RegisterMultipleBackends)
 
 TEST_F (BackendRegistryTest, DuplicateRegistrationFails)
 
 TEST_F (BackendRegistryTest, UnregisterExistingBackend)
 
 TEST_F (BackendRegistryTest, UnregisterNonExistentBackendFails)
 
 TEST_F (BackendRegistryTest, CreateRegisteredBackend)
 
 TEST_F (BackendRegistryTest, CreateUnregisteredBackendReturnsNull)
 
 TEST_F (BackendRegistryTest, CreateReturnsDistinctInstances)
 
 TEST_F (BackendRegistryTest, CreatedBackendIsNotInitialized)
 
 TEST_F (BackendRegistryTest, HasBackendReturnsTrueForRegistered)
 
 TEST_F (BackendRegistryTest, HasBackendReturnsFalseForUnregistered)
 
 TEST_F (BackendRegistryTest, AvailableBackendsListsAll)
 
 TEST_F (BackendRegistryTest, BackendCountMatchesRegistrations)
 
 TEST_F (BackendRegistryTest, EmptyRegistryHasZeroCount)
 
 TEST_F (BackendRegistryTest, ClearRemovesAllBackends)
 
 TEST_F (BackendRegistryTest, ReRegisterAfterClear)
 
 TEST_F (BackendRegistryTest, ConvenienceCreateBackend)
 
 TEST_F (BackendRegistryTest, ConvenienceHasBackend)
 
 TEST_F (BackendRegistryTest, ConvenienceAvailableBackends)
 
 TEST_F (BackendRegistryTest, ConcurrentRegistration)
 
 TEST_F (BackendRegistryTest, ConcurrentCreation)
 
 TEST_F (BackendRegistryTest, ConcurrentRegistrationAndQuery)
 
 TEST_F (BackendRegistryTest, EmptyNameRegistration)
 
 TEST_F (BackendRegistryTest, RegisterUnregisterRegister)
 
 TEST_F (BackendRegistryTest, SingletonConsistency)
 
int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int argc,
char ** argv )

Definition at line 461 of file backend_registry_test.cpp.

462{
463 ::testing::InitGoogleTest(&argc, argv);
464 return RUN_ALL_TESTS();
465}

◆ TEST_F() [1/25]

TEST_F ( BackendRegistryTest ,
AvailableBackendsListsAll  )

Definition at line 261 of file backend_registry_test.cpp.

262{
263 backend_registry::instance().register_backend("alpha", &test_backend::create);
264 backend_registry::instance().register_backend("beta", &test_backend_alt::create);
265
267 EXPECT_EQ(backends.size(), 2u);
268 EXPECT_TRUE(std::find(backends.begin(), backends.end(), "alpha") != backends.end());
269 EXPECT_TRUE(std::find(backends.begin(), backends.end(), "beta") != backends.end());
270}
std::vector< std::string > available_backends() const
Get list of all registered backend names.
static backend_registry & instance()
Get the singleton instance.
kcenon::common::VoidResult register_backend(const std::string &name, backend_factory_fn factory)
Register a backend factory function.

References database::core::backend_registry::available_backends(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [2/25]

TEST_F ( BackendRegistryTest ,
BackendCountMatchesRegistrations  )

Definition at line 272 of file backend_registry_test.cpp.

273{
274 EXPECT_EQ(backend_registry::instance().backend_count(), 0u);
275 backend_registry::instance().register_backend("a", &test_backend::create);
276 EXPECT_EQ(backend_registry::instance().backend_count(), 1u);
277 backend_registry::instance().register_backend("b", &test_backend_alt::create);
278 EXPECT_EQ(backend_registry::instance().backend_count(), 2u);
279}

References database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [3/25]

TEST_F ( BackendRegistryTest ,
ClearRemovesAllBackends  )

Definition at line 291 of file backend_registry_test.cpp.

292{
293 backend_registry::instance().register_backend("a", &test_backend::create);
294 backend_registry::instance().register_backend("b", &test_backend_alt::create);
295 EXPECT_EQ(backend_registry::instance().backend_count(), 2u);
296
298 EXPECT_EQ(backend_registry::instance().backend_count(), 0u);
299 EXPECT_FALSE(backend_registry::instance().has_backend("a"));
300 EXPECT_FALSE(backend_registry::instance().has_backend("b"));
301}
void clear()
Clear all registered backends (for testing)
bool has_backend(const std::string &name)
Convenience function for checking backend availability.

References database::core::backend_registry::clear(), database::core::has_backend(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [4/25]

TEST_F ( BackendRegistryTest ,
ConcurrentCreation  )

Definition at line 370 of file backend_registry_test.cpp.

371{
372 backend_registry::instance().register_backend("test", &test_backend::create);
373
374 constexpr int num_threads = 20;
375 std::atomic<int> success_count{0};
376 std::vector<std::thread> threads;
377
378 for (int i = 0; i < num_threads; ++i) {
379 threads.emplace_back([&success_count]() {
380 auto backend = backend_registry::instance().create("test");
381 if (backend != nullptr) {
382 success_count++;
383 }
384 });
385 }
386
387 for (auto& t : threads) {
388 t.join();
389 }
390
391 EXPECT_EQ(success_count.load(), num_threads);
392}
std::unique_ptr< database_backend > create(const std::string &name) const
Create a backend instance by name.

References database::core::backend_registry::create(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [5/25]

TEST_F ( BackendRegistryTest ,
ConcurrentRegistration  )

Definition at line 345 of file backend_registry_test.cpp.

346{
347 constexpr int num_threads = 10;
348 std::atomic<int> success_count{0};
349 std::vector<std::thread> threads;
350
351 for (int i = 0; i < num_threads; ++i) {
352 threads.emplace_back([i, &success_count]() {
354 "backend_" + std::to_string(i), &test_backend::create);
355 if (result.is_ok()) {
356 success_count++;
357 }
358 });
359 }
360
361 for (auto& t : threads) {
362 t.join();
363 }
364
365 EXPECT_EQ(success_count.load(), num_threads);
366 EXPECT_EQ(backend_registry::instance().backend_count(),
367 static_cast<size_t>(num_threads));
368}

References database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [6/25]

TEST_F ( BackendRegistryTest ,
ConcurrentRegistrationAndQuery  )

Definition at line 394 of file backend_registry_test.cpp.

395{
396 constexpr int num_threads = 10;
397 std::vector<std::thread> threads;
398
399 // Register in parallel
400 for (int i = 0; i < num_threads; ++i) {
401 threads.emplace_back([i]() {
403 "backend_" + std::to_string(i), &test_backend::create);
404 });
405 }
406
407 // Query in parallel at the same time
408 for (int i = 0; i < num_threads; ++i) {
409 threads.emplace_back([]() {
410 // These may or may not find backends depending on timing
413 });
414 }
415
416 for (auto& t : threads) {
417 t.join();
418 }
419
420 // All registrations should eventually succeed
421 EXPECT_EQ(backend_registry::instance().backend_count(),
422 static_cast<size_t>(num_threads));
423}
size_t backend_count() const
Get number of registered backends.

References database::core::backend_registry::available_backends(), database::core::backend_registry::backend_count(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [7/25]

TEST_F ( BackendRegistryTest ,
ConvenienceAvailableBackends  )

Definition at line 333 of file backend_registry_test.cpp.

334{
335 backend_registry::instance().register_backend("x", &test_backend::create);
336 auto backends = available_backends();
337 EXPECT_EQ(backends.size(), 1u);
338 EXPECT_EQ(backends[0], "x");
339}
std::vector< std::string > available_backends()
Convenience function for getting available backends.

References database::core::available_backends(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [8/25]

TEST_F ( BackendRegistryTest ,
ConvenienceCreateBackend  )

Definition at line 318 of file backend_registry_test.cpp.

319{
320 backend_registry::instance().register_backend("test", &test_backend::create);
321 auto backend = create_backend("test");
322 ASSERT_NE(backend, nullptr);
323 EXPECT_EQ(backend->type(), database_types::sqlite);
324}
std::unique_ptr< database_backend > create_backend(const std::string &name)
Convenience function for creating backends (static method style)

References database::core::create_backend(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [9/25]

TEST_F ( BackendRegistryTest ,
ConvenienceHasBackend  )

Definition at line 326 of file backend_registry_test.cpp.

327{
328 backend_registry::instance().register_backend("test", &test_backend::create);
329 EXPECT_TRUE(has_backend("test"));
330 EXPECT_FALSE(has_backend("nonexistent"));
331}

References database::core::has_backend(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [10/25]

TEST_F ( BackendRegistryTest ,
CreatedBackendIsNotInitialized  )

Definition at line 238 of file backend_registry_test.cpp.

239{
240 backend_registry::instance().register_backend("test", &test_backend::create);
241 auto backend = backend_registry::instance().create("test");
242 ASSERT_NE(backend, nullptr);
243 EXPECT_FALSE(backend->is_initialized());
244}

References database::core::backend_registry::create(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [11/25]

TEST_F ( BackendRegistryTest ,
CreateRegisteredBackend  )

Definition at line 214 of file backend_registry_test.cpp.

215{
216 backend_registry::instance().register_backend("test", &test_backend::create);
217 auto backend = backend_registry::instance().create("test");
218 ASSERT_NE(backend, nullptr);
219 EXPECT_EQ(backend->type(), database_types::sqlite);
220}

References database::core::backend_registry::create(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [12/25]

TEST_F ( BackendRegistryTest ,
CreateReturnsDistinctInstances  )

Definition at line 228 of file backend_registry_test.cpp.

229{
230 backend_registry::instance().register_backend("test", &test_backend::create);
231 auto b1 = backend_registry::instance().create("test");
232 auto b2 = backend_registry::instance().create("test");
233 ASSERT_NE(b1, nullptr);
234 ASSERT_NE(b2, nullptr);
235 EXPECT_NE(b1.get(), b2.get());
236}

References database::core::backend_registry::create(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [13/25]

TEST_F ( BackendRegistryTest ,
CreateUnregisteredBackendReturnsNull  )

Definition at line 222 of file backend_registry_test.cpp.

223{
224 auto backend = backend_registry::instance().create("nonexistent");
225 EXPECT_EQ(backend, nullptr);
226}

References database::core::backend_registry::create(), and database::core::backend_registry::instance().

Here is the call graph for this function:

◆ TEST_F() [14/25]

TEST_F ( BackendRegistryTest ,
DuplicateRegistrationFails  )

Definition at line 187 of file backend_registry_test.cpp.

188{
189 EXPECT_TRUE(backend_registry::instance()
190 .register_backend("test", &test_backend::create).is_ok());
191 auto result = backend_registry::instance()
192 .register_backend("test", &test_backend::create);
193 EXPECT_FALSE(result.is_ok());
194}

References database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [15/25]

TEST_F ( BackendRegistryTest ,
EmptyNameRegistration  )

Definition at line 429 of file backend_registry_test.cpp.

430{
432 "", &test_backend::create);
433 // Empty name should still be valid (implementation-dependent)
434 // but we test that it doesn't crash
435 if (result.is_ok()) {
436 EXPECT_TRUE(backend_registry::instance().has_backend(""));
437 }
438}

References database::core::has_backend(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [16/25]

TEST_F ( BackendRegistryTest ,
EmptyRegistryHasZeroCount  )

Definition at line 281 of file backend_registry_test.cpp.

282{
283 EXPECT_EQ(backend_registry::instance().backend_count(), 0u);
284 EXPECT_TRUE(backend_registry::instance().available_backends().empty());
285}

References database::core::available_backends(), and database::core::backend_registry::instance().

Here is the call graph for this function:

◆ TEST_F() [17/25]

TEST_F ( BackendRegistryTest ,
HasBackendReturnsFalseForUnregistered  )

Definition at line 256 of file backend_registry_test.cpp.

257{
258 EXPECT_FALSE(backend_registry::instance().has_backend("nonexistent"));
259}

References database::core::has_backend(), and database::core::backend_registry::instance().

Here is the call graph for this function:

◆ TEST_F() [18/25]

TEST_F ( BackendRegistryTest ,
HasBackendReturnsTrueForRegistered  )

Definition at line 250 of file backend_registry_test.cpp.

251{
252 backend_registry::instance().register_backend("test", &test_backend::create);
253 EXPECT_TRUE(backend_registry::instance().has_backend("test"));
254}

References database::core::has_backend(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [19/25]

TEST_F ( BackendRegistryTest ,
RegisterBackendSucceeds  )

Definition at line 171 of file backend_registry_test.cpp.

172{
174 "test", &test_backend::create);
175 EXPECT_TRUE(result.is_ok());
176}

References database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [20/25]

TEST_F ( BackendRegistryTest ,
RegisterMultipleBackends  )

Definition at line 178 of file backend_registry_test.cpp.

179{
180 EXPECT_TRUE(backend_registry::instance()
181 .register_backend("test1", &test_backend::create).is_ok());
182 EXPECT_TRUE(backend_registry::instance()
183 .register_backend("test2", &test_backend_alt::create).is_ok());
184 EXPECT_EQ(backend_registry::instance().backend_count(), 2u);
185}

References database::core::backend_registry::instance().

Here is the call graph for this function:

◆ TEST_F() [21/25]

TEST_F ( BackendRegistryTest ,
RegisterUnregisterRegister  )

Definition at line 440 of file backend_registry_test.cpp.

441{
442 backend_registry::instance().register_backend("test", &test_backend::create);
445 "test", &test_backend_alt::create);
446 EXPECT_TRUE(result.is_ok());
447
448 auto backend = backend_registry::instance().create("test");
449 ASSERT_NE(backend, nullptr);
450 // After re-registration with alt type, should return postgres type
451 EXPECT_EQ(backend->type(), database_types::postgres);
452}
kcenon::common::VoidResult unregister_backend(const std::string &name)
Unregister a backend (for testing or dynamic unloading)

References database::core::backend_registry::create(), database::core::backend_registry::instance(), database::core::backend_registry::register_backend(), and database::core::backend_registry::unregister_backend().

Here is the call graph for this function:

◆ TEST_F() [22/25]

TEST_F ( BackendRegistryTest ,
ReRegisterAfterClear  )

Definition at line 303 of file backend_registry_test.cpp.

304{
305 backend_registry::instance().register_backend("test", &test_backend::create);
307
309 "test", &test_backend::create);
310 EXPECT_TRUE(result.is_ok());
311 EXPECT_TRUE(backend_registry::instance().has_backend("test"));
312}

References database::core::backend_registry::clear(), database::core::has_backend(), database::core::backend_registry::instance(), and database::core::backend_registry::register_backend().

Here is the call graph for this function:

◆ TEST_F() [23/25]

TEST_F ( BackendRegistryTest ,
SingletonConsistency  )

Definition at line 454 of file backend_registry_test.cpp.

455{
456 auto& instance1 = backend_registry::instance();
457 auto& instance2 = backend_registry::instance();
458 EXPECT_EQ(&instance1, &instance2);
459}

References database::core::backend_registry::instance().

Here is the call graph for this function:

◆ TEST_F() [24/25]

TEST_F ( BackendRegistryTest ,
UnregisterExistingBackend  )

Definition at line 196 of file backend_registry_test.cpp.

197{
198 backend_registry::instance().register_backend("test", &test_backend::create);
199 auto result = backend_registry::instance().unregister_backend("test");
200 EXPECT_TRUE(result.is_ok());
201 EXPECT_FALSE(backend_registry::instance().has_backend("test"));
202}

References database::core::has_backend(), database::core::backend_registry::instance(), database::core::backend_registry::register_backend(), and database::core::backend_registry::unregister_backend().

Here is the call graph for this function:

◆ TEST_F() [25/25]

TEST_F ( BackendRegistryTest ,
UnregisterNonExistentBackendFails  )

Definition at line 204 of file backend_registry_test.cpp.

205{
206 auto result = backend_registry::instance().unregister_backend("nonexistent");
207 EXPECT_FALSE(result.is_ok());
208}

References database::core::backend_registry::instance(), and database::core::backend_registry::unregister_backend().

Here is the call graph for this function: