YASL Request

Patrick Venture venture at google.com
Wed Apr 11 03:59:07 AEST 2018

On Mon, Apr 9, 2018 at 8:19 PM, Patrick Venture <venture at google.com> wrote:
> On Mon, Apr 9, 2018 at 7:45 PM, Lei YU <mine260309 at gmail.com> wrote:
>> On Tue, Apr 10, 2018 at 6:27 AM, Patrick Venture <venture at google.com> wrote:
>>> 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
>> Great! I have tried to make sdbusplus mockable previously, by changing its
>> interfaces virtual, and find out that it is somehow complicated because some
>> of the interfaces return the objects and it's kind of hard to mock things like
>> bus::new_method_call().
> Yeah, ran into that problem, worked around it.  I'm currently fighting
> my way through the var_args in message::append where there can be
> mixed types, so I can't just cast the tuple to a normal array.  Could
> use boost::any, but haven't given into that yet.

Resolved.  I'll have this up for review today along with some dummy
code that exercises it.

>> At that time I discussed this with Patrick Williams and he suggested sdbusplus
>> should be compact and fast, so it's not a good idea to make it virtual.
>> Later it's found that Brad has some good example of mocking sdbusplus in
>> https://github.com/openbmc/phosphor-dbus-monitor/tree/master/src/test
>> Hopefully we can get a mockable sdbusplus as a shared library as well!
> I'm mocking it in sdbusplus itself, so you get it for free.
>>> 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.
>> So this library would contain several interfaces classes (e.g. FileInterface,
>> TimeInterface, and hopefully SdbusplusInterface etc) all together, right?
>> I vote for it!
> The sdbusplus library will have mocks ready sometime this week if I
> can get past this va_args issue.  I haven't tried converting the call
> to sd_bus_message_append to sd_bus_message_appendv, but I haven't
> burned much time trying to handle this.  I haven't yet mocked out
> everything, but sdbusplus::bus::bus and sdbusplus::message::message
> are nearly done.  There are other bits, I just haven't started.
> If we have a set of shared libraries, then those shared libraries
> should all have mocks available to enable testing.
>>> ***Not meant as a unit-test primer, just trying to provide some real examples.
>>> Patrick

More information about the openbmc mailing list