mirror of
https://github.com/fluencelabs/marine-rs-sdk-test
synced 2025-03-15 12:40:50 +00:00
Pass module interfaces as args in marine-test macro (#54)
This commit is contained in:
parent
84d5c2af66
commit
2ee2cf3a2c
130
Cargo.lock
generated
130
Cargo.lock
generated
@ -13,9 +13,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "anyhow"
|
name = "anyhow"
|
||||||
version = "1.0.42"
|
version = "1.0.43"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486"
|
checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "arrayref"
|
name = "arrayref"
|
||||||
@ -57,9 +57,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.2.1"
|
version = "1.3.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
|
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blake3"
|
name = "blake3"
|
||||||
@ -101,9 +101,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.69"
|
version = "1.0.70"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e70cc2f62c6ce1868963827bd677764c62d07c3d9a3e1fb1177ee1a9ab199eb2"
|
checksum = "d26a6ce4b6a484fa3edb70f7efa6fc430fd2b87285fe8b84304fd0936faa0dc0"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
@ -278,9 +278,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ctor"
|
name = "ctor"
|
||||||
version = "0.1.20"
|
version = "0.1.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5e98e2ad1a782e33928b96fc3948e7c355e5af34ba4de7670fe8bac2a3b2006d"
|
checksum = "ccc0a48a9b826acdf4028595adc9db92caea352f7af011a3034acd172a52a0aa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"syn",
|
"syn",
|
||||||
@ -425,13 +425,14 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fluence-it-types"
|
name = "fluence-it-types"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5006d09553345421af5dd2334cc945fc34dc2a73d7c1ed842a39a3803699619d"
|
checksum = "047f670b4807cab8872550a607b1515daff08b3e3bb7576ce8f45971fd811a4e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"it-to-bytes",
|
"it-to-bytes",
|
||||||
"nom",
|
"nom",
|
||||||
"serde",
|
"serde",
|
||||||
|
"variant_count",
|
||||||
"wast",
|
"wast",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -638,9 +639,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "0.4.7"
|
version = "0.4.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd25036021b0de88a0aff6b850051563c6516d0bf53f8638938edbb9de732736"
|
checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
@ -669,9 +670,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.98"
|
version = "0.2.101"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
|
checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
@ -705,7 +706,7 @@ checksum = "e62f29b16bbdb0763a04f8561c954624ee9cd9f558af4e67b95eb00880da11ec"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"cargo_toml",
|
"cargo_toml",
|
||||||
"it-lilo",
|
"it-lilo",
|
||||||
"marine-it-parser 0.6.5",
|
"marine-it-parser",
|
||||||
"marine-macro-impl 0.6.10",
|
"marine-macro-impl 0.6.10",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"serde",
|
"serde",
|
||||||
@ -715,16 +716,6 @@ dependencies = [
|
|||||||
"wasmer-interface-types-fl",
|
"wasmer-interface-types-fl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "marine-it-interfaces"
|
|
||||||
version = "0.3.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "97c533789e72808630cc35b5d14d286382236282525f82ddce8fb47eb9d659e8"
|
|
||||||
dependencies = [
|
|
||||||
"multimap",
|
|
||||||
"wasmer-interface-types-fl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine-it-interfaces"
|
name = "marine-it-interfaces"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -735,23 +726,6 @@ dependencies = [
|
|||||||
"wasmer-interface-types-fl",
|
"wasmer-interface-types-fl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "marine-it-parser"
|
|
||||||
version = "0.5.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e59c7067a18b9e4aebe67bee033638fae97d6fe4fb00f70f9a509eb5d03d1c5d"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"marine-it-interfaces 0.3.0",
|
|
||||||
"nom",
|
|
||||||
"semver 0.11.0",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
"walrus",
|
|
||||||
"wasmer-interface-types-fl",
|
|
||||||
"wasmer-runtime-core-fl",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine-it-parser"
|
name = "marine-it-parser"
|
||||||
version = "0.6.5"
|
version = "0.6.5"
|
||||||
@ -760,7 +734,7 @@ checksum = "19a6606e472587b2e7b759b16d037a4ea951facc2a6650f668f22403978c2442"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"itertools 0.10.1",
|
"itertools 0.10.1",
|
||||||
"marine-it-interfaces 0.4.0",
|
"marine-it-interfaces",
|
||||||
"marine-module-interface",
|
"marine-module-interface",
|
||||||
"nom",
|
"nom",
|
||||||
"semver 0.11.0",
|
"semver 0.11.0",
|
||||||
@ -805,6 +779,7 @@ dependencies = [
|
|||||||
name = "marine-macro-impl"
|
name = "marine-macro-impl"
|
||||||
version = "0.6.11"
|
version = "0.6.11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"marine-macro-testing-utils",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -814,6 +789,15 @@ dependencies = [
|
|||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "marine-macro-testing-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine-module-info-parser"
|
name = "marine-module-info-parser"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
@ -838,7 +822,7 @@ checksum = "d8a5936273bebb523ed169863282dbc19fc66bb983c7031c5b8b0556584f2401"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"itertools 0.10.1",
|
"itertools 0.10.1",
|
||||||
"marine-it-interfaces 0.4.0",
|
"marine-it-interfaces",
|
||||||
"nom",
|
"nom",
|
||||||
"semver 0.11.0",
|
"semver 0.11.0",
|
||||||
"serde",
|
"serde",
|
||||||
@ -895,12 +879,13 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine-rs-sdk-test"
|
name = "marine-rs-sdk-test"
|
||||||
version = "0.1.11"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"fluence-app-service",
|
"fluence-app-service",
|
||||||
"marine-test-macro",
|
"marine-test-macro",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"trybuild",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -915,8 +900,8 @@ dependencies = [
|
|||||||
"it-lilo",
|
"it-lilo",
|
||||||
"log",
|
"log",
|
||||||
"marine-it-generator",
|
"marine-it-generator",
|
||||||
"marine-it-interfaces 0.4.0",
|
"marine-it-interfaces",
|
||||||
"marine-it-parser 0.6.5",
|
"marine-it-parser",
|
||||||
"marine-module-info-parser",
|
"marine-module-info-parser",
|
||||||
"marine-module-interface",
|
"marine-module-interface",
|
||||||
"marine-utils",
|
"marine-utils",
|
||||||
@ -936,7 +921,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine-test-macro"
|
name = "marine-test-macro"
|
||||||
version = "0.1.11"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"marine-test-macro-impl",
|
"marine-test-macro-impl",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
@ -947,14 +932,17 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "marine-test-macro-impl"
|
name = "marine-test-macro-impl"
|
||||||
version = "0.1.11"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"darling",
|
"darling",
|
||||||
"fluence-app-service",
|
"fluence-app-service",
|
||||||
"marine-it-parser 0.5.0",
|
"itertools 0.10.1",
|
||||||
|
"marine-it-parser",
|
||||||
|
"marine-macro-testing-utils",
|
||||||
"proc-macro-error",
|
"proc-macro-error",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
"static_assertions",
|
||||||
"syn",
|
"syn",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
@ -985,9 +973,9 @@ checksum = "8dc5838acba84ce4d802d672afd0814fae0ae7098021ae5b06d975e70d09f812"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.4.0"
|
version = "2.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
|
checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap"
|
name = "memmap"
|
||||||
@ -1177,9 +1165,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.28"
|
version = "1.0.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612"
|
checksum = "b9f5105d4fdaab20335ca9565e106a5d9b82b6219b5ba735731124ac6711d23d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
@ -1347,9 +1335,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.66"
|
version = "1.0.67"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "336b10da19a12ad094b59d870ebde26a45402e5b470add4b5fd03c5048a32127"
|
checksum = "a7f9e390c27c3c0ce8bc5d725f6e4d30a29d26659494aa4b17535f7522c5c950"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"itoa",
|
"itoa",
|
||||||
"ryu",
|
"ryu",
|
||||||
@ -1358,9 +1346,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "simple_logger"
|
name = "simple_logger"
|
||||||
version = "1.12.1"
|
version = "1.13.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28475b72d7e5da6ad80c6d284aa557821bb4f7f788b9f607632635e3783a8608"
|
checksum = "b7de33c687404ec3045d4a0d437580455257c0436f858d702f244e7d652f9f07"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atty",
|
"atty",
|
||||||
"chrono",
|
"chrono",
|
||||||
@ -1395,9 +1383,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.74"
|
version = "1.0.75"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c"
|
checksum = "b7f58f7e8eaa0009c5fec437aabf511bd9933e4b2d7407bd05273c01a8906ea7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1421,18 +1409,18 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.26"
|
version = "1.0.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "93119e4feac1cbe6c798c34d3a53ea0026b0b1de6a120deef895137c0529bfe2"
|
checksum = "283d5230e63df9608ac7d9691adc1dfb6e701225436eb64d0b9a7f0a5a04f6ec"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.26"
|
version = "1.0.28"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "060d69a0afe7796bf42e9e2ff91f5ee691fb15c53d38b4b62a9a53eb23164745"
|
checksum = "fa3884228611f5cd3608e2d409bf7dce832e4eb3135e3f11addbd7e41bd68e71"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@ -1461,9 +1449,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "trybuild"
|
name = "trybuild"
|
||||||
version = "1.0.43"
|
version = "1.0.45"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c02c413315329fc96167f922b46fd0caa3a43f4697b7a7896b183c7142635832"
|
checksum = "5bdaf2a1d317f3d58b44b31c7f6436b9b9acafe7bddfeace50897c2b804d7792"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"glob",
|
"glob",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
@ -1530,6 +1518,16 @@ dependencies = [
|
|||||||
"getrandom 0.2.3",
|
"getrandom 0.2.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "variant_count"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aae2faf80ac463422992abf4de234731279c058aaf33171ca70277c98406b124"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
|
21
crates/macro-testing-utils/Cargo.toml
Normal file
21
crates/macro-testing-utils/Cargo.toml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
[package]
|
||||||
|
name = "marine-macro-testing-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2018"
|
||||||
|
description = "Some functions for testing procedural macros"
|
||||||
|
documentation = "https://docs.rs/fluence/marine-macro-testing-utils"
|
||||||
|
repository = "https://github.com/fluencelabs/marine-rs-sdk/tree/master/crates/marine-macro-testing-utils"
|
||||||
|
authors = ["Fluence Labs"]
|
||||||
|
keywords = ["fluence", "marine", "sdk", "webassembly"]
|
||||||
|
categories = ["development-tools::testing"]
|
||||||
|
license = "Apache-2.0"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
crate-type = ["rlib"]
|
||||||
|
doctest = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
quote = "1.0.9"
|
||||||
|
proc-macro2 = "1.0.26"
|
||||||
|
syn = { version = '1.0.64', features = ['full'] }
|
44
crates/macro-testing-utils/src/lib.rs
Normal file
44
crates/macro-testing-utils/src/lib.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::io::Read;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub fn stream_from_file<P>(path: P) -> proc_macro2::TokenStream
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let items = items_from_file(path);
|
||||||
|
quote::quote! { #(#items)* }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn items_from_file<P>(path: P) -> Vec<syn::Item>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let mut file = std::fs::File::open(path).expect("Unable to open file");
|
||||||
|
|
||||||
|
let mut src = String::new();
|
||||||
|
file.read_to_string(&mut src).expect("Unable to read file");
|
||||||
|
|
||||||
|
let token_file = syn::parse_file(&src).expect("Unable to parse file");
|
||||||
|
token_file.items
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_syn_item(token_stream: proc_macro2::TokenStream) -> Vec<syn::Item> {
|
||||||
|
let file: syn::File = syn::parse2(token_stream).expect("token stream should be parsed");
|
||||||
|
file.items
|
||||||
|
}
|
@ -23,3 +23,4 @@ uuid = { version = "0.8.2", features = ["v4"] }
|
|||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "0.7.1"
|
pretty_assertions = "0.7.1"
|
||||||
|
marine-macro-testing-utils = {path = "../macro-testing-utils"}
|
||||||
|
@ -16,7 +16,8 @@
|
|||||||
|
|
||||||
use marine_macro_impl::marine;
|
use marine_macro_impl::marine;
|
||||||
|
|
||||||
use std::io::Read;
|
use marine_macro_testing_utils::{items_from_file, stream_from_file, to_syn_item};
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
pub fn test_marine_token_streams<FP, EP>(marine_path: FP, expanded_path: EP) -> bool
|
pub fn test_marine_token_streams<FP, EP>(marine_path: FP, expanded_path: EP) -> bool
|
||||||
@ -34,29 +35,3 @@ where
|
|||||||
|
|
||||||
marine_item == expanded_item
|
marine_item == expanded_item
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stream_from_file<P>(path: P) -> proc_macro2::TokenStream
|
|
||||||
where
|
|
||||||
P: AsRef<Path>,
|
|
||||||
{
|
|
||||||
let items = items_from_file(path);
|
|
||||||
quote::quote! { #(#items)* }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn items_from_file<P>(path: P) -> Vec<syn::Item>
|
|
||||||
where
|
|
||||||
P: AsRef<Path>,
|
|
||||||
{
|
|
||||||
let mut file = std::fs::File::open(path).expect("Unable to open file");
|
|
||||||
|
|
||||||
let mut src = String::new();
|
|
||||||
file.read_to_string(&mut src).expect("Unable to read file");
|
|
||||||
|
|
||||||
let token_file = syn::parse_file(&src).expect("Unable to parse file");
|
|
||||||
token_file.items
|
|
||||||
}
|
|
||||||
|
|
||||||
fn to_syn_item(token_stream: proc_macro2::TokenStream) -> Vec<syn::Item> {
|
|
||||||
let file: syn::File = syn::parse2(token_stream).expect("token stream should be parsed");
|
|
||||||
file.items
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "marine-test-macro-impl"
|
name = "marine-test-macro-impl"
|
||||||
version = "0.1.11" # remember to update html_root_url
|
version = "0.2.0" # remember to update html_root_url
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Implementation of the `#[marine_test]` macro"
|
description = "Implementation of the `#[marine_test]` macro"
|
||||||
documentation = "https://docs.rs/fluence/marine-test-macro-impl"
|
documentation = "https://docs.rs/fluence/marine-test-macro-impl"
|
||||||
@ -15,11 +15,15 @@ all-features = true
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
fluence-app-service = { version = "0.9.0", features = ["raw-module-api"] }
|
fluence-app-service = { version = "0.9.0", features = ["raw-module-api"] }
|
||||||
marine-it-parser = "0.5.0"
|
marine-it-parser = "0.6.5"
|
||||||
|
itertools = "0.10.1"
|
||||||
darling = "0.12.2"
|
darling = "0.12.2"
|
||||||
quote = "1.0.9"
|
quote = "1.0.9"
|
||||||
proc-macro2 = "1.0.26"
|
proc-macro2 = "1.0.26"
|
||||||
proc-macro-error = { version = "1.0.4", default-features = false }
|
proc-macro-error = { version = "1.0.4", default-features = false }
|
||||||
syn = { version = '1.0.64', features = ['full'] }
|
syn = { version = '1.0.64', features = ['full'] }
|
||||||
thiserror = "1.0.24"
|
thiserror = "1.0.24"
|
||||||
|
static_assertions = "1.1.0"
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
marine-macro-testing-utils = {path = "../macro-testing-utils"}
|
||||||
|
@ -50,6 +50,12 @@ pub enum TestGeneratorError {
|
|||||||
|
|
||||||
#[error("{0} is invalid UTF8 path")]
|
#[error("{0} is invalid UTF8 path")]
|
||||||
InvalidUTF8Path(PathBuf),
|
InvalidUTF8Path(PathBuf),
|
||||||
|
|
||||||
|
#[error(r#"a "self" argument found and it is not supported in test function"#)]
|
||||||
|
UnexpectedSelf,
|
||||||
|
|
||||||
|
#[error("Duplicate module: {0}")]
|
||||||
|
DuplicateModuleName(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, ThisError)]
|
#[derive(Debug, ThisError)]
|
||||||
|
@ -17,19 +17,19 @@
|
|||||||
use crate::TResult;
|
use crate::TResult;
|
||||||
|
|
||||||
use fluence_app_service::TomlAppServiceConfig;
|
use fluence_app_service::TomlAppServiceConfig;
|
||||||
use marine_it_parser::module_raw_interface;
|
use marine_it_parser::module_it_interface;
|
||||||
use marine_it_parser::interface::MModuleInterface;
|
use marine_it_parser::it_interface::IModuleInterface;
|
||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub(super) struct Module<'m> {
|
pub(super) struct Module<'m> {
|
||||||
pub name: &'m str,
|
pub name: &'m str,
|
||||||
pub interface: MModuleInterface,
|
pub interface: IModuleInterface,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'m> Module<'m> {
|
impl<'m> Module<'m> {
|
||||||
fn new(name: &'m str, interface: MModuleInterface) -> Self {
|
fn new(name: &'m str, interface: IModuleInterface) -> Self {
|
||||||
Self { name, interface }
|
Self { name, interface }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -43,9 +43,7 @@ pub(super) fn collect_modules(
|
|||||||
|
|
||||||
module_paths
|
module_paths
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(name, path)| {
|
.map(|(name, path)| module_it_interface(path).map(|interface| Module::new(name, interface)))
|
||||||
module_raw_interface(path).map(|interface| Module::new(name, interface))
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<_>, _>>()
|
.collect::<Result<Vec<_>, _>>()
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
@ -23,9 +23,11 @@ use crate::marine_test::config_utils;
|
|||||||
use fluence_app_service::TomlAppServiceConfig;
|
use fluence_app_service::TomlAppServiceConfig;
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
use quote::ToTokens;
|
||||||
|
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use syn::FnArg;
|
||||||
|
|
||||||
/// Generates glue code for tests.
|
/// Generates glue code for tests.
|
||||||
/// F.e. for this test for the greeting service
|
/// F.e. for this test for the greeting service
|
||||||
@ -128,30 +130,40 @@ pub(super) fn generate_test_glue_code(
|
|||||||
let modules_dir = file_path.join(modules_dir);
|
let modules_dir = file_path.join(modules_dir);
|
||||||
let module_interfaces =
|
let module_interfaces =
|
||||||
marine_test::config_utils::collect_modules(&marine_config, modules_dir)?;
|
marine_test::config_utils::collect_modules(&marine_config, modules_dir)?;
|
||||||
|
let linked_modules = marine_test::modules_linker::link_modules(&module_interfaces)?;
|
||||||
|
|
||||||
let module_definitions =
|
let module_definitions = marine_test::module_generator::generate_module_definitions(
|
||||||
marine_test::module_generator::generate_module_definitions(module_interfaces.iter())?;
|
module_interfaces.iter(),
|
||||||
|
&linked_modules,
|
||||||
let module_iter = module_interfaces.iter().map(|module| module.name);
|
)?;
|
||||||
let module_ctors = generate_module_ctors(module_iter)?;
|
|
||||||
|
|
||||||
let original_block = func_item.block;
|
let original_block = func_item.block;
|
||||||
let signature = func_item.sig;
|
let signature = func_item.sig;
|
||||||
|
let name = &signature.ident;
|
||||||
|
let inputs = &signature.inputs;
|
||||||
|
let arg_names = generate_arg_names(inputs.iter())?;
|
||||||
|
let module_ctors = generate_module_ctors(inputs.iter())?;
|
||||||
|
|
||||||
let glue_code = quote! {
|
let glue_code = quote! {
|
||||||
#[test]
|
#[test]
|
||||||
#signature {
|
fn #name() {
|
||||||
// definitions for wasm modules specified in config
|
// definitions for wasm modules specified in config
|
||||||
#(#module_definitions)*
|
pub mod marine_test_env {
|
||||||
|
#(#module_definitions)*
|
||||||
|
}
|
||||||
// AppService constructor and instantiation to implicit `marine` variable
|
// AppService constructor and instantiation to implicit `marine` variable
|
||||||
#app_service_ctor
|
#app_service_ctor
|
||||||
|
|
||||||
// constructors of all modules of the tested service
|
// constructors of all modules of the tested service
|
||||||
#(#module_ctors)*
|
#(#module_ctors)*
|
||||||
|
|
||||||
// original test function as is
|
fn test_func(#inputs) {
|
||||||
#original_block
|
#(let mut #arg_names = #arg_names;)*
|
||||||
|
// original test function as is
|
||||||
|
#original_block
|
||||||
|
}
|
||||||
|
|
||||||
|
test_func(#(#arg_names,)*)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,9 +193,7 @@ fn generate_app_service_ctor(config_path: &str, modules_dir: &Path) -> TResult<T
|
|||||||
}
|
}
|
||||||
|
|
||||||
let (file_path_, remainder) = match file_path.next_back().and_then(|p| match p {
|
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 => {
|
std::path::Component::Normal(_) | std::path::Component::CurDir | std::path::Component::ParentDir => Some((file_path, p)),
|
||||||
Some((file_path, p))
|
|
||||||
}
|
|
||||||
_ => None,
|
_ => None,
|
||||||
}) {
|
}) {
|
||||||
Some(t) => t,
|
Some(t) => t,
|
||||||
@ -218,21 +228,32 @@ fn generate_app_service_ctor(config_path: &str, modules_dir: &Path) -> TResult<T
|
|||||||
Ok(service_ctor)
|
Ok(service_ctor)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_module_ctors<'n>(
|
fn generate_module_ctors<'inputs>(
|
||||||
module_names: impl ExactSizeIterator<Item = &'n str>,
|
inputs: impl Iterator<Item = &'inputs FnArg>,
|
||||||
) -> TResult<Vec<TokenStream>> {
|
) -> TResult<Vec<TokenStream>> {
|
||||||
module_names
|
inputs
|
||||||
.map(|name| -> TResult<_> {
|
.map(|x| -> TResult<_> {
|
||||||
// TODO: optimize these two call because they are called twice for each module name
|
match x {
|
||||||
// and internally allocate memory in format call.
|
FnArg::Receiver(_) => Err(TestGeneratorError::UnexpectedSelf),
|
||||||
let module_name = marine_test::utils::generate_structs_module_ident(&name)?;
|
FnArg::Typed(x) => {
|
||||||
let struct_name = marine_test::utils::generate_struct_name(&name)?;
|
let pat = &x.pat;
|
||||||
let name_for_user = marine_test::utils::new_ident(&name)?;
|
let ty = &x.ty;
|
||||||
|
Ok(quote! {let mut #pat = #ty::new(marine.clone());})
|
||||||
let module_ctor =
|
}
|
||||||
quote! { let mut #name_for_user = #module_name::#struct_name::new(marine.clone()); };
|
}
|
||||||
|
})
|
||||||
Ok(module_ctor)
|
.collect::<TResult<_>>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate_arg_names<'inputs>(
|
||||||
|
inputs: impl Iterator<Item = &'inputs FnArg>,
|
||||||
|
) -> TResult<Vec<TokenStream>> {
|
||||||
|
inputs
|
||||||
|
.map(|x| -> TResult<_> {
|
||||||
|
match x {
|
||||||
|
FnArg::Receiver(_) => Err(TestGeneratorError::UnexpectedSelf),
|
||||||
|
FnArg::Typed(x) => Ok(x.pat.to_token_stream()),
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect::<TResult<_>>()
|
.collect::<TResult<_>>()
|
||||||
}
|
}
|
||||||
|
@ -19,5 +19,6 @@ mod marine_test_impl;
|
|||||||
mod glue_code_generator;
|
mod glue_code_generator;
|
||||||
mod module_generator;
|
mod module_generator;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
mod modules_linker;
|
||||||
|
|
||||||
pub use marine_test_impl::marine_test_impl;
|
pub use marine_test_impl::marine_test_impl;
|
||||||
|
@ -21,6 +21,7 @@ mod record_type_generator;
|
|||||||
use crate::marine_test::utils;
|
use crate::marine_test::utils;
|
||||||
use crate::marine_test::config_utils::Module;
|
use crate::marine_test::config_utils::Module;
|
||||||
use crate::TResult;
|
use crate::TResult;
|
||||||
|
use crate::marine_test::modules_linker::{LinkedModules, LinkedModule};
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
@ -56,21 +57,24 @@ use quote::quote;
|
|||||||
///```
|
///```
|
||||||
pub(super) fn generate_module_definitions<'i>(
|
pub(super) fn generate_module_definitions<'i>(
|
||||||
modules: impl ExactSizeIterator<Item = &'i Module<'i>>,
|
modules: impl ExactSizeIterator<Item = &'i Module<'i>>,
|
||||||
|
linked_modules: &'i LinkedModules<'_>,
|
||||||
) -> TResult<Vec<TokenStream>> {
|
) -> TResult<Vec<TokenStream>> {
|
||||||
modules
|
modules
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(generate_module_definition)
|
.map(|value| generate_module_definition(value, linked_modules.get(&value.name).unwrap())) // linked_modules are built from modules
|
||||||
.collect::<TResult<Vec<_>>>()
|
.collect::<TResult<Vec<_>>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_module_definition(module: &Module<'_>) -> TResult<TokenStream> {
|
fn generate_module_definition(
|
||||||
|
module: &Module<'_>,
|
||||||
|
linked_module: &'_ LinkedModule<'_>,
|
||||||
|
) -> TResult<TokenStream> {
|
||||||
let module_name = module.name;
|
let module_name = module.name;
|
||||||
let module_ident = utils::generate_module_ident(module_name)?;
|
let module_ident = utils::new_ident(module_name)?;
|
||||||
let structs_module_ident = utils::generate_structs_module_ident(module_name)?;
|
let struct_ident = utils::new_ident("ModuleInterface")?;
|
||||||
let struct_ident = utils::generate_struct_name(module_name)?;
|
|
||||||
|
|
||||||
let module_interface = &module.interface;
|
let module_interface = &module.interface;
|
||||||
let module_records = record_type_generator::generate_records(&module_interface.record_types)?;
|
let module_records = record_type_generator::generate_records(linked_module)?;
|
||||||
let module_functions = methods_generator::generate_module_methods(
|
let module_functions = methods_generator::generate_module_methods(
|
||||||
module_name,
|
module_name,
|
||||||
module_interface.function_signatures.iter(),
|
module_interface.function_signatures.iter(),
|
||||||
@ -79,26 +83,22 @@ fn generate_module_definition(module: &Module<'_>) -> TResult<TokenStream> {
|
|||||||
|
|
||||||
let module_definition = quote! {
|
let module_definition = quote! {
|
||||||
// it's a sort of hack: this module structure allows user to import structs by
|
// it's a sort of hack: this module structure allows user to import structs by
|
||||||
// use module_name_structs::StructName;
|
// using marine_env_test::module_name::StructName;
|
||||||
pub mod #structs_module_ident {
|
pub mod #module_ident {
|
||||||
pub use #module_ident::*;
|
#(#module_records)*
|
||||||
|
|
||||||
pub mod #module_ident {
|
pub struct #struct_ident {
|
||||||
#(#module_records)*
|
marine: std::rc::Rc<std::cell::RefCell<marine_rs_sdk_test::internal::AppService>, >,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct #struct_ident {
|
impl #struct_ident {
|
||||||
marine: std::rc::Rc<std::cell::RefCell<marine_rs_sdk_test::internal::AppService>>,
|
pub fn new(marine: std::rc::Rc<std::cell::RefCell<marine_rs_sdk_test::internal::AppService>, >) -> Self {
|
||||||
|
Self { marine }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl #struct_ident {
|
impl #struct_ident {
|
||||||
pub fn new(marine: std::rc::Rc<std::cell::RefCell<marine_rs_sdk_test::internal::AppService>>) -> Self {
|
#(#module_functions)*
|
||||||
Self { marine }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl #struct_ident {
|
|
||||||
#(#module_functions)*
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -17,27 +17,32 @@
|
|||||||
use super::methods_generator_utils::*;
|
use super::methods_generator_utils::*;
|
||||||
use crate::TResult;
|
use crate::TResult;
|
||||||
|
|
||||||
use marine_it_parser::interface::MRecordTypes;
|
use marine_it_parser::it_interface::IFunctionSignature;
|
||||||
use marine_it_parser::interface::MFunctionSignature;
|
use marine_it_parser::it_interface::IRecordTypes;
|
||||||
|
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
pub(super) fn generate_module_methods<'m, 'r>(
|
pub(super) fn generate_module_methods<'m, 'r>(
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
mut method_signatures: impl ExactSizeIterator<Item = &'m MFunctionSignature>,
|
method_signatures: impl ExactSizeIterator<Item = &'m IFunctionSignature>,
|
||||||
records: &'r MRecordTypes,
|
records: &'r IRecordTypes,
|
||||||
) -> TResult<Vec<proc_macro2::TokenStream>> {
|
) -> TResult<Vec<proc_macro2::TokenStream>> {
|
||||||
use CallParametersSettings::*;
|
use CallParametersSettings::*;
|
||||||
|
|
||||||
let methods_count = 2 * method_signatures.len();
|
let methods_count = 2 * method_signatures.len();
|
||||||
method_signatures.try_fold::<_, _, TResult<_>>(
|
method_signatures
|
||||||
Vec::with_capacity(methods_count),
|
.sorted_by(|lhs, rhs| lhs.name.cmp(&rhs.name))
|
||||||
|mut methods, signature| {
|
.try_fold::<_, _, TResult<_>>(
|
||||||
let default_cp = generate_module_method(module_name, &signature, Default, records)?;
|
Vec::with_capacity(methods_count),
|
||||||
let user_cp = generate_module_method(module_name, &signature, UserDefined, records)?;
|
|mut methods, signature| {
|
||||||
|
let default_cp = generate_module_method(module_name, &signature, Default, records)?;
|
||||||
|
let user_cp =
|
||||||
|
generate_module_method(module_name, &signature, UserDefined, records)?;
|
||||||
|
|
||||||
methods.push(default_cp);
|
methods.push(default_cp);
|
||||||
methods.push(user_cp);
|
methods.push(user_cp);
|
||||||
|
|
||||||
Ok(methods)
|
Ok(methods)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,10 @@ use crate::marine_test::utils::new_ident;
|
|||||||
use crate::marine_test::utils::itype_to_tokens;
|
use crate::marine_test::utils::itype_to_tokens;
|
||||||
use crate::TResult;
|
use crate::TResult;
|
||||||
|
|
||||||
use marine_it_parser::interface::it::IType;
|
use marine_it_parser::it_interface::it::IType;
|
||||||
use marine_it_parser::interface::it::IFunctionArg;
|
use marine_it_parser::it_interface::it::IFunctionArg;
|
||||||
use marine_it_parser::interface::MRecordTypes;
|
use marine_it_parser::it_interface::IRecordTypes;
|
||||||
use marine_it_parser::interface::MFunctionSignature;
|
use marine_it_parser::it_interface::IFunctionSignature;
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
@ -34,9 +34,9 @@ pub(super) enum CallParametersSettings {
|
|||||||
|
|
||||||
pub(super) fn generate_module_method(
|
pub(super) fn generate_module_method(
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
signature: &MFunctionSignature,
|
signature: &IFunctionSignature,
|
||||||
cp_setting: CallParametersSettings,
|
cp_setting: CallParametersSettings,
|
||||||
records: &MRecordTypes,
|
records: &IRecordTypes,
|
||||||
) -> TResult<TokenStream> {
|
) -> TResult<TokenStream> {
|
||||||
let arguments = generate_arguments(signature.arguments.iter(), records)?;
|
let arguments = generate_arguments(signature.arguments.iter(), records)?;
|
||||||
let output_type = generate_output_type(&signature.outputs, records)?;
|
let output_type = generate_output_type(&signature.outputs, records)?;
|
||||||
@ -73,8 +73,8 @@ pub(super) fn generate_module_method(
|
|||||||
fn generate_marine_call(
|
fn generate_marine_call(
|
||||||
module_name: &str,
|
module_name: &str,
|
||||||
cp_settings: CallParametersSettings,
|
cp_settings: CallParametersSettings,
|
||||||
method_signature: &MFunctionSignature,
|
method_signature: &IFunctionSignature,
|
||||||
records: &MRecordTypes,
|
records: &IRecordTypes,
|
||||||
) -> TResult<TokenStream> {
|
) -> TResult<TokenStream> {
|
||||||
let args = method_signature.arguments.iter().map(|a| a.name.as_str());
|
let args = method_signature.arguments.iter().map(|a| a.name.as_str());
|
||||||
let convert_arguments = generate_arguments_converter(args)?;
|
let convert_arguments = generate_arguments_converter(args)?;
|
||||||
@ -133,7 +133,7 @@ fn generate_set_result(output_type: &Option<&IType>) -> TokenStream {
|
|||||||
|
|
||||||
fn generate_convert_to_output(
|
fn generate_convert_to_output(
|
||||||
output_type: &Option<&IType>,
|
output_type: &Option<&IType>,
|
||||||
records: &MRecordTypes,
|
records: &IRecordTypes,
|
||||||
) -> TResult<TokenStream> {
|
) -> TResult<TokenStream> {
|
||||||
let result_stream = match output_type {
|
let result_stream = match output_type {
|
||||||
Some(ty) => {
|
Some(ty) => {
|
||||||
@ -157,7 +157,7 @@ fn generate_ret(output_type: &Option<&IType>) -> TokenStream {
|
|||||||
|
|
||||||
fn generate_arguments<'a, 'r>(
|
fn generate_arguments<'a, 'r>(
|
||||||
arguments: impl ExactSizeIterator<Item = &'a IFunctionArg>,
|
arguments: impl ExactSizeIterator<Item = &'a IFunctionArg>,
|
||||||
records: &'r MRecordTypes,
|
records: &'r IRecordTypes,
|
||||||
) -> TResult<Vec<TokenStream>> {
|
) -> TResult<Vec<TokenStream>> {
|
||||||
arguments
|
arguments
|
||||||
.map(|argument| -> TResult<_> {
|
.map(|argument| -> TResult<_> {
|
||||||
@ -170,7 +170,7 @@ fn generate_arguments<'a, 'r>(
|
|||||||
.collect::<TResult<Vec<_>>>()
|
.collect::<TResult<Vec<_>>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_output_type(output_types: &[IType], records: &MRecordTypes) -> TResult<TokenStream> {
|
fn generate_output_type(output_types: &[IType], records: &IRecordTypes) -> TResult<TokenStream> {
|
||||||
let output_type = get_output_type(output_types)?;
|
let output_type = get_output_type(output_types)?;
|
||||||
match output_type {
|
match output_type {
|
||||||
None => Ok(TokenStream::new()),
|
None => Ok(TokenStream::new()),
|
||||||
|
@ -17,35 +17,47 @@
|
|||||||
use crate::marine_test::utils;
|
use crate::marine_test::utils;
|
||||||
use crate::TResult;
|
use crate::TResult;
|
||||||
|
|
||||||
use marine_it_parser::interface::it::IRecordFieldType;
|
use marine_it_parser::it_interface::it::IRecordFieldType;
|
||||||
use marine_it_parser::interface::MRecordTypes;
|
use marine_it_parser::it_interface::IRecordTypes;
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
|
||||||
pub(super) fn generate_records(records: &MRecordTypes) -> TResult<Vec<TokenStream>> {
|
use crate::marine_test::modules_linker::{LinkedModule, RecordEntry};
|
||||||
use std::ops::Deref;
|
use itertools::Itertools;
|
||||||
|
|
||||||
records.iter().map(|(_, record)| -> TResult<_> {
|
pub(super) fn generate_records(linked_module: &LinkedModule<'_>) -> TResult<Vec<TokenStream>> {
|
||||||
let record_name_ident = utils::generate_record_name(&record.name)?;
|
linked_module.records
|
||||||
let fields = prepare_field(record.fields.deref().iter(), records)?;
|
.iter()
|
||||||
|
.sorted()
|
||||||
|
.map(|record| -> TResult<_> {
|
||||||
|
use RecordEntry::*;
|
||||||
|
match record {
|
||||||
|
Use(use_info) => {
|
||||||
|
let from_module_ident = utils::new_ident(use_info.from)?;
|
||||||
|
let record_name_ident = utils::new_ident(use_info.name)?;
|
||||||
|
Ok(quote! {pub use super::#from_module_ident::#record_name_ident;})
|
||||||
|
},
|
||||||
|
Declare(record) => {
|
||||||
|
let record_name_ident = utils::new_ident(&record.record_type.name)?;
|
||||||
|
let fields = prepare_field(record.record_type.fields.iter(), record.records)?;
|
||||||
|
|
||||||
let generated_record = quote! {
|
Ok(quote! {
|
||||||
#[derive(Clone, Debug, marine_rs_sdk_test::internal::serde::Serialize, marine_rs_sdk_test::internal::serde::Deserialize)]
|
#[derive(Clone, Debug, marine_rs_sdk_test::internal::serde::Serialize, marine_rs_sdk_test::internal::serde::Deserialize)]
|
||||||
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
pub struct #record_name_ident {
|
pub struct #record_name_ident {
|
||||||
#(pub #fields),*
|
#(pub #fields),*
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
})
|
||||||
|
.collect::<TResult<Vec<_>>>()
|
||||||
Ok(generated_record)
|
|
||||||
}
|
|
||||||
).collect::<TResult<Vec<_>>>()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_field<'f>(
|
fn prepare_field<'f>(
|
||||||
fields: impl ExactSizeIterator<Item = &'f IRecordFieldType>,
|
fields: impl ExactSizeIterator<Item = &'f IRecordFieldType>,
|
||||||
records: &MRecordTypes,
|
records: &IRecordTypes,
|
||||||
) -> TResult<Vec<TokenStream>> {
|
) -> TResult<Vec<TokenStream>> {
|
||||||
fields
|
fields
|
||||||
.map(|field| -> TResult<_> {
|
.map(|field| -> TResult<_> {
|
||||||
|
198
crates/marine-test-macro-impl/src/marine_test/modules_linker.rs
Normal file
198
crates/marine-test-macro-impl/src/marine_test/modules_linker.rs
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use crate::marine_test::config_utils::Module;
|
||||||
|
use crate::{TResult, TestGeneratorError};
|
||||||
|
|
||||||
|
use marine_it_parser::it_interface::IRecordTypes;
|
||||||
|
use marine_it_parser::it_interface::it::{IType, IRecordType};
|
||||||
|
|
||||||
|
use itertools::zip;
|
||||||
|
use std::cmp::Ordering;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::hash::Hasher;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use static_assertions::const_assert;
|
||||||
|
|
||||||
|
pub(super) fn link_modules<'modules>(
|
||||||
|
modules: &'modules [Module<'_>],
|
||||||
|
) -> TResult<LinkedModules<'modules>> {
|
||||||
|
let mut all_record_types = HashMap::<IRecordTypeClosed<'_>, &str>::new();
|
||||||
|
let mut linked_modules = HashMap::<&str, LinkedModule<'_>>::new();
|
||||||
|
|
||||||
|
for module in modules {
|
||||||
|
let mut linking_module = LinkedModule::default();
|
||||||
|
for (_, record_type) in &module.interface.record_types {
|
||||||
|
let record_type_ex =
|
||||||
|
IRecordTypeClosed::new(record_type.clone(), &module.interface.record_types);
|
||||||
|
|
||||||
|
let entry = match all_record_types.get(&record_type_ex) {
|
||||||
|
Some(owner_module) => RecordEntry::Use(UseDescription {
|
||||||
|
from: owner_module,
|
||||||
|
name: &record_type.name,
|
||||||
|
}),
|
||||||
|
None => {
|
||||||
|
all_record_types.insert(record_type_ex.clone(), module.name);
|
||||||
|
RecordEntry::Declare(record_type_ex)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
linking_module.records.push(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
if linked_modules.insert(module.name, linking_module).is_some() {
|
||||||
|
return Err(TestGeneratorError::DuplicateModuleName(
|
||||||
|
module.name.to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(linked_modules)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ITypeClosed<'r> {
|
||||||
|
ty: &'r IType,
|
||||||
|
records: &'r IRecordTypes,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r> ITypeClosed<'r> {
|
||||||
|
fn new(ty: &'r IType, records: &'r IRecordTypes) -> Self {
|
||||||
|
Self { ty, records }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for ITypeClosed<'_> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
use IType::*;
|
||||||
|
// check if new variants require special handling in the match below
|
||||||
|
#[allow(unused)]
|
||||||
|
const LAST_VERIFIED_ITYPE_SIZE: usize = 17;
|
||||||
|
const_assert!(IType::VARIANT_COUNT == LAST_VERIFIED_ITYPE_SIZE);
|
||||||
|
|
||||||
|
match (&self.ty, &other.ty) {
|
||||||
|
(Array(self_ty), Array(other_ty)) => {
|
||||||
|
ITypeClosed::new(self_ty, self.records) == ITypeClosed::new(other_ty, other.records)
|
||||||
|
}
|
||||||
|
(Record(self_record), Record(other_record)) => {
|
||||||
|
let self_record = self.records.get(self_record);
|
||||||
|
let other_record = other.records.get(other_record);
|
||||||
|
|
||||||
|
// ID from Record(ID) potentially may not be in .records, if it happens comparision is always FALSE
|
||||||
|
match (self_record, other_record) {
|
||||||
|
(None, _) => false,
|
||||||
|
(_, None) => false,
|
||||||
|
(Some(self_record), Some(other_record)) => {
|
||||||
|
IRecordTypeClosed::new(self_record.clone(), self.records)
|
||||||
|
== IRecordTypeClosed::new(other_record.clone(), other.records)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(lhs, rhs) if lhs == rhs => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct IRecordTypeClosed<'r> {
|
||||||
|
pub record_type: Rc<IRecordType>,
|
||||||
|
pub records: &'r IRecordTypes,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'r> IRecordTypeClosed<'r> {
|
||||||
|
fn new(record_type: Rc<IRecordType>, records: &'r IRecordTypes) -> Self {
|
||||||
|
Self {
|
||||||
|
record_type,
|
||||||
|
records,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for IRecordTypeClosed<'_> {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
let names_are_equal = self.record_type.name == other.record_type.name;
|
||||||
|
names_are_equal && fields_are_equal(self, other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fields_are_equal(lhs: &IRecordTypeClosed<'_>, rhs: &IRecordTypeClosed<'_>) -> bool {
|
||||||
|
let same_fields_count = lhs.record_type.fields.len() == rhs.record_type.fields.len();
|
||||||
|
same_fields_count
|
||||||
|
&& zip(lhs.record_type.fields.iter(), rhs.record_type.fields.iter()).all(
|
||||||
|
|(lhs_field, rhs_field)| -> bool {
|
||||||
|
lhs_field.name == rhs_field.name
|
||||||
|
&& ITypeClosed::new(&lhs_field.ty, lhs.records)
|
||||||
|
== ITypeClosed::new(&rhs_field.ty, rhs.records)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for IRecordTypeClosed<'_> {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for IRecordTypeClosed<'_> {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
self.record_type.name.cmp(&other.record_type.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for IRecordTypeClosed<'_> {}
|
||||||
|
|
||||||
|
impl std::hash::Hash for IRecordTypeClosed<'_> {
|
||||||
|
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||||
|
self.record_type.name.hash(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type LinkedModules<'r> = HashMap<&'r str, LinkedModule<'r>>;
|
||||||
|
|
||||||
|
#[derive(Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||||
|
pub struct UseDescription<'r> {
|
||||||
|
pub from: &'r str,
|
||||||
|
pub name: &'r str,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq)]
|
||||||
|
pub enum RecordEntry<'r> {
|
||||||
|
Use(UseDescription<'r>),
|
||||||
|
Declare(IRecordTypeClosed<'r>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for RecordEntry<'_> {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for RecordEntry<'_> {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
use RecordEntry::*;
|
||||||
|
match (self, other) {
|
||||||
|
(Use(_), Declare(_)) => Ordering::Less,
|
||||||
|
(Declare(_), Use(_)) => Ordering::Greater,
|
||||||
|
(Use(lhs), Use(rhs)) => lhs.cmp(rhs),
|
||||||
|
(Declare(lhs), Declare(rhs)) => lhs.record_type.name.cmp(&rhs.record_type.name),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct LinkedModule<'all> {
|
||||||
|
pub records: Vec<RecordEntry<'all>>,
|
||||||
|
}
|
@ -15,38 +15,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::TResult;
|
use crate::TResult;
|
||||||
use marine_it_parser::interface::MRecordTypes;
|
use marine_it_parser::it_interface::IRecordTypes;
|
||||||
use marine_it_parser::interface::it::IType;
|
use marine_it_parser::it_interface::it::IType;
|
||||||
|
|
||||||
use proc_macro2::TokenStream;
|
use proc_macro2::TokenStream;
|
||||||
use quote::quote;
|
use quote::quote;
|
||||||
|
|
||||||
pub(super) fn generate_module_ident(module_name: &str) -> TResult<syn::Ident> {
|
|
||||||
let generated_module_name = format!("__m_generated_{}", module_name);
|
|
||||||
new_ident(&generated_module_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn generate_structs_module_ident(module_name: &str) -> TResult<syn::Ident> {
|
|
||||||
let generated_module_name = format!("{}_structs", module_name);
|
|
||||||
new_ident(&generated_module_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn generate_record_name(record_name: &str) -> TResult<syn::Ident> {
|
|
||||||
let extended_record_name = record_name.to_string();
|
|
||||||
new_ident(&extended_record_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn generate_struct_name(struct_name: &str) -> TResult<syn::Ident> {
|
|
||||||
let extended_struct_name = format!("MGeneratedStruct{}", struct_name);
|
|
||||||
new_ident(&extended_struct_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn new_ident(ident_str: &str) -> TResult<syn::Ident> {
|
pub(super) fn new_ident(ident_str: &str) -> TResult<syn::Ident> {
|
||||||
let ident_str = ident_str.replace('-', "_");
|
let ident_str = ident_str.replace('-', "_");
|
||||||
syn::parse_str::<syn::Ident>(&ident_str).map_err(Into::into)
|
syn::parse_str::<syn::Ident>(&ident_str).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn itype_to_tokens(itype: &IType, records: &MRecordTypes) -> TResult<TokenStream> {
|
pub(super) fn itype_to_tokens(itype: &IType, records: &IRecordTypes) -> TResult<TokenStream> {
|
||||||
let token_stream = match itype {
|
let token_stream = match itype {
|
||||||
IType::Record(record_id) => {
|
IType::Record(record_id) => {
|
||||||
let record = records
|
let record = records
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
modules_dir = "artifacts/"
|
||||||
|
|
||||||
|
[[module]]
|
||||||
|
name = "greeting"
|
||||||
|
mem_pages_count = 1
|
||||||
|
logger_enabled = false
|
Binary file not shown.
@ -0,0 +1,128 @@
|
|||||||
|
#[test]
|
||||||
|
fn empty_string() {
|
||||||
|
pub mod marine_test_env {
|
||||||
|
pub mod greeting {
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct CallParameters {
|
||||||
|
pub init_peer_id: String,
|
||||||
|
pub service_id: String,
|
||||||
|
pub service_creator_peer_id: String,
|
||||||
|
pub host_id: String,
|
||||||
|
pub particle_id: String,
|
||||||
|
pub tetraplets: Vec<Vec<SecurityTetraplet>>
|
||||||
|
}
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct MountedBinaryResult {
|
||||||
|
pub ret_code: i32,
|
||||||
|
pub error: String,
|
||||||
|
pub stdout: Vec<u8>,
|
||||||
|
pub stderr: Vec<u8>
|
||||||
|
}
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct MountedBinaryStringResult {
|
||||||
|
pub ret_code: i32,
|
||||||
|
pub error: String,
|
||||||
|
pub stdout: String,
|
||||||
|
pub stderr: String
|
||||||
|
}
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct SecurityTetraplet {
|
||||||
|
pub peer_pk: String,
|
||||||
|
pub service_id: String,
|
||||||
|
pub function_name: String,
|
||||||
|
pub json_path: String
|
||||||
|
}
|
||||||
|
pub struct ModuleInterface {
|
||||||
|
marine:
|
||||||
|
std::rc::Rc<std::cell::RefCell<marine_rs_sdk_test::internal::AppService>, >,
|
||||||
|
}
|
||||||
|
impl ModuleInterface {
|
||||||
|
pub fn new(
|
||||||
|
marine: std::rc::Rc<
|
||||||
|
std::cell::RefCell<marine_rs_sdk_test::internal::AppService>,>
|
||||||
|
) -> Self {
|
||||||
|
Self { marine }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ModuleInterface {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let tmp_dir = std::env::temp_dir();
|
||||||
|
let service_id = marine_rs_sdk_test::internal::Uuid::new_v4().to_string();
|
||||||
|
let tmp_dir = tmp_dir.join(&service_id);
|
||||||
|
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 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.toml");
|
||||||
|
let modules_dir = module_path.join("artifacts");
|
||||||
|
let modules_dir = modules_dir
|
||||||
|
.to_str()
|
||||||
|
.expect("modules_dir contains invalid UTF8 string");
|
||||||
|
let mut __m_generated_marine_config = marine_rs_sdk_test::internal::TomlAppServiceConfig::load(
|
||||||
|
&config_path
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|e|
|
||||||
|
panic!(
|
||||||
|
"app service config located at `{:?}` can't be loaded: {}",
|
||||||
|
config_path, e
|
||||||
|
));
|
||||||
|
__m_generated_marine_config.service_base_dir = Some(tmp_dir);
|
||||||
|
__m_generated_marine_config.toml_faas_config.modules_dir = Some(modules_dir.to_string());
|
||||||
|
let marine = marine_rs_sdk_test::internal::AppService::new_with_empty_facade(
|
||||||
|
__m_generated_marine_config,
|
||||||
|
service_id,
|
||||||
|
std::collections::HashMap::new()
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|e| panic!("app service can't be created: {}", e));
|
||||||
|
let marine = std::rc::Rc::new(std::cell::RefCell::new(marine));
|
||||||
|
fn test_func() {
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
test_func()
|
||||||
|
}
|
@ -0,0 +1 @@
|
|||||||
|
fn empty_string() {}
|
@ -0,0 +1,8 @@
|
|||||||
|
modules_dir = "artifacts/"
|
||||||
|
|
||||||
|
[[module]]
|
||||||
|
name = "greeting"
|
||||||
|
mem_pages_count = 1
|
||||||
|
logger_enabled = false
|
||||||
|
[module.mounted_binaries]
|
||||||
|
echo = "/usr/bin/curl"
|
Binary file not shown.
@ -0,0 +1,167 @@
|
|||||||
|
#[test]
|
||||||
|
fn test() {
|
||||||
|
pub mod marine_test_env {
|
||||||
|
pub mod greeting {
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct CallParameters {
|
||||||
|
pub init_peer_id: String,
|
||||||
|
pub service_id: String,
|
||||||
|
pub service_creator_peer_id: String,
|
||||||
|
pub host_id: String,
|
||||||
|
pub particle_id: String,
|
||||||
|
pub tetraplets: Vec<Vec<SecurityTetraplet>>
|
||||||
|
}
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct MountedBinaryResult {
|
||||||
|
pub ret_code: i32,
|
||||||
|
pub error: String,
|
||||||
|
pub stdout: Vec<u8>,
|
||||||
|
pub stderr: Vec<u8>
|
||||||
|
}
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct MountedBinaryStringResult {
|
||||||
|
pub ret_code: i32,
|
||||||
|
pub error: String,
|
||||||
|
pub stdout: String,
|
||||||
|
pub stderr: String
|
||||||
|
}
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct SecurityTetraplet {
|
||||||
|
pub peer_pk: String,
|
||||||
|
pub service_id: String,
|
||||||
|
pub function_name: String,
|
||||||
|
pub json_path: String
|
||||||
|
}
|
||||||
|
pub struct ModuleInterface {
|
||||||
|
marine:
|
||||||
|
std::rc::Rc<std::cell::RefCell<marine_rs_sdk_test::internal::AppService>, >,
|
||||||
|
}
|
||||||
|
impl ModuleInterface {
|
||||||
|
pub fn new(
|
||||||
|
marine: std::rc::Rc<
|
||||||
|
std::cell::RefCell<marine_rs_sdk_test::internal::AppService>,
|
||||||
|
>
|
||||||
|
) -> Self {
|
||||||
|
Self { marine }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ModuleInterface {
|
||||||
|
pub fn download(&mut self, url: String) -> String {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
let arguments = marine_rs_sdk_test::internal::serde_json::json!([url]);
|
||||||
|
let result = self
|
||||||
|
.marine
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.call_module("greeting", "download", arguments, <_>::default())
|
||||||
|
.expect("call to Marine failed");
|
||||||
|
let result: String =
|
||||||
|
marine_rs_sdk_test::internal::serde_json::from_value(result)
|
||||||
|
.expect("the default deserializer shouldn't fail");
|
||||||
|
result
|
||||||
|
}
|
||||||
|
pub fn download_cp(
|
||||||
|
&mut self,
|
||||||
|
url: String,
|
||||||
|
cp: marine_rs_sdk_test::CallParameters
|
||||||
|
) -> String {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
let arguments = marine_rs_sdk_test::internal::serde_json::json!([url]);
|
||||||
|
let result = self
|
||||||
|
.marine
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.call_module("greeting", "download", arguments, cp)
|
||||||
|
.expect("call to Marine failed");
|
||||||
|
let result: String =
|
||||||
|
marine_rs_sdk_test::internal::serde_json::from_value(result)
|
||||||
|
.expect("the default deserializer shouldn't fail");
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let tmp_dir = std::env::temp_dir();
|
||||||
|
let service_id = marine_rs_sdk_test::internal::Uuid::new_v4().to_string();
|
||||||
|
let tmp_dir = tmp_dir.join(&service_id);
|
||||||
|
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 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.toml");
|
||||||
|
let modules_dir = module_path.join("artifacts");
|
||||||
|
let modules_dir = modules_dir
|
||||||
|
.to_str()
|
||||||
|
.expect("modules_dir contains invalid UTF8 string");
|
||||||
|
let mut __m_generated_marine_config = marine_rs_sdk_test::internal::TomlAppServiceConfig::load(
|
||||||
|
&config_path
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|e|
|
||||||
|
panic!(
|
||||||
|
"app service config located at `{:?}` can't be loaded: {}",
|
||||||
|
config_path, e
|
||||||
|
)
|
||||||
|
);
|
||||||
|
__m_generated_marine_config.service_base_dir = Some(tmp_dir);
|
||||||
|
__m_generated_marine_config.toml_faas_config.modules_dir = Some(modules_dir.to_string());
|
||||||
|
let marine = marine_rs_sdk_test::internal::AppService::new_with_empty_facade(
|
||||||
|
__m_generated_marine_config,
|
||||||
|
service_id,
|
||||||
|
std::collections::HashMap::new()
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|e| panic!("app service can't be created: {}", e));
|
||||||
|
let marine = std::rc::Rc::new(std::cell::RefCell::new(marine));
|
||||||
|
let mut greeting = marine_test_env::greeting::ModuleInterface::new(marine.clone());
|
||||||
|
fn test_func(greeting: marine_test_env::greeting::ModuleInterface) {
|
||||||
|
let mut greeting = greeting;
|
||||||
|
{
|
||||||
|
let _ = greeting.download("duckduckgo.com");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test_func(greeting,)
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
fn test(greeting: marine_test_env::greeting::ModuleInterface) {
|
||||||
|
let _ = greeting.download("duckduckgo.com");
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
modules_dir = "artifacts/"
|
||||||
|
[[module]]
|
||||||
|
name = "greeting"
|
||||||
|
mem_pages_count = 1
|
||||||
|
logger_enabled = false
|
||||||
|
|
||||||
|
[[module]]
|
||||||
|
name = "call_parameters"
|
||||||
|
mem_pages_count = 1
|
||||||
|
logger_enabled = false
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,321 @@
|
|||||||
|
#[test]
|
||||||
|
fn empty_string() {
|
||||||
|
pub mod marine_test_env {
|
||||||
|
pub mod greeting {
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct CallParameters {
|
||||||
|
pub init_peer_id: String,
|
||||||
|
pub service_id: String,
|
||||||
|
pub service_creator_peer_id: String,
|
||||||
|
pub host_id: String,
|
||||||
|
pub particle_id: String,
|
||||||
|
pub tetraplets: Vec<Vec<SecurityTetraplet>>
|
||||||
|
}
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct MountedBinaryResult {
|
||||||
|
pub ret_code: i32,
|
||||||
|
pub error: String,
|
||||||
|
pub stdout: Vec<u8>,
|
||||||
|
pub stderr: Vec<u8>
|
||||||
|
}
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct MountedBinaryStringResult {
|
||||||
|
pub ret_code: i32,
|
||||||
|
pub error: String,
|
||||||
|
pub stdout: String,
|
||||||
|
pub stderr: String
|
||||||
|
}
|
||||||
|
#[derive(
|
||||||
|
Clone,
|
||||||
|
Debug,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Serialize,
|
||||||
|
marine_rs_sdk_test :: internal :: serde :: Deserialize
|
||||||
|
)]
|
||||||
|
#[serde(crate = "marine_rs_sdk_test::internal::serde")]
|
||||||
|
pub struct SecurityTetraplet {
|
||||||
|
pub peer_pk: String,
|
||||||
|
pub service_id: String,
|
||||||
|
pub function_name: String,
|
||||||
|
pub json_path: String
|
||||||
|
}
|
||||||
|
pub struct ModuleInterface {
|
||||||
|
marine: std::rc::Rc<std::cell::RefCell<marine_rs_sdk_test::internal::AppService>, >,
|
||||||
|
}
|
||||||
|
impl ModuleInterface {
|
||||||
|
pub fn new(
|
||||||
|
marine: std::rc::Rc<
|
||||||
|
std::cell::RefCell<marine_rs_sdk_test::internal::AppService>,
|
||||||
|
>
|
||||||
|
) -> Self {
|
||||||
|
Self { marine }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ModuleInterface {
|
||||||
|
pub fn greeting(&mut self, name: String) -> String {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
let arguments = marine_rs_sdk_test::internal::serde_json::json!([name]);
|
||||||
|
let result = self
|
||||||
|
.marine
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.call_module("greeting", "greeting", arguments, <_>::default())
|
||||||
|
.expect("call to Marine failed");
|
||||||
|
let result: String =
|
||||||
|
marine_rs_sdk_test::internal::serde_json::from_value(result)
|
||||||
|
.expect("the default deserializer shouldn't fail");
|
||||||
|
result
|
||||||
|
}
|
||||||
|
pub fn greeting_cp(
|
||||||
|
&mut self,
|
||||||
|
name: String,
|
||||||
|
cp: marine_rs_sdk_test::CallParameters
|
||||||
|
) -> String {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
let arguments = marine_rs_sdk_test::internal::serde_json::json!([name]);
|
||||||
|
let result = self
|
||||||
|
.marine
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.call_module("greeting", "greeting", arguments, cp)
|
||||||
|
.expect("call to Marine failed");
|
||||||
|
let result: String =
|
||||||
|
marine_rs_sdk_test::internal::serde_json::from_value(result)
|
||||||
|
.expect("the default deserializer shouldn't fail");
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub mod call_parameters {
|
||||||
|
pub use super::greeting::CallParameters;
|
||||||
|
pub use super::greeting::SecurityTetraplet;
|
||||||
|
pub struct ModuleInterface {
|
||||||
|
marine: std::rc::Rc<std::cell::RefCell<marine_rs_sdk_test::internal::AppService>, >,
|
||||||
|
}
|
||||||
|
impl ModuleInterface {
|
||||||
|
pub fn new(
|
||||||
|
marine: std::rc::Rc<
|
||||||
|
std::cell::RefCell<marine_rs_sdk_test::internal::AppService>,
|
||||||
|
>
|
||||||
|
) -> Self {
|
||||||
|
Self { marine }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl ModuleInterface {
|
||||||
|
pub fn call_parameters(&mut self, ) -> String {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
let arguments = marine_rs_sdk_test::internal::serde_json::json!([]);
|
||||||
|
let result = self
|
||||||
|
.marine
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.call_module(
|
||||||
|
"call_parameters",
|
||||||
|
"call_parameters",
|
||||||
|
arguments,
|
||||||
|
<_>::default()
|
||||||
|
)
|
||||||
|
.expect("call to Marine failed");
|
||||||
|
let result: String =
|
||||||
|
marine_rs_sdk_test::internal::serde_json::from_value(result)
|
||||||
|
.expect("the default deserializer shouldn't fail");
|
||||||
|
result
|
||||||
|
}
|
||||||
|
pub fn call_parameters_cp(
|
||||||
|
&mut self,
|
||||||
|
cp: marine_rs_sdk_test::CallParameters
|
||||||
|
) -> String {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
let arguments = marine_rs_sdk_test::internal::serde_json::json!([]);
|
||||||
|
let result = self
|
||||||
|
.marine
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.call_module("call_parameters", "call_parameters", arguments, cp)
|
||||||
|
.expect("call to Marine failed");
|
||||||
|
let result: String =
|
||||||
|
marine_rs_sdk_test::internal::serde_json::from_value(result)
|
||||||
|
.expect("the default deserializer shouldn't fail");
|
||||||
|
result
|
||||||
|
}
|
||||||
|
pub fn return_string(&mut self,) -> String {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
let arguments = marine_rs_sdk_test::internal::serde_json::json!([]);
|
||||||
|
let result = self
|
||||||
|
.marine
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.call_module(
|
||||||
|
"call_parameters",
|
||||||
|
"return_string",
|
||||||
|
arguments,
|
||||||
|
<_>::default()
|
||||||
|
)
|
||||||
|
.expect("call to Marine failed");
|
||||||
|
let result: String =
|
||||||
|
marine_rs_sdk_test::internal::serde_json::from_value(result)
|
||||||
|
.expect("the default deserializer shouldn't fail");
|
||||||
|
result
|
||||||
|
}
|
||||||
|
pub fn return_string_cp(
|
||||||
|
&mut self,
|
||||||
|
cp: marine_rs_sdk_test::CallParameters
|
||||||
|
) -> String {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
let arguments = marine_rs_sdk_test::internal::serde_json::json!([]);
|
||||||
|
let result = self
|
||||||
|
.marine
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.call_module("call_parameters", "return_string", arguments, cp)
|
||||||
|
.expect("call to Marine failed");
|
||||||
|
let result: String =
|
||||||
|
marine_rs_sdk_test::internal::serde_json::from_value(result)
|
||||||
|
.expect("the default deserializer shouldn't fail");
|
||||||
|
result
|
||||||
|
}
|
||||||
|
pub fn test_array_refs(&mut self, ) -> Vec<String> {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
let arguments = marine_rs_sdk_test::internal::serde_json::json!([]);
|
||||||
|
let result = self
|
||||||
|
.marine
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.call_module(
|
||||||
|
"call_parameters",
|
||||||
|
"test_array_refs",
|
||||||
|
arguments,
|
||||||
|
<_>::default()
|
||||||
|
)
|
||||||
|
.expect("call to Marine failed");
|
||||||
|
let result: Vec<String> =
|
||||||
|
marine_rs_sdk_test::internal::serde_json::from_value(result)
|
||||||
|
.expect("the default deserializer shouldn't fail");
|
||||||
|
result
|
||||||
|
}
|
||||||
|
pub fn test_array_refs_cp(
|
||||||
|
&mut self,
|
||||||
|
cp: marine_rs_sdk_test::CallParameters
|
||||||
|
) -> Vec<String> {
|
||||||
|
use std::ops::DerefMut;
|
||||||
|
let arguments = marine_rs_sdk_test::internal::serde_json::json!([]);
|
||||||
|
let result = self
|
||||||
|
.marine
|
||||||
|
.as_ref()
|
||||||
|
.borrow_mut()
|
||||||
|
.call_module("call_parameters", "test_array_refs", arguments, cp)
|
||||||
|
.expect("call to Marine failed");
|
||||||
|
let result: Vec<String> =
|
||||||
|
marine_rs_sdk_test::internal::serde_json::from_value(result)
|
||||||
|
.expect("the default deserializer shouldn't fail");
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let tmp_dir = std::env::temp_dir();
|
||||||
|
let service_id = marine_rs_sdk_test::internal::Uuid::new_v4().to_string();
|
||||||
|
let tmp_dir = tmp_dir.join(&service_id);
|
||||||
|
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 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.toml");
|
||||||
|
let modules_dir = module_path.join("artifacts");
|
||||||
|
let modules_dir = modules_dir
|
||||||
|
.to_str()
|
||||||
|
.expect("modules_dir contains invalid UTF8 string");
|
||||||
|
let mut __m_generated_marine_config = marine_rs_sdk_test::internal::TomlAppServiceConfig::load(
|
||||||
|
&config_path
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|e|
|
||||||
|
panic!(
|
||||||
|
"app service config located at `{:?}` can't be loaded: {}",
|
||||||
|
config_path, e
|
||||||
|
)
|
||||||
|
);
|
||||||
|
__m_generated_marine_config.service_base_dir = Some(tmp_dir);
|
||||||
|
__m_generated_marine_config.toml_faas_config.modules_dir = Some(modules_dir.to_string());
|
||||||
|
let marine = marine_rs_sdk_test::internal::AppService::new_with_empty_facade(
|
||||||
|
__m_generated_marine_config,
|
||||||
|
service_id,
|
||||||
|
std::collections::HashMap::new()
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|e| panic!("app service can't be created: {}", e));
|
||||||
|
let marine = std::rc::Rc::new(std::cell::RefCell::new(marine));
|
||||||
|
let mut greeting_m = marine_test_env::greeting::ModuleInterface::new(marine.clone());
|
||||||
|
let mut call_parameters_m =
|
||||||
|
marine_test_env::call_parameters::ModuleInterface::new(marine.clone());
|
||||||
|
fn test_func(
|
||||||
|
greeting_m: marine_test_env::greeting::ModuleInterface,
|
||||||
|
call_parameters_m: marine_test_env::call_parameters::ModuleInterface
|
||||||
|
) {
|
||||||
|
let mut greeting_m = greeting_m;
|
||||||
|
let mut call_parameters_m = call_parameters_m;
|
||||||
|
{
|
||||||
|
let init_peer_id = "init_peer_id";
|
||||||
|
let service_id = "service_id";
|
||||||
|
let service_creator_peer_id = "service_creator_peer_id";
|
||||||
|
let host_id = "host_id";
|
||||||
|
let particle_id = "particle_id";
|
||||||
|
let greeting = greeting_m.greeting("asd");
|
||||||
|
let mut tetraplet = SecurityTetraplet::default();
|
||||||
|
tetraplet.function_name = "some_func_name".to_string();
|
||||||
|
tetraplet.json_path = "some_json_path".to_string();
|
||||||
|
let tetraplets = vec![vec![tetraplet]];
|
||||||
|
let cp = CallParameters {
|
||||||
|
init_peer_id: init_peer_id.to_string(),
|
||||||
|
service_id: service_id.to_string(),
|
||||||
|
service_creator_peer_id: service_creator_peer_id.to_string(),
|
||||||
|
host_id: host_id.to_string(),
|
||||||
|
particle_id: particle_id.to_string(),
|
||||||
|
tetraplets: tetraplets.clone(),
|
||||||
|
};
|
||||||
|
let actual = call_parameters_m.call_parameters_cp(cp);
|
||||||
|
let expected = format!(
|
||||||
|
"{}\n{}\n{}\n{}\n{}\n{:?}",
|
||||||
|
init_peer_id, service_id, service_creator_peer_id, host_id, particle_id, tetraplets
|
||||||
|
);
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test_func(greeting_m, call_parameters_m, )
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
fn empty_string(greeting_m: marine_test_env::greeting::ModuleInterface, call_parameters_m: marine_test_env::call_parameters::ModuleInterface) {
|
||||||
|
let init_peer_id = "init_peer_id";
|
||||||
|
let service_id = "service_id";
|
||||||
|
let service_creator_peer_id = "service_creator_peer_id";
|
||||||
|
let host_id = "host_id";
|
||||||
|
let particle_id = "particle_id";
|
||||||
|
|
||||||
|
let greeting = greeting_m.greeting("asd");
|
||||||
|
let mut tetraplet = SecurityTetraplet::default();
|
||||||
|
tetraplet.function_name = "some_func_name".to_string();
|
||||||
|
tetraplet.json_path = "some_json_path".to_string();
|
||||||
|
let tetraplets = vec![vec![tetraplet]];
|
||||||
|
|
||||||
|
let cp = CallParameters {
|
||||||
|
init_peer_id: init_peer_id.to_string(),
|
||||||
|
service_id: service_id.to_string(),
|
||||||
|
service_creator_peer_id: service_creator_peer_id.to_string(),
|
||||||
|
host_id: host_id.to_string(),
|
||||||
|
particle_id: particle_id.to_string(),
|
||||||
|
tetraplets: tetraplets.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let actual = call_parameters_m.call_parameters_cp(cp);
|
||||||
|
let expected = format!(
|
||||||
|
"{}\n{}\n{}\n{}\n{}\n{:?}",
|
||||||
|
init_peer_id, service_id, service_creator_peer_id, host_id, particle_id, tetraplets
|
||||||
|
);
|
||||||
|
assert_eq!(actual, expected);
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
mod utils;
|
||||||
|
|
||||||
|
use utils::test_marine_test_token_streams;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_empty_func() {
|
||||||
|
assert!(test_marine_test_token_streams(
|
||||||
|
"tests/generation_tests/empty_func/marine_test.rs",
|
||||||
|
"tests/generation_tests/empty_func/expanded.rs",
|
||||||
|
"Config.toml",
|
||||||
|
"artifacts"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mounted_binary() {
|
||||||
|
assert!(test_marine_test_token_streams(
|
||||||
|
"tests/generation_tests/mounted_binary/marine_test.rs",
|
||||||
|
"tests/generation_tests/mounted_binary/expanded.rs",
|
||||||
|
"Config.toml",
|
||||||
|
"artifacts"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_multiple_modules() {
|
||||||
|
assert!(test_marine_test_token_streams(
|
||||||
|
"tests/generation_tests/multiple_modules/marine_test.rs",
|
||||||
|
"tests/generation_tests/multiple_modules/expanded.rs",
|
||||||
|
"Config.toml",
|
||||||
|
"artifacts"
|
||||||
|
));
|
||||||
|
}
|
48
crates/marine-test-macro-impl/tests/utils.rs
Normal file
48
crates/marine-test-macro-impl/tests/utils.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2021 Fluence Labs Limited
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
use marine_test_macro_impl::marine_test_impl;
|
||||||
|
|
||||||
|
use marine_macro_testing_utils::{items_from_file, stream_from_file, to_syn_item};
|
||||||
|
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
pub fn test_marine_test_token_streams<FP, EP>(
|
||||||
|
marine_path: FP,
|
||||||
|
expanded_path: EP,
|
||||||
|
config_path: &str,
|
||||||
|
modules_dir: &str,
|
||||||
|
) -> bool
|
||||||
|
where
|
||||||
|
FP: AsRef<Path>,
|
||||||
|
EP: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let marine_item = stream_from_file(&marine_path);
|
||||||
|
let test_token_stream = quote::quote! { #marine_item };
|
||||||
|
let buf = marine_path.as_ref().to_path_buf();
|
||||||
|
let attrs = quote::quote! {config_path = #config_path, modules_dir = #modules_dir};
|
||||||
|
let marine_token_streams = marine_test_impl(
|
||||||
|
attrs,
|
||||||
|
test_token_stream,
|
||||||
|
buf.parent().unwrap().to_path_buf(),
|
||||||
|
)
|
||||||
|
.unwrap_or_else(|e| panic!("failed to apply the marine macro due {}", e));
|
||||||
|
|
||||||
|
let expanded_item = items_from_file(&expanded_path);
|
||||||
|
let marine_item = to_syn_item(marine_token_streams.clone());
|
||||||
|
|
||||||
|
marine_item == expanded_item
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "marine-test-macro"
|
name = "marine-test-macro"
|
||||||
version = "0.1.11" # remember to update html_root_url
|
version = "0.2.0" # remember to update html_root_url
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Definition of the `#[marine_test]` macro"
|
description = "Definition of the `#[marine_test]` macro"
|
||||||
documentation = "https://docs.rs/fluence/marine-test-macro"
|
documentation = "https://docs.rs/fluence/marine-test-macro"
|
||||||
@ -18,7 +18,7 @@ proc-macro = true
|
|||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
marine-test-macro-impl = { path = "../marine-test-macro-impl", version = "=0.1.11" }
|
marine-test-macro-impl = { path = "../marine-test-macro-impl", version = "=0.2.0" }
|
||||||
|
|
||||||
quote = "1.0.9"
|
quote = "1.0.9"
|
||||||
proc-macro2 = "1.0.24"
|
proc-macro2 = "1.0.24"
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/sdk-test-macro/0.1.11")]
|
#![doc(html_root_url = "https://docs.rs/sdk-test-macro/0.2.0")]
|
||||||
#![deny(
|
#![deny(
|
||||||
dead_code,
|
dead_code,
|
||||||
nonstandard_style,
|
nonstandard_style,
|
||||||
@ -36,7 +36,7 @@ use syn::spanned::Spanned;
|
|||||||
/// This macro allows user to write tests for services in the following form:
|
/// This macro allows user to write tests for services in the following form:
|
||||||
///```rust
|
///```rust
|
||||||
/// #[marine_test(config = "/path/to/Config.toml", modules_dir = "path/to/service/modules")]
|
/// #[marine_test(config = "/path/to/Config.toml", modules_dir = "path/to/service/modules")]
|
||||||
/// fn test() {
|
/// fn test(greeting: marine_test_env::greeting::ModuleInterface) {
|
||||||
/// let service_result = greeting.greeting("John".to_string());
|
/// let service_result = greeting.greeting("John".to_string());
|
||||||
/// assert_eq!(&service_result, "Hi, name!");
|
/// assert_eq!(&service_result, "Hi, name!");
|
||||||
/// }
|
/// }
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "marine-rs-sdk-test"
|
name = "marine-rs-sdk-test"
|
||||||
version = "0.1.11" # remember to update html_root_url
|
version = "0.2.0" # remember to update html_root_url
|
||||||
description = "Backend SDK that allows testing modules for the Marine runtime"
|
description = "Backend SDK that allows testing modules for the Marine runtime"
|
||||||
documentation = "https://docs.rs/marine-rs-sdk-test"
|
documentation = "https://docs.rs/marine-rs-sdk-test"
|
||||||
repository = "https://github.com/fluencelabs/marine-rs-sdk/tree/master/fluence-test"
|
repository = "https://github.com/fluencelabs/marine-rs-sdk/tree/master/fluence-test"
|
||||||
@ -17,8 +17,11 @@ all-features = true
|
|||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
doctest = false
|
doctest = false
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
trybuild = "1.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
marine-test-macro = { path = "../crates/marine-test-macro", version = "=0.1.11" }
|
marine-test-macro = { path = "../crates/marine-test-macro", version = "=0.2.0" }
|
||||||
fluence-app-service = { version = "0.9.0", features = ["raw-module-api"] }
|
fluence-app-service = { version = "0.9.0", features = ["raw-module-api"] }
|
||||||
|
|
||||||
serde = { version = "1.0.118", features = ["derive"] }
|
serde = { version = "1.0.118", features = ["derive"] }
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#![doc(html_root_url = "https://docs.rs/sdk-test/0.1.11")]
|
#![doc(html_root_url = "https://docs.rs/sdk-test/0.2.0")]
|
||||||
#![deny(
|
#![deny(
|
||||||
dead_code,
|
dead_code,
|
||||||
nonstandard_style,
|
nonstandard_style,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user