Compare commits
5 Commits
47d7d81f60
...
8d4b5b3f1c
Author | SHA1 | Date |
---|---|---|
Ayrton Chilibeck | 8d4b5b3f1c | |
Ayrton Chilibeck | eaca213f26 | |
Ayrton Chilibeck | 3693ff1668 | |
Ayrton Chilibeck | 4561caa6cf | |
Ayrton Chilibeck | d4a6c1132d |
|
@ -3,7 +3,7 @@
|
|||
This is a (mostly) drop-in replacement for the previous tester written for CMPUT 415.
|
||||
|
||||
Most of the options are specified in the [config file](#configuration-file), so the cli is minimal. We do specify some options:
|
||||
``` rust
|
||||
```
|
||||
Usage: tester [OPTIONS] --config-file <CONFIG> <COMMAND>
|
||||
|
||||
Commands:
|
||||
|
@ -14,11 +14,11 @@ Commands:
|
|||
|
||||
Options:
|
||||
-v, --verbosity... Sets the verbosity of the tester
|
||||
-t, --threads <THREADS> Set the number of threads (only valid in run and grade mode)
|
||||
-c, --config-file <CONFIG> Set the config file
|
||||
-g, --grading-conf <GRADING_CONFIG> Set the grading config file
|
||||
-h, --help Print help
|
||||
-V, --version Print version
|
||||
|
||||
```
|
||||
|
||||
the verbosity defines the level of logging, you can play around with it (specify `-v[v]+` for more verbose logging).
|
||||
|
|
|
@ -16,8 +16,7 @@ fn main() {
|
|||
let threads = get_threads(cli.threads);
|
||||
let config = util::config::parse_config(cli.config_file);
|
||||
|
||||
//parse the config file
|
||||
// let config = parse_config(cli.config_file);
|
||||
assert!(threads > 0);
|
||||
|
||||
match &cli.command {
|
||||
Command::Validate => validate::validate(verbosity, config),
|
||||
|
|
|
@ -5,39 +5,39 @@ use serde_yaml::{self};
|
|||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Config {
|
||||
tested_executables: Vec<Team>,
|
||||
pub tested_executables: Vec<Team>,
|
||||
|
||||
input_path: PathBuf,
|
||||
output_path: PathBuf,
|
||||
in_stream_path: PathBuf,
|
||||
pub input_path: PathBuf,
|
||||
pub output_path: PathBuf,
|
||||
pub in_stream_path: PathBuf,
|
||||
|
||||
runtimes: Option<Vec<Team>>,
|
||||
pub runtimes: Option<Vec<Team>>,
|
||||
|
||||
toolchains: Vec<Toolchain>,
|
||||
pub toolchains: Vec<Toolchain>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Team {
|
||||
name: String,
|
||||
executable: PathBuf,
|
||||
pub name: String,
|
||||
pub executable: PathBuf,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Toolchain {
|
||||
name: String,
|
||||
steps: Vec<Step>,}
|
||||
pub name: String,
|
||||
pub steps: Vec<Step>,}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Step {
|
||||
name: String,
|
||||
pub name: String,
|
||||
|
||||
executable_path: Option<PathBuf>, // if None then we use the current executable path
|
||||
arguments: Vec<String>, // special string $INPUT corresponds to previous step output
|
||||
output: String, // the output file name
|
||||
pub executable_path: Option<PathBuf>, // if None then we use the current executable path
|
||||
pub arguments: Vec<String>, // special string $INPUT corresponds to previous step output
|
||||
pub output: String, // the output file name
|
||||
|
||||
uses_runtime: Option<bool>,
|
||||
uses_in_stream: Option<bool>,
|
||||
allow_error: Option<bool>
|
||||
pub uses_runtime: Option<bool>,
|
||||
pub uses_in_stream: Option<bool>,
|
||||
pub allow_error: Option<bool>
|
||||
}
|
||||
|
||||
pub fn parse_config(path: PathBuf) -> Config {
|
||||
|
|
|
@ -1,9 +1,104 @@
|
|||
use std::{path::PathBuf, fs};
|
||||
|
||||
use crate::util;
|
||||
|
||||
pub fn validate(verbosity: u8, config: util::config::Config) {
|
||||
println!("Validating");
|
||||
|
||||
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 mismatch: Vec<(PathBuf, PathBuf)>;
|
||||
let mut invalid_suffix_in: Vec<PathBuf> = vec![];
|
||||
let mut invalid_suffix_out: Vec<PathBuf> = vec![];
|
||||
|
||||
// check if they end in .in or .out respectively
|
||||
for file in in_files {
|
||||
if !file.ends_with(in_suffix) {
|
||||
invalid_suffix_in.push(file);
|
||||
}
|
||||
}
|
||||
|
||||
for file in out_files {
|
||||
if !file.ends_with(out_suffix) {
|
||||
invalid_suffix_out.push(file);
|
||||
}
|
||||
}
|
||||
|
||||
// print the delinquints
|
||||
if invalid_suffix_in.len() > 0 {
|
||||
print_invalid_suffixes(invalid_suffix_in, String::from(in_suffix));
|
||||
}
|
||||
|
||||
if invalid_suffix_out.len() > 0 {
|
||||
print_invalid_suffixes(invalid_suffix_out, String::from(out_suffix));
|
||||
}
|
||||
|
||||
// make sure each has a match
|
||||
}
|
||||
|
||||
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
|
||||
let entries = match fs::read_dir(path) {
|
||||
Ok(x) => x,
|
||||
Err(..) => return Err("Failed to read from the given directory"),
|
||||
};
|
||||
|
||||
for entry in entries {
|
||||
let p = entry.expect("Bad element: validate::get_dir_files(..)");
|
||||
if p.path().is_dir() {
|
||||
();
|
||||
} else {
|
||||
res.push(p.path());
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(res);
|
||||
}
|
||||
|
||||
fn compare_files(in_files: Vec<PathBuf>, out_files: Vec<PathBuf>) -> Vec<PathBuf> {
|
||||
let mut res: Vec<PathBuf> = vec![];
|
||||
|
||||
res.append(&mut compare_list(in_files, out_files));
|
||||
res.append(&mut compare_list(out_files, in_files));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
fn compare_list(from: Vec<PathBuf>, against: Vec<PathBuf>) -> Vec<PathBuf> {
|
||||
let res: Vec<PathBuf> = vec![];
|
||||
|
||||
// Compare each input file to each output file
|
||||
for file in from {
|
||||
let beg = file.file_stem().unwrap(); // ignore suffix
|
||||
for out in against {
|
||||
if beg == out.file_stem().unwrap() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
res.push(file); // if the file does not have a counterpart, then push to the lost files
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
fn print_invalid_suffixes(files: Vec<PathBuf>, exp: String) {
|
||||
println!("Invalid suffixes detected 😱:" );
|
||||
println!("Current => Suggested");
|
||||
for mut file in files {
|
||||
let initial = match file.to_str() {
|
||||
Some(x) => x,
|
||||
_ => panic!("Failed to load the file"),
|
||||
};
|
||||
|
||||
println!("{} => {}", initial, file.set_extension(exp).to_string());
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
|
Loading…
Reference in New Issue