From 11cc9113cc67942df6bb3ab545c5cac10e524ec9 Mon Sep 17 00:00:00 2001 From: ksolana <110843012+ksolana@users.noreply.github.com> Date: Tue, 2 Apr 2024 22:16:31 -0700 Subject: [PATCH 1/3] fix doc to mention MOVE_NATIVE --- .../move/solana/move-mv-llvm-compiler/docs/Development.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/external-crates/move/solana/move-mv-llvm-compiler/docs/Development.md b/external-crates/move/solana/move-mv-llvm-compiler/docs/Development.md index 0e8d8ce5dc79c7..e9a1d93cb1fe68 100644 --- a/external-crates/move/solana/move-mv-llvm-compiler/docs/Development.md +++ b/external-crates/move/solana/move-mv-llvm-compiler/docs/Development.md @@ -280,7 +280,7 @@ Add these to settings.json file }, "rust-analyzer.server.extraEnv": { "LLVM_SYS_170_PREFIX":"/path/to/platform-tools-1.41/move-dev", - "MOVE_NATIVE_PATH":"/path/to/move/language/move-native", + "MOVE_NATIVE":"/path/to/move/language/move-native", "PLATFORM_TOOLS_ROOT":"/path/to/platform-tools-1.41" }, ``` From 69123242e14e7dad55a2a93d4e434d46fa77633d Mon Sep 17 00:00:00 2001 From: ksolana <110843012+ksolana@users.noreply.github.com> Date: Mon, 15 Apr 2024 10:50:36 -0700 Subject: [PATCH 2/3] Gas limit to limit execution of unbounded methods After Jan's fix on adding terminators to basic blocks with infinite loops, all the remaining tests can be fixed by having a reasonable compute budget. This patch creates a new compute budget for Solana tests. A possible extension will be to allow each test to specify a compute budget (added as a TODO in test_runner.rs:exec_module_tests_solana) --- .../tests/concrete_check_testsuite.rs | 4 ++-- .../move/crates/move-cli/src/base/test.rs | 4 ++-- .../crates/move-unit-test/src/cargo_runner.rs | 3 ++- .../move/crates/move-unit-test/src/lib.rs | 15 ++++++++++----- .../move/crates/move-unit-test/src/main.rs | 4 ++-- .../crates/move-unit-test/src/test_runner.rs | 4 +++- .../tests/move_unit_test_testsuite.rs | 6 +++--- .../test_sources/other_expected_failures.move | 3 +-- .../other_expected_failures.solana.exp | 5 ++++- .../tests/test_sources/out_of_gas.move | 3 +-- .../tests/test_sources/out_of_gas.solana.exp | 5 ++++- .../tests/test_sources/timeout.move | 6 ++---- .../tests/test_sources/timeout.solana.exp | 17 ++++++++++++++--- .../move/solana/move-to-solana/src/runner.rs | 17 ++++++++++------- 14 files changed, 60 insertions(+), 36 deletions(-) diff --git a/external-crates/move/crates/bytecode-interpreter-testsuite/tests/concrete_check_testsuite.rs b/external-crates/move/crates/bytecode-interpreter-testsuite/tests/concrete_check_testsuite.rs index 329ac07732c7fd..e1283e5cb80567 100644 --- a/external-crates/move/crates/bytecode-interpreter-testsuite/tests/concrete_check_testsuite.rs +++ b/external-crates/move/crates/bytecode-interpreter-testsuite/tests/concrete_check_testsuite.rs @@ -7,7 +7,7 @@ use std::{env, path::Path}; use move_command_line_common::{env::read_bool_env_var, testing::EXP_EXT}; use move_prover_test_utils::baseline_test::verify_or_update_baseline; use move_stdlib::move_stdlib_files; -use move_unit_test::UnitTestingConfig; +use move_unit_test::{UnitTestingConfig, DEFAULT_EXECUTION_BOUND_SOLANA}; fn test_runner(path: &Path) -> datatest_stable::Result<()> { env::set_var("NO_COLOR", "1"); @@ -29,7 +29,7 @@ fn test_runner(path: &Path) -> datatest_stable::Result<()> { let test_plan = config.build_test_plan().unwrap(); let mut buffer = vec![]; - config.run_and_report_unit_tests(test_plan, None, None, &mut buffer)?; + config.run_and_report_unit_tests(test_plan, None, None, &mut buffer, DEFAULT_EXECUTION_BOUND_SOLANA)?; let output = String::from_utf8(buffer)?; let baseline_path = path.with_extension(EXP_EXT); diff --git a/external-crates/move/crates/move-cli/src/base/test.rs b/external-crates/move/crates/move-cli/src/base/test.rs index 8112dcb0510d07..bddbaafac14c0d 100644 --- a/external-crates/move/crates/move-cli/src/base/test.rs +++ b/external-crates/move/crates/move-cli/src/base/test.rs @@ -14,7 +14,7 @@ use move_compiler::{ }; use move_coverage::coverage_map::{output_map_to_file, CoverageMap}; use move_package::{compilation::build_plan::BuildPlan, BuildConfig}; -use move_unit_test::UnitTestingConfig; +use move_unit_test::{UnitTestingConfig, DEFAULT_EXECUTION_BOUND_SOLANA_STDLIB_TEST}; use move_vm_test_utils::gas_schedule::CostTable; use std::{ collections::HashMap, @@ -241,7 +241,7 @@ pub fn run_move_unit_tests( // Run the tests. If any of the tests fail, then we don't produce a coverage report, so cleanup // the trace files. if !unit_test_config - .run_and_report_unit_tests(test_plan, Some(natives), cost_table, writer) + .run_and_report_unit_tests(test_plan, Some(natives), cost_table, writer, DEFAULT_EXECUTION_BOUND_SOLANA_STDLIB_TEST) .unwrap() .1 { diff --git a/external-crates/move/crates/move-unit-test/src/cargo_runner.rs b/external-crates/move/crates/move-unit-test/src/cargo_runner.rs index 0784e5ebad505d..8dee75077f7fc1 100644 --- a/external-crates/move/crates/move-unit-test/src/cargo_runner.rs +++ b/external-crates/move/crates/move-unit-test/src/cargo_runner.rs @@ -6,7 +6,7 @@ use move_command_line_common::files::find_filenames; use move_vm_runtime::native_functions::NativeFunctionTable; use move_vm_test_utils::gas_schedule::CostTable; -use crate::UnitTestingConfig; +use crate::{UnitTestingConfig, DEFAULT_EXECUTION_BOUND}; pub fn run_tests_with_config_and_filter( mut config: UnitTestingConfig, @@ -40,6 +40,7 @@ pub fn run_tests_with_config_and_filter( native_function_table, cost_table, std::io::stdout(), + DEFAULT_EXECUTION_BOUND ) .expect("Failed to execute tests"); diff --git a/external-crates/move/crates/move-unit-test/src/lib.rs b/external-crates/move/crates/move-unit-test/src/lib.rs index 71ec764f7cb9e3..dcfa992387c0f6 100644 --- a/external-crates/move/crates/move-unit-test/src/lib.rs +++ b/external-crates/move/crates/move-unit-test/src/lib.rs @@ -28,7 +28,10 @@ use std::{ }; /// The default value bounding the amount of gas consumed in a test. -const DEFAULT_EXECUTION_BOUND: u64 = 1_000_000; +pub const DEFAULT_EXECUTION_BOUND: u64 = 1_000_000; +pub const DEFAULT_EXECUTION_BOUND_SOLANA: u64 = 10000; +// TODO: Remove this after tests have the ability to provide gas_limit. anza-xyz/sui/issues/20 +pub const DEFAULT_EXECUTION_BOUND_SOLANA_STDLIB_TEST: u64 = u64::MAX; #[derive(Debug, Parser, Clone)] #[clap(author, version, about)] @@ -195,6 +198,7 @@ impl UnitTestingConfig { native_function_table: Option, cost_table: Option, writer: W, + gas_limit: u64, ) -> Result<(W, bool)> { let shared_writer = Mutex::new(writer); @@ -213,13 +217,14 @@ impl UnitTestingConfig { } writeln!(shared_writer.lock().unwrap(), "Running Move unit tests")?; - let num_threads = if cfg!(feature = "solana-backend") { - 1 // enforce single threaded execution for Solana, as llvm-sys is not re-entrant. + let (num_threads, cgas_limit) = if cfg!(feature = "solana-backend") { + (1, gas_limit) // enforce single threaded execution for Solana, as llvm-sys is not re-entrant. } else { - self.num_threads + (self.num_threads, self.gas_limit.unwrap()) }; + let mut test_runner = TestRunner::new( - self.gas_limit.unwrap_or(DEFAULT_EXECUTION_BOUND), + cgas_limit, num_threads, self.check_stackless_vm, self.verbose, diff --git a/external-crates/move/crates/move-unit-test/src/main.rs b/external-crates/move/crates/move-unit-test/src/main.rs index f3521bcc2ceb50..15327d00fe083d 100644 --- a/external-crates/move/crates/move-unit-test/src/main.rs +++ b/external-crates/move/crates/move-unit-test/src/main.rs @@ -3,14 +3,14 @@ // SPDX-License-Identifier: Apache-2.0 use clap::*; -use move_unit_test::UnitTestingConfig; +use move_unit_test::{UnitTestingConfig, DEFAULT_EXECUTION_BOUND}; pub fn main() { let args = UnitTestingConfig::parse(); let test_plan = args.build_test_plan(); if let Some(test_plan) = test_plan { - args.run_and_report_unit_tests(test_plan, None, None, std::io::stdout()) + args.run_and_report_unit_tests(test_plan, None, None, std::io::stdout(), DEFAULT_EXECUTION_BOUND) .unwrap(); } } diff --git a/external-crates/move/crates/move-unit-test/src/test_runner.rs b/external-crates/move/crates/move-unit-test/src/test_runner.rs index 6ba355c35a2092..23357d4016ef02 100644 --- a/external-crates/move/crates/move-unit-test/src/test_runner.rs +++ b/external-crates/move/crates/move-unit-test/src/test_runner.rs @@ -529,6 +529,8 @@ impl SharedTestingConfig { } let gen_options = move_to_solana::options::Options::default(); + // TODO: Get the compute budget from the test file. anza-xyz/sui/issues/20 + let compute_budget = move_to_solana::runner::compute_budget(self.execution_bound); for (function_name, test_info) in &test_plan.tests { let shared_object = match move_to_solana::run_for_unit_test( @@ -555,7 +557,7 @@ impl SharedTestingConfig { } }; - let (result, duration) = move_to_solana::runner::run_solana_vm(shared_object); + let (result, duration) = move_to_solana::runner::run_solana_vm(shared_object, compute_budget); let test_run_info = || -> TestRunInfo { TestRunInfo::new(function_name.to_string(), duration, result.compute_units) }; diff --git a/external-crates/move/crates/move-unit-test/tests/move_unit_test_testsuite.rs b/external-crates/move/crates/move-unit-test/tests/move_unit_test_testsuite.rs index 43a25645b8f4ac..eac9ce02ee57bb 100644 --- a/external-crates/move/crates/move-unit-test/tests/move_unit_test_testsuite.rs +++ b/external-crates/move/crates/move-unit-test/tests/move_unit_test_testsuite.rs @@ -5,7 +5,7 @@ use move_command_line_common::testing::{ add_update_baseline_fix, format_diff, read_env_update_baseline, EXP_EXT, }; -use move_unit_test::{self, UnitTestingConfig}; +use move_unit_test::{self, UnitTestingConfig, DEFAULT_EXECUTION_BOUND, DEFAULT_EXECUTION_BOUND_SOLANA}; use regex::RegexBuilder; use std::{ fs, @@ -34,12 +34,12 @@ fn run_test_with_modifiers( if !cfg!(feature = "solana-backend") { results.push(( - unit_test_config.run_and_report_unit_tests(test_plan.unwrap(), None, None, buffer)?, + unit_test_config.run_and_report_unit_tests(test_plan.unwrap(), None, None, buffer, DEFAULT_EXECUTION_BOUND)?, path.with_extension(EXP_EXT), )); } else { results.push(( - unit_test_config.run_and_report_unit_tests(test_plan.unwrap(), None, None, buffer)?, + unit_test_config.run_and_report_unit_tests(test_plan.unwrap(), None, None, buffer, DEFAULT_EXECUTION_BOUND_SOLANA)?, path.with_extension(format!("{}.{}", "solana", EXP_EXT)), )); } diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/other_expected_failures.move b/external-crates/move/crates/move-unit-test/tests/test_sources/other_expected_failures.move index def48c42ebe228..c0a81b502a4f8d 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/other_expected_failures.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/other_expected_failures.move @@ -26,8 +26,7 @@ module 0x42::m { #[test] #[expected_failure(out_of_gas, location=Self)] fun t4() { - // fixme solana - bb without terminator - //loop {} + loop {} } } diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/other_expected_failures.solana.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/other_expected_failures.solana.exp index 2b5bc5b93a643d..3803ae79d499d3 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/other_expected_failures.solana.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/other_expected_failures.solana.exp @@ -36,7 +36,10 @@ Failures in 0x42::m: ┌── t4 ────── -│ Test did not error as expected +│ Failed to run a program on Solana VM. +│ +│ +│ Err(ExceededMaxInstructions(3248)) └────────────────── Test result: FAILED. Total tests: 5; passed: 0; failed: 5 diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/out_of_gas.move b/external-crates/move/crates/move-unit-test/tests/test_sources/out_of_gas.move index 18e0921e85c0e9..78e171ae3673ee 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/out_of_gas.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/out_of_gas.move @@ -7,8 +7,7 @@ fun t0() {} #[test] #[expected_failure(arithmetic_error, location=Self)] fun t1() { - // fixme solana - bb without terminator - //loop {} + loop {} } #[test] diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/out_of_gas.solana.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/out_of_gas.solana.exp index 739c0a08810df6..f5b6039bd65ac5 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/out_of_gas.solana.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/out_of_gas.solana.exp @@ -13,7 +13,10 @@ Failures in 0x42::m: ┌── t1 ────── -│ Test did not error as expected +│ Failed to run a program on Solana VM. +│ +│ +│ Err(ExceededMaxInstructions(3182)) └────────────────── diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.move b/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.move index eca78f836ba0fa..1c045830269af6 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.move +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.move @@ -2,15 +2,13 @@ address 0x1 { module M { #[test] fun timeout_fail() { - // fixme solana - bb without terminator - //while (true) {} + while (true) {} } #[test] #[expected_failure] fun timeout_fail_with_expected_failure() { - // fixme solana - bb without terminator - //while (true) {} + while (true) {} } #[test] diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.solana.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.solana.exp index ce1e7e7535d18c..1c0b112892d682 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.solana.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.solana.exp @@ -2,7 +2,7 @@ Running Move unit tests [ PASS ] 0x1::M::no_timeout [ FAIL ] 0x1::M::no_timeout_fail [ PASS ] 0x1::M::no_timeout_while_loop -[ PASS ] 0x1::M::timeout_fail +[ FAIL ] 0x1::M::timeout_fail [ FAIL ] 0x1::M::timeout_fail_with_expected_failure Test failures: @@ -14,8 +14,19 @@ Failures in 0x1::M: └────────────────── +┌── timeout_fail ────── +│ Failed to run a program on Solana VM. +│ +│ +│ Err(ExceededMaxInstructions(110)) +└────────────────── + + ┌── timeout_fail_with_expected_failure ────── -│ Test did not error as expected +│ Failed to run a program on Solana VM. +│ +│ +│ Err(ExceededMaxInstructions(112)) └────────────────── -Test result: FAILED. Total tests: 5; passed: 3; failed: 2 +Test result: FAILED. Total tests: 5; passed: 2; failed: 3 diff --git a/external-crates/move/solana/move-to-solana/src/runner.rs b/external-crates/move/solana/move-to-solana/src/runner.rs index ce1b9d73d7f117..b810a55397ba81 100644 --- a/external-crates/move/solana/move-to-solana/src/runner.rs +++ b/external-crates/move/solana/move-to-solana/src/runner.rs @@ -67,6 +67,15 @@ pub struct ExecuteResult { pub log: String, } +pub fn compute_budget(execution_bound: u64) -> ComputeBudget { + ComputeBudget { + compute_unit_limit: execution_bound, + heap_size: Some(10000000), + max_call_depth: 8192, + ..ComputeBudget::default() + } +} + fn load_input(path: PathBuf) -> serde_json::Result { debug!("Reading input file {path:?}"); let file = fs::File::open(path).unwrap(); @@ -314,17 +323,11 @@ fn execution_result( } } -pub fn run_solana_vm(exe: String) -> (ExecuteResult, Duration) { +pub fn run_solana_vm(exe: String, compute_budget: ComputeBudget) -> (ExecuteResult, Duration) { let exe = Path::new(&exe); let (instruction_accounts, transaction_accounts, instruction_data, program_id) = parse_input("input.json"); - let compute_budget = ComputeBudget { - compute_unit_limit: i64::MAX as u64, - heap_size: Some(10000000), - max_call_depth: 8192, - ..ComputeBudget::default() - }; let mut transaction_context = TransactionContext::new( transaction_accounts, Some(Rent::default()), From f923b0be74b6f50ec0a631f83a6984cff2c707d0 Mon Sep 17 00:00:00 2001 From: Jan Civlin <30603832+jcivlin@users.noreply.github.com> Date: Fri, 19 Apr 2024 10:27:32 -0700 Subject: [PATCH 3/3] Support naked expected_failure in tests (#22) * 041924-naked-expected_failure: ini * 041924-naked-expected_failure: test * 041924-naked-expected_failure: expected result update --- .../move/crates/move-stdlib/tests/vector_tests.move | 5 ++--- .../move/crates/move-unit-test/src/test_runner.rs | 6 ++++++ .../tests/test_sources/timeout.solana.exp | 12 ++---------- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/external-crates/move/crates/move-stdlib/tests/vector_tests.move b/external-crates/move/crates/move-stdlib/tests/vector_tests.move index 99008a1a37be59..65bfe6040d0058 100644 --- a/external-crates/move/crates/move-stdlib/tests/vector_tests.move +++ b/external-crates/move/crates/move-stdlib/tests/vector_tests.move @@ -565,9 +565,8 @@ module std::vector_tests { }; } - // todo solana - //#[test] - //#[expected_failure(vector_error, minor_status = 4, location = Self)] + #[test] + #[expected_failure] fun size_limit_fail() { let v = V::empty(); let i = 0; diff --git a/external-crates/move/crates/move-unit-test/src/test_runner.rs b/external-crates/move/crates/move-unit-test/src/test_runner.rs index 23357d4016ef02..41333cd99fd144 100644 --- a/external-crates/move/crates/move-unit-test/src/test_runner.rs +++ b/external-crates/move/crates/move-unit-test/src/test_runner.rs @@ -660,6 +660,12 @@ impl SharedTestingConfig { output.pass(function_name); stats.test_success(test_run_info(), test_plan); } + // Support tests with naked expected_failure, for example size_limit_fail in vector_tests.move + (Some( + ExpectedFailure::Expected), move_to_solana::runner::ExitReason::Failure) => { + output.pass(function_name); + stats.test_success(test_run_info(), test_plan); + } (_exp, _reason) => { output.fail(function_name); stats.test_failure( diff --git a/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.solana.exp b/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.solana.exp index 1c0b112892d682..eaddb787a1786a 100644 --- a/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.solana.exp +++ b/external-crates/move/crates/move-unit-test/tests/test_sources/timeout.solana.exp @@ -3,7 +3,7 @@ Running Move unit tests [ FAIL ] 0x1::M::no_timeout_fail [ PASS ] 0x1::M::no_timeout_while_loop [ FAIL ] 0x1::M::timeout_fail -[ FAIL ] 0x1::M::timeout_fail_with_expected_failure +[ PASS ] 0x1::M::timeout_fail_with_expected_failure Test failures: @@ -21,12 +21,4 @@ Failures in 0x1::M: │ Err(ExceededMaxInstructions(110)) └────────────────── - -┌── timeout_fail_with_expected_failure ────── -│ Failed to run a program on Solana VM. -│ -│ -│ Err(ExceededMaxInstructions(112)) -└────────────────── - -Test result: FAILED. Total tests: 5; passed: 2; failed: 3 +Test result: FAILED. Total tests: 5; passed: 3; failed: 2