mirror of
https://github.com/XRPLF/clio.git
synced 2025-11-21 04:05:51 +00:00
Fix backend factory test and remove cout from base tests (#792)
Fixes #793
This commit is contained in:
@@ -113,7 +113,8 @@ TEST_F(BackendCassandraFactoryTestWithDB, CreateCassandraBackend)
|
|||||||
}})",
|
}})",
|
||||||
contactPoints,
|
contactPoints,
|
||||||
keyspace))};
|
keyspace))};
|
||||||
// FIXME: this currently throws runtime_error (Could not create keyspace). no idea why
|
|
||||||
|
{
|
||||||
auto backend = make_Backend(ctx, cfg);
|
auto backend = make_Backend(ctx, cfg);
|
||||||
EXPECT_TRUE(backend);
|
EXPECT_TRUE(backend);
|
||||||
|
|
||||||
@@ -125,14 +126,17 @@ TEST_F(BackendCassandraFactoryTestWithDB, CreateCassandraBackend)
|
|||||||
EXPECT_TRUE(handle.connect());
|
EXPECT_TRUE(handle.connect());
|
||||||
handle.execute(fmt::format("INSERT INTO {}.ledger_range (is_latest, sequence) VALUES (False, 100)", keyspace));
|
handle.execute(fmt::format("INSERT INTO {}.ledger_range (is_latest, sequence) VALUES (False, 100)", keyspace));
|
||||||
handle.execute(fmt::format("INSERT INTO {}.ledger_range (is_latest, sequence) VALUES (True, 500)", keyspace));
|
handle.execute(fmt::format("INSERT INTO {}.ledger_range (is_latest, sequence) VALUES (True, 500)", keyspace));
|
||||||
|
}
|
||||||
|
|
||||||
backend = make_Backend(ctx, cfg);
|
{
|
||||||
|
auto backend = make_Backend(ctx, cfg);
|
||||||
EXPECT_TRUE(backend);
|
EXPECT_TRUE(backend);
|
||||||
|
|
||||||
auto const range = backend->fetchLedgerRange();
|
auto const range = backend->fetchLedgerRange();
|
||||||
EXPECT_EQ(range->minSequence, 100);
|
EXPECT_EQ(range->minSequence, 100);
|
||||||
EXPECT_EQ(range->maxSequence, 500);
|
EXPECT_EQ(range->maxSequence, 500);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(BackendCassandraFactoryTestWithDB, CreateCassandraBackendReadOnlyWithEmptyDB)
|
TEST_F(BackendCassandraFactoryTestWithDB, CreateCassandraBackendReadOnlyWithEmptyDB)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <backend/cassandra/Handle.h>
|
#include <backend/cassandra/Handle.h>
|
||||||
|
|
||||||
|
#include <fmt/core.h>
|
||||||
#include <gtest/gtest.h>
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
#include <semaphore>
|
#include <semaphore>
|
||||||
@@ -32,7 +33,6 @@ using namespace Backend::Cassandra;
|
|||||||
|
|
||||||
namespace json = boost::json;
|
namespace json = boost::json;
|
||||||
|
|
||||||
// TODO: get rid of cout and use expectations instead to verify output
|
|
||||||
class BackendCassandraBaseTest : public NoLoggerFixture
|
class BackendCassandraBaseTest : public NoLoggerFixture
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@@ -41,11 +41,13 @@ protected:
|
|||||||
{
|
{
|
||||||
Handle handle{contactPoints};
|
Handle handle{contactPoints};
|
||||||
EXPECT_TRUE(handle.connect());
|
EXPECT_TRUE(handle.connect());
|
||||||
std::string query = "CREATE KEYSPACE IF NOT EXISTS " + std::string{keyspace} +
|
auto const query = fmt::format(
|
||||||
" WITH replication = {'class': "
|
R"(
|
||||||
"'SimpleStrategy', 'replication_factor': '1'} AND "
|
CREATE KEYSPACE IF NOT EXISTS {}
|
||||||
"durable_writes = "
|
WITH replication = {{'class': 'SimpleStrategy', 'replication_factor': '1'}}
|
||||||
"true";
|
AND durable_writes = true
|
||||||
|
)",
|
||||||
|
keyspace);
|
||||||
EXPECT_TRUE(handle.execute(query));
|
EXPECT_TRUE(handle.execute(query));
|
||||||
EXPECT_TRUE(handle.reconnect(keyspace));
|
EXPECT_TRUE(handle.reconnect(keyspace));
|
||||||
return handle;
|
return handle;
|
||||||
@@ -69,17 +71,19 @@ protected:
|
|||||||
"fifth",
|
"fifth",
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string q1 =
|
auto const q1 = fmt::format(
|
||||||
"CREATE TABLE IF NOT EXISTS strings "
|
R"(
|
||||||
"(hash blob PRIMARY KEY, sequence bigint) "
|
CREATE TABLE IF NOT EXISTS strings (hash blob PRIMARY KEY, sequence bigint)
|
||||||
"WITH default_time_to_live = " +
|
WITH default_time_to_live = {}
|
||||||
to_string(5000);
|
)",
|
||||||
auto f1 = handle.asyncExecute(q1);
|
to_string(5000));
|
||||||
if (auto const rc = f1.await(); not rc)
|
|
||||||
std::cout << "oops: " << rc.error() << '\n';
|
auto const f1 = handle.asyncExecute(q1);
|
||||||
|
auto const rc = f1.await();
|
||||||
|
ASSERT_TRUE(rc) << rc.error();
|
||||||
|
|
||||||
std::string q2 = "INSERT INTO strings (hash, sequence) VALUES (?, ?)";
|
std::string q2 = "INSERT INTO strings (hash, sequence) VALUES (?, ?)";
|
||||||
auto insert = handle.prepare(q2);
|
auto const insert = handle.prepare(q2);
|
||||||
|
|
||||||
std::vector<Statement> statements;
|
std::vector<Statement> statements;
|
||||||
int64_t idx = 1000;
|
int64_t idx = 1000;
|
||||||
@@ -95,16 +99,18 @@ protected:
|
|||||||
TEST_F(BackendCassandraBaseTest, ConnectionSuccess)
|
TEST_F(BackendCassandraBaseTest, ConnectionSuccess)
|
||||||
{
|
{
|
||||||
Handle handle{"127.0.0.1"};
|
Handle handle{"127.0.0.1"};
|
||||||
auto f = handle.asyncConnect();
|
auto const f = handle.asyncConnect();
|
||||||
auto res = f.await();
|
auto const res = f.await();
|
||||||
|
|
||||||
ASSERT_TRUE(res);
|
ASSERT_TRUE(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BackendCassandraBaseTest, ConnectionFailFormat)
|
TEST_F(BackendCassandraBaseTest, ConnectionFailFormat)
|
||||||
{
|
{
|
||||||
Handle handle{"127.0.0."};
|
Handle handle{"127.0.0."};
|
||||||
auto f = handle.asyncConnect();
|
auto const f = handle.asyncConnect();
|
||||||
auto res = f.await();
|
auto const res = f.await();
|
||||||
|
|
||||||
ASSERT_FALSE(res);
|
ASSERT_FALSE(res);
|
||||||
EXPECT_EQ(res.error(), "No hosts available: Unable to connect to any contact points");
|
EXPECT_EQ(res.error(), "No hosts available: Unable to connect to any contact points");
|
||||||
EXPECT_EQ(res.error().code(), CASS_ERROR_LIB_NO_HOSTS_AVAILABLE);
|
EXPECT_EQ(res.error().code(), CASS_ERROR_LIB_NO_HOSTS_AVAILABLE);
|
||||||
@@ -117,9 +123,11 @@ TEST_F(BackendCassandraBaseTest, ConnectionFailTimeout)
|
|||||||
settings.connectionInfo = Settings::ContactPoints{"127.0.0.2"};
|
settings.connectionInfo = Settings::ContactPoints{"127.0.0.2"};
|
||||||
|
|
||||||
Handle handle{settings};
|
Handle handle{settings};
|
||||||
auto f = handle.asyncConnect();
|
auto const f = handle.asyncConnect();
|
||||||
auto res = f.await();
|
auto const res = f.await();
|
||||||
|
|
||||||
ASSERT_FALSE(res);
|
ASSERT_FALSE(res);
|
||||||
|
|
||||||
// scylla and cassandra produce different text
|
// scylla and cassandra produce different text
|
||||||
EXPECT_TRUE(res.error().message().starts_with("No hosts available: Underlying connection error:"));
|
EXPECT_TRUE(res.error().message().starts_with("No hosts available: Underlying connection error:"));
|
||||||
EXPECT_EQ(res.error().code(), CASS_ERROR_LIB_NO_HOSTS_AVAILABLE);
|
EXPECT_EQ(res.error().code(), CASS_ERROR_LIB_NO_HOSTS_AVAILABLE);
|
||||||
@@ -133,12 +141,12 @@ TEST_F(BackendCassandraBaseTest, FutureCallback)
|
|||||||
auto const statement = handle.prepare("SELECT keyspace_name FROM system_schema.keyspaces").bind();
|
auto const statement = handle.prepare("SELECT keyspace_name FROM system_schema.keyspaces").bind();
|
||||||
|
|
||||||
bool complete = false;
|
bool complete = false;
|
||||||
auto f = handle.asyncExecute(statement, [&complete](auto const res) {
|
auto const f = handle.asyncExecute(statement, [&complete](auto const res) {
|
||||||
complete = true;
|
complete = true;
|
||||||
EXPECT_TRUE(res.value().hasRows());
|
EXPECT_TRUE(res.value().hasRows());
|
||||||
|
|
||||||
for (auto [ks] : extract<std::string>(res.value()))
|
for (auto [ks] : extract<std::string>(res.value()))
|
||||||
std::cout << "keyspace: " << ks << '\n';
|
EXPECT_TRUE(not ks.empty()); // keyspace got some name
|
||||||
});
|
});
|
||||||
|
|
||||||
auto const res = f.await(); // callback should still be called
|
auto const res = f.await(); // callback should still be called
|
||||||
@@ -162,7 +170,7 @@ TEST_F(BackendCassandraBaseTest, FutureCallbackSurviveMove)
|
|||||||
EXPECT_TRUE(res.value().hasRows());
|
EXPECT_TRUE(res.value().hasRows());
|
||||||
|
|
||||||
for (auto [ks] : extract<std::string>(res.value()))
|
for (auto [ks] : extract<std::string>(res.value()))
|
||||||
std::cout << "keyspace: " << ks << '\n';
|
EXPECT_TRUE(not ks.empty()); // keyspace got some name
|
||||||
|
|
||||||
sem.release();
|
sem.release();
|
||||||
}));
|
}));
|
||||||
@@ -189,10 +197,13 @@ TEST_F(BackendCassandraBaseTest, KeyspaceManipulation)
|
|||||||
ASSERT_TRUE(rc); // expect that we can still connect without keyspace
|
ASSERT_TRUE(rc); // expect that we can still connect without keyspace
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
std::string query = "CREATE KEYSPACE " + keyspace +
|
const auto query = fmt::format(
|
||||||
" WITH replication = {'class': "
|
R"(
|
||||||
"'SimpleStrategy', 'replication_factor': '1'} AND durable_writes = "
|
CREATE KEYSPACE {}
|
||||||
"true";
|
WITH replication = {{'class': 'SimpleStrategy', 'replication_factor': '1'}}
|
||||||
|
AND durable_writes = true
|
||||||
|
)",
|
||||||
|
keyspace);
|
||||||
auto const f = handle.asyncExecute(query);
|
auto const f = handle.asyncExecute(query);
|
||||||
auto const rc = f.await();
|
auto const rc = f.await();
|
||||||
ASSERT_TRUE(rc); // keyspace created
|
ASSERT_TRUE(rc); // keyspace created
|
||||||
@@ -215,7 +226,6 @@ TEST_F(BackendCassandraBaseTest, KeyspaceManipulation)
|
|||||||
|
|
||||||
TEST_F(BackendCassandraBaseTest, CreateTableWithStrings)
|
TEST_F(BackendCassandraBaseTest, CreateTableWithStrings)
|
||||||
{
|
{
|
||||||
using std::to_string;
|
|
||||||
auto const entries = std::vector<std::string>{
|
auto const entries = std::vector<std::string>{
|
||||||
"first",
|
"first",
|
||||||
"second",
|
"second",
|
||||||
@@ -225,14 +235,16 @@ TEST_F(BackendCassandraBaseTest, CreateTableWithStrings)
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto handle = createHandle("127.0.0.1", "test");
|
auto handle = createHandle("127.0.0.1", "test");
|
||||||
std::string q1 =
|
auto q1 = fmt::format(
|
||||||
"CREATE TABLE IF NOT EXISTS strings "
|
R"(
|
||||||
"(hash blob PRIMARY KEY, sequence bigint) "
|
CREATE TABLE IF NOT EXISTS strings (hash blob PRIMARY KEY, sequence bigint)
|
||||||
"WITH default_time_to_live = " +
|
WITH default_time_to_live = {}
|
||||||
to_string(5000);
|
)",
|
||||||
auto f1 = handle.asyncExecute(q1);
|
5000);
|
||||||
if (auto const rc = f1.await(); not rc)
|
|
||||||
std::cout << "oops: " << rc.error() << '\n';
|
auto const f1 = handle.asyncExecute(q1);
|
||||||
|
auto const rc = f1.await();
|
||||||
|
ASSERT_TRUE(rc) << rc.error();
|
||||||
|
|
||||||
std::string q2 = "INSERT INTO strings (hash, sequence) VALUES (?, ?)";
|
std::string q2 = "INSERT INTO strings (hash, sequence) VALUES (?, ?)";
|
||||||
auto insert = handle.prepare(q2);
|
auto insert = handle.prepare(q2);
|
||||||
@@ -249,44 +261,33 @@ TEST_F(BackendCassandraBaseTest, CreateTableWithStrings)
|
|||||||
for (auto const& f : futures)
|
for (auto const& f : futures)
|
||||||
{
|
{
|
||||||
auto const rc = f.await();
|
auto const rc = f.await();
|
||||||
if (not rc)
|
ASSERT_TRUE(rc) << rc.error();
|
||||||
std::cout << rc.error() << '\n';
|
|
||||||
ASSERT_TRUE(rc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read data back
|
// read data back
|
||||||
{
|
{
|
||||||
auto const res = handle.execute("SELECT hash, sequence FROM strings");
|
auto const res = handle.execute("SELECT hash, sequence FROM strings");
|
||||||
ASSERT_TRUE(res);
|
ASSERT_TRUE(res) << res.error();
|
||||||
|
|
||||||
if (not res)
|
|
||||||
std::cout << "oops: " << res.error() << '\n';
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto const& results = res.value();
|
auto const& results = res.value();
|
||||||
auto const totalRows = results.numRows();
|
auto const totalRows = results.numRows();
|
||||||
std::cout << "total rows: " << totalRows << '\n';
|
EXPECT_EQ(totalRows, entries.size());
|
||||||
|
|
||||||
for (auto [hash, seq] : extract<std::string, int64_t>(results))
|
for (auto [hash, seq] : extract<std::string, int64_t>(results))
|
||||||
std::cout << "row: " << seq << ":" << hash << '\n';
|
EXPECT_TRUE(std::find(std::begin(entries), std::end(entries), hash) != std::end(entries));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// delete everything
|
// delete everything
|
||||||
{
|
{
|
||||||
auto const res = handle.execute("DROP TABLE strings");
|
auto const res = handle.execute("DROP TABLE strings");
|
||||||
ASSERT_TRUE(res);
|
ASSERT_TRUE(res) << res.error();
|
||||||
|
|
||||||
if (not res)
|
|
||||||
std::cout << "oops: " << res.error() << '\n';
|
|
||||||
dropKeyspace(handle, "test");
|
dropKeyspace(handle, "test");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(BackendCassandraBaseTest, BatchInsert)
|
TEST_F(BackendCassandraBaseTest, BatchInsert)
|
||||||
{
|
{
|
||||||
using std::to_string;
|
|
||||||
auto const entries = std::vector<std::string>{
|
auto const entries = std::vector<std::string>{
|
||||||
"first",
|
"first",
|
||||||
"second",
|
"second",
|
||||||
@@ -296,17 +297,18 @@ TEST_F(BackendCassandraBaseTest, BatchInsert)
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto handle = createHandle("127.0.0.1", "test");
|
auto handle = createHandle("127.0.0.1", "test");
|
||||||
std::string q1 =
|
auto const q1 = fmt::format(
|
||||||
"CREATE TABLE IF NOT EXISTS strings "
|
R"(
|
||||||
"(hash blob PRIMARY KEY, sequence bigint) "
|
CREATE TABLE IF NOT EXISTS strings (hash blob PRIMARY KEY, sequence bigint)
|
||||||
"WITH default_time_to_live = " +
|
WITH default_time_to_live = {}
|
||||||
to_string(5000);
|
)",
|
||||||
auto f1 = handle.asyncExecute(q1);
|
5000);
|
||||||
if (auto const rc = f1.await(); not rc)
|
auto const f1 = handle.asyncExecute(q1);
|
||||||
std::cout << "oops: " << rc.error() << '\n';
|
auto const rc = f1.await();
|
||||||
|
ASSERT_TRUE(rc) << rc.error();
|
||||||
|
|
||||||
std::string q2 = "INSERT INTO strings (hash, sequence) VALUES (?, ?)";
|
std::string q2 = "INSERT INTO strings (hash, sequence) VALUES (?, ?)";
|
||||||
auto insert = handle.prepare(q2);
|
auto const insert = handle.prepare(q2);
|
||||||
|
|
||||||
// write data in bulk
|
// write data in bulk
|
||||||
{
|
{
|
||||||
@@ -317,28 +319,22 @@ TEST_F(BackendCassandraBaseTest, BatchInsert)
|
|||||||
statements.push_back(insert.bind(entry, static_cast<int64_t>(idx++)));
|
statements.push_back(insert.bind(entry, static_cast<int64_t>(idx++)));
|
||||||
|
|
||||||
ASSERT_EQ(statements.size(), entries.size());
|
ASSERT_EQ(statements.size(), entries.size());
|
||||||
auto rc = handle.execute(statements);
|
|
||||||
if (not rc)
|
auto const rc = handle.execute(statements);
|
||||||
std::cout << rc.error() << '\n';
|
ASSERT_TRUE(rc) << rc.error();
|
||||||
ASSERT_TRUE(rc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read data back
|
// read data back
|
||||||
{
|
{
|
||||||
auto const res = handle.execute("SELECT hash, sequence FROM strings");
|
auto const res = handle.execute("SELECT hash, sequence FROM strings");
|
||||||
ASSERT_TRUE(res);
|
ASSERT_TRUE(res) << res.error();
|
||||||
|
|
||||||
if (not res)
|
|
||||||
std::cout << "oops: " << res.error() << '\n';
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto const& results = res.value();
|
auto const& results = res.value();
|
||||||
auto const totalRows = results.numRows();
|
auto const totalRows = results.numRows();
|
||||||
std::cout << "total rows: " << totalRows << '\n';
|
EXPECT_EQ(totalRows, entries.size());
|
||||||
|
|
||||||
for (auto [hash, seq] : extract<std::string, int64_t>(results))
|
for (auto [hash, seq] : extract<std::string, int64_t>(results))
|
||||||
std::cout << "row: " << seq << ":" << hash << '\n';
|
EXPECT_TRUE(std::find(std::begin(entries), std::end(entries), hash) != std::end(entries));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dropKeyspace(handle, "test");
|
dropKeyspace(handle, "test");
|
||||||
@@ -356,17 +352,18 @@ TEST_F(BackendCassandraBaseTest, BatchInsertAsync)
|
|||||||
};
|
};
|
||||||
|
|
||||||
auto handle = createHandle("127.0.0.1", "test");
|
auto handle = createHandle("127.0.0.1", "test");
|
||||||
std::string q1 =
|
auto const q1 = fmt::format(
|
||||||
"CREATE TABLE IF NOT EXISTS strings "
|
R"(
|
||||||
"(hash blob PRIMARY KEY, sequence bigint) "
|
CREATE TABLE IF NOT EXISTS strings (hash blob PRIMARY KEY, sequence bigint)
|
||||||
"WITH default_time_to_live = " +
|
WITH default_time_to_live = {}
|
||||||
to_string(5000);
|
)",
|
||||||
auto f1 = handle.asyncExecute(q1);
|
5000);
|
||||||
if (auto const rc = f1.await(); not rc)
|
auto const f1 = handle.asyncExecute(q1);
|
||||||
std::cout << "oops: " << rc.error() << '\n';
|
auto const rc = f1.await();
|
||||||
|
ASSERT_TRUE(rc) << rc.error();
|
||||||
|
|
||||||
std::string q2 = "INSERT INTO strings (hash, sequence) VALUES (?, ?)";
|
std::string q2 = "INSERT INTO strings (hash, sequence) VALUES (?, ?)";
|
||||||
auto insert = handle.prepare(q2);
|
auto const insert = handle.prepare(q2);
|
||||||
|
|
||||||
// write data in bulk
|
// write data in bulk
|
||||||
{
|
{
|
||||||
@@ -399,11 +396,12 @@ TEST_F(BackendCassandraBaseTest, BatchInsertAsync)
|
|||||||
TEST_F(BackendCassandraBaseTest, AlterTableAddColumn)
|
TEST_F(BackendCassandraBaseTest, AlterTableAddColumn)
|
||||||
{
|
{
|
||||||
auto handle = createHandle("127.0.0.1", "test");
|
auto handle = createHandle("127.0.0.1", "test");
|
||||||
std::string q1 =
|
auto const q1 = fmt::format(
|
||||||
"CREATE TABLE IF NOT EXISTS strings "
|
R"(
|
||||||
"(hash blob PRIMARY KEY, sequence bigint) "
|
CREATE TABLE IF NOT EXISTS strings (hash blob PRIMARY KEY, sequence bigint)
|
||||||
"WITH default_time_to_live = " +
|
WITH default_time_to_live = {}
|
||||||
to_string(5000);
|
)",
|
||||||
|
5000);
|
||||||
ASSERT_TRUE(handle.execute(q1));
|
ASSERT_TRUE(handle.execute(q1));
|
||||||
|
|
||||||
std::string update = "ALTER TABLE strings ADD tmp blob";
|
std::string update = "ALTER TABLE strings ADD tmp blob";
|
||||||
@@ -417,11 +415,12 @@ TEST_F(BackendCassandraBaseTest, AlterTableMoveToNewTable)
|
|||||||
auto handle = createHandle("127.0.0.1", "test");
|
auto handle = createHandle("127.0.0.1", "test");
|
||||||
prepStringsTable(handle);
|
prepStringsTable(handle);
|
||||||
|
|
||||||
std::string newTable =
|
auto const newTable = fmt::format(
|
||||||
"CREATE TABLE IF NOT EXISTS strings_v2 "
|
R"(
|
||||||
"(hash blob PRIMARY KEY, sequence bigint, tmp bigint) "
|
CREATE TABLE IF NOT EXISTS strings_v2 (hash blob PRIMARY KEY, sequence bigint, tmp bigint)
|
||||||
"WITH default_time_to_live = " +
|
WITH default_time_to_live = {}
|
||||||
to_string(5000);
|
)",
|
||||||
|
5000);
|
||||||
ASSERT_TRUE(handle.execute(newTable));
|
ASSERT_TRUE(handle.execute(newTable));
|
||||||
|
|
||||||
// now migrate data; tmp column will just get the sequence number + 1 stored
|
// now migrate data; tmp column will just get the sequence number + 1 stored
|
||||||
|
|||||||
Reference in New Issue
Block a user