From 25a738d912e087f34bd75399f51906d4d62cef57 Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Wed, 29 May 2024 20:46:45 -0700 Subject: [PATCH] add `test/` to chat --- src/build/mod.rs | 7 +- src/new/mod.rs | 26 +++-- .../api/{package_name}:{publisher}-v0.wit | 2 +- .../templates/rust/no-ui/chat/metadata.json | 1 + .../rust/no-ui/chat/send/Cargo.toml_ | 2 +- .../no-ui/chat/{package_name}/Cargo.toml_ | 2 +- src/new/templates/test/chat/tests.toml | 24 ++++ .../test/chat/{package_name}_test/Cargo.toml_ | 10 ++ .../{package_name}_test/api/tester:sys-v0.wit | 27 +++++ .../api/{package_name}:{publisher}-v0.wit | 27 +++++ .../{package_name}_test:{publisher}-v0.wit | 5 + .../chat/{package_name}_test/metadata.json | 17 +++ .../{package_name}_test/pkg/manifest.json | 13 +++ .../{package_name}_test/Cargo.toml_ | 21 ++++ .../{package_name}_test/src/lib.rs | 108 ++++++++++++++++++ .../{package_name}_test/src/tester_lib.rs | 31 +++++ src/run_tests/mod.rs | 41 +++++-- src/run_tests/tester_types.rs | 91 --------------- 18 files changed, 343 insertions(+), 112 deletions(-) create mode 100644 src/new/templates/test/chat/tests.toml create mode 100644 src/new/templates/test/chat/{package_name}_test/Cargo.toml_ create mode 100644 src/new/templates/test/chat/{package_name}_test/api/tester:sys-v0.wit create mode 100644 src/new/templates/test/chat/{package_name}_test/api/{package_name}:{publisher}-v0.wit create mode 100644 src/new/templates/test/chat/{package_name}_test/api/{package_name}_test:{publisher}-v0.wit create mode 100644 src/new/templates/test/chat/{package_name}_test/metadata.json create mode 100644 src/new/templates/test/chat/{package_name}_test/pkg/manifest.json create mode 100644 src/new/templates/test/chat/{package_name}_test/{package_name}_test/Cargo.toml_ create mode 100644 src/new/templates/test/chat/{package_name}_test/{package_name}_test/src/lib.rs create mode 100644 src/new/templates/test/chat/{package_name}_test/{package_name}_test/src/tester_lib.rs delete mode 100644 src/run_tests/tester_types.rs diff --git a/src/build/mod.rs b/src/build/mod.rs index 9a53b7f6..6bc9bd31 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; use std::path::Path; use std::process::Command; -use color_eyre::{eyre::{eyre, WrapErr}, Result}; +use color_eyre::{{eyre::{eyre, WrapErr}, Result}, Section}; use fs_err as fs; use serde::{Deserialize, Serialize}; use tracing::{info, instrument, warn}; @@ -650,9 +650,10 @@ pub async fn execute( return Ok(()); } return Err(eyre!( - "Required `pkg/` dir not found within given input dir {:?} (or cwd, if none given). Please re-run targeting a package.", + "Required `pkg/` dir not found within given input dir {:?} (or cwd, if none given).", package_dir, - )); + ).with_suggestion(|| "Please re-run targeting a package.") + ); } let ui_dir = package_dir.join("ui"); diff --git a/src/new/mod.rs b/src/new/mod.rs index 84db514b..e88b9b7a 100644 --- a/src/new/mod.rs +++ b/src/new/mod.rs @@ -200,16 +200,28 @@ pub fn execute( ui_infix, template.to_string(), ); + let test_prefix = format!( + "test/{}/", + template.to_string(), + ); let mut path_to_content: HashMap = PATH_TO_CONTENT .iter() - .filter_map(|(k, v)| { - k - .strip_prefix(&template_prefix) - .or_else(|| k.strip_prefix(&ui_prefix)) + .filter_map(|(path, content)| { + path.strip_prefix(&template_prefix) + .map(|p| p.to_string()) + .or_else(|| path.strip_prefix(&ui_prefix).map(|p| p.to_string())) + .or_else(|| path.strip_prefix(&test_prefix).map(|p| format!("test/{p}"))) + .or_else(|| { + if path.starts_with(&test_prefix) { + Some(path.to_string()) + } else { + None + } + }) .and_then(|stripped| { - let key = replace_vars(stripped, &package_name, &publisher); - let val = replace_vars(v, &package_name, &publisher); - Some((key, val)) + let modified_path = replace_vars(&stripped, &package_name, &publisher); + let modified_content = replace_vars(content, &package_name, &publisher); + Some((modified_path, modified_content)) }) }) .collect(); diff --git a/src/new/templates/rust/no-ui/chat/api/{package_name}:{publisher}-v0.wit b/src/new/templates/rust/no-ui/chat/api/{package_name}:{publisher}-v0.wit index 32cee559..c6eb7c36 100644 --- a/src/new/templates/rust/no-ui/chat/api/{package_name}:{publisher}-v0.wit +++ b/src/new/templates/rust/no-ui/chat/api/{package_name}:{publisher}-v0.wit @@ -23,5 +23,5 @@ interface {package_name_kebab} { world {package_name_kebab}-{publisher_dotted_kebab}-v0 { import {package_name_kebab}; - include process; + include process-v0; } diff --git a/src/new/templates/rust/no-ui/chat/metadata.json b/src/new/templates/rust/no-ui/chat/metadata.json index 944b2bb4..940b56a7 100644 --- a/src/new/templates/rust/no-ui/chat/metadata.json +++ b/src/new/templates/rust/no-ui/chat/metadata.json @@ -10,6 +10,7 @@ "code_hashes": { "0.1.0": "" }, + "wit_version": 0, "dependencies": [] }, "external_url": "", diff --git a/src/new/templates/rust/no-ui/chat/send/Cargo.toml_ b/src/new/templates/rust/no-ui/chat/send/Cargo.toml_ index efa24945..bedc0287 100644 --- a/src/new/templates/rust/no-ui/chat/send/Cargo.toml_ +++ b/src/new/templates/rust/no-ui/chat/send/Cargo.toml_ @@ -5,7 +5,7 @@ edition = "2021" [dependencies] anyhow = "1.0" -kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "84b3d84" } +kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "b492f3b" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" wit-bindgen = "0.24.0" diff --git a/src/new/templates/rust/no-ui/chat/{package_name}/Cargo.toml_ b/src/new/templates/rust/no-ui/chat/{package_name}/Cargo.toml_ index 084992fe..f644b051 100644 --- a/src/new/templates/rust/no-ui/chat/{package_name}/Cargo.toml_ +++ b/src/new/templates/rust/no-ui/chat/{package_name}/Cargo.toml_ @@ -6,7 +6,7 @@ edition = "2021" [dependencies] anyhow = "1.0" bincode = "1.3.3" -kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "84b3d84" } +kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "b492f3b" } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" wit-bindgen = "0.24.0" diff --git a/src/new/templates/test/chat/tests.toml b/src/new/templates/test/chat/tests.toml new file mode 100644 index 00000000..c08a7ee4 --- /dev/null +++ b/src/new/templates/test/chat/tests.toml @@ -0,0 +1,24 @@ +runtime = { FetchVersion = "latest" } +# runtime = { RepoPath = "~/git/kinode" } +runtime_build_release = false + + +[[tests]] +setup_package_paths = [".."] +test_packages = [ + { path = "{package_name}_test", grant_capabilities = ["{package_name}:{package_name}:template.os"] }, +] +timeout_secs = 5 +fakechain_router = 8545 + +[[tests.nodes]] +port = 8080 +home = "home/first" +fake_node_name = "first.dev" +runtime_verbosity = 0 + +[[tests.nodes]] +port = 8081 +home = "home/second" +fake_node_name = "second.dev" +runtime_verbosity = 0 diff --git a/src/new/templates/test/chat/{package_name}_test/Cargo.toml_ b/src/new/templates/test/chat/{package_name}_test/Cargo.toml_ new file mode 100644 index 00000000..6c797c34 --- /dev/null +++ b/src/new/templates/test/chat/{package_name}_test/Cargo.toml_ @@ -0,0 +1,10 @@ +[workspace] +resolver = "2" +members = [ + "{package_name}_test", +] + +[profile.release] +panic = "abort" +opt-level = "s" +lto = true diff --git a/src/new/templates/test/chat/{package_name}_test/api/tester:sys-v0.wit b/src/new/templates/test/chat/{package_name}_test/api/tester:sys-v0.wit new file mode 100644 index 00000000..7fe0574b --- /dev/null +++ b/src/new/templates/test/chat/{package_name}_test/api/tester:sys-v0.wit @@ -0,0 +1,27 @@ +interface tester { + variant request { + run(run-request), + } + + variant response { + run(result<_, fail-response>) + } + + record run-request { + input-node-names: list, + test-names: list, + test-timeout: u64, + } + + record fail-response { + test: string, + file: string, + line: u32, + column: u32, + } +} + +world tester-sys-v0 { + import tester; + include process-v0; +} diff --git a/src/new/templates/test/chat/{package_name}_test/api/{package_name}:{publisher}-v0.wit b/src/new/templates/test/chat/{package_name}_test/api/{package_name}:{publisher}-v0.wit new file mode 100644 index 00000000..c6eb7c36 --- /dev/null +++ b/src/new/templates/test/chat/{package_name}_test/api/{package_name}:{publisher}-v0.wit @@ -0,0 +1,27 @@ +interface {package_name_kebab} { + variant request { + send(send-request), + /// history of chat with given node + history(string), + } + + variant response { + send, + history(list), + } + + record send-request { + target: string, + message: string, + } + + record chat-message { + author: string, + content: string, + } +} + +world {package_name_kebab}-{publisher_dotted_kebab}-v0 { + import {package_name_kebab}; + include process-v0; +} diff --git a/src/new/templates/test/chat/{package_name}_test/api/{package_name}_test:{publisher}-v0.wit b/src/new/templates/test/chat/{package_name}_test/api/{package_name}_test:{publisher}-v0.wit new file mode 100644 index 00000000..79c71980 --- /dev/null +++ b/src/new/templates/test/chat/{package_name}_test/api/{package_name}_test:{publisher}-v0.wit @@ -0,0 +1,5 @@ +world {package_name_kebab}-test-{publisher_dotted_kebab}-v0 { + import {package_name_kebab}; + import tester; + include process-v0; +} diff --git a/src/new/templates/test/chat/{package_name}_test/metadata.json b/src/new/templates/test/chat/{package_name}_test/metadata.json new file mode 100644 index 00000000..cea44761 --- /dev/null +++ b/src/new/templates/test/chat/{package_name}_test/metadata.json @@ -0,0 +1,17 @@ +{ + "name": "{package_name} Test", + "description": "A test for {package_name}.", + "image": "", + "properties": { + "package_name": "{package_name}_test", + "current_version": "0.1.0", + "publisher": "{publisher}", + "mirrors": [], + "code_hashes": { + "0.1.0": "" + }, + "wit_version": 0 + }, + "external_url": "", + "animation_url": "" +} diff --git a/src/new/templates/test/chat/{package_name}_test/pkg/manifest.json b/src/new/templates/test/chat/{package_name}_test/pkg/manifest.json new file mode 100644 index 00000000..61ef3388 --- /dev/null +++ b/src/new/templates/test/chat/{package_name}_test/pkg/manifest.json @@ -0,0 +1,13 @@ +[ + { + "process_name": "{package_name}_test", + "process_wasm_path": "/{package_name}_test.wasm", + "on_exit": "Restart", + "request_networking": false, + "request_capabilities": [], + "grant_capabilities": [ + "{package_name}:{package_name}:{publisher}" + ], + "public": true + } +] diff --git a/src/new/templates/test/chat/{package_name}_test/{package_name}_test/Cargo.toml_ b/src/new/templates/test/chat/{package_name}_test/{package_name}_test/Cargo.toml_ new file mode 100644 index 00000000..402919e0 --- /dev/null +++ b/src/new/templates/test/chat/{package_name}_test/{package_name}_test/Cargo.toml_ @@ -0,0 +1,21 @@ +[package] +name = "{package_name}_test" +version = "0.1.0" +edition = "2021" + +[dependencies] +anyhow = "1.0" +bincode = "1.3" +kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "b492f3b" } +process_macros = { git = "https://github.com/kinode-dao/process_macros", rev = "626e501" } +rmp-serde = "1.1" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" +thiserror = "1.0" +wit-bindgen = "0.24.0" + +[lib] +crate-type = ["cdylib"] + +[package.metadata.component] +package = "kinode:process" diff --git a/src/new/templates/test/chat/{package_name}_test/{package_name}_test/src/lib.rs b/src/new/templates/test/chat/{package_name}_test/{package_name}_test/src/lib.rs new file mode 100644 index 00000000..531bba95 --- /dev/null +++ b/src/new/templates/test/chat/{package_name}_test/{package_name}_test/src/lib.rs @@ -0,0 +1,108 @@ +use crate::kinode::process::{package_name}::{ChatMessage, Request as ChatRequest, Response as ChatResponse, SendRequest}; +use crate::kinode::process::tester::{Request as TesterRequest, Response as TesterResponse, RunRequest, FailResponse}; + +use kinode_process_lib::{await_message, call_init, print_to_terminal, println, Address, Message, ProcessId, Request, Response}; + +mod tester_lib; + +wit_bindgen::generate!({ + path: "target/wit", + world: "{package_name_kebab}-test-{publisher_dotted_kebab}-v0", + generate_unused_types: true, + additional_derives: [PartialEq, serde::Deserialize, serde::Serialize, process_macros::SerdeJsonInto], +}); + +fn handle_message (our: &Address) -> anyhow::Result<()> { + let message = await_message().unwrap(); + + match message { + Message::Response { .. } => { unimplemented!() }, + Message::Request { ref source, ref body, .. } => { + if our.node != source.node { + return Err(anyhow::anyhow!( + "rejecting foreign Message from {:?}", + source, + )); + } + match serde_json::from_slice(body)? { + TesterRequest::Run(RunRequest { input_node_names: node_names, .. }) => { + print_to_terminal(0, "{package_name}_test: a"); + assert!(node_names.len() >= 2); + if our.node != node_names[0] { + // we are not master node: return + Response::new() + .body(TesterResponse::Run(Ok(()))) + .send() + .unwrap(); + return Ok(()); + } + + // we are master node + + let our_chat_address = Address { + node: our.node.clone(), + process: ProcessId::new(Some("{package_name}"), "{package_name}", "{publisher}"), + }; + let their_chat_address = Address { + node: node_names[1].clone(), + process: ProcessId::new(Some("{package_name}"), "{package_name}", "{publisher}"), + }; + + // Send + print_to_terminal(0, "{package_name}_test: b"); + let message: String = "hello".into(); + let _ = Request::new() + .target(our_chat_address.clone()) + .body(ChatRequest::Send(SendRequest { + target: node_names[1].clone(), + message: message.clone(), + })) + .send_and_await_response(15)?.unwrap(); + + // Get history from receiver & test + print_to_terminal(0, "{package_name}_test: c"); + let response = Request::new() + .target(their_chat_address.clone()) + .body(ChatRequest::History(our.node.clone())) + .send_and_await_response(15)?.unwrap(); + if response.is_request() { panic!("") }; + let ChatResponse::History(messages) = response.body().try_into()? else { + fail!("{package_name}_test"); + }; + let expected_messages = vec![ChatMessage { + author: our.node.clone(), + content: message, + }]; + + if messages != expected_messages { + println!("{messages:?} != {expected_messages:?}"); + fail!("{package_name}_test"); + } + + Response::new() + .body(TesterResponse::Run(Ok(()))) + .send() + .unwrap(); + }, + } + + Ok(()) + }, + } +} + +call_init!(init); +fn init(our: Address) { + print_to_terminal(0, "begin"); + + loop { + match handle_message(&our) { + Ok(()) => {}, + Err(e) => { + print_to_terminal(0, format!("{package_name}_test: error: {e:?}").as_str()); + + fail!("{package_name}_test"); + }, + }; + } +} diff --git a/src/new/templates/test/chat/{package_name}_test/{package_name}_test/src/tester_lib.rs b/src/new/templates/test/chat/{package_name}_test/{package_name}_test/src/tester_lib.rs new file mode 100644 index 00000000..9b367d36 --- /dev/null +++ b/src/new/templates/test/chat/{package_name}_test/{package_name}_test/src/tester_lib.rs @@ -0,0 +1,31 @@ +use crate::kinode::process::tester::{ + Response as TesterResponse, FailResponse, +}; + +#[macro_export] +macro_rules! fail { + ($test:expr) => { + Response::new() + .body(TesterResponse::Run(Err(FailResponse { + test: $test.into(), + file: file!().into(), + line: line!(), + column: column!(), + }))) + .send() + .unwrap(); + panic!("") + }; + ($test:expr, $file:expr, $line:expr, $column:expr) => { + Response::new() + .body(TesterResponse::Run(Err(FailResponse { + test: $test.into(), + file: $file.into(), + line: $line, + column: $column, + }))) + .send() + .unwrap(); + panic!("") + }; +} diff --git a/src/run_tests/mod.rs b/src/run_tests/mod.rs index 4cde1f1a..34a260e3 100644 --- a/src/run_tests/mod.rs +++ b/src/run_tests/mod.rs @@ -289,12 +289,35 @@ async fn run_tests( } #[instrument(level = "trace", skip_all)] -async fn handle_test(detached: bool, runtime_path: &Path, test: Test) -> Result<()> { - for setup_package_path in &test.setup_package_paths { - build::execute(&setup_package_path, false, false, false, "", None, None).await?; // TODO +async fn handle_test( + detached: bool, + runtime_path: &Path, + test: Test, + test_dir_path: &Path, +) -> Result<()> { + let setup_package_paths: Vec = test.setup_package_paths + .iter() + .cloned() + .map(|p| test_dir_path.join(p).canonicalize().unwrap()) + .collect(); + let test_packages: Vec = test.test_packages + .iter() + .cloned() + .map(|tp| { + TestPackage { + path: test_dir_path.join(tp.path).canonicalize().unwrap(), + grant_capabilities: tp.grant_capabilities, + } + }) + .collect(); + //for setup_package_path in &test.setup_package_paths { + // let path = test_dir_path.join(setup_package_path).canonicalize()?; + for path in &setup_package_paths { + build::execute(&path, false, false, false, "", None, None).await?; // TODO } - for TestPackage { ref path, .. } in &test.test_packages { - build::execute(path, false, false, false, "", None, None).await?; // TODO + for TestPackage { ref path, .. } in &test_packages { + let path = test_dir_path.join(path).canonicalize()?; + build::execute(&path, false, false, false, "", None, None).await?; // TODO } // Initialize variables for master node and nodes list @@ -405,10 +428,10 @@ async fn handle_test(detached: bool, runtime_path: &Path, test: Test) -> Result< } for node in &test.nodes { - load_setups(&test.setup_package_paths, node.port.clone()).await?; + load_setups(&setup_package_paths, node.port.clone()).await?; } - load_tests(&test.test_packages, master_node_port.unwrap().clone()).await?; + load_tests(&test_packages, master_node_port.unwrap().clone()).await?; let ports = test.nodes.iter().map(|n| n.port).collect(); @@ -462,8 +485,10 @@ pub async fn execute(config_path: &str) -> Result<()> { }, }; + let test_dir_path = PathBuf::from(config_path).canonicalize()?; + let test_dir_path = test_dir_path.parent().unwrap(); for test in config.tests { - handle_test(detached, &runtime_path, test).await?; + handle_test(detached, &runtime_path, test, &test_dir_path).await?; } Ok(()) diff --git a/src/run_tests/tester_types.rs b/src/run_tests/tester_types.rs deleted file mode 100644 index 73c8c3c7..00000000 --- a/src/run_tests/tester_types.rs +++ /dev/null @@ -1,91 +0,0 @@ -use serde::{Deserialize, Serialize}; - -use kinode_process_lib::kernel_types as kt; -use kinode_process_lib::Address; - -type Rsvp = Option
; - -#[derive(Clone, Debug, Serialize, Deserialize)] -pub struct KernelMessage { - pub id: u64, - pub source: Address, - pub target: Address, - pub rsvp: Rsvp, - pub message: kt::Message, - pub lazy_load_blob: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum TesterRequest { - Run { - input_node_names: Vec, - test_names: Vec, - test_timeout: u64, - }, - KernelMessage(KernelMessage), - GetFullMessage(kt::Message), -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct TesterFail { - pub test: String, - pub file: String, - pub line: u32, - pub column: u32, -} - -#[derive(Debug, Serialize, Deserialize)] -pub enum TesterResponse { - Pass, - Fail { - test: String, - file: String, - line: u32, - column: u32, - }, - GetFullMessage(Option), -} - -#[derive(Debug, Serialize, Deserialize, thiserror::Error)] -pub enum TesterError { - #[error("RejectForeign")] - RejectForeign, - #[error("UnexpectedResponse")] - UnexpectedResponse, - #[error("FAIL {test} {message}")] - Fail { test: String, message: String }, -} - -#[macro_export] -macro_rules! fail { - ($test:expr) => { - Response::new() - .body( - serde_json::to_vec(&tt::TesterResponse::Fail { - test: $test.into(), - file: file!().into(), - line: line!(), - column: column!(), - }) - .unwrap(), - ) - .send() - .unwrap(); - panic!("") - }; - ($test:expr, $file:expr, $line:expr, $column:expr) => { - Response::new() - .body( - serde_json::to_vec(&tt::TesterResponse::Fail { - test: $test.into(), - file: $file.into(), - line: $line, - column: $column, - }) - .unwrap(), - ) - .send() - .unwrap(); - panic!("") - }; -}