From 4bf9152fc49df12e8e17f55c8364e9f83a4cd30b Mon Sep 17 00:00:00 2001 From: Maksim Dimitrov Date: Tue, 8 Aug 2023 08:58:55 +0300 Subject: [PATCH] Refactor/cli commands and options (#15) * refactor(cli)!: Remove nothing injection. Add inject and decode subcommads Signed-off-by: Maksim Dimitrov * chore(tests): Remove stack_limiter tests Signed-off-by: Maksim Dimitrov * refactor(cli): Fix naming when no destination file is passed Signed-off-by: Maksim Dimitrov * ci: Add github workflow for crago test, fmt, clippy Signed-off-by: Maksim Dimitrov * chore(cargo): Update clap version Signed-off-by: Maksim Dimitrov * Make the julia script to execute tests for a specific host only Signed-off-by: Maksim Dimitrov * refactor(cli): Rename Decode to Convert. Add convert options Signed-off-by: Maksim Dimitrov * Update the workflow Signed-off-by: Maksim Dimitrov * ci: Trigger zombienet workflow on changes to tests or main.taml Signed-off-by: Maksim Dimitrov * chore(cli): Update help messages Signed-off-by: Maksim Dimitrov * ci: Remove base_ref check Signed-off-by: Maksim Dimitrov * chore(readme): Update readme Signed-off-by: Maksim Dimitrov * chore(readme): Update folder name Signed-off-by: Maksim Dimitrov --------- Signed-off-by: Maksim Dimitrov --- .github/workflows/main.yaml | 27 +++--- .github/workflows/rust.yaml | 61 +++++++++++++ Cargo.toml | 2 +- README.md | 140 ++++++++++++++++++++--------- scripts/runTests.jl | 79 ++++++++++------- src/injecting/injections.rs | 24 +++-- src/injecting/injector.rs | 2 +- src/main.rs | 170 +++++++++++++++++++++++++++++------- src/stack_limiter.rs | 30 ------- src/util.rs | 5 +- 10 files changed, 379 insertions(+), 161 deletions(-) create mode 100644 .github/workflows/rust.yaml diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index 8f885bc..bb67e15 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -1,11 +1,13 @@ -name: Run zombienet tests +name: Zombienet on: schedule: - cron: '0 0 * * *' workflow_dispatch: - pull_request: - branches: [ develop ] + push: + paths: + - 'tests/**' + - '.github/workflows/main.yaml' jobs: check: @@ -91,12 +93,10 @@ jobs: git pull --rebase origin feat/cicd git push origin feat/cicd - - run-tests: runs-on: ubuntu-latest needs: check - if: ${{ needs.check.outputs.new_release == 'true' }} + if: needs.check.outputs.new_release == 'true' || github.event_name == 'push' steps: - name: Checkout uses: actions/checkout@v2 @@ -189,15 +189,18 @@ jobs: - name: Run wasm_injector run: | - ./target/debug/wasm_injector nothing ./target/debug/test.wasm ./wasm/orig.wasm.hex --hexified - ./target/debug/wasm_injector stack-overflow ./target/debug/test.wasm ./wasm/stack-overflow.wasm.hex --hexified - ./target/debug/wasm_injector heap-overflow ./target/debug/test.wasm ./wasm/heap-overflow.wasm.hex --hexified - ./target/debug/wasm_injector infinite-loop ./target/debug/test.wasm ./wasm/infinite-loop.wasm.hex --hexified + ./target/debug/wasm_injector convert ./target/debug/test.wasm ./wasm/orig.wasm.hex --hexified + ./target/debug/wasm_injector inject stack-overflow ./target/debug/test.wasm ./wasm/stack-overflow.wasm.hex --hexified + ./target/debug/wasm_injector inject heap-overflow ./target/debug/test.wasm ./wasm/heap-overflow.wasm.hex --hexified + ./target/debug/wasm_injector inject infinite-loop ./target/debug/test.wasm ./wasm/infinite-loop.wasm.hex --hexified - name: Set up Julia uses: julia-actions/setup-julia@v1 with: version: '1.9.1' - - name: Run Julia script - run: julia scripts/runTests.jl + - name: Run Polkadot Tests + run: julia scripts/runTests.jl polkadot + + - name: Run Kagome Tests + run: julia scripts/runTests.jl kagome diff --git a/.github/workflows/rust.yaml b/.github/workflows/rust.yaml new file mode 100644 index 0000000..1550950 --- /dev/null +++ b/.github/workflows/rust.yaml @@ -0,0 +1,61 @@ +name: Rust + +on: + push: + branches: + - master + - develop + pull_request: + branches: + - master + - develop + +env: + CARGO_TERM_COLOR: always + +jobs: + test: + name: Test Suite + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - uses: actions-rs/cargo@v1 + with: + command: test + + fmt: + name: Rustfmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - run: rustup component add rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --all -- --check + + clippy: + name: Clippy + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: stable + override: true + - run: rustup component add clippy + - uses: actions-rs/cargo@v1 + with: + command: clippy + args: -- -D warnings \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 7ae539d..4e02efb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -clap = { version = "4.3.10", features = [ "derive" ] } +clap = { version = "4.3.19", features = [ "derive" ] } itertools = "0.11.0" sp-maybe-compressed-blob = "5.0.0" thiserror = "1.0.40" diff --git a/README.md b/README.md index 796aa1d..99092eb 100644 --- a/README.md +++ b/README.md @@ -1,66 +1,120 @@ - # wasm-injector +# wasm_injector - `wasm-injector` is a Rust-based command line utility to manipulate WebAssembly (wasm) modules. It allows you to inject code, compress, and hexify a given wasm module. This utility is especially useful when you need to modify wasm files for testing, optimization, or debugging. +`wasm_injector` is a Rust-based command line utility to manipulate WebAssembly (wasm) modules. It allows you to inject code, compress, and hexify a given wasm module. This utility is especially useful when you need to modify wasm files for testing, optimization, or debugging. - ## Prerequisites +## Prerequisites - To use this utility, you need to have Rust installed on your system. If you don't have Rust installed, you can follow the official instructions [here](https://www.rust-lang.org/tools/install). +To use this utility, you need to have Rust installed on your system. If you don't have Rust installed, you can follow the official instructions [here](https://www.rust-lang.org/tools/install). - ## Installation +## Installation - Clone the repository and build the project with `cargo`, Rust's package manager: +Clone the repository and build the project with `cargo`, Rust's package manager: - ```sh - git clone https://github.com/your_github_username/wasm-injector.git - cd wasm-injector - cargo build --release - ``` +```sh +git clone https://github.com/LimeChain/parachain-conformance-dev.git +cd parachain-conformance-dev +cargo build --release +``` - This will create an executable in the `target/release` directory. +This will create an executable in the `target/release` directory. - ## Usage - - This project is developed to inject instructions in WASM modules or polkadot conformance testing. You can download a sample WASM file from [here](https://github.com/paritytech/cumulus/releases/tag/parachains-v9430). - - The script will automatically unhexify and decompress WASM modules passed in as input - - The general format to run the `wasm-injector` is as follows: +## Usage +- This project is developed to inject instructions in WASM modules or polkadot conformance testing. You can download a sample WASM file from [here](https://github.com/paritytech/cumulus/releases/tag/parachains-v9430). +- The script will automatically unhexify and decompress WASM modules passed in as input +- The general format to run the `wasm_injector` is as follows: - ```sh - ./wasm-injector [INJECTION] [SOURCE] [DESTINATION] [--compressed] [--hexified] - ``` +```sh +Usage: wasm_injector - - `[INJECTION]` (required): The type of injection to apply to the wasm module. Possible values ```possible values: [nothing, infinite-loop, jibberish-return-value, stack-overflow, noops, heap-overflow]``` +Commands: + inject Inject invalid instructions into a wasm module + convert Convert from `hexified` and/or `compressed` to `raw` wasm module and vice versa + help Print this message or the help of the given subcommand(s) - - `[SOURCE]` (required): A path to the wasm source file. If the wasm module is compressed or hexified, indicate this in the path name as "(hexified)" and/or "(compressed)". +Options: + -h, --help Print help + -V, --version Print version +``` - - `[DESTINATION]` (optional): A path where you want the output wasm file to be saved. If this argument is not provided, the modified wasm file will be saved alongside the source file with a predefined file name. +### Inject: +```sh +Usage: wasm_injector inject [OPTIONS] [DESTINATION] - - `--compressed` (optional): If this flag is provided, the output file will be compressed. +Arguments: + [possible values: infinite-loop, bad-return-value, stack-overflow, noops, heap-overflow] + Wasm source file path. Can be compressed and/or hexified. + [DESTINATION] Destination file path (optional). If not specified, the output file will be a prefixed source file name. - - `--hexified` (optional): If this flag is provided, the output file will be hexified (converted to a hexadecimal representation). +Options: + --compressed Compresses the wasm. Can be used with `--hexified` + --hexified Hexifies the wasm. Can be used with `--compressed` + -h, --help Print help +``` + +### Convert: +```sh +Usage: wasm_injector convert [OPTIONS] [DESTINATION] + +Arguments: + Wasm source file path. Can be compressed and/or hexified. + [DESTINATION] Destination file path (optional). If not specified, the output file will be a prefixed source file name. + +Options: + --raw Saves the file as raw wasm (default). Can not be used with `--compressed` or `--hexified`. + --compressed Compresses the wasm (zstd compression). Can be used with `--hexified`. + --hexified Hexifies the wasm. Can be used with `--compressed` + -h, --help Print help +``` ## Examples - To inject code into a wasm file, compress and hexify it, you can run: +### Inject: +To inject code into a wasm file, compress and hexify it, you can run: + +```sh +./wasm_injector inject noops my_wasm_file.wasm --compressed --hexified +``` + +To specify a custom destination path, you can run: + +```sh +./wasm_injector inject noops my_wasm_file.wasm my_destination_directory/injected_new_file.wasm +``` + +### Convert: + +#### From Compressed and/or Hexified Wasm to Raw (default): +```sh +./wasm_injector convert --raw compressed_and_hexified_wasm_file.wasm.hex raw_wasm_file.wasm +``` + +or + +```sh +./wasm_injector convert compressed_and_hexified_wasm_file.wasm.hex raw_wasm_file.wasm +``` + +#### From Raw Wasm to Compressed and/or Hexified: + +```sh +./wasm_injector convert --hexified raw_wasm_file.wasm heified_wasm_file.wasm.hex +``` + +```sh +./wasm_injector convert --compressed --hexified raw_wasm_file.wasm compressed_and_hexified_wasm_file.wasm.hex +``` - ```sh - ./wasm-injector noops my_wasm_file.wasm --compressed --hexified - ``` +To run the WASM you need Linux environment with [Zombienet](https://github.com/paritytech/zombienet) +For each test you need to specify the path to the WASM module in the corresponding `.toml` file before running the test - To specify a custom destination path, you can run: +```sh +zombienet -p native test ./tests/0001-parachains-pvf-compilation-time-bad.zndsl +``` - ```sh - ./wasm-injector noops my_wasm_file.wasm my_destination_directory/my_new_file.wasm - ``` - To run the WASM you need Linux environment with [Zombienet](https://github.com/paritytech/zombienet) - For each test you need to specify the path to the WASM module in the corresponding `.toml` file before running the test - - ```sh - zombienet -p native test ./tests/0001-parachains-pvf-compilation-time-bad.zndsl - ``` - - ## Contributing +## Contributing - Please feel free to contribute to the project. For major changes, please open an issue first to discuss what you would like to change. +Please feel free to contribute to the project. For major changes, please open an issue first to discuss what you would like to change. - ## License +## License - This project is licensed under [TODO]. See the LICENSE file for details. +This project is licensed under [TODO]. See the LICENSE file for details. diff --git a/scripts/runTests.jl b/scripts/runTests.jl index adea7cf..33ca14c 100644 --- a/scripts/runTests.jl +++ b/scripts/runTests.jl @@ -7,51 +7,64 @@ ENV["PATH"] *= ":$(pwd())/bin" # Tests directory tests_dir::String = get(ENV ,"ZN_TESTS", "./tests") -# Test output path -tests_output::String = get(ENV, "ZN_TEST_OUTPUT", "./tests_output") - # Arrays to accumulate passed and failed test names passed_tests::Vector{String} = [] failed_tests::Vector{String} = [] -# For each host ... -for host::String in hosts - withenv("ZOMBIENET_DEFAULT_START_COMMAND" => host) do - # Get host tests directory - host_tests_dir::String = joinpath(tests_dir, host) - # Filter out the non-`.zndsl` files for each host - tests::Vector{String} = filter(file -> endswith(file, ".zndsl"), readdir(host_tests_dir)) - - # ... run each test - for test::String in tests - if endswith(test, ".zndsl") - # Extract the index and test name from the test path - match_captures = match(r"(\d+)-(.*?)\.zndsl", basename(test)).captures - index::Int64 = parse(Int64, match_captures[1]) - test_name::String = match_captures[2] +function run_host_tests(host::String) + println("Running tests for host $(host)") + # Get host tests directory + host_tests_dir::String = joinpath(tests_dir, host) + # Filter out the non-`.zndsl` files for each host + tests::Vector{String} = filter(file -> endswith(file, ".zndsl"), readdir(host_tests_dir)) + + # ... run each test + for test::String in tests + if endswith(test, ".zndsl") + # Extract the index and test name from the test path + match_captures = match(r"(\d+)-(.*?)\.zndsl", basename(test)).captures + index::Int64 = parse(Int64, match_captures[1]) + test_name::String = match_captures[2] - # Prepare the `zombienet test` command - command::Cmd = `zombienet -p native test $(joinpath(host_tests_dir, test))` - full_test_name::String = "[$(host)] $(test_name)" - println("Running test $(full_test_name)") + # Prepare the `zombienet test` command + command::Cmd = `zombienet -p native test $(joinpath(host_tests_dir, test))` + full_test_name::String = "[$(host)] $(test_name)" + println("Running test $(full_test_name)") - # Try to run the test - try - # Try to run the command - run(command) + # Try to run the test + try + # Try to run the command + run(command) - # Add the test name to the passed tests array - push!(passed_tests, full_test_name) - catch e - showerror(stdout, e) - # Add the test name to the failed tests array - push!(failed_tests, full_test_name) - end + # Add the test name to the passed tests array + push!(passed_tests, full_test_name) + catch e + println(e) + # Add the test name to the failed tests array + push!(failed_tests, full_test_name) end end end end +if isempty(ARGS) + # For each host ... + for host::String in hosts + withenv("ZOMBIENET_DEFAULT_START_COMMAND" => host) do + run_host_tests(host) + end + end +else + # Get the host from the command line arguments + host::String = getindex(ARGS, 1) + if (length(findall( x -> x == host, hosts )) == 0) + println("Host `$(host)` not supported.") + exit(1) + end + # Run the tests for the specified host + run_host_tests(host) +end + # Report the passed and failed tests println("Passed tests:") println(passed_tests) diff --git a/src/injecting/injections.rs b/src/injecting/injections.rs index b056d1a..e9996d6 100644 --- a/src/injecting/injections.rs +++ b/src/injecting/injections.rs @@ -1,3 +1,4 @@ +use std::fmt::{Display, Formatter}; use wasm_instrument::parity_wasm::elements::{ BlockType, FuncBody, Instruction, Instructions, Module, }; @@ -17,9 +18,8 @@ use super::injector::FunctionMapper; #[derive(clap::ValueEnum, PartialEq, Eq, Clone, Debug)] pub enum Injection { - Nothing, InfiniteLoop, - JibberishReturnValue, + BadReturnValue, StackOverflow, Noops, HeapOverflow, @@ -33,14 +33,24 @@ impl Injection { } } +impl Display for Injection { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + Injection::InfiniteLoop => write!(f, "infinite-loop"), + Injection::BadReturnValue => write!(f, "bad-return-value"), + Injection::StackOverflow => write!(f, "stack-overflow"), + Injection::Noops => write!(f, "noops"), + Injection::HeapOverflow => write!(f, "heap-overflow"), + } + } +} type InjectionFn = dyn FnMut(&mut Module) -> Result<(), String>; /// # Takes an injection and returns a function that performs the injection. fn get_injection(injection: Injection) -> Box { Box::new(match injection { - Injection::Nothing => |_| Ok(()), Injection::InfiniteLoop => inject_infinite_loop, - Injection::JibberishReturnValue => inject_jibberish_return_value, + Injection::BadReturnValue => inject_bad_return_value, Injection::StackOverflow => inject_stack_overflow, Injection::Noops => inject_noops, Injection::HeapOverflow => inject_heap_overflow, @@ -66,7 +76,7 @@ fn inject_infinite_loop(module: &mut Module) -> Result<(), String> { } /// # Takes a module and injects a store and return on the last value from the stack in the beginning of the module. -fn inject_jibberish_return_value(module: &mut Module) -> Result<(), String> { +fn inject_bad_return_value(module: &mut Module) -> Result<(), String> { module.map_function("validate_block", |func_body: &mut FuncBody, _| { *func_body.code_mut() = Instructions::new(vec![ // Last value on the stack gets returned @@ -147,7 +157,7 @@ mod tests { function_body } - fn load_module() -> Module{ + fn load_module() -> Module { let module_path = Path::new(WASM_PATH); let module = load_module_from_wasm(module_path).unwrap(); module @@ -174,7 +184,7 @@ mod tests { #[test] fn test_inject_jibberish_return_value() { let mut module = load_module(); - let injection = Injection::JibberishReturnValue; + let injection = Injection::BadReturnValue; assert!(injection.inject(&mut module).is_ok()); diff --git a/src/injecting/injector.rs b/src/injecting/injector.rs index 09ee706..f88cee3 100644 --- a/src/injecting/injector.rs +++ b/src/injecting/injector.rs @@ -157,7 +157,7 @@ mod tests { const WASM_INSTRUCTION_COUNT: usize = 358; const WASM_PATH: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/test-wasm/test.wasm"); - fn load_module() -> Module{ + fn load_module() -> Module { let module_path = Path::new(WASM_PATH); let module = load_module_from_wasm(module_path).unwrap(); module diff --git a/src/main.rs b/src/main.rs index db9c323..2c67ba8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,68 +1,172 @@ -use clap::{Parser, ValueHint}; +use clap::{builder::ArgPredicate, Parser, Subcommand, ValueHint}; use std::path::PathBuf; use wasm_injector::injecting::injections::Injection; use wasm_injector::util::{load_module_from_wasm, modify_file_name, save_module_to_wasm}; #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] -struct Args { - #[arg(index = 1, required = true, value_name = "injection")] - injection: Injection, +struct Cli { + #[command(subcommand)] + action: Action, +} - #[arg(index = 2, required = true, value_name = "(hexified) (compressed) wasm source file", value_hint = ValueHint::FilePath)] - source: PathBuf, +#[derive(Debug, Subcommand)] +enum Action { + #[command(about = "Inject invalid instructions into a wasm module")] + Inject { + #[arg(required = true, value_name = "injection", value_hint = ValueHint::Other)] + injection: Injection, - #[arg(index = 3, value_name = "destination path (directory/file)", value_hint = ValueHint::FilePath)] - destination: Option, + #[command(flatten)] + global_opts: GlobalOpts, + + #[arg( + long, + value_name = "compressed", + help = "Compresses the wasm. Can be used with `--hexified`", + default_value_t = false + )] + compressed: bool, + + #[arg( + long, + value_name = "hexified", + help = "Hexifies the wasm. Can be used with `--compressed`", + default_value_t = false + )] + hexified: bool, + }, + #[command( + about = "Convert from `hexified` and/or `compressed` to `raw` wasm module and vice versa" + )] + Convert { + #[command(flatten)] + global_opts: GlobalOpts, - #[arg(long, value_name = "compressed", default_value_t = false)] - compressed: bool, + #[arg( + long, + value_name = "raw", + help = "Saves the file as raw wasm (default). Can not be used with `--compressed` or `--hexified`.", + default_value_t = true, + default_value_ifs = [ + ("compressed", ArgPredicate::IsPresent, "false"), + ("hexified", ArgPredicate::IsPresent, "false") + ], + conflicts_with_all = ["hexified", "compressed"] + )] + raw: bool, - #[arg(long, value_name = "hexified", default_value_t = false)] - hexified: bool, + #[arg( + long, + value_name = "compressed", + help = "Compresses the wasm (zstd compression). Can be used with `--hexified`.", + default_value_t = false + )] + compressed: bool, + + #[arg( + long, + value_name = "hexified", + help = "Hexifies the wasm. Can be used with `--compressed`", + default_value_t = false + )] + hexified: bool, + }, +} + +#[derive(Parser, Debug, Clone)] +struct ConvertOpts {} + +#[derive(Parser, Debug, Clone)] +struct GlobalOpts { + #[arg(required = true, help = "Wasm source file path. Can be compressed and/or hexified.", value_hint = ValueHint::FilePath)] + source: PathBuf, + + #[arg(help = "Destination file path (optional). If not specified, the output file will be a prefixed source file name. ", value_hint = ValueHint::FilePath)] + destination: Option, } fn main() -> Result<(), String> { - let Args { - injection, - source, - destination, - compressed, - hexified, - } = Args::parse(); + let Cli { action } = Cli::parse(); let calculate_default_destination_file_name = |file_name: &str| { let mut file_name = String::from(file_name); - if injection != Injection::Nothing { - file_name = format!("injected_{}", file_name); - } - if compressed { - file_name = format!("compressed_{}", file_name); - } - if hexified { - file_name = format!("hexified_{}.hex", file_name); + match &action { + Action::Inject { + injection, + hexified, + compressed, + .. + } => { + file_name = format!("{}-{}.wasm", injection, file_name); + if *compressed { + file_name = format!("compressed-{}", file_name); + } + if *hexified { + file_name = format!("hexified-{}.hex", file_name); + } + } + Action::Convert { + raw, + compressed, + hexified, + .. + } => { + println!( + "raw: {}, compressed: {}, hexified: {}", + raw, compressed, hexified + ); + if *raw { + file_name = format!("raw-{}.wasm", file_name); + } + if *compressed { + file_name = format!("compressed-{}", file_name); + } + if *hexified { + file_name = format!("hexified-{}.hex", file_name); + } + } } file_name }; - let destination = match destination { + let (global_opts, hexified, compressed) = match &action { + Action::Inject { + global_opts, + hexified, + compressed, + .. + } + | Action::Convert { + global_opts, + hexified, + compressed, + .. + } => (global_opts.clone(), *hexified, *compressed), + }; + + let destination = match global_opts.destination { // Creates a new file with the destination as name Some(destination_file) => destination_file, // There is no destination: // put it next to the source, surrounding it with the appropriate modifiers - None => modify_file_name(source.as_path(), calculate_default_destination_file_name)?, + None => modify_file_name( + global_opts.source.as_path(), + calculate_default_destination_file_name, + )?, }; // Get the module - let mut module = load_module_from_wasm(source.as_path())?; + let mut module = load_module_from_wasm(global_opts.source.as_path())?; - // "Inject" the module - injection.inject(&mut module)?; + if let Action::Inject { injection, .. } = action { + // Inject the module + injection.inject(&mut module)?; + } - // Save the modified module save_module_to_wasm(module, destination.as_path(), compressed, hexified)?; Ok(()) diff --git a/src/stack_limiter.rs b/src/stack_limiter.rs index 3d8b84d..3f4c755 100644 --- a/src/stack_limiter.rs +++ b/src/stack_limiter.rs @@ -116,33 +116,3 @@ fn show_information(path: &str, file_name: &str) { println!("entry: {:?}", entry); }); } - -#[cfg(test)] -mod tests { - #[test] - fn inject_stack_limiter() { - use super::*; - - let path = "wasm"; - let file_name = "rococo-parachain_runtime-v9400.compact.compressed.wasm"; - inject_single(path, file_name); - } - - #[test] - fn show_wasm_information() { - use super::*; - - let path = "wasm"; - let file_name = "rococo-parachain_runtime-v9381.compact.compressed.wasm"; - show_information(path, file_name); - } - - #[test] - fn decompress() { - use super::*; - - let path = "wasm"; - let file_name = "rococo-parachain_runtime-v9381.compact.compressed.wasm"; - decompress_wasm(path, file_name); - } -} diff --git a/src/util.rs b/src/util.rs index d82b4e3..736ba1d 100644 --- a/src/util.rs +++ b/src/util.rs @@ -43,7 +43,10 @@ pub fn get_file_name(path: &Path) -> Result<&str, String> { path.file_name() .ok_or(format!("{} is not a file", path.display()))? .to_str() - .ok_or("Couldn't convert filename to string".to_string()) + .ok_or("Couldn't convert filename to string".to_string())? + .split('.') + .next() + .ok_or("Couldn't get file name".to_string()) } /// # Modify the filename of a path. The mapper function will be called with the current filename