// Copyright 2019 metadata-backup Authors (see AUTHORS.md) // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. extern crate csv; extern crate proptest; use metadata_backup::metadata::Metadata; use std::path::PathBuf; fn get_base_path() -> PathBuf { let mut out = PathBuf::from(env!["CARGO_MANIFEST_DIR"]); out.push("tests"); out.push("tree"); out } fn get_resource(path_components: &Vec<&str>) -> PathBuf { let mut out = get_base_path(); for component in path_components.iter() { out.push(component); } out } fn get_metadata(path_components: &Vec<&str>) -> Result { let pathbuf = get_resource(path_components); let path = pathbuf.as_path(); Metadata::new(&path) } #[test] fn test_size() { let test_cases = [ (vec!["f1.txt"], 0), (vec!["f2.txt"], 256), (vec!["a", "a1.txt"], 117), ]; for (path_components, expected_size) in test_cases.iter() { let meta = get_metadata(path_components).unwrap(); assert_eq!(meta.size, *expected_size); } } #[test] fn test_name() { let test_cases = [ (vec!["f1.txt"], "f1.txt"), (vec!["f2.txt"], "f2.txt"), (vec!["a1.txt"], "a1.txt"), (vec!["a", "a1.txt"], "a1.txt"), (vec!["b", "b1.txt"], "b1.txt"), ]; for (path_components, expected_name) in test_cases.iter() { let meta = get_metadata(path_components).unwrap(); assert_eq!(meta.name, expected_name.to_string()); } } #[test] fn test_is_dir() { let test_cases = [ (vec!["a"], true), (vec!["b"], true), (vec!["f1.txt"], false), (vec!["f2.txt"], false), (vec!["a1.txt"], false), (vec!["a", "a1.txt"], false), (vec!["b", "b1.txt"], false), ]; for (path_components, expected) in test_cases.iter() { let meta = get_metadata(path_components).unwrap(); assert_eq!(meta.is_dir, *expected); } } mod prop_tests { extern crate strmode; use metadata_backup::metadata::Metadata; use proptest::prelude::*; use std::time::{Duration, SystemTime, UNIX_EPOCH}; prop_compose! { fn system_time_truncated() (seconds in 0..(2u64^64 - 1)) -> SystemTime { UNIX_EPOCH + Duration::from_secs(seconds) } } prop_compose! { fn arb_metadata() (name in ".*", size in any::(), is_dir in any::(), atime in prop::option::of(system_time_truncated()), mtime in prop::option::of(system_time_truncated()), ctime in prop::option::of(system_time_truncated()), st_mode in prop::option::of(any::()), uid in prop::option::of(any::()), gid in prop::option::of(any::()), link in prop::option::of("[^\0]+"), ) -> Metadata { Metadata { name: name, size: size, is_dir: is_dir, atime: atime, mtime: mtime, ctime: ctime, st_mode: st_mode, st_mode_string: st_mode.map(strmode::strmode), uid: uid, gid: gid, link: link, } } } proptest! { #[test] fn serialize_deserialize_records(metadata_records in prop::collection::vec(arb_metadata(), 1..100)) { let mut wtr = csv::Writer::from_writer(vec![]); for record in &metadata_records { wtr.serialize(record).unwrap(); }; let data = String::from_utf8(wtr.into_inner().unwrap()).unwrap(); let mut reader = csv::Reader::from_reader(data.as_bytes()); let mut deserialized_vec : Vec = Vec::with_capacity(metadata_records.len()); for result in reader.deserialize::() { let record = result.unwrap(); deserialized_vec.push(record); } let deserialized_vec = deserialized_vec; assert_eq!(metadata_records.len(), deserialized_vec.len()); for (record_in, record_out) in metadata_records.iter().zip(deserialized_vec) { assert_eq!(*record_in, record_out); } } } }