mirror of
https://github.com/esphome/esphome.git
synced 2026-09-25 22:10:21 +00:00
[api] Register homeassistant.action with synchronous=False to fix stale trigger args in response callbacks (#17367)
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
"""Tests for arg-type selection of api user-defined services with homeassistant.action."""
|
||||
|
||||
CONFIG = "tests/component_tests/api/test_homeassistant_action.yaml"
|
||||
|
||||
|
||||
def test_synchronous_chain_keeps_zero_copy_args(generate_main):
|
||||
"""A chain of synchronous actions keeps the non-owning StringRef arg type."""
|
||||
main_cpp = generate_main(CONFIG)
|
||||
|
||||
assert (
|
||||
"api::UserServiceTrigger<api::enums::SUPPORTS_RESPONSE_NONE, StringRef>"
|
||||
'("zero_copy_args", {"message"})' in main_cpp
|
||||
)
|
||||
|
||||
|
||||
def test_response_callback_args_are_owning(generate_main):
|
||||
"""homeassistant.action with on_success/on_error stores the trigger args
|
||||
until the HomeassistantActionResponse arrives, so string args must fall
|
||||
back to owning std::string; StringRef would point into the connection's
|
||||
receive buffer, which is reused before the response arrives."""
|
||||
main_cpp = generate_main(CONFIG)
|
||||
|
||||
assert (
|
||||
"api::UserServiceTrigger<api::enums::SUPPORTS_RESPONSE_NONE, std::string>"
|
||||
'("response_args", {"message"})' in main_cpp
|
||||
)
|
||||
assert "api::HomeAssistantServiceCallAction<std::string>" in main_cpp
|
||||
assert "api::HomeAssistantServiceCallAction<StringRef>" not in main_cpp
|
||||
@@ -0,0 +1,43 @@
|
||||
esphome:
|
||||
name: test
|
||||
|
||||
esp32:
|
||||
board: esp32dev
|
||||
|
||||
wifi:
|
||||
ssid: SomeNetwork
|
||||
password: SomePassword
|
||||
|
||||
logger:
|
||||
|
||||
api:
|
||||
actions:
|
||||
# Chain of synchronous actions that never store the args:
|
||||
# keeps the zero-copy StringRef arg type.
|
||||
- action: zero_copy_args
|
||||
variables:
|
||||
message: string
|
||||
then:
|
||||
- logger.log:
|
||||
format: "%s"
|
||||
args: [message.c_str()]
|
||||
# homeassistant.action with on_success/on_error stores the trigger args
|
||||
# until the action response arrives, so the codegen must fall back to
|
||||
# owning std::string args (StringRef would dangle once the receive
|
||||
# buffer is reused).
|
||||
- action: response_args
|
||||
variables:
|
||||
message: string
|
||||
then:
|
||||
- homeassistant.action:
|
||||
action: notify.notify
|
||||
data:
|
||||
message: !lambda return message;
|
||||
on_success:
|
||||
- logger.log:
|
||||
format: "sent %s"
|
||||
args: [message.c_str()]
|
||||
on_error:
|
||||
- logger.log:
|
||||
format: "failed (%s): %s"
|
||||
args: [error.c_str(), message.c_str()]
|
||||
Reference in New Issue
Block a user