Files
esphome/tests/integration/fixtures/wait_until_reentrant_restart.yaml
T

87 lines
2.4 KiB
YAML

esphome:
name: wait-until-reentrant-restart
host:
api:
actions:
- action: start_self_restart
then:
- script.execute: retry_script
- action: start_stop_during_wait
then:
- globals.set:
id: gate_open
value: 'false'
# num 0 is a blocker: its condition never becomes true, so it is still
# waiting (already checked and set aside) when num 1 stops the script -
# it must be cancelled, not restored, so its timeout must never fire
- script.execute:
id: waiter
num: 0
- script.execute:
id: waiter
num: 1
- script.execute:
id: waiter
num: 2
- script.execute:
id: waiter
num: 3
# Give all three instances time to queue in the same wait_until
- delay: 100ms
- globals.set:
id: gate_open
value: 'true'
- delay: 200ms
- logger.log: "stop test complete"
logger:
level: DEBUG
globals:
- id: attempt
type: int
initial_value: '0'
- id: gate_open
type: bool
initial_value: 'false'
script:
# Self-restart retry pattern: when the wait_until times out, the rest of the
# script runs synchronously from inside the wait queue processing and restarts
# this same script - re-entering the same WaitUntilAction while it is still
# processing its queue. This used to corrupt the queue and crash.
- id: retry_script
mode: restart
then:
- wait_until:
condition:
lambda: 'return false;'
timeout: 20ms
- lambda: |-
id(attempt) += 1;
ESP_LOGD("test", "attempt %d done", id(attempt));
- if:
condition:
lambda: 'return id(attempt) < 5;'
then:
- script.execute: retry_script
else:
- logger.log: "retry test complete"
# Parallel waiters all queued in the same wait_until; the first one to pass the
# gate stops the script from its continuation, cancelling the other waiters
# while the queue is still being processed.
- id: waiter
mode: parallel
parameters:
num: int
then:
- wait_until:
condition:
lambda: 'return num != 0 && id(gate_open);'
timeout: 1s
- lambda: 'ESP_LOGD("test", "gate passed %d", num);'
- script.stop: waiter