-
Andreas Rauschert authored
fix: set environment defaults before initializing environment and don't stop creating controllers on non-controllable entities
Andreas Rauschert authoredfix: set environment defaults before initializing environment and don't stop creating controllers on non-controllable entities
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ControllerCreatorTest.cpp 11.20 KiB
/*******************************************************************************
* Copyright (c) 2023, Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
* Copyright (c) 2023 Ansys, Inc.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
#include <ApiClassWriterInterfacesV1_2.h>
#include <MantleAPI/Test/test_utils.h>
#include <gtest/gtest.h>
#include <openScenarioLib/generated/v1_2/impl/ApiClassImplV1_2.h>
#include <openScenarioLib/generated/v1_2/impl/OpenScenarioWriterFactoryImplV1_2.h>
#include "MantleAPI/Common/i_identifiable.h"
#include "TestUtils.h"
#include "TestUtils/TestLogger.h"
#include "Utils/ControllerCreator.h"
using testing::_;
using testing::Gt;
using testing::HasSubstr;
using testing::Ne;
using testing::Return;
using testing::ReturnRef;
using testing::SizeIs;
class ControllerCreator : public ::testing::Test
{
public:
inline static constexpr mantle_api::UniqueId TEST_CONTROLLER_ID{1234};
inline static const std::string TEST_CONTROLLER_NAME{"TEST_CONTROLLER"};
ControllerCreator()
: LOGGER{std::make_unique<testing::OpenScenarioEngine::v1_2::TestLogger>()},
mockEnvironment{},
mockEntityRepository{dynamic_cast<mantle_api::MockEntityRepository&>(mockEnvironment.GetEntityRepository())},
mockControllerRepository{mockEnvironment.GetControllerRepository()},
mockController{}
{
ON_CALL(mockController, GetName()).WillByDefault(ReturnRef(TEST_CONTROLLER_NAME));
ON_CALL(mockController, GetUniqueId()).WillByDefault(testing::Invoke([] {
// id will be incremented at every call, starting with 1000
static mantle_api::UniqueId id{1000};
return id++;
}));
}
void SET_VEHICLE_MOCK_NAME_AND_ID(const std::string& name, mantle_api::UniqueId id)
{
auto& mockVehicle = dynamic_cast<mantle_api::MockVehicle&>(mockEnvironment.GetEntityRepository().Get(name).value().get());
mockVehicle.SetName(name);
ON_CALL(mockVehicle, GetUniqueId()).WillByDefault(Return(id));
}
void SETUP_ENTITY(std::string entity_name, mantle_api::UniqueId entity_id, bool entity_is_controllable, bool with_user_defined_controller)
{
using namespace NET_ASAM_OPENSCENARIO::v1_2;
auto scenario_object = std::make_shared<ScenarioObjectImpl>();
scenario_object->SetName(std::move(entity_name));
if (with_user_defined_controller)
{
// create a controller
auto controller = std::make_shared<ControllerImpl>();
controller->SetName("USER_DEFINED_CONTROLLER");
// adding a property to controller
std::shared_ptr<IPropertiesWriter> properties{std::make_shared<PropertiesImpl>()};
std::shared_ptr<IPropertyWriter> property{std::make_shared<PropertyImpl>()};
property->SetName("TEST_PROPERTY_NAME");
property->SetValue("TEST_PROPERTY_VALUE");
controller->SetProperties({properties});
// create object_controllers and add controller to the first (and only) object_controller
std::vector<std::shared_ptr<IObjectControllerWriter>> object_controller{std::make_shared<ObjectControllerImpl>()};
auto object_controller_impl = std::dynamic_pointer_cast<ObjectControllerImpl>(object_controller.front());
object_controller_impl->SetController(std::move(controller));
// wiring objects to scenario
scenario_object->SetObjectController(object_controller);
}
auto entity_object = std::make_shared<EntityObjectImpl>();
if (entity_is_controllable)
{
auto vehicle = std::make_shared<VehicleImpl>();
entity_object->SetVehicle(vehicle);
SET_VEHICLE_MOCK_NAME_AND_ID(entity_name, entity_id);
}
else
{
auto misc_object = std::make_shared<MiscObjectImpl>();
entity_object->SetMiscObject(misc_object);
}
scenario_object->SetEntityObject(entity_object);
scenario_objects.push_back(std::move(scenario_object));
}
std::unique_ptr<testing::OpenScenarioEngine::v1_2::TestLogger> LOGGER;
mantle_api::MockEnvironment mockEnvironment;
mantle_api::MockEntityRepository& mockEntityRepository;
mantle_api::MockControllerRepository& mockControllerRepository;
mantle_api::MockController mockController;
std::vector<std::shared_ptr<NET_ASAM_OPENSCENARIO::v1_2::IScenarioObject>> scenario_objects{};
std::vector<std::unique_ptr<mantle_api::IEntity>> entities_{};
};
TEST_F(ControllerCreator, GivenNoScenarioObjects_WhenCreateIsCalled_ThenDoesNothing)
{
EXPECT_CALL(mockControllerRepository, Create(_)).Times(0);
OpenScenarioEngine::v1_2::ControllerCreator controller_creator(mockEnvironment);
controller_creator.CreateControllers(scenario_objects);
}
TEST_F(ControllerCreator, GivenScenarioObjectWithoutController_WhenCreateIsCalled_ThenCreatesDefaultController)
{
SETUP_ENTITY("test_entity", 1234, true, false);
EXPECT_CALL(mockControllerRepository, Create(_)).WillOnce(ReturnRef(mockController));
OpenScenarioEngine::v1_2::ControllerCreator controller_creator(mockEnvironment);
controller_creator.CreateControllers(scenario_objects);
}
TEST_F(ControllerCreator, GivenUncontrollableScenarioObject_WhenCreateIsCalled_ThenDoesNothingAndLogsMessage)
{
SETUP_ENTITY("test_entity", 1234, false, false);
EXPECT_CALL(mockControllerRepository, Create(_)).Times(0);
OpenScenarioEngine::v1_2::ControllerCreator controller_creator(mockEnvironment);
controller_creator.CreateControllers(scenario_objects);
EXPECT_THAT(LOGGER->LastLogLevel(), mantle_api::LogLevel::kInfo);
EXPECT_THAT(LOGGER->LastLogMessage(), HasSubstr("No controller created"));
EXPECT_THAT(LOGGER->LastLogMessage(), HasSubstr("test_entity"));
}
TEST_F(ControllerCreator, GivenUncontrollableAndControllableScenarioObject_WhenCreateIsCalled_ThenControllerOnlyForControllableObjectIsCreated)
{
SETUP_ENTITY("uncontrollable_entity", 1234, false, false);
SETUP_ENTITY("entity_2", 5678, true, false);
EXPECT_CALL(mockControllerRepository, Create(_)).Times(1).WillOnce(ReturnRef(mockController));
OpenScenarioEngine::v1_2::ControllerCreator controller_creator(mockEnvironment);
controller_creator.CreateControllers(scenario_objects);
}
TEST_F(ControllerCreator, GivenScenarioObjectWithController_WhenCreateIsCalled_ThenCreatesDefaultAndUserDefinedController)
{
SETUP_ENTITY("test_entity", 1234, true, true);
EXPECT_CALL(mockControllerRepository, Create(_))
.WillOnce(ReturnRef(mockController))
.WillOnce(ReturnRef(mockController));
OpenScenarioEngine::v1_2::ControllerCreator controller_creator(mockEnvironment);
controller_creator.CreateControllers(scenario_objects);
}
TEST_F(ControllerCreator, GivenScenarioObjectWithController_WhenCreateIsCalled_ThenControllerServiceContainsEntitiyControllers)
{
constexpr mantle_api::UniqueId ENTITY_ID = 1234;
SETUP_ENTITY("test_entity", ENTITY_ID, true, true);
ON_CALL(mockControllerRepository, Create(_)).WillByDefault(ReturnRef(mockController));
OpenScenarioEngine::v1_2::ControllerCreator controller_creator(mockEnvironment);
controller_creator.CreateControllers(scenario_objects);
auto controller_service = controller_creator.GetControllerService();
auto controllers = controller_service->GetControllers(ENTITY_ID);
auto internal_controller_id = controllers->internal.first;
EXPECT_THAT(internal_controller_id, Gt(0));
ASSERT_THAT(controllers->user_defined, SizeIs(1));
auto user_defined_controller_id = controllers->user_defined.begin()->first;
EXPECT_THAT(user_defined_controller_id, Gt(0));
ASSERT_THAT(internal_controller_id, Ne(user_defined_controller_id));
}
TEST_F(ControllerCreator, GivenExternalControllerOverrideSet_WhenCreateControllerIsCalled_ThenHostGetsUserDefinedController)
{
constexpr mantle_api::UniqueId ENTITY_ID = 1234;
// "DSpace" host "M1:..." and no external controller
SETUP_ENTITY("M1:test_entity", ENTITY_ID, true, false);
mantle_api::MockController default_controller{};
constexpr mantle_api::UniqueId DEFAULT_CONTROLLER_ID{1000};
std::string DEFAULT_CONTROLLER_NAME{"DEFAULT_CONTROLLER"};
ON_CALL(default_controller, GetUniqueId()).WillByDefault(Return(DEFAULT_CONTROLLER_ID));
ON_CALL(default_controller, GetName()).WillByDefault(ReturnRef(DEFAULT_CONTROLLER_NAME));
EXPECT_CALL(default_controller,
ChangeState(mantle_api::IController::LateralState::kActivate, mantle_api::IController::LongitudinalState::kActivate))
.Times(1);
EXPECT_CALL(default_controller,
ChangeState(mantle_api::IController::LateralState::kDeactivate, mantle_api::IController::LongitudinalState::kDeactivate))
.Times(1);
mantle_api::MockController user_defined_controller{};
constexpr mantle_api::UniqueId USER_DEFINED_CONTROLLER_ID{1001};
std::string USER_DEFINED_CONTROLLER_NAME{"USED_DEFINED_CONTROLLER"};
ON_CALL(user_defined_controller, GetUniqueId()).WillByDefault(Return(USER_DEFINED_CONTROLLER_ID));
ON_CALL(user_defined_controller, GetName()).WillByDefault(ReturnRef(USER_DEFINED_CONTROLLER_NAME));
EXPECT_CALL(user_defined_controller,
ChangeState(mantle_api::IController::LateralState::kActivate, mantle_api::IController::LongitudinalState::kActivate))
.Times(1);
EXPECT_CALL(mockControllerRepository, Create(_))
.WillOnce(ReturnRef(default_controller))
.WillOnce(ReturnRef(user_defined_controller));
OpenScenarioEngine::v1_2::ControllerCreator controller_creator(mockEnvironment);
controller_creator.EnableUserDefinedControllerOverride();
controller_creator.CreateControllers(scenario_objects);
auto controller_service = controller_creator.GetControllerService();
auto controllers = controller_service->GetControllers(ENTITY_ID);
auto actual_internal_controller_id = controllers->internal.first;
EXPECT_EQ(actual_internal_controller_id, DEFAULT_CONTROLLER_ID);
ASSERT_THAT(controllers->user_defined, SizeIs(1));
auto actual_user_defined_controller_id = controllers->user_defined.begin()->first;
EXPECT_EQ(actual_user_defined_controller_id, USER_DEFINED_CONTROLLER_ID);
}
TEST_F(ControllerCreator, GivenScenarioObjectWithoutController_WhenCreateControllersIsCalled_ThenDefaultControllerIsCreatedAndActivated)
{
SETUP_ENTITY("test_entity", 1234, true, false);
EXPECT_CALL(mockControllerRepository, Create(_)).WillOnce(ReturnRef(mockController));
EXPECT_CALL(mockController, ChangeState(_, _)).Times(1);
OpenScenarioEngine::v1_2::ControllerCreator controller_creator(mockEnvironment);
controller_creator.CreateControllers(scenario_objects);
}
TEST_F(ControllerCreator, GivenScenarioObjectWithController_WhenResetControllerMappingsIsCalled_ThenControllerServiceInternalStateIsReset)
{
constexpr mantle_api::UniqueId ENTITY_ID = 1234;
SETUP_ENTITY("test_entity", ENTITY_ID, true, true);
ON_CALL(mockControllerRepository, Create(_)).WillByDefault(ReturnRef(mockController));
OpenScenarioEngine::v1_2::ControllerCreator controller_creator(mockEnvironment);
controller_creator.CreateControllers(scenario_objects);
auto controller_service = controller_creator.GetControllerService();
ASSERT_TRUE(controller_service->GetControllers(ENTITY_ID).has_value());
controller_service->ResetControllerMappings();
EXPECT_FALSE(controller_service->GetControllers(ENTITY_ID).has_value());
}