proc-macro: Timeout for tests

Signed-off-by: Alexandru Vasile <alexandru.vasile@parity.io>
This commit is contained in:
Alexandru Vasile
2024-03-01 20:20:14 +02:00
parent 88ccc54339
commit b6c98c7fa0
6 changed files with 124 additions and 0 deletions
Generated
+10
View File
@@ -2266,6 +2266,7 @@ dependencies = [
"frame-metadata 16.0.0",
"futures",
"hex",
"integration-tests-proc-macro",
"parity-scale-codec",
"regex",
"scale-info",
@@ -2284,6 +2285,15 @@ dependencies = [
"wabt",
]
[[package]]
name = "integration-tests-proc-macro"
version = "0.34.0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.48",
]
[[package]]
name = "io-lifetimes"
version = "1.0.11"
+1
View File
@@ -6,6 +6,7 @@ members = [
"testing/substrate-runner",
"testing/test-runtime",
"testing/integration-tests",
"testing/integration-tests/proc-macro",
"testing/ui-tests",
"testing/generate-custom-metadata",
"macro",
+1
View File
@@ -46,6 +46,7 @@ tracing = { workspace = true }
tracing-subscriber = { workspace = true }
wabt = { workspace = true }
substrate-runner = { workspace = true }
integration-tests-proc-macro = { path = "proc-macro" }
[build-dependencies]
cfg_aliases = "0.2.0"
@@ -0,0 +1,21 @@
[package]
name = "integration-tests-proc-macro"
version.workspace = true
authors.workspace = true
edition.workspace = true
rust-version.workspace = true
publish = false
license.workspace = true
repository.workspace = true
documentation.workspace = true
homepage.workspace = true
description = "Subxt integration tests proc-macros"
[lib]
proc-macro = true
[dependencies]
syn = { workspace = true }
proc-macro2 = { workspace = true }
quote = { workspace = true }
@@ -0,0 +1,80 @@
// Copyright 2019-2023 Parity Technologies (UK) Ltd.
// This file is dual-licensed as Apache-2.0 or GPL-3.0.
// see LICENSE for license details.
extern crate proc_macro;
use proc_macro::TokenStream;
use quote::{format_ident, quote};
use syn::{
parse::{Parse, ParseStream},
Error,
};
#[proc_macro_attribute]
pub fn subxt_test(attr: TokenStream, item: TokenStream) -> TokenStream {
let subxt_attr = match syn::parse::<SubxtTestAttr>(attr) {
Ok(subxt_attr) => subxt_attr,
Err(err) => return err.into_compile_error().into(),
};
let timeout_duration = subxt_attr.timeout.unwrap_or(60 * 5);
let func: syn::ItemFn = match syn::parse(item) {
Ok(func) => func,
Err(err) => return err.into_compile_error().into(),
};
let func_attrs = &func.attrs;
let func_vis = &func.vis;
let func_sig = &func.sig;
let func_block = &func.block;
let func_output = &func.sig.output;
let func_name = &func.sig.ident;
let inner_func_name = format_ident!("{}_inner", func_name);
let result = quote! {
#[tokio::test]
#( #func_attrs )*
#func_vis #func_sig #func_output {
async fn #inner_func_name() #func_output
#func_block
tokio::time::timeout(std::time::Duration::from_secs(#timeout_duration), #inner_func_name())
.await
.expect("Test timedout");
}
};
result.into()
}
mod keywords {
syn::custom_keyword!(timeout);
}
struct SubxtTestAttr {
timeout: Option<u64>,
}
impl Parse for SubxtTestAttr {
fn parse(input: ParseStream) -> Result<Self, Error> {
if input.is_empty() {
return Ok(Self { timeout: None });
}
let _keyword = input.parse::<keywords::timeout>()?;
input.parse::<syn::token::Eq>()?;
let timeout = input.parse::<syn::LitInt>()?.base10_parse::<u64>()?;
if !input.is_empty() {
return Err(Error::new(
input.span(),
"Expected tokens: `timeout = value`",
));
}
Ok(Self {
timeout: Some(timeout),
})
}
}
@@ -11,3 +11,14 @@ pub use context::*;
pub use node_proc::TestNodeProcess;
pub use tx_retries::*;
pub use wait_for_blocks::*;
pub use integration_tests_proc_macro::subxt_test;
/// The test timeout is set to 1 second.
/// However, the test is sleeping for 5 seconds.
/// This must cause the test to panic.
#[subxt_test(timeout = 1)]
#[should_panic]
async fn test_subxt_macro() {
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
}