mirror of
https://github.com/boostorg/mysql.git
synced 2026-02-15 01:02:17 +00:00
Completed serializ tests for ComStmtExecute
Now serialization tests provide better diagnostics
This commit is contained in:
@@ -87,14 +87,18 @@ constexpr std::uint16_t num = 32768; // Field is num (for clients)
|
||||
}
|
||||
|
||||
// Prepared statements
|
||||
constexpr std::uint8_t CURSOR_TYPE_NO_CURSOR = 0;
|
||||
constexpr std::uint8_t CURSOR_TYPE_READ_ONLY = 1;
|
||||
constexpr std::uint8_t CURSOR_TYPE_FOR_UPDATE = 2;
|
||||
constexpr std::uint8_t CURSOR_TYPE_SCROLLABLE = 4;
|
||||
namespace cursor_types
|
||||
{
|
||||
constexpr std::uint8_t no_cursor = 0;
|
||||
constexpr std::uint8_t read_only = 1;
|
||||
constexpr std::uint8_t for_update = 2;
|
||||
constexpr std::uint8_t scrollable = 4;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -23,13 +23,13 @@ inline protocol_field_type get_protocol_field_type(
|
||||
constexpr auto operator()(std::uint32_t) const noexcept { return protocol_field_type::long_; }
|
||||
constexpr auto operator()(std::int64_t) const noexcept { return protocol_field_type::longlong; }
|
||||
constexpr auto operator()(std::uint64_t) const noexcept { return protocol_field_type::longlong; }
|
||||
constexpr auto operator()(std::string_view) const noexcept { return protocol_field_type::var_string; }
|
||||
constexpr auto operator()(std::string_view) const noexcept { return protocol_field_type::varchar; }
|
||||
constexpr auto operator()(float) const noexcept { return protocol_field_type::float_; }
|
||||
constexpr auto operator()(double) const noexcept { return protocol_field_type::double_; }
|
||||
constexpr auto operator()(date) const noexcept { return protocol_field_type::date; }
|
||||
constexpr auto operator()(datetime) const noexcept { return protocol_field_type::datetime; }
|
||||
constexpr auto operator()(time) const noexcept { return protocol_field_type::time; }
|
||||
constexpr auto operator()(year) const noexcept { return protocol_field_type::year; }
|
||||
constexpr auto operator()(year) const noexcept { return protocol_field_type::short_; }
|
||||
constexpr auto operator()(std::nullptr_t) const noexcept { return protocol_field_type::null; }
|
||||
};
|
||||
return std::visit(visitor(), input);
|
||||
@@ -45,7 +45,8 @@ inline bool is_unsigned(
|
||||
return std::visit([](auto v) {
|
||||
using type = decltype(v);
|
||||
return std::is_same_v<type, std::uint32_t> ||
|
||||
std::is_same_v<type, std::uint64_t>;
|
||||
std::is_same_v<type, std::uint64_t> ||
|
||||
std::is_same_v<type, year>;
|
||||
}, input);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <gmock/gmock.h>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
@@ -69,6 +70,12 @@ inline std::string_view makesv(const std::uint8_t (&value) [N])
|
||||
return std::string_view(reinterpret_cast<const char*>(value), N);
|
||||
}
|
||||
|
||||
inline std::string_view makesv(const std::uint8_t* value, std::size_t size)
|
||||
{
|
||||
return std::string_view(reinterpret_cast<const char*>(value), size);
|
||||
}
|
||||
|
||||
|
||||
inline void validate_string_contains(std::string value, const std::vector<std::string>& to_check)
|
||||
{
|
||||
std::transform(value.begin(), value.end(), value.begin(), &tolower);
|
||||
@@ -83,6 +90,31 @@ inline void validate_error_info(const mysql::error_info& value, const std::vecto
|
||||
validate_string_contains(value.message(), to_check);
|
||||
}
|
||||
|
||||
inline std::string buffer_diff(std::string_view s0, std::string_view s1)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << std::hex;
|
||||
for (std::size_t i = 0; i < std::min(s0.size(), s1.size()); ++i)
|
||||
{
|
||||
unsigned b0 = reinterpret_cast<const std::uint8_t*>(s0.data())[i];
|
||||
unsigned b1 = reinterpret_cast<const std::uint8_t*>(s1.data())[i];
|
||||
if (b0 != b1)
|
||||
{
|
||||
ss << "i=" << i << ": " << b0 << " != " << b1 << "\n";
|
||||
}
|
||||
}
|
||||
if (s0.size() != s1.size())
|
||||
{
|
||||
ss << "sizes: " << s0.size() << " != " << s1.size() << "\n";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
inline void compare_buffers(std::string_view s0, std::string_view s1, const char* msg = "")
|
||||
{
|
||||
EXPECT_EQ(s0, s1) << msg << ":\n" << buffer_diff(s0, s1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -649,23 +649,128 @@ INSTANTIATE_TEST_SUITE_P(ComStmtExecute, SerializeTest, testing::Values(
|
||||
0xab, 0x00
|
||||
},
|
||||
"uint32_t"
|
||||
),
|
||||
make_stmt_execute_test(1, 0, 1, 1, // stmt ID, flags, itercount, new params
|
||||
{ std::int32_t(-0xabffff) }, {
|
||||
0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x01, 0x00,
|
||||
0x54, 0xff
|
||||
},
|
||||
"int32_t"
|
||||
),
|
||||
make_stmt_execute_test(1, 0x80, 1, 1, // stmt ID, flags, itercount, new params
|
||||
{ std::uint64_t(0xabffffabacadae) }, {
|
||||
0x17, 0x01, 0x00, 0x00, 0x00, 0x80, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x08, 0x80, 0xae, 0xad,
|
||||
0xac, 0xab, 0xff, 0xff, 0xab, 0x00
|
||||
},
|
||||
"uint64_t"
|
||||
),
|
||||
make_stmt_execute_test(1, 0, 1, 1, // stmt ID, flags, itercount, new params
|
||||
{ std::int64_t(-0xabffffabacadae) }, {
|
||||
0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x52, 0x52,
|
||||
0x53, 0x54, 0x00, 0x00, 0x54, 0xff
|
||||
},
|
||||
"int64_t"
|
||||
),
|
||||
make_stmt_execute_test(1, 0, 1, 1, // stmt ID, flags, itercount, new params
|
||||
{ std::string_view("test") }, {
|
||||
0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x0f, 0x00, 0x04, 0x74,
|
||||
0x65, 0x73, 0x74
|
||||
},
|
||||
"string_view"
|
||||
),
|
||||
make_stmt_execute_test(1, 0, 1, 1, // stmt ID, flags, itercount, new params
|
||||
{ 3.14e20f }, {
|
||||
0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x04, 0x00, 0x01, 0x2d,
|
||||
0x88, 0x61
|
||||
},
|
||||
"float"
|
||||
),
|
||||
make_stmt_execute_test(1, 0, 1, 1, // stmt ID, flags, itercount, new params
|
||||
{ 2.1e214 }, {
|
||||
0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x05, 0x00, 0x56, 0xc0,
|
||||
0xee, 0xa6, 0x95, 0x30, 0x6f, 0x6c
|
||||
},
|
||||
"double"
|
||||
),
|
||||
make_stmt_execute_test(1, 0, 1, 1, // stmt ID, flags, itercount, new params
|
||||
{ makedate(2010, 9, 3) }, {
|
||||
0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x0a, 0x00, 0x04, 0xda,
|
||||
0x07, 0x09, 0x03
|
||||
},
|
||||
"date"
|
||||
),
|
||||
make_stmt_execute_test(1, 0, 1, 1, // stmt ID, flags, itercount, new params
|
||||
{ makedt(2010, 9, 3, 10, 30, 59, 231800) }, {
|
||||
0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x0b, 0xda,
|
||||
0x07, 0x09, 0x03, 0x0a, 0x1e, 0x3b, 0x78, 0x89,
|
||||
0x03, 0x00
|
||||
},
|
||||
"datetime"
|
||||
),
|
||||
make_stmt_execute_test(1, 0, 1, 1, // stmt ID, flags, itercount, new params
|
||||
{ maket(230, 30, 59, 231800) }, {
|
||||
0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x0b, 0x00, 0x0c, 0x00,
|
||||
0x09, 0x00, 0x00, 0x00, 0x0e, 0x1e, 0x3b, 0x78,
|
||||
0x89, 0x03, 0x00
|
||||
},
|
||||
"time"
|
||||
),
|
||||
make_stmt_execute_test(1, 0, 1, 1, // stmt ID, flags, itercount, new params
|
||||
{ mysql::year(2010) }, {
|
||||
0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x02, 0x80, 0xda, 0x07
|
||||
},
|
||||
"year"
|
||||
),
|
||||
make_stmt_execute_test(1, 0, 1, 1, // stmt ID, flags, itercount, new params
|
||||
{ nullptr }, {
|
||||
0x17, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x01, 0x01, 0x06, 0x00
|
||||
},
|
||||
"null"
|
||||
),
|
||||
make_stmt_execute_test(2, 0, 1, 1, makevalues(
|
||||
std::uint32_t(0xabffff),
|
||||
std::int32_t(-0xabffff),
|
||||
std::uint64_t(0xabffffabacadae),
|
||||
std::int64_t(-0xabffffabacadae),
|
||||
std::string_view("test"),
|
||||
nullptr,
|
||||
2.1e214,
|
||||
mysql::year(2010),
|
||||
makedate(2010, 9, 3),
|
||||
makedt(2010, 9, 3, 10, 30, 59, 231800),
|
||||
maket(230, 30, 59, 231800),
|
||||
nullptr,
|
||||
mysql::year(2010)
|
||||
), {
|
||||
0x17, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x20, 0x08, 0x01, 0x03, 0x80, 0x03,
|
||||
0x00, 0x08, 0x80, 0x08, 0x00, 0x0f, 0x00, 0x06,
|
||||
0x00, 0x05, 0x00, 0x02, 0x80, 0x0a, 0x00, 0x0c,
|
||||
0x00, 0x0b, 0x00, 0x06, 0x00, 0x02, 0x80, 0xff,
|
||||
0xff, 0xab, 0x00, 0x01, 0x00, 0x54, 0xff, 0xae,
|
||||
0xad, 0xac, 0xab, 0xff, 0xff, 0xab, 0x00, 0x52,
|
||||
0x52, 0x53, 0x54, 0x00, 0x00, 0x54, 0xff, 0x04,
|
||||
0x74, 0x65, 0x73, 0x74, 0x56, 0xc0, 0xee, 0xa6,
|
||||
0x95, 0x30, 0x6f, 0x6c, 0xda, 0x07, 0x04, 0xda,
|
||||
0x07, 0x09, 0x03, 0x0b, 0xda, 0x07, 0x09, 0x03,
|
||||
0x0a, 0x1e, 0x3b, 0x78, 0x89, 0x03, 0x00, 0x0c,
|
||||
0x00, 0x09, 0x00, 0x00, 0x00, 0x0e, 0x1e, 0x3b,
|
||||
0x78, 0x89, 0x03, 0x00, 0xda, 0x07
|
||||
},
|
||||
"several_params"
|
||||
)
|
||||
));
|
||||
|
||||
/*
|
||||
* std::int32_t, // signed TINYINT, SMALLINT, MEDIUMINT, INT
|
||||
std::int64_t, // signed BIGINT
|
||||
std::uint32_t, // unsigned TINYINT, SMALLINT, MEDIUMINT, INT
|
||||
std::uint64_t, // unsigned BIGINT
|
||||
std::string_view, // CHAR, VARCHAR, BINARY, VARBINARY, TEXT (all sizes), BLOB (all sizes), ENUM, SET, DECIMAL, BIT, GEOMTRY
|
||||
float, // FLOAT
|
||||
double, // DOUBLE
|
||||
date, // DATE
|
||||
datetime, // DATETIME, TIMESTAMP
|
||||
time, // TIME
|
||||
year, // YEAR
|
||||
std::nullptr_t // Any of the above when the value is NULL
|
||||
*/
|
||||
|
||||
|
||||
} // anon namespace
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <boost/type_index.hpp>
|
||||
#include "mysql/impl/serialization.hpp"
|
||||
#include "mysql/value.hpp"
|
||||
#include "test_common.hpp"
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
@@ -178,11 +179,6 @@ std::vector<uint8_t> concat(std::vector<uint8_t>&& lhs, const std::vector<uint8_
|
||||
// Test fixtures
|
||||
struct SerializationFixture : public testing::TestWithParam<SerializeParams>
|
||||
{
|
||||
static std::string_view make_buffer_view(const uint8_t* buff, size_t sz)
|
||||
{
|
||||
return std::string_view(reinterpret_cast<const char*>(buff), sz);
|
||||
}
|
||||
|
||||
// get_size
|
||||
void get_size_test()
|
||||
{
|
||||
@@ -203,14 +199,14 @@ struct SerializationFixture : public testing::TestWithParam<SerializeParams>
|
||||
EXPECT_EQ(ctx.first(), buffer.data() + expected_size) << "Iterator not updated correctly";
|
||||
|
||||
// Buffer
|
||||
std::string_view expected_populated = make_buffer_view(GetParam().expected_buffer.data(), expected_size);
|
||||
std::string_view actual_populated = make_buffer_view(buffer.data(), expected_size);
|
||||
EXPECT_EQ(expected_populated, actual_populated) << "Buffer contents incorrect";
|
||||
std::string_view expected_populated = test::makesv(GetParam().expected_buffer.data(), expected_size);
|
||||
std::string_view actual_populated = test::makesv(buffer.data(), expected_size);
|
||||
test::compare_buffers(expected_populated, actual_populated, "Buffer contents incorrect");
|
||||
|
||||
// Check for buffer overruns
|
||||
std::string expected_clean (8, 0x7a);
|
||||
std::string_view actual_clean = make_buffer_view(buffer.data() + expected_size, 8);
|
||||
EXPECT_EQ(expected_clean, actual_clean) << "Buffer overrun";
|
||||
std::string_view actual_clean = test::makesv(buffer.data() + expected_size, 8);
|
||||
test::compare_buffers(expected_clean, actual_clean, "Buffer overrun");
|
||||
}
|
||||
|
||||
// deserialize
|
||||
|
||||
Reference in New Issue
Block a user