-
Notifications
You must be signed in to change notification settings - Fork 244
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
testing: Prepare light client testing with substrate binary and add subxt-test macro #1507
Changes from 39 commits
34e9222
518aa8e
ea6f3cc
ca36ef6
8fe7e86
593fbeb
1fc1bb4
ca60c31
3c58c5e
0248343
8400a0e
d671664
318ba5c
1a6f1af
332fa72
88ccc54
b6c98c7
20e75bc
c5c7972
d3923c8
1a64750
4c3226e
fbe2a74
30073d3
aa55cea
09277fe
5039f1c
410aaed
d81c70c
00c4b78
03da904
292f971
2bc8947
811f70c
2bb8acb
1fdd734
1bc6eb9
5692703
fd47be1
be4b34c
7270da8
a62ceb7
7664b56
510578f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
use cfg_aliases::cfg_aliases; | ||
|
||
fn main() { | ||
// Setup cfg aliases | ||
cfg_aliases! { | ||
lightclient: { any(feature = "unstable-light-client", feature = "unstable-light-client-long-running") }, | ||
fullclient: { all(not(feature = "unstable-light-client"), not(feature = "unstable-light-client-long-running")) }, | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
[package] | ||
name = "subxt-test-proc-macro" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: also rename the folder to |
||
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 } | ||
quote = { workspace = true } |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// 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, | ||
}; | ||
|
||
/// Environment variable for setting the timeout for the test. | ||
const SUBXT_TEST_TIMEOUT: &str = "SUBXT_TEST_TIMEOUT"; | ||
|
||
/// Default timeout for the test. | ||
const DEFAULT_TIMEOUT: u64 = 60 * 6; | ||
|
||
#[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(), | ||
}; | ||
|
||
// Timeout is determined by: | ||
// - The timeout attribute if it is set. | ||
// - The SUBXT_TEST_TIMEOUT environment variable if it is set. | ||
// - A default of 6 minutes. | ||
let timeout_duration = subxt_attr.timeout.unwrap_or_else(|| { | ||
std::env::var(SUBXT_TEST_TIMEOUT) | ||
.map(|str| str.parse().unwrap_or(DEFAULT_TIMEOUT)) | ||
.unwrap_or(DEFAULT_TIMEOUT) | ||
}); | ||
|
||
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 mut inner_func_sig = func.sig.clone(); | ||
inner_func_sig.ident = format_ident!("{}_inner", inner_func_sig.ident); | ||
let inner_func_name = &inner_func_sig.ident; | ||
|
||
let result = quote! { | ||
#[tokio::test] | ||
#( #func_attrs )* | ||
#func_vis #func_sig { | ||
#func_vis #inner_func_sig | ||
#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), | ||
}) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,17 +2,27 @@ | |
// This file is dual-licensed as Apache-2.0 or GPL-3.0. | ||
// see LICENSE for license details. | ||
|
||
use crate::{test_context, utils::node_runtime}; | ||
use crate::{subxt_test, test_context}; | ||
use codec::{Compact, Encode}; | ||
use futures::StreamExt; | ||
|
||
#[cfg(fullclient)] | ||
use crate::utils::node_runtime; | ||
#[cfg(fullclient)] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is it possible to merge the use stuff to avoid repeating |
||
use subxt::config::signed_extensions::{ChargeAssetTxPayment, CheckMortality, CheckNonce}; | ||
#[cfg(fullclient)] | ||
use subxt::config::DefaultExtrinsicParamsBuilder; | ||
#[cfg(fullclient)] | ||
use subxt::config::SubstrateConfig; | ||
#[cfg(fullclient)] | ||
use subxt::utils::Era; | ||
use subxt_metadata::Metadata; | ||
#[cfg(fullclient)] | ||
use subxt_signer::sr25519::dev; | ||
|
||
#[tokio::test] | ||
use subxt_metadata::Metadata; | ||
|
||
#[cfg(fullclient)] | ||
#[subxt_test] | ||
async fn block_subscriptions_are_consistent_with_eachother() -> Result<(), subxt::Error> { | ||
let ctx = test_context().await; | ||
let api = ctx.client(); | ||
|
@@ -76,7 +86,7 @@ async fn block_subscriptions_are_consistent_with_eachother() -> Result<(), subxt | |
Ok(()) | ||
} | ||
|
||
#[tokio::test] | ||
#[subxt_test] | ||
async fn finalized_headers_subscription() -> Result<(), subxt::Error> { | ||
let ctx = test_context().await; | ||
let api = ctx.client(); | ||
|
@@ -93,7 +103,7 @@ async fn finalized_headers_subscription() -> Result<(), subxt::Error> { | |
Ok(()) | ||
} | ||
|
||
#[tokio::test] | ||
#[subxt_test] | ||
async fn missing_block_headers_will_be_filled_in() -> Result<(), subxt::Error> { | ||
use subxt::backend::legacy; | ||
|
||
|
@@ -138,7 +148,7 @@ async fn missing_block_headers_will_be_filled_in() -> Result<(), subxt::Error> { | |
} | ||
|
||
// Check that we can subscribe to non-finalized blocks. | ||
#[tokio::test] | ||
#[subxt_test] | ||
async fn runtime_api_call() -> Result<(), subxt::Error> { | ||
let ctx = test_context().await; | ||
let api = ctx.client(); | ||
|
@@ -163,7 +173,8 @@ async fn runtime_api_call() -> Result<(), subxt::Error> { | |
Ok(()) | ||
} | ||
|
||
#[tokio::test] | ||
#[cfg(fullclient)] | ||
#[subxt_test] | ||
async fn fetch_block_and_decode_extrinsic_details() { | ||
let ctx = test_context().await; | ||
let api = ctx.client(); | ||
|
@@ -232,7 +243,8 @@ async fn fetch_block_and_decode_extrinsic_details() { | |
assert!(tx.is_signed()); | ||
} | ||
|
||
#[tokio::test] | ||
#[cfg(fullclient)] | ||
#[subxt_test] | ||
async fn decode_signed_extensions_from_blocks() { | ||
let ctx = test_context().await; | ||
let api = ctx.client(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
slightly weird comment; we could actually throw an error if both
finalized_block_hash
andfinalized_block_hashes
.now, we checking
finalized_block_hashes
first and if that doesn't exist we fallback tofinalized_block_hash
which is probably fine but if one inserts both by accident it lead to confusing scenarios but fine :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know this only exists until we update smoldot :)