Skip to content
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

Extract e2e testing framework to its own crate #1429

Merged
merged 12 commits into from
Oct 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ examples-contract-build:
<<: *test-refs
script:
- rustup component add rust-src --toolchain stable
- cargo install cargo-contract --git https://github.com/paritytech/cargo-contract --version 2.0.0-alpha.3 --force
- cargo install cargo-contract --git https://github.com/paritytech/cargo-contract --version 2.0.0-alpha.4 --force
- cargo contract -V
- for example in examples/*/; do
if [ "$example" = "examples/upgradeable-contracts/" ]; then continue; fi;
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ members = [
"crates/ink/macro",
"crates/prelude",
"crates/primitives",
"crates/e2e",
"crates/e2e/macro",
"crates/engine",
"crates/env",
"crates/storage",
Expand Down
44 changes: 44 additions & 0 deletions crates/e2e/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
[package]
name = "ink_e2e"
version = "4.0.0-alpha.3"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"

license = "Apache-2.0"
readme = "README.md"
repository = "https://github.com/paritytech/ink"
documentation = "https://docs.rs/ink_e2e/"
homepage = "https://www.parity.io/"
description = "[ink!] End-to-end testing framework for smart contracts."
keywords = ["wasm", "parity", "webassembly", "blockchain", "edsl"]
categories = ["no-std", "embedded"]
include = ["/Cargo.toml", "src/**/*.rs", "/README.md", "/LICENSE"]

[dependencies]
ink_e2e_macro = { version = "4.0.0-alpha.3", path = "./macro" }
ink_env = { version = "4.0.0-alpha.3", path = "../env" }

contract-metadata = { version = "2.0.0-alpha.2" }
impl-serde = { version = "0.3.1", default-features = false }
jsonrpsee = { version = "0.15.1", features = ["ws-client"] }
pallet-contracts-primitives = { version = "6.0.0" }
serde = { version = "1.0.137", default-features = false, features = ["derive"] }
serde_json = { version = "1.0.81" }
tokio = { version = "1.18.2", features = ["rt-multi-thread"] }
log = { version = "0.4" }
env_logger = { version = "0.9" }
scale = { package = "parity-scale-codec", version = "3", default-features = false, features = ["derive", "full"] }
subxt = { version = "0.24.0" }

# Substrate
sp-rpc = { version = "6.0.0" }
sp-core = { version = "6.0.0" }
sp-keyring = { version = "6.0.0" }
sp-runtime = { version = "6.0.0" }

# TODO(#1421) `smart-bench_macro` needs to be forked.
smart-bench-macro = { git = "https://github.com/paritytech/smart-bench", branch = "aj-ink-e2e-test-mvp", package = "smart-bench-macro" }

[features]
default = ["std"]
std = []
1 change: 1 addition & 0 deletions crates/e2e/LICENSE
1 change: 1 addition & 0 deletions crates/e2e/README.md
29 changes: 29 additions & 0 deletions crates/e2e/macro/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "ink_e2e_macro"
version = "4.0.0-alpha.3"
authors = ["Parity Technologies <admin@parity.io>"]
edition = "2021"

license = "Apache-2.0"
readme = "README.md"
repository = "https://github.com/paritytech/ink"
documentation = "https://docs.rs/ink_macro/"
homepage = "https://www.parity.io/"
description = "[ink!] Macro for generating end-to-end tests"
keywords = ["wasm", "parity", "webassembly", "blockchain", "edsl"]
categories = ["no-std", "embedded"]
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"]

[lib]
name = "ink_e2e_macro"
proc-macro = true

[dependencies]
ink_ir = { version = "4.0.0-alpha.3", path = "../../ink/ir" }
derive_more = "0.99.17"
env_logger = "0.9.1"
log = "0.4.17"
serde_json = "1.0.85"
syn = "1"
proc-macro2 = "1"
quote = "1"
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::GenerateCode;
use crate::ir;
use core::cell::RefCell;
use derive_more::From;
use proc_macro2::TokenStream as TokenStream2;
Expand All @@ -38,14 +38,14 @@ pub fn contract_path() -> Option<PathBuf> {

/// Generates code for the `[ink::e2e_test]` macro.
#[derive(From)]
pub struct InkE2ETest<'a> {
pub struct InkE2ETest {
/// The test function to generate code for.
test: &'a ir::InkE2ETest,
test: ir::InkE2ETest,
}

impl GenerateCode for InkE2ETest<'_> {
impl InkE2ETest {
/// Generates the code for `#[ink:e2e_test]`.
fn generate_code(&self) -> TokenStream2 {
pub fn generate_code(&self) -> TokenStream2 {
#[cfg(clippy)]
if true {
return quote! {}
Expand Down Expand Up @@ -147,42 +147,46 @@ impl GenerateCode for InkE2ETest<'_> {

quote! {
#( #attrs )*
#[ink::env::e2e::tokio::test]
async #vis fn #fn_name () #ret {
use ink::env::e2e::log_info;
ink::env::e2e::LOG_PREFIX.with(|log_prefix| {
#[test]
#vis fn #fn_name () #ret {
use ::ink_e2e::log_info;
::ink_e2e::LOG_PREFIX.with(|log_prefix| {
let str = format!("test: {}", stringify!(#fn_name));
*log_prefix.borrow_mut() = String::from(str);
});
log_info("setting up e2e test");

ink::env::e2e::INIT.call_once(|| {
ink::env::e2e::env_logger::init();
::ink_e2e::INIT.call_once(|| {
::ink_e2e::env_logger::init();
});

log_info("extracting metadata");
// TODO(#1421) `smart-bench_macro` needs to be forked.
ink::env::e2e::smart_bench_macro::contract!(#path);
::ink_e2e::smart_bench_macro::contract!(#path);

log_info("creating new client");

// TODO(#xxx) Make those two generic environments customizable.
let mut client = ink::env::e2e::Client::<
ink::env::e2e::PolkadotConfig,
ink::env::DefaultEnvironment
>::new(&#path, &#ws_url, &#node_log).await;

let __ret = {
#block
let run = async {
// TODO(#xxx) Make those two generic environments customizable.
let mut client = ::ink_e2e::Client::<
::ink_e2e::PolkadotConfig,
ink::env::DefaultEnvironment
>::new(&#path, &#ws_url, &#node_log).await;

let __ret = {
#block
};
__ret
};
__ret

{
return ::ink_e2e::tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.expect("Failed building the Runtime")
.block_on(run);
}
}
}
}
}

impl GenerateCode for ir::InkE2ETest {
fn generate_code(&self) -> TokenStream2 {
InkE2ETest::from(self).generate_code()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::{
use ink_ir::{
ast,
format_err_spanned,
utils::{
duplicate_config_err,
WhitelistedAttributes,
Expand Down Expand Up @@ -121,11 +122,6 @@ impl E2EConfig {
let default_skip_build = syn::LitBool::new(false, proc_macro2::Span::call_site());
self.skip_build.clone().unwrap_or(default_skip_build)
}

/// Return set of attributes that can be passed to call builder in the codegen.
pub fn whitelisted_attributes(&self) -> &WhitelistedAttributes {
&self.whitelisted_attributes
}
}

/// The environmental types definition.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
// limitations under the License.

use crate::{
ast,
config::E2EConfig,
ir,
ir::idents_lint,
};
use proc_macro2::TokenStream as TokenStream2;

Expand All @@ -24,32 +23,24 @@ pub struct InkE2ETest {
/// The function which was annotated.
pub item_fn: E2EFn,
/// The specified configuration.
pub config: ir::E2EConfig,
pub config: E2EConfig,
}

/// The End-to-End test with all required information.
#[derive(derive_more::From)]
pub struct E2EFn {
/// The function which was annotated.
pub item_fn: syn::ItemFn,
}

impl TryFrom<syn::ItemFn> for E2EFn {
type Error = syn::Error;

fn try_from(item_fn: syn::ItemFn) -> Result<E2EFn, Self::Error> {
idents_lint::ensure_no_ink_identifiers(&item_fn)?;
Ok(E2EFn { item_fn })
}
}

impl InkE2ETest {
/// Returns `Ok` if the test matches all requirements for an
/// ink! E2E test definition.
pub fn new(attrs: TokenStream2, input: TokenStream2) -> Result<Self, syn::Error> {
let config = syn::parse2::<ast::AttributeArgs>(attrs)?;
let config = syn::parse2::<ink_ir::ast::AttributeArgs>(attrs)?;
let e2e_config = ir::E2EConfig::try_from(config)?;
let item_fn = syn::parse2::<syn::ItemFn>(input)?;
let e2e_fn = E2EFn::try_from(item_fn)?;
let e2e_fn = E2EFn::from(item_fn);
Ok(Self {
item_fn: e2e_fn,
config: e2e_config,
Expand Down
Loading