From cd0c890bbac8c4bd7d1ccd0090f6a9f45c9571c5 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Wed, 28 Aug 2019 11:57:40 +0300 Subject: [core] Add filtering option to test-runner This change adds filter command line option to render test runner, so that test can be filtered by providing regular expression, for instance: mbgl-render-test -f .*hillshade.* --- render-test/main.cpp | 37 ++------------------------------- render-test/parser.cpp | 55 +++++++++++++++++++++++++++++++++++++++++++++----- render-test/parser.hpp | 2 +- 3 files changed, 53 insertions(+), 41 deletions(-) diff --git a/render-test/main.cpp b/render-test/main.cpp index c7b0b6be55..3ab48fe5b2 100644 --- a/render-test/main.cpp +++ b/render-test/main.cpp @@ -3,13 +3,11 @@ #include #include -#include "filesystem.hpp" #include "metadata.hpp" #include "parser.hpp" #include "runner.hpp" #include -#include #define ANSI_COLOR_RED "\x1b[31m" #define ANSI_COLOR_GREEN "\x1b[32m" @@ -36,49 +34,18 @@ void operator delete(void* ptr, size_t) noexcept { AllocationIndex::deallocate(ptr); } -namespace { - -TestPaths makeTestPaths(mbgl::filesystem::path stylePath) { - std::vector expectations{ stylePath }; - expectations.front().remove_filename(); - - const static std::regex regex{ TestRunner::getBasePath() }; - for (const std::string& path : TestRunner::getPlatformExpectationsPaths()) { - expectations.emplace_back(std::regex_replace(expectations.front().string(), regex, path)); - assert(!expectations.back().empty()); - } - - return { - std::move(stylePath), - std::move(expectations) - }; -} - -} // namespace - int main(int argc, char** argv) { bool recycleMap; bool shuffle; uint32_t seed; std::string testRootPath; - std::vector ids; + std::vector testPaths; - std::tie(recycleMap, shuffle, seed, testRootPath, ids) = parseArguments(argc, argv); + std::tie(recycleMap, shuffle, seed, testRootPath, testPaths) = parseArguments(argc, argv); const std::string::size_type rootLength = testRootPath.length(); const auto ignores = parseIgnores(); - // Recursively traverse through the test paths and collect test directories containing "style.json". - std::vector testPaths; - testPaths.reserve(ids.size()); - for (const auto& id : ids) { - for (auto& testPath : mbgl::filesystem::recursive_directory_iterator(mbgl::filesystem::path(id))) { - if (testPath.path().filename() == "style.json") { - testPaths.emplace_back(makeTestPaths(testPath)); - } - } - } - if (shuffle) { printf(ANSI_COLOR_YELLOW "Shuffle seed: %d" ANSI_COLOR_RESET "\n", seed); diff --git a/render-test/parser.cpp b/render-test/parser.cpp index 4598ba3786..6e6ebb0ba4 100644 --- a/render-test/parser.cpp +++ b/render-test/parser.cpp @@ -13,8 +13,9 @@ #include #include -#include "parser.hpp" +#include "filesystem.hpp" #include "metadata.hpp" +#include "parser.hpp" #include "runner.hpp" #include @@ -162,6 +163,22 @@ mbgl::optional localizeMapboxTilesetURL(const std::string& url) { return getIntegrationPath(url, "tilesets/", regex); } +TestPaths makeTestPaths(mbgl::filesystem::path stylePath) { + std::vector expectations{ stylePath }; + expectations.front().remove_filename(); + + const static std::regex regex{ TestRunner::getBasePath() }; + for (const std::string& path : TestRunner::getPlatformExpectationsPaths()) { + expectations.emplace_back(std::regex_replace(expectations.front().string(), regex, path)); + assert(!expectations.back().empty()); + } + + return { + std::move(stylePath), + std::move(expectations) + }; +} + } // namespace JSONReply readJson(const mbgl::filesystem::path& jsonPath) { @@ -239,6 +256,8 @@ ArgumentsTuple parseArguments(int argc, char** argv) { { "seed" }); args::ValueFlag testPathValue(argumentParser, "rootPath", "Test root rootPath", { 'p', "rootPath" }); + args::ValueFlag testFilterValue(argumentParser, "filter", "Test filter regex", + { 'f', "filter" }); args::PositionalList testNameValues(argumentParser, "URL", "Test name(s)"); try { @@ -260,10 +279,16 @@ ArgumentsTuple parseArguments(int argc, char** argv) { mbgl::Log::Info(mbgl::Event::General, stream.str()); mbgl::Log::Error(mbgl::Event::General, e.what()); exit(2); + } catch (const std::regex_error& e) { + mbgl::Log::Error(mbgl::Event::General, "Invalid filter regular expression: %s", e.what()); + exit(3); } - const std::string testDefaultPath = - std::string(TEST_RUNNER_ROOT_PATH).append("/mapbox-gl-js/test/integration/render-tests"); + const auto rootPath = testPathValue ? args::get(testPathValue) : TestRunner::getBasePath(); + if (!mbgl::filesystem::exists(mbgl::filesystem::path(rootPath))) { + mbgl::Log::Error(mbgl::Event::General, "Provided rootPath '%s' does not exist.", rootPath.c_str()); + exit(4); + } std::vector ids; for (const auto& id : args::get(testNameValues)) { @@ -274,11 +299,31 @@ ArgumentsTuple parseArguments(int argc, char** argv) { ids.emplace_back(TestRunner::getBasePath()); } + // Recursively traverse through the test paths and collect test directories containing "style.json". + std::vector testPaths; + testPaths.reserve(ids.size()); + for (const auto& id : ids) { + auto path = mbgl::filesystem::path(id); + if (!mbgl::filesystem::exists(path)) { + mbgl::Log::Error(mbgl::Event::General, "Provided test folder '%s' does not exist.", id.c_str()); + continue; + } + for (auto& testPath : mbgl::filesystem::recursive_directory_iterator(path)) { + // Skip paths that fail regexp match. + if (testFilterValue && !std::regex_match(testPath.path().string(), args::get(testFilterValue))) { + continue; + } + if (testPath.path().filename() == "style.json") { + testPaths.emplace_back(makeTestPaths(testPath)); + } + } + } + return ArgumentsTuple { recycleMapFlag ? args::get(recycleMapFlag) : false, shuffleFlag ? args::get(shuffleFlag) : false, seedValue ? args::get(seedValue) : 1u, - testPathValue ? args::get(testPathValue) : testDefaultPath, - std::move(ids) + testPathValue ? args::get(testPathValue) : TestRunner::getBasePath(), + std::move(testPaths) }; } diff --git a/render-test/parser.hpp b/render-test/parser.hpp index 483089266e..94fb212944 100644 --- a/render-test/parser.hpp +++ b/render-test/parser.hpp @@ -12,7 +12,7 @@ using ErrorMessage = std::string; using JSONReply = mbgl::variant; -using ArgumentsTuple = std::tuple>; +using ArgumentsTuple = std::tuple>; JSONReply readJson(const mbgl::filesystem::path&); std::string serializeJsonValue(const mbgl::JSValue&); -- cgit v1.2.1