YASL Request
Patrick Venture
venture at google.com
Tue Apr 10 08:27:31 AEST 2018
Everyone,
I'm working on unit-testing in openbmc, and have cracked most of
sdbusplus into mockable pieces and verified I can in fact test against
those mocks with a downstream daemon. I'll be grabbing an upstream
daemon (or providing a piece of one) to demonstrate how to leverage
the mocks to test OpenBMC. If one designs with testing in mind, the
designs come out very differently if not, and so getting unit-tests
throughout OpenBMC will be a lot of breaking things apart into
testable pieces. Anyways, where I'm going with this email is that
everything we do within a daemon needs to be something that can be
mocked -- basically.
***
What do I mean specifically? Consider, file access. If a daemon
routes all file accesses throug a common object implementation
provided by a shared library, that shared library can easily also
provide a mock interface for those accesses, such that one can easily
verify behaviors based on file contents without implementing local
files or trying to inject errors. With a mock's file system
interface, you can simply say that a file was unable to be read, or
written, or opened, etc. Another example is mocking ctime. If you
want to test whether something happens after some sleep or period, if
your code can receive a mock version of that library, one can
deliberately control the results of 'time' or 'difftime', etc. I have
to build these interfaces for some of our downstream daemons and
likely for other parts of OpenBMC, and to avoid code duplication it'll
help to have them in some library.
YASL (yet-another-shared-library) Request.
Previous conversations along these lines lead to the idea that we need
multiple new libraries for various things. So, this is yet another
use case. The library itself should be written in such a way that it
can be tested via unit-tests, but depending on how thin of a shim it
is, that isn't always practical. See:
class FileInterface {
public:
virtual int open(const char *filename, int flags) = 0;
};
class FileImplementation : public FileInterface {
public:
int open(const char *filename, int flags) override {
return ::open(filename, flags);
}
};
class FileMock : public FileInterface {
public:
MOCK_METHOD2(open, int(const char *, int));
};
.... then one just uses the FileInterface for their normally direct
posix-style file access. This can easily wrap iostream, or fstream,
or anything. And then if we provide some libraries for use by
daemons, they can transition over to them over time, and then they get
mocks for free :D For a daemon downstream, I've written a ctime
wrapper, I'll submit it for consideration later tonight along with a
few other things, and then I'll reply to this email with links.
***Not meant as a unit-test primer, just trying to provide some real examples.
Patrick
More information about the openbmc
mailing list