Add roborock.testing — stateful device simulators for integration testing#860
Open
allenporter wants to merge 5 commits into
Open
Add roborock.testing — stateful device simulators for integration testing#860allenporter wants to merge 5 commits into
allenporter wants to merge 5 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR introduces a new roborock.testing package intended to provide stateful device simulators, fake transport channels, and a fake cloud environment so downstream projects can write higher-fidelity integration tests against the real client codepaths.
Changes:
- Added
roborock.testingfakes:FakeChannel,FakeRoborockCloud,RoborockDeviceSimulator, and a V1 stateful firmware simulator (V1VacuumSimulator). - Added a new
tests/testing/test suite validating the new fakes/simulators and their interaction with the real device manager/client traits. - Modified test fixtures to (intendedly) reuse the shared
FakeChannelrather than maintaining a local copy.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
roborock/testing/__init__.py |
Exposes the new testing fakes/simulators and documents intended architecture/usage. |
roborock/testing/channel.py |
Adds FakeChannel transport implementation for publish/subscribe testing and simulators. |
roborock/testing/simulator.py |
Adds base stateful simulator that wires fake channels to per-protocol _handle_publish logic. |
roborock/testing/v1_simulator.py |
Adds a V1 vacuum firmware simulator with handlers for core RPCs and DPS push updates. |
roborock/testing/cloud.py |
Adds a fake cloud orchestrator that patches HTTP + channel factories for integration-style tests. |
tests/testing/test_channel.py |
New tests for FakeChannel subscribe/unsubscribe/notify/publish capturing. |
tests/testing/test_cloud.py |
New tests for fake-cloud login/home/device discovery and protocol unsupported behavior. |
tests/testing/test_v1_simulator.py |
New integration tests validating trait behavior via the V1 simulator. |
tests/testing/__init__.py |
Adds the tests.testing package marker. |
tests/fixtures/channel_fixtures.py |
Fixture file changed; currently ends up empty and needs to re-export FakeChannel (or imports updated). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Introduces a new roborock.testing package that provides stateful firmware simulators, fake transport channels, and cloud environment fakes. This allows downstream consumers (like the Home Assistant integration) to write high-fidelity integration tests using the real client library classes instead of fragile top-level mocks. New modules: - channel.py: FakeChannel in-memory transport implementing Channel protocol - simulator.py: RoborockDeviceSimulator base class - v1_simulator.py: V1VacuumSimulator with stateful command handlers - cloud.py: FakeRoborockCloud with HTTP endpoint mocking Tests split by module: - test_channel.py: FakeChannel subscribe/publish/notify - test_cloud.py: Discovery, login errors, dynamic device addition - test_v1_simulator.py: Trait refresh/reset, state transitions, push updates
328a72a to
ba06b45
Compare
…Error in base _handle_publish
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Introduces a new
roborock.testingpackage that provides stateful firmware simulators, fake transport channels, and cloud environment fakes. This allows downstream consumers (like the Home Assistant integration) to write high-fidelity integration tests using the real client library classes instead of fragile top-level mocks.Motivation
Today, testing against this library requires mocking at the Python API level (patching methods, return values, etc.), which is brittle and doesn't exercise the real protocol handling, message encoding, or trait update logic. This package fakes communication at two well-defined boundaries:
aioresponsesintercepts network requests so the realRoborockApiClientexecutes fully against fake endpoints.RoborockMessagelevel. The realV1Channel, subscribers, and DPS listeners all run under test.Architecture
New Files
roborock/testing/__init__.pychannel.pyFakeChannel— in-memory transport with mock attributes for failure injection and call inspectionsimulator.pyRoborockDeviceSimulator— base class with optional local/MQTT channelsv1_simulator.pyV1VacuumSimulator— stateful V1 firmware simulator with command handlers forget_status,app_start,app_stop,set_custom_mode, consumables, DND, etc.cloud.pyFakeRoborockCloud— cloud environment orchestrator withFakeUserState,FakeWebApiClient, andpatch_device_manager()context managertests/testing/test_channel.pytest_cloud.pytest_v1_simulator.pyModified
tests/fixtures/channel_fixtures.pyFakeChannelfromroborock.testinginstead of defining it locallyUsage Example
Future Work
Migrate existing tests to use
roborock.testingAn earlier review identified which existing test suites should migrate to use these fakes vs. remain as-is:
High priority — should migrate:
tests/devices/test_device_manager.py— Currently mockscreate_v1_channelandcreate_mqtt_channelwith fragilesend_commandside-effect arrays. Usingpatch_device_manager()with aV1VacuumSimulatorwould eliminate the brittle handshake sequence mocking entirely.tests/devices/test_v1_device.py— Manually stubs subscribe, connection, and channel creation withAsyncMock. Using a realV1Channelbound toFakeChannelwould test actual client routing logic.Medium priority — optional migration:
test_status.py,test_consumable.py) — Direct mocks are fine for parsing edge cases, but integration-level tests using the simulator would complement them.Should remain unchanged:
tests/e2e/) — These verify raw protocol byte parsing, TCP framing, and cryptography at Layer 1. Our fakes operate above that layer, so these tests serve a different purpose.Additional enhancements
RoborockDeviceSimulatorsupportshas_local_channel=Falsefor MQTT-only protocols, but no A01 (Zeo/Dyad) or B01 (Q7/Q10) simulators exist yet.patch_device_manager()currently raisesNotImplementedErrorfor these.app_segment_clean), map operations, volume control, etc.