[389-devel] Proof of concept: mocking DS in lib389

Roberto Polli rpolli at babel.it
Tue Oct 29 13:55:03 UTC 2013


Hi @all,

Jan wrote:
> I am in fact
> creating MockDS class with custom ldapadd,
actually I agree with Jan about how the mocking process works:
 1- reuse/create an ldap mocking class;
 2- rewire existing tests on the mock;

> Hence, a unit test.
Ok, I agree to add unit-testing. Just I don't want to move integration tests 
(the one against a real instance) in another repo.
I'd leave the integration tests there so that whenever somebody clones he can 
test if the lib works for his installation.

> It will *not* verify the correctness of ldapadd method of real DSInstance
>class (that is the job of ldapadd`s unit test
About testing ldapadd & co, we should consider that - as of now - lib389 wraps 
some python-ldap methods with *args, **kwds. 
We should even be more consistent in parameter names between wrapping and 
wrapped method .

Peace,
R.



On Tuesday 29 October 2013 14:18:59 Jan Rusnacko wrote:
> Hello Thierry,
> 
> I am not rewriting ldapadd,...  methods of "real" DS class, I am in fact
> creating MockDS class with custom ldapadd,... methods, _just_ like you
> suggest :)
> 
> Furthermore, you can view it as a subclass of "real_ds" - even though it is
> not a proper Python subclass, it inherits all functions from repl module
> just like "real_ds" would (again through ModuleProxy mechanism). So,
> methods that are defined in repl are the same for "real_ds" class and for
> MockDS class, but ldap.. methods are different. So, basically exactly what
> you suggest :)
> 
> Code of the whole class along with all methods is in file
> tests/test_dsmodules/conftest.py line 7.
> 
> Thank you,
> Jan
> 
> On 10/28/2013 12:02 PM, thierry bordaz wrote:
> > Hi Jan,
> > 
> >     That is very impressive POC, far above my skill in python. Thanks for
> >     sharing this.
> >     I have a novice question.
> >     This implementation overwrites the basic ldapadd,ldapsearch...
> >     function of
> >     the "real" DS.
> >     An other approach is to write a 'mock_ds' class being a subclass of
> >     'real_ds' and to overwrite the ldapadd,ldapsearch in mock_ds class (to
> >     store data into a dict). What would be the advantages of your
> >     approach ?> 
> > best regards
> > thierry
> > 
> > On 10/25/2013 09:36 PM, Jan Rusnacko wrote:
> >> Hello Roberto and Thierry,
> >> 
> >> as I promised, I am sending you a proof-of-concept code that
> >> demonstrates, how we can mock DS in unit tests for library function (see
> >> attachment). You can run tests just by executing py.test in tests
> >> directory.
> >> 
> >> Only 3 files are of interest here:
> >> 
> >> lib389/dsmodules/repl.py - this is a Python module with functions - they
> >> expect DS instance as the first argument. Since they are functions, not
> >> methods, I can just mock DS and pass that fake one as the first argument
> >> to them in unit tests.
> >> 
> >> tests/test_dsmodules/conftest.py - this file contains definition of mock
> >> DS
> >> class along with py.test fixture, that returns it.
> >> 
> >> tests/test_dsmodules/test_repl.py - this contains unit tests for
> >> functions from repl.py.
> >> 
> >> What I do is quite simple - I override ldapadd, ldapdelete .. methods of
> >> mock DS class, so that instead of sending command to real DS instance,
> >> they just store the data in 'dit' dictionary (which represents content
> >> stored in DS). This way, I can check that when I call e.g. function
> >> enable_changelog(..), in the end DS will have correct changelog entry.
> >> 
> >> To put it very bluntly - enable_changelog(..) function just adds correct
> >> changelog entry to whatever is passed to it as the first argument. In
> >> unit
> >> tests, it is mock DS, otherwise it would be real DS class that sends real
> >> ldap commands to real DS instance behind.
> >> 
> >> Now I can successfully test that enable_changelog really works, without
> >> going into trouble defining DSInstance or ldap calls at all. Also, I
> >> believe this approach would work for 95% of all functions in lib389.
> >> Another benefit is that unit tests are much faster, than on real DS
> >> instance.
> >> 
> >> Sidenote: even though everything is defined in separate namespace of
> >> 'repl'
> >> module as function, in runtime they can be used as normal methods of
> >> class
> >> DSInstance. That is handled by DSModuleProxy. We already went through
> >> this, but not with Roberto.
> >> 
> >> Hopefully, now with some code in our hands, we will be able to understand
> >> each other on this 'mocking' issue and come to conclusions more quickly.
> >> 
> >> Let me know what you think.
> >> 
> >> Thank you,
> >> Jan

-- 
Roberto Polli
Community Manager
Babel S.r.l. - http://www.babel.it
T: +39.06.9826.9651 M: +39.340.652.2736 F: +39.06.9826.9680
P.zza S.Benedetto da Norcia, 33 - 00040 Pomezia (Roma)

CONFIDENZIALE: Questo messaggio ed i suoi allegati sono di carattere 
confidenziale per i destinatari in indirizzo.
E' vietato l'inoltro non autorizzato a destinatari diversi da quelli indicati 
nel messaggio originale.
Se ricevuto per errore, l'uso del contenuto e' proibito; si prega di 
comunicarlo al mittente e cancellarlo immediatamente.


More information about the 389-devel mailing list