Implementation and Tests of map_files

- Changed the config.yaml to reflect testing needs
- Completed the function implementation
- Tests passing
pull/5/head
Ayrton Chilibeck 2024-01-14 16:46:12 -07:00
parent 775dfab349
commit 809e6837eb
Signed by: ayrton
GPG Key ID: BAE24A03DCBF160D
2 changed files with 114 additions and 40 deletions

View File

@ -1,6 +1,6 @@
input_path: "/path/to/dir"
output_path: "/path/to/out/dir"
in_stream_path: "/path/to/in/stream"
input_path: "/test/in"
output_path: "/test/out"
in_stream_path: "/test/instream"
tested_executables:
- name: "team1"

View File

@ -1,4 +1,4 @@
use std::{path::PathBuf, fs, collections::HashMap, borrow::BorrowMut};
use std::{path::{PathBuf, Path, Components, Component}, fs, collections::{HashMap, VecDeque}, borrow::BorrowMut};
use crate::util;
@ -8,8 +8,8 @@ pub fn validate(verbosity: u8, config: util::config::Config) {
let in_suffix = "in"; //TODO make this configurable?
let out_suffix = "out";
// get list of all file names in input/output
let in_files: Vec<PathBuf> = get_dir_files(config.input_path).expect("Failed to read the input directory contents");
let out_files: Vec<PathBuf> = get_dir_files(config.output_path).expect("Failed to read the output directory contents");
let in_files: Vec<PathBuf> = get_dir_files(&config.input_path).expect("Failed to read the input directory contents");
let out_files: Vec<PathBuf> = get_dir_files(&config.output_path).expect("Failed to read the output directory contents");
let mismatch: Vec<(PathBuf, PathBuf)>;
@ -27,7 +27,7 @@ pub fn validate(verbosity: u8, config: util::config::Config) {
}
// make sure each has a match
let mut in_to_out: (Vec<(PathBuf, PathBuf)>, Vec<PathBuf>) = map_files(in_files, out_files);
let in_to_out: (Vec<(PathBuf, PathBuf)>, Vec<PathBuf>) = map_files(in_files, out_files, &config);
let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(in_to_out.0, in_suffix, out_suffix);
print_unmached(in_to_out.1);
@ -45,8 +45,73 @@ pub fn validate(verbosity: u8, config: util::config::Config) {
* - A vector containing the file mappings from input to output (if found)
* - A vector containing paths for which a match was not found
*/
fn map_files(in_files: Vec<PathBuf>, out_files: Vec<PathBuf>) -> (Vec<(PathBuf, PathBuf)>, Vec<PathBuf>) {
fn map_files(in_files: Vec<PathBuf>, out_files: Vec<PathBuf>, config: &util::config::Config) -> (Vec<(PathBuf, PathBuf)>, Vec<PathBuf>) {
let mut res: (Vec<(PathBuf, PathBuf)>, Vec<PathBuf>) = (vec![], vec![]);
// get the prefixes
let mut in_prefix = vec![];
for pre in config.input_path.components() {
in_prefix.push(pre);
}
let mut out_prefix = vec![];
for pre in config.output_path.components() {
out_prefix.push(pre);
}
// check if the files have the same paths relative to in/out directory
for ifile in &in_files {
let mut found = false;
// get the components of the path
let mut in_comp: VecDeque<Component> = VecDeque::from(vec![]);
for tmp in ifile.components() {
in_comp.push_back(tmp);
}
in_comp.pop_back();
// check if the files share common ancestors except for the first path
for ofile in &out_files {
// get the components of the path
let mut out_comp: VecDeque<Component> = VecDeque::from(vec![]);
for tmp in ofile.components() {
out_comp.push_back(tmp);
}
out_comp.pop_back();
// println!("{:?}", ofile);
// println!("{:?}", out_comp);
// check if the file names are the same
if ofile.file_stem() == ifile.file_stem() {
// check that their paths are the same relative to the input/output directory
for comp in &in_prefix { if &comp == &in_comp.front().expect("Failed to extract") { in_comp.pop_front(); } }
for comp in &out_prefix { if &comp == &out_comp.front().expect("Failed to extract") { out_comp.pop_front(); } }
println!("{:?}\n{:?}\n{:?}", in_prefix, in_comp,out_comp);
// if the files match, then we add them to the mapping
if out_comp == in_comp {
println!("Added to map");
res.0.push((ifile.clone(), ofile.clone()));
found = true;
}
}
}
// if we fail to find a match, we add the file to the rest
if !found { res.1.push(ifile.clone()); }
}
let mut cl: Vec<PathBuf> = Vec::from(out_files.clone());
let mut r: Vec<PathBuf> = vec![];
for tup in &res.0 {
r.push(tup.1.clone());
}
cl.retain(|x| !r.contains(&x));
res.1.append(&mut cl);
println!("{:?}", res);
return res;
}
/**
@ -59,7 +124,7 @@ fn map_files(in_files: Vec<PathBuf>, out_files: Vec<PathBuf>) -> (Vec<(PathBuf,
* @return A vector of tuples with (input, output) PathBufs
*/
fn check_mappings(mappings: Vec<(PathBuf, PathBuf)>, in_suffix: &str, out_suffix: &str) -> Vec<(PathBuf, PathBuf)> {
return vec![(PathBuf::from("a"), PathBuf::from("b"))];
}
/**
@ -89,7 +154,7 @@ fn collect_invalid(files: &Vec<PathBuf>, suf: &str) -> Vec<PathBuf> {
*
* @returns Result with a Vector of PathBuf or error
*/
fn get_dir_files(path: PathBuf) -> Result<Vec<PathBuf>, &'static str> {
fn get_dir_files(path: &PathBuf) -> Result<Vec<PathBuf>, &'static str> {
let mut res: Vec<PathBuf> = vec![];
// get the readout of the path for error handling
@ -175,13 +240,13 @@ mod tests {
#[fixture]
fn in_files() -> Vec<PathBuf> {
let invalid_map11 = PathBuf::from("in/inv/path/file.in ");
let invalid_map12 = PathBuf::from("in/inv/path/file_stupid.in");
let invalid_map13 = PathBuf::from("in/inv/path/file/dead.inn");
let invalid_map11 = PathBuf::from("/test/in/inv/path/file.in ");
let invalid_map12 = PathBuf::from("/test/in/inv/path/file_stupid.in");
let invalid_map13 = PathBuf::from("/test/in/inv/path/dead.inn");
let valid_map11 = PathBuf::from("in/val/path/file.in");
let valid_map12 = PathBuf::from("in/val/path/file_stupid.in");
let valid_map13 = PathBuf::from("in/val/path/file/dead.in");
let valid_map11 = PathBuf::from("/test/in/val/path/file.in");
let valid_map12 = PathBuf::from("/test/in/val/path/file_stupid.in");
let valid_map13 = PathBuf::from("/test/in/val/path/file/dead.in");
let in_files = vec![invalid_map11, invalid_map12, invalid_map13,
valid_map11, valid_map12, valid_map13];
@ -191,13 +256,13 @@ mod tests {
#[fixture]
fn out_files() -> Vec<PathBuf> {
let invalid_map21 = PathBuf::from("out/inv/path/file.out");
let invalid_map22 = PathBuf::from("out/inv/path/file_stupid.out ");
let invalid_map23 = PathBuf::from("out/inv/path/file.outt");
let invalid_map21 = PathBuf::from("/test/out/inv/path/file.out");
let invalid_map22 = PathBuf::from("/test/out/inv/path/file_stupid.out ");
let invalid_map23 = PathBuf::from("/test/out/inv/path/file/dead.outt");
let valid_map21 = PathBuf::from("out/val/path/file.out");
let valid_map22 = PathBuf::from("out/val/path/file_stupid.out");
let valid_map23 = PathBuf::from("out/val/path/file.out");
let valid_map21 = PathBuf::from("/test/out/val/path/file.out");
let valid_map22 = PathBuf::from("/test/out/val/path/file_stupid.out");
let valid_map23 = PathBuf::from("/test/out/val/path/file/dead.out");
let out_files = vec![invalid_map21, invalid_map22, invalid_map23,
valid_map21, valid_map22, valid_map23];
@ -205,6 +270,11 @@ mod tests {
return out_files;
}
#[fixture]
fn config() -> util::config::Config {
return util::config::parse_config(PathBuf::from("src/util/test/parse_config/config.yaml"));
}
#[rstest]
fn test_collect_invalid(files: Vec<PathBuf>) {
let suffix = "suf";
@ -225,31 +295,35 @@ mod tests {
}
#[rstest]
fn test_map(in_files: Vec<PathBuf>, out_files: Vec<PathBuf>) {
let mappings: (Vec<(PathBuf, PathBuf)>, Vec<PathBuf>) = map_files(in_files, out_files);
fn test_map(in_files: Vec<PathBuf>, out_files: Vec<PathBuf>, config: util::config::Config) {
let mappings: (Vec<(PathBuf, PathBuf)>, Vec<PathBuf>) = map_files(in_files.clone(), out_files.clone(), &config);
print_unmached(mappings.1);
assert!(&mappings.0.contains(&(in_files[0], out_files[0])));
assert!(&mappings.0.contains(&(in_files[1], out_files[1])));
assert!(&mappings.0.contains(&(in_files[2], out_files[2])));
assert!(&mappings.0.contains(&(in_files[3], out_files[3])));
assert!(&mappings.0.contains(&(in_files[4], out_files[4])));
assert!(&mappings.0.contains(&(in_files[5], out_files[5])));
// print_unmached(mappings.1);
let test = (in_files[0].clone(), out_files[0].clone());
assert!(&mappings.0.contains(&test), "The mapping does not contain {:?}", test);
assert!(&mappings.0.contains(&(in_files[1].clone(), out_files[1].clone())));
assert!(!&mappings.0.contains(&(in_files[2].clone(), out_files[2].clone())));
assert!(&mappings.0.contains(&(in_files[3].clone(), out_files[3].clone())));
assert!(&mappings.0.contains(&(in_files[4].clone(), out_files[4].clone())));
assert!(&mappings.0.contains(&(in_files[5].clone(), out_files[5].clone())));
assert!(&mappings.1.contains(&in_files[2]));
assert!(&mappings.1.contains(&out_files[2]));
}
#[rstest]
fn test_check_valid_mappings(in_files: Vec<PathBuf>, out_files: Vec<PathBuf>) {
fn test_check_valid_mappings(in_files: Vec<PathBuf>, out_files: Vec<PathBuf>, config: util::config::Config) {
let in_suffix = "in";
let out_suffix = "out";
let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(map_files(in_files, out_files).0, in_suffix, out_suffix);
let invalid: Vec<(PathBuf, PathBuf)> = check_mappings(map_files(in_files.clone(), out_files.clone(), &config).0, in_suffix, out_suffix);
print_invalid_pairs(invalid, in_suffix, out_suffix);
assert!(&invalid.contains(&(in_files[0], out_files[0])));
assert!(&invalid.contains(&(in_files[1], out_files[1])));
assert!(&invalid.contains(&(in_files[2], out_files[2])));
print_invalid_pairs(invalid.clone(), in_suffix, out_suffix);
assert!(&invalid.contains(&(in_files[0].clone(), out_files[0].clone())));
assert!(&invalid.contains(&(in_files[1].clone(), out_files[1].clone())));
assert!(&invalid.contains(&(in_files[2].clone(), out_files[2].clone())));
assert!(!&invalid.contains(&(in_files[3], out_files[3])));
assert!(!&invalid.contains(&(in_files[4], out_files[4])));
assert!(!&invalid.contains(&(in_files[5], out_files[5])));
assert!(!&invalid.contains(&(in_files[3].clone(), out_files[3].clone())));
assert!(!&invalid.contains(&(in_files[4].clone(), out_files[4].clone())));
assert!(!&invalid.contains(&(in_files[5].clone(), out_files[5].clone())));
}
}