-
Notifications
You must be signed in to change notification settings - Fork 42
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
[sled agent] Fakes are better than mocks; get rid of mocks #2422
Comments
Sorry for the ignorant question but what do we mean by "fakes"? I googled it and found https://stackoverflow.com/questions/346372/whats-the-difference-between-faking-mocking-and-stubbing ...which has several different definitions. |
My intention was "a struct that lies about implementing the functionality, often by just storing a According to that stackoverflow post, I'd say it's closest to:
For example:
|
…2451) This PR should make no substantive changes other than changes to visibility, imports, etc., associated with moving: * `sled_agent::hardware` -> `sled-hardware` * `sled_agent::illumos` -> `illumos-utils` The primary motivation of these is to allow `installinator` to also use `sled-hardware` using the same hardware scraping/monitoring logic as sled-agent. `sled_agent::hardware` had dependencies on `sled_agent::illumos`, which led to extracting it too. A handful of supporting but smaller changes: * `illumos_utils::running_zone` had a dependency on `sled_agent::opte::Port`, and it didn't seem right to pull all of `opte` out with `illumos_utils`, so I broke this dependency by adding an `OptePort` trait and making `RunningZone` and `InstalledZone` generic over a `Port: OptePort` type. * I moved `sled_agent::vlan` to `omicron_common::vlan`. * `sled-agent`'s tests depend on mocks set up in what is now a separate crate (`illumos_utils`). #2422 tracks replacing the mocks altogether; in the meantime, 16c9017 is a workaround that adds a `testing` feature to `illumos_utils` that builds the mocks. `sled-agent` enables that feature when _it_ is being tested, allowing the mocks to exist for its use.
…stead (#3427) - Create a small fake NexusServer within Sled Agent - Add some utilities for also creating a transient internal DNS server pointing to the fake Nexus server - Use both of these servers in the (fairly small) number of Sled Agent tests - Hopefully, in the future, we can use this fake to better test the Sled Agent's interactions with Nexus Part of #2422
- Removes all references to `rpool/zones` - Exclusively stores zone filesystems on the U.2, under an encrypted dataset - Wipes these datasets from the U.2s when parsing them on sled agent boot - Tangentially related: Removes a handful of low-quality Sled Agent tests, reliant heavily on mock interfaces (see #2422 , though we still have work to improve this test coverage). Fixes #3533
Closing largely in favor of the option proposed in #5226 |
Sled agent uses a lot of mocks to represent interactions with underlying resources. It uses a library named
mockall
to help with this interaction. We should use fakes instead.Background
When the sled agent is provisioning a zone, it "mocks" access to zones. This enables unit tests to verify "hey, you would have created a zone here", but in reality, make no such call.
This is okay-ish for some types of unit tests, where we have a module
foo
which depends on a interfaceresource
:foo
can be conditionally compiled withcfg(test)
to use themockResource
foo
's tests can then usemockall
's API to set expectations about calls to themockResource
This is one such example of a test written in this style.
Problems
This testing strategy really breaks down when it gets nested. Suppose we have a module
baz
, which depends onfoo
andbar
.foo
's dependency onmockResource
still needs to be captured, sobaz
also needs to set up "expectation" calls in testsbar
, and any other modules which contains mocksThis is apparent for modules like the
storage_manager
, where we're interfacing with:and all of them would need to be mocked to actually write tests.
Proposal
We should implement fakes wherever these mocks are being used. This will give us a more flexible interface for testing, and make dependencies on "global-ish resources" much more apparent.
Admittedly, doing so will require providing the interfaces to these modules as up-front objects. I propose doing so with
Arc
-bound trait objects, rather than generics, to keep things relatively simple. The cost of a singleBox
+Arc
's refcounting should be trivial compared with the cost of "provisioning a filesystem" or "managing a zone".The text was updated successfully, but these errors were encountered: