328 lines
10 KiB
C++
328 lines
10 KiB
C++
//
|
|
// Copyright (c) 2019-2023 Ruben Perez Hidalgo (rubenperez038 at gmail dot com)
|
|
//
|
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
|
//
|
|
|
|
#include <boost/mysql/connection.hpp>
|
|
#include <boost/mysql/execution_state.hpp>
|
|
#include <boost/mysql/field_view.hpp>
|
|
#include <boost/mysql/results.hpp>
|
|
#include <boost/mysql/row_view.hpp>
|
|
#include <boost/mysql/rows_view.hpp>
|
|
|
|
#include "integration_test_common.hpp"
|
|
#include "metadata_validator.hpp"
|
|
#include "test_common.hpp"
|
|
|
|
using namespace boost::mysql::test;
|
|
using boost::mysql::common_server_errc;
|
|
using boost::mysql::execution_state;
|
|
using boost::mysql::field_view;
|
|
using boost::mysql::results;
|
|
using boost::mysql::row_view;
|
|
|
|
namespace {
|
|
|
|
BOOST_AUTO_TEST_SUITE(test_spotchecks)
|
|
|
|
auto err_net_samples = create_network_samples({
|
|
"tcp_sync_errc",
|
|
"tcp_sync_exc",
|
|
"tcp_async_callback",
|
|
"tcp_async_coroutines",
|
|
});
|
|
|
|
// Handshake
|
|
BOOST_MYSQL_NETWORK_TEST(handshake_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_physical_connect(sample.net);
|
|
conn->handshake(params).validate_no_error();
|
|
BOOST_TEST(conn->uses_ssl() == var->supports_ssl());
|
|
}
|
|
|
|
BOOST_MYSQL_NETWORK_TEST(handshake_error, network_fixture, err_net_samples)
|
|
{
|
|
setup_and_physical_connect(sample.net);
|
|
params.set_database("bad_database");
|
|
conn->handshake(params).validate_error(
|
|
common_server_errc::er_dbaccess_denied_error,
|
|
{"database", "bad_database"}
|
|
);
|
|
}
|
|
|
|
// Connect: success is already widely tested throughout integ tests
|
|
BOOST_MYSQL_NETWORK_TEST(connect_error, network_fixture, err_net_samples)
|
|
{
|
|
setup(sample.net);
|
|
set_credentials("integ_user", "bad_password");
|
|
conn->connect(params).validate_error(
|
|
common_server_errc::er_access_denied_error,
|
|
{"access denied", "integ_user"}
|
|
);
|
|
BOOST_TEST(!conn->is_open());
|
|
}
|
|
|
|
// Start query
|
|
BOOST_MYSQL_NETWORK_TEST(start_query_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_connect(sample.net);
|
|
|
|
execution_state st;
|
|
conn->start_query("SELECT * FROM empty_table", st).get();
|
|
BOOST_TEST(!st.complete());
|
|
validate_2fields_meta(st.meta(), "empty_table");
|
|
}
|
|
|
|
BOOST_MYSQL_NETWORK_TEST(start_query_error, network_fixture, err_net_samples)
|
|
{
|
|
setup_and_connect(sample.net);
|
|
|
|
execution_state st;
|
|
conn->start_query("SELECT field_varchar, field_bad FROM one_row_table", st)
|
|
.validate_error(common_server_errc::er_bad_field_error, {"unknown column", "field_bad"});
|
|
}
|
|
|
|
// Query
|
|
BOOST_MYSQL_NETWORK_TEST(query_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_connect(sample.net);
|
|
|
|
results result;
|
|
conn->query("SELECT 'hello', 42", result).get();
|
|
BOOST_TEST(result.rows().size() == 1u);
|
|
BOOST_TEST(result.rows()[0] == makerow("hello", 42));
|
|
BOOST_TEST(result.meta().size() == 2u);
|
|
}
|
|
|
|
BOOST_MYSQL_NETWORK_TEST(query_error, network_fixture, err_net_samples)
|
|
{
|
|
setup_and_connect(sample.net);
|
|
|
|
results result;
|
|
conn->query("SELECT field_varchar, field_bad FROM one_row_table", result)
|
|
.validate_error(common_server_errc::er_bad_field_error, {"unknown column", "field_bad"});
|
|
}
|
|
|
|
// Prepare statement
|
|
BOOST_MYSQL_NETWORK_TEST(prepare_statement_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_connect(sample.net);
|
|
auto stmt = conn->prepare_statement("SELECT * FROM empty_table WHERE id IN (?, ?)").get();
|
|
BOOST_TEST_REQUIRE(stmt.valid());
|
|
BOOST_TEST(stmt.id() > 0u);
|
|
BOOST_TEST(stmt.num_params() == 2u);
|
|
}
|
|
|
|
BOOST_MYSQL_NETWORK_TEST(prepare_statement_error, network_fixture, err_net_samples)
|
|
{
|
|
setup_and_connect(sample.net);
|
|
conn->prepare_statement("SELECT * FROM bad_table WHERE id IN (?, ?)")
|
|
.validate_error(common_server_errc::er_no_such_table, {"table", "doesn't exist", "bad_table"});
|
|
}
|
|
|
|
// Start statement execution (iterator version)
|
|
BOOST_MYSQL_NETWORK_TEST(start_statement_execution_it_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_connect(sample.net);
|
|
|
|
// Prepare
|
|
auto stmt = conn->prepare_statement("SELECT * FROM empty_table WHERE id IN (?, ?)").get();
|
|
|
|
// Execute
|
|
execution_state st;
|
|
std::forward_list<field_view> params{field_view("item"), field_view(42)};
|
|
conn->start_statement_execution(stmt, params.begin(), params.end(), st).validate_no_error();
|
|
validate_2fields_meta(st.meta(), "empty_table");
|
|
BOOST_TEST(!st.complete());
|
|
}
|
|
|
|
BOOST_MYSQL_NETWORK_TEST(start_statement_execution_it_error, network_fixture, err_net_samples)
|
|
{
|
|
setup_and_connect(sample.net);
|
|
start_transaction();
|
|
|
|
// Prepare
|
|
auto stmt = conn->prepare_statement("INSERT INTO inserts_table (field_varchar, field_date) VALUES (?, ?)")
|
|
.get();
|
|
|
|
// Execute
|
|
execution_state st;
|
|
std::forward_list<field_view> params{field_view("f0"), field_view("bad_date")};
|
|
conn->start_statement_execution(stmt, params.begin(), params.end(), st)
|
|
.validate_error(
|
|
common_server_errc::er_truncated_wrong_value,
|
|
{"field_date", "bad_date", "incorrect date value"}
|
|
);
|
|
}
|
|
|
|
// Start statement execution (tuple version)
|
|
BOOST_MYSQL_NETWORK_TEST(start_statement_execution_tuple_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_connect(sample.net);
|
|
|
|
// Prepare
|
|
auto stmt = conn->prepare_statement("SELECT * FROM empty_table WHERE id IN (?, ?)").get();
|
|
|
|
// Execute
|
|
execution_state st;
|
|
conn->start_statement_execution(stmt, field_view(42), field_view(40), st).validate_no_error();
|
|
validate_2fields_meta(st.meta(), "empty_table");
|
|
BOOST_TEST(!st.complete());
|
|
}
|
|
|
|
BOOST_MYSQL_NETWORK_TEST(start_statement_execution_tuple_error, network_fixture, err_net_samples)
|
|
{
|
|
setup_and_connect(sample.net);
|
|
start_transaction();
|
|
|
|
// Prepare
|
|
auto stmt = conn->prepare_statement("INSERT INTO inserts_table (field_varchar, field_date) VALUES (?, ?)")
|
|
.get();
|
|
|
|
// Execute
|
|
execution_state st;
|
|
conn->start_statement_execution(stmt, field_view("abc"), field_view("bad_date"), st)
|
|
.validate_error(
|
|
common_server_errc::er_truncated_wrong_value,
|
|
{"field_date", "bad_date", "incorrect date value"}
|
|
);
|
|
}
|
|
|
|
// Execute statement
|
|
BOOST_MYSQL_NETWORK_TEST(execute_statement_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_connect(sample.net);
|
|
|
|
// Prepare
|
|
auto stmt = conn->prepare_statement("SELECT * FROM empty_table WHERE id IN (?, ?)").get();
|
|
|
|
// Execute
|
|
results result;
|
|
conn->execute_statement(stmt, field_view("item"), field_view(42), result).validate_no_error();
|
|
BOOST_TEST(result.rows().size() == 0u);
|
|
}
|
|
|
|
BOOST_MYSQL_NETWORK_TEST(execute_statement_error, network_fixture, err_net_samples)
|
|
{
|
|
setup_and_connect(sample.net);
|
|
start_transaction();
|
|
|
|
// Prepare
|
|
auto stmt = conn->prepare_statement("INSERT INTO inserts_table (field_varchar, field_date) VALUES (?, ?)")
|
|
.get();
|
|
|
|
// Execute
|
|
results result;
|
|
conn->execute_statement(stmt, field_view("f0"), field_view("bad_date"), result)
|
|
.validate_error(
|
|
common_server_errc::er_truncated_wrong_value,
|
|
{"field_date", "bad_date", "incorrect date value"}
|
|
);
|
|
}
|
|
|
|
// Close statement: no server error spotcheck
|
|
BOOST_MYSQL_NETWORK_TEST(close_statement_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_connect(sample.net);
|
|
|
|
// Prepare a statement
|
|
auto stmt = conn->prepare_statement("SELECT * FROM empty_table WHERE id IN (?, ?)").get();
|
|
|
|
// Close the statement
|
|
conn->close_statement(stmt).validate_no_error();
|
|
|
|
// The statement is no longer valid
|
|
results result;
|
|
conn->execute_statement(stmt, field_view("a"), field_view("b"), result).validate_any_error();
|
|
}
|
|
|
|
// Read some rows: no server error spotcheck
|
|
BOOST_MYSQL_NETWORK_TEST(read_some_rows_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_connect(sample.net);
|
|
|
|
// Generate an execution state
|
|
execution_state st;
|
|
conn->start_query("SELECT * FROM one_row_table", st);
|
|
BOOST_TEST_REQUIRE(!st.complete());
|
|
|
|
// Read once. st may or may not be complete, depending
|
|
// on how the buffer reallocated memory
|
|
auto rows = conn->read_some_rows(st).get();
|
|
BOOST_TEST((rows == makerows(2, 1, "f0")));
|
|
|
|
// Reading again should complete st
|
|
rows = conn->read_some_rows(st).get();
|
|
BOOST_TEST(rows.empty());
|
|
validate_eof(st);
|
|
|
|
// Reading again does nothing
|
|
rows = conn->read_some_rows(st).get();
|
|
BOOST_TEST(rows.empty());
|
|
validate_eof(st);
|
|
}
|
|
|
|
// Ping
|
|
BOOST_MYSQL_NETWORK_TEST(ping_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_connect(sample.net);
|
|
conn->ping().validate_no_error();
|
|
}
|
|
|
|
BOOST_MYSQL_NETWORK_TEST(ping_error, network_fixture, all_network_samples())
|
|
{
|
|
setup(sample.net);
|
|
|
|
// Ping should return an error for an unconnected connection
|
|
conn->ping().validate_any_error();
|
|
}
|
|
|
|
// Quit connection: no server error spotcheck
|
|
BOOST_MYSQL_NETWORK_TEST(quit_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_connect(sample.net);
|
|
|
|
// Quit
|
|
conn->quit().validate_no_error();
|
|
|
|
// We are no longer able to query
|
|
results result;
|
|
conn->query("SELECT 1", result).validate_any_error();
|
|
}
|
|
|
|
// Close connection: no server error spotcheck
|
|
BOOST_MYSQL_NETWORK_TEST(close_connection_success, network_fixture, all_network_samples())
|
|
{
|
|
setup_and_connect(sample.net);
|
|
|
|
// Close
|
|
conn->close().validate_no_error();
|
|
|
|
// We are no longer able to query
|
|
boost::mysql::results result;
|
|
conn->query("SELECT 1", result).validate_any_error();
|
|
|
|
// The stream is closed
|
|
BOOST_TEST(!conn->is_open());
|
|
|
|
// Closing again returns OK (and does nothing)
|
|
conn->close().validate_no_error();
|
|
|
|
// Stream (socket) still closed
|
|
BOOST_TEST(!conn->is_open());
|
|
}
|
|
|
|
// TODO: move this to a unit test
|
|
BOOST_MYSQL_NETWORK_TEST(not_open_connection, network_fixture, err_net_samples)
|
|
{
|
|
setup(sample.net);
|
|
conn->close().validate_no_error();
|
|
BOOST_TEST(!conn->is_open());
|
|
}
|
|
|
|
BOOST_AUTO_TEST_SUITE_END() // test_spotchecks
|
|
|
|
} // namespace
|