mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-10 15:16:56 +00:00
add disk test
This commit is contained in:
+217
-294
@@ -454,106 +454,29 @@ impl Eq for DiskError {}
|
||||
|
||||
impl Hash for DiskError {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
match self {
|
||||
DiskError::Io(e) => e.to_string().hash(state),
|
||||
_ => self.to_u32().hash(state),
|
||||
}
|
||||
self.to_u32().hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
// impl CheckErrorFn for DiskError {
|
||||
// fn is(&self, e: &DiskError) -> bool {
|
||||
// NOTE: Remove commented out code later if not needed
|
||||
// Some error-related helper functions and complex error handling logic
|
||||
// is currently commented out to avoid complexity. These can be re-enabled
|
||||
// when needed for specific disk quorum checking and error aggregation logic.
|
||||
|
||||
// }
|
||||
// }
|
||||
/// Bitrot errors
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum BitrotErrorType {
|
||||
#[error("bitrot checksum verification failed")]
|
||||
BitrotChecksumMismatch { expected: String, got: String },
|
||||
}
|
||||
|
||||
// pub fn clone_disk_err(e: &DiskError) -> Error {
|
||||
// match e {
|
||||
// DiskError::MaxVersionsExceeded => DiskError::MaxVersionsExceeded,
|
||||
// DiskError::Unexpected => DiskError::Unexpected,
|
||||
// DiskError::CorruptedFormat => DiskError::CorruptedFormat,
|
||||
// DiskError::CorruptedBackend => DiskError::CorruptedBackend,
|
||||
// DiskError::UnformattedDisk => DiskError::UnformattedDisk,
|
||||
// DiskError::InconsistentDisk => DiskError::InconsistentDisk,
|
||||
// DiskError::UnsupportedDisk => DiskError::UnsupportedDisk,
|
||||
// DiskError::DiskFull => DiskError::DiskFull,
|
||||
// DiskError::DiskNotDir => DiskError::DiskNotDir,
|
||||
// DiskError::DiskNotFound => DiskError::DiskNotFound,
|
||||
// DiskError::DiskOngoingReq => DiskError::DiskOngoingReq,
|
||||
// DiskError::DriveIsRoot => DiskError::DriveIsRoot,
|
||||
// DiskError::FaultyRemoteDisk => DiskError::FaultyRemoteDisk,
|
||||
// DiskError::FaultyDisk => DiskError::FaultyDisk,
|
||||
// DiskError::DiskAccessDenied => DiskError::DiskAccessDenied,
|
||||
// DiskError::FileNotFound => DiskError::FileNotFound,
|
||||
// DiskError::FileVersionNotFound => DiskError::FileVersionNotFound,
|
||||
// DiskError::TooManyOpenFiles => DiskError::TooManyOpenFiles,
|
||||
// DiskError::FileNameTooLong => DiskError::FileNameTooLong,
|
||||
// DiskError::VolumeExists => DiskError::VolumeExists,
|
||||
// DiskError::IsNotRegular => DiskError::IsNotRegular,
|
||||
// DiskError::PathNotFound => DiskError::PathNotFound,
|
||||
// DiskError::VolumeNotFound => DiskError::VolumeNotFound,
|
||||
// DiskError::VolumeNotEmpty => DiskError::VolumeNotEmpty,
|
||||
// DiskError::VolumeAccessDenied => DiskError::VolumeAccessDenied,
|
||||
// DiskError::FileAccessDenied => DiskError::FileAccessDenied,
|
||||
// DiskError::FileCorrupt => DiskError::FileCorrupt,
|
||||
// DiskError::BitrotHashAlgoInvalid => DiskError::BitrotHashAlgoInvalid,
|
||||
// DiskError::CrossDeviceLink => DiskError::CrossDeviceLink,
|
||||
// DiskError::LessData => DiskError::LessData,
|
||||
// DiskError::MoreData => DiskError::MoreData,
|
||||
// DiskError::OutdatedXLMeta => DiskError::OutdatedXLMeta,
|
||||
// DiskError::PartMissingOrCorrupt => DiskError::PartMissingOrCorrupt,
|
||||
// DiskError::NoHealRequired => DiskError::NoHealRequired,
|
||||
// DiskError::Other(s) => DiskError::Other(s.clone()),
|
||||
// }
|
||||
// }
|
||||
|
||||
// pub fn os_err_to_file_err(e: io::Error) -> Error {
|
||||
// match e.kind() {
|
||||
// ErrorKind::NotFound => Error::new(DiskError::FileNotFound),
|
||||
// ErrorKind::PermissionDenied => Error::new(DiskError::FileAccessDenied),
|
||||
// // io::ErrorKind::ConnectionRefused => todo!(),
|
||||
// // io::ErrorKind::ConnectionReset => todo!(),
|
||||
// // io::ErrorKind::HostUnreachable => todo!(),
|
||||
// // io::ErrorKind::NetworkUnreachable => todo!(),
|
||||
// // io::ErrorKind::ConnectionAborted => todo!(),
|
||||
// // io::ErrorKind::NotConnected => todo!(),
|
||||
// // io::ErrorKind::AddrInUse => todo!(),
|
||||
// // io::ErrorKind::AddrNotAvailable => todo!(),
|
||||
// // io::ErrorKind::NetworkDown => todo!(),
|
||||
// // io::ErrorKind::BrokenPipe => todo!(),
|
||||
// // io::ErrorKind::AlreadyExists => todo!(),
|
||||
// // io::ErrorKind::WouldBlock => todo!(),
|
||||
// // io::ErrorKind::NotADirectory => DiskError::FileNotFound,
|
||||
// // io::ErrorKind::IsADirectory => DiskError::FileNotFound,
|
||||
// // io::ErrorKind::DirectoryNotEmpty => DiskError::VolumeNotEmpty,
|
||||
// // io::ErrorKind::ReadOnlyFilesystem => todo!(),
|
||||
// // io::ErrorKind::FilesystemLoop => todo!(),
|
||||
// // io::ErrorKind::StaleNetworkFileHandle => todo!(),
|
||||
// // io::ErrorKind::InvalidInput => todo!(),
|
||||
// // io::ErrorKind::InvalidData => todo!(),
|
||||
// // io::ErrorKind::TimedOut => todo!(),
|
||||
// // io::ErrorKind::WriteZero => todo!(),
|
||||
// // io::ErrorKind::StorageFull => DiskError::DiskFull,
|
||||
// // io::ErrorKind::NotSeekable => todo!(),
|
||||
// // io::ErrorKind::FilesystemQuotaExceeded => todo!(),
|
||||
// // io::ErrorKind::FileTooLarge => todo!(),
|
||||
// // io::ErrorKind::ResourceBusy => todo!(),
|
||||
// // io::ErrorKind::ExecutableFileBusy => todo!(),
|
||||
// // io::ErrorKind::Deadlock => todo!(),
|
||||
// // io::ErrorKind::CrossesDevices => todo!(),
|
||||
// // io::ErrorKind::TooManyLinks =>DiskError::TooManyOpenFiles,
|
||||
// // io::ErrorKind::InvalidFilename => todo!(),
|
||||
// // io::ErrorKind::ArgumentListTooLong => todo!(),
|
||||
// // io::ErrorKind::Interrupted => todo!(),
|
||||
// // io::ErrorKind::Unsupported => todo!(),
|
||||
// // io::ErrorKind::UnexpectedEof => todo!(),
|
||||
// // io::ErrorKind::OutOfMemory => todo!(),
|
||||
// // io::ErrorKind::Other => todo!(),
|
||||
// // TODO: 把不支持的 king 用字符串处理
|
||||
// _ => Error::new(e),
|
||||
// }
|
||||
// }
|
||||
impl From<BitrotErrorType> for DiskError {
|
||||
fn from(e: BitrotErrorType) -> Self {
|
||||
DiskError::other(e)
|
||||
}
|
||||
}
|
||||
|
||||
/// Context wrapper for file access errors
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub struct FileAccessDeniedWithContext {
|
||||
pub path: PathBuf,
|
||||
@@ -563,239 +486,239 @@ pub struct FileAccessDeniedWithContext {
|
||||
|
||||
impl std::fmt::Display for FileAccessDeniedWithContext {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "访问文件 '{}' 被拒绝:{}", self.path.display(), self.source)
|
||||
write!(f, "file access denied for path: {}", self.path.display())
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn is_unformatted_disk(err: &Error) -> bool {
|
||||
// matches!(err.downcast_ref::<DiskError>(), Some(DiskError::UnformattedDisk))
|
||||
// }
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
// pub fn is_err_file_not_found(err: &Error) -> bool {
|
||||
// if let Some(ioerr) = err.downcast_ref::<io::Error>() {
|
||||
// return ioerr.kind() == ErrorKind::NotFound;
|
||||
// }
|
||||
#[test]
|
||||
fn test_disk_error_variants() {
|
||||
let errors = vec![
|
||||
DiskError::MaxVersionsExceeded,
|
||||
DiskError::Unexpected,
|
||||
DiskError::CorruptedFormat,
|
||||
DiskError::CorruptedBackend,
|
||||
DiskError::UnformattedDisk,
|
||||
DiskError::InconsistentDisk,
|
||||
DiskError::UnsupportedDisk,
|
||||
DiskError::DiskFull,
|
||||
DiskError::DiskNotDir,
|
||||
DiskError::DiskNotFound,
|
||||
DiskError::DiskOngoingReq,
|
||||
DiskError::DriveIsRoot,
|
||||
DiskError::FaultyRemoteDisk,
|
||||
DiskError::FaultyDisk,
|
||||
DiskError::DiskAccessDenied,
|
||||
DiskError::FileNotFound,
|
||||
DiskError::FileVersionNotFound,
|
||||
DiskError::TooManyOpenFiles,
|
||||
DiskError::FileNameTooLong,
|
||||
DiskError::VolumeExists,
|
||||
DiskError::IsNotRegular,
|
||||
DiskError::PathNotFound,
|
||||
DiskError::VolumeNotFound,
|
||||
DiskError::VolumeNotEmpty,
|
||||
DiskError::VolumeAccessDenied,
|
||||
DiskError::FileAccessDenied,
|
||||
DiskError::FileCorrupt,
|
||||
DiskError::ShortWrite,
|
||||
DiskError::BitrotHashAlgoInvalid,
|
||||
DiskError::CrossDeviceLink,
|
||||
DiskError::LessData,
|
||||
DiskError::MoreData,
|
||||
DiskError::OutdatedXLMeta,
|
||||
DiskError::PartMissingOrCorrupt,
|
||||
DiskError::NoHealRequired,
|
||||
DiskError::MethodNotAllowed,
|
||||
DiskError::ErasureWriteQuorum,
|
||||
DiskError::ErasureReadQuorum,
|
||||
];
|
||||
|
||||
// matches!(err.downcast_ref::<DiskError>(), Some(DiskError::FileNotFound))
|
||||
// }
|
||||
for error in errors {
|
||||
// Test error display
|
||||
assert!(!error.to_string().is_empty());
|
||||
|
||||
// pub fn is_err_file_version_not_found(err: &Error) -> bool {
|
||||
// matches!(err.downcast_ref::<DiskError>(), Some(DiskError::FileVersionNotFound))
|
||||
// }
|
||||
// Test error conversion to u32 and back
|
||||
let code = error.to_u32();
|
||||
let converted_back = DiskError::from_u32(code);
|
||||
assert!(converted_back.is_some());
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn is_err_volume_not_found(err: &Error) -> bool {
|
||||
// matches!(err.downcast_ref::<DiskError>(), Some(DiskError::VolumeNotFound))
|
||||
// }
|
||||
#[test]
|
||||
fn test_disk_error_other() {
|
||||
let custom_error = DiskError::other("custom error message");
|
||||
assert!(matches!(custom_error, DiskError::Io(_)));
|
||||
// The error message format might vary, so just check it's not empty
|
||||
assert!(!custom_error.to_string().is_empty());
|
||||
}
|
||||
|
||||
// pub fn is_err_eof(err: &Error) -> bool {
|
||||
// if let Some(ioerr) = err.downcast_ref::<io::Error>() {
|
||||
// return ioerr.kind() == ErrorKind::UnexpectedEof;
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
#[test]
|
||||
fn test_disk_error_from_io_error() {
|
||||
let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
|
||||
let disk_error = DiskError::from(io_error);
|
||||
assert!(matches!(disk_error, DiskError::Io(_)));
|
||||
}
|
||||
|
||||
// pub fn is_sys_err_no_space(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// return no == 28;
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
#[test]
|
||||
fn test_is_all_not_found() {
|
||||
// Empty slice
|
||||
assert!(!DiskError::is_all_not_found(&[]));
|
||||
|
||||
// pub fn is_sys_err_invalid_arg(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// return no == 22;
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
// All file not found
|
||||
let all_not_found = vec![
|
||||
Some(DiskError::FileNotFound),
|
||||
Some(DiskError::FileVersionNotFound),
|
||||
Some(DiskError::FileNotFound),
|
||||
];
|
||||
assert!(DiskError::is_all_not_found(&all_not_found));
|
||||
|
||||
// pub fn is_sys_err_io(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// return no == 5;
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
// Mixed errors
|
||||
let mixed_errors = vec![
|
||||
Some(DiskError::FileNotFound),
|
||||
Some(DiskError::DiskNotFound),
|
||||
Some(DiskError::FileNotFound),
|
||||
];
|
||||
assert!(!DiskError::is_all_not_found(&mixed_errors));
|
||||
|
||||
// pub fn is_sys_err_is_dir(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// return no == 21;
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
// Contains None
|
||||
let with_none = vec![Some(DiskError::FileNotFound), None, Some(DiskError::FileNotFound)];
|
||||
assert!(!DiskError::is_all_not_found(&with_none));
|
||||
}
|
||||
|
||||
// pub fn is_sys_err_not_dir(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// return no == 20;
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
#[test]
|
||||
fn test_is_err_object_not_found() {
|
||||
assert!(DiskError::is_err_object_not_found(&DiskError::FileNotFound));
|
||||
assert!(DiskError::is_err_object_not_found(&DiskError::VolumeNotFound));
|
||||
assert!(!DiskError::is_err_object_not_found(&DiskError::DiskNotFound));
|
||||
assert!(!DiskError::is_err_object_not_found(&DiskError::FileCorrupt));
|
||||
}
|
||||
|
||||
// pub fn is_sys_err_too_long(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// return no == 63;
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
#[test]
|
||||
fn test_is_err_version_not_found() {
|
||||
assert!(DiskError::is_err_version_not_found(&DiskError::FileVersionNotFound));
|
||||
assert!(!DiskError::is_err_version_not_found(&DiskError::FileNotFound));
|
||||
assert!(!DiskError::is_err_version_not_found(&DiskError::VolumeNotFound));
|
||||
}
|
||||
|
||||
// pub fn is_sys_err_too_many_symlinks(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// return no == 62;
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
#[test]
|
||||
fn test_disk_error_to_u32_from_u32() {
|
||||
let test_cases = vec![
|
||||
(DiskError::MaxVersionsExceeded, 1),
|
||||
(DiskError::Unexpected, 2),
|
||||
(DiskError::CorruptedFormat, 3),
|
||||
(DiskError::UnformattedDisk, 5),
|
||||
(DiskError::DiskNotFound, 10),
|
||||
(DiskError::FileNotFound, 16),
|
||||
(DiskError::VolumeNotFound, 23),
|
||||
];
|
||||
|
||||
// pub fn is_sys_err_not_empty(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// if no == 66 {
|
||||
// return true;
|
||||
// }
|
||||
for (error, expected_code) in test_cases {
|
||||
assert_eq!(error.to_u32(), expected_code);
|
||||
assert_eq!(DiskError::from_u32(expected_code), Some(error));
|
||||
}
|
||||
|
||||
// if cfg!(target_os = "solaris") && no == 17 {
|
||||
// return true;
|
||||
// }
|
||||
// Test unknown error code
|
||||
assert_eq!(DiskError::from_u32(999), None);
|
||||
}
|
||||
|
||||
// if cfg!(target_os = "windows") && no == 145 {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
#[test]
|
||||
fn test_disk_error_equality() {
|
||||
assert_eq!(DiskError::FileNotFound, DiskError::FileNotFound);
|
||||
assert_ne!(DiskError::FileNotFound, DiskError::VolumeNotFound);
|
||||
|
||||
// pub fn is_sys_err_path_not_found(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// if cfg!(target_os = "windows") {
|
||||
// if no == 3 {
|
||||
// return true;
|
||||
// }
|
||||
// } else if no == 2 {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
let error1 = DiskError::other("test");
|
||||
let error2 = DiskError::other("test");
|
||||
// IO errors with the same message should be equal
|
||||
assert_eq!(error1, error2);
|
||||
}
|
||||
|
||||
// pub fn is_sys_err_handle_invalid(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// if cfg!(target_os = "windows") {
|
||||
// if no == 6 {
|
||||
// return true;
|
||||
// }
|
||||
// } else {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
#[test]
|
||||
fn test_disk_error_clone() {
|
||||
let original = DiskError::FileNotFound;
|
||||
let cloned = original.clone();
|
||||
assert_eq!(original, cloned);
|
||||
|
||||
// pub fn is_sys_err_cross_device(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// return no == 18;
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
let io_error = DiskError::other("test error");
|
||||
let cloned_io = io_error.clone();
|
||||
assert_eq!(io_error, cloned_io);
|
||||
}
|
||||
|
||||
// pub fn is_sys_err_too_many_files(e: &io::Error) -> bool {
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// return no == 23 || no == 24;
|
||||
// }
|
||||
// false
|
||||
// }
|
||||
#[test]
|
||||
fn test_disk_error_hash() {
|
||||
let mut map = HashMap::new();
|
||||
map.insert(DiskError::FileNotFound, "file not found");
|
||||
map.insert(DiskError::VolumeNotFound, "volume not found");
|
||||
|
||||
// pub fn os_is_not_exist(e: &io::Error) -> bool {
|
||||
// e.kind() == ErrorKind::NotFound
|
||||
// }
|
||||
assert_eq!(map.get(&DiskError::FileNotFound), Some(&"file not found"));
|
||||
assert_eq!(map.get(&DiskError::VolumeNotFound), Some(&"volume not found"));
|
||||
assert_eq!(map.get(&DiskError::DiskNotFound), None);
|
||||
}
|
||||
|
||||
// pub fn os_is_permission(e: &io::Error) -> bool {
|
||||
// if e.kind() == ErrorKind::PermissionDenied {
|
||||
// return true;
|
||||
// }
|
||||
// if let Some(no) = e.raw_os_error() {
|
||||
// if no == 30 {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
#[test]
|
||||
fn test_error_conversions() {
|
||||
// Test From implementations
|
||||
let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "test");
|
||||
let _disk_error: DiskError = io_error.into();
|
||||
|
||||
// false
|
||||
// }
|
||||
let json_str = r#"{"invalid": json}"#; // Invalid JSON
|
||||
let json_error = serde_json::from_str::<serde_json::Value>(json_str).unwrap_err();
|
||||
let _disk_error: DiskError = json_error.into();
|
||||
}
|
||||
|
||||
// pub fn os_is_exist(e: &io::Error) -> bool {
|
||||
// e.kind() == ErrorKind::AlreadyExists
|
||||
// }
|
||||
#[test]
|
||||
fn test_bitrot_error_type() {
|
||||
let bitrot_error = BitrotErrorType::BitrotChecksumMismatch {
|
||||
expected: "abc123".to_string(),
|
||||
got: "def456".to_string(),
|
||||
};
|
||||
|
||||
// // map_err_not_exists
|
||||
// pub fn map_err_not_exists(e: io::Error) -> Error {
|
||||
// if os_is_not_exist(&e) {
|
||||
// return Error::new(DiskError::VolumeNotEmpty);
|
||||
// } else if is_sys_err_io(&e) {
|
||||
// return Error::new(DiskError::FaultyDisk);
|
||||
// }
|
||||
assert!(bitrot_error.to_string().contains("bitrot checksum verification failed"));
|
||||
|
||||
// Error::new(e)
|
||||
// }
|
||||
let disk_error: DiskError = bitrot_error.into();
|
||||
assert!(matches!(disk_error, DiskError::Io(_)));
|
||||
}
|
||||
|
||||
// pub fn convert_access_error(e: io::Error, per_err: DiskError) -> Error {
|
||||
// if os_is_not_exist(&e) {
|
||||
// return Error::new(DiskError::VolumeNotEmpty);
|
||||
// } else if is_sys_err_io(&e) {
|
||||
// return Error::new(DiskError::FaultyDisk);
|
||||
// } else if os_is_permission(&e) {
|
||||
// return Error::new(per_err);
|
||||
// }
|
||||
#[test]
|
||||
fn test_file_access_denied_with_context() {
|
||||
let path = PathBuf::from("/test/path");
|
||||
let io_error = std::io::Error::new(std::io::ErrorKind::PermissionDenied, "permission denied");
|
||||
|
||||
// Error::new(e)
|
||||
// }
|
||||
let context_error = FileAccessDeniedWithContext {
|
||||
path: path.clone(),
|
||||
source: io_error,
|
||||
};
|
||||
|
||||
// pub fn is_all_not_found(errs: &[Option<Error>]) -> bool {
|
||||
// for err in errs.iter() {
|
||||
// if let Some(err) = err {
|
||||
// if let Some(err) = err.downcast_ref::<DiskError>() {
|
||||
// match err {
|
||||
// DiskError::FileNotFound | DiskError::VolumeNotFound | &DiskError::FileVersionNotFound => {
|
||||
// continue;
|
||||
// }
|
||||
// _ => return false,
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
let display_str = format!("{}", context_error);
|
||||
assert!(display_str.contains("/test/path"));
|
||||
assert!(display_str.contains("file access denied"));
|
||||
}
|
||||
|
||||
// !errs.is_empty()
|
||||
// }
|
||||
#[test]
|
||||
fn test_error_debug_format() {
|
||||
let error = DiskError::FileNotFound;
|
||||
let debug_str = format!("{:?}", error);
|
||||
assert_eq!(debug_str, "FileNotFound");
|
||||
|
||||
// pub fn is_all_volume_not_found(errs: &[Option<Error>]) -> bool {
|
||||
// DiskError::VolumeNotFound.count_errs(errs) == errs.len()
|
||||
// }
|
||||
let io_error = DiskError::other("test error");
|
||||
let debug_str = format!("{:?}", io_error);
|
||||
assert!(debug_str.contains("Io"));
|
||||
}
|
||||
|
||||
// pub fn is_all_buckets_not_found(errs: &[Option<Error>]) -> bool {
|
||||
// if errs.is_empty() {
|
||||
// return false;
|
||||
// }
|
||||
// let mut not_found_count = 0;
|
||||
// for err in errs.iter().flatten() {
|
||||
// match err.downcast_ref() {
|
||||
// Some(DiskError::VolumeNotFound) | Some(DiskError::DiskNotFound) => {
|
||||
// not_found_count += 1;
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
// }
|
||||
// errs.len() == not_found_count
|
||||
// }
|
||||
#[test]
|
||||
fn test_error_source() {
|
||||
use std::error::Error;
|
||||
|
||||
// pub fn is_err_os_not_exist(err: &Error) -> bool {
|
||||
// if let Some(os_err) = err.downcast_ref::<io::Error>() {
|
||||
// os_is_not_exist(os_err)
|
||||
// } else {
|
||||
// false
|
||||
// }
|
||||
// }
|
||||
let io_error = std::io::Error::new(std::io::ErrorKind::NotFound, "test");
|
||||
let disk_error = DiskError::Io(io_error);
|
||||
|
||||
// pub fn is_err_os_disk_full(err: &Error) -> bool {
|
||||
// if let Some(os_err) = err.downcast_ref::<io::Error>() {
|
||||
// is_sys_err_no_space(os_err)
|
||||
// } else if let Some(e) = err.downcast_ref::<DiskError>() {
|
||||
// e == &DiskError::DiskFull
|
||||
// } else {
|
||||
// false
|
||||
// }
|
||||
// }
|
||||
// DiskError should have a source
|
||||
if let DiskError::Io(ref inner) = disk_error {
|
||||
assert!(inner.source().is_none()); // std::io::Error typically doesn't have a source
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user