mirror of git://git.psyced.org/git/pypsyc
207 lines
6.8 KiB
Python
207 lines
6.8 KiB
Python
"""
|
|
:copyright: 2010 by Manuel Jacob
|
|
:license: MIT
|
|
"""
|
|
from greenlet import greenlet
|
|
from mock import Mock, sentinel
|
|
from nose.tools import assert_raises
|
|
from tests.constants import SERVER1, IP, PORT
|
|
from tests.helpers import mockified, check_success, StubException
|
|
from twisted.internet.defer import Deferred, fail
|
|
from twisted.names.dns import RRHeader, Record_A, Record_SRV
|
|
from twisted.names.error import DNSNameError
|
|
from twisted.python.failure import Failure
|
|
|
|
from pypsyc.util import (scheduler, schedule, Waiter, DNSError,
|
|
resolve_hostname, _PSYCConnector, connect, Event)
|
|
|
|
|
|
@mockified('pypsyc.util', ['greenlet'])
|
|
def test_schedule_scheduler(greenlet):
|
|
func = Mock()
|
|
|
|
schedule(func)
|
|
assert greenlet.call_args_list == [((func, scheduler),)]
|
|
assert greenlet.return_value.method_calls == [('switch',)]
|
|
|
|
orig_greenlet = greenlet
|
|
@mockified('pypsyc.util', ['greenlet', 'reactor'])
|
|
def test_schedule_nonscheduler(greenlet, reactor):
|
|
func = Mock()
|
|
|
|
orig_greenlet(schedule).switch(func)
|
|
assert greenlet.call_args_list == [((func, scheduler),)]
|
|
assert reactor.method_calls == [
|
|
('callLater', (0, greenlet.return_value.switch))]
|
|
|
|
|
|
class TestWaiter(object):
|
|
def test_callback_sync(self):
|
|
waiter = Waiter()
|
|
|
|
waiter.callback(sentinel.value)
|
|
ret = waiter.get()
|
|
assert ret == sentinel.value
|
|
|
|
def test_errback_sync(self):
|
|
e = StubException()
|
|
waiter = Waiter()
|
|
|
|
waiter.errback(e)
|
|
assert_raises(StubException, waiter.get)
|
|
|
|
@check_success
|
|
def test_callback_async(self):
|
|
waiter = Waiter()
|
|
|
|
def _test():
|
|
ret = waiter.get()
|
|
assert ret == sentinel.value
|
|
self.success = True
|
|
greenlet(_test).switch()
|
|
waiter.callback(sentinel.value)
|
|
|
|
@check_success
|
|
def test_errback_async(self):
|
|
e = StubException()
|
|
waiter = Waiter()
|
|
|
|
def _test():
|
|
assert_raises(StubException, waiter.get)
|
|
self.success = True
|
|
greenlet(_test).switch()
|
|
waiter.errback(e)
|
|
|
|
|
|
class TestResolveHostname(object):
|
|
@check_success
|
|
@mockified('pypsyc.util', ['lookupService', 'getHostByName'])
|
|
def test_resolve_hostname_srv(self, lookupService, getHostByName):
|
|
SERVICE = '_psyc._tcp.%s.' % SERVER1
|
|
srv_rr = RRHeader(name=SERVICE, type=Record_SRV.TYPE,
|
|
payload=Record_SRV(target=SERVER1, port=PORT))
|
|
a_rr = RRHeader(name=SERVER1, type=Record_A.TYPE,
|
|
payload=Record_A(IP))
|
|
looked_up = lookupService.return_value = Deferred()
|
|
|
|
def _test():
|
|
ip, port = resolve_hostname(SERVER1)
|
|
assert ip == IP
|
|
assert port == PORT
|
|
assert lookupService.call_args_list == [((SERVICE,),)]
|
|
self.success = True
|
|
schedule(_test)
|
|
looked_up.callback(([srv_rr], [], [a_rr]))
|
|
|
|
@check_success
|
|
@mockified('pypsyc.util', ['lookupService', 'getHostByName'])
|
|
def test_resolve_hostname_a(self, lookupService, getHostByName):
|
|
lookupService.side_effect = DNSNameError
|
|
looked_up = getHostByName.return_value = Deferred()
|
|
|
|
def _test():
|
|
ip, port = resolve_hostname(SERVER1)
|
|
assert ip == IP
|
|
assert port == PORT
|
|
assert getHostByName.call_args_list == [((SERVER1,),)]
|
|
self.success = True
|
|
schedule(_test)
|
|
looked_up.callback(IP)
|
|
|
|
@check_success
|
|
@mockified('pypsyc.util', ['lookupService', 'getHostByName'])
|
|
def test_resolve_hostname_a_error(self, lookupService, getHostByName):
|
|
lookupService.side_effect = DNSNameError
|
|
getHostByName.return_value = fail(DNSNameError())
|
|
|
|
def _test():
|
|
assert_raises(DNSError, resolve_hostname, SERVER1)
|
|
self.success = True
|
|
schedule(_test)
|
|
|
|
|
|
class TestConnector(object):
|
|
@mockified('pypsyc.util', ['reactor'])
|
|
def setup(self, reactor):
|
|
self.reactor = reactor
|
|
self.factory = Mock()
|
|
self.circuit = self.factory.buildProtocol.return_value
|
|
self.connector = _PSYCConnector(SERVER1, PORT, self.factory, 30, None)
|
|
self.transport = Mock()
|
|
self.connector._makeTransport = lambda: self.transport
|
|
self.connector.cancelTimeout = Mock()
|
|
|
|
@check_success
|
|
def test_connect(self):
|
|
def _test():
|
|
circuit = self.connector.connect()
|
|
assert circuit == self.circuit
|
|
self.success = True
|
|
schedule(_test)
|
|
assert self.connector.state == 'connecting'
|
|
assert self.connector.transport == self.transport
|
|
assert self.connector.timeoutID == self.reactor.callLater.return_value
|
|
|
|
self.connector.buildProtocol(None)
|
|
assert self.connector.state == 'connected'
|
|
assert self.connector.cancelTimeout.called
|
|
assert self.factory.method_calls == [('buildProtocol', (None,))]
|
|
|
|
self.circuit.inited()
|
|
|
|
@check_success
|
|
def test_connection_failed(self):
|
|
def _test():
|
|
assert_raises(StubException, self.connector.connect)
|
|
self.success = True
|
|
schedule(_test)
|
|
self.connector.connectionFailed(Failure(StubException()))
|
|
assert self.connector.cancelTimeout.called
|
|
assert self.connector.transport is None
|
|
assert self.connector.state == 'disconnected'
|
|
|
|
def test_connection_lost(self):
|
|
ERROR = StubException()
|
|
self.connector.buildProtocol(None)
|
|
self.connector.connectionLost(Failure(ERROR))
|
|
assert self.connector.state == 'disconnected'
|
|
assert self.factory.method_calls == [
|
|
('buildProtocol', (None,)),
|
|
('connection_lost', (self.circuit, ERROR))]
|
|
|
|
@mockified('pypsyc.util', ['_PSYCConnector'])
|
|
def test_connect1(_PSYCConnector):
|
|
connect(sentinel.host, sentinel.port, sentinel.factory)
|
|
assert _PSYCConnector.call_args_list == [
|
|
((sentinel.host, sentinel.port, sentinel.factory, 30, None),)]
|
|
assert _PSYCConnector.return_value.method_calls == [('connect',)]
|
|
|
|
@mockified('pypsyc.util', ['_PSYCConnector'])
|
|
def test_connect2(_PSYCConnector):
|
|
connect(sentinel.host, sentinel.port, sentinel.factory,
|
|
timeout=sentinel.timeout, bindAddress=sentinel.bindAddress)
|
|
assert _PSYCConnector.call_args_list == [
|
|
((sentinel.host, sentinel.port, sentinel.factory, sentinel.timeout,
|
|
sentinel.bindAddress),)]
|
|
assert _PSYCConnector.return_value.method_calls == [('connect',)]
|
|
|
|
|
|
def test_event():
|
|
event = Event()
|
|
f1 = Mock()
|
|
f2 = Mock()
|
|
event += f1
|
|
event.add_observer(f2, 1, i=2)
|
|
|
|
x = Mock()
|
|
y = Mock()
|
|
|
|
event(x, y=y)
|
|
assert f1.call_args_list == [((x,), {'y': y})]
|
|
assert f2.call_args_list == [((x, 1), {'y': y, 'i': 2})]
|
|
|
|
event -= f2
|
|
event(x)
|
|
assert f1.call_args_list == [((x,), {'y': y}), ((x,),)]
|
|
assert f2.call_args_list == [((x, 1), {'y': y, 'i': 2})]
|