Merge pull request #32 from fluencelabs/fixup_branch

Allow fce_test to work with relative paths
This commit is contained in:
vms 2021-05-06 11:42:35 +03:00 committed by GitHub
commit 18c0a39efe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 75 additions and 21 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "fluence-sdk-test-macro-impl"
version = "0.1.3" # remember to update html_root_url
version = "0.1.4" # remember to update html_root_url
edition = "2018"
description = "Implementation of the `#[fce_test]` macro"
repository = "https://github.com/fluencelabs/rust-sdk/crates/macro-test"
@ -18,7 +18,7 @@ fce-wit-parser = "0.5.0"
darling = "0.12.2"
quote = "1.0.9"
proc-macro2 = "1.0.24"
proc-macro2 = "1.0.26"
proc-macro-error = { version = "1.0.4", default-features = false }
syn = { version = '1.0.64', features = ['full'] }
thiserror = "1.0.24"

View File

@ -21,6 +21,8 @@ use darling::Error as DarlingError;
use syn::Error as SynError;
use thiserror::Error as ThisError;
use std::path::PathBuf;
#[derive(Debug, ThisError)]
pub enum TestGeneratorError {
#[error("Can't load Wasm modules into FCE: {0}")]
@ -45,6 +47,9 @@ pub enum TestGeneratorError {
#[error("a Wasm file compiled with newer version of sdk that supports multi-value")]
ManyFnOutputsUnsupported,
#[error("{0} is invalid UTF8 path")]
InvalidUTF8Path(PathBuf),
}
#[derive(Debug, ThisError)]

View File

@ -21,8 +21,13 @@ use crate::fce_test::glue_code_generator::generate_test_glue_code;
use proc_macro2::TokenStream;
use darling::FromMeta;
use syn::parse::Parser;
use std::path::PathBuf;
pub fn fce_test_impl(attrs: TokenStream, input: TokenStream) -> TResult<TokenStream> {
pub fn fce_test_impl(
attrs: TokenStream,
input: TokenStream,
file_path: PathBuf,
) -> TResult<TokenStream> {
// from https://github.com/dtolnay/syn/issues/788
let parser = syn::punctuated::Punctuated::<syn::NestedMeta, syn::Token![,]>::parse_terminated;
let attrs = parser.parse2(attrs)?;
@ -31,5 +36,5 @@ pub fn fce_test_impl(attrs: TokenStream, input: TokenStream) -> TResult<TokenStr
let func_item = syn::parse2::<syn::ItemFn>(input)?;
generate_test_glue_code(func_item, attrs)
generate_test_glue_code(func_item, attrs, file_path)
}

View File

@ -23,9 +23,9 @@ use crate::fce_test::config_utils;
use fluence_app_service::TomlAppServiceConfig;
use proc_macro2::TokenStream;
use quote::quote;
use quote::ToTokens;
use std::path::Path;
use std::path::PathBuf;
/// Generates glue code for tests.
/// F.e. for this test for the greeting service
@ -114,14 +114,18 @@ use std::path::Path;
pub(super) fn generate_test_glue_code(
func_item: syn::ItemFn,
attrs: FCETestAttributes,
file_path: PathBuf,
) -> TResult<TokenStream> {
let fce_config = TomlAppServiceConfig::load(&attrs.config_path)?;
let config_path = file_path.join(&attrs.config_path);
let fce_config = TomlAppServiceConfig::load(&config_path)?;
let modules_dir = match config_utils::resolve_modules_dir(&fce_config, attrs.modules_dir) {
Some(modules_dir) => modules_dir,
None => return Err(TestGeneratorError::ModulesDirUnspecified),
};
let app_service_ctor = generate_app_service_ctor(&attrs.config_path, &modules_dir);
let app_service_ctor = generate_app_service_ctor(&attrs.config_path, &modules_dir)?;
let modules_dir = file_path.join(modules_dir);
let module_interfaces = fce_test::config_utils::collect_modules(&fce_config, modules_dir)?;
let module_definitions =
@ -153,11 +157,12 @@ pub(super) fn generate_test_glue_code(
Ok(glue_code)
}
fn generate_app_service_ctor(config_path: &str, modules_dir: &Path) -> TokenStream {
let config_path = config_path.to_token_stream();
let modules_dir = modules_dir.to_string_lossy().to_string();
fn generate_app_service_ctor(config_path: &str, modules_dir: &Path) -> TResult<TokenStream> {
let modules_dir = modules_dir
.to_str()
.ok_or_else(|| TestGeneratorError::InvalidUTF8Path(modules_dir.to_path_buf()))?;
quote! {
let service_ctor = quote! {
let tmp_dir = std::env::temp_dir();
let service_id = fluence_test::internal::Uuid::new_v4().to_string();
@ -165,16 +170,51 @@ fn generate_app_service_ctor(config_path: &str, modules_dir: &Path) -> TokenStre
let tmp_dir = tmp_dir.to_string_lossy().to_string();
std::fs::create_dir(&tmp_dir).expect("can't create a directory for service in tmp");
let mut __fce_generated_fce_config = fluence_test::internal::TomlAppServiceConfig::load(#config_path.to_string())
.unwrap_or_else(|e| panic!("app service located at `{}` config can't be loaded: {}", #config_path, e));
let mut module_path = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let mut file_path = std::path::Path::new(file!()).components();
let mut truncated_file_path = Vec::new();
loop {
if module_path.ends_with(file_path.as_path()) {
break;
}
let (file_path_, remainder) = match file_path.next_back().and_then(|p| match p {
std::path::Component::Normal(_) | std::path::Component::CurDir | std::path::Component::ParentDir => {
Some((file_path, p))
}
_ => None,
}) {
Some(t) => t,
None => break,
};
file_path = file_path_;
truncated_file_path.push(remainder);
}
for path in truncated_file_path.iter().rev() {
module_path.push(path);
}
let _ = module_path.pop();
let config_path = module_path.join(#config_path);
let modules_dir = module_path.join(#modules_dir);
let modules_dir = modules_dir.to_str().expect("modules_dir contains invalid UTF8 string");
let mut __fce_generated_fce_config = fluence_test::internal::TomlAppServiceConfig::load(&config_path)
.unwrap_or_else(|e| panic!("app service config located at `{:?}` can't be loaded: {}", config_path, e));
__fce_generated_fce_config.service_base_dir = Some(tmp_dir);
__fce_generated_fce_config.toml_faas_config.modules_dir = Some(#modules_dir.to_string());
__fce_generated_fce_config.toml_faas_config.modules_dir = Some(modules_dir.to_string());
let fce = fluence_test::internal::AppService::new_with_empty_facade(__fce_generated_fce_config, service_id, std::collections::HashMap::new())
.unwrap_or_else(|e| panic!("app service can't be created: {}", e));
let fce = std::rc::Rc::new(std::cell::RefCell::new(fce));
}
};
Ok(service_ctor)
}
fn generate_module_ctors<'n>(

View File

@ -1,6 +1,6 @@
[package]
name = "fluence-sdk-test-macro"
version = "0.1.3" # remember to update html_root_url
version = "0.1.4" # remember to update html_root_url
edition = "2018"
description = "Definition of the `#[fce_test]` macro"
repository = "https://github.com/fluencelabs/rust-sdk/crates/macro-test"
@ -17,7 +17,7 @@ proc-macro = true
doctest = false
[dependencies]
fluence-sdk-test-macro-impl = { path = "../fce-test-macro-impl", version = "0.1.3" }
fluence-sdk-test-macro-impl = { path = "../fce-test-macro-impl", version = "0.1.4" }
quote = "1.0.9"
proc-macro2 = "1.0.24"

View File

@ -14,7 +14,7 @@
* limitations under the License.
*/
#![doc(html_root_url = "https://docs.rs/fluence-sdk-macro/0.5.0")]
#![doc(html_root_url = "https://docs.rs/fluence-test-macro/0.1.4")]
#![deny(
dead_code,
nonstandard_style,
@ -24,6 +24,7 @@
unused_unsafe,
unreachable_patterns
)]
#![feature(proc_macro_span)]
#![warn(rust_2018_idioms)]
#![recursion_limit = "1024"]
@ -45,8 +46,11 @@ use syn::spanned::Spanned;
pub fn fce_test(attrs: TokenStream, input: TokenStream) -> TokenStream {
let attrs: proc_macro2::TokenStream = attrs.into();
let attrs_span = attrs.span();
// here it obtains a path to the current file where macro is applied
let mut file_path = proc_macro::Span::call_site().source_file().path();
let _ = file_path.pop();
match fce_test_impl(attrs, input.into()) {
match fce_test_impl(attrs, input.into(), file_path) {
Ok(stream) => stream.into(),
Err(e) => proc_macro_error::abort!(attrs_span, format!("{}", e)),
}

View File

@ -1,6 +1,6 @@
[package]
name = "fluence-test"
version = "0.1.3" # remember to update html_root_url
version = "0.1.4" # remember to update html_root_url
description = "Fluence backend SDK for testing"
documentation = "https://docs.rs/fluence/"
repository = "https://github.com/fluencelabs/rust-sdk"
@ -19,7 +19,7 @@ path = "src/lib.rs"
doctest = false
[dependencies]
fluence-sdk-test-macro = { path = "../crates/fce-test-macro", version = "0.1.3" }
fluence-sdk-test-macro = { path = "../crates/fce-test-macro", version = "0.1.4" }
fluence-app-service = { version = "0.7.0", features = ["raw-module-api"] }
serde = { version = "1.0.118", features = ["derive"] }