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


##########
include/mgmt/config/ConfigContext.h:
##########
@@ -186,7 +189,8 @@ class ConfigContext
   /// @code
   ///   if (auto yaml = ctx.supplied_yaml()) { /* use yaml node */ }
   /// @endcode
-  /// @return copy of the supplied YAML node (cheap - YAML::Node is internally 
reference-counted).
+  /// @return copy of the supplied YAML node (cheap - YAML::Node is internally 
reference-counted),
+  ///         or a new Undefined node on each call when none was supplied.

Review Comment:
   A YAML::Node copy is a handle to the same underlying node, not an 
independent value. Because the payload is shared by copies and dependents, 
writing through the returned node is visible to every context that shares that 
content, as the comment in ConfigContext.cc notes. Document this aliasing here 
(for example, 'returns a handle to the shared node; changes are visible to all 
contexts sharing this content') so callers do not assume they are isolated. The 
same applies to reload_directives().



##########
src/records/unit_tests/test_ConfigRegistry.cc:
##########
@@ -309,3 +314,131 @@ TEST_CASE("ConfigRegistry is_reloadable distinguishes 
handler-less entries", "[c
   // An unknown key is not reloadable.
   CHECK_FALSE(reg.is_reloadable("test_reloadable_unknown_xyz"));
 }
+
+// ─── ConfigContext content on the execute_reload() path 
───────────────────────
+//
+// No reload is in progress here, so execute_reload() hands the handler a 
task-less
+// context, and the RPC-supplied content is still applied to it.
+
+namespace
+{
+ConfigContext
+reload_with(std::string const &key, YAML::Node const &content)

Review Comment:
   The name reload_with does not say that the helper runs a reload and returns 
the context the handler received. A name such as capture_reload_context(key, 
content) would make the test setup clearer, since it is used by many of the new 
cases.



##########
src/records/unit_tests/test_ConfigReloadProgress.cc:
##########
@@ -86,3 +93,55 @@ TEST_CASE("Progress checker releases a task that timed out", 
"[config][reload][l
   REQUIRE(wait_for_sole_owner(task, std::chrono::seconds{10}));
   REQUIRE(task->get_state() == ConfigReloadTask::State::TIMEOUT);
 }
+
+// execute_reload() gives a handler a context with a task only while a reload 
is in
+// progress, and starting one needs ET_TASK for its progress checker, so this 
case
+// lives in this binary.
+TEST_CASE("A dependent context inherits its parent's RPC content", 
"[config][reload][context]")
+{
+  static std::optional<ConfigContext> parent;
+  static std::optional<ConfigContext> child;
+
+  std::string token;
+  REQUIRE(ReloadCoordinator::Get_Instance().prepare_reload(token, 
"test-dep-").is_ok());
+  auto const main_task = ReloadCoordinator::Get_Instance().get_current_task();
+  REQUIRE(main_task);
+  // prepare_reload() started a progress checker, which holds one of these.
+  auto const owners_with_checker = main_task.use_count();
+
+  auto &reg = config::ConfigRegistry::Get_Instance();
+  reg.register_config("test_dependent_payload", "", "",
+                      [](ConfigContext ctx) {
+                        parent.emplace(ctx);
+                        child.emplace(ctx.add_dependent_ctx("dependent"));
+                        child->complete();
+                        ctx.complete();
+                      },
+                      config::ConfigSource::FileAndRpc, {});
+  reg.set_passed_config("test_dependent_payload", YAML::Load("{_reload: {id: 
foo}, data: x}"));
+  reg.execute_reload("test_dependent_payload");
+
+  REQUIRE(parent.has_value());
+  REQUIRE(child.has_value());
+  REQUIRE(static_cast<bool>(*parent));
+  REQUIRE(static_cast<bool>(*child));
+
+  YAML::Node const content = child->supplied_yaml();
+  REQUIRE(content);
+  REQUIRE(content["data"].as<std::string>() == "x");
+  YAML::Node const directives = child->reload_directives();
+  REQUIRE(directives);
+  REQUIRE(directives["id"].as<std::string>() == "foo");
+  REQUIRE(content.is(parent->supplied_yaml()));
+  REQUIRE(directives.is(parent->reload_directives()));
+
+  child.reset();
+  parent.reset();
+
+  // Like the cases above, don't leave the checker running past the test.
+  auto const deadline = std::chrono::steady_clock::now() + 
std::chrono::seconds{15};
+  while (main_task.use_count() >= owners_with_checker && 
std::chrono::steady_clock::now() < deadline) {

Review Comment:
   "The 15-second deadline is an unexplained magic number, and this polling 
loop repeats the wait logic already used by the existing timeout case, which 
waits 10 seconds through wait_for_sole_owner. Extract a shared helper that 
waits until the owner count drops below a threshold, with the timeout passed in 
or defined as a named constant. That keeps the timeout values consistent and 
makes the test easier to maintain."
   - fix



-- 
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