Compare commits
No commits in common. "8d4b5b3f1ce4076283e237130807985424a8ccf9" and "47d7d81f60b107e7b7e2a60c3fab4a90cf702c6b" have entirely different histories.
8d4b5b3f1c
...
47d7d81f60
|
@ -3,7 +3,7 @@
|
||||||
This is a (mostly) drop-in replacement for the previous tester written for CMPUT 415.
|
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:
|
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>
|
Usage: tester [OPTIONS] --config-file <CONFIG> <COMMAND>
|
||||||
|
|
||||||
Commands:
|
Commands:
|
||||||
|
@ -14,11 +14,11 @@ Commands:
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-v, --verbosity... Sets the verbosity of the tester
|
-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
|
-c, --config-file <CONFIG> Set the config file
|
||||||
-g, --grading-conf <GRADING_CONFIG> Set the grading config file
|
-g, --grading-conf <GRADING_CONFIG> Set the grading config file
|
||||||
-h, --help Print help
|
-h, --help Print help
|
||||||
-V, --version Print version
|
-V, --version Print version
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
the verbosity defines the level of logging, you can play around with it (specify `-v[v]+` for more verbose logging).
|
the verbosity defines the level of logging, you can play around with it (specify `-v[v]+` for more verbose logging).
|
||||||
|
|
|
@ -16,7 +16,8 @@ fn main() {
|
||||||
let threads = get_threads(cli.threads);
|
let threads = get_threads(cli.threads);
|
||||||
let config = util::config::parse_config(cli.config_file);
|
let config = util::config::parse_config(cli.config_file);
|
||||||
|
|
||||||
assert!(threads > 0);
|
//parse the config file
|
||||||
|
// let config = parse_config(cli.config_file);
|
||||||
|
|
||||||
match &cli.command {
|
match &cli.command {
|
||||||
Command::Validate => validate::validate(verbosity, config),
|
Command::Validate => validate::validate(verbosity, config),
|
||||||
|
|
|
@ -5,39 +5,39 @@ use serde_yaml::{self};
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub tested_executables: Vec<Team>,
|
tested_executables: Vec<Team>,
|
||||||
|
|
||||||
pub input_path: PathBuf,
|
input_path: PathBuf,
|
||||||
pub output_path: PathBuf,
|
output_path: PathBuf,
|
||||||
pub in_stream_path: PathBuf,
|
in_stream_path: PathBuf,
|
||||||
|
|
||||||
pub runtimes: Option<Vec<Team>>,
|
runtimes: Option<Vec<Team>>,
|
||||||
|
|
||||||
pub toolchains: Vec<Toolchain>,
|
toolchains: Vec<Toolchain>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Team {
|
pub struct Team {
|
||||||
pub name: String,
|
name: String,
|
||||||
pub executable: PathBuf,
|
executable: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Toolchain {
|
pub struct Toolchain {
|
||||||
pub name: String,
|
name: String,
|
||||||
pub steps: Vec<Step>,}
|
steps: Vec<Step>,}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
pub struct Step {
|
pub struct Step {
|
||||||
pub name: String,
|
name: String,
|
||||||
|
|
||||||
pub executable_path: Option<PathBuf>, // if None then we use the current executable path
|
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
|
arguments: Vec<String>, // special string $INPUT corresponds to previous step output
|
||||||
pub output: String, // the output file name
|
output: String, // the output file name
|
||||||
|
|
||||||
pub uses_runtime: Option<bool>,
|
uses_runtime: Option<bool>,
|
||||||
pub uses_in_stream: Option<bool>,
|
uses_in_stream: Option<bool>,
|
||||||
pub allow_error: Option<bool>
|
allow_error: Option<bool>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_config(path: PathBuf) -> Config {
|
pub fn parse_config(path: PathBuf) -> Config {
|
||||||
|
|
|
@ -1,104 +1,9 @@
|
||||||
use std::{path::PathBuf, fs};
|
|
||||||
|
|
||||||
use crate::util;
|
use crate::util;
|
||||||
|
|
||||||
pub fn validate(verbosity: u8, config: util::config::Config) {
|
pub fn validate(verbosity: u8, config: util::config::Config) {
|
||||||
println!("Validating");
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
Loading…
Reference in New Issue