core/protocol: test de/serialization of all protocol messages
Build and test / check (push) Successful in 1m42s
Build and test / check-license (push) Successful in 57s
Build and test / build (push) Successful in 2m40s
Build and test / test (push) Failing after 3m45s
Build and test / docs (push) Successful in 5m23s

This commit is contained in:
2026-04-28 07:27:55 +09:00
parent b12acbf3b4
commit 5444ab46ca
16 changed files with 538 additions and 1 deletions
+1 -1
View File
@@ -29,7 +29,7 @@ pub const DATABASE_PRIVILEGE_FIELDS: [&str; 13] = [
// doesn't have any natural implementation semantics.
/// Representation of the set of privileges for a single user on a single database.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, PartialOrd, Ord, Default)]
pub struct DatabasePrivilegeRow {
// TODO: don't store the db and user here, let the type be stored in a mapping
pub db: MySQLDatabase,
@@ -67,3 +67,43 @@ impl CheckAuthorizationError {
self.0.error_type()
}
}
#[cfg(test)]
mod tests {
use crate::core::protocol::request_validation::NameValidationError;
use super::*;
#[test]
fn test_serialize_deserialize_request() {
let request: CheckAuthorizationRequest = vec![
DbOrUser::Database("test_db".into()),
DbOrUser::User("test_user".into()),
];
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: CheckAuthorizationRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response: CheckAuthorizationResponse = BTreeMap::from([
(DbOrUser::Database("test_db".into()), Ok(())),
(
DbOrUser::User("test_user".into()),
Err(CheckAuthorizationError(
ValidationError::NameValidationError(NameValidationError::TooLong),
)),
),
]);
let json = serde_json::to_string_pretty(&response).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: CheckAuthorizationResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response, deserialized);
}
}
@@ -87,3 +87,41 @@ impl CreateDatabaseError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_request() {
let request: CreateDatabasesRequest =
vec!["test_db1".into(), "test_db2".into(), "test_db3".into()];
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: CreateDatabasesRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response: CreateDatabasesResponse = BTreeMap::from([
("test_db1".into(), Ok(())),
(
"test_db2".into(),
Err(CreateDatabaseError::DatabaseAlreadyExists),
),
(
"test_db3".into(),
Err(CreateDatabaseError::MySqlError("Some MySQL error".into())),
),
]);
let json = serde_json::to_string_pretty(&response).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: CreateDatabasesResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response, deserialized);
}
}
@@ -87,3 +87,37 @@ impl CreateUserError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_request() {
let request: CreateUsersRequest = vec!["alice".into(), "bob".into(), "charlie".into()];
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: CreateUsersRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response: CreateUsersResponse = BTreeMap::from([
("alice".into(), Ok(())),
("bob".into(), Err(CreateUserError::UserAlreadyExists)),
(
"charlie".into(),
Err(CreateUserError::MySqlError("Some MySQL error".into())),
),
]);
let json = serde_json::to_string_pretty(&response).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: CreateUsersResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response, deserialized);
}
}
@@ -90,3 +90,37 @@ impl DropDatabaseError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_request() {
let request: DropDatabasesRequest = vec!["db1".into(), "db2".into(), "db3".into()];
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: DropDatabasesRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response: DropDatabasesResponse = BTreeMap::from([
("db1".into(), Ok(())),
("db2".into(), Err(DropDatabaseError::DatabaseDoesNotExist)),
(
"db3".into(),
Err(DropDatabaseError::MySqlError("Some MySQL error".into())),
),
]);
let json = serde_json::to_string_pretty(&response).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: DropDatabasesResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response, deserialized);
}
}
+34
View File
@@ -87,3 +87,37 @@ impl DropUserError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_request() {
let request: DropUsersRequest = vec!["alice".into(), "bob".into(), "charlie".into()];
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: DropUsersRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response: DropUsersResponse = BTreeMap::from([
("alice".into(), Ok(())),
("bob".into(), Err(DropUserError::UserDoesNotExist)),
(
"charlie".into(),
Err(DropUserError::MySqlError("Some MySQL error".into())),
),
]);
let json = serde_json::to_string_pretty(&response).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: DropUsersResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response, deserialized);
}
}
@@ -27,3 +27,36 @@ impl ListAllDatabasesError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_response() {
let response: ListAllDatabasesResponse = Ok(vec![
DatabaseRow {
database: "db1".into(),
tables: vec!["table1".into(), "table2".into()],
users: vec!["user1".into(), "user2".into()],
collation: Some("utf8mb4_general_ci".into()),
character_set: Some("utf8mb4".into()),
size_bytes: 1024,
},
DatabaseRow {
database: "db2".into(),
tables: vec!["table3".into(), "table4".into()],
users: vec!["user3".into(), "user4".into()],
collation: Some("utf8mb4_general_ci".into()),
character_set: Some("utf8mb4".into()),
size_bytes: 2048,
},
]);
let json = serde_json::to_string_pretty(&response).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: ListAllDatabasesResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response, deserialized);
}
}
@@ -27,3 +27,34 @@ impl ListAllPrivilegesError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_response() {
let response: ListAllPrivilegesResponse = Ok(vec![
DatabasePrivilegeRow {
user: "user1".into(),
db: "db1".into(),
select_priv: true,
insert_priv: false,
..Default::default()
},
DatabasePrivilegeRow {
user: "user2".into(),
db: "db2".into(),
select_priv: false,
insert_priv: true,
..Default::default()
},
]);
let json = serde_json::to_string_pretty(&response).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: ListAllPrivilegesResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response, deserialized);
}
}
@@ -27,3 +27,37 @@ impl ListAllUsersError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_response() {
let response: ListAllUsersResponse = Ok(vec![
DatabaseUser {
user: "user1".into(),
host: "%".into(),
has_password: true,
is_locked: false,
databases: vec!["db1".into(), "db2".into()],
},
DatabaseUser {
user: "user2".into(),
host: "%".into(),
has_password: false,
is_locked: true,
databases: vec!["db3".into()],
},
]);
let json = serde_json::to_string_pretty(&response).unwrap();
println!("Serialized response:\n{}", json);
let mut deserialized: ListAllUsersResponse = serde_json::from_str(&json).unwrap();
deserialized.as_mut().unwrap()[0].host = "%".into();
deserialized.as_mut().unwrap()[1].host = "%".into();
assert_eq!(response, deserialized);
}
}
@@ -137,3 +137,44 @@ impl ListDatabasesError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_request() {
let request = Some(vec!["db1".into(), "db2".into()]);
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: ListDatabasesRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response: ListDatabasesResponse = vec![
(
"db1".into(),
Ok(DatabaseRow {
database: "db1".into(),
tables: vec!["table1".to_string(), "table2".to_string()],
users: vec!["user1".into(), "user2".into()],
collation: Some("utf8mb4_general_ci".to_string()),
character_set: Some("utf8mb4".to_string()),
size_bytes: 1024,
}),
),
("db2".into(), Err(ListDatabasesError::DatabaseDoesNotExist)),
]
.into_iter()
.collect();
let json = serde_json::to_string_pretty(&response).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: ListDatabasesResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response, deserialized);
}
}
@@ -153,3 +153,44 @@ impl ListPrivilegesError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_request() {
let request: ListPrivilegesRequest = Some(vec!["test_db1".into(), "test_db2".into()]);
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: ListPrivilegesRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response: ListPrivilegesResponse = BTreeMap::from([
(
"test_db1".into(),
Ok(vec![DatabasePrivilegeRow {
db: "test_db1".into(),
user: "user1".into(),
select_priv: true,
insert_priv: false,
..Default::default()
}]),
),
(
"test_db2".into(),
Err(ListPrivilegesError::DatabaseDoesNotExist),
),
]);
let json = serde_json::to_string_pretty(&response).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: ListPrivilegesResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response, deserialized);
}
}
+45
View File
@@ -121,3 +121,48 @@ impl ListUsersError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_request() {
let request: ListUsersRequest = Some(vec!["test_user1".into(), "test_user2".into()]);
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: ListUsersRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response_ok: ListUsersResponse = BTreeMap::from([
(
"test_user1".into(),
Ok(DatabaseUser {
user: "test_user1".into(),
host: "%".into(),
has_password: true,
is_locked: false,
databases: vec!["db1".into(), "db2".into()],
}),
),
("test_user2".into(), Err(ListUsersError::UserDoesNotExist)),
]);
let json = serde_json::to_string_pretty(&response_ok).unwrap();
println!("Serialized response:\n{}", json);
let mut deserialized: ListUsersResponse = serde_json::from_str(&json).unwrap();
deserialized
.get_mut(&"test_user1".into())
.unwrap()
.as_mut()
.unwrap()
.host = "%".into();
assert_eq!(response_ok, deserialized);
}
}
+30
View File
@@ -94,3 +94,33 @@ impl LockUserError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_request() {
let request: LockUsersRequest = vec!["test_user1".into(), "test_user2".into()];
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: LockUsersRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response_ok: LockUsersResponse = BTreeMap::from([
("test_user1".into(), Ok(())),
("test_user2".into(), Err(LockUserError::UserDoesNotExist)),
]);
let json = serde_json::to_string_pretty(&response_ok).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: LockUsersResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response_ok, deserialized);
}
}
@@ -144,3 +144,43 @@ impl DiffDoesNotApplyError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::core::*;
#[test]
fn test_serialize_deserialize_request() {
let request =
BTreeSet::from([DatabasePrivilegesDiff::Modified(DatabasePrivilegeRowDiff {
db: "test_db".into(),
user: "test_user".into(),
select_priv: Some(database_privileges::DatabasePrivilegeChange::NoToYes),
..Default::default()
})]);
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: ModifyPrivilegesRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response: ModifyPrivilegesResponse = BTreeMap::from([
(("test_db".into(), "test_user".into()), Ok(())),
(
("test_db".into(), "invalid_user".into()),
Err(ModifyDatabasePrivilegesError::UserDoesNotExist),
),
]);
let json = serde_json::to_string_pretty(&response).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: ModifyPrivilegesResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response, deserialized);
}
}
+32
View File
@@ -60,3 +60,35 @@ impl SetPasswordError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_request() {
let request: SetUserPasswordRequest = ("test_user".into(), "new_password".into());
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: SetUserPasswordRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response_ok: SetUserPasswordResponse = Ok(());
let response_err: SetUserPasswordResponse = Err(SetPasswordError::UserDoesNotExist);
let json_ok = serde_json::to_string_pretty(&response_ok).unwrap();
let json_err = serde_json::to_string_pretty(&response_err).unwrap();
println!("Serialized OK response:\n{}", json_ok);
println!("Serialized Error response:\n{}", json_err);
let deserialized_ok: SetUserPasswordResponse = serde_json::from_str(&json_ok).unwrap();
let deserialized_err: SetUserPasswordResponse = serde_json::from_str(&json_err).unwrap();
assert_eq!(response_ok, deserialized_ok);
assert_eq!(response_err, deserialized_err);
}
}
@@ -94,3 +94,33 @@ impl UnlockUserError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_serialize_deserialize_request() {
let request: UnlockUsersRequest = vec!["test_user1".into(), "test_user2".into()];
let json = serde_json::to_string_pretty(&request).unwrap();
println!("Serialized request:\n{}", json);
let deserialized: UnlockUsersRequest = serde_json::from_str(&json).unwrap();
assert_eq!(request, deserialized);
}
#[test]
fn test_serialize_deserialize_response() {
let response_ok: UnlockUsersResponse = BTreeMap::from([
("test_user1".into(), Ok(())),
("test_user2".into(), Err(UnlockUserError::UserDoesNotExist)),
]);
let json = serde_json::to_string_pretty(&response_ok).unwrap();
println!("Serialized response:\n{}", json);
let deserialized: UnlockUsersResponse = serde_json::from_str(&json).unwrap();
assert_eq!(response_ok, deserialized);
}
}