From 76b9f72d415668b98ac541aa19bdfd9412cbedb3 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Fri, 12 Jan 2024 13:07:39 -0700 Subject: [PATCH 1/6] Added stubs --- Cargo.lock | 74 ++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/util.rs | 1 + src/util/config.rs | 1 + 4 files changed, 77 insertions(+) create mode 100644 src/util.rs create mode 100644 src/util/config.rs diff --git a/Cargo.lock b/Cargo.lock index d3a1b8c..5303825 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,12 +96,40 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + [[package]] name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + [[package]] name = "proc-macro2" version = "1.0.76" @@ -120,6 +148,45 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "serde" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_yaml" +version = "0.9.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1bf28c79a99f70ee1f1d83d10c875d2e70618417fda01ad1785e027579d9d38" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + [[package]] name = "strsim" version = "0.10.0" @@ -142,6 +209,7 @@ name = "tester" version = "0.1.0" dependencies = [ "clap", + "serde_yaml", ] [[package]] @@ -150,6 +218,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unsafe-libyaml" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b" + [[package]] name = "utf8parse" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index 2a8cbec..88a5171 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,3 +7,4 @@ edition = "2021" [dependencies] clap = { version = "4.4.16", features = ["derive"] } +serde_yaml = "0.9.30" diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..1bf79df --- /dev/null +++ b/src/util.rs @@ -0,0 +1 @@ +mod config; diff --git a/src/util/config.rs b/src/util/config.rs new file mode 100644 index 0000000..dd12d12 --- /dev/null +++ b/src/util/config.rs @@ -0,0 +1 @@ +use serde_yaml; From 9f509a929f0c76d20030cd0eeca43181ff9842e6 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Fri, 12 Jan 2024 13:21:04 -0700 Subject: [PATCH 2/6] Added structs for config data --- src/util/config.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/util/config.rs b/src/util/config.rs index dd12d12..97dd99c 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -1 +1,32 @@ +use std::{path::PathBuf, collections::HashMap}; + use serde_yaml; + +#[derive(Default)] +struct Config { + executable_paths: HashMap, + + input_path: PathBuf, + output_path: PathBuf, + + toolchains: Vec, +} + +#[derive(Default)] +struct Toolchain { + name: String, + steps: Vec, +} + +#[derive(Default)] +struct Step { + name: String, + + executable_path: Option, // if None then we use the current executable path + arguments: Vec, // special string $INPUT corresponds to previous step output + output: String, // the output file name +} + +pub fn parse_config(path: PathBuf) { + +} From bb968d770ef9a31c44cbc6c171913b8c72e2a70f Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Fri, 12 Jan 2024 21:34:45 -0700 Subject: [PATCH 3/6] Added Configuration parsing module --- Cargo.lock | 1 + Cargo.toml | 1 + src/util.rs | 2 +- src/util/config.rs | 74 +++++++++++++++++++++++++++++++++++++++------- 4 files changed, 66 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5303825..a646b96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -209,6 +209,7 @@ name = "tester" version = "0.1.0" dependencies = [ "clap", + "serde", "serde_yaml", ] diff --git a/Cargo.toml b/Cargo.toml index 88a5171..b78d78d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] clap = { version = "4.4.16", features = ["derive"] } +serde = { version = "1.0.195", features = ["derive"] } serde_yaml = "0.9.30" diff --git a/src/util.rs b/src/util.rs index 1bf79df..ef68c36 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1 +1 @@ -mod config; +pub mod config; diff --git a/src/util/config.rs b/src/util/config.rs index 97dd99c..1aa5457 100644 --- a/src/util/config.rs +++ b/src/util/config.rs @@ -1,32 +1,84 @@ -use std::{path::PathBuf, collections::HashMap}; +use std::path::PathBuf; -use serde_yaml; +use serde::Deserialize; +use serde_yaml::{self}; -#[derive(Default)] -struct Config { - executable_paths: HashMap, +#[derive(Debug, Deserialize)] +pub struct Config { + tested_executables: Vec, input_path: PathBuf, output_path: PathBuf, + in_stream_path: PathBuf, + + runtimes: Option>, toolchains: Vec, } -#[derive(Default)] -struct Toolchain { +#[derive(Debug, Deserialize)] +pub struct Team { name: String, - steps: Vec, + executable: PathBuf, } -#[derive(Default)] -struct Step { +#[derive(Debug, Deserialize)] +pub struct Toolchain { + name: String, + steps: Vec,} + +#[derive(Debug, Deserialize)] +pub struct Step { name: String, executable_path: Option, // if None then we use the current executable path arguments: Vec, // special string $INPUT corresponds to previous step output output: String, // the output file name + + uses_runtime: Option, + uses_in_stream: Option, + allow_error: Option } -pub fn parse_config(path: PathBuf) { +pub fn parse_config(path: PathBuf) -> Config { + // load the yaml from the system path, if it fails, tell the user and exit + let yaml_load = std::fs::File::open(path); + let yaml_file = match yaml_load { + Ok(file) => file, + Err(error) => panic!("Failed to load configuration file 🤮, error thrown: {:?}", error), + }; + let config: Config = match serde_yaml::from_reader(yaml_file) { + Ok(conf) => conf, + Err(error) => panic!("Failed to parse YAML file 😕, error: {}", error), + }; + + return config; +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + #[should_panic] + fn test_nonexistant_config() { + let path: PathBuf = PathBuf::from("src/util/test/parse_config/non_existant.yaml"); + parse_config(path); + } + + #[test] + fn test_load_config() { + let path: PathBuf = PathBuf::from("src/util/test/parse_config/config.yaml"); + let config = parse_config(path); + println!("{:?}", config); + } + + #[test] + #[should_panic] + fn test_load_bad_config() { + let path: PathBuf = PathBuf::from("src/util/test/parse_config/bad_config.yaml"); + let config = parse_config(path); + println!("{:?}", config); + } } From 6e9b15571cc4f87d68db978937c863d2204abb83 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Fri, 12 Jan 2024 21:35:27 -0700 Subject: [PATCH 4/6] Added test files for configuration parsing --- src/util/test/parse_config/bad_config.yaml | 37 ++++++++++++++++++++++ src/util/test/parse_config/config.yaml | 37 ++++++++++++++++++++++ src/util/test/parse_config/file1.txt | 0 src/util/test/parse_config/file10.txt | 0 src/util/test/parse_config/file2.txt | 0 src/util/test/parse_config/file3.txt | 0 src/util/test/parse_config/file4.txt | 0 src/util/test/parse_config/file5.txt | 0 src/util/test/parse_config/file6.txt | 0 src/util/test/parse_config/file7.txt | 0 src/util/test/parse_config/file8.txt | 0 src/util/test/parse_config/file9.txt | 0 12 files changed, 74 insertions(+) create mode 100644 src/util/test/parse_config/bad_config.yaml create mode 100644 src/util/test/parse_config/config.yaml create mode 100644 src/util/test/parse_config/file1.txt create mode 100644 src/util/test/parse_config/file10.txt create mode 100644 src/util/test/parse_config/file2.txt create mode 100644 src/util/test/parse_config/file3.txt create mode 100644 src/util/test/parse_config/file4.txt create mode 100644 src/util/test/parse_config/file5.txt create mode 100644 src/util/test/parse_config/file6.txt create mode 100644 src/util/test/parse_config/file7.txt create mode 100644 src/util/test/parse_config/file8.txt create mode 100644 src/util/test/parse_config/file9.txt diff --git a/src/util/test/parse_config/bad_config.yaml b/src/util/test/parse_config/bad_config.yaml new file mode 100644 index 0000000..6436c18 --- /dev/null +++ b/src/util/test/parse_config/bad_config.yaml @@ -0,0 +1,37 @@ + +input_path: "/path/to/dir" +in_stream_path: "/path/to/in/stream" + +tested_executables: + - name: "team1" + executable: "/path/to/exec" + - name: "team2" + executable: "/path/to/exec2" + +runtimes: + - name: "team1" + executable: "/path/to/exec" + - name: "team1" + executable: "/path/to/exec" + +toolchains: + - name: "toolchain1" + steps: + - name: "step1" + executable_path: "$EXE" + arguments: + - $INPUT + - $OUTPUT + output: "out.test" + - name: "step2" + executable_path: "/bin/bash" + arguments: + - echo "Hello World" + output: "-" + - name: "toolchain2" + steps: + - name: "step1" + executable_path: "/bin/bash" + arguments: + - echo "Hello toolchain 2!" + output: "-" diff --git a/src/util/test/parse_config/config.yaml b/src/util/test/parse_config/config.yaml new file mode 100644 index 0000000..e166161 --- /dev/null +++ b/src/util/test/parse_config/config.yaml @@ -0,0 +1,37 @@ +input_path: "/path/to/dir" +output_path: "/path/to/out/dir" +in_stream_path: "/path/to/in/stream" + +tested_executables: + - name: "team1" + executable: "/path/to/exec" + - name: "team2" + executable: "/path/to/exec2" + +runtimes: + - name: "team1" + executable: "/path/to/exec" + - name: "team1" + executable: "/path/to/exec" + +toolchains: + - name: "toolchain1" + steps: + - name: "step1" + executable_path: "$EXE" + arguments: + - $INPUT + - $OUTPUT + output: "out.test" + - name: "step2" + executable_path: "/bin/bash" + arguments: + - echo "Hello World" + output: "-" + - name: "toolchain2" + steps: + - name: "step1" + executable_path: "/bin/bash" + arguments: + - echo "Hello toolchain 2!" + output: "-" diff --git a/src/util/test/parse_config/file1.txt b/src/util/test/parse_config/file1.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/util/test/parse_config/file10.txt b/src/util/test/parse_config/file10.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/util/test/parse_config/file2.txt b/src/util/test/parse_config/file2.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/util/test/parse_config/file3.txt b/src/util/test/parse_config/file3.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/util/test/parse_config/file4.txt b/src/util/test/parse_config/file4.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/util/test/parse_config/file5.txt b/src/util/test/parse_config/file5.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/util/test/parse_config/file6.txt b/src/util/test/parse_config/file6.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/util/test/parse_config/file7.txt b/src/util/test/parse_config/file7.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/util/test/parse_config/file8.txt b/src/util/test/parse_config/file8.txt new file mode 100644 index 0000000..e69de29 diff --git a/src/util/test/parse_config/file9.txt b/src/util/test/parse_config/file9.txt new file mode 100644 index 0000000..e69de29 From 6449aed9ec0e41fdfb816788d8825a046bc02c81 Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Fri, 12 Jan 2024 21:54:57 -0700 Subject: [PATCH 5/6] Modified runners to accept a config object --- src/grade.rs | 6 ++++-- src/main.rs | 13 ++++++++++--- src/run.rs | 9 +++++++-- src/validate.rs | 10 ++++++++-- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/grade.rs b/src/grade.rs index fd55e01..c8c7f39 100644 --- a/src/grade.rs +++ b/src/grade.rs @@ -1,5 +1,7 @@ -use std::path::{Path, PathBuf}; +use std::path::Path; -pub fn grade(verbosity: u8, config_file: PathBuf, grade_config: Option<&Path>) { +use crate::util; + +pub fn grade(verbosity: u8, config: util::config::Config, grade_config: Option<&Path>) { println!("Grading!"); } diff --git a/src/main.rs b/src/main.rs index ffe15dd..8ec0d7b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use clap::{Parser, Subcommand}; mod validate; mod run; mod grade; +pub mod util; fn main() { // get cli args @@ -12,11 +13,15 @@ fn main() { // parse the verbosity and eliminate the Option<> let verbosity = get_verbosity(cli.verbosity); + let config = util::config::parse_config(cli.config_file); + + //parse the config file + // let config = parse_config(cli.config_file); match &cli.command { - Command::Validate => validate::validate(verbosity, cli.config_file), - Command::Run => run::run(verbosity, cli.config_file), - Command::Grade => grade::grade(verbosity, cli.config_file, cli.grading_conf.as_deref()), + Command::Validate => validate::validate(verbosity, config), + Command::Run => run::run(verbosity, config), + Command::Grade => grade::grade(verbosity, config, cli.grading_conf.as_deref()), } } @@ -28,6 +33,8 @@ struct Cli { #[arg(short, long, action = clap::ArgAction::Count)] verbosity: Option, + //TODO implement a thread count variable for the runner + /// Set the config file #[arg(short, long, value_name = "CONFIG")] config_file: PathBuf, diff --git a/src/run.rs b/src/run.rs index 1dcb660..a2d7891 100644 --- a/src/run.rs +++ b/src/run.rs @@ -1,5 +1,10 @@ -use std::path::PathBuf; +use crate::util; -pub fn run(verbosity: u8, config_file: PathBuf) { +pub fn run(verbosity: u8, config: util::config::Config) { println!("Running!"); } + +#[cfg(test)] +mod tests { + +} diff --git a/src/validate.rs b/src/validate.rs index 2bb60d6..fb88886 100644 --- a/src/validate.rs +++ b/src/validate.rs @@ -1,5 +1,11 @@ -use std::path::PathBuf; +use crate::util; -pub fn validate(verbosity: u8, config_file: PathBuf) { +pub fn validate(verbosity: u8, config: util::config::Config) { println!("Validating"); } + + +#[cfg(test)] +mod tests { + +} From b13c42841b271c5569baa0cfe4a70a543ee68a0a Mon Sep 17 00:00:00 2001 From: Ayrton Chilibeck Date: Fri, 12 Jan 2024 22:03:52 -0700 Subject: [PATCH 6/6] Added a README --- README.md | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..680488e --- /dev/null +++ b/README.md @@ -0,0 +1,70 @@ +# Tester CMPUT 415 (rust version) + +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 + +Commands: + validate Validate test matching and config file correctness + run Run all tests + grade Grade with grading config + help Print this message or the help of the given subcommand(s) + +Options: + -v, --verbosity... Sets the verbosity of the tester + -c, --config-file Set the config file + -g, --grading-conf 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). + +## Configuration File + +The configuration file is specified in [YAML](https://yaml.org/spec/1.2.2/), so go check it out. Below is a fully featured config file, with more to come: + +``` yaml +input_path: "/path/to/dir" +output_path: "/path/to/out/dir" +in_stream_path: "/path/to/in/stream" + +tested_executables: + - name: "team1" + executable: "/path/to/exec" + - name: "team2" + executable: "/path/to/exec2" + +runtimes: + - name: "team1" + executable: "/path/to/exec" + - name: "team1" + executable: "/path/to/exec" + +toolchains: + - name: "toolchain1" + steps: + - name: "step1" + executable_path: "$EXE" + arguments: + - $INPUT + - $OUTPUT + output: "out.test" + - name: "step2" + executable_path: "/bin/bash" + arguments: + - echo "Hello World" + output: "-" + - name: "toolchain2" + steps: + - name: "step1" + executable_path: "/bin/bash" + arguments: + - echo "Hello toolchain 2!" + output: "-" +``` + +You can refer to the [original tester](https://github.com/cmput415/Tester) documentation to see some more options (#TODO will be pasting that here)