TestFixture.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "TestFixture.h"
  9. #include <AzCore/Component/EntityId.h>
  10. #include <Clients/SimulationEntitiesManager.h>
  11. #include <Clients/SimulationManager.h>
  12. #include <SimulationInterfaces/SimulationEntityManagerRequestBus.h>
  13. #include <gtest/gtest.h>
  14. namespace UnitTest
  15. {
  16. void SimulationInterfaceTestEnvironment::AddGemsAndComponents()
  17. {
  18. constexpr AZStd::array<AZStd::string_view, 4> requiredGems = { "PhysX5", // required for PhysX Dynamic
  19. "LmbrCentral", // for shapes
  20. "ROS2", // For frame component
  21. "SimulationInterfaces" };
  22. AddActiveGems(requiredGems);
  23. AddDynamicModulePaths({ "PhysX5.Gem" });
  24. AddDynamicModulePaths({ "LmbrCentral" });
  25. AddDynamicModulePaths({ "ROS2" });
  26. AddComponentDescriptors(
  27. AZStd::initializer_list<AZ::ComponentDescriptor*>{ SimulationInterfaces::SimulationEntitiesManager::CreateDescriptor(),
  28. SimulationInterfaces::SimulationManager::CreateDescriptor() });
  29. AddRequiredComponents(
  30. { SimulationInterfaces::SimulationEntitiesManager::TYPEINFO_Uuid(), SimulationInterfaces::SimulationManager::TYPEINFO_Uuid() });
  31. }
  32. void SimulationInterfaceTestEnvironment::PostSystemEntityActivate()
  33. {
  34. AZ::UserSettingsComponentRequestBus::Broadcast(&AZ::UserSettingsComponentRequests::DisableSaveOnFinalize);
  35. }
  36. AZ::ComponentApplication* SimulationInterfaceTestEnvironment::CreateApplicationInstance()
  37. {
  38. // Using ToolsTestApplication to have AzFramework and AzToolsFramework components.
  39. return aznew UnitTest::ToolsTestApplication("SimulationInterfaceTestEnvironment");
  40. }
  41. void SimulationInterfaceTestFixture::AddAsset(const AZStd::string& assetPath)
  42. {
  43. AZ::Data::AssetInfo info;
  44. info.m_relativePath = assetPath;
  45. info.m_sizeBytes = 1;
  46. AZ::Data::AssetId id = AZ::Data::AssetId(AZ::Uuid::CreateRandom());
  47. AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::RegisterAsset, id, info);
  48. m_registeredAssets.insert(id);
  49. }
  50. AzPhysics::SceneHandle SimulationInterfaceTestFixture::GetDefaultSceneHandle() const
  51. {
  52. return m_testSceneHandle;
  53. }
  54. AZ::EntityId SimulationInterfaceTestFixture::CreateEntityWithStaticBodyComponent(
  55. const AZStd::string& entityName, const AZ::Transform& transform)
  56. {
  57. AZStd::unique_ptr<AZ::Entity> entity = AZStd::make_unique<AZ::Entity>(entityName.c_str());
  58. auto* transformComponent = entity->CreateComponent(AZ::TransformComponentTypeId);
  59. AZ_Assert(transformComponent, "Failed to create TransformComponent");
  60. auto* transformInterface = azrtti_cast<AZ::TransformInterface*>(transformComponent);
  61. AZ_Assert(transformInterface, "Failed to get TransformInterface");
  62. transformInterface->SetWorldTM(transform);
  63. entity->CreateComponent(AZ::Uuid(PhysXRigidBodyComponentTypeId));
  64. entity->CreateComponent(AZ::Uuid(PhysXShapeColliderComponentTypeId));
  65. entity->CreateComponent(AZ::Uuid(SphereShapeComponentTypeId));
  66. entity->Init();
  67. entity->Activate();
  68. AZ_Assert(entity->GetState() == AZ::Entity::State::Active, "Entity is not active");
  69. // register entity
  70. AZ::Outcome<AZStd::string, SimulationInterfaces::FailedResult> output;
  71. SimulationInterfaces::SimulationEntityManagerRequestBus::BroadcastResult(
  72. output, &SimulationInterfaces::SimulationEntityManagerRequests::RegisterNewSimulatedBody, entityName, entity->GetId());
  73. // function return type is different than void, so ASSERT_TRUE cannot be used. Expect_true and early return is added to mimic assert
  74. // behaviour
  75. EXPECT_TRUE(output.IsSuccess()) << "Failed to register entity to simulation_interfaces, "
  76. << output.GetError().m_errorString.c_str();
  77. if (!output.IsSuccess())
  78. {
  79. return AZ::EntityId{ AZ::EntityId::InvalidEntityId };
  80. }
  81. entity->SetName(output.GetValue()); // name in simulation_interfaces registry could be change to ensure uniqueness. Apply new name
  82. // to the created entity
  83. auto id = entity->GetId();
  84. m_entities.emplace(AZStd::make_pair(id, AZStd::move(entity)));
  85. return id;
  86. }
  87. void SimulationInterfaceTestFixture::ClearEntities()
  88. {
  89. for (auto& entity : m_entities)
  90. {
  91. AZ::Outcome<void, SimulationInterfaces::FailedResult> output;
  92. SimulationInterfaces::SimulationEntityManagerRequestBus::BroadcastResult(
  93. output, &SimulationInterfaces::SimulationEntityManagerRequests::UnregisterSimulatedBody, entity.second->GetName());
  94. AZ_Assert(
  95. output.IsSuccess(), "Failed to unregister entity from simulation_interfaces, %s", output.GetError().m_errorString.c_str());
  96. entity.second->Deactivate();
  97. }
  98. m_entities.clear();
  99. }
  100. void SimulationInterfaceTestFixture::DeleteEntity(const AZ::EntityId& entityId)
  101. {
  102. auto findIt = m_entities.find(entityId);
  103. if (findIt != m_entities.end())
  104. {
  105. AZ::Outcome<void, SimulationInterfaces::FailedResult> output;
  106. SimulationInterfaces::SimulationEntityManagerRequestBus::BroadcastResult(
  107. output, &SimulationInterfaces::SimulationEntityManagerRequests::UnregisterSimulatedBody, findIt->second->GetName());
  108. AZ_Assert(
  109. output.IsSuccess(), "Failed to unregister entity from simulation_interfaces, %s", output.GetError().m_errorString.c_str());
  110. findIt->second->Deactivate();
  111. m_entities.erase(findIt);
  112. }
  113. }
  114. void SimulationInterfaceTestFixture::SetUp()
  115. {
  116. if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
  117. {
  118. AzPhysics::SceneConfiguration sceneConfiguration = physicsSystem->GetDefaultSceneConfiguration();
  119. sceneConfiguration.m_sceneName = AzPhysics::DefaultPhysicsSceneName;
  120. m_testSceneHandle = physicsSystem->AddScene(sceneConfiguration);
  121. m_defaultScene = physicsSystem->GetScene(m_testSceneHandle);
  122. }
  123. Physics::DefaultWorldBus::Handler::BusConnect();
  124. }
  125. void SimulationInterfaceTestFixture::TearDown()
  126. {
  127. ClearEntities();
  128. Physics::DefaultWorldBus::Handler::BusDisconnect();
  129. m_defaultScene = nullptr;
  130. // Clean up the Test scene
  131. if (auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get())
  132. {
  133. physicsSystem->RemoveScene(m_testSceneHandle);
  134. }
  135. m_testSceneHandle = AzPhysics::InvalidSceneHandle;
  136. for (const auto& id : m_registeredAssets)
  137. {
  138. AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::UnregisterAsset, id);
  139. }
  140. m_registeredAssets.clear();
  141. }
  142. void SimulationInterfaceTestFixture::StepPhysics(int numSteps)
  143. {
  144. for (int i = 0; i < numSteps; i++)
  145. {
  146. auto* physicsSystem = AZ::Interface<AzPhysics::SystemInterface>::Get();
  147. physicsSystem->Simulate(1.0f / 60.0f);
  148. }
  149. }
  150. void SimulationInterfaceTestFixture::TickApp(int numTicks)
  151. {
  152. AZ::ComponentApplication* app = nullptr;
  153. AZ::ComponentApplicationBus::BroadcastResult(app, &AZ::ComponentApplicationBus::Events::GetApplication);
  154. AZ_Assert(app, "Failed to get application");
  155. for (int i = 0; i < numTicks; i++)
  156. {
  157. app->Tick();
  158. }
  159. }
  160. } // namespace UnitTest