From dc03108b6dd0b683be90d5eda1650d2f0917f643 Mon Sep 17 00:00:00 2001 From: s1rius Date: Sun, 13 Aug 2023 15:51:04 +0800 Subject: [PATCH] add cli test --- examples/hello_world.rs | 4 +- ezlog-cli/Cargo.toml | 13 +++- ezlog-cli/resources/test/test.mmap | Bin 0 -> 150000 bytes ezlog-cli/src/main.rs | 121 +++++++++++++++++------------ ezlog-core/src/lib.rs | 2 + ezlog-core/src/logger.rs | 90 ++++++++++----------- 6 files changed, 130 insertions(+), 100 deletions(-) create mode 100644 ezlog-cli/resources/test/test.mmap diff --git a/examples/hello_world.rs b/examples/hello_world.rs index 6bbed00..db63489 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -103,8 +103,8 @@ fn read_log_file_rewrite() { let mut writer = BufWriter::new(plaintext_log); - let mut compression = EZLogger::create_compress(&log_config); - let mut cryptor = EZLogger::create_cryptor(&log_config).unwrap(); + let mut compression = ezlog::create_compress(&log_config); + let mut cryptor = ezlog::create_cryptor(&log_config).unwrap(); let header = Header::decode(&mut cursor).unwrap(); ezlog::decode::decode_body_and_write( &mut cursor, diff --git a/ezlog-cli/Cargo.toml b/ezlog-cli/Cargo.toml index 88e4191..00690f3 100644 --- a/ezlog-cli/Cargo.toml +++ b/ezlog-cli/Cargo.toml @@ -1,15 +1,22 @@ [package] name = "ezlog-cli" -version = "0.2.0-beta.2" +version = "0.2.0-beta.4" edition = "2021" description = "EZLog command line tool" homepage = "https://github.com/s1rius/ezlog" repository = "https://github.com/s1rius/ezlog" license = "MIT OR Apache-2.0" keywords = ["ezlog", "cli"] +exclude = ["/resources"] [dependencies] ezlog = { version = "0.2.0-beta.2", path = "../ezlog-core", features = ["decode"] } -clap = { version = "4.0.8", features = ["derive"] } +clap = { version = "4.3.21", features = ["derive"] } serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0" \ No newline at end of file +serde_json = "1.0" +anyhow = "1.0.72" +assert_cmd = "2.0.12" +escargot = "0.5.8" + +[dev-dependencies] +dirs = "5.0" \ No newline at end of file diff --git a/ezlog-cli/resources/test/test.mmap b/ezlog-cli/resources/test/test.mmap new file mode 100644 index 0000000000000000000000000000000000000000..8023a5c38081bd801ac9ef380257cbc7fc7d03b0 GIT binary patch literal 150000 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 zc6u_V%v9S~1R1{^r!!tZQrFeuL$8ulL@lZ+$NEN#0uKm)00@8p2!H?xfB*=900@8p z2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?x zfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=9 z00@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p z2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?x zfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=9 z00@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p z2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?x zfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=9 z00@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p z2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?x zfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=9 z00@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p2!H?xfB*=900@8p Q2!H?xfB*=9!2c!iKR^b!o&W#< literal 0 HcmV?d00001 diff --git a/ezlog-cli/src/main.rs b/ezlog-cli/src/main.rs index da372ba..d004a55 100644 --- a/ezlog-cli/src/main.rs +++ b/ezlog-cli/src/main.rs @@ -4,35 +4,11 @@ use std::{ path::PathBuf, }; +use anyhow::Context; use clap::Parser; pub use ezlog::*; use serde::{Deserialize, Serialize}; -macro_rules! unwrap_or_return { - ( $e:expr, $e1:expr ) => { - match $e { - Ok(x) => x, - Err(e) => { - $e1; - println!("{}", e); - return; - } - } - }; -} - -macro_rules! some_or_return { - ( $e:expr, $e1:expr ) => { - match $e { - Some(x) => x, - None => { - $e1; - return; - } - } - }; -} - #[derive(Parser, Debug)] #[clap(author, version, about, long_about = None)] struct Cli { @@ -72,7 +48,7 @@ struct Config { nonce: String, } -pub fn main() { +pub fn main() -> anyhow::Result<()> { let cli = Cli::parse(); if cli.debug { @@ -81,28 +57,34 @@ pub fn main() { println!("{:?}", cli); } - let input = some_or_return!(cli.input.as_deref(), println!("-i input file must set")); + let input = cli + .input + .as_deref() + .with_context(|| "-i input file must be set".to_string())?; - let input_file = unwrap_or_return!( - OpenOptions::new().read(true).open(input), - println!("-i input file open error") - ); + let input_file = OpenOptions::new() + .read(true) + .write(true) + .open(input) + .with_context(|| "input file must valid".to_string())?; - let output = some_or_return!(cli.output.as_deref(), println!("-o output file must set")); + let output = cli + .output + .as_deref() + .with_context(|| "-o output file must be set".to_string())?; - let output_file = unwrap_or_return!( - OpenOptions::new().write(true).create(true).open(output), - println!("-o output file create error") - ); + let output_file = OpenOptions::new() + .write(true) + .create(true) + .open(output) + .with_context(|| "output file create error".to_string())?; let mut buf = Vec::::new(); let mut reader = BufReader::new(input_file); reader.read_to_end(&mut buf).unwrap(); let mut cursor = Cursor::new(buf); - let header = unwrap_or_return!( - ezlog::Header::decode(&mut cursor), - println!("log file can not be recognized") - ); + let header = + ezlog::Header::decode(&mut cursor).with_context(|| "header decode error".to_string())?; if cli.debug { println!(); @@ -119,10 +101,8 @@ pub fn main() { .read_to_string(&mut json) .is_ok() { - let config: Config = unwrap_or_return!( - serde_json::from_str(&json), - println!("parse config json error") - ); + let config: Config = serde_json::from_str(&json) + .with_context(|| "config file is not valid".to_string())?; key = config.key.as_bytes().to_vec(); nonce = config.nonce.as_bytes().to_vec(); @@ -152,11 +132,9 @@ pub fn main() { .cipher_nonce(nonce) .build(); - let compression = EZLogger::create_compress(&config); - let decryptor = unwrap_or_return!( - EZLogger::create_cryptor(&config), - println!("create cryptor error") - ); + let compression = ezlog::create_compress(&config); + let decryptor = + ezlog::create_cryptor(&config).with_context(|| "create cryptor error".to_string())?; let mut plain_text_write = BufWriter::new(output_file); @@ -169,11 +147,54 @@ pub fn main() { &header, ) .unwrap(); + Ok(()) } #[cfg(test)] mod tests { + use std::path::PathBuf; + + use assert_cmd::prelude::{OutputAssertExt, OutputOkExt}; + + #[test] + fn test_help() { + escargot::CargoBuild::new() + .bin("ezlog-cli") + .current_release() + .current_target() + .run() + .unwrap() + .command() + .arg("--help") + .unwrap().assert().success(); + } #[test] - fn test_decode() {} + fn test_decode() { + let bin_under_test = escargot::CargoBuild::new() + .bin("ezlog-cli") + .current_release() + .current_target() + .run() + .unwrap(); + + let mut input_file = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + input_file.push("resources/test/test.mmap"); + + let mut output_file = dirs::cache_dir().unwrap(); + output_file.push("1.log"); + + let cmd = bin_under_test + .command() + .arg("-i") + .arg(input_file.into_os_string()) + .arg("-o") + .arg(output_file.into_os_string()) + .arg("-k") + .arg("an example very very secret key.") + .arg("-n") + .arg("unique nonce") + .unwrap(); + cmd.assert().success(); + } } diff --git a/ezlog-core/src/lib.rs b/ezlog-core/src/lib.rs index 4798aab..96cd39d 100644 --- a/ezlog-core/src/lib.rs +++ b/ezlog-core/src/lib.rs @@ -74,6 +74,8 @@ pub use self::init::InitBuilder; pub use self::init::MsgHandler; pub use self::logger::EZLogger; pub use self::logger::Header; +pub use self::logger::create_cryptor; +pub use self::logger::create_compress; pub use self::recorder::EZRecord; pub use self::recorder::EZRecordBuilder; diff --git a/ezlog-core/src/logger.rs b/ezlog-core/src/logger.rs index 013b023..238729a 100644 --- a/ezlog-core/src/logger.rs +++ b/ezlog-core/src/logger.rs @@ -41,6 +41,49 @@ pub(crate) fn encode_content(mut buf: Vec) -> Result> { Ok(chunk) } +#[allow(deprecated)] +pub fn create_cryptor(config: &EZLogConfig) -> Result>> { + if let Some(key) = &config.cipher_key { + if let Some(nonce) = &config.cipher_nonce { + #[warn(unreachable_patterns)] + match config.cipher { + #[cfg(feature = "decode")] + CipherKind::AES128GCM => { + let encryptor = Aes128Gcm::new(key, nonce)?; + Ok(Some(Box::new(encryptor))) + } + #[cfg(feature = "decode")] + CipherKind::AES256GCM => { + let encryptor = Aes256Gcm::new(key, nonce)?; + Ok(Some(Box::new(encryptor))) + } + CipherKind::AES128GCMSIV => { + let encryptor = Aes128GcmSiv::new(key, nonce)?; + Ok(Some(Box::new(encryptor))) + } + CipherKind::AES256GCMSIV => { + let encryptor = Aes256GcmSiv::new(key, nonce)?; + Ok(Some(Box::new(encryptor))) + } + CipherKind::NONE => Ok(None), + unknown => Err(LogError::Crypto(format!("unknown cryption {}", unknown))), + } + } else { + Ok(None) + } + } else { + Ok(None) + } +} + +pub fn create_compress(config: &EZLogConfig) -> Option> { + match config.compress { + CompressKind::ZLIB => Some(Box::new(ZlibCodec::new(&config.compress_level))), + CompressKind::NONE => None, + CompressKind::UNKNOWN => None, + } +} + pub struct EZLogger { pub(crate) config: Rc, pub(crate) appender: EZAppender, @@ -53,8 +96,8 @@ impl EZLogger { let rc_conf = Rc::new(config); let mut appender = EZAppender::new(Rc::clone(&rc_conf))?; appender.check_config_rolling(&rc_conf)?; - let compression = EZLogger::create_compress(&rc_conf); - let cryptor = EZLogger::create_cryptor(&rc_conf)?; + let compression = create_compress(&rc_conf); + let cryptor = create_cryptor(&rc_conf)?; Ok(Self { config: Rc::clone(&rc_conf), @@ -64,49 +107,6 @@ impl EZLogger { }) } - #[allow(deprecated)] - pub fn create_cryptor(config: &EZLogConfig) -> Result>> { - if let Some(key) = &config.cipher_key { - if let Some(nonce) = &config.cipher_nonce { - #[warn(unreachable_patterns)] - match config.cipher { - #[cfg(feature = "decode")] - CipherKind::AES128GCM => { - let encryptor = Aes128Gcm::new(key, nonce)?; - Ok(Some(Box::new(encryptor))) - } - #[cfg(feature = "decode")] - CipherKind::AES256GCM => { - let encryptor = Aes256Gcm::new(key, nonce)?; - Ok(Some(Box::new(encryptor))) - } - CipherKind::AES128GCMSIV => { - let encryptor = Aes128GcmSiv::new(key, nonce)?; - Ok(Some(Box::new(encryptor))) - } - CipherKind::AES256GCMSIV => { - let encryptor = Aes256GcmSiv::new(key, nonce)?; - Ok(Some(Box::new(encryptor))) - } - CipherKind::NONE => Ok(None), - unknown => Err(LogError::Crypto(format!("unknown cryption {}", unknown))), - } - } else { - Ok(None) - } - } else { - Ok(None) - } - } - - pub fn create_compress(config: &EZLogConfig) -> Option> { - match config.compress { - CompressKind::ZLIB => Some(Box::new(ZlibCodec::new(&config.compress_level))), - CompressKind::NONE => None, - CompressKind::UNKNOWN => None, - } - } - pub(crate) fn append(&mut self, record: &EZRecord) -> Result<()> { if record.content().len() > self.config.max_size as usize / 2 { let mut e: Option = None;