10#include <gtest/gtest.h>
35 header.
magic = 0xDEADBEEF;
47 original.
type = message_type::QUERY_REQUEST;
52 EXPECT_EQ(bytes.size(), 20u);
57 auto recovered = result.value();
58 EXPECT_EQ(recovered.magic, original.
magic);
59 EXPECT_EQ(recovered.version, original.
version);
60 EXPECT_EQ(recovered.type, original.
type);
61 EXPECT_EQ(recovered.request_id, original.
request_id);
62 EXPECT_EQ(recovered.payload_size, original.
payload_size);
66 std::vector<uint8_t> data = {0x01, 0x02, 0x03};
68 EXPECT_TRUE(result.is_err());
73 std::vector<uint8_t> data(20, 0);
75 data[0] = 0xEF; data[1] = 0xBE; data[2] = 0xAD; data[3] = 0xDE;
77 data[4] = 0x01; data[5] = 0x00;
80 EXPECT_TRUE(result.is_err());
85 message_type::CONNECT_REQUEST, message_type::CONNECT_RESPONSE,
86 message_type::DISCONNECT, message_type::PING, message_type::PONG,
87 message_type::QUERY_REQUEST, message_type::QUERY_RESPONSE,
88 message_type::BEGIN_TRANSACTION, message_type::COMMIT_TRANSACTION,
89 message_type::ROLLBACK_TRANSACTION, message_type::TRANSACTION_RESPONSE,
90 message_type::PREPARE_STATEMENT, message_type::EXECUTE_PREPARED,
91 message_type::CLOSE_PREPARED, message_type::ERROR_RESPONSE
94 for (
auto type : types) {
102 ASSERT_TRUE(result.is_ok()) <<
"Failed for message_type " <<
static_cast<uint16_t
>(type);
103 EXPECT_EQ(result.value().type, type);
109 header.
type = message_type::QUERY_REQUEST;
116 EXPECT_EQ(result.value().request_id, UINT64_MAX);
117 EXPECT_EQ(result.value().payload_size, UINT32_MAX);
130 original.
options = {{
"timeout",
"30"}, {
"ssl",
"true"}};
133 EXPECT_FALSE(bytes.empty());
138 auto recovered = result.value();
141 EXPECT_EQ(recovered.options.size(), original.
options.size());
142 EXPECT_EQ(recovered.options.at(
"timeout"),
"30");
143 EXPECT_EQ(recovered.options.at(
"ssl"),
"true");
155 auto recovered = result.value();
156 EXPECT_EQ(recovered.database_type,
"sqlite");
157 EXPECT_EQ(recovered.connection_string,
"file:test.db");
158 EXPECT_TRUE(recovered.options.empty());
162 std::vector<uint8_t> data = {0x01, 0x02};
164 EXPECT_TRUE(result.is_err());
177 auto recovered = result.value();
178 EXPECT_TRUE(recovered.success);
179 EXPECT_EQ(recovered.session_id,
"sess-abc-123-def-456");
180 EXPECT_TRUE(recovered.error_message.empty());
187 original.
error_message =
"Authentication failed: invalid credentials";
193 auto recovered = result.value();
194 EXPECT_FALSE(recovered.success);
195 EXPECT_TRUE(recovered.session_id.empty());
196 EXPECT_EQ(recovered.error_message,
"Authentication failed: invalid credentials");
200 std::vector<uint8_t> data;
202 EXPECT_TRUE(result.is_err());
213 original.
operation = query_operation::SELECT;
214 original.
query_string =
"SELECT * FROM users WHERE id = ?";
221 auto recovered = result.value();
222 EXPECT_EQ(recovered.operation, query_operation::SELECT);
223 EXPECT_EQ(recovered.query_string, original.
query_string);
224 ASSERT_EQ(recovered.parameters.size(), 1u);
225 EXPECT_EQ(recovered.parameters[0],
"42");
230 original.
operation = query_operation::INSERT;
231 original.
query_string =
"INSERT INTO users (name, email, age) VALUES (?, ?, ?)";
232 original.
parameters = {
"Alice",
"alice@example.com",
"30"};
238 auto recovered = result.value();
239 EXPECT_EQ(recovered.operation, query_operation::INSERT);
240 ASSERT_EQ(recovered.parameters.size(), 3u);
241 EXPECT_EQ(recovered.parameters[0],
"Alice");
242 EXPECT_EQ(recovered.parameters[1],
"alice@example.com");
243 EXPECT_EQ(recovered.parameters[2],
"30");
248 original.
operation = query_operation::CREATE;
249 original.
query_string =
"CREATE TABLE test (id INTEGER PRIMARY KEY)";
255 auto recovered = result.value();
256 EXPECT_EQ(recovered.operation, query_operation::CREATE);
257 EXPECT_TRUE(recovered.parameters.empty());
262 query_operation::SELECT, query_operation::INSERT,
263 query_operation::UPDATE, query_operation::DELETE,
264 query_operation::CREATE, query_operation::ALTER,
265 query_operation::DROP, query_operation::OTHER
268 for (
auto op : ops) {
275 ASSERT_TRUE(result.is_ok()) <<
"Failed for operation " <<
static_cast<int>(op);
276 EXPECT_EQ(result.value().operation, op);
282 original.
operation = query_operation::SELECT;
283 original.
query_string =
"SELECT * FROM users WHERE name LIKE ?";
284 original.
parameters = {
"O'Brien",
"50%",
"tab\tchar",
"newline\nchar"};
290 auto recovered = result.value();
291 ASSERT_EQ(recovered.parameters.size(), 4u);
292 EXPECT_EQ(recovered.parameters[0],
"O'Brien");
293 EXPECT_EQ(recovered.parameters[1],
"50%");
294 EXPECT_EQ(recovered.parameters[2],
"tab\tchar");
295 EXPECT_EQ(recovered.parameters[3],
"newline\nchar");
299 std::vector<uint8_t> data;
301 EXPECT_TRUE(result.is_err());
312 {{
"id",
"1"}, {
"name",
"Alice"}, {
"email",
"alice@test.com"}},
313 {{
"id",
"2"}, {
"name",
"Bob"}, {
"email",
"bob@test.com"}}
320 auto recovered = result.value();
321 EXPECT_TRUE(recovered.success);
322 EXPECT_EQ(recovered.affected_rows, 0u);
323 ASSERT_EQ(recovered.column_names.size(), 3u);
324 EXPECT_EQ(recovered.column_names[0],
"id");
325 EXPECT_EQ(recovered.column_names[1],
"name");
326 EXPECT_EQ(recovered.column_names[2],
"email");
328 EXPECT_EQ(recovered.rows[0].at(
"name"),
"Alice");
329 EXPECT_EQ(recovered.rows[1].at(
"email"),
"bob@test.com");
343 auto recovered = result.value();
344 EXPECT_TRUE(recovered.success);
345 EXPECT_EQ(recovered.affected_rows, 1u);
346 EXPECT_EQ(recovered.last_insert_id, 42u);
347 EXPECT_TRUE(recovered.column_names.empty());
348 EXPECT_TRUE(recovered.rows.empty());
355 original.
error_message =
"Access denied for user 'root'@'localhost'";
361 auto recovered = result.value();
362 EXPECT_FALSE(recovered.success);
363 EXPECT_EQ(recovered.error_code, 1045);
364 EXPECT_EQ(recovered.error_message,
"Access denied for user 'root'@'localhost'");
368 std::vector<uint8_t> data;
370 EXPECT_TRUE(result.is_err());
378 for (
int i = 0; i < 100; ++i) {
379 original.
rows.push_back({
380 {
"id", std::to_string(i)},
381 {
"data", std::string(256,
'x')}
389 auto recovered = result.value();
391 EXPECT_EQ(recovered.rows[50].at(
"id"),
"50");
392 EXPECT_EQ(recovered.rows[50].at(
"data").size(), 256u);
403 original.
operation = message_type::BEGIN_TRANSACTION;
408 EXPECT_EQ(result.value().operation, message_type::BEGIN_TRANSACTION);
413 original.
operation = message_type::COMMIT_TRANSACTION;
418 EXPECT_EQ(result.value().operation, message_type::COMMIT_TRANSACTION);
423 original.
operation = message_type::ROLLBACK_TRANSACTION;
428 EXPECT_EQ(result.value().operation, message_type::ROLLBACK_TRANSACTION);
432 std::vector<uint8_t> data = {0x01};
434 EXPECT_TRUE(result.is_err());
446 auto recovered = result.value();
447 EXPECT_TRUE(recovered.success);
448 EXPECT_TRUE(recovered.error_message.empty());
460 auto recovered = result.value();
461 EXPECT_FALSE(recovered.success);
462 EXPECT_EQ(recovered.error_message,
"Deadlock detected");
466 std::vector<uint8_t> data;
468 EXPECT_TRUE(result.is_err());
487 auto recovered = result.value();
488 EXPECT_EQ(recovered.error_code, 1001);
489 EXPECT_EQ(recovered.error_message,
"Table not found");
490 EXPECT_EQ(recovered.error_context,
"SELECT * FROM nonexistent_table");
503 auto recovered = result.value();
504 EXPECT_EQ(recovered.error_code, -1);
505 EXPECT_EQ(recovered.error_message,
"Internal server error");
506 EXPECT_TRUE(recovered.error_context.empty());
510 std::vector<uint8_t> data = {0x01, 0x02};
512 EXPECT_TRUE(result.is_err());
530 auto recovered = result.value();
531 EXPECT_TRUE(recovered.database_type.empty());
532 EXPECT_TRUE(recovered.connection_string.empty());
543 EXPECT_EQ(result.value().connection_string.size(), 4096u);
549 original.
connection_string =
"dbname=\xE4\xB8\xAD\xE6\x96\x87\xE6\xB5\x8B\xE8\xAF\x95";
562 for (
int i = 0; i < 50; ++i) {
563 original.
options[
"key_" + std::to_string(i)] =
"val_" + std::to_string(i);
570 auto recovered = result.value();
571 EXPECT_EQ(recovered.options.size(), 50u);
572 EXPECT_EQ(recovered.options.at(
"key_25"),
"val_25");
577 original.
operation = query_operation::SELECT;
580 for (
int i = 0; i < 100; ++i) {
581 original.
parameters.push_back(
"param_" + std::to_string(i));
588 auto recovered = result.value();
589 ASSERT_EQ(recovered.parameters.size(), 100u);
590 EXPECT_EQ(recovered.parameters[0],
"param_0");
591 EXPECT_EQ(recovered.parameters[99],
"param_99");
596 header.
type = message_type::PING;
603 EXPECT_EQ(result.value().request_id, 0u);
604 EXPECT_EQ(result.value().payload_size, 0u);
static kcenon::common::Result< connect_request > deserialize_connect_request(const std::vector< uint8_t > &data)
Deserialize connect request.
static kcenon::common::Result< message_header > deserialize_header(const std::vector< uint8_t > &data)
Deserialize message header from bytes.
static std::vector< uint8_t > serialize(const connect_request &request)
Serialize connect request.
static kcenon::common::Result< query_request > deserialize_query_request(const std::vector< uint8_t > &data)
Deserialize query request.
static kcenon::common::Result< connect_response > deserialize_connect_response(const std::vector< uint8_t > &data)
Deserialize connect response.
static std::vector< uint8_t > serialize_header(const message_header &header)
Serialize message header to bytes.
static kcenon::common::Result< transaction_response > deserialize_transaction_response(const std::vector< uint8_t > &data)
Deserialize transaction response.
static kcenon::common::Result< query_response > deserialize_query_response(const std::vector< uint8_t > &data)
Deserialize query response.
static kcenon::common::Result< error_response > deserialize_error_response(const std::vector< uint8_t > &data)
Deserialize error response.
static kcenon::common::Result< transaction_request > deserialize_transaction_request(const std::vector< uint8_t > &data)
Deserialize transaction request.
message_type
Database protocol message types.
query_operation
Type of query operation.
Client connection request.
std::string connection_string
std::map< std::string, std::string > options
std::string database_type
Server connection response.
std::string error_message
std::string error_message
std::string error_context
query_operation operation
std::vector< std::string > parameters
Query execution response.
std::string error_message
std::vector< std::map< std::string, std::string > > rows
std::vector< std::string > column_names
Transaction control request.
Transaction control response.
std::string error_message
#define ASSERT_EQ(expected, actual, message)
#define ASSERT_TRUE(condition, message)
TEST_F(MessageHeaderTest, DefaultMagicAndVersion)