From 25ca21546e56254fe894c87f5749c5b2de3bd1c2 Mon Sep 17 00:00:00 2001 From: Ruben Perez Date: Fri, 14 Oct 2022 17:00:36 +0200 Subject: [PATCH] Recovered query tests --- .../boost/mysql/detail/channel/channel.hpp | 8 ++ .../impl/close_statement.hpp | 9 +-- .../network_algorithms/impl/handshake.hpp | 2 +- .../impl/prepare_statement.hpp | 9 +-- .../impl/quit_connection.hpp | 5 +- include/boost/mysql/resultset_base.hpp | 2 +- test/integration/query.cpp | 75 +++++++++++-------- .../utils/include/network_test.hpp | 32 ++++---- 8 files changed, 78 insertions(+), 64 deletions(-) diff --git a/include/boost/mysql/detail/channel/channel.hpp b/include/boost/mysql/detail/channel/channel.hpp index e37e06f3..b122620f 100644 --- a/include/boost/mysql/detail/channel/channel.hpp +++ b/include/boost/mysql/detail/channel/channel.hpp @@ -144,11 +144,19 @@ public: capabilities current_capabilities() const noexcept { return current_caps_; } void set_current_capabilities(capabilities value) noexcept { current_caps_ = value; } + void reset() + { + stream_.reset(); + current_caps_ = capabilities(); + reset_sequence_number(); + } + // Internal buffer, error_info and sequence_number to help async ops const bytestring& shared_buffer() const noexcept { return shared_buff_; } bytestring& shared_buffer() noexcept { return shared_buff_; } error_info& shared_info() noexcept { return shared_info_; } std::uint8_t& shared_sequence_number() noexcept { return shared_sequence_number_; } + std::uint8_t& reset_sequence_number() noexcept { return shared_sequence_number_ = 0; } std::vector& shared_fields() noexcept { return shared_fields_; } const std::vector& shared_fields() const noexcept { return shared_fields_; } }; diff --git a/include/boost/mysql/detail/network_algorithms/impl/close_statement.hpp b/include/boost/mysql/detail/network_algorithms/impl/close_statement.hpp index 03e5a876..270e9282 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/close_statement.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/close_statement.hpp @@ -42,11 +42,8 @@ struct close_statement_op : boost::asio::coroutine BOOST_ASIO_CORO_REENTER(*this) { // Write message (already serialized at this point) - BOOST_ASIO_CORO_YIELD chan_.async_write( - chan_.shared_buffer(), - chan_.shared_sequence_number(), - std::move(self) - ); + BOOST_ASIO_CORO_YIELD chan_ + .async_write(chan_.shared_buffer(), chan_.reset_sequence_number(), std::move(self)); // Mark the statement as invalid stmt_.reset(); @@ -72,7 +69,7 @@ void boost::mysql::detail:: serialize_message(packet, chan.current_capabilities(), chan.shared_buffer()); // Send it. No response is sent back - chan.write(boost::asio::buffer(chan.shared_buffer()), chan.shared_sequence_number(), code); + chan.write(boost::asio::buffer(chan.shared_buffer()), chan.reset_sequence_number(), code); // Mark the statement as invalid stmt.reset(); diff --git a/include/boost/mysql/detail/network_algorithms/impl/handshake.hpp b/include/boost/mysql/detail/network_algorithms/impl/handshake.hpp index 8ccabdb0..c9c69c77 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/handshake.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/handshake.hpp @@ -373,7 +373,7 @@ void boost::mysql::detail::handshake( error_info& info ) { - channel.stream().reset(); + channel.reset(); // Set up processor handshake_processor processor(params); diff --git a/include/boost/mysql/detail/network_algorithms/impl/prepare_statement.hpp b/include/boost/mysql/detail/network_algorithms/impl/prepare_statement.hpp index 4c69d0c8..ce010ebd 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/prepare_statement.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/prepare_statement.hpp @@ -107,11 +107,8 @@ struct prepare_statement_op : boost::asio::coroutine BOOST_ASIO_CORO_REENTER(*this) { // Write message (already serialized at this point) - BOOST_ASIO_CORO_YIELD chan_.async_write( - chan_.shared_buffer(), - chan_.shared_sequence_number(), - std::move(self) - ); + BOOST_ASIO_CORO_YIELD chan_ + .async_write(chan_.shared_buffer(), chan_.reset_sequence_number(), std::move(self)); // Read response BOOST_ASIO_CORO_YIELD chan_.async_read_one( @@ -173,7 +170,7 @@ void boost::mysql::detail::prepare_statement( processor.process_request(statement); // Write message - channel.write(channel.shared_buffer(), channel.shared_sequence_number(), err); + channel.write(channel.shared_buffer(), channel.reset_sequence_number(), err); if (err) return; diff --git a/include/boost/mysql/detail/network_algorithms/impl/quit_connection.hpp b/include/boost/mysql/detail/network_algorithms/impl/quit_connection.hpp index c0ef749e..12f43303 100644 --- a/include/boost/mysql/detail/network_algorithms/impl/quit_connection.hpp +++ b/include/boost/mysql/detail/network_algorithms/impl/quit_connection.hpp @@ -40,7 +40,8 @@ struct quit_connection_op : boost::asio::coroutine { // Quit message compose_quit(chan_); - BOOST_ASIO_CORO_YIELD chan_.async_write(chan_.shared_buffer(), std::move(self)); + BOOST_ASIO_CORO_YIELD chan_ + .async_write(chan_.shared_buffer(), chan_.reset_sequence_number(), std::move(self)); if (err) { self.complete(err); @@ -65,7 +66,7 @@ template void boost::mysql::detail::quit_connection(channel& chan, error_code& err, error_info&) { compose_quit(chan); - chan.write(chan.shared_buffer(), chan.shared_sequence_number(), err); + chan.write(chan.shared_buffer(), chan.reset_sequence_number(), err); if (err) return; if (chan.stream().ssl_active()) diff --git a/include/boost/mysql/resultset_base.hpp b/include/boost/mysql/resultset_base.hpp index 7e42ca63..a944e04e 100644 --- a/include/boost/mysql/resultset_base.hpp +++ b/include/boost/mysql/resultset_base.hpp @@ -115,7 +115,7 @@ public: ok_packet_.assign(ok_pack); } - void prepare_meta(std::size_t num_fields) { meta_.resize(num_fields); } + void prepare_meta(std::size_t num_fields) { meta_.reserve(num_fields); } void add_meta(const detail::column_definition_packet& pack) { meta_.emplace_back(pack, true); } diff --git a/test/integration/query.cpp b/test/integration/query.cpp index 90f9f1fd..bbeb21e4 100644 --- a/test/integration/query.cpp +++ b/test/integration/query.cpp @@ -6,8 +6,9 @@ // #include -#include "metadata_validator.hpp" + #include "integration_test_common.hpp" +#include "metadata_validator.hpp" #include "test_common.hpp" using namespace boost::mysql::test; @@ -21,17 +22,21 @@ BOOST_MYSQL_NETWORK_TEST(insert_ok, network_fixture) start_transaction(); // Issue query - auto result = conn->query( - "INSERT INTO inserts_table (field_varchar, field_date) VALUES ('v0', '2010-10-11')").get(); + auto result = create_resultset(); + conn->query( + "INSERT INTO inserts_table (field_varchar, field_date) VALUES ('v0', '2010-10-11')", + *result + ) + .get(); // Verify resultset_base - BOOST_TEST(result->fields().empty()); - BOOST_TEST(result->valid()); - BOOST_TEST(result->complete()); - BOOST_TEST(result->affected_rows() == 1u); - BOOST_TEST(result->warning_count() == 0u); - BOOST_TEST(result->last_insert_id() > 0u); - BOOST_TEST(result->info() == ""); + BOOST_TEST(result->base().fields().empty()); + BOOST_TEST(result->base().valid()); + BOOST_TEST(result->base().complete()); + BOOST_TEST(result->base().affected_rows() == 1u); + BOOST_TEST(result->base().warning_count() == 0u); + BOOST_TEST(result->base().last_insert_id() > 0u); + BOOST_TEST(result->base().info() == ""); // Verify insertion took place BOOST_TEST(this->get_table_size("inserts_table") == 1u); @@ -41,9 +46,12 @@ BOOST_MYSQL_NETWORK_TEST(insert_error, network_fixture) { setup_and_connect(sample.net); start_transaction(); - auto result = conn->query( - "INSERT INTO bad_table (field_varchar, field_date) VALUES ('v0', '2010-10-11')"); - result.validate_error(errc::no_such_table, {"table", "doesn't exist", "bad_table"}); + auto result = create_resultset(); + auto netresult = conn->query( + "INSERT INTO bad_table (field_varchar, field_date) VALUES ('v0', '2010-10-11')", + *result + ); + netresult.validate_error(errc::no_such_table, {"table", "doesn't exist", "bad_table"}); } BOOST_MYSQL_NETWORK_TEST(update_ok, network_fixture) @@ -52,37 +60,42 @@ BOOST_MYSQL_NETWORK_TEST(update_ok, network_fixture) start_transaction(); // Issue the query - auto result = conn->query("UPDATE updates_table SET field_int = field_int+10").get(); + auto result = create_resultset(); + conn->query("UPDATE updates_table SET field_int = field_int+10", *result).get(); // Validate resultset_base - BOOST_TEST(result->fields().empty()); - BOOST_TEST(result->valid()); - BOOST_TEST(result->complete()); - BOOST_TEST(result->affected_rows() == 2u); - BOOST_TEST(result->warning_count() == 0u); - BOOST_TEST(result->last_insert_id() == 0u); - validate_string_contains(std::string(result->info()), {"rows matched"}); + BOOST_TEST(result->base().fields().empty()); + BOOST_TEST(result->base().valid()); + BOOST_TEST(result->base().complete()); + BOOST_TEST(result->base().affected_rows() == 2u); + BOOST_TEST(result->base().warning_count() == 0u); + BOOST_TEST(result->base().last_insert_id() == 0u); + validate_string_contains(std::string(result->base().info()), {"rows matched"}); // Validate it took effect - result = conn->query("SELECT field_int FROM updates_table WHERE field_varchar = 'f0'").get(); - auto updated_value = result->read_all().get().at(0).values().at(0).template get(); - BOOST_TEST(updated_value == 52); // initial value was 42 + conn->query("SELECT field_int FROM updates_table WHERE field_varchar = 'f0'", *result).get(); + auto updated_value = result->read_all().get().at(0).at(0).as_int64(); + BOOST_TEST(updated_value == 52); // initial value was 42 } BOOST_MYSQL_NETWORK_TEST(select_ok, network_fixture) { setup_and_connect(sample.net); - auto result = conn->query("SELECT * FROM empty_table").get(); - BOOST_TEST(result->valid()); - BOOST_TEST(!result->complete()); - this->validate_2fields_meta(*result, "empty_table"); + + auto result = create_resultset(); + conn->query("SELECT * FROM empty_table", *result).get(); + + BOOST_TEST(result->base().valid()); + BOOST_TEST(!result->base().complete()); + this->validate_2fields_meta(result->base(), "empty_table"); } BOOST_MYSQL_NETWORK_TEST(select_error, network_fixture) { setup_and_connect(sample.net); - auto result = conn->query("SELECT field_varchar, field_bad FROM one_row_table"); - result.validate_error(errc::bad_field_error, {"unknown column", "field_bad"}); + auto result = create_resultset(); + auto netresult = conn->query("SELECT field_varchar, field_bad FROM one_row_table", *result); + netresult.validate_error(errc::bad_field_error, {"unknown column", "field_bad"}); } -BOOST_AUTO_TEST_SUITE_END() // test_query +BOOST_AUTO_TEST_SUITE_END() // test_query diff --git a/test/integration/utils/include/network_test.hpp b/test/integration/utils/include/network_test.hpp index 6afadcc3..d65c8a6f 100644 --- a/test/integration/utils/include/network_test.hpp +++ b/test/integration/utils/include/network_test.hpp @@ -8,6 +8,8 @@ #ifndef BOOST_MYSQL_TEST_INTEGRATION_UTILS_INCLUDE_NETWORK_TEST_HPP #define BOOST_MYSQL_TEST_INTEGRATION_UTILS_INCLUDE_NETWORK_TEST_HPP +#include + #include /** @@ -33,9 +35,8 @@ namespace test { // The type of a sample generated by DataGenerator template -using data_gen_sample_type = typename std::decay::type>()()[0] -)>::type; +using data_gen_sample_type = typename std::decay< + decltype(std::declval::type>()()[0])>::type; inline boost::unit_test::test_suite* create_test_suite( boost::unit_test::const_string tc_name, @@ -75,7 +76,7 @@ struct network_test_registrar // Create a test for each sample for (const auto& sample : datagen()) { - std::string test_name = stringize(sample); + std::string test_name = detail::stringize(sample); auto* test = boost::unit_test::make_test_case( [sample] { Testcase tc_struct; @@ -91,21 +92,18 @@ struct network_test_registrar } }; -} // test -} // mysql -} // boost +} // namespace test +} // namespace mysql +} // namespace boost -#define BOOST_MYSQL_NETWORK_TEST_EX(name, fixture, sample_generator) \ - struct name : public fixture \ - { \ +#define BOOST_MYSQL_NETWORK_TEST_EX(name, fixture, sample_generator) \ + struct name : public fixture \ + { \ void test_method(const data_gen_sample_type&); \ - }; \ - static ::boost::mysql::test::network_test_registrar \ - name##_registrar BOOST_ATTRIBUTE_UNUSED ( \ - #name, __FILE__, __LINE__, sample_generator); \ - void name::test_method( \ - const data_gen_sample_type& sample \ - ) + }; \ + static ::boost::mysql::test::network_test_registrar name##_registrar \ + BOOST_ATTRIBUTE_UNUSED(#name, __FILE__, __LINE__, sample_generator); \ + void name::test_method(const data_gen_sample_type& sample) #define BOOST_MYSQL_NETWORK_TEST(name, fixture) \ BOOST_MYSQL_NETWORK_TEST_EX(name, fixture, all_variants_gen())