Copilot commented on code in PR #13649:
URL: https://github.com/apache/trafficserver/pull/13649#discussion_r3956593840


##########
src/mgmt/rpc/server/unit_tests/test_rpcserver.cc:
##########
@@ -77,6 +77,45 @@ add_method_handler(const std::string &name, Func &&call)
 {
   return rpc::JsonRPCManager::instance().add_method_handler(name, 
std::forward<Func>(call), nullptr, {});
 }
+
+/// Registers a method handler and removes it when the scope ends.
+///
+/// Catch2 re-runs a TEST_CASE body once per leaf SECTION. Registering at the 
top of the body and
+/// removing at the bottom only works while every assertion passes: REQUIRE is 
fatal, so a failure
+/// inside a SECTION unwinds before the trailing removal and the handler 
survives into the next
+/// SECTION's run, where re-registering it fails. One real failure then 
reports as two, and the
+/// second points at a registration that was never the problem.
+class ScopedMethodHandler
+{
+public:
+  template <typename Func> ScopedMethodHandler(std::string name, Func &&call) 
: _name{std::move(name)}
+  {
+    _registered = rpc::add_method_handler(_name, std::forward<Func>(call));
+  }
+
+  ~ScopedMethodHandler()
+  {
+    if (_registered) {
+      // CHECK rather than REQUIRE: this runs during stack unwinding when a 
SECTION failed, and a
+      // fatal assertion there would abort instead of reporting.
+      INFO("handler: " << _name);
+      CHECK(rpc::test_remove_handler(_name));
+    }
+  }

Review Comment:
   Since this is test-only infrastructure (and it depends on Catch2 macros), 
placing `ScopedMethodHandler` in the production `rpc` namespace can be 
misleading and increases the chance of name collisions with real RPC code. 
Consider moving it to an unnamed namespace or a clearly test-scoped namespace 
(e.g., `namespace rpc_test`), while still calling `rpc::add_method_handler` / 
`rpc::test_remove_handler` internally.



##########
src/mgmt/rpc/server/unit_tests/test_rpcserver.cc:
##########
@@ -77,6 +77,45 @@ add_method_handler(const std::string &name, Func &&call)
 {
   return rpc::JsonRPCManager::instance().add_method_handler(name, 
std::forward<Func>(call), nullptr, {});
 }
+
+/// Registers a method handler and removes it when the scope ends.
+///
+/// Catch2 re-runs a TEST_CASE body once per leaf SECTION. Registering at the 
top of the body and
+/// removing at the bottom only works while every assertion passes: REQUIRE is 
fatal, so a failure
+/// inside a SECTION unwinds before the trailing removal and the handler 
survives into the next
+/// SECTION's run, where re-registering it fails. One real failure then 
reports as two, and the
+/// second points at a registration that was never the problem.
+class ScopedMethodHandler
+{
+public:
+  template <typename Func> ScopedMethodHandler(std::string name, Func &&call) 
: _name{std::move(name)}
+  {
+    _registered = rpc::add_method_handler(_name, std::forward<Func>(call));
+  }
+
+  ~ScopedMethodHandler()
+  {
+    if (_registered) {
+      // CHECK rather than REQUIRE: this runs during stack unwinding when a 
SECTION failed, and a
+      // fatal assertion there would abort instead of reporting.
+      INFO("handler: " << _name);
+      CHECK(rpc::test_remove_handler(_name));

Review Comment:
   This destructor can execute during stack unwinding (as noted), so it should 
be `noexcept` to avoid a potential `std::terminate` if anything unexpectedly 
throws (including from test-framework diagnostics/streaming). Consider marking 
`~ScopedMethodHandler() noexcept` and ensuring any diagnostic/removal path 
cannot throw (e.g., by guarding with a `try/catch` inside the destructor, or by 
avoiding potentially-throwing operations there).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to