Skip to content

Commit

Permalink
Add macro for generating runtime tests automatically
Browse files Browse the repository at this point in the history
Signed-off-by: Ryan Levick <[email protected]>
  • Loading branch information
rylev committed Dec 21, 2023
1 parent 0e291d1 commit 841e11e
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 39 deletions.
9 changes: 9 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 2 additions & 6 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ e2e-testing = { path = "crates/e2e-testing" }
http-body-util = { workspace = true }
runtime-tests = { path = "tests/runtime-tests" }
test-components = { path = "tests/test-components" }
test-codegen-macro = { path = "crates/test-codegen-macro" }

[build-dependencies]
cargo-target-dep = { git = "https://github.com/fermyon/cargo-target-dep", rev = "482f269eceb7b1a7e8fc618bf8c082dd24979cf1" }
Expand All @@ -113,12 +114,7 @@ llm-metal = ["llm", "spin-trigger-http/llm-metal"]
llm-cublas = ["llm", "spin-trigger-http/llm-cublas"]

[workspace]
members = [
"crates/*",
"sdk/rust",
"sdk/rust/macro",
"tests/runtime-tests",
]
members = ["crates/*", "sdk/rust", "sdk/rust/macro", "tests/runtime-tests"]

[workspace.dependencies]
anyhow = "1.0.75"
Expand Down
14 changes: 14 additions & 0 deletions crates/test-codegen-macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "test-codegen-macro"
version = "0.0.0"
edition.workspace = true
publish = false

[lib]
proc-macro = true
doctest = false
test = false

[dependencies]
heck = "0.4.0"
quote = "1.0.32"
3 changes: 3 additions & 0 deletions crates/test-codegen-macro/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Test Codegen Macro

A macro for automatically producing `#[test]` annotated functions based on file directory structure. This is used by the runtime tests so that when adding a runtime test, you're not required to also add a test function corresponding to that runtime test.
42 changes: 42 additions & 0 deletions crates/test-codegen-macro/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use heck::*;
use proc_macro::TokenStream;
use std::{env, path::PathBuf};

/// This macro generates the `#[test]` functions for the runtime tests.
#[proc_macro]
pub fn codegen_tests(_input: TokenStream) -> TokenStream {
let mut tests = Vec::new();
let tests_path =
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../tests/runtime-tests/tests");
for entry in std::fs::read_dir(tests_path).expect("failed to read tests directory") {
let entry = entry.expect("error reading test directory entry");
let test = entry.path();

if entry.file_type().unwrap().is_dir() {
let requires_services = entry.path().join("services").exists();

let name = test.file_stem().unwrap().to_str().unwrap();
let ident = quote::format_ident!("{}", name.to_snake_case());
let feature_attribute = if requires_services {
quote::quote!(#[cfg(feature = "e2e-tests")])
} else {
quote::quote!()
};
// Generate the following code:
// ```rust
// #[test]
// fn outbound_mysql() {
// run("outbound-mysql")
// }
// ```
tests.push(quote::quote! {
#[test]
#feature_attribute
fn #ident() {
run(#name)
}
});
}
}
(quote::quote!(#(#tests)*)).into()
}
37 changes: 4 additions & 33 deletions tests/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,11 @@
#[cfg(feature = "e2e-tests")]
/// Run the tests found in `tests/runtime-tests` directory.
mod runtime_tests {
use runtime_tests::Config;
use std::path::PathBuf;

// TODO: write a proc macro that reads from the tests folder
// and creates tests for every subdirectory
macro_rules! test {
($ident:ident, $path:literal) => {
#[test]
fn $ident() {
run($path)
}
};
}

test!(outbound_mysql, "outbound-mysql");
test!(outbound_mysql_no_permission, "outbound-mysql-no-permission");
test!(outbound_postgres, "outbound-postgres");
test!(
outbound_postgres_no_permission,
"outbound-postgres-no-permission"
);
test!(outbound_redis, "outbound-redis");
test!(outbound_redis_no_permission, "outbound-redis-no-permission");
test!(sqlite, "sqlite");
test!(sqlite_no_permission, "sqlite-no-permission");
test!(key_value, "key-value");
test!(key_value_no_permission, "key-value-no-permission");
test!(variables, "variables");
test!(tcp_sockets, "tcp-sockets");
test!(tcp_sockets_ip_range, "tcp-sockets-ip-range");
test!(
tcp_sockets_no_port_permission,
"tcp-sockets-no-port-permission"
);
test!(tcp_sockets_no_ip_permission, "tcp-sockets-no-ip-permission");
// The macro inspects the tests directory and
// generates individual tests for each one.
test_codegen_macro::codegen_tests!();

fn run(name: &str) {
let spin_binary_path = env!("CARGO_BIN_EXE_spin").into();
Expand Down

0 comments on commit 841e11e

Please sign in to comment.