From 7d79dcf75e36b693901493a9978d0b889c11558c Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Thu, 7 Nov 2024 14:49:33 +0900 Subject: [PATCH 01/12] Added prerequisites tag to input. Moved process_requirements to validation.cpp Signed-off-by: TaikiYamada4 --- .../CMakeLists.txt | 24 +- .../src/common/validation.cpp | 339 ++++++++++++++++++ .../lanelet2_map_validator/validation.hpp | 40 +++ .../src/main.cpp | 125 +------ .../test/data/test_input.json | 33 ++ .../test/src/test_json_processing.cpp | 195 ++++++++++ .../src/test_missing_regulatory_elements.cpp | 2 +- .../src/test_regulatory_element_details.cpp | 2 +- 8 files changed, 633 insertions(+), 127 deletions(-) create mode 100644 map/autoware_lanelet2_map_validator/test/data/test_input.json create mode 100644 map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp diff --git a/map/autoware_lanelet2_map_validator/CMakeLists.txt b/map/autoware_lanelet2_map_validator/CMakeLists.txt index 0b686701..9326b83f 100644 --- a/map/autoware_lanelet2_map_validator/CMakeLists.txt +++ b/map/autoware_lanelet2_map_validator/CMakeLists.txt @@ -21,16 +21,32 @@ target_include_directories( src/include ) +ament_target_dependencies(autoware_lanelet2_map_validator_lib nlohmann_json) + ament_auto_add_executable(autoware_lanelet2_map_validator src/main.cpp ) target_link_libraries(autoware_lanelet2_map_validator autoware_lanelet2_map_validator_lib - nlohmann_json ) if(BUILD_TESTING) + find_package(ament_index_cpp REQUIRED) + + # test for json processing + ament_add_ros_isolated_gtest( + json_processing_test + test/src/test_json_processing.cpp + ) + + target_link_libraries( + json_processing_test + autoware_lanelet2_map_validator_lib + ament_index_cpp::ament_index_cpp + ) + + # test for general lanelet2 map validators function(add_validation_test VALIDATION_NAME) ament_add_ros_isolated_gtest( ${VALIDATION_NAME}_test @@ -39,7 +55,6 @@ if(BUILD_TESTING) target_link_libraries( ${VALIDATION_NAME}_test autoware_lanelet2_map_validator_lib - nlohmann_json ) endfunction() @@ -47,4 +62,7 @@ if(BUILD_TESTING) add_validation_test(regulatory_element_details) endif() -ament_auto_package() +ament_auto_package( + INSTALL_TO_SHARE + test/data +) diff --git a/map/autoware_lanelet2_map_validator/src/common/validation.cpp b/map/autoware_lanelet2_map_validator/src/common/validation.cpp index 1b454a76..fc68aa36 100644 --- a/map/autoware_lanelet2_map_validator/src/common/validation.cpp +++ b/map/autoware_lanelet2_map_validator/src/common/validation.cpp @@ -16,9 +16,25 @@ #include #include +#include #include +#include +#include +#include +#include #include +#include +#include + +// ANSI color codes for console output +#define BOLD_ONLY "\033[1m" +#define BOLD_GREEN "\033[1;32m" +#define BOLD_YELLOW "\033[1;33m" +#define BOLD_RED "\033[1;31m" +#define NORMAL_GREEN "\033[32m" +#define NORMAL_RED "\033[31m" +#define FONT_RESET "\033[0m" namespace lanelet { @@ -76,9 +92,332 @@ std::vector validateMap( })); } + appendIssues(issues, lanelet::validation::validateMap(*map, val_config)); return issues; } +Validators parse_validators(const json & json_data) +{ + Validators validators; + + for (const auto & requirement : json_data["requirements"]) { + for (const auto & validator : requirement["validators"]) { + ValidatorInfo info; + + if (validator.contains("prerequisites")) { + for (const auto & prereq : validator["prerequisites"]) { + info.prerequisites.push_back(prereq["name"]); + if (prereq.contains("forgive_warnings")) { + info.forgive_warnings[prereq["name"]] = prereq["forgive_warnings"]; + } + } + } + validators[validator["name"]] = info; + } + } + return validators; +} + +std::pair, Validators> create_validation_queue( + const Validators & validators) +{ + std::unordered_map> graph; // Graph of dependencies + std::unordered_map + indegree; // Indegree (number of prerequisites) for each validator + std::vector validation_queue; + Validators remaining_validators; // Validators left unprocessed + + // Build the graph and initialize indegree + for (const auto & v : validators) { + std::string name = v.first; + indegree[name] = 0; // Initialize indegree + remaining_validators.insert(v); // Throw all validators to remaining_validators first + + for (const auto & prereq : v.second.prerequisites) { + graph[prereq].push_back(name); // prereq -> validator (prereq points to validator) + indegree[name]++; // Increment the indegree of the validator + } + } + + // Use a queue to store validators with no prerequisites (indegree == 0) + std::queue q; + for (const auto & [name, count] : indegree) { + if (count == 0) { + q.push(name); + remaining_validators.erase(name); // Remove from unprocessed set + } + } + + // Perform topological sort to derive execution order + while (!q.empty()) { + std::string current_validator_name = q.front(); + q.pop(); + + // Add the current validator to the execution queue + validation_queue.push_back(current_validator_name); + + // For each dependent validator, reduce indegree and add to the queue if indegree becomes 0 + for (const auto & neighbor : graph[current_validator_name]) { + indegree[neighbor]--; + if (indegree[neighbor] == 0) { + q.push(neighbor); + remaining_validators.erase(neighbor); // Remove from unprocessed set + } + } + } + + for (auto & [name, info] : remaining_validators) { + info.max_severity = ValidatorInfo::Severity::ERROR; + } + + return {validation_queue, remaining_validators}; +} + +// Function to find a validator block by name +json & find_validator_block(json & json_data, const std::string & validator_name) +{ + for (auto & requirement : json_data["requirements"]) { + for (auto & validator : requirement["validators"]) { + if (validator["name"] == validator_name) { + return validator; // Return a reference to the found validator + } + } + } + throw std::runtime_error( + "Validator block not found"); // Handle case where validator is not found +} + +std::vector descript_unused_validators_to_json( + json & json_data, const Validators & unused_validators) +{ + lanelet::validation::Issues issues; + std::vector detected_issues; + + for (const auto & [name, validator] : unused_validators) { + json & validator_json = find_validator_block(json_data, name); + validator_json["passed"] = false; + json issues_json; + json issue_json; + issue_json["severity"] = lanelet::validation::toString(lanelet::validation::Severity::Error); + issue_json["primitive"] = + lanelet::validation::toString(lanelet::validation::Primitive::Primitive); + issue_json["id"] = 0; + issue_json["message"] = "Prerequisites don't exist OR they are making a loop."; + issues_json.push_back(issue_json); + validator_json["issues"] = issues_json; + + lanelet::validation::Issue issue; + issue.severity = lanelet::validation::Severity::Error; + issue.primitive = lanelet::validation::Primitive::Primitive; + issue.id = lanelet::InvalId; + issue.message = "Prerequisites don't exist OR they are making a loop."; + issues.push_back(issue); + } + + if (issues.size() > 0) { + detected_issues.push_back({"invalid_prerequisites", issues}); + } + return detected_issues; +} + +std::vector check_prerequisite_completion( + json & json_data, const Validators & validators, const std::string target_validator_name) +{ + lanelet::validation::Issues issues; + std::vector detected_issues; + + ValidatorInfo current_validator_info = validators.at(target_validator_name); + json & validator_json = find_validator_block(json_data, target_validator_name); + + bool prerequisite_complete = true; + for (const auto & prereq : current_validator_info.prerequisites) { + if ( + validators.at(prereq).max_severity == ValidatorInfo::Severity::ERROR || + (validators.at(prereq).max_severity == ValidatorInfo::Severity::WARNING && + !current_validator_info.forgive_warnings.at(prereq))) { + prerequisite_complete = false; + break; + } + } + + if (!prerequisite_complete) { + validator_json["passed"] = false; + json issues_json; + json issue_json; + issue_json["severity"] = lanelet::validation::toString(lanelet::validation::Severity::Error); + issue_json["primitive"] = + lanelet::validation::toString(lanelet::validation::Primitive::Primitive); + issue_json["id"] = 0; + issue_json["message"] = "Prerequisites didn't pass"; + issues_json.push_back(issue_json); + validator_json["issues"] = issues_json; + + lanelet::validation::Issue issue; + issue.severity = lanelet::validation::Severity::Error; + issue.primitive = lanelet::validation::Primitive::Primitive; + issue.id = lanelet::InvalId; + issue.message = "Prerequisites didn't pass"; + issues.push_back(issue); + } + + if (issues.size() > 0) { + detected_issues.push_back({target_validator_name, issues}); + } + + return detected_issues; +} + +void summarize_validator_results(json & json_data) +{ + uint64_t warning_count = 0; + uint64_t error_count = 0; + + for (auto & requirement : json_data["requirements"]) { + std::string id = requirement["id"]; + bool is_requirement_passed = true; + std::map validator_results; + + for (const auto & validator : requirement["validators"]) { + bool validator_passed = validator["passed"]; + validator_results[validator["name"]] = validator_passed; + is_requirement_passed &= validator_passed; + + if (!validator.contains("issues")) { + continue; + } + for (const auto & issue : validator["issues"]) { + if ( + issue["severity"] == + lanelet::validation::toString(lanelet::validation::Severity::Warning)) { + warning_count++; + } else if ( + issue["severity"] == + lanelet::validation::toString(lanelet::validation::Severity::Error)) { + error_count++; + } + } + } + + std::cout << BOLD_ONLY << "[" << id << "] "; + + if (is_requirement_passed) { + requirement["passed"] = true; + std::cout << BOLD_GREEN << "Passed" << FONT_RESET << std::endl; + } else { + requirement["passed"] = false; + std::cout << BOLD_RED << "Failed" << FONT_RESET << std::endl; + } + + for (const auto & [name, result] : validator_results) { + if (result) { + std::cout << " - " << name << ": " << NORMAL_GREEN << "Passed" << FONT_RESET << std::endl; + } else { + std::cout << " - " << name << ": " << NORMAL_RED << "Failed" << FONT_RESET << std::endl; + } + } + } + + if (warning_count + error_count == 0) { + std::cout << BOLD_GREEN << "No errors nor warnings were found" << FONT_RESET << std::endl; + } else { + if (warning_count > 0) { + std::cout << BOLD_YELLOW << "Total of " << warning_count << " warnings were found" + << FONT_RESET << std::endl; + } + if (error_count > 0) { + std::cout << BOLD_RED << "Total of " << error_count << " errors were found" << FONT_RESET + << std::endl; + } + } +} + +lanelet::validation::ValidationConfig replace_validator( + const lanelet::validation::ValidationConfig & input, const std::string & validator_name) +{ + auto temp = input; + temp.checksFilter = validator_name; + return temp; +} + +void process_requirements(json json_data, const MetaConfig & validator_config) +{ + std::vector issues; + + // List up validators in order + Validators validators = parse_validators(json_data); + auto [validation_queue, remaining_validators] = create_validation_queue(validators); + + // Note validators that cannot be run from the start + std::vector unused_validator_issues = + descript_unused_validators_to_json(json_data, remaining_validators); + appendIssues(issues, std::move(unused_validator_issues)); + + // Main validation process + for (const auto & validator_name : validation_queue) { + // Check prerequisites are OK + std::vector prerequisite_failure_issues = + check_prerequisite_completion(json_data, validators, validator_name); + appendIssues(issues, std::move(prerequisite_failure_issues)); + if (prerequisite_failure_issues.size() > 0) { + continue; + } + + // Validate map + std::vector temp_issues = validateMap( + validator_config.projector_type, validator_config.command_line_config.mapFile, + replace_validator(validator_config.command_line_config.validationConfig, validator_name)); + + // Add validation results to the json data + json & validator_json = find_validator_block(json_data, validator_name); + if (temp_issues.size() == 0) { + validator_json["passed"] = true; + continue; + } + + if (temp_issues[0].warnings().size() + temp_issues[0].errors().size() == 0) { + validator_json["passed"] = true; + } else { + validator_json["passed"] = false; + } + if (temp_issues[0].issues.size() > 0) { + json issues_json; + for (const auto & issue : temp_issues[0].issues) { + json issue_json; + issue_json["severity"] = lanelet::validation::toString(issue.severity); + issue_json["primitive"] = lanelet::validation::toString(issue.primitive); + issue_json["id"] = issue.id; + issue_json["message"] = issue.message; + issues_json.push_back(issue_json); + + if ( + static_cast(issue.severity) < + static_cast(validators[validator_name].max_severity)) { + validators[validator_name].max_severity = + static_cast(static_cast(issue.severity)); + } + } + validator_json["issues"] = issues_json; + } + appendIssues(issues, std::move(temp_issues)); + } + + // Show results + summarize_validator_results(json_data); + lanelet::validation::printAllIssues(issues); + + // Save results + if (!validator_config.output_file_path.empty()) { + if (!std::filesystem::is_directory(validator_config.output_file_path)) { + throw std::invalid_argument("Output path doesn't exist or is not a directory!"); + } + std::filesystem::path file_directory = validator_config.output_file_path; + std::filesystem::path file_path = file_directory / "lanelet2_validation_results.json"; + std::ofstream output_file(file_path); + output_file << std::setw(4) << json_data; + std::cout << "Results are output to " << file_path << std::endl; + } +} + } // namespace validation } // namespace autoware } // namespace lanelet diff --git a/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp b/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp index 42c65c10..c5d8f9b6 100644 --- a/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp +++ b/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp @@ -18,6 +18,8 @@ #include "lanelet2_map_validator/cli.hpp" #include "lanelet2_map_validator/utils.hpp" +#include + #include #include #include @@ -26,8 +28,12 @@ #include #include #include +#include +#include #include +using json = nlohmann::json; + namespace { namespace projector_names @@ -44,11 +50,45 @@ namespace autoware { namespace validation { +struct ValidatorInfo +{ + enum class Severity { ERROR, WARNING, INFO, NONE }; + + std::vector prerequisites; + std::unordered_map forgive_warnings; + Severity max_severity = Severity::NONE; +}; + +using Validators = std::unordered_map; + std::unique_ptr getProjector( const std::string & projector_type, const lanelet::GPSPoint & origin); + std::vector validateMap( const std::string & projector_type, const std::string & map_file, const lanelet::validation::ValidationConfig & val_config); + +Validators parse_validators(const json & json_data); + +std::pair, Validators> create_validation_queue( + const Validators & validators); + +// Function to find a validator block by name +json & find_validator_block(json & json_data, const std::string & validator_name); + +std::vector descript_unused_validators_to_json( + json & json_data, const Validators & unused_validators); + +std::vector check_prerequisite_completion( + json & json_data, const Validators & validators, const std::string target_validator_name); + +void summarize_validator_results(json & json_data); + +lanelet::validation::ValidationConfig replace_validator( + const lanelet::validation::ValidationConfig & input, const std::string & validator_name); + +void process_requirements( + json json_data, const lanelet::autoware::validation::MetaConfig & validator_config); } // namespace validation } // namespace autoware } // namespace lanelet diff --git a/map/autoware_lanelet2_map_validator/src/main.cpp b/map/autoware_lanelet2_map_validator/src/main.cpp index bcbd0dc8..9c97bf06 100644 --- a/map/autoware_lanelet2_map_validator/src/main.cpp +++ b/map/autoware_lanelet2_map_validator/src/main.cpp @@ -18,129 +18,10 @@ #include -#include - #include #include #include -// Use nlohmann::json for JSON handling -using json = nlohmann::json; - -// ANSI color codes for console output -#define BOLD_ONLY "\033[1m" -#define BOLD_GREEN "\033[1;32m" -#define BOLD_YELLOW "\033[1;33m" -#define BOLD_RED "\033[1;31m" -#define NORMAL_GREEN "\033[32m" -#define NORMAL_RED "\033[31m" -#define FONT_RESET "\033[0m" - -lanelet::validation::ValidationConfig replace_validator( - const lanelet::validation::ValidationConfig & input, const std::string & validator_name) -{ - auto temp = input; - temp.checksFilter = validator_name; - return temp; -} - -void process_requirements( - json json_config, const lanelet::autoware::validation::MetaConfig & validator_config) -{ - uint64_t warning_count = 0; - uint64_t error_count = 0; - - for (auto & requirement : json_config["requirements"]) { - std::string id = requirement["id"]; - bool requirement_passed = true; - - std::vector issues; - std::map temp_validation_results; - - for (auto & validator : requirement["validators"]) { - const std::string validator_name = validator["name"]; - - std::vector temp_issues = - lanelet::autoware::validation::validateMap( - validator_config.projector_type, validator_config.command_line_config.mapFile, - replace_validator(validator_config.command_line_config.validationConfig, validator_name)); - - if (temp_issues.empty()) { - // Validator passed - temp_validation_results[validator_name] = true; - validator["passed"] = true; - } else { - // Validator failed - requirement_passed = false; - warning_count += temp_issues[0].warnings().size(); - error_count += temp_issues[0].errors().size(); - temp_validation_results[validator_name] = false; - validator["passed"] = false; - - json issues_json; - for (const auto & issue : temp_issues[0].issues) { - json issue_json; - issue_json["severity"] = lanelet::validation::toString(issue.severity); - issue_json["primitive"] = lanelet::validation::toString(issue.primitive); - issue_json["id"] = issue.id; - issue_json["message"] = issue.message; - issues_json.push_back(issue_json); - } - validator["issues"] = issues_json; - } - - lanelet::autoware::validation::appendIssues(issues, std::move(temp_issues)); - } - - std::cout << BOLD_ONLY << "[" << id << "] "; - - if (requirement_passed) { - requirement["passed"] = true; - std::cout << BOLD_GREEN << "Passed" << FONT_RESET << std::endl; - } else { - requirement["passed"] = false; - std::cout << BOLD_RED << "Failed" << FONT_RESET << std::endl; - } - - for (const auto & result : temp_validation_results) { - if (result.second) { - std::cout << " - " << result.first << ": " << NORMAL_GREEN << "Passed" << FONT_RESET - << std::endl; - } else { - std::cout << " - " << result.first << ": " << NORMAL_RED << "Failed" << FONT_RESET - << std::endl; - } - } - lanelet::validation::printAllIssues(issues); - std::cout << std::endl; - } - - if (warning_count + error_count == 0) { - std::cout << BOLD_GREEN << "No issues were found from " << FONT_RESET - << validator_config.command_line_config.mapFile << std::endl; - } else { - if (warning_count > 0) { - std::cout << BOLD_YELLOW << "Total of " << warning_count << " warnings were found from " - << FONT_RESET << validator_config.command_line_config.mapFile << std::endl; - } - if (error_count > 0) { - std::cout << BOLD_RED << "Total of " << error_count << " errors were found from " - << FONT_RESET << validator_config.command_line_config.mapFile << std::endl; - } - } - - if (!validator_config.output_file_path.empty()) { - if (!std::filesystem::is_directory(validator_config.output_file_path)) { - throw std::invalid_argument("Output path doesn't exist or is not a directory!"); - } - std::filesystem::path file_directory = validator_config.output_file_path; - std::filesystem::path file_path = file_directory / "lanelet2_validation_results.json"; - std::ofstream output_file(file_path); - output_file << std::setw(4) << json_config; - std::cout << "Results are output to " << file_path << std::endl; - } -} - int main(int argc, char * argv[]) { lanelet::autoware::validation::MetaConfig meta_config = @@ -181,9 +62,9 @@ int main(int argc, char * argv[]) throw std::invalid_argument("Input file doesn't exist or is not a file!"); } std::ifstream input_file(meta_config.requirements_file); - json json_config; - input_file >> json_config; - process_requirements(json_config, meta_config); + json json_data; + input_file >> json_data; + lanelet::autoware::validation::process_requirements(json_data, meta_config); } else { auto issues = lanelet::autoware::validation::validateMap( meta_config.projector_type, meta_config.command_line_config.mapFile, diff --git a/map/autoware_lanelet2_map_validator/test/data/test_input.json b/map/autoware_lanelet2_map_validator/test/data/test_input.json new file mode 100644 index 00000000..a7c81dba --- /dev/null +++ b/map/autoware_lanelet2_map_validator/test/data/test_input.json @@ -0,0 +1,33 @@ +{ + "requirements": [ + { + "id": "test-01", + "validators": [ + { + "name": "parsing.valid_input.no_prerequisites1" + }, + { + "name": "parsing.valid_input.no_prerequisites2" + } + ] + }, + { + "id": "test-02", + "validators": [ + { + "name": "parsing.valid_input.with_prerequisites1", + "prerequisites": [ + { + "name": "parsing.valid_input.no_prerequisites1", + "forgive_warnings": true + }, + { + "name": "parsing.valid_input.no_prerequisites2", + "forgive_warnings": false + } + ] + } + ] + } + ] +} diff --git a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp new file mode 100644 index 00000000..8baad86d --- /dev/null +++ b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp @@ -0,0 +1,195 @@ +// Copyright 2024 Autoware Foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "lanelet2_map_validator/cli.hpp" +#include "lanelet2_map_validator/utils.hpp" +#include "lanelet2_map_validator/validation.hpp" + +#include +#include + +#include +#include + +#include +#include + +using json = nlohmann::json; + +namespace lanelet +{ +namespace autoware +{ +namespace validation +{ + +class JsonProcessingTest : public ::testing::Test +{ +protected: + void SetUp() override + { + std::string package_share_directory = + ament_index_cpp::get_package_share_directory("autoware_lanelet2_map_validator"); + std::ifstream file(package_share_directory + "/data/test_input.json"); + ASSERT_TRUE(file.is_open()) << "Failed to open test JSON file."; + + file >> sample_input_data; + } + json sample_input_data; + json sample_output_data; +}; + +TEST_F(JsonProcessingTest, ParseValidatorsWithValidInput) +{ + Validators validators = parse_validators(sample_input_data); + ASSERT_EQ(validators.size(), 3); + ASSERT_TRUE(validators.find("parsing.valid_input.no_prerequisites1") != validators.end()); + ASSERT_TRUE(validators.find("parsing.valid_input.no_prerequisites2") != validators.end()); + ASSERT_TRUE(validators.find("parsing.valid_input.with_prerequisites1") != validators.end()); + EXPECT_EQ(validators["parsing.valid_input.no_prerequisites1"].prerequisites.size(), 0); + EXPECT_EQ(validators["parsing.valid_input.no_prerequisites2"].prerequisites.size(), 0); + EXPECT_EQ(validators["parsing.valid_input.with_prerequisites1"].prerequisites.size(), 2); + EXPECT_TRUE(validators["parsing.valid_input.with_prerequisites1"] + .forgive_warnings["parsing.valid_input.no_prerequisites1"]); + EXPECT_FALSE(validators["parsing.valid_input.with_prerequisites1"] + .forgive_warnings["parsing.valid_input.no_prerequisites2"]); +} +/* +TEST_F(JsonProcessingTest, CreateValidationQueueNoCycles) +{ + Validators validators = { + {"validator1", ValidatorInfo{.prerequisites = {}}}, + {"validator2", ValidatorInfo{.prerequisites = {"validator1"}}}, + }; + + auto [queue, remaining] = create_validation_queue(validators); + EXPECT_EQ(queue.size(), 2); + EXPECT_TRUE(remaining.empty()); +} + +TEST_F(JsonProcessingTest, CreateValidationQueueWithCycles) +{ + Validators validators = { + {"validator1", ValidatorInfo{.prerequisites = {"validator2"}}}, + {"validator2", ValidatorInfo{.prerequisites = {"validator1"}}}, + }; + + auto [queue, remaining] = create_validation_queue(validators); + EXPECT_EQ(queue.size(), 0); // Expect empty queue because of a cycle + EXPECT_EQ(remaining.size(), 2); + EXPECT_EQ(remaining["validator1"].max_severity, ValidatorInfo::Severity::ERROR); +} + +TEST_F(JsonProcessingTest, CheckPrerequisiteCompletionSuccess) +{ + Validators validators = { + {"validator1", + ValidatorInfo{.prerequisites = {}, .max_severity = ValidatorInfo::Severity::INFO}}, + {"validator2", ValidatorInfo{.prerequisites = {"validator1"}}}, + }; + + sample_input_data = R"({ + "requirements": [{ + "id": "1", + "validators": [{"name": "validator2"}] + }] + })"_json; + + auto issues = check_prerequisite_completion(sample_input_data, validators, "validator2"); + EXPECT_TRUE(issues.empty()); +} + +TEST_F(JsonProcessingTest, CheckPrerequisiteCompletionFailure) +{ + Validators validators = { + {"validator1", + ValidatorInfo{.prerequisites = {}, .max_severity = ValidatorInfo::Severity::ERROR}}, + {"validator2", ValidatorInfo{.prerequisites = {"validator1"}}}, + }; + + sample_input_data = R"({ + "requirements": [{ + "id": "1", + "validators": [{"name": "validator2"}] + }] + })"_json; + + auto issues = check_prerequisite_completion(sample_input_data, validators, "validator2"); + EXPECT_FALSE(issues.empty()); +} + +TEST_F(JsonProcessingTest, DescriptUnusedValidatorsToJson) +{ + Validators unused_validators = { + {"validator1", + ValidatorInfo{.prerequisites = {}, .max_severity = ValidatorInfo::Severity::ERROR}}, + }; + + sample_input_data = R"({ + "requirements": [{ + "id": "1", + "validators": [{"name": "validator1"}] + }] + })"_json; + + auto detected_issues = descript_unused_validators_to_json(sample_input_data, unused_validators); + EXPECT_EQ(detected_issues.size(), 1); + EXPECT_EQ(detected_issues[0].issues.size(), 1); + EXPECT_EQ(detected_issues[0].issues[0].severity, lanelet::validation::Severity::Error); + + // Check json_data too, +} + +TEST_F(JsonProcessingTest, SummarizeValidatorResultsAllPassed) +{ + sample_input_data = R"({ + "requirements": [{ + "id": "1", + "validators": [{"name": "validator1", "passed": true}] + }] + })"_json; + + testing::internal::CaptureStdout(); + summarize_validator_results(sample_input_data); + std::string output = testing::internal::GetCapturedStdout(); + EXPECT_NE(output.find("Passed"), std::string::npos); +} + +TEST_F(JsonProcessingTest, SummarizeValidatorResultsWithWarningsAndErrors) +{ + sample_input_data = R"({ + "requirements": [{ + "id": "1", + "validators": [{ + "name": "validator1", + "passed": false, + "issues": [ + {"severity": "Error", "message": "Test error"}, + {"severity": "Warning", "message": "Test warning"} + ] + }] + }] + })"_json; + + testing::internal::CaptureStdout(); + summarize_validator_results(sample_input_data); + std::string output = testing::internal::GetCapturedStdout(); + EXPECT_NE(output.find("Failed"), std::string::npos); + EXPECT_NE(output.find("errors were found"), std::string::npos); + EXPECT_NE(output.find("warnings were found"), std::string::npos); +} +*/ +} // namespace validation +} // namespace autoware +} // namespace lanelet diff --git a/map/autoware_lanelet2_map_validator/test/src/test_missing_regulatory_elements.cpp b/map/autoware_lanelet2_map_validator/test/src/test_missing_regulatory_elements.cpp index a6a2e62d..ed13af24 100644 --- a/map/autoware_lanelet2_map_validator/test/src/test_missing_regulatory_elements.cpp +++ b/map/autoware_lanelet2_map_validator/test/src/test_missing_regulatory_elements.cpp @@ -1,4 +1,4 @@ -// Copyright 2023 Autoware Foundation +// Copyright 2024 Autoware Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/map/autoware_lanelet2_map_validator/test/src/test_regulatory_element_details.cpp b/map/autoware_lanelet2_map_validator/test/src/test_regulatory_element_details.cpp index 7e94a955..191884b1 100644 --- a/map/autoware_lanelet2_map_validator/test/src/test_regulatory_element_details.cpp +++ b/map/autoware_lanelet2_map_validator/test/src/test_regulatory_element_details.cpp @@ -1,4 +1,4 @@ -// Copyright 2023 Autoware Foundation +// Copyright 2024 Autoware Foundation // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. From 88dcb9448223c03761b105ec4e7599a232d4ce4b Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Thu, 7 Nov 2024 17:17:36 +0900 Subject: [PATCH 02/12] Added prerequisites to autoware_requirement_set.json Signed-off-by: TaikiYamada4 --- .../autoware_requirement_set.json | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/map/autoware_lanelet2_map_validator/autoware_requirement_set.json b/map/autoware_lanelet2_map_validator/autoware_requirement_set.json index 5dd2edfb..9ca9b716 100644 --- a/map/autoware_lanelet2_map_validator/autoware_requirement_set.json +++ b/map/autoware_lanelet2_map_validator/autoware_requirement_set.json @@ -15,7 +15,12 @@ "name": "mapping.crosswalk.missing_regulatory_elements" }, { - "name": "mapping.crosswalk.regulatory_element_details" + "name": "mapping.crosswalk.regulatory_element_details", + "prerequisites": [ + { + "name": "mapping.crosswalk.missing_regulatory_elements" + } + ] } ] }, @@ -26,7 +31,12 @@ "name": "mapping.traffic_light.missing_regulatory_elements" }, { - "name": "mapping.traffic_light.regulatory_element_details" + "name": "mapping.traffic_light.regulatory_element_details", + "prerequisites": [ + { + "name": "mapping.traffic_light.missing_regulatory_elements" + } + ] } ] } From 95eaf23eacc410ff4e345146ccc236ed50a0c047 Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Thu, 7 Nov 2024 15:47:16 +0900 Subject: [PATCH 03/12] Redefine ValidatorInfo Signed-off-by: TaikiYamada4 --- .../src/common/validation.cpp | 43 +++++++++++-------- .../lanelet2_map_validator/validation.hpp | 7 +-- .../test/src/test_json_processing.cpp | 13 +++--- 3 files changed, 36 insertions(+), 27 deletions(-) diff --git a/map/autoware_lanelet2_map_validator/src/common/validation.cpp b/map/autoware_lanelet2_map_validator/src/common/validation.cpp index fc68aa36..133bbc5a 100644 --- a/map/autoware_lanelet2_map_validator/src/common/validation.cpp +++ b/map/autoware_lanelet2_map_validator/src/common/validation.cpp @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -106,9 +107,9 @@ Validators parse_validators(const json & json_data) if (validator.contains("prerequisites")) { for (const auto & prereq : validator["prerequisites"]) { - info.prerequisites.push_back(prereq["name"]); + info.prereq_with_forgive_warnings[prereq["name"]] = false; if (prereq.contains("forgive_warnings")) { - info.forgive_warnings[prereq["name"]] = prereq["forgive_warnings"]; + info.prereq_with_forgive_warnings[prereq["name"]] = prereq["forgive_warnings"]; } } } @@ -118,22 +119,20 @@ Validators parse_validators(const json & json_data) return validators; } -std::pair, Validators> create_validation_queue( +std::tuple, Validators> create_validation_queue( const Validators & validators) { std::unordered_map> graph; // Graph of dependencies - std::unordered_map - indegree; // Indegree (number of prerequisites) for each validator - std::vector validation_queue; + std::unordered_map indegree; // Indegree (number of prerequisites) + std::queue validation_queue; Validators remaining_validators; // Validators left unprocessed // Build the graph and initialize indegree - for (const auto & v : validators) { - std::string name = v.first; - indegree[name] = 0; // Initialize indegree - remaining_validators.insert(v); // Throw all validators to remaining_validators first + for (const auto & [name, info] : validators) { + indegree[name] = 0; // Initialize indegree + remaining_validators[name] = info; // Throw all validators to remaining_validators first - for (const auto & prereq : v.second.prerequisites) { + for (const auto & [prereq, forgive_warnings] : info.prereq_with_forgive_warnings) { graph[prereq].push_back(name); // prereq -> validator (prereq points to validator) indegree[name]++; // Increment the indegree of the validator } @@ -144,7 +143,7 @@ std::pair, Validators> create_validation_queue( for (const auto & [name, count] : indegree) { if (count == 0) { q.push(name); - remaining_validators.erase(name); // Remove from unprocessed set + remaining_validators.erase(name); } } @@ -154,14 +153,14 @@ std::pair, Validators> create_validation_queue( q.pop(); // Add the current validator to the execution queue - validation_queue.push_back(current_validator_name); + validation_queue.push(current_validator_name); // For each dependent validator, reduce indegree and add to the queue if indegree becomes 0 for (const auto & neighbor : graph[current_validator_name]) { indegree[neighbor]--; if (indegree[neighbor] == 0) { q.push(neighbor); - remaining_validators.erase(neighbor); // Remove from unprocessed set + remaining_validators.erase(neighbor); } } } @@ -183,8 +182,10 @@ json & find_validator_block(json & json_data, const std::string & validator_name } } } - throw std::runtime_error( - "Validator block not found"); // Handle case where validator is not found + + // Handle case where validator is not found + std::string msg = "Validator block " + validator_name + " not found"; + throw std::runtime_error(msg); } std::vector descript_unused_validators_to_json( @@ -230,11 +231,12 @@ std::vector check_prerequisite_completion( json & validator_json = find_validator_block(json_data, target_validator_name); bool prerequisite_complete = true; - for (const auto & prereq : current_validator_info.prerequisites) { + for (const auto & [prereq, forgive_warnings] : + current_validator_info.prereq_with_forgive_warnings) { if ( validators.at(prereq).max_severity == ValidatorInfo::Severity::ERROR || (validators.at(prereq).max_severity == ValidatorInfo::Severity::WARNING && - !current_validator_info.forgive_warnings.at(prereq))) { + !forgive_warnings)) { prerequisite_complete = false; break; } @@ -353,7 +355,10 @@ void process_requirements(json json_data, const MetaConfig & validator_config) appendIssues(issues, std::move(unused_validator_issues)); // Main validation process - for (const auto & validator_name : validation_queue) { + while (!validation_queue.empty()) { + std::string validator_name = validation_queue.front(); + validation_queue.pop(); + // Check prerequisites are OK std::vector prerequisite_failure_issues = check_prerequisite_completion(json_data, validators, validator_name); diff --git a/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp b/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp index c5d8f9b6..c05605df 100644 --- a/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp +++ b/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp @@ -26,8 +26,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -54,8 +56,7 @@ struct ValidatorInfo { enum class Severity { ERROR, WARNING, INFO, NONE }; - std::vector prerequisites; - std::unordered_map forgive_warnings; + std::unordered_map prereq_with_forgive_warnings; Severity max_severity = Severity::NONE; }; @@ -70,7 +71,7 @@ std::vector validateMap( Validators parse_validators(const json & json_data); -std::pair, Validators> create_validation_queue( +std::tuple, Validators> create_validation_queue( const Validators & validators); // Function to find a validator block by name diff --git a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp index 8baad86d..6b939418 100644 --- a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp +++ b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp @@ -57,13 +57,16 @@ TEST_F(JsonProcessingTest, ParseValidatorsWithValidInput) ASSERT_TRUE(validators.find("parsing.valid_input.no_prerequisites1") != validators.end()); ASSERT_TRUE(validators.find("parsing.valid_input.no_prerequisites2") != validators.end()); ASSERT_TRUE(validators.find("parsing.valid_input.with_prerequisites1") != validators.end()); - EXPECT_EQ(validators["parsing.valid_input.no_prerequisites1"].prerequisites.size(), 0); - EXPECT_EQ(validators["parsing.valid_input.no_prerequisites2"].prerequisites.size(), 0); - EXPECT_EQ(validators["parsing.valid_input.with_prerequisites1"].prerequisites.size(), 2); + EXPECT_EQ( + validators["parsing.valid_input.no_prerequisites1"].prereq_with_forgive_warnings.size(), 0); + EXPECT_EQ( + validators["parsing.valid_input.no_prerequisites2"].prereq_with_forgive_warnings.size(), 0); + EXPECT_EQ( + validators["parsing.valid_input.with_prerequisites1"].prereq_with_forgive_warnings.size(), 2); EXPECT_TRUE(validators["parsing.valid_input.with_prerequisites1"] - .forgive_warnings["parsing.valid_input.no_prerequisites1"]); + .prereq_with_forgive_warnings["parsing.valid_input.no_prerequisites1"]); EXPECT_FALSE(validators["parsing.valid_input.with_prerequisites1"] - .forgive_warnings["parsing.valid_input.no_prerequisites2"]); + .prereq_with_forgive_warnings["parsing.valid_input.no_prerequisites2"]); } /* TEST_F(JsonProcessingTest, CreateValidationQueueNoCycles) From 9e97bd88d31d3538f8dc420d3753a1225ffebbc5 Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Thu, 7 Nov 2024 17:00:15 +0900 Subject: [PATCH 04/12] Changed check_prerequisite_completion not to read the json_data Signed-off-by: TaikiYamada4 --- .../src/common/validation.cpp | 36 +++++++------------ .../lanelet2_map_validator/validation.hpp | 2 +- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/map/autoware_lanelet2_map_validator/src/common/validation.cpp b/map/autoware_lanelet2_map_validator/src/common/validation.cpp index 133bbc5a..91befdc5 100644 --- a/map/autoware_lanelet2_map_validator/src/common/validation.cpp +++ b/map/autoware_lanelet2_map_validator/src/common/validation.cpp @@ -222,13 +222,12 @@ std::vector descript_unused_validators_to_j } std::vector check_prerequisite_completion( - json & json_data, const Validators & validators, const std::string target_validator_name) + const Validators & validators, const std::string target_validator_name) { lanelet::validation::Issues issues; std::vector detected_issues; ValidatorInfo current_validator_info = validators.at(target_validator_name); - json & validator_json = find_validator_block(json_data, target_validator_name); bool prerequisite_complete = true; for (const auto & [prereq, forgive_warnings] : @@ -243,17 +242,6 @@ std::vector check_prerequisite_completion( } if (!prerequisite_complete) { - validator_json["passed"] = false; - json issues_json; - json issue_json; - issue_json["severity"] = lanelet::validation::toString(lanelet::validation::Severity::Error); - issue_json["primitive"] = - lanelet::validation::toString(lanelet::validation::Primitive::Primitive); - issue_json["id"] = 0; - issue_json["message"] = "Prerequisites didn't pass"; - issues_json.push_back(issue_json); - validator_json["issues"] = issues_json; - lanelet::validation::Issue issue; issue.severity = lanelet::validation::Severity::Error; issue.primitive = lanelet::validation::Primitive::Primitive; @@ -359,18 +347,20 @@ void process_requirements(json json_data, const MetaConfig & validator_config) std::string validator_name = validation_queue.front(); validation_queue.pop(); + std::vector temp_issues; + // Check prerequisites are OK - std::vector prerequisite_failure_issues = - check_prerequisite_completion(json_data, validators, validator_name); - appendIssues(issues, std::move(prerequisite_failure_issues)); - if (prerequisite_failure_issues.size() > 0) { - continue; - } + appendIssues(temp_issues, check_prerequisite_completion(validators, validator_name)); - // Validate map - std::vector temp_issues = validateMap( - validator_config.projector_type, validator_config.command_line_config.mapFile, - replace_validator(validator_config.command_line_config.validationConfig, validator_name)); + if (temp_issues.size() == 0) { + // Validate map + appendIssues( + temp_issues, + validateMap( + validator_config.projector_type, validator_config.command_line_config.mapFile, + replace_validator( + validator_config.command_line_config.validationConfig, validator_name))); + } // Add validation results to the json data json & validator_json = find_validator_block(json_data, validator_name); diff --git a/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp b/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp index c05605df..bc4f8e11 100644 --- a/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp +++ b/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp @@ -81,7 +81,7 @@ std::vector descript_unused_validators_to_j json & json_data, const Validators & unused_validators); std::vector check_prerequisite_completion( - json & json_data, const Validators & validators, const std::string target_validator_name); + const Validators & validators, const std::string target_validator_name); void summarize_validator_results(json & json_data); From 7c52214a2629ac8a03c2c22c056ff20921fa1ddd Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Thu, 7 Nov 2024 17:01:06 +0900 Subject: [PATCH 05/12] Added two tests CreateValidationQueueNoCycles CreateValidationQueueWithCycles Signed-off-by: TaikiYamada4 --- .../test/src/test_json_processing.cpp | 27 ++++++++++--------- 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp index 6b939418..13cc6248 100644 --- a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp +++ b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp @@ -68,32 +68,35 @@ TEST_F(JsonProcessingTest, ParseValidatorsWithValidInput) EXPECT_FALSE(validators["parsing.valid_input.with_prerequisites1"] .prereq_with_forgive_warnings["parsing.valid_input.no_prerequisites2"]); } -/* + TEST_F(JsonProcessingTest, CreateValidationQueueNoCycles) { Validators validators = { - {"validator1", ValidatorInfo{.prerequisites = {}}}, - {"validator2", ValidatorInfo{.prerequisites = {"validator1"}}}, - }; - + {"validator1", {{}, ValidatorInfo::Severity::NONE}}, + {"validator2", {{{"validator1", true}}, ValidatorInfo::Severity::NONE}}, + {"validator3", {{{"validator2", true}}, ValidatorInfo::Severity::NONE}}}; auto [queue, remaining] = create_validation_queue(validators); - EXPECT_EQ(queue.size(), 2); + EXPECT_EQ(queue.size(), 3); EXPECT_TRUE(remaining.empty()); } TEST_F(JsonProcessingTest, CreateValidationQueueWithCycles) { Validators validators = { - {"validator1", ValidatorInfo{.prerequisites = {"validator2"}}}, - {"validator2", ValidatorInfo{.prerequisites = {"validator1"}}}, - }; + {"validator1", {{{"validator3", true}}, ValidatorInfo::Severity::NONE}}, + {"validator2", {{{"validator1", true}}, ValidatorInfo::Severity::NONE}}, + {"validator3", {{{"validator2", true}}, ValidatorInfo::Severity::NONE}}, + {"validator4", {{}, ValidatorInfo::Severity::NONE}}}; auto [queue, remaining] = create_validation_queue(validators); - EXPECT_EQ(queue.size(), 0); // Expect empty queue because of a cycle - EXPECT_EQ(remaining.size(), 2); + EXPECT_EQ(queue.size(), 1); // Expect empty queue because of a cycle + EXPECT_EQ(remaining.size(), 3); EXPECT_EQ(remaining["validator1"].max_severity, ValidatorInfo::Severity::ERROR); + EXPECT_EQ(remaining["validator2"].max_severity, ValidatorInfo::Severity::ERROR); + EXPECT_EQ(remaining["validator3"].max_severity, ValidatorInfo::Severity::ERROR); + EXPECT_EQ(remaining["validator4"].max_severity, ValidatorInfo::Severity::NONE); } - +/* TEST_F(JsonProcessingTest, CheckPrerequisiteCompletionSuccess) { Validators validators = { From ec12e9a85c3574d53250d954ab297ce2c2453067 Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Thu, 7 Nov 2024 17:49:58 +0900 Subject: [PATCH 06/12] Added test CheckPrerequisiteCompletionSuccess CheckPrerequisiteCompletionFailure Signed-off-by: TaikiYamada4 --- .../test/src/test_json_processing.cpp | 38 +++++-------------- 1 file changed, 10 insertions(+), 28 deletions(-) diff --git a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp index 13cc6248..b080dfc2 100644 --- a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp +++ b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp @@ -96,45 +96,27 @@ TEST_F(JsonProcessingTest, CreateValidationQueueWithCycles) EXPECT_EQ(remaining["validator3"].max_severity, ValidatorInfo::Severity::ERROR); EXPECT_EQ(remaining["validator4"].max_severity, ValidatorInfo::Severity::NONE); } -/* + TEST_F(JsonProcessingTest, CheckPrerequisiteCompletionSuccess) { Validators validators = { - {"validator1", - ValidatorInfo{.prerequisites = {}, .max_severity = ValidatorInfo::Severity::INFO}}, - {"validator2", ValidatorInfo{.prerequisites = {"validator1"}}}, - }; + {"validator1", {{}, ValidatorInfo::Severity::INFO}}, + {"validator2", {{{"validator1", true}}, ValidatorInfo::Severity::NONE}}}; - sample_input_data = R"({ - "requirements": [{ - "id": "1", - "validators": [{"name": "validator2"}] - }] - })"_json; - - auto issues = check_prerequisite_completion(sample_input_data, validators, "validator2"); - EXPECT_TRUE(issues.empty()); + auto issues = check_prerequisite_completion(validators, "validator2"); + EXPECT_EQ(issues.size(), 0); } TEST_F(JsonProcessingTest, CheckPrerequisiteCompletionFailure) { Validators validators = { - {"validator1", - ValidatorInfo{.prerequisites = {}, .max_severity = ValidatorInfo::Severity::ERROR}}, - {"validator2", ValidatorInfo{.prerequisites = {"validator1"}}}, - }; - - sample_input_data = R"({ - "requirements": [{ - "id": "1", - "validators": [{"name": "validator2"}] - }] - })"_json; + {"validator1", {{}, ValidatorInfo::Severity::ERROR}}, + {"validator2", {{{"validator1", true}}, ValidatorInfo::Severity::NONE}}}; - auto issues = check_prerequisite_completion(sample_input_data, validators, "validator2"); - EXPECT_FALSE(issues.empty()); + auto issues = check_prerequisite_completion(validators, "validator2"); + EXPECT_EQ(issues.size(), 1); } - +/* TEST_F(JsonProcessingTest, DescriptUnusedValidatorsToJson) { Validators unused_validators = { From c2eedd19ec63a10bed0d8a1ea813169f906245fc Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Thu, 7 Nov 2024 18:26:19 +0900 Subject: [PATCH 07/12] Change how to load json files in tests. Signed-off-by: TaikiYamada4 --- .../test/src/test_json_processing.cpp | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp index b080dfc2..3ef7627b 100644 --- a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp +++ b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp @@ -37,14 +37,16 @@ namespace validation class JsonProcessingTest : public ::testing::Test { protected: - void SetUp() override + json load_json_file(std::string file_name) { std::string package_share_directory = ament_index_cpp::get_package_share_directory("autoware_lanelet2_map_validator"); - std::ifstream file(package_share_directory + "/data/test_input.json"); - ASSERT_TRUE(file.is_open()) << "Failed to open test JSON file."; + std::ifstream file(package_share_directory + "/data/" + file_name); + EXPECT_TRUE(file.is_open()) << "Failed to open test JSON file."; - file >> sample_input_data; + json json_data; + file >> json_data; + return json_data; } json sample_input_data; json sample_output_data; @@ -52,6 +54,7 @@ class JsonProcessingTest : public ::testing::Test TEST_F(JsonProcessingTest, ParseValidatorsWithValidInput) { + sample_input_data = load_json_file("test_input.json"); Validators validators = parse_validators(sample_input_data); ASSERT_EQ(validators.size(), 3); ASSERT_TRUE(validators.find("parsing.valid_input.no_prerequisites1") != validators.end()); @@ -119,9 +122,10 @@ TEST_F(JsonProcessingTest, CheckPrerequisiteCompletionFailure) /* TEST_F(JsonProcessingTest, DescriptUnusedValidatorsToJson) { - Validators unused_validators = { - {"validator1", - ValidatorInfo{.prerequisites = {}, .max_severity = ValidatorInfo::Severity::ERROR}}, + Validators error_validators = { + {"validator1", {{{"validator3", true}}, ValidatorInfo::Severity::ERROR}}, + {"validator2", {{{"validator1", true}}, ValidatorInfo::Severity::ERROR}}, + {"validator3", {{{"validator2", true}}, ValidatorInfo::Severity::ERROR}} }; sample_input_data = R"({ @@ -131,7 +135,7 @@ TEST_F(JsonProcessingTest, DescriptUnusedValidatorsToJson) }] })"_json; - auto detected_issues = descript_unused_validators_to_json(sample_input_data, unused_validators); + auto detected_issues = descript_unused_validators_to_json(sample_input_data, error_validators); EXPECT_EQ(detected_issues.size(), 1); EXPECT_EQ(detected_issues[0].issues.size(), 1); EXPECT_EQ(detected_issues[0].issues[0].severity, lanelet::validation::Severity::Error); From 83daca908b79d5a5454d93809240e28af8f826aa Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Fri, 8 Nov 2024 11:54:57 +0900 Subject: [PATCH 08/12] Added test DescriptUnusedValidatorsToJson and SummarizeValidatorResults Signed-off-by: TaikiYamada4 --- ...test_descript_unused_validators_input.json | 33 ++++++++++ ...est_descript_unused_validators_output.json | 60 +++++++++++++++++ .../test/data/test_input.json | 4 +- ...est_summarize_validator_results_input.json | 43 ++++++++++++ ...st_summarize_validator_results_output.json | 45 +++++++++++++ .../test/src/test_json_processing.cpp | 66 ++++++------------- 6 files changed, 203 insertions(+), 48 deletions(-) create mode 100644 map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_input.json create mode 100644 map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_output.json create mode 100644 map/autoware_lanelet2_map_validator/test/data/test_summarize_validator_results_input.json create mode 100644 map/autoware_lanelet2_map_validator/test/data/test_summarize_validator_results_output.json diff --git a/map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_input.json b/map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_input.json new file mode 100644 index 00000000..0d438a26 --- /dev/null +++ b/map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_input.json @@ -0,0 +1,33 @@ +{ + "requirements": [ + { + "id": "test-cycle-prerequisites", + "validators": [ + { + "name": "validator1", + "prerequisites": [ + { + "name": "validator3" + } + ] + }, + { + "name": "validator2", + "prerequisites": [ + { + "name": "validator1" + } + ] + }, + { + "name": "validator3", + "prerequisites": [ + { + "name": "validator2" + } + ] + } + ] + } + ] +} diff --git a/map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_output.json b/map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_output.json new file mode 100644 index 00000000..5bdaec9e --- /dev/null +++ b/map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_output.json @@ -0,0 +1,60 @@ +{ + "requirements": [ + { + "id": "test-cycle-prerequisites", + "validators": [ + { + "name": "validator1", + "passed": false, + "prerequisites": [ + { + "name": "validator3" + } + ], + "issues": [ + { + "severity": "Error", + "primitive": "primitive", + "id": 0, + "message": "Prerequisites don't exist OR they are making a loop." + } + ] + }, + { + "name": "validator2", + "passed": false, + "prerequisites": [ + { + "name": "validator1" + } + ], + "issues": [ + { + "severity": "Error", + "primitive": "primitive", + "id": 0, + "message": "Prerequisites don't exist OR they are making a loop." + } + ] + }, + { + "name": "validator3", + "passed": false, + "prerequisites": [ + { + "name": "validator2" + } + ], + "issues": [ + { + "severity": "Error", + "primitive": "primitive", + "id": 0, + "message": "Prerequisites don't exist OR they are making a loop." + } + ] + } + ] + } + ] +} diff --git a/map/autoware_lanelet2_map_validator/test/data/test_input.json b/map/autoware_lanelet2_map_validator/test/data/test_input.json index a7c81dba..8569240f 100644 --- a/map/autoware_lanelet2_map_validator/test/data/test_input.json +++ b/map/autoware_lanelet2_map_validator/test/data/test_input.json @@ -1,7 +1,7 @@ { "requirements": [ { - "id": "test-01", + "id": "test-parsing-01", "validators": [ { "name": "parsing.valid_input.no_prerequisites1" @@ -12,7 +12,7 @@ ] }, { - "id": "test-02", + "id": "test-parsing-02", "validators": [ { "name": "parsing.valid_input.with_prerequisites1", diff --git a/map/autoware_lanelet2_map_validator/test/data/test_summarize_validator_results_input.json b/map/autoware_lanelet2_map_validator/test/data/test_summarize_validator_results_input.json new file mode 100644 index 00000000..90312901 --- /dev/null +++ b/map/autoware_lanelet2_map_validator/test/data/test_summarize_validator_results_input.json @@ -0,0 +1,43 @@ +{ + "requirements": [ + { + "id": "success-requirement", + "validators": [ + { + "name": "validator1", + "passed": true + }, + { + "name": "validator2", + "passed": true + } + ] + }, + { + "id": "failure-requirement", + "validators": [ + { + "name": "validator3", + "passed": true + }, + { + "name": "validator4", + "passed": false, + "prerequisites": [ + { + "name": "validator5" + } + ], + "issues": [ + { + "severity": "Error", + "primitive": "primitive", + "id": 0, + "message": "Prerequisites don't exist OR they are making a loop." + } + ] + } + ] + } + ] +} diff --git a/map/autoware_lanelet2_map_validator/test/data/test_summarize_validator_results_output.json b/map/autoware_lanelet2_map_validator/test/data/test_summarize_validator_results_output.json new file mode 100644 index 00000000..b925fadf --- /dev/null +++ b/map/autoware_lanelet2_map_validator/test/data/test_summarize_validator_results_output.json @@ -0,0 +1,45 @@ +{ + "requirements": [ + { + "id": "success-requirement", + "passed": true, + "validators": [ + { + "name": "validator1", + "passed": true + }, + { + "name": "validator2", + "passed": true + } + ] + }, + { + "id": "failure-requirement", + "passed": false, + "validators": [ + { + "name": "validator3", + "passed": true + }, + { + "name": "validator4", + "passed": false, + "prerequisites": [ + { + "name": "validator5" + } + ], + "issues": [ + { + "severity": "Error", + "primitive": "primitive", + "id": 0, + "message": "Prerequisites don't exist OR they are making a loop." + } + ] + } + ] + } + ] +} diff --git a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp index 3ef7627b..21380e14 100644 --- a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp +++ b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp @@ -48,13 +48,11 @@ class JsonProcessingTest : public ::testing::Test file >> json_data; return json_data; } - json sample_input_data; - json sample_output_data; }; TEST_F(JsonProcessingTest, ParseValidatorsWithValidInput) { - sample_input_data = load_json_file("test_input.json"); + json sample_input_data = load_json_file("test_input.json"); Validators validators = parse_validators(sample_input_data); ASSERT_EQ(validators.size(), 3); ASSERT_TRUE(validators.find("parsing.valid_input.no_prerequisites1") != validators.end()); @@ -119,69 +117,45 @@ TEST_F(JsonProcessingTest, CheckPrerequisiteCompletionFailure) auto issues = check_prerequisite_completion(validators, "validator2"); EXPECT_EQ(issues.size(), 1); } -/* + TEST_F(JsonProcessingTest, DescriptUnusedValidatorsToJson) { Validators error_validators = { {"validator1", {{{"validator3", true}}, ValidatorInfo::Severity::ERROR}}, {"validator2", {{{"validator1", true}}, ValidatorInfo::Severity::ERROR}}, - {"validator3", {{{"validator2", true}}, ValidatorInfo::Severity::ERROR}} - }; + {"validator3", {{{"validator2", true}}, ValidatorInfo::Severity::ERROR}}}; - sample_input_data = R"({ - "requirements": [{ - "id": "1", - "validators": [{"name": "validator1"}] - }] - })"_json; + json sample_input_data = load_json_file("test_descript_unused_validators_input.json"); + json answer_output_data = load_json_file("test_descript_unused_validators_output.json"); + // Check issues auto detected_issues = descript_unused_validators_to_json(sample_input_data, error_validators); EXPECT_EQ(detected_issues.size(), 1); - EXPECT_EQ(detected_issues[0].issues.size(), 1); + EXPECT_EQ(detected_issues[0].issues.size(), 3); + EXPECT_EQ(detected_issues[0].checkName, "invalid_prerequisites"); EXPECT_EQ(detected_issues[0].issues[0].severity, lanelet::validation::Severity::Error); + EXPECT_EQ(detected_issues[0].issues[1].severity, lanelet::validation::Severity::Error); + EXPECT_EQ(detected_issues[0].issues[2].severity, lanelet::validation::Severity::Error); - // Check json_data too, + // Check json_data + EXPECT_EQ(sample_input_data, answer_output_data); } -TEST_F(JsonProcessingTest, SummarizeValidatorResultsAllPassed) +TEST_F(JsonProcessingTest, SummarizeValidatorResults) { - sample_input_data = R"({ - "requirements": [{ - "id": "1", - "validators": [{"name": "validator1", "passed": true}] - }] - })"_json; + json sample_input_data = load_json_file("test_summarize_validator_results_input.json"); + json answer_output_data = load_json_file("test_summarize_validator_results_output.json"); testing::internal::CaptureStdout(); summarize_validator_results(sample_input_data); - std::string output = testing::internal::GetCapturedStdout(); - EXPECT_NE(output.find("Passed"), std::string::npos); -} + EXPECT_EQ(sample_input_data, answer_output_data); -TEST_F(JsonProcessingTest, SummarizeValidatorResultsWithWarningsAndErrors) -{ - sample_input_data = R"({ - "requirements": [{ - "id": "1", - "validators": [{ - "name": "validator1", - "passed": false, - "issues": [ - {"severity": "Error", "message": "Test error"}, - {"severity": "Warning", "message": "Test warning"} - ] - }] - }] - })"_json; - - testing::internal::CaptureStdout(); - summarize_validator_results(sample_input_data); std::string output = testing::internal::GetCapturedStdout(); - EXPECT_NE(output.find("Failed"), std::string::npos); - EXPECT_NE(output.find("errors were found"), std::string::npos); - EXPECT_NE(output.find("warnings were found"), std::string::npos); + EXPECT_NE(output.find("[success-requirement] \033[1;32mPassed"), std::string::npos); + EXPECT_NE(output.find("[failure-requirement] \033[1;31mFailed"), std::string::npos); + EXPECT_NE(output.find("Total of 1 errors were found"), std::string::npos); + EXPECT_EQ(output.find("warnings were found"), std::string::npos); } -*/ } // namespace validation } // namespace autoware } // namespace lanelet From 828792c4850c21c3909c0fdb5e54d4fac2df4572 Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Fri, 8 Nov 2024 13:42:34 +0900 Subject: [PATCH 09/12] Revised README.md to the current status Signed-off-by: TaikiYamada4 --- map/autoware_lanelet2_map_validator/README.md | 101 ++++++++++++------ 1 file changed, 68 insertions(+), 33 deletions(-) diff --git a/map/autoware_lanelet2_map_validator/README.md b/map/autoware_lanelet2_map_validator/README.md index cd8ea6f0..a81e8341 100644 --- a/map/autoware_lanelet2_map_validator/README.md +++ b/map/autoware_lanelet2_map_validator/README.md @@ -32,7 +32,7 @@ ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator You can use `autoware_lanelet2_map_validator` with the following command. This will run all validators including the default built-in validators in the [lanelet2_validation](https://github.com/fzi-forschungszentrum-informatik/Lanelet2/tree/master/lanelet2_validation). ```bash -ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_file path/to_your/lanelet2_map.osm +ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_file path/to_your/lanelet2_map.osm --projection mgrs ``` ### Run a specific validator @@ -41,10 +41,11 @@ ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_f If you want to call a few validators, you can select them with the `--validator, -v` option. ```bash -ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_file path/to_your/lanelet2_map.osm --validator mapping.traffic_light.missing_regulatory_elements +ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_file path/to_your/lanelet2_map.osm --projection mgrs --validator mapping.traffic_light.missing_regulatory_elements ``` -You can get a list of available validators with the `--print, -p` option. +You can get a list of available validators with the `--print` option. +(`-p` is for `--projection`) ```bash ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --print @@ -57,7 +58,13 @@ ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --print The output filename will be `lanelet2_validation_results.json`. ```bash -ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --input_requirements autoware_requirements_set.json --output_directory ./ +ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator --map_file path/to_your/lanelet2_map.osm --projection mgrs --input_requirements autoware_requirements_set.json --output_directory ./ +``` + +(Short version) + +```bash +ros2 run autoware_lanelet2_map_validator autoware_lanelet2_map_validator -m path/to_your/lanelet2_map.osm -p mgrs -i autoware_requirements_set.json -o ./ ``` #### Input file @@ -66,35 +73,44 @@ The JSON file input should follow the structure like this example. ```json { - "version": "0.1.0", "requirements": [ { - "id": "example-01-01", + "id": "vm-02-02", "validators": [ { - "name": "mapping.crosswalk.missing_regulatory_elements" - }, - { - "name": "mapping.crosswalk.regulatory_element_details" + "name": "mapping.stop_line.missing_regulatory_elements" } ] }, { - "id": "example-01-02", + "id": "vm-04-01", "validators": [ { - "name": "mapping.traffic_light.missing_regulatory_elements" + "name": "mapping.crosswalk.missing_regulatory_elements" }, { - "name": "mapping.traffic_light.regulatory_element_details" + "name": "mapping.crosswalk.regulatory_element_details", + "prerequisites": [ + { + "name": "mapping.crosswalk.missing_regulatory_elements" + } + ] } ] }, { - "id": "example-01-03", + "id": "vm-05-01", "validators": [ { - "name": "mapping.stop_line.missing_regulatory_elements" + "name": "mapping.traffic_light.missing_regulatory_elements" + }, + { + "name": "mapping.traffic_light.regulatory_element_details", + "prerequisites": [ + { + "name": "mapping.traffic_light.missing_regulatory_elements" + } + ] } ] } @@ -108,6 +124,8 @@ The JSON file input should follow the structure like this example. - `validators` : A list of validators that structures the requirement. - A validator MUST be given with its name on the `name` field. - The name list of available validators can be obtained from the `--print` option. + - You can add a list of `prerequisites` to each validator. Then, the validator will only be run when the prequisites pass the validation. + - In the `prerequisites` field, you can add `forgive_warnings: true` in order to run the validator even if the prequisites output warning issues. (Error issues from prerequisites will still skip the validation.). Note that NOT writing the `forgive_warnings` field and writing `forgive_warnings: false` means the same. - The user can write any other field (like `version`) besides `requirements`. #### Output file @@ -118,7 +136,17 @@ When the `input_requirements` is thrown to `autoware_lanelet2_map_validator`, it { "requirements": [ { - "id": "example-01-01", + "id": "vm-02-02", + "passed": true, + "validators": [ + { + "name": "mapping.stop_line.missing_regulatory_elements", + "passed": true + } + ] + }, + { + "id": "vm-04-01", "passed": false, "validators": [ { @@ -152,13 +180,26 @@ When the `input_requirements` is thrown to `autoware_lanelet2_map_validator`, it "passed": false }, { + "issues": [ + { + "id": 0, + "message": "Prerequisites didn't pass", + "primitive": "primitive", + "severity": "Error" + } + ], "name": "mapping.crosswalk.regulatory_element_details", - "passed": true + "passed": false, + "prerequisites": [ + { + "name": "mapping.crosswalk.missing_regulatory_elements" + } + ] } ] }, { - "id": "example-01-02", + "id": "vm-05-01", "passed": false, "validators": [ { @@ -193,27 +234,21 @@ When the `input_requirements` is thrown to `autoware_lanelet2_map_validator`, it } ], "name": "mapping.traffic_light.regulatory_element_details", - "passed": false - } - ] - }, - { - "id": "example-01-03", - "passed": true, - "validators": [ - { - "name": "mapping.stop_line.missing_regulatory_elements", - "passed": true + "passed": false, + "prerequisites": [ + { + "name": "mapping.traffic_light.missing_regulatory_elements" + } + ] } ] } - ], - "version": "0.1.0" + ] } ``` - `lanelet2_validation_results.json` inherits the JSON file of `input_requirements` and add results to it. - - So non-required fields (line `version`) remains in the output. + - So additional input information not related to this validator also remains in the output. - `autoware_lanelet2_map_validator` adds a boolean `passed` field to each requirement. If all validators of the requirement have been passed, the `passed` field of the requirement will be `true` (`false` if not). - The `passed` field is also given to each validator. If the validator found any issues the `passed` field will turn to be `false` (`true` if not), and adds an `issues` field which is a list of issues found. Each issue contains information of `severity`, `primitive`, `id`, and `message`. @@ -227,7 +262,7 @@ When the `input_requirements` is thrown to `autoware_lanelet2_map_validator`, it | `-i, --input_requirements` | Path to the JSON file where the list of requirements and validations is written | | `-o, --output_directory` | Directory to save the list of validation results in a JSON format | | `-v, --validator` | Comma separated list of regexes to filter the applicable validators. Will run all validators by default. Example: `mapping.*` to run all checks for the mapping | -| `-p, --projector` | Projector used for loading lanelet map. Available projectors are: mgrs, utm, transverse_mercator. (default: mgrs) | +| `-p, --projector` | Projector used for loading lanelet map. Available projectors are: `mgrs`, `utm`, and `transverse_mercator`. | | `-l, --location` | Location of the map (for instantiating the traffic rules), e.g. de for Germany | | `--participants` | Participants for which the routing graph will be instantiated (default: vehicle) | | `--lat` | latitude coordinate of map origin. This is required for the transverse mercator and utm projector. | From 5a5bcccd2517641c1789aaaef83e5526fe85f296 Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Fri, 8 Nov 2024 14:36:49 +0900 Subject: [PATCH 10/12] Fixed typo and unknown words Signed-off-by: TaikiYamada4 --- map/autoware_lanelet2_map_validator/README.md | 4 ++-- map/autoware_lanelet2_map_validator/src/common/validation.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/map/autoware_lanelet2_map_validator/README.md b/map/autoware_lanelet2_map_validator/README.md index a81e8341..60991d58 100644 --- a/map/autoware_lanelet2_map_validator/README.md +++ b/map/autoware_lanelet2_map_validator/README.md @@ -124,8 +124,8 @@ The JSON file input should follow the structure like this example. - `validators` : A list of validators that structures the requirement. - A validator MUST be given with its name on the `name` field. - The name list of available validators can be obtained from the `--print` option. - - You can add a list of `prerequisites` to each validator. Then, the validator will only be run when the prequisites pass the validation. - - In the `prerequisites` field, you can add `forgive_warnings: true` in order to run the validator even if the prequisites output warning issues. (Error issues from prerequisites will still skip the validation.). Note that NOT writing the `forgive_warnings` field and writing `forgive_warnings: false` means the same. + - You can add a list of `prerequisites` to each validator. Then, the validator will only be run when the prerequisites pass the validation. + - In the `prerequisites` field, you can add `forgive_warnings: true` in order to run the validator even if the prerequisites output warning issues. (Error issues from prerequisites will still skip the validation.). Note that NOT writing the `forgive_warnings` field and writing `forgive_warnings: false` means the same. - The user can write any other field (like `version`) besides `requirements`. #### Output file diff --git a/map/autoware_lanelet2_map_validator/src/common/validation.cpp b/map/autoware_lanelet2_map_validator/src/common/validation.cpp index 91befdc5..9b6083fe 100644 --- a/map/autoware_lanelet2_map_validator/src/common/validation.cpp +++ b/map/autoware_lanelet2_map_validator/src/common/validation.cpp @@ -37,6 +37,8 @@ #define NORMAL_RED "\033[31m" #define FONT_RESET "\033[0m" +// cSpell:words indegree Indegree + namespace lanelet { namespace autoware From be45043c11907a331c5df05d3926a766f445bfbb Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Fri, 8 Nov 2024 18:03:37 +0900 Subject: [PATCH 11/12] Reflect PR comments Signed-off-by: TaikiYamada4 --- .../src/common/validation.cpp | 10 ++++++---- .../src/include/lanelet2_map_validator/validation.hpp | 2 +- ...json => test_describe_unused_validators_input.json} | 0 ...son => test_describe_unused_validators_output.json} | 0 .../test/src/test_json_processing.cpp | 6 +++--- 5 files changed, 10 insertions(+), 8 deletions(-) rename map/autoware_lanelet2_map_validator/test/data/{test_descript_unused_validators_input.json => test_describe_unused_validators_input.json} (100%) rename map/autoware_lanelet2_map_validator/test/data/{test_descript_unused_validators_output.json => test_describe_unused_validators_output.json} (100%) diff --git a/map/autoware_lanelet2_map_validator/src/common/validation.cpp b/map/autoware_lanelet2_map_validator/src/common/validation.cpp index 9b6083fe..e4f794ad 100644 --- a/map/autoware_lanelet2_map_validator/src/common/validation.cpp +++ b/map/autoware_lanelet2_map_validator/src/common/validation.cpp @@ -190,7 +190,7 @@ json & find_validator_block(json & json_data, const std::string & validator_name throw std::runtime_error(msg); } -std::vector descript_unused_validators_to_json( +std::vector describe_unused_validators_to_json( json & json_data, const Validators & unused_validators) { lanelet::validation::Issues issues; @@ -340,9 +340,11 @@ void process_requirements(json json_data, const MetaConfig & validator_config) auto [validation_queue, remaining_validators] = create_validation_queue(validators); // Note validators that cannot be run from the start - std::vector unused_validator_issues = - descript_unused_validators_to_json(json_data, remaining_validators); - appendIssues(issues, std::move(unused_validator_issues)); + if (auto unused_validator_issues = + describe_unused_validators_to_json(json_data, remaining_validators); + !unused_validator_issues.empty()) { + appendIssues(issues, std::move(unused_validator_issues)); + } // Main validation process while (!validation_queue.empty()) { diff --git a/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp b/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp index bc4f8e11..5b1d230d 100644 --- a/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp +++ b/map/autoware_lanelet2_map_validator/src/include/lanelet2_map_validator/validation.hpp @@ -77,7 +77,7 @@ std::tuple, Validators> create_validation_queue( // Function to find a validator block by name json & find_validator_block(json & json_data, const std::string & validator_name); -std::vector descript_unused_validators_to_json( +std::vector describe_unused_validators_to_json( json & json_data, const Validators & unused_validators); std::vector check_prerequisite_completion( diff --git a/map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_input.json b/map/autoware_lanelet2_map_validator/test/data/test_describe_unused_validators_input.json similarity index 100% rename from map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_input.json rename to map/autoware_lanelet2_map_validator/test/data/test_describe_unused_validators_input.json diff --git a/map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_output.json b/map/autoware_lanelet2_map_validator/test/data/test_describe_unused_validators_output.json similarity index 100% rename from map/autoware_lanelet2_map_validator/test/data/test_descript_unused_validators_output.json rename to map/autoware_lanelet2_map_validator/test/data/test_describe_unused_validators_output.json diff --git a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp index 21380e14..de2c8c0a 100644 --- a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp +++ b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp @@ -125,11 +125,11 @@ TEST_F(JsonProcessingTest, DescriptUnusedValidatorsToJson) {"validator2", {{{"validator1", true}}, ValidatorInfo::Severity::ERROR}}, {"validator3", {{{"validator2", true}}, ValidatorInfo::Severity::ERROR}}}; - json sample_input_data = load_json_file("test_descript_unused_validators_input.json"); - json answer_output_data = load_json_file("test_descript_unused_validators_output.json"); + json sample_input_data = load_json_file("test_describe_unused_validators_input.json"); + json answer_output_data = load_json_file("test_describe_unused_validators_output.json"); // Check issues - auto detected_issues = descript_unused_validators_to_json(sample_input_data, error_validators); + auto detected_issues = describe_unused_validators_to_json(sample_input_data, error_validators); EXPECT_EQ(detected_issues.size(), 1); EXPECT_EQ(detected_issues[0].issues.size(), 3); EXPECT_EQ(detected_issues[0].checkName, "invalid_prerequisites"); From e5ee2e78ed143cde39428b2fc4905937dac060d9 Mon Sep 17 00:00:00 2001 From: TaikiYamada4 Date: Fri, 8 Nov 2024 18:14:15 +0900 Subject: [PATCH 12/12] Fixed typo Signed-off-by: TaikiYamada4 --- .../test/src/test_json_processing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp index de2c8c0a..1c8a0e3e 100644 --- a/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp +++ b/map/autoware_lanelet2_map_validator/test/src/test_json_processing.cpp @@ -118,7 +118,7 @@ TEST_F(JsonProcessingTest, CheckPrerequisiteCompletionFailure) EXPECT_EQ(issues.size(), 1); } -TEST_F(JsonProcessingTest, DescriptUnusedValidatorsToJson) +TEST_F(JsonProcessingTest, DescribeUnusedValidatorsToJson) { Validators error_validators = { {"validator1", {{{"validator3", true}}, ValidatorInfo::Severity::ERROR}},