Skip to content

Commit

Permalink
Make lights controller tests lightweight
Browse files Browse the repository at this point in the history
  • Loading branch information
pawelirh committed Sep 5, 2024
1 parent fb71613 commit 7f2dc9e
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 101 deletions.
39 changes: 21 additions & 18 deletions panther_lights/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ install(DIRECTORY animations config launch DESTINATION share/${PROJECT_NAME})

if(BUILD_TESTING)
find_package(ament_cmake_gtest REQUIRED)
find_package(ament_cmake_gmock REQUIRED)
find_package(ros_testing REQUIRED)

ament_add_gtest(${PROJECT_NAME}_test_animation
test/animation/test_animation.cpp)
Expand Down Expand Up @@ -183,6 +185,25 @@ if(BUILD_TESTING)
panther_utils rclcpp)
target_link_libraries(${PROJECT_NAME}_test_led_animations_queue yaml-cpp)

ament_add_gmock(${PROJECT_NAME}_test_apa102 test/test_apa102.cpp
src/apa102.cpp)
target_include_directories(
${PROJECT_NAME}_test_apa102
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)

ament_add_gmock(
${PROJECT_NAME}_test_lights_driver_node test/test_lights_driver_node.cpp
src/apa102.cpp src/lights_driver_node.cpp)
target_include_directories(
${PROJECT_NAME}_test_lights_driver_node
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
ament_target_dependencies(${PROJECT_NAME}_test_lights_driver_node
panther_utils)
target_link_libraries(${PROJECT_NAME}_test_lights_driver_node
lights_driver_node_component)

ament_add_gtest(
${PROJECT_NAME}_test_lights_controller_node
test/test_lights_controller_node.cpp
Expand All @@ -200,24 +221,6 @@ if(BUILD_TESTING)
target_link_libraries(${PROJECT_NAME}_test_lights_controller_node
lights_controller_node_component yaml-cpp)

ament_add_gtest(${PROJECT_NAME}_test_apa102 test/test_apa102.cpp
src/apa102.cpp)
target_include_directories(
${PROJECT_NAME}_test_apa102
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)

ament_add_gtest(
${PROJECT_NAME}_test_lights_driver_node test/test_lights_driver_node.cpp
src/apa102.cpp src/lights_driver_node.cpp)
target_include_directories(
${PROJECT_NAME}_test_lights_driver_node
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
ament_target_dependencies(${PROJECT_NAME}_test_lights_driver_node
panther_utils)
target_link_libraries(${PROJECT_NAME}_test_lights_driver_node
lights_driver_node_component)
endif()

ament_export_include_directories(include)
Expand Down
4 changes: 4 additions & 0 deletions panther_lights/package.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@
<depend>sensor_msgs</depend>
<depend>std_srvs</depend>

<test_depend>ament_cmake_gtest</test_depend>
<test_depend>google-mock</test_depend>
<test_depend>ros_testing</test_depend>

<export>
<build_type>ament_cmake</build_type>
</export>
Expand Down
97 changes: 14 additions & 83 deletions panther_lights/test/test_lights_controller_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,14 @@ class ControllerNodeWrapper : public panther_lights::LightsControllerNode
}
};

class TestControllerNode : public testing::Test
class TestLightsControllerNode : public testing::Test
{
public:
TestControllerNode();
~TestControllerNode();
TestLightsControllerNode();
~TestLightsControllerNode();

protected:
void CreateLEDConfig(const std::filesystem::path file_path);
void CallSetLEDAnimationSrv(
const std::size_t animation_id, const bool repeating, const std::string & param = "");

static constexpr std::size_t kTestNumberOfLeds = 10;
static constexpr std::size_t kTestChannel = 1;
Expand All @@ -81,10 +79,9 @@ class TestControllerNode : public testing::Test

std::filesystem::path led_config_file_;
std::shared_ptr<ControllerNodeWrapper> lights_controller_node_;
rclcpp::Client<panther_msgs::srv::SetLEDAnimation>::SharedPtr set_led_anim_client_;
};

TestControllerNode::TestControllerNode()
TestLightsControllerNode::TestLightsControllerNode()
{
led_config_file_ = testing::TempDir() + "/led_config.yaml";

Expand All @@ -97,14 +94,11 @@ TestControllerNode::TestControllerNode()
options.parameter_overrides(params);

lights_controller_node_ = std::make_shared<ControllerNodeWrapper>(options);

set_led_anim_client_ = lights_controller_node_->create_client<panther_msgs::srv::SetLEDAnimation>(
"lights/set_animation");
}

TestControllerNode::~TestControllerNode() { std::filesystem::remove(led_config_file_); }
TestLightsControllerNode::~TestLightsControllerNode() { std::filesystem::remove(led_config_file_); }

void TestControllerNode::CreateLEDConfig(const std::filesystem::path file_path)
void TestLightsControllerNode::CreateLEDConfig(const std::filesystem::path file_path)
{
YAML::Node panel;
panel["channel"] = kTestChannel;
Expand Down Expand Up @@ -157,23 +151,7 @@ void TestControllerNode::CreateLEDConfig(const std::filesystem::path file_path)
}
}

void TestControllerNode::CallSetLEDAnimationSrv(
const std::size_t animation_id, const bool repeating, const std::string & param)
{
auto request = std::make_shared<panther_msgs::srv::SetLEDAnimation::Request>();
request->animation.id = animation_id;
request->animation.param = param;
request->repeating = repeating;

auto result = set_led_anim_client_->async_send_request(request);

ASSERT_TRUE(
rclcpp::spin_until_future_complete(lights_controller_node_, result) ==
rclcpp::FutureReturnCode::SUCCESS);
EXPECT_TRUE(result.get()->success);
}

TEST_F(TestControllerNode, InitializeLEDPanelsThrowRepeatingChannel)
TEST_F(TestLightsControllerNode, InitializeLEDPanelsThrowRepeatingChannel)
{
YAML::Node panel_1_desc;
panel_1_desc["channel"] = kTestChannel;
Expand All @@ -195,7 +173,7 @@ TEST_F(TestControllerNode, InitializeLEDPanelsThrowRepeatingChannel)
"Multiple panels with channel nr"));
}

TEST_F(TestControllerNode, InitializeLEDSegmentsThrowRepeatingName)
TEST_F(TestLightsControllerNode, InitializeLEDSegmentsThrowRepeatingName)
{
YAML::Node segment_1_desc;
segment_1_desc["name"] = kTestSegmentName;
Expand All @@ -219,7 +197,7 @@ TEST_F(TestControllerNode, InitializeLEDSegmentsThrowRepeatingName)
"Multiple segments with given name found"));
}

TEST_F(TestControllerNode, LoadAnimationInvalidPriority)
TEST_F(TestLightsControllerNode, LoadAnimationInvalidPriority)
{
YAML::Node led_animation_desc;
led_animation_desc["id"] = 11;
Expand All @@ -236,7 +214,7 @@ TEST_F(TestControllerNode, LoadAnimationInvalidPriority)
"Invalid LED animation priority"));
}

TEST_F(TestControllerNode, LoadAnimationThrowRepeatingID)
TEST_F(TestLightsControllerNode, LoadAnimationThrowRepeatingID)
{
YAML::Node led_animation_desc;
led_animation_desc["id"] = 11;
Expand All @@ -249,74 +227,27 @@ TEST_F(TestControllerNode, LoadAnimationThrowRepeatingID)
"Animation with given ID already exists"));
}

TEST_F(TestControllerNode, AddAnimationToQueueThrowBadAnimationID)
TEST_F(TestLightsControllerNode, AddAnimationToQueueThrowBadAnimationID)
{
EXPECT_TRUE(panther_utils::test_utils::IsMessageThrown<std::runtime_error>(
[&]() { lights_controller_node_->AddAnimationToQueue(99, false); }, "No animation with ID:"));
}

TEST_F(TestControllerNode, AddAnimationToQueue)
TEST_F(TestLightsControllerNode, AddAnimationToQueue)
{
auto queue = lights_controller_node_->GetQueue();
EXPECT_TRUE(queue->Empty());
EXPECT_NO_THROW(lights_controller_node_->AddAnimationToQueue(0, false));
EXPECT_FALSE(queue->Empty());
}

TEST_F(TestControllerNode, CallSelLEDAnimationService)
{
this->CallSetLEDAnimationSrv(0, false);

// spin to invoke timer
auto anim = lights_controller_node_->GetCurrentAnimation();
while (!anim) {
rclcpp::spin_some(lights_controller_node_->get_node_base_interface());
std::this_thread::sleep_for(std::chrono::milliseconds(10));
anim = lights_controller_node_->GetCurrentAnimation();
}

EXPECT_STREQ("ANIMATION_0", anim->GetName().c_str());

// add another animation to queue
auto queue = lights_controller_node_->GetQueue();
EXPECT_TRUE(queue->Empty());

this->CallSetLEDAnimationSrv(0, false);

EXPECT_FALSE(queue->Empty());
}

TEST_F(TestControllerNode, CallSelLEDAnimationServicePriorityInterrupt)
{
this->CallSetLEDAnimationSrv(0, false);

// spin to invoke timer
auto anim = lights_controller_node_->GetCurrentAnimation();
while (!anim) {
rclcpp::spin_some(lights_controller_node_->get_node_base_interface());
std::this_thread::sleep_for(std::chrono::milliseconds(10));
anim = lights_controller_node_->GetCurrentAnimation();
}

// add animation with higher priority spin to give time for controller to overwrite current
// animation then check if animation has changed
this->CallSetLEDAnimationSrv(1, false);
for (int i = 0; i < 10; i++) {
rclcpp::spin_some(lights_controller_node_->get_node_base_interface());
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}

anim = lights_controller_node_->GetCurrentAnimation();
EXPECT_STREQ("ANIMATION_1", anim->GetName().c_str());
}

int main(int argc, char ** argv)
{
rclcpp::init(argc, argv);
testing::InitGoogleTest(&argc, argv);

auto run_tests = RUN_ALL_TESTS();
auto result = RUN_ALL_TESTS();

rclcpp::shutdown();
return run_tests;
return result;
}

0 comments on commit 7f2dc9e

Please sign in to comment.