""" :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})]