drogonframework / drogon

Drogon: A C++14/17/20 based HTTP web application framework running on Linux/macOS/Unix/Windows
MIT License
11.04k stars 1.06k forks source link

Question: How can i get connection to postgresql in tests ? #2068

Closed spiritEcosse closed 2 weeks ago

spiritEcosse commented 2 weeks ago

Hello there!

Here is my code where i try to access db from DROGON_TEST but in the test in a line

auto dbClient = app().getFastDbClient("default");

i get an error

101: Assertion failed: (idx < storage_.size()), function getThreadData, file IOThreadStorage.h, line 100.
#include <drogon/drogon.h>
#include <future>
#include <thread>
#include <iostream>
#include "drogon/drogon_test.h"

using namespace drogon;

// Test case for creating an item, ensuring access to the database client
DROGON_TEST(CreateItem) {
    auto dbClient = app().getFastDbClient("default");
    REQUIRE(dbClient != nullptr);  // Ensure the dbClient is not null
    // Add your test logic here
}

int main(int argc, char **argv) {
    // Initialize the Drogon application
    app().loadConfigFile("./config.json");

    std::promise<void> appStartedPromise;
    std::future<void> appStartedFuture = appStartedPromise.get_future();

    // Start the main loop on another thread
    std::thread appThread([&]() {
        // Queues the promise to be fulfilled after starting the loop
        app().getLoop()->queueInLoop([&appStartedPromise]() {
            appStartedPromise.set_value();
        });

        // Run the event loop
        app().run();
    });

    // Wait until the event loop has started
    appStartedFuture.get();

    // Run the tests
    int status = test::run(argc, argv);

    // Ask the event loop to shutdown and wait
    app().getLoop()->queueInLoop([]() {
        app().quit();
    });

    // Wait for the application thread to finish
    appThread.join();

    return status;
}

How can i fix it ?

Thanks in advance.

hwc0919 commented 2 weeks ago

getFastDbClient() should run in IO loop or main loop.

Use like this in test:

drogon::app().getLoop()->runInLoop([TEST_CTX](){
    auto dbClient = drogon::app().getFastDbClient("default");
    REQUIRE(dbClient != nullptr);  // Ensure the dbClient is not null
    // Add your test logic here
});
spiritEcosse commented 2 weeks ago

Thanks a lot, @hwc0919. It works.