[SSSD] [PATCH] RFC: Unit test for the NSS responder based on the cmocka library

Sumit Bose sbose at redhat.com
Thu Feb 14 12:42:27 UTC 2013


On Tue, Feb 12, 2013 at 06:12:13PM +0100, Jakub Hrozek wrote:
> Hi,
> 
> Short version - attached is a patch proposal for a unit test based on
> cmocka. The patches are an example of a complex, yet isolated unit test
> and I'd like to get opinions on whether this would be a good way to go.
> 
> Long version:
> Our check based test suite is OK for developing simple tests for APIs
> like sysdb but not really great for testing of more complex interfaces.
> 
> In particular, it's hard to simulate certain pieces of functionality
> that require interaction with network or the rest of the system such as
> LDAP searches or logins, especially in environments like buildsystems.
> 
> I think we might want to look at Cmocka to provide this missing functionality
> and test complex interfaces in isolation. Cmocka[1] is a fork of Google's
> cmockery which is not maintained upstream anymore. Cmocka is maintained
> by Andreas Schneider.
> 
> I've been playing with cmocka lately and wrote a couple of patches that
> add a unit test for the NSS responder, in particular the getpwnam()
> function. It was quite easy to simulate the Data Provider and the client
> using two concepts:
> 
> 1) cmocka's mocking feature
> Functions that provide external interface, like the dummy DP functions
> in my patches, can access a stack of values. The unit test can push some
> expected return values onto the stack before launching the test and the
> dummy functions would then pop the values and use them as appropriate.
> It's quite easy to simulate a Data Provider saving an entry to cache
> with call like this (pseudocode):
> 
> int unit_test()
> {
>     will_return(sss_dp_get_account_recv, "testuser");
>     will_return(sss_dp_get_account_recv, 10);
>     will_return(sss_dp_get_account_recv, 11);
> }
> 
> int sss_dp_get_account_recv(TALLOC_CTX *mem_ctx, tevent_req *req)
> {
>     char *username = mock();
>     uid_t uid = mock();
>     gid_t gid = mock();
> 
>     sysdb_store_user(username, uid, gid);
> }
> 
> 2) the -wrap feature of ld
> It is possible to selectively override functions from modules linked against
> to intercept calls using the -wrap feature of ld. In my unit tests I used
> this feature to check results of responder search with defined callbacks
> instead of returning the results to the nss client. Here is a simple example
> of intercepting a call to negative cache to make sure the negative cache
> is hit when it's supposed to:
> 
> int __wrap_sss_ncache_check_user(struct sss_nc_ctx *ctx, int ttl,
>                                  struct sss_domain_info *dom,
>                                  const char *name)
> {
>     int ret;
> 
>     ret = __real_sss_ncache_check_user(ctx, ttl, dom, name);
>     if (ret == EEXIST) {
>         nss_test_ctx->ncache_hit = true;
>     }
>     return ret;
> }
> 
> There's a couple of boilerplate functions but once these are in place,
> they can be reused to cover different pieces of functionality..the
> attached patches test the following requests:
>  * cached user including assertion that DP was not contacted
>  * nonexistant user including assertion that on a subsequent lookup, the
>    request is returned from negative cache
>  * search for a user that has not been cache prior to the search
>  * updating an expired user including assertions that the user had been
>    updated from DP and the updated entry is returned.
> 
> The downsides of using cmocka as far as I can see are:
>   * writing the mocking code can be tedious. On the other hand, the NSS
>     responder I picked was probably the most complex code I could test
>     as it communicates with both DP and the client library. Even more
>     isolated testing (the AD sites feature comes to mind) would be much
>     easier I think.
>   * cmocka is not present in RHEL
> 
> I'll be glad to hear comments about this unit test proposal. Patches
> are attached.
> 
> [1] http://cmocka.cryptomilk.org/

I think this is really great. Being able to test a full request to a
responder puts the included test-suite to the next level and will
increase the amount of code covered by tests a lot.

I will send a review of the code later but in general I think those
patches should be push upstream to encourage people to add more tests
for the NSS responder or start new tests for the other responders.

In an ideal world it would be possible to add a new test for the NSS
responder without writing code but just dropping a JSON/XML/INI file
with the relevant data for a single test in a directory. But I think we
need a bit more experience with cmocka based tests to understand what is
necessary for this kind of abstraction.

Review will follow.

bye,
Sumit



More information about the sssd-devel mailing list