From 83c16e7ad9cb8b960e21933c9a441ff6d21a130f Mon Sep 17 00:00:00 2001 From: Eugen Wissner Date: Mon, 27 May 2024 22:58:54 +0200 Subject: [PATCH] Add missing virtual distructors --- CMakeLists.txt | 3 - include/elna/source/parser.hpp | 1 + include/elna/source/result.hpp | 2 + include/elna/tester.hpp | 44 ----- source/optimizer.cpp | 4 +- tests/tester.cpp | 319 --------------------------------- tools/tester.js | 11 +- 7 files changed, 10 insertions(+), 374 deletions(-) delete mode 100644 include/elna/tester.hpp delete mode 100755 tests/tester.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 9461ef6..215a0ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,9 +9,6 @@ find_package(Boost COMPONENTS program_options REQUIRED) find_package(FLEX) include_directories(${Boost_INCLUDE_DIR}) -add_executable(tester tests/tester.cpp include/elna/tester.hpp) -target_include_directories(tester PRIVATE include) - FLEX_TARGET(scanner source/scanner.l ${CMAKE_CURRENT_BINARY_DIR}/scanner.cpp) add_executable(elna cli/main.cpp diff --git a/include/elna/source/parser.hpp b/include/elna/source/parser.hpp index d32d078..5ad14a1 100644 --- a/include/elna/source/parser.hpp +++ b/include/elna/source/parser.hpp @@ -153,6 +153,7 @@ namespace elna::source explicit node(const position position); public: + virtual ~node() noexcept = default; virtual void accept(parser_visitor *) = 0; /** diff --git a/include/elna/source/result.hpp b/include/elna/source/result.hpp index f3761fa..acbc2cd 100644 --- a/include/elna/source/result.hpp +++ b/include/elna/source/result.hpp @@ -41,6 +41,8 @@ namespace elna::source error(const std::filesystem::path& path, const position position); public: + virtual ~error() noexcept = default; + /// Error text. virtual std::string what() const = 0; diff --git a/include/elna/tester.hpp b/include/elna/tester.hpp deleted file mode 100644 index fb1e6a1..0000000 --- a/include/elna/tester.hpp +++ /dev/null @@ -1,44 +0,0 @@ -#pragma once - -#include -#include - -#define BOOST_PROCESS_USE_STD_FS - -#include -#include -#include - -namespace elna -{ - enum class test_status - { - successful, - compile_failed, - expectation_failed, - }; - - class test_results final - { - std::uint32_t m_total{ 0 }; - std::uint32_t m_passed{ 0 }; - - public: - test_results() = default; - - std::uint32_t total() const noexcept; - std::uint32_t passed() const noexcept; - std::uint32_t failed() const noexcept; - - int exit_code() const noexcept; - void add_exit_code(const test_status result) noexcept; - }; - - boost::process::v2::process_stdio get_output_streams(const std::uint8_t stream_number, - boost::asio::readable_pipe& read_pipe); - int run_for_output(boost::asio::io_context& context, const std::uint8_t stream_number, - const std::filesystem::path& binary, std::initializer_list arguments); - test_status build_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry); - void run_test(boost::asio::io_context& context, const std::filesystem::path& test_entry); - void print_result(const std::filesystem::path& test_entry, const test_status& result); -} diff --git a/source/optimizer.cpp b/source/optimizer.cpp index be1b436..75c25e0 100644 --- a/source/optimizer.cpp +++ b/source/optimizer.cpp @@ -43,8 +43,8 @@ namespace elna::source void intermediate_code::clear() { this->instructions.clear(); - std::uint32_t variable_counter = 1; - std::uint32_t label_counter = 0; + this->m_variable_counter = 1; + this->m_label_counter = 0; } std::vector::iterator intermediate_code::begin() diff --git a/tests/tester.cpp b/tests/tester.cpp deleted file mode 100755 index 6707751..0000000 --- a/tests/tester.cpp +++ /dev/null @@ -1,319 +0,0 @@ -#include "elna/tester.hpp" - -#include -#include -#include -#include - -namespace elna -{ - std::uint32_t test_results::total() const noexcept - { - return m_total; - } - - std::uint32_t test_results::passed() const noexcept - { - return m_passed; - } - - std::uint32_t test_results::failed() const noexcept - { - return m_total - m_passed; - } - - int test_results::exit_code() const noexcept - { - return m_total == m_passed ? EXIT_SUCCESS : EXIT_FAILURE; - } - - void test_results::add_exit_code(const test_status status) noexcept - { - ++m_total; - if (status == test_status::successful) - { - ++m_passed; - } - } - - static std::filesystem::path in_build_directory() - { - return "build/riscv"; - } - - static std::string in_build_directory(const std::filesystem::path& path) - { - return in_build_directory() / path; - } - - static std::filesystem::path in_actual_directory() - { - return "build/tests"; - } - - static std::filesystem::path in_root_directory() - { - return "build/root"; - } - - static std::filesystem::path in_root_directory(const std::filesystem::path& path) - { - return in_root_directory() / path; - } - - boost::process::v2::process_stdio get_output_streams(const std::uint8_t stream_number, - boost::asio::readable_pipe& read_pipe) - { - if (stream_number == 1) - { - return boost::process::v2::process_stdio{ nullptr, read_pipe }; - } - if (stream_number == 2) - { - return boost::process::v2::process_stdio{ nullptr, {}, read_pipe }; - } - return boost::process::v2::process_stdio{ nullptr, read_pipe, read_pipe }; - } - - int run_for_output(boost::asio::io_context& context, const std::filesystem::path& log_path, - const std::filesystem::path& binary, std::initializer_list arguments) - { - boost::asio::readable_pipe read_pipe{ context }; - std::string output; - boost::asio::dynamic_string_buffer buffer = boost::asio::dynamic_buffer(output); - boost::system::error_code ec; - - boost::process::v2::process_stdio process_stdio; - boost::process::v2::process elna_child(context, binary, arguments, - boost::process::v2::process_stdio{ nullptr, read_pipe, 1 }); - std::ofstream log_file{ log_path }; - do - { - std::size_t transferred = read_pipe.read_some(buffer.prepare(512), ec); - - if (transferred == 0) - { - break; - } - buffer.commit(transferred); - log_file.write(boost::asio::buffer_cast(buffer.data()), buffer.size()); - buffer.consume(transferred); - } - while (ec == boost::system::errc::success); - - return elna_child.wait(); - } - - test_status build_test(boost::asio::io_context& context, const std::filesystem::directory_entry& test_entry) - { - const std::filesystem::path test_filename = test_entry.path().filename(); - - std::filesystem::path test_binary = in_root_directory("tests" / test_filename); - std::filesystem::path test_object = in_build_directory(test_filename); - std::filesystem::path test_log = in_build_directory(test_filename); - test_binary.replace_extension(); - test_object.replace_extension(".o"); - test_log.replace_extension(".log"); - - std::filesystem::remove(test_binary); - std::filesystem::remove(test_object); - - auto result_code = run_for_output(context, test_log, "./build/bin/elna", - { "-o", test_object.string(), test_entry.path().string() }); - if (result_code != 0) - { - return test_status::compile_failed; - } - test_status result = result_code == 0 ? test_status::successful : test_status::compile_failed; - std::vector environment; - std::vector linker_arguments = { "-o", test_binary.string() }; - - linker_arguments.push_back(test_object.string()); - - boost::process::v2::execute(boost::process::v2::process(context, boost::process::search_path("ld"), - linker_arguments - )); - return result; - } - - static test_status check_expectation(const std::filesystem::path& expectation_path, - const std::filesystem::path& actual_directory) - { - std::filesystem::path log_filename = expectation_path.filename(); - log_filename.replace_extension(".log"); - - std::filesystem::path test_log = actual_directory / log_filename; - - test_log.replace_extension(".log"); - boost::process::child diff( - boost::process::search_path("diff"), "-Nur", "--color", - expectation_path, test_log - ); - diff.wait(); - - if (diff.exit_code() == 0) - { - return test_status::successful; - } - return test_status::expectation_failed; - } - - void run_test(boost::asio::io_context& context, const std::filesystem::path& test_binary) - { - std::filesystem::path test_log = test_binary; - test_log.replace_extension(".log"); - - run_for_output(context, test_log, boost::process::search_path("qemu-riscv32"), - { test_binary.string() }); - } - - static void cpio_archive(boost::asio::io_context& context) - { - boost::asio::readable_pipe read_pipe{ context }; - boost::asio::writable_pipe write_pipe{ context }; - std::string output; - boost::asio::dynamic_string_buffer buffer = boost::asio::dynamic_buffer(output); - boost::system::error_code ec; - std::ofstream archive_output{ "build/root.cpio", std::ios::binary }; - boost::process::v2::process_stdio process_stdio; - auto current_path = std::filesystem::current_path(); - - std::filesystem::current_path(in_root_directory()); - boost::process::v2::process cpio_child(context, boost::process::search_path("cpio"), - { "-o", "--format=newc" }, - boost::process::v2::process_stdio{ write_pipe, read_pipe, nullptr }); - - for (const auto& entry : std::filesystem::recursive_directory_iterator(".")) - { - auto entry_path = entry.path().string() + "\n"; - auto entry_iterator = std::cbegin(entry_path); - std::size_t written{ 0 }; - - while (entry_iterator != std::cend(entry_path)) - { - std::size_t written = write_pipe.write_some(boost::asio::buffer(entry_iterator.base(), - std::distance(entry_iterator, std::cend(entry_path)))); - std::advance(entry_iterator, written); - } - } - - write_pipe.close(); - do - { - std::size_t transferred = read_pipe.read_some(buffer.prepare(512), ec); - - if (transferred == 0) - { - break; - } - buffer.commit(transferred); - archive_output.write(boost::asio::buffer_cast(buffer.data()), buffer.size()); - buffer.consume(transferred); - } - while (ec == boost::system::errc::success); - - std::filesystem::current_path(current_path); - } - - static void run_vm(boost::asio::io_context& context) - { - std::vector arguments = { - "-nographic", - "-M", "virt", - "-bios", "default", - "-kernel", "build/tools/linux-5.15.159/arch/riscv/boot/Image", - "-append", "quiet", - "-initrd", "build/root.cpio" - }; - auto process = boost::process::v2::process(context, - boost::process::search_path("qemu-system-riscv32"), arguments); - boost::process::v2::execute(std::move(process)); - } - - static void create_init() - { - std::filesystem::copy("build/tools/init", in_root_directory()); - } - - static test_results run_in_path(const std::filesystem::path test_directory) - { - test_results results; - boost::asio::io_context context; - - for (const auto& test_entry : std::filesystem::directory_iterator(test_directory)) - { - if (test_entry.path().extension() != ".eln" || !test_entry.is_regular_file()) - { - continue; - } - test_status result; - - std::cout << "Compiling " << test_entry << std::endl; - try - { - build_test(context, test_entry); - } - catch (const boost::process::process_error& exception) - { - std::cout << exception.what() << std::endl; - } - } - for (const auto& executable_test : std::filesystem::directory_iterator(in_build_directory())) - { - if (executable_test.path().has_extension()) - { - continue; - } - run_test(context, executable_test.path()); - } - for (const auto& expectation_entry : std::filesystem::directory_iterator(test_directory / "failures")) - { - auto test_entry = test_directory / expectation_entry.path().filename(); - test_entry.replace_extension(".eln"); - auto result = check_expectation(expectation_entry.path(), in_build_directory()); - - print_result(test_entry, result); - results.add_exit_code(result); - } - std::filesystem::copy(test_directory / "expectations", in_root_directory("expectations"), - std::filesystem::copy_options::recursive); - create_init(); - cpio_archive(context); - run_vm(context); - - return results; - } - - void print_result(const std::filesystem::path& test_entry, const test_status& result) - { - if (result != test_status::successful) - { - std::cout << test_entry << " failed." << std::endl; - } - } -}; - -int main() -{ - std::filesystem::create_directory(elna::in_build_directory()); - std::filesystem::create_directory(elna::in_actual_directory()); - - std::filesystem::remove_all(elna::in_root_directory()); - std::filesystem::create_directory(elna::in_root_directory()); - std::filesystem::create_directory(elna::in_root_directory("expectations")); - std::filesystem::create_directory(elna::in_root_directory("tests")); - - auto current_environment = boost::this_process::environment(); - current_environment["PATH"] += "./build/tools/sysroot/bin"; - - std::cout << "Run all tests and check the results" << std::endl; - std::filesystem::path test_directory{ "tests" }; - const auto results = elna::run_in_path(test_directory); - - std::cout << std::endl; - std::cout << results.total() << " tests run, " - << results.passed() << " passed, " - << results.failed() << " failed." << std::endl; - - return results.exit_code(); -} diff --git a/tools/tester.js b/tools/tester.js index 76c7b09..210f085 100644 --- a/tools/tester.js +++ b/tools/tester.js @@ -96,16 +96,15 @@ async function runVM(cpioImage) { } async function runInDirectory (directoryPath) { - const testSources = await glob(path.join(directoryPath, '*.eln')) let failed = 0 - for (const testEntry of testSources) { - console.log(`Compiling ${path.basename(testEntry)}.`) - + for (const testEntry of await glob(path.join(directoryPath, '*.eln'))) { const parsedPath = path.parse(testEntry) + + console.log(`Compiling ${parsedPath.base}.`) const buildResult = await compileTest(parsedPath) - if (buildResult.output !== '') { + if (buildResult.code !== 0) { if (!(await checkFailure(parsedPath, buildResult))) { ++failed } @@ -120,7 +119,7 @@ async function runInDirectory (directoryPath) { await runVM(cpioImage) return { - total: testSources.length, + total: (await glob(path.join(directoryPath, 'failures/*'))).length, failed, passed () {