diff options
author | Justus Winter <justus@sequoia-pgp.org> | 2019-04-04 18:06:55 +0200 |
---|---|---|
committer | Justus Winter <justus@sequoia-pgp.org> | 2019-04-04 18:06:55 +0200 |
commit | 2254016c0306c30e8c7d362a949fe9ba7fc9b836 (patch) | |
tree | 1e87ff0251f6b8bedcb4fa6f8b4f4aac46a9abfc /openpgp/tests | |
parent | 7ade4f780f8a0d39a53f6432d4f7718fb626791d (diff) |
openpgp: Add a new test.
- For every file in openpgp/tests/data, parse it, and roundtrip each
packet.
- Fixes 243.
Diffstat (limited to 'openpgp/tests')
-rw-r--r-- | openpgp/tests/for-each-artifact.rs | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/openpgp/tests/for-each-artifact.rs b/openpgp/tests/for-each-artifact.rs new file mode 100644 index 00000000..ec84d821 --- /dev/null +++ b/openpgp/tests/for-each-artifact.rs @@ -0,0 +1,97 @@ +use std::env; +use std::fs; +use std::io; +use std::path::{Path, PathBuf}; + +extern crate sequoia_openpgp as openpgp; +use openpgp::parse::*; +use openpgp::serialize::Serialize; + +mod for_each_artifact { + use super::*; + + #[test] + fn packet_roundtrip() { + for_all_files(&test_data_dir(), |src| { + for_all_packets(src, |p| { + let mut v = Vec::new(); + p.serialize(&mut v)?; + let q = openpgp::Packet::from_bytes(&v)?; + assert_eq!(p, &q); + Ok(()) + }) + }).unwrap(); + } +} + +/// Computes the path to the test directory. +fn test_data_dir() -> PathBuf { + let manifest_dir = PathBuf::from( + env::var_os("CARGO_MANIFEST_DIR") + .as_ref() + .expect("CARGO_MANIFEST_DIR not set")); + + manifest_dir.join("tests").join("data") +} + +/// Maps the given function `fun` over all Rust files in `src`. +fn for_all_files<F>(src: &Path, mut fun: F) -> openpgp::Result<()> + where F: FnMut(&Path) -> openpgp::Result<()> +{ + let mut dirs = vec![src.to_path_buf()]; + + while let Some(dir) = dirs.pop() { + for entry in fs::read_dir(dir).unwrap() { + let entry = entry?; + let path = entry.path(); + if path.is_file() { + fun(&path)?; + } + if path.is_dir() { + dirs.push(path.clone()); + } + } + } + Ok(()) +} + +/// Maps the given function `fun` over all packets in `src`. +fn for_all_packets<F>(src: &Path, mut fun: F) -> openpgp::Result<()> + where F: FnMut(&openpgp::Packet) -> openpgp::Result<()> +{ + let ppb = PacketParserBuilder::from_file(src)?.buffer_unread_content(); + let mut ppr = if let Ok(ppr) = ppb.finalize() { + ppr + } else { + // Ignore junk. + return Ok(()); + }; + + while let PacketParserResult::Some(pp) = ppr { + match pp.recurse() { + Ok((packet, ppr_)) => { + ppr = ppr_; + + if let openpgp::Packet::Unknown(_) = packet { + continue; // Ignore packets that we cannot parse. + } + + match fun(&packet) { + Ok(_) => (), + Err(e) => { + eprintln!("Failed on packet {:?}:\n", packet); + let mut sink = io::stderr(); + let mut w = openpgp::armor::Writer::new( + &mut sink, + openpgp::armor::Kind::File, + &[])?; + packet.serialize(&mut w)?; + return Err(e); + }, + } + }, + Err(_) => break, + } + } + Ok(()) +} |