From 24523544f21d470c8354eb947627778ce688d266 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 19 Feb 2024 20:17:34 +0100 Subject: [PATCH 1/4] test: Use regex to extract state_transition sub-suite name --- test/unittests/state_transition.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/test/unittests/state_transition.cpp b/test/unittests/state_transition.cpp index 35a1ad0e78..4bcb838b3b 100644 --- a/test/unittests/state_transition.cpp +++ b/test/unittests/state_transition.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace fs = std::filesystem; @@ -147,16 +148,14 @@ namespace /// Creates the file path for the exported test based on its name. fs::path get_export_test_path(const testing::TestInfo& test_info, std::string_view export_dir) { - const std::string_view test_suite_name{test_info.test_suite_name()}; + const std::string suite_name{test_info.test_suite_name()}; const auto stem = fs::path{test_info.file()}.stem().string(); - auto filename = std::string_view{stem}; - if (filename.starts_with(test_suite_name)) - filename.remove_prefix(test_suite_name.size() + 1); - if (filename.ends_with("_test")) - filename.remove_suffix(5); + const std::regex re{suite_name + "_(.*)_test"}; + std::smatch m; + const auto sub_suite_name = std::regex_match(stem, m, re) ? m[1] : std::string{}; - const auto dir = fs::path{export_dir} / test_suite_name / filename; + const auto dir = fs::path{export_dir} / suite_name / sub_suite_name; fs::create_directories(dir); return dir / (std::string{test_info.name()} + ".json"); From 22579cbcaea02bcfffb681bd7aa8d7a53274b924 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 14 Feb 2024 13:35:15 +0100 Subject: [PATCH 2/4] test: ExportableFixture for JSON tests exporting Extract utils for JSON tests exporting to abstract `ExportableFixture`. --- test/unittests/CMakeLists.txt | 2 ++ test/unittests/exportable_fixture.cpp | 46 +++++++++++++++++++++++++++ test/unittests/exportable_fixture.hpp | 18 +++++++++++ test/unittests/state_transition.cpp | 40 +++-------------------- test/unittests/state_transition.hpp | 9 +++--- 5 files changed, 75 insertions(+), 40 deletions(-) create mode 100644 test/unittests/exportable_fixture.cpp create mode 100644 test/unittests/exportable_fixture.hpp diff --git a/test/unittests/CMakeLists.txt b/test/unittests/CMakeLists.txt index 5dc1d5899b..86f16da1a5 100644 --- a/test/unittests/CMakeLists.txt +++ b/test/unittests/CMakeLists.txt @@ -41,6 +41,8 @@ target_sources( evmmax_secp256k1_test.cpp evmone_test.cpp execution_state_test.cpp + exportable_fixture.hpp + exportable_fixture.cpp instructions_test.cpp state_block_test.cpp state_bloom_filter_test.cpp diff --git a/test/unittests/exportable_fixture.cpp b/test/unittests/exportable_fixture.cpp new file mode 100644 index 0000000000..316189a52a --- /dev/null +++ b/test/unittests/exportable_fixture.cpp @@ -0,0 +1,46 @@ +// evmone: Fast Ethereum Virtual Machine implementation +// Copyright 2024 The evmone Authors. +// SPDX-License-Identifier: Apache-2.0 + +#ifdef _MSC_VER +// Disable warning C4996: 'getenv': This function or variable may be unsafe. +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include "exportable_fixture.hpp" +#include +#include + +namespace fs = std::filesystem; + +namespace evmone::test +{ +namespace +{ +/// Creates the file path for the exported test based on its name. +fs::path get_export_test_path(const testing::TestInfo& test_info, std::string_view export_dir) +{ + const std::string suite_name{test_info.test_suite_name()}; + + const auto stem = fs::path{test_info.file()}.stem().string(); + const std::regex re{suite_name + "_(.*)_test"}; + std::smatch m; + const auto sub_suite_name = std::regex_match(stem, m, re) ? m[1] : std::string{}; + + const auto dir = fs::path{export_dir} / suite_name / sub_suite_name; + + fs::create_directories(dir); + return dir / (std::string{test_info.name()} + ".json"); +} +} // namespace + +ExportableFixture::ExportableFixture() +{ + if (const auto export_dir = std::getenv("EVMONE_EXPORT_TESTS"); export_dir != nullptr) + { + const auto& test_info = *testing::UnitTest::GetInstance()->current_test_info(); + export_test_name = test_info.name(); + export_file_path = get_export_test_path(test_info, export_dir).string(); + } +} +} // namespace evmone::test diff --git a/test/unittests/exportable_fixture.hpp b/test/unittests/exportable_fixture.hpp new file mode 100644 index 0000000000..892c544edb --- /dev/null +++ b/test/unittests/exportable_fixture.hpp @@ -0,0 +1,18 @@ +// evmone: Fast Ethereum Virtual Machine implementation +// Copyright 2024 The evmone Authors. +// SPDX-License-Identifier: Apache-2.0 +#pragma once + +#include + +namespace evmone::test +{ +class ExportableFixture : public testing::Test +{ +protected: + std::string_view export_test_name; + std::string export_file_path; + + ExportableFixture(); +}; +} // namespace evmone::test diff --git a/test/unittests/state_transition.cpp b/test/unittests/state_transition.cpp index 4bcb838b3b..65406772a7 100644 --- a/test/unittests/state_transition.cpp +++ b/test/unittests/state_transition.cpp @@ -2,20 +2,12 @@ // Copyright 2023 The evmone Authors. // SPDX-License-Identifier: Apache-2.0 -#ifdef _MSC_VER -// Disable warning C4996: 'getenv': This function or variable may be unsafe. -#define _CRT_SECURE_NO_WARNINGS -#endif - #include "state_transition.hpp" #include #include #include #include #include -#include - -namespace fs = std::filesystem; namespace evmone::test { @@ -139,36 +131,14 @@ void state_transition::TearDown() EXPECT_TRUE(expect.post.contains(addr)) << "unexpected account " << addr; } - if (const auto export_dir = std::getenv("EVMONE_EXPORT_TESTS"); export_dir != nullptr) - export_state_test(receipt, state, export_dir); -} - -namespace -{ -/// Creates the file path for the exported test based on its name. -fs::path get_export_test_path(const testing::TestInfo& test_info, std::string_view export_dir) -{ - const std::string suite_name{test_info.test_suite_name()}; - - const auto stem = fs::path{test_info.file()}.stem().string(); - const std::regex re{suite_name + "_(.*)_test"}; - std::smatch m; - const auto sub_suite_name = std::regex_match(stem, m, re) ? m[1] : std::string{}; - - const auto dir = fs::path{export_dir} / suite_name / sub_suite_name; - - fs::create_directories(dir); - return dir / (std::string{test_info.name()} + ".json"); + if (!export_file_path.empty()) + export_state_test(receipt, state); } -} // namespace -void state_transition::export_state_test( - const TransactionReceipt& receipt, const State& post, std::string_view export_dir) +void state_transition::export_state_test(const TransactionReceipt& receipt, const State& post) { - const auto& test_info = *testing::UnitTest::GetInstance()->current_test_info(); - json::json j; - auto& jt = j[test_info.name()]; + auto& jt = j[export_test_name]; auto& jenv = jt["env"]; jenv["currentNumber"] = hex0x(block.number); @@ -197,6 +167,6 @@ void state_transition::export_state_test( jpost["hash"] = hex0x(mpt_hash(post.get_accounts())); jpost["logs"] = hex0x(logs_hash(receipt.logs)); - std::ofstream{get_export_test_path(test_info, export_dir)} << std::setw(2) << j; + std::ofstream{export_file_path} << std::setw(2) << j; } } // namespace evmone::test diff --git a/test/unittests/state_transition.hpp b/test/unittests/state_transition.hpp index a7e9a383aa..c609b87e9c 100644 --- a/test/unittests/state_transition.hpp +++ b/test/unittests/state_transition.hpp @@ -3,8 +3,8 @@ // SPDX-License-Identifier: Apache-2.0 #pragma once +#include "exportable_fixture.hpp" #include -#include #include #include @@ -17,7 +17,7 @@ using namespace evmone::state; /// /// It takes the "pre" state and produces "post" state by applying the defined "tx" transaction. /// Then expectations declared in "except" are checked in the "post" state. -class state_transition : public testing::Test +class state_transition : public ExportableFixture { protected: /// The default sender address of the test transaction. @@ -91,9 +91,8 @@ class state_transition : public testing::Test /// The test runner. void TearDown() override; - /// Exports the test in the JSON State Test format in the given directory. - void export_state_test( - const TransactionReceipt& receipt, const State& post, std::string_view export_dir); + /// Exports the test in the JSON State Test format to ExportableFixture::export_out. + void export_state_test(const TransactionReceipt& receipt, const State& post); }; } // namespace evmone::test From 66fef058bc2d3943a50be32ec23d06b97ad254b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 21 Feb 2024 11:05:03 +0100 Subject: [PATCH 3/4] test: Verify any file has been created during export --- test/integration/statetest/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/integration/statetest/CMakeLists.txt b/test/integration/statetest/CMakeLists.txt index c6ce9dced9..46b668d75d 100644 --- a/test/integration/statetest/CMakeLists.txt +++ b/test/integration/statetest/CMakeLists.txt @@ -131,6 +131,15 @@ set_tests_properties( FIXTURES_SETUP EXPORT_JSON_TESTS ) +add_test( + NAME ${PREFIX}/export_to_json_created_files + COMMAND ${CMAKE_COMMAND} -E sha256sum ${EXPORT_DIR}/state_transition/block/known_block_hash.json +) +set_tests_properties( + ${PREFIX}/export_to_json_created_files PROPERTIES + FIXTURES_REQUIRED EXPORT_JSON_TESTS +) + add_test( NAME ${PREFIX}/execute_exported_tests # TODO: Broken exported tests are filtered out. From 5de76a652f1b9b379b4b1108147e8b676a25e5bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Wed, 21 Feb 2024 13:41:11 +0100 Subject: [PATCH 4/4] =?UTF-8?q?test:=20Rename=20eof=5F{stack=5Fvalidation?= =?UTF-8?q?=E2=86=92validation=5Fstack}=5Ftest.cpp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To follow the ExportableFixture file naming convention. --- test/unittests/CMakeLists.txt | 2 +- ..._stack_validation_test.cpp => eof_validation_stack_test.cpp} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename test/unittests/{eof_stack_validation_test.cpp => eof_validation_stack_test.cpp} (100%) diff --git a/test/unittests/CMakeLists.txt b/test/unittests/CMakeLists.txt index 86f16da1a5..a0b43159cc 100644 --- a/test/unittests/CMakeLists.txt +++ b/test/unittests/CMakeLists.txt @@ -9,7 +9,7 @@ target_sources( analysis_test.cpp blockchaintest_loader_test.cpp bytecode_test.cpp - eof_stack_validation_test.cpp + eof_validation_stack_test.cpp eof_test.cpp eof_validation.hpp eof_validation.cpp diff --git a/test/unittests/eof_stack_validation_test.cpp b/test/unittests/eof_validation_stack_test.cpp similarity index 100% rename from test/unittests/eof_stack_validation_test.cpp rename to test/unittests/eof_validation_stack_test.cpp