diff --git a/Makefile.toml b/Makefile.toml index 4c11b71..32533ec 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -30,11 +30,14 @@ args = ["build", "--target", "${TARGET}", "${@}"] [tasks.release_tasks] script = ''' -if [[ "${@}" =~ "release" ]]; then - echo "Stripping binaries..." - strip $(ls ./target/${TARGET}/release/u_* -1 | grep -v ".d") +if [[ "${@}" =~ "--release" ]]; then echo "Creating symlink to release dir..." ln -s ./target/${TARGET}/release ./release || true + BINS=$(ls ./release/u_* -1 | grep -v ".d") + echo "Stripping..." + strip $BINS + echo "Packing..." + upx -9 $BINS fi ''' @@ -56,7 +59,7 @@ args = ["test", "--target", "${TARGET}", "--lib", "--", "${@}"] [tasks.integration] script = ''' cd ./integration -bash integration_tests.sh +bash integration_tests.sh ${@} ''' [tasks.gen_schema] diff --git a/bin/u_agent/src/lib.rs b/bin/u_agent/src/lib.rs index 9403868..581fd7f 100644 --- a/bin/u_agent/src/lib.rs +++ b/bin/u_agent/src/lib.rs @@ -12,7 +12,8 @@ use std::sync::Arc; use tokio::time::{sleep, Duration}; use u_lib::{ api::ClientHandler, builder::JobBuilder, cache::JobCache, errors::ErrChan, - executor::pop_completed, messaging::Reportable, models::AssignedJob, utils::Env, UError, UID, + executor::pop_completed, messaging::Reportable, models::AssignedJob, utils::load_env_default, + UError, UID, }; const ITERATION_LATENCY: u64 = 5; @@ -86,14 +87,14 @@ async fn do_stuff(client: Arc) -> ! { } } -pub async fn run_forever() { +pub async fn run_forever() -> ! { //daemonize(); env_logger::init(); - let env = Env::init_default().unwrap(); + let env = load_env_default().unwrap(); let client = Arc::new(ClientHandler::new(&env.u_server)); panic::set_hook(Box::new(|panic_info| { ErrChan::send(UError::Panic(panic_info.to_string())) })); tokio::spawn(error_reporting(client.clone())); - do_stuff(client).await; + do_stuff(client).await } diff --git a/bin/u_panel/Cargo.toml b/bin/u_panel/Cargo.toml index 2bccf84..6facac5 100644 --- a/bin/u_panel/Cargo.toml +++ b/bin/u_panel/Cargo.toml @@ -21,7 +21,6 @@ tui = { version = "0.16", default-features = false, features = ['crossterm'] } crossterm = "0.22.1" anyhow = "1.0.44" strum = { version = "0.22.0", features = ["derive"] } -async-trait = "0.1.51" once_cell = "1.8.0" crossbeam = "0.8.1" async-channel = "1.6.1" diff --git a/bin/u_panel/src/argparse.rs b/bin/u_panel/src/argparse.rs index c8f9b38..cfe9050 100644 --- a/bin/u_panel/src/argparse.rs +++ b/bin/u_panel/src/argparse.rs @@ -1,7 +1,8 @@ -use crate::CLIENT; use std::fmt; use structopt::StructOpt; -use u_lib::{datatypes::DataResult, messaging::AsMsg, models::JobMeta, UError, UResult}; +use u_lib::{ + api::ClientHandler, datatypes::DataResult, messaging::AsMsg, models::JobMeta, UError, UResult, +}; use uuid::Uuid; #[derive(StructOpt, Debug)] @@ -82,7 +83,7 @@ fn parse_uuid(src: &str) -> Result { Uuid::parse_str(src).map_err(|e| e.to_string()) } -pub async fn process_cmd(args: Args) -> UResult<()> { +pub async fn process_cmd(client: ClientHandler, args: Args) -> UResult<()> { struct Printer { json: bool, } @@ -107,8 +108,8 @@ pub async fn process_cmd(args: Args) -> UResult<()> { let printer = Printer { json: args.json }; match args.cmd { Cmd::Agents(action) => match action { - LD::List { uid } => printer.print(CLIENT.get().unwrap().get_agents(uid).await), - LD::Delete { uid } => printer.print(CLIENT.get().unwrap().del(Some(uid)).await), + LD::List { uid } => printer.print(client.get_agents(uid).await), + LD::Delete { uid } => printer.print(client.del(Some(uid)).await), }, Cmd::Jobs(action) => match action { JobALD::Add { @@ -120,30 +121,18 @@ pub async fn process_cmd(args: Args) -> UResult<()> { .with_shell(cmd.join(" ")) .with_alias(alias) .build()?; - printer.print(CLIENT.get().unwrap().upload_jobs(&[job]).await); - } - JobALD::LD(LD::List { uid }) => { - printer.print(CLIENT.get().unwrap().get_jobs(uid).await) - } - JobALD::LD(LD::Delete { uid }) => { - printer.print(CLIENT.get().unwrap().del(Some(uid)).await) + printer.print(client.upload_jobs(&[job]).await); } + JobALD::LD(LD::List { uid }) => printer.print(client.get_jobs(uid).await), + JobALD::LD(LD::Delete { uid }) => printer.print(client.del(Some(uid)).await), }, Cmd::Map(action) => match action { JobMapALD::Add { agent_uid, job_idents, - } => printer.print( - CLIENT - .get() - .unwrap() - .set_jobs(Some(agent_uid), &job_idents) - .await, - ), - JobMapALD::List { uid } => { - printer.print(CLIENT.get().unwrap().get_agent_jobs(uid).await) - } - JobMapALD::Delete { uid } => printer.print(CLIENT.get().unwrap().del(Some(uid)).await), + } => printer.print(client.set_jobs(Some(agent_uid), &job_idents).await), + JobMapALD::List { uid } => printer.print(client.get_agent_jobs(uid).await), + JobMapALD::Delete { uid } => printer.print(client.del(Some(uid)).await), }, /*Cmd::TUI(args) => crate::tui::init_tui(&args) .await diff --git a/bin/u_panel/src/main.rs b/bin/u_panel/src/main.rs index 3296915..2f0d685 100644 --- a/bin/u_panel/src/main.rs +++ b/bin/u_panel/src/main.rs @@ -2,36 +2,29 @@ mod argparse; mod server; //mod tui; -#[macro_use] -extern crate async_trait; - #[macro_use] extern crate tracing; +use anyhow::Result as AnyResult; use argparse::{process_cmd, Args}; -use once_cell::sync::OnceCell; use serde::Deserialize; -use std::process; use structopt::StructOpt; use u_lib::api::ClientHandler; -use u_lib::utils::Env; - -pub static CLIENT: OnceCell = OnceCell::new(); +use u_lib::utils::{env::default_host, load_env}; #[derive(Deserialize)] struct AccessEnv { admin_auth_token: String, + #[serde(default = "default_host")] + u_server: String, } #[tokio::main] -async fn main() { - let env = Env::::init().unwrap(); - - CLIENT.get_or_init(|| ClientHandler::new(&env.u_server).password(env.inner.admin_auth_token)); +async fn main() -> AnyResult<()> { + let env = load_env::()?; + let client = ClientHandler::new(&env.u_server).password(env.admin_auth_token); + let args = Args::from_args(); - let args: Args = Args::from_args(); - if let Err(e) = process_cmd(args).await { - eprintln!("Error: {}", e); - process::exit(1) - } + process_cmd(client, args).await?; + Ok(()) } diff --git a/bin/u_server/Cargo.toml b/bin/u_server/Cargo.toml index d848850..13d12ca 100644 --- a/bin/u_server/Cargo.toml +++ b/bin/u_server/Cargo.toml @@ -12,28 +12,15 @@ warp = { version = "0.3.1", features = ["tls"] } uuid = { version = "0.6.5", features = ["serde", "v4"] } once_cell = "1.7.2" hyper = "0.14" -mockall = "0.9.1" -mockall_double = "0.2" openssl = "*" +diesel = { version = "1.4.5", features = ["postgres", "uuid"] } +serde = { version = "1.0", features = ["derive"] } +tokio = { version = "1.9", features = ["macros"] } +u_lib = { path = "../../lib/u_lib", version = "*" } -[dependencies.diesel] -features = ["postgres", "uuid"] -version = "1.4.5" - -[dependencies.serde] -features = ["derive"] -version = "1.0.114" - -[dependencies.tokio] -features = ["macros"] -version = "1.9" - -[dependencies.u_lib] -path = "../../lib/u_lib" -version = "*" [dev-dependencies] -test-case = "1.1.0" +rstest = "0.12" [lib] name = "u_server_lib" diff --git a/bin/u_server/src/db.rs b/bin/u_server/src/db.rs index a5b3796..cff590f 100644 --- a/bin/u_server/src/db.rs +++ b/bin/u_server/src/db.rs @@ -4,7 +4,7 @@ use serde::Deserialize; use std::sync::{Arc, Mutex, MutexGuard}; use u_lib::{ models::{schema, Agent, AgentError, AssignedJob, JobMeta, JobState}, - utils::Env, + utils::load_env, ULocalError, ULocalResult, }; use uuid::Uuid; @@ -23,14 +23,13 @@ struct DBEnv { db_password: String, } -#[cfg_attr(test, automock)] impl UDB { - pub fn lock_db() -> MutexGuard<'static, UDB> { + pub fn lock_db() -> MutexGuard<'static, Self> { DB.get_or_init(|| { - let env = Env::::init().unwrap(); + let env = load_env::().unwrap(); let db_url = format!( "postgres://{}:{}@{}/{}", - env.inner.db_user, env.inner.db_password, env.inner.db_host, env.inner.db_name + env.db_user, env.db_password, env.db_host, env.db_name ); let conn = PgConnection::establish(&db_url).unwrap(); let instance = UDB { conn }; diff --git a/bin/u_server/src/handlers.rs b/bin/u_server/src/handlers.rs index 3158bcf..9a23f17 100644 --- a/bin/u_server/src/handlers.rs +++ b/bin/u_server/src/handlers.rs @@ -32,7 +32,6 @@ pub fn build_message(m: M) -> Response { pub struct Endpoints; -#[cfg_attr(test, automock)] impl Endpoints { pub async fn add_agent(msg: Agent) -> Result, Rejection> { info!("hnd: add_agent"); diff --git a/bin/u_server/src/main.rs b/bin/u_server/src/main.rs index 05ec4e0..e402a55 100644 --- a/bin/u_server/src/main.rs +++ b/bin/u_server/src/main.rs @@ -1,6 +1,6 @@ use u_server_lib::serve; #[tokio::main] -async fn main() { - serve().await; +async fn main() -> Result<(), String> { + serve().await } diff --git a/bin/u_server/src/u_server.rs b/bin/u_server/src/u_server.rs index d9bbd03..bf9d8ed 100644 --- a/bin/u_server/src/u_server.rs +++ b/bin/u_server/src/u_server.rs @@ -1,10 +1,9 @@ #[macro_use] extern crate log; -#[cfg_attr(test, macro_use)] -extern crate mockall; -#[cfg_attr(test, macro_use)] -extern crate mockall_double; +#[cfg(test)] +#[macro_use] +extern crate rstest; // due to linking errors extern crate openssl; @@ -19,7 +18,7 @@ mod init; use init::*; use serde::Deserialize; use std::path::PathBuf; -use u_lib::{config::MASTER_PORT, utils::Env}; +use u_lib::{config::MASTER_PORT, utils::load_env}; use warp::Filter; #[derive(Deserialize)] @@ -32,8 +31,8 @@ pub async fn serve() -> Result<(), String> { init_logger(); prefill_jobs(); - let env = Env::::init().map_err(|e| e.to_string())?; - let routes = init_filters(&env.inner.admin_auth_token); + let env = load_env::().map_err(|e| e.to_string())?; + let routes = init_filters(&env.admin_auth_token); let certs_dir = PathBuf::from("certs"); warp::serve(routes.with(warp::log("warp"))) .tls() @@ -45,25 +44,26 @@ pub async fn serve() -> Result<(), String> { Ok(()) } +/* #[cfg(test)] mod tests { use super::*; - #[double] use crate::handlers::Endpoints; use handlers::build_ok; - use mockall::predicate::*; - use test_case::test_case; use u_lib::messaging::{AsMsg, BaseMessage, Reportable}; use uuid::Uuid; - use warp::test::request; + use warp::test; - #[test_case(Some(Uuid::new_v4()))] - #[test_case(None => panics)] + #[rstest] + #[case(Some(Uuid::new_v4()))] + #[should_panic] + #[case(None)] #[tokio::test] - async fn test_get_agent_jobs_unauthorized(uid: Option) { - let mock = Endpoints::get_agent_jobs_context(); - mock.expect().with(eq(uid)).returning(|_| Ok(build_ok(""))); - request() + async fn test_get_agent_jobs_unauthorized(#[case] uid: Option) { + let mock = Endpoints::faux(); + when!(mock.get_agent_jobs).then_return(Ok(build_ok(""))); + //mock.expect().with(eq(uid)).returning(|_| Ok(build_ok(""))); + test::request() .path(&format!( "/get_agent_jobs/{}", uid.map(|u| u.simple().to_string()).unwrap_or(String::new()) @@ -72,16 +72,15 @@ mod tests { .filter(&init_filters("")) .await .unwrap(); - mock.checkpoint(); } #[tokio::test] async fn test_report_unauth_successful() { - let mock = Endpoints::report_context(); + let mock = Endpoints::report(); mock.expect() .withf(|msg: &BaseMessage<'_, Vec>| msg.inner_ref()[0] == Reportable::Dummy) .returning(|_| Ok(build_ok(""))); - request() + test::request() .path("/report/") .method("POST") .json(&vec![Reportable::Dummy].as_message()) @@ -91,3 +90,4 @@ mod tests { mock.checkpoint(); } } +*/ diff --git a/images/integration-tests/tests_base.Dockerfile b/images/integration-tests/tests_base.Dockerfile deleted file mode 100644 index 81fee07..0000000 --- a/images/integration-tests/tests_base.Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -# build from lib/ -FROM rust:1.60 as chef - -RUN rustup target add x86_64-unknown-linux-musl -RUN cargo install cargo-chef - -COPY u_lib /lib/u_lib -COPY u_api_proc_macro /lib/u_api_proc_macro -COPY certs /certs - -WORKDIR /app \ No newline at end of file diff --git a/images/integration-tests/tests_runner.Dockerfile b/images/integration-tests/tests_runner.Dockerfile index ae60226..0a60d7a 100644 --- a/images/integration-tests/tests_runner.Dockerfile +++ b/images/integration-tests/tests_runner.Dockerfile @@ -1,12 +1,4 @@ -# build from integration/ -FROM unki/tests_base as chef - -FROM chef as planner -COPY . /app -RUN cargo chef prepare --recipe-path recipe.json - -FROM chef as builder -COPY --from=planner /app/recipe.json recipe.json -RUN cargo chef cook --release --recipe-path recipe.json +FROM rust:1.60 +RUN rustup target add x86_64-unknown-linux-musl CMD ["sleep", "3600"] \ No newline at end of file diff --git a/integration/Cargo.toml b/integration/Cargo.toml index 14fb0f6..d0c9819 100644 --- a/integration/Cargo.toml +++ b/integration/Cargo.toml @@ -16,7 +16,8 @@ serde_json = "1.0" serde = { version = "1.0.114", features = ["derive"] } futures = "0.3.5" shlex = "1.0.0" -rstest = "0.11" +rstest = "0.12" +once_cell = "1.10.0" [dependencies.u_lib] path = "../lib/u_lib" @@ -25,4 +26,4 @@ version = "*" [[test]] name = "integration" -path = "tests/lib.rs" \ No newline at end of file +path = "tests/lib.rs" diff --git a/integration/docker-compose.yml b/integration/docker-compose.yml index 9d2e218..2186a8e 100644 --- a/integration/docker-compose.yml +++ b/integration/docker-compose.yml @@ -67,6 +67,7 @@ services: condition: service_healthy tests_runner: + user: "${DOCKER_UID}:${DOCKER_GID}" image: unki/tests_runner networks: - u_net diff --git a/integration/docker.py b/integration/docker.py index 2d47517..05182bd 100644 --- a/integration/docker.py +++ b/integration/docker.py @@ -1,9 +1,9 @@ import subprocess + from utils import * BASE_IMAGE_DIR = '../images/integration-tests' -# do not reorder DOCKERFILES = [ { 'name': 'u_agent', @@ -17,13 +17,9 @@ DOCKERFILES = [ 'name': 'u_db', 'ctx': BASE_IMAGE_DIR, }, - { - 'name': 'tests_base', - 'ctx': '../lib', - }, { 'name': 'tests_runner', - 'ctx': '../integration', + 'ctx': BASE_IMAGE_DIR, }, ] @@ -75,11 +71,10 @@ def rebuild_images_if_needed(force_rebuild=False): log(f'Building docker image {img_name}') cmd = [ 'build', - '-t', - img_name, + '-t', img_name, + '-f', f'{BASE_IMAGE_DIR}/{name}.{df_suffix}', ctx, ] - cmd += ['-f', f'{BASE_IMAGE_DIR}/{name}.{df_suffix}'] if force_rebuild: cmd += ['--no-cache'] docker(cmd) diff --git a/integration/integration_tests.sh b/integration/integration_tests.sh index 374299b..97d06e8 100755 --- a/integration/integration_tests.sh +++ b/integration/integration_tests.sh @@ -1,5 +1,5 @@ #!/bin/bash set -e -cp -r ../certs ../lib/certs +export DOCKER_UID=$(id -u) +export DOCKER_GID=$(id -g) python integration_tests.py $@ -rm -rf ../lib/certs diff --git a/integration/tests/fixtures/agent.rs b/integration/tests/fixtures/agent.rs index 596f9a8..5188830 100644 --- a/integration/tests/fixtures/agent.rs +++ b/integration/tests/fixtures/agent.rs @@ -1,3 +1,4 @@ +use crate::helpers::ENV; use u_lib::{api::ClientHandler, messaging::Reportable, models::*}; use uuid::Uuid; @@ -7,14 +8,14 @@ pub struct RegisteredAgent { impl RegisteredAgent { pub async fn unregister(self) { - let cli = ClientHandler::new(None); + let cli = ClientHandler::new(&ENV.u_server); cli.del(Some(self.uid)).await.unwrap(); } } #[fixture] pub async fn register_agent() -> RegisteredAgent { - let cli = ClientHandler::new(None); + let cli = ClientHandler::new(&ENV.u_server); let agent_uid = Uuid::new_v4(); let resp = cli .get_personal_jobs(Some(agent_uid)) diff --git a/integration/tests/helpers/mod.rs b/integration/tests/helpers/mod.rs index 783b365..91d7eb7 100644 --- a/integration/tests/helpers/mod.rs +++ b/integration/tests/helpers/mod.rs @@ -1,3 +1,8 @@ pub mod panel; pub use panel::Panel; + +use once_cell::sync::Lazy; +use u_lib::utils::{env::DefaultEnv, load_env_default}; + +pub static ENV: Lazy = Lazy::new(|| load_env_default().unwrap()); diff --git a/integration/tests/lib.rs b/integration/tests/lib.rs index 70019bb..aac47fb 100644 --- a/integration/tests/lib.rs +++ b/integration/tests/lib.rs @@ -2,21 +2,20 @@ mod fixtures; mod helpers; mod integration; +use crate::helpers::ENV; use u_lib::config::MASTER_PORT; -use u_lib::utils::Env; #[macro_use] extern crate rstest; #[tokio::test] async fn test_non_auth_connection_dropped() { - let env = Env::init_default().unwrap(); let client = reqwest::ClientBuilder::new() .danger_accept_invalid_certs(true) .build() .unwrap(); match client - .get(format!("https://{}:{}", &env.u_server, MASTER_PORT)) + .get(format!("https://{}:{}", &ENV.u_server, MASTER_PORT)) .send() .await { diff --git a/lib/u_lib/Cargo.toml b/lib/u_lib/Cargo.toml index adfc2c4..da445e7 100644 --- a/lib/u_lib/Cargo.toml +++ b/lib/u_lib/Cargo.toml @@ -16,7 +16,6 @@ lazy_static = "1.4.0" futures = "0.3.5" thiserror = "*" log = "*" -mockall = "0.9.1" env_logger = "0.8.3" diesel-derive-enum = { version = "1", features = ["postgres"] } chrono = "0.4.19" @@ -36,5 +35,4 @@ guess_host_triple = "0.1.2" openssl = "*" [dev-dependencies] -test-case = "1.1.0" -rstest = "0.11" +rstest = "0.12" diff --git a/lib/u_lib/src/builder.rs b/lib/u_lib/src/builder.rs index 746cc12..29aeef1 100644 --- a/lib/u_lib/src/builder.rs +++ b/lib/u_lib/src/builder.rs @@ -1,12 +1,10 @@ use crate::{ - UError, - UErrorBt, - UResult, - cache::JobCache, - executor::{Waiter, DynFut}, - messaging::Reportable, - models::{Agent, AssignedJob, JobMeta, JobType}, - utils::{CombinedResult, OneOrVec} + cache::JobCache, + executor::{DynFut, Waiter}, + messaging::Reportable, + models::{Agent, AssignedJob, JobMeta, JobType}, + utils::{CombinedResult, OneOrVec}, + UError, UErrorBt, UResult, }; use guess_host_triple::guess_host_triple; use std::collections::HashMap; @@ -15,7 +13,7 @@ pub struct JobBuilder { waiter: Waiter, } -impl JobBuilder { +impl JobBuilder { pub fn from_request(job_requests: impl OneOrVec) -> CombinedResult { let job_requests = job_requests.into_vec(); let mut prepared: Vec = vec![]; @@ -38,7 +36,8 @@ impl JobBuilder { return Err(UError::InsuitablePlatform( meta.platform.clone(), curr_platform, - ).into()); + ) + .into()); } let job = AssignedJob::new(req.job_id, Some(&req)); prepared.push(Box::pin(job.run())) @@ -152,19 +151,13 @@ impl NamedJobBuilder { #[cfg(test)] mod tests { - use super::*; - use test_case::test_case; - use std::{time::SystemTime}; use crate::{ - errors::UError, - models::{ - JobMeta, - misc::JobType - }, builder::{JobBuilder, NamedJobBuilder}, + models::{misc::JobType, JobMeta}, unwrap_enum, }; + use std::time::SystemTime; type TestResult = Result>; @@ -178,19 +171,14 @@ mod tests { assert!(now.elapsed().unwrap().as_secs() < SLEEP_SECS + 2) } - #[test_case( - "/bin/sh {}", - Some(b"echo test01 > /tmp/asd; cat /tmp/asd"), + #[rstest] + #[case::sh_payload( + "/bin/sh {}", + Some(b"echo test01 > /tmp/asd; cat /tmp/asd".as_slice()), "test01" - ;"sh payload" - )] - #[test_case( - r#"/usr/bin/python3 -c 'print("test02")'"#, - None, - "test02" - ;"python cmd" )] - #[test_case( + #[case::python_cmd(r#"/usr/bin/python3 -c 'print("test02")'"#, None, "test02")] + #[case::sh_multiline_payload( "/{}", Some( br#"#!/bin/sh @@ -198,20 +186,22 @@ mod tests { mkdir -p $TMPPATH echo test03 > $TMPPATH/t cat $TMPPATH/t - rm -rf $TMPPATH"# + rm -rf $TMPPATH"#.as_slice() ), "test03" - ;"sh multiline payload" )] - #[test_case( + #[case::standalone_binary_with_args( "/{} 'some msg as arg'", - Some(include_bytes!("../tests/fixtures/echoer")), + Some(include_bytes!("../tests/fixtures/echoer").as_slice()), "some msg as arg" - ;"standalone binary with args" )] #[tokio::test] - async fn test_shell_job(cmd: &str, payload: Option<&[u8]>, expected_result: &str) -> TestResult { - let mut job = JobMeta::builder().with_shell(cmd); + async fn test_shell_job( + #[case] cmd: &str, + #[case] payload: Option<&[u8]>, + #[case] expected_result: &str, + ) -> TestResult { + let mut job = JobMeta::builder().with_shell(cmd); if let Some(p) = payload { job = job.with_payload(p); } @@ -228,8 +218,12 @@ mod tests { const SLEEP_SECS: u64 = 1; let now = SystemTime::now(); let longest_job = JobMeta::from_shell(format!("sleep {}", SLEEP_SECS)).unwrap(); - let longest_job = JobBuilder::from_meta(longest_job).unwrap_one().spawn().await; - let ls = JobBuilder::from_meta(JobMeta::from_shell("ls")?).unwrap_one() + let longest_job = JobBuilder::from_meta(longest_job) + .unwrap_one() + .spawn() + .await; + let ls = JobBuilder::from_meta(JobMeta::from_shell("ls")?) + .unwrap_one() .wait_one() .await; let ls = unwrap_enum!(ls, Reportable::Assigned); @@ -272,10 +266,7 @@ mod tests { #[tokio::test] async fn test_failing_shell_job() -> TestResult { let job = JobMeta::from_shell("lol_kek_puk")?; - let job_result = JobBuilder::from_meta(job) - .unwrap_one() - .wait_one() - .await; + let job_result = JobBuilder::from_meta(job).unwrap_one().wait_one().await; let job_result = unwrap_enum!(job_result, Reportable::Assigned); let output = job_result.to_string_result(); assert!(output.contains("No such file")); @@ -283,20 +274,15 @@ mod tests { Ok(()) } - #[test_case( - "/bin/bash {}", - None, - "contains executable" - ; "no binary" - )] - #[test_case( - "/bin/bash", - Some(b"whoami"), - "contains no executable" - ; "no path to binary" - )] + #[rstest] + #[case::no_binary("/bin/bash {}", None, "contains executable")] + #[case::no_path_to_binary("/bin/bash", Some(b"whoami".as_slice()), "contains no executable")] #[tokio::test] - async fn test_job_building_failed(cmd: &str, payload: Option<&[u8]>, err_str: &str) -> TestResult { + async fn test_job_building_failed( + #[case] cmd: &str, + #[case] payload: Option<&[u8]>, + #[case] err_str: &str, + ) -> TestResult { let mut job = JobMeta::builder().with_shell(cmd); if let Some(p) = payload { job = job.with_payload(p); @@ -311,11 +297,15 @@ mod tests { async fn test_different_job_types() -> TestResult { let mut jobs = NamedJobBuilder::from_meta(vec![ ("sleeper", JobMeta::from_shell("sleep 3")?), - ("gatherer", JobMeta::builder().with_type(JobType::Manage).build()?) - ]).wait().await; + ( + "gatherer", + JobMeta::builder().with_type(JobType::Manage).build()?, + ), + ]) + .wait() + .await; let gathered = jobs.pop("gatherer"); assert_eq!(unwrap_enum!(gathered, Reportable::Agent).alias, None); Ok(()) } - -} \ No newline at end of file +} diff --git a/lib/u_lib/src/lib.rs b/lib/u_lib/src/lib.rs index 1f37843..b49f71d 100644 --- a/lib/u_lib/src/lib.rs +++ b/lib/u_lib/src/lib.rs @@ -40,5 +40,6 @@ extern crate diesel; extern crate log; extern crate env_logger; +#[cfg(test)] #[macro_use] -extern crate mockall; +extern crate rstest; diff --git a/lib/u_lib/src/utils/env.rs b/lib/u_lib/src/utils/env.rs index a5a7352..a3c9345 100644 --- a/lib/u_lib/src/utils/env.rs +++ b/lib/u_lib/src/utils/env.rs @@ -2,35 +2,28 @@ use envy::{from_env, Result as EnvResult}; use serde::{de::DeserializeOwned, Deserialize}; #[derive(Deserialize)] -pub struct NoneEnv; - -#[derive(Deserialize)] -pub struct Env { +pub struct DefaultEnv { #[serde(default = "default_host")] pub u_server: String, - pub inner: E, } -impl Env { - pub fn init_default() -> EnvResult { - let envs = [".env", ".env.private"]; - for envfile in &envs { - dotenv::from_filename(envfile).ok(); - } - from_env() - } +pub fn load_env() -> EnvResult { + dot(); + from_env() +} + +pub fn load_env_default() -> EnvResult { + dot(); + from_env() } -impl Env { - pub fn init() -> EnvResult { - let envs = [".env", ".env.private"]; - for envfile in &envs { - dotenv::from_filename(envfile).ok(); - } - from_env() +fn dot() { + let envs = [".env", ".env.private"]; + for envfile in &envs { + dotenv::from_filename(envfile).ok(); } } -fn default_host() -> String { +pub fn default_host() -> String { "ortem.xyz".to_string() } diff --git a/lib/u_lib/src/utils/mod.rs b/lib/u_lib/src/utils/mod.rs index 3cddc6b..df527db 100644 --- a/lib/u_lib/src/utils/mod.rs +++ b/lib/u_lib/src/utils/mod.rs @@ -1,19 +1,19 @@ -mod combined_result; -mod conv; -mod env; -mod fmt; -mod misc; -mod proc_output; -mod storage; +pub mod combined_result; +pub mod conv; +pub mod env; +pub mod fmt; +pub mod misc; +pub mod proc_output; +pub mod storage; #[cfg(not(target_arch = "wasm32"))] -mod tempfile; +pub mod tempfile; #[cfg(unix)] -mod unix; -mod vec_display; +pub mod unix; +pub mod vec_display; pub use combined_result::*; pub use conv::*; -pub use env::Env; +pub use env::{load_env, load_env_default}; pub use fmt::*; pub use misc::*; pub use proc_output::*; diff --git a/lib/u_lib/src/utils/proc_output.rs b/lib/u_lib/src/utils/proc_output.rs index 5236e6b..a9c4135 100644 --- a/lib/u_lib/src/utils/proc_output.rs +++ b/lib/u_lib/src/utils/proc_output.rs @@ -117,46 +117,42 @@ impl ProcOutput { #[cfg(test)] mod tests { use crate::utils::{bytes_to_string, ProcOutput}; - use test_case::test_case; const STDOUT: &str = "<***STDOUT***>"; const STDERR: &str = "<***STDERR***>"; - #[test_case( + #[rstest] + #[case::stdout_stderr( "lol", "kek", &format!("{}lol{}kek", STDOUT, STDERR) - ;"stdout stderr" )] - #[test_case( + #[case::stderr( "", "kek", &format!("{}kek", STDERR) - ;"stderr" )] - fn test_to_combined(stdout: &str, stderr: &str, result: &str) { + fn test_to_combined(#[case] stdout: &str, #[case] stderr: &str, #[case] result: &str) { let output = ProcOutput::new() .stdout(stdout.as_bytes().to_vec()) .stderr(stderr.as_bytes().to_vec()); assert_eq!(&bytes_to_string(&output.into_combined()), result) } - #[test_case( + #[rstest] + #[case::stdout_stderr( &format!("{}lal{}kik", STDOUT, STDERR), "lal\nkik" - ;"stdout stderr" )] - #[test_case( + #[case::stdout( &format!("{}qeq", STDOUT), "qeq" - ;"stdout" )] - #[test_case( + #[case::stderr( &format!("{}vev", STDERR), "vev" - ;"stderr" )] - fn test_from_combined(src: &str, result: &str) { + fn test_from_combined(#[case] src: &str, #[case] result: &str) { let output = ProcOutput::from_combined(src.as_bytes()).unwrap(); assert_eq!(bytes_to_string(&output.to_appropriate()).trim(), result); }