Re: [Twisted-Python] Review tag for closed tickets

2015-01-27 Thread Adi Roiban
On 27 January 2015 at 00:44,   wrote:
> On 26 Jan, 08:51 pm, a...@roiban.ro wrote:
>>>
>>>
>>> The review should be completed before the ticket is merged, so the bot
>>> should not be doing this automatically.
>>
>>
>> but in the commit message I do add the author, why not have the bot
>> automatically assign the first author form the list, review merge and
>> close the ticket?
>>
>> What is the purpose of these manual task and why you don't want to
>> automate them?
>
>
> You jumped pretty quickly from "it is not automated" to "you don't want to
> automate them".

Sorry for that.  I have interpreted "the bot should not be doing this
automatically" as a statement
that any work in this direction will be rejected

> Building reliable automation is work.  If that's work you want to do, feel
> free.

Will do. https://github.com/twisted-infra/trac-config/issues/19

Thanks for the comments!
-- 
Adi Roiban

___
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python


[Twisted-Python] Unit testing, trail, inlineCallbacks, deferreds and mocking

2015-01-27 Thread Patryk Ściborek
Hi!

I've just started a new project using Twisted and I want to write unit
tests since the beginning. Unfortunately I've got some trouble
understanding how should I do it. I read 'Test-driven development with
Twisted', read some articles on the web and searched on the mailing list
but I couldn't find anything which make it clear for me.

I've got a class:

class SessionCleaner(object):
def __init__(self, session_db, interval=10):
self.session_db = session_db
self.lc = task.LoopingCall(self.check_old_sessions)
self.lc.start(interval)

@defer.inlineCallbacks
def check_old_sessions(self):
log.msg('check_old_sessions()', logLevel=logging.DEBUG)
try:
old_sessions = yield self.session_db.get_old_sessions()
for s in old_sessions:
yield self.session_db.process_stopped(s)

except txredisapi.ConnectionError as e:
log.msg('check_old_sessions - connection error {}'
.format(e), logLevel=logging.WARNING)

session_db is a object with methods which makes some calls to Redis.

Testing if __init__ works correctly is easy - I can mock task.LoopingCall
and check if it was called with correct attributes.

I've got trouble testing check_old_sessions. Since I'm writing unit tests I
don't want to call real session_db methods and make real Redis queries. I'd
like to mock them and test just few things:
- is the method get_old_sessions called?
- is the method process_stopped called N times with the arguments returned
by mocked get_old_sessions?
- is txredisapi.ConnectionError handled correctly?

So is there any "right" way of mocking functions which returns deferreds?
Or maybe I should test this method differently?

Best regards,
Patryk
___
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python


Re: [Twisted-Python] Unit testing, trail, inlineCallbacks, deferreds and mocking

2015-01-27 Thread James Broadhead
Hey

I raised a similar question a while ago:
http://twistedmatrix.com/pipermail/twisted-python/2013-July/027241.html

Since then, our approach has evolved into the below, which may be useful.
https://github.com/jamesbroadhead/bttrtwisted/blob/master/bttrtwisted/testing.py

Usage:
  expected = Foo()
  remote_result = Result()
  thing = Thing()
  thing.call_external_service = dmockfunc(remote_result)

  d = thing.function_under_test(..)
  d.addCallback(self.assertEqual, expected)
  return d

You can use the func_dict param to gen_nondeferred_mock to have it stand
in-place-of an object

As always with mocks, a little can be helpful, but if you find you're
instantiating a lot of them, you may want to reconsider your approach.

Feedback welcome!
[ the repo is for experiments, so use with care ]

James

On 27 January 2015 at 13:00, Patryk Ściborek  wrote:

> Hi!
>
> I've just started a new project using Twisted and I want to write unit
> tests since the beginning. Unfortunately I've got some trouble
> understanding how should I do it. I read 'Test-driven development with
> Twisted', read some articles on the web and searched on the mailing list
> but I couldn't find anything which make it clear for me.
>
> I've got a class:
>
> class SessionCleaner(object):
> def __init__(self, session_db, interval=10):
> self.session_db = session_db
> self.lc = task.LoopingCall(self.check_old_sessions)
> self.lc.start(interval)
>
> @defer.inlineCallbacks
> def check_old_sessions(self):
> log.msg('check_old_sessions()', logLevel=logging.DEBUG)
> try:
> old_sessions = yield self.session_db.get_old_sessions()
> for s in old_sessions:
> yield self.session_db.process_stopped(s)
>
> except txredisapi.ConnectionError as e:
> log.msg('check_old_sessions - connection error {}'
> .format(e), logLevel=logging.WARNING)
>
> session_db is a object with methods which makes some calls to Redis.
>
> Testing if __init__ works correctly is easy - I can mock task.LoopingCall
> and check if it was called with correct attributes.
>
> I've got trouble testing check_old_sessions. Since I'm writing unit tests
> I don't want to call real session_db methods and make real Redis queries.
> I'd like to mock them and test just few things:
> - is the method get_old_sessions called?
> - is the method process_stopped called N times with the arguments returned
> by mocked get_old_sessions?
> - is txredisapi.ConnectionError handled correctly?
>
> So is there any "right" way of mocking functions which returns deferreds?
> Or maybe I should test this method differently?
>
> Best regards,
> Patryk
>
> ___
> Twisted-Python mailing list
> Twisted-Python@twistedmatrix.com
> http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
>
>
___
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python


Re: [Twisted-Python] Unit testing, trail, inlineCallbacks, deferreds and mocking

2015-01-27 Thread Adi Roiban
On 27 January 2015 at 13:00, Patryk Ściborek  wrote:
> Hi!
>
> I've just started a new project using Twisted and I want to write unit tests
> since the beginning. Unfortunately I've got some trouble understanding how
> should I do it. I read 'Test-driven development with Twisted', read some
> articles on the web and searched on the mailing list but I couldn't find
> anything which make it clear for me.
>
> I've got a class:
>
> class SessionCleaner(object):
> def __init__(self, session_db, interval=10):
> self.session_db = session_db
> self.lc = task.LoopingCall(self.check_old_sessions)

def __init__(self, session_db, interval=10, reactor=reactor)
self.lc = task.LoopingCall(self.check_old_sessions)
self.lc.clock = reactor

Then in tests you can replace the default reactor with
twisted.internet.task.Clock
In this way you have control over the looping call.

> self.lc.start(interval)
>
> @defer.inlineCallbacks
> def check_old_sessions(self):
> log.msg('check_old_sessions()', logLevel=logging.DEBUG)
> try:
> old_sessions = yield self.session_db.get_old_sessions()
> for s in old_sessions:
> yield self.session_db.process_stopped(s)
>
> except txredisapi.ConnectionError as e:
> log.msg('check_old_sessions - connection error {}'
> .format(e), logLevel=logging.WARNING)
>
> session_db is a object with methods which makes some calls to Redis.

In tests you can replace session_db with an InMemorySessionDB which is
rigged to return on demand a failure or success.

class InMemorySessionDB(object):

def __init__(self):
 self._session = []
 self._stop_session = {}

def addRiggedSession(self, session, stop_result):
  self._session.append(session)
  self._stop_session[session] = stop_result

def get_old_sessions(self)
return self._session

   def process_stopped(self, session):
  return self._stop_session[session]

InMemorySessionDB can also inherit form the real deal class and just
overwrite exit points.

This is more like a mock with a spec.. as it will fail if arbitrary
methods are called with arbitrary arguments.

I don't think there is a right way of doing it, but I try to avoid
using generic Mock or MagicMock objects.

Good luck!
-- 
Adi Roiban

___
Twisted-Python mailing list
Twisted-Python@twistedmatrix.com
http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python