@@ -48,6 +48,36 @@ void malformedRequestScenario()
4848 std::exit (EXIT_SUCCESS );
4949}
5050
51+ void incompleteHookScenario ()
52+ {
53+ BT ::BehaviorTreeFactory factory;
54+ auto tree = factory.createTreeFromText (R"(
55+ <root BTCPP_format="4">
56+ <BehaviorTree ID="MainTree">
57+ <AlwaysSuccess/>
58+ </BehaviorTree>
59+ </root>
60+ )" );
61+ auto [publisher, port] = Groot2Test::makePublisher (tree);
62+ Groot2Test::Client client (port);
63+
64+ // Well-formed JSON object, but missing the required "uid"/"position" keys.
65+ auto error_reply =
66+ client.rawRequest (BT ::Monitor::RequestType::HOOK_INSERT , R"( {"enabled":true})" );
67+ if (error_reply.size () != 2 || error_reply[0 ].to_string () != " error" )
68+ {
69+ std::exit (EXIT_FAILURE );
70+ }
71+
72+ // The server thread must remain usable after rejecting the incomplete request.
73+ auto valid_reply = client.request (BT ::Monitor::RequestType::FULLTREE );
74+ if (valid_reply.size () != 2 )
75+ {
76+ std::exit (EXIT_FAILURE );
77+ }
78+ std::exit (EXIT_SUCCESS );
79+ }
80+
5181BT ::Tree createTreeWithNamedSubtrees (BT ::BehaviorTreeFactory& factory,
5282 const BT ::Blackboard::Ptr& main_blackboard)
5383{
@@ -139,6 +169,12 @@ TEST(Groot2PublisherIntegration, MalformedRequestDoesNotTerminateServer)
139169 EXPECT_EXIT (malformedRequestScenario (), ::testing::ExitedWithCode (EXIT_SUCCESS ), " .*" );
140170}
141171
172+ TEST (Groot2PublisherIntegration, IncompleteHookRequestDoesNotTerminateServer)
173+ {
174+ ::testing::FLAGS_gtest_death_test_style = " threadsafe" ;
175+ EXPECT_EXIT (incompleteHookScenario (), ::testing::ExitedWithCode (EXIT_SUCCESS ), " .*" );
176+ }
177+
142178TEST (Groot2PublisherIntegration, BlackboardDump_NoRootWithoutExternalBlackboard)
143179{
144180 BT ::BehaviorTreeFactory factory;
0 commit comments