-
-
Notifications
You must be signed in to change notification settings - Fork 80
Change execute_service to be async to handle timeouts internally
#1443
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1443 +/- ##
=========================================
Coverage 100.00% 100.00%
=========================================
Files 22 22
Lines 3335 3342 +7
=========================================
+ Hits 3335 3342 +7 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
CodSpeed Performance ReportMerging #1443 will not alter performanceComparing Summary
|
Walkthrough
Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
tests/test_client.py (2)
1046-1092: call_id generation and timeout behavior are well covered; confirm error-type choiceThese tests nicely validate that:
call_idstays0whenreturn_responseis left as default,- non‑zero
call_ids are auto‑generated whenreturn_responseis set, and- the counter increments across calls, using very short timeouts to keep tests fast (which matches the project’s preference for sub‑second tests, based on learnings).
One thing to double‑check: here you assert
asyncio.TimeoutErrordirectly fromexecute_service, whereas other APIs in this module typically surfaceTimeoutAPIErrorfor timeouts. If you later decide to wrap this inTimeoutAPIErrorfor consistency, these assertions will need to change accordingly; if the intention is to expose the rawasyncio.TimeoutErrorfor this low‑level helper, the tests are already aligned.
2239-2336: execute_service_with_response test correctly exercises response correlation and ignores mismatched call_idsThis test does a good job of:
- Capturing the sent
ExecuteServiceRequestto verify a non‑zero auto‑generatedcall_id.- Simulating a matching
ExecuteServiceResponseand asserting thatexecute_servicereturns the expectedExecuteServiceResponseModel.- Verifying that a response with the wrong
call_idis ignored and the task remains pending until the correctcall_idarrives.One optional hardening you might consider (not required) is passing an explicit, relatively small
timeoutwhen callingexecute_servicehere so that, if the correlation logic regresses and no response ever matches, the test fails fast instead of potentially waiting on the default long timeout.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
tests/test_client.py(12 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.py: Useruff check --fixto check and fix Python linting issues before committing
Useruff formatto format Python code before committing
Files:
tests/test_client.py
**
⚙️ CodeRabbit configuration file
- Do not generate or add any sequence diagrams
Files:
tests/test_client.py
🧠 Learnings (1)
📓 Common learnings
Learnt from: bdraco
Repo: esphome/aioesphomeapi PR: 1065
File: .github/workflows/ci.yml:114-114
Timestamp: 2025-02-14T16:26:00.072Z
Learning: In aioesphomeapi, all tests are designed to complete within 1 second. The CI configuration uses a 4-second timeout which provides sufficient buffer for test execution across all environments.
Learnt from: bdraco
Repo: esphome/aioesphomeapi PR: 999
File: aioesphomeapi/client.py:610-612
Timestamp: 2024-11-23T18:39:41.119Z
Learning: In the `aioesphomeapi/client.py` file within the `APIClient` class, it's intentional to catch `BaseException` in methods like `bluetooth_device_connect` to ensure cleanup is performed after cancellations or unexpected exceptions, preventing connection leaks.
Learnt from: bdraco
Repo: esphome/aioesphomeapi PR: 1156
File: tests/test_log_runner.py:187-187
Timestamp: 2025-04-16T01:35:06.073Z
Learning: In the aioesphomeapi project, the maintainers prefer using `asyncio.get_running_loop()` without fallbacks to `asyncio.get_event_loop()`, as this makes incorrect usage fail fast rather than having confusing outcomes. This was decided during a major version increment, making it an intentional breaking change.
🧬 Code graph analysis (1)
tests/test_client.py (2)
tests/conftest.py (2)
auth_client(71-85)api_client(209-238)aioesphomeapi/client.py (2)
execute_service(1317-1381)APIClient(202-1650)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Run benchmarks
🔇 Additional comments (3)
tests/test_client.py (3)
945-1044: execute_service async migration and arg mapping tests look solidAwaiting
auth_client.execute_servicein both theKeyErrorpath and the various arg/api_versioncases is consistent with the new async signature, and the coverage of bool/int/float/string/array types plus legacylegacy_intand arg-order handling is preserved. I don’t see issues here.
1094-1128: return_response tri‑state combinations test the new semantics comprehensivelyThe
test_execute_service_return_response_combinationsfunction gives good coverage of the three cases:
return_response=None→call_id == 0, no waiting.return_response=True→ non‑zerocall_id, request field set toTrue, and a timeout when no response arrives.return_response=False→ non‑zerocall_id, request field set toFalse, and the same wait/timeout semantics.The use of a 0.01‑second timeout keeps these negative‑path tests cheap while still verifying the internal wait logic. No changes needed.
3338-3350: Updated execute_service usage after disconnect is consistentSwitching the “after connection closed” assertion to
await client.execute_service(service, {})keeps the existing behavior check (raisingAPIConnectionError) while matching the new async contract forexecute_service. This is consistent with how other client methods in the test are awaited.
What does this implement/fix?
This alters
execute_serviceto be an async function so that it can timeout while waiting for a response for a device.Before this, the message subscription would forever be in memory if the device did not respons, even if the calling code (HA) had already given up.
Types of changes
Related issue or feature (if applicable):
Pull request in esphome (if applicable):
Checklist:
tests/folder).