1
0
Fork 0
mirror of git://git.psyced.org/git/pypsyc synced 2024-08-15 03:20:04 +00:00

added new pypsyc as 'mjacob2'

This commit is contained in:
psyc://psyced.org/~lynX 2012-01-02 14:12:33 +01:00
parent 0abc7a0888
commit 9f7c4147c7
46 changed files with 7243 additions and 0 deletions

View file

@ -0,0 +1,4 @@
import tests.helpers
from twisted.python.log import defaultObserver, PythonLoggingObserver
defaultObserver.stop()
PythonLoggingObserver().start()

View file

@ -0,0 +1,41 @@
from pypsyc.client.model import Presence
from pypsyc.core.mmp import Uni
SERVER1 = 'server1'
SERVER1_UNI = Uni('psyc://%s/' % SERVER1)
USER1 = '~user1'
USER2 = '~user2'
USER1_UNI = SERVER1_UNI.chain(USER1)
USER2_UNI = SERVER1_UNI.chain(USER2)
USER1_NICK = 'user1'
USER2_NICK = 'user2'
RESOURCE = '*Resource'
RESOURCE1_UNI = USER1_UNI.chain(RESOURCE)
RESOURCE2_UNI = USER2_UNI.chain(RESOURCE)
PLACE = '@place'
PLACE_UNI = SERVER1_UNI.chain(PLACE)
SERVER2 = 'server2'
SERVER2_UNI = Uni('psyc://%s/' % SERVER2)
SERVER3 = 'server3'
SERVER3_UNI = Uni('psyc://%s/' % SERVER3)
INTERFACE = 'interface'
IP = '10.0.0.1'
PORT = 4404
VARIABLES = {'_key': 'value'}
CONTENT = ['']
PASSWORD = 'password'
MESSAGE = 'message'
UNKNOWN = 0
OFFLINE = 1
ONLINE = 7
PRESENCE_UNKNOWN = Presence(UNKNOWN)
PRESENCE_OFFLINE = Presence(OFFLINE)
PRESENCE_ONLINE = Presence(ONLINE)
PENDING = 'pending'
OFFERED = 'offered'
ESTABLISHED = 'established'
ERROR = 'error'
EXCEPTION = Exception(ERROR)

133
mjacob2/tests/helpers.py Normal file
View file

@ -0,0 +1,133 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from functools import wraps
from traceback import format_exc
import sys
from greenlet import getcurrent
from mock import Mock
import twisted.internet
from pypsyc.core.mmp import Header
# keep reactor from being installed
assert not 'twisted.internet.reactor' in sys.modules
twisted.internet.reactor = sys.modules['twisted.internet.reactor'] = None
# random helpers
def inited_header(*args, **kwds):
header = Header(*args, **kwds)
header._init()
return header
def _make_send_function(other_circuit):
def f(header, content):
try:
other_circuit.packet_received(inited_header(header), content)
except:
raise Exception("%s.packet_received raised exception:\n%s" %
(other_circuit, format_exc()))
return f
def connect_circuits(c1, c2):
"""Make a virtual connection between two curcuits."""
c1.send = c1.psyc._send = _make_send_function(c2)
c2.send = c2.psyc._send = _make_send_function(c1)
return c1, c2
class iter_(object):
def __init__(self, *iter_):
self.iter_ = iter_
def __eq__(self, iter_):
return tuple(iter_) == self.iter_
def rendered(packet):
return iter_(*packet.render())
def check_success(f):
"""
Wrap `f` so that it checks if :attr:`TestCase.success` is ``True``. This is
useful to check if an asynchronous test has passed completely.
"""
@wraps(f)
def _wrapper(self):
self.success = False
f(self)
assert self.success
del self.success
return _wrapper
class AsyncMethod(object):
def __call__(self, *args, **kwds):
self.child = getcurrent()
return self.child.parent.switch()
def callback(self, *args, **kwds):
self.child.switch(*args, **kwds)
def errback(self, *args, **kwds):
self.child.throw(*args, **kwds)
def mockify(obj, attrs):
"""Replace attrs of obj with mocks. Return the original attributes."""
originals = {}
for attr in attrs:
orig = originals[attr] = getattr(obj, attr)
mock = Mock(spec=orig)
setattr(obj, attr, mock)
return originals
class mockified(object):
"""
Wrap a function so that it 'mockifies' and resets `obj`. If `obj` is a
string, mockify the module named like it.
Can also be used as a context manager.
"""
def __init__(self, obj, attrs):
if isinstance(obj, basestring):
self.obj = __import__(obj, globals(), locals(), attrs)
else:
self.obj = obj
self.attrs = attrs
def __enter__(self):
self.originals = mockify(self.obj, self.attrs)
return (getattr(self.obj, attr) for attr in self.attrs)
def __exit__(self, type, value, traceback):
for attr, original in self.originals.iteritems():
setattr(self.obj, attr, original)
def __call__(self, f):
@wraps(f)
def _wrapper(*args, **kwds):
with self:
kwds.update((attr, getattr(self.obj, attr)) for attr in self.attrs)
return f(*args, **kwds)
return _wrapper
class PlaceHolder(object):
"""
An object that be used as a placeholder for comparisons. The object on the
other side of the comparison is saved as attribute `obj`.
"""
def __eq__(self, other):
self.obj = other
return True
class StubException(Exception):
pass

View file

@ -0,0 +1,680 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from mock import Mock, MagicMock
from nose.tools import assert_raises
from tests.constants import (SERVER1, USER1_UNI, USER2_UNI, USER1_NICK,
USER2_NICK, PLACE_UNI, SERVER2_UNI, MESSAGE, PRESENCE_OFFLINE,
PRESENCE_ONLINE, ERROR, EXCEPTION)
from tests.helpers import mockified, AsyncMethod, PlaceHolder, iter_
from pypsyc.client.controller import (ListBinding, AccountsController,
ConversationController, ConferenceController, TabsController,
FriendListController, DumpController, MainController)
from pypsyc.client.model import Message
from pypsyc.client.observable import ObsList, ObsDict, ObsObj, ObsAttr
from pypsyc.util import Event
def _check_obs_list(obs_list):
assert obs_list.setitem_evt.observers == []
assert obs_list.delitem_evt.observers == []
assert obs_list.insert_evt.observers == []
assert obs_list.update_evt.observers == []
return True
def _check_obs_dict(obs_dict):
assert obs_dict.setitem_evt.observers == []
assert obs_dict.delitem_evt.observers == []
assert obs_dict.update_evt.observers == []
return True
def _check_obs_obj(obs_obj):
assert obs_obj.update_evt != {}
for evt in obs_obj.update_evt.itervalues():
assert evt.observers == []
return True
class TestListBinding(object):
def setup(self):
self.model = Mock()
self.model_list = ObsList([self.model])
self.view_list = []
self.make_row = Mock()
self.binding = ListBinding(self.model_list, self.view_list,
self.make_row)
def test_bind(self):
assert self.make_row.call_args_list == [((self.model,),)]
assert self.view_list == [self.make_row.return_value]
def test_add(self):
assert self.make_row.call_args_list == [((self.model,),)]
self.make_row.reset_mock()
model2 = Mock()
self.model_list.append(model2)
assert self.make_row.call_args_list == [((model2,),)]
assert self.view_list == [self.make_row.return_value] * 2
def test_update(self):
assert self.make_row.call_args_list == [((self.model,),)]
self.make_row.reset_mock()
self.model_list.updated_item(self.model)
assert self.make_row.call_args_list == [((self.model,),)]
assert self.view_list == [self.make_row.return_value]
def test_delete(self):
del self.model_list[0]
assert self.view_list == []
def test_unbind(self):
self.binding.unbind()
assert _check_obs_list(self.model_list)
assert self.view_list == []
class _List(list):
def __init__(self, *args, **kwds):
list.__init__(self, *args, **kwds)
self.updated_item = Mock()
class TestAccountsController(object):
@mockified('pypsyc.client.controller', ['ListBinding'])
def setup(self, ListBinding):
self.ListBinding = ListBinding
self.account = Mock()
self.client = Mock()
self.client.accounts = _List([self.account])
self.view = Mock()
self.controller = AccountsController(self.client, self.view)
def test_binding(self):
make_row_ph = PlaceHolder()
assert self.ListBinding.call_args_list == [
((self.client.accounts, self.view.accounts, make_row_ph),)]
account = Mock()
row = make_row_ph.obj(account)
assert row == (account.uni, account.active)
@mockified('pypsyc.client.controller', ['Account'])
def test_add_account(self, Account):
account = Account.return_value
callback_ph = PlaceHolder()
self.controller.add_account()
assert Account.call_args_list == [
((self.client, '', '', '', False, False),)]
assert self.view.method_calls == [
('show_addedit_dialog', (account.__dict__, True, callback_ph))]
callback_ph.obj()
assert self.client.accounts == [self.account, account]
assert self.client.method_calls == [('save_accounts',)]
def test_edit_account(self):
callback_ph = PlaceHolder()
self.controller.edit_account(0)
assert self.view.method_calls == [
('show_addedit_dialog', (self.account.__dict__, False,
callback_ph))]
callback_ph.obj()
assert self.client.accounts.updated_item.call_args_list == [
((self.account,),)]
assert self.client.method_calls == [('save_accounts',)]
def test_remove_account(self):
assert_raises(IndexError, self.controller.remove_account, 1)
self.controller.remove_account(0)
assert self.client.accounts == []
assert self.client.method_calls == [('save_accounts',)]
def test_set_active(self):
self.controller.set_active(0, True)
assert self.account.active == True
assert self.client.accounts.updated_item.call_args_list == [
((self.account,),)]
assert self.client.method_calls == [('save_accounts',)]
def test_closed(self):
self.controller.closed()
assert self.ListBinding.return_value.method_calls == [('unbind',)]
IN = 'i'
OUT = 'o'
LINE = 'line'
class _StubAccount(ObsObj):
circuit = ObsAttr('circuit')
class TestDumpController:
def setup(self):
self.circuit = Mock()
self.circuit.dump_evt = Event()
self.account = _StubAccount()
self.account.uni = USER1_UNI
self.client = Mock()
self.client.accounts = ObsList()
self.view = Mock()
def test_connected(self):
self.account.circuit = self.circuit
self.client.accounts.append(self.account)
DumpController(self.client, self.view)
self.circuit.dump_evt(IN, LINE)
assert self.view.method_calls == [('show_line', (IN, LINE, USER1_UNI))]
def test_connect(self):
DumpController(self.client, self.view)
self.client.accounts.append(self.account)
self.account.circuit = self.circuit
self.circuit.dump_evt(IN, LINE)
assert self.view.method_calls == [('show_line', (IN, LINE, USER1_UNI))]
def test_disconnect(self):
self.account.circuit = self.circuit
self.client.accounts.append(self.account)
DumpController(self.client, self.view)
del self.account.circuit
assert self.circuit.dump_evt.observers == []
def test_reconnect(self):
DumpController(self.client, self.view)
self.account.circuit = self.circuit
self.client.accounts.append(self.account)
circuit2 = Mock()
circuit2.dump_evt = Event()
self.account.circuit = circuit2
assert self.circuit.dump_evt.observers == []
circuit2.dump_evt(OUT, LINE)
assert self.view.method_calls == [
('show_line', (OUT, LINE, USER1_UNI))]
def test_remove(self):
self.client.accounts.append(self.account)
self.account.circuit = self.circuit
DumpController(self.client, self.view)
self.client.accounts.remove(self.account)
assert _check_obs_obj(self.account)
assert self.circuit.dump_evt.observers == []
def test_remove_nocircuit(self):
self.client.accounts.append(self.account)
DumpController(self.client, self.view)
self.client.accounts.remove(self.account)
assert _check_obs_obj(self.account)
def test_closed(self):
self.client.accounts.append(self.account)
self.account.circuit = self.circuit
dump_controller = DumpController(self.client, self.view)
dump_controller.closed()
assert _check_obs_list(self.client.accounts)
assert _check_obs_obj(self.account)
assert self.circuit.dump_evt.observers == []
class TestConversationController(object):
def setup(self):
self.tabs_controller = Mock()
self.conversation = Mock()
self.conversation.messages = ObsList()
self.conversation.unknown_target_evt = Event()
self.conversation.delivery_failed_evt = Event()
self.view = Mock()
self.controller = ConversationController(self.tabs_controller,
self.conversation, self.view)
def test_message(self):
MESSAGE_OBJ = Message(USER2_UNI, MESSAGE)
MESSAGE_LINE = "(%s) <%s> %s" % (
MESSAGE_OBJ.time.strftime("%H:%M:%S"), USER2_UNI, MESSAGE)
self.conversation.messages.append(MESSAGE_OBJ)
assert self.view.method_calls == [('show_message', (MESSAGE_LINE,))]
def test_unknown_target(self):
self.conversation.unknown_target_evt()
assert self.view.method_calls == [('show_unknown_target',)]
def test_delivery_failed(self):
self.conversation.delivery_failed_evt(ERROR)
assert self.view.method_calls == [('show_delivery_failed', (ERROR,))]
def test_enter_message(self):
self.controller.enter(MESSAGE)
assert self.conversation.method_calls == [('send_message', (MESSAGE,))]
def test_enter_command(self):
self.controller.enter("/command")
assert self.view.method_calls == [('show_unknown_command',)]
assert self.conversation.method_calls == []
def test_closed(self):
self.conversation.messages.append(Message(None, None))
self.controller.closed()
assert _check_obs_list(self.conversation.messages)
assert self.conversation.unknown_target_evt.observers == []
assert self.conversation.delivery_failed_evt.observers == []
class TestConferenceController(object):
@mockified('pypsyc.client.controller', ['ListBinding'])
def setup(self, ListBinding):
self.ListBinding = ListBinding
self.tabs_controller = Mock()
self.conference = Mock()
self.conference.members = []
self.conference.messages = ObsList()
self.conference.unknown_target_evt = Event()
self.conference.delivery_failed_evt = Event()
self.view = Mock()
self.controller = ConferenceController(self.tabs_controller,
self.conference, self.view)
def test_binding(self):
makerow_ph = PlaceHolder()
assert self.ListBinding.call_args_list == [
((self.conference.members, self.view.members, makerow_ph),)]
member = Mock()
row = makerow_ph.obj(member)
assert row == (member.uni, member.nick)
def test_open_conversation(self):
member = Mock()
self.conference.members.append(member)
account = self.conference.conferencing.account
conversation = account.get_conversation.return_value
self.controller.open_conversation(0)
assert self.conference.conferencing.account.method_calls == [
('get_conversation', (member.uni,))]
assert self.tabs_controller.method_calls == [
('focus_conversation', (conversation,))]
def test_closed(self):
self.controller.closed()
assert self.ListBinding.return_value.method_calls == [('unbind',)]
assert _check_obs_list(self.conference.messages)
assert self.conference.unknown_target_evt.observers == []
assert self.conference.delivery_failed_evt.observers == []
class TestTabsController(object):
def setup(self):
self.client = Mock()
self.client.accounts = ObsList()
self.view = Mock()
self.account = Mock()
self.account.conversations = ObsDict()
self.account.conferences = ObsDict()
self.client.accounts.append(self.account)
@mockified('pypsyc.client.controller', ['ConversationController',
'ConferenceController'])
def test_deleted_account(self, ConversationController,
ConferenceController):
self.account.conversations[USER2_UNI] = Mock()
self.account.conferences[PLACE_UNI] = Mock()
conv_view = self.view.show_conversation.return_value
conv_controller = ConversationController.return_value
conf_view = self.view.show_conference.return_value
conf_controller = ConferenceController.return_value
TabsController(self.client, self.view)
self.view.reset_mock()
del self.client.accounts[0]
assert _check_obs_dict(self.account.conversations)
assert _check_obs_dict(self.account.conferences)
assert self.view.method_calls == [('remove_tab', (conv_view,)),
('remove_tab', (conf_view,))]
assert conv_controller.method_calls == [('closed',)]
assert conf_controller.method_calls == [('closed',)]
@mockified('pypsyc.client.controller', ['ConversationController'])
def test_conversation(self, ConversationController):
conversation = Mock()
conversation.uni = USER2_UNI
conv_view = self.view.show_conversation.return_value
conv_controller = ConversationController.return_value
controller = TabsController(self.client, self.view)
self.account.conversations[USER2_UNI] = conversation
assert self.view.method_calls == [('show_conversation', (USER2_UNI,))]
assert ConversationController.call_args_list == [
((controller, conversation, conv_view),)]
self.view.reset_mock()
controller.focus_conversation(conversation)
assert self.view.method_calls == [('focus_tab', (conv_view,))]
self.view.reset_mock()
controller.close_tab(conv_view)
assert self.account.conversations == {}
assert self.view.method_calls == [('remove_tab', (conv_view,))]
assert conv_controller.method_calls == [('closed',)]
@mockified('pypsyc.client.controller', ['ConferenceController'])
def test_conference(self, ConferenceController):
conference = Mock()
conference.uni = PLACE_UNI
conf_view = self.view.show_conference.return_value
conf_controller = ConferenceController.return_value
self.account.conferences[PLACE_UNI] = conference
controller = TabsController(self.client, self.view)
assert self.view.method_calls == [
('show_conference', (PLACE_UNI,),)]
assert ConferenceController.call_args_list == [
((controller, conference, conf_view),)]
self.view.reset_mock()
controller.focus_conversation(conference)
assert self.view.method_calls == [('focus_tab', (conf_view,))]
self.view.reset_mock()
controller.close_tab(conf_view)
assert self.account.conferences == {}
assert self.view.method_calls == [('remove_tab', (conf_view,))]
assert conf_controller.method_calls == [('closed',)]
class TestFriendListController(object):
@mockified('pypsyc.client.controller', ['ListBinding'])
def setup(self, ListBinding):
self.ListBinding = ListBinding
model_list_ph = PlaceHolder()
make_row_ph = PlaceHolder()
self.client = Mock()
self.client.accounts = ObsList()
self.view = Mock()
self.tabs_controller = Mock()
self.controller = FriendListController(self.client, self.view,
self.tabs_controller)
assert self.ListBinding.call_args_list == [
((model_list_ph, self.view.friends, make_row_ph),)]
self.model_list = model_list_ph.obj
self.make_row = make_row_ph.obj
def test_binding(self):
EXTERN_FRIEND_UNI = SERVER2_UNI.chain('~friend')
friend = Mock()
friend.account.server = SERVER1
friend.uni = USER1_UNI
friend.presence = PRESENCE_OFFLINE
row = self.make_row(friend)
assert row == (USER1_NICK, False, friend.state)
friend.uni = EXTERN_FRIEND_UNI
friend.presence = PRESENCE_ONLINE
row = self.make_row(friend)
assert row == (EXTERN_FRIEND_UNI, True, friend.state)
def test_account(self):
update_evt = Mock()
friend1 = Mock()
friend2 = Mock()
account = Mock()
account.friends = ObsDict({USER1_UNI: friend1})
self.model_list.update_evt += update_evt
assert self.model_list == []
self.client.accounts.append(account)
assert self.model_list == [friend1]
account.friends[USER2_UNI] = friend2
assert self.model_list == [friend1, friend2]
account.friends.updated_item(USER2_UNI)
assert update_evt.call_args_list == [((1, friend2),)]
del account.friends[USER1_UNI]
assert self.model_list == [friend2]
del self.client.accounts[0]
assert _check_obs_dict(account.friends)
assert self.model_list == []
def test_open_conversation(self):
friend = Mock()
friend.uni = USER2_UNI
self.model_list.append(friend)
conversation = friend.account.get_conversation.return_value
self.controller.open_conversation(0)
assert friend.account.method_calls == [
('get_conversation', (USER2_UNI,))]
assert self.tabs_controller.method_calls == [
('focus_conversation', (conversation,))]
def test_accept_friendship(self):
friend = Mock()
friend.uni = USER2_UNI
friend.account.add_friend.side_effect = AsyncMethod()
self.model_list.append(friend)
self.controller.accept_friendship(0)
assert friend.account.method_calls == [('add_friend', (USER2_UNI,))]
def test_cancel_friendship(self):
friend = Mock()
friend.uni = USER2_UNI
friend.account.remove_friend.side_effect = AsyncMethod()
self.model_list.append(friend)
self.controller.cancel_friendship(0)
assert friend.account.method_calls == [('remove_friend', (USER2_UNI,))]
class TestMainController(object):
@mockified('pypsyc.client.controller', ['TabsController',
'FriendListController'])
def setup(self, TabsController, FriendListController):
self.client = Mock()
self.client.accounts = ObsList()
self.view = Mock()
self.controller = MainController(self.client, self.view)
self.TabsController = TabsController
self.FriendListController = FriendListController
def test_main_controller(self):
tabs_controller = self.TabsController.return_value
assert self.TabsController.call_args_list == [
((self.client, self.view.tabs_view),)]
assert self.FriendListController.call_args_list == [
((self.client, self.view.friends_view, tabs_controller),)]
def test_no_password(self):
account = self._make_account()
self.client.accounts.append(account)
callback_ph = PlaceHolder()
update_evt = Mock()
self.client.accounts.update_evt += update_evt
account.no_password_evt()
assert self.view.method_calls == [
('show_password_dialog', (account.uni, account.__dict__,
callback_ph))]
callback_ph.obj()
assert account.active == True
assert update_evt.call_args_list == [((0, account),)]
assert self.client.method_calls == [('save_accounts',)]
del self.client.accounts[0]
assert account.no_password_evt.observers == []
def test_connection_error(self):
account = self._make_account()
self.client.accounts.append(account)
account.connection_error_evt(EXCEPTION)
assert self.view.method_calls == [
('show_conn_error', (account.uni, ERROR))]
del self.client.accounts[0]
assert account.connection_error_evt.observers == []
def test_no_such_user(self):
account = self._make_account()
self.client.accounts.append(account)
account.no_such_user_evt(EXCEPTION)
assert self.view.method_calls == [('show_no_such_user', (ERROR,))]
del self.client.accounts[0]
assert account.no_such_user_evt.observers == []
def test_auth_error(self):
account = self._make_account()
self.client.accounts.append(account)
account.auth_error_evt(EXCEPTION)
assert self.view.method_calls == [
('show_auth_error', (account.uni, ERROR))]
del self.client.accounts[0]
assert account.auth_error_evt.observers == []
def _make_account(self, active=False):
account = Mock()
account.active = active
account.no_password_evt = Event()
account.connection_error_evt = Event()
account.no_such_user_evt = Event()
account.auth_error_evt = Event()
return account
@mockified('pypsyc.client.controller', ['AccountsController'])
def test_open_accounts(self, AccountsController):
self.controller.open_accounts()
assert AccountsController.call_args_list == [
((self.client, self.view.show_accounts.return_value),)]
@mockified('pypsyc.client.controller', ['DumpController'])
def test_open_dump(self, DumpController):
self.controller.open_dump()
assert DumpController.call_args_list == [
((self.client, self.view.show_dump_win.return_value),)]
def test_open_conversation(self):
account1 = Mock()
account1.active = False
account2 = Mock()
account2.active = True
self.client.accounts = [account1, account2]
callback_ph = PlaceHolder()
conversation = account2.get_conversation.return_value
self.controller.open_conversation()
assert self.view.method_calls == [
('show_open_conv_dialog', (iter_(account2.uni), callback_ph))]
callback_ph.obj(0, SERVER1, USER2_NICK)
assert account2.method_calls == [('get_conversation', (USER2_UNI,))]
assert self.TabsController.return_value.method_calls == [
('focus_conversation', (conversation,))]
def test_open_conference(self):
account1 = Mock()
account1.active = False
account2 = Mock()
account2.active = True
self.client.accounts = [account1, account2]
callback_ph = PlaceHolder()
conference = account2.get_conference.return_value
self.controller.open_conference()
assert self.view.method_calls == [
('show_open_conf_dialog', (iter_(account2.uni), callback_ph))]
callback_ph.obj(0, SERVER1, 'place')
assert account2.method_calls == [
('get_conference', (PLACE_UNI,), {'subscribe': True})]
assert self.TabsController.return_value.method_calls == [
('focus_conversation', (conference,))]
def test_add_friend(self):
account1 = Mock()
account1.active = False
account2 = Mock()
account2.active = True
account2.add_friend.side_effect = AsyncMethod()
callback_ph = PlaceHolder()
self.client.accounts = [account1, account2]
self.controller.add_friend()
assert self.view.method_calls == [
('show_add_friend_dialog', (iter_(account2.uni), callback_ph))]
callback_ph.obj(0, SERVER1, USER2_NICK)
assert account2.method_calls == [('add_friend', (USER2_UNI,))]
def test_show_active_accounts(self):
account1 = self._make_account(active=True)
account2 = self._make_account(active=True)
self.client.accounts.append(account1)
assert self.view.method_calls == [('show_active_accounts', (True,))]
self.view.reset_mock()
self.client.accounts.append(account2)
assert self.view.method_calls == []
self.client.accounts.remove(account1)
assert self.view.method_calls == []
self.client.accounts.remove(account2)
assert self.view.method_calls == [('show_active_accounts', (False,))]
def test_show_active_accounts_updated(self):
account = self._make_account(active=False)
self.client.accounts.append(account)
assert self.view.method_calls == []
account.active = True
self.client.accounts.updated_item(account)
assert self.view.method_calls == [('show_active_accounts', (True,))]
self.view.reset_mock()
self.client.accounts.updated_item(account)
assert self.view.method_calls == []
account.active = False
self.client.accounts.updated_item(account)
assert self.view.method_calls == [('show_active_accounts', (False,))]
self.view.reset_mock()
self.client.accounts.updated_item(account)
assert self.view.method_calls == []
del self.client.accounts[0]
assert self.view.method_calls == []
def test_quit(self):
self.controller.quit()
assert _check_obs_list(self.client.accounts)
assert self.client.method_calls == [('quit',)]

View file

@ -0,0 +1,563 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from os import remove
from tempfile import NamedTemporaryFile
from mock import Mock, MagicMock, sentinel
from nose.tools import assert_raises
from tests.constants import (SERVER1, SERVER2, USER1_UNI, USER2_UNI,
USER1_NICK, USER2_NICK, RESOURCE, RESOURCE1_UNI, PLACE_UNI, VARIABLES,
CONTENT, PASSWORD, MESSAGE, ONLINE, PRESENCE_UNKNOWN, PRESENCE_ONLINE,
OFFERED, ESTABLISHED, ERROR, EXCEPTION)
from tests.helpers import mockified, PlaceHolder, inited_header, AsyncMethod
from pypsyc.client.model import (Conversation, Member, Conference, Messaging,
Conferencing, Account, FriendList, ClientCircuit, Circuit, Client)
from pypsyc.core.psyc import PSYCPacket
from pypsyc.protocol import (UnknownTargetError, DeliveryFailedError,
AuthenticationError)
class TestConversation(object):
def test_send_message(self):
message_ph = PlaceHolder()
messaging = Mock()
conversation = Conversation(messaging, USER2_UNI)
conversation.send_message(MESSAGE)
assert messaging.protocol.method_calls == [
('send_private_message', (USER2_UNI, MESSAGE),
{'relay': messaging.account.uni})]
assert conversation.messages == [message_ph]
assert message_ph.obj.source == messaging.account.uni
class TestConference(object):
def test_send_message(self):
conferencing = Mock()
conference = Conference(conferencing, PLACE_UNI)
conference.send_message(MESSAGE)
assert conferencing.protocol.method_calls == [
('send_public_message', (PLACE_UNI, MESSAGE))]
class TestMessaging(object):
def test_recv_message(self):
account = Mock()
conversation = account.get_conversation.return_value
conversation.messages = []
message_ph = PlaceHolder()
messaging = Messaging(account)
messaging.private_message(USER2_UNI, MESSAGE)
assert account.get_conversation.call_args_list == [((USER2_UNI,),)]
assert conversation.messages == [message_ph]
assert message_ph.obj.source == USER2_UNI
assert message_ph.obj.message == MESSAGE
@mockified('pypsyc.client.model', ['MessagingProtocol'])
def test_connected(self, MessagingProtocol):
circuit = Mock()
messaging = Messaging(Mock())
messaging.connected(circuit)
assert circuit.psyc.method_calls == [
('add_handler', (MessagingProtocol.return_value,))]
def test_disconnected(self):
Messaging(Mock).disconnected()
class TestConferencing(object):
def test_member_entered(self):
account = Mock()
conference = account.get_conference.return_value
conference.members = []
conferencing = Conferencing(account)
conferencing.member_entered(PLACE_UNI, USER2_UNI, USER2_NICK)
assert account.get_conference.call_args_list == [((PLACE_UNI,),)]
assert conference.members == [Member(USER2_UNI, USER2_NICK)]
def test_member_left(self):
account = Mock()
conference = account.get_conference.return_value
conference.members = [Member(USER1_UNI, USER1_NICK),
Member(USER2_UNI, USER2_NICK)]
conferencing = Conferencing(account)
conferencing.member_left(PLACE_UNI, USER2_UNI)
assert conference.members == [Member(USER1_UNI, USER1_NICK)]
def test_recv_message(self):
account = Mock()
conference = account.get_conference.return_value
conference.messages = []
message_ph = PlaceHolder()
conferencing = Conferencing(account)
conferencing.public_message(PLACE_UNI, USER2_UNI, MESSAGE)
assert account.get_conference.call_args_list == [((PLACE_UNI,),)]
assert conference.messages == [message_ph]
assert message_ph.obj.source == USER2_UNI
assert message_ph.obj.message == MESSAGE
@mockified('pypsyc.client.model', ['ConferencingProtocol'])
def test_connected(self, ConferencingProtocol):
circuit = Mock()
conferencing = Conferencing(Mock())
conferencing.connected(circuit)
assert circuit.method_calls == [
('psyc.add_handler', (ConferencingProtocol.return_value,)),
('add_pvar_handler', (ConferencingProtocol.return_value,))]
def test_disconnected(self):
Conferencing(Mock()).disconnected()
class _Dict(dict):
def __init__(self, *args, **kwds):
dict.__init__(self, *args, **kwds)
self.updated_item = Mock()
class TestFriendList(object):
def test_friendship(self):
friend_ph = PlaceHolder()
account = Mock()
account.friends = _Dict()
friend_list = FriendList(account)
friend_list.friendship(USER1_UNI, OFFERED)
assert account.friends == {USER1_UNI: friend_ph}
friend = friend_ph.obj
assert friend.account == account
assert friend.uni == USER1_UNI
assert friend.presence == PRESENCE_UNKNOWN
assert friend.state == OFFERED
friend_list.friendship(USER1_UNI, ESTABLISHED)
assert friend.state == ESTABLISHED
assert account.friends.updated_item.call_args_list == [((USER1_UNI,),)]
friend_list.friendship_removed(USER1_UNI)
assert account.friends == {}
def test_presence(self):
account = Mock()
account.friends = _Dict({USER2_UNI: Mock()})
friend_list = FriendList(account)
friend_list.presence(USER2_UNI, ONLINE)
assert account.friends[USER2_UNI].presence == PRESENCE_ONLINE
assert account.friends.updated_item.call_args_list == [((USER2_UNI,),)]
@mockified('pypsyc.client.model', ['FriendshipProtocol'])
def test_connected(self, FriendshipProtocol):
circuit = Mock()
friend_list = FriendList(Mock())
friend_list.connected(circuit)
assert circuit.method_calls == [
('psyc.add_handler', (FriendshipProtocol.return_value,)),
('add_pvar_handler', (FriendshipProtocol.return_value,))]
def test_disconnected(self):
account = Mock()
account.friends = _Dict({USER2_UNI: Mock()})
friend_list = FriendList(account)
friend_list.disconnected()
assert account.friends == {}
class TestAccount(object):
@mockified('pypsyc.client.model', ['ObsDict'])
def test_account(self, ObsDict):
obs_dict = ObsDict.return_value = MagicMock()
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
assert account.uni == USER1_UNI
assert ObsDict.call_args_list == [(), (), ()]
assert account.conversations == obs_dict
assert account.conferences == obs_dict
assert account.friends == obs_dict
@mockified('pypsyc.client.model', ['Messaging', 'Conversation'])
def test_get_conversation(self, Messaging, Conversation):
messaging = Messaging.return_value
conversation = Conversation.return_value
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
assert Messaging.call_args_list == [((account,),)]
assert account.get_conversation(USER2_UNI) == conversation
assert account.get_conversation(USER2_UNI) == conversation
assert Conversation.call_args_list == [((messaging, USER2_UNI),)]
assert account.conversations == {USER2_UNI: conversation}
@mockified('pypsyc.client.model', ['Conferencing', 'Conference'])
def test_get_conference(self, Conferencing, Conference):
conferencing = Conferencing.return_value
conference = Conference.return_value
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
assert Conferencing.call_args_list == [((account,),)]
assert account.get_conference(PLACE_UNI) == conference
assert account.get_conference(PLACE_UNI) == conference
assert Conference.call_args_list == [((conferencing, PLACE_UNI),)]
assert account.conferences == {PLACE_UNI: conference}
@mockified('pypsyc.client.model', ['Conferencing', 'Conference'])
def test_get_conference_subscribe(self, Conferencing, Conference):
conferencing = Conferencing.return_value
conference = Conference.return_value
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
client_interface = account.client_interface = Mock()
client_interface.subscribe.side_effect = AsyncMethod()
assert account.get_conference(PLACE_UNI, subscribe=True) == conference
assert account.get_conference(PLACE_UNI, subscribe=True) == conference
assert Conference.call_args_list == [((conferencing, PLACE_UNI),)]
assert account.conferences == {PLACE_UNI: conference}
assert client_interface.method_calls == [('subscribe', (PLACE_UNI,))]
@mockified('pypsyc.client.model', ['Conference'])
def test_get_conference_subscribe_unknown_target(self, Conference):
conference = Conference.return_value
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
client_interface = account.client_interface = Mock()
client_interface.subscribe.side_effect = UnknownTargetError
account.get_conference(PLACE_UNI, subscribe=True)
assert conference.method_calls == [('unknown_target_evt',)]
@mockified('pypsyc.client.model', ['Conference'])
def test_get_conference_subscribe_delivery_failed(self, Conference):
conference = Conference.return_value
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
client_interface = account.client_interface = Mock()
client_interface.subscribe.side_effect = DeliveryFailedError(ERROR)
account.get_conference(PLACE_UNI, subscribe=True)
assert conference.method_calls == [('delivery_failed_evt', (ERROR,))]
def test_remove_conference(self):
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
account.conferences[PLACE_UNI] = Mock()
client_interface = account.client_interface = Mock()
client_interface.unsubscribe.side_effect = AsyncMethod()
del account.conferences[PLACE_UNI]
assert client_interface.method_calls == [('unsubscribe', (PLACE_UNI,))]
def test_add_friend(self):
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
client_interface = account.client_interface = Mock()
account.add_friend(USER2_UNI)
assert client_interface.method_calls == [('add_friend', (USER2_UNI,))]
def test_remove_friend(self):
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
client_interface = account.client_interface = Mock()
account.remove_friend(USER2_UNI)
assert client_interface.method_calls == [
('remove_friend', (USER2_UNI,))]
@mockified('pypsyc.client.model', ['FriendList'])
def test_friendlist(self, FriendList):
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
assert FriendList.call_args_list == [((account,),)]
def test_unknown_target_error(self):
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
account.conversations[USER1_UNI] = conversation = Mock()
account.conferences[PLACE_UNI] = conference = Mock()
account.unknown_target_error(USER1_UNI)
account.unknown_target_error(USER2_UNI)
account.unknown_target_error(PLACE_UNI)
assert conversation.method_calls == [('unknown_target_evt',)]
assert conference.method_calls == [('unknown_target_evt',)]
def test_delivery_failed_error(self):
account = Account(None, SERVER1, USER1_NICK, PASSWORD, True, False)
account.conversations[USER1_UNI] = conversation = Mock()
account.conferences[PLACE_UNI] = conference = Mock()
account.delivery_failed_error(USER1_UNI, ERROR)
account.delivery_failed_error(USER2_UNI, ERROR)
account.delivery_failed_error(PLACE_UNI, ERROR)
assert conversation.method_calls == [('delivery_failed_evt', (ERROR,))]
assert conference.method_calls == [('delivery_failed_evt', (ERROR,))]
@mockified('pypsyc.client.model', ['resolve_hostname', 'connect',
'LinkingProtocol',
'RoutingErrorProtocol',
'ClientInterfaceProtocol', 'Messaging',
'Conferencing', 'FriendList'])
def test_active(self, resolve_hostname, connect, LinkingProtocol,
RoutingErrorProtocol, ClientInterfaceProtocol, Messaging,
Conferencing, FriendList):
resolve_hostname.return_value = (sentinel.ip, sentinel.port)
circuit = connect.return_value
linking_protocol = LinkingProtocol.return_value
linked = linking_protocol.link.side_effect = AsyncMethod()
messaging = Messaging.return_value
conferencing = Conferencing.return_value
friend_list = FriendList.return_value
client = Mock()
account = Account(client, SERVER1, USER1_NICK, PASSWORD, True, False)
account.active = True
account.active = True
assert resolve_hostname.call_args_list == [((account.server,),)]
assert connect.call_args_list == [
((sentinel.ip, sentinel.port, client),)]
assert LinkingProtocol.call_args_list == [((circuit,),)]
assert linking_protocol.method_calls == [
('link', (USER1_UNI, RESOURCE, PASSWORD))]
linked.callback()
assert circuit.psyc.uni == RESOURCE1_UNI
assert RoutingErrorProtocol.call_args_list == [((account,),)]
assert circuit.psyc.method_calls == [
('add_handler', (RoutingErrorProtocol.return_value,))]
assert ClientInterfaceProtocol.call_args_list == [((account,),)]
assert messaging.method_calls == [('connected', (circuit,))]
assert conferencing.method_calls == [('connected', (circuit,))]
assert friend_list.method_calls == [('connected', (circuit,))]
messaging.reset_mock()
conferencing.reset_mock()
friend_list.reset_mock()
account.active = False
account.active = False
assert circuit.transport.method_calls == [('loseConnection',)]
assert not hasattr(account, 'circuit')
assert messaging.method_calls == [('disconnected',)]
assert conferencing.method_calls == [('disconnected',)]
assert friend_list.method_calls == [('disconnected',)]
@mockified('pypsyc.client.model', ['resolve_hostname'])
def test_active_no_password(self, resolve_hostname):
no_password_evt = Mock()
account = Account(None, SERVER1, USER1_NICK, '', False, False)
account.no_password_evt += no_password_evt
account.active = True
assert account.active == False
assert no_password_evt.call_args_list == [()]
assert resolve_hostname.call_args_list == []
@mockified('pypsyc.client.model', ['resolve_hostname', 'connect'])
def test_active_dns_error(self, resolve_hostname, connect):
resolve_hostname.side_effect = EXCEPTION
client = Mock()
connection_error_evt = Mock()
account = Account(client, SERVER1, USER1_NICK, PASSWORD, False, False)
account.connection_error_evt += connection_error_evt
account.active = True
assert account.active == False
assert client.accounts.updated_item.call_args_list == [((account,),)]
assert connection_error_evt.call_args_list == [((EXCEPTION,),)]
assert connect.call_args_list == []
@mockified('pypsyc.client.model', ['resolve_hostname', 'connect',
'LinkingProtocol'])
def test_active_connect_error(self, resolve_hostname, connect,
LinkingProtocol):
client = Mock()
resolve_hostname.return_value = (sentinel.ip, sentinel.port)
connect.side_effect = EXCEPTION
connection_error_evt = Mock()
account = Account(client, SERVER1, USER1_NICK, PASSWORD, False, False)
account.connection_error_evt += connection_error_evt
account.active = True
assert account.active == False
assert client.accounts.updated_item.call_args_list == [((account,),)]
assert connection_error_evt.call_args_list == [((EXCEPTION,),)]
assert LinkingProtocol.call_args_list == []
@mockified('pypsyc.client.model', ['resolve_hostname', 'connect',
'LinkingProtocol'])
def test_active_no_such_user(self, resolve_hostname, connect,
LinkingProtocol):
ERROR = UnknownTargetError()
client = Mock()
resolve_hostname.return_value = (sentinel.ip, sentinel.port)
circuit = connect.return_value
LinkingProtocol.return_value.link.side_effect = ERROR
no_such_user_evt = Mock()
account = Account(client, SERVER1, USER1_NICK, PASSWORD, False, False)
account.no_such_user_evt += no_such_user_evt
account.active = True
assert account.active == False
assert client.accounts.updated_item.call_args_list == [((account,),)]
assert no_such_user_evt.call_args_list == [((ERROR,),)]
assert circuit.psyc.uni != account.uni.chain(account.resource)
@mockified('pypsyc.client.model', ['resolve_hostname', 'connect',
'LinkingProtocol'])
def test_active_incorrect_password(self, resolve_hostname, connect,
LinkingProtocol):
ERROR = AuthenticationError()
client = Mock()
resolve_hostname.return_value = (sentinel.ip, sentinel.port)
circuit = connect.return_value
LinkingProtocol.return_value.link.side_effect = ERROR
auth_error_evt = Mock()
account = Account(client, SERVER1, USER1_NICK, 'wrong', False, False)
account.auth_error_evt += auth_error_evt
account.active = True
assert account.active == False
assert client.accounts.updated_item.call_args_list == [((account,),)]
assert auth_error_evt.call_args_list == [((ERROR,),)]
assert circuit.psyc.uni != account.uni.chain(account.resource)
def test_connection_error(self):
client = Mock()
connection_error_evt = Mock()
account = Account(client, SERVER1, USER1_NICK, PASSWORD, False, False)
account.connection_error_evt += connection_error_evt
account.connection_error(EXCEPTION)
assert account.active == False
assert client.accounts.updated_item.call_args_list == [((account,),)]
assert connection_error_evt.call_args_list == [((EXCEPTION,),)]
class TestClientCircuit(object):
@mockified(Circuit, ['connectionMade'])
def test_dump_out(self, connectionMade):
LINE1 = ':_target\t' + USER2_UNI
LINE2 = '|'
cc = ClientCircuit()
dump_evt = Mock()
cc.dump_evt += dump_evt
cc.transport = Mock()
orig_write = cc.transport.write
cc.connectionMade()
assert connectionMade.call_args_list == [((cc,),)]
cc.send({'_target': USER2_UNI}, '')
assert dump_evt.call_args_list == [(('o', LINE1),), (('o', LINE2),)]
assert orig_write.call_args_list == [((LINE1+'\n'+LINE2+'\n',),)]
@mockified(Circuit, ['lineReceived'])
def test_dump_in(self, lineReceived):
lineReceived.return_value = None
cc = ClientCircuit()
dump_evt = Mock()
cc.dump_evt += dump_evt
cc.dataReceived('a\nb\n')
assert dump_evt.call_args_list == [(('i', 'a'),), (('i', 'b'),)]
assert lineReceived.call_args_list == [((cc, 'a'),), ((cc, 'b'),)]
@mockified('pypsyc.client.model', ['PSYCObject'])
def test_packet_received(self, PSYCObject):
psyc = PSYCObject.return_value
psyc.handle_packet.return_value = PSYCPacket()
cc = ClientCircuit()
assert PSYCObject.call_args_list == [((cc.send,),)]
cc.packet_received({}, CONTENT)
assert psyc.method_calls == [('handle_packet', ({}, CONTENT))]
@mockified('pypsyc.client.model', ['PSYCObject'])
def test_relay(self, PSYCObject):
psyc = PSYCObject.return_value
psyc.uni = RESOURCE1_UNI
psyc.handle_packet.return_value = PSYCPacket()
cc = ClientCircuit()
header = inited_header(_source=USER1_UNI, _source_relay=USER2_UNI)
cc.packet_received(header, CONTENT)
assert header.source == USER2_UNI
header2 = inited_header(_source=USER2_UNI, _source_relay=USER2_UNI)
assert_raises(AssertionError, cc.packet_received, header2, CONTENT)
@mockified('pypsyc.client.model', ['PSYCObject'])
def test_persistent(self, PSYCObject):
HEADER = {'_context': USER2_UNI}
packet = PSYCPacket({'=': VARIABLES, '+': VARIABLES, '-': VARIABLES})
packet.header = inited_header(HEADER)
psyc = PSYCObject.return_value
psyc.handle_packet.return_value = packet
cc = ClientCircuit()
handler = Mock()
state_set_key = handler.state_set_key = Mock()
state_add_key = handler.state_add_key = Mock()
state_remove_key = handler.state_remove_key = Mock()
cc.add_pvar_handler(handler)
cc.packet_received(HEADER, CONTENT)
assert psyc.method_calls == [('handle_packet', (HEADER, CONTENT))]
assert state_set_key.call_args_list == [((USER2_UNI, VARIABLES),)]
assert state_add_key.call_args_list == [((USER2_UNI, VARIABLES),)]
assert state_remove_key.call_args_list == [((USER2_UNI, VARIABLES),)]
class TestClient(object):
@mockified('pypsyc.client.model', ['Account'])
def test_accounts(self, Account):
account = Account.return_value
error_ph = PlaceHolder()
account1 = Mock()
account1.server = SERVER1
account1.person = USER1_NICK
account1.password = PASSWORD
account1.save_password = True
account1.active = False
account2 = Mock()
account2.server = SERVER2
account2.person = USER2_NICK
account2.password = PASSWORD
account2.save_password = False
account2.active = True
try:
with NamedTemporaryFile(delete=False) as f:
f.write('[]')
client = Client(accounts_file=f.name)
assert client.accounts == []
client.accounts = [account1, account2]
client.save_accounts()
client = Client(accounts_file=f.name)
client.load_accounts()
assert client.accounts == [Account.return_value] * 2
assert Account.call_args_list == [
((client, SERVER1, USER1_NICK, PASSWORD, True, False),),
((client, SERVER2, USER2_NICK, '', False, True),)]
finally:
remove(f.name)
client.connection_lost(account.circuit, sentinel.error)
assert account.method_calls == [('connection_error', (error_ph,))] * 2
assert error_ph.obj.args[0] == str(sentinel.error)
@mockified('pypsyc.client.model', ['reactor'])
def test_quit(self, reactor):
account = Mock()
client = Client()
client.accounts = [account]
client.quit()
assert account.active == False
assert reactor.method_calls == [('stop',)]

View file

@ -0,0 +1,173 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from mock import Mock
from nose.tools import assert_raises
from pypsyc.client.observable import ObsAttr, ObsObj, ObsList, ObsDict
class StubObsObj(ObsObj):
foo = ObsAttr('foo')
def test_obs_obj():
obs_obj = StubObsObj()
update_evt = Mock()
obs_obj.update_evt['foo'] += update_evt
obs_obj.ignore = 'foo'
assert not hasattr(obs_obj, 'foo')
obs_obj.foo = 'foo'
obs_obj.foo = 'foo'
obs_obj.foo = 'bar'
assert obs_obj.foo == 'bar'
del obs_obj.foo
assert not hasattr(obs_obj, 'foo')
assert_raises(AttributeError, obs_obj.__delattr__, 'foo')
assert update_evt.call_args_list == [
((None, 'foo'),), (('foo', 'bar'),), (('bar', None),)]
class TestObsList(object):
def test_basic(self):
obs_list = ObsList(xrange(10))
setitem_evt = Mock()
obs_list.setitem_evt += setitem_evt
delitem_evt = Mock()
obs_list.delitem_evt += delitem_evt
insert_evt = Mock()
obs_list.insert_evt += insert_evt
obs_list[3] = 3
obs_list[3] = 333
del obs_list[3]
obs_list.insert(3, 3)
assert obs_list == list(xrange(10))
assert setitem_evt.call_args_list == [((3, 3, 333),)]
assert delitem_evt.call_args_list == [((3, 333),)]
assert insert_evt.call_args_list == [((3, 3),)]
def test_ext_add(self):
obs_list = ObsList()
insert_evt = Mock()
obs_list.insert_evt += insert_evt
obs_list.append(42)
obs_list.extend([42, 1337])
obs_list += [42, 1337]
assert obs_list == [42, 42, 1337, 42, 1337]
assert insert_evt.call_args_list == [
((0, 42),), ((1, 42),), ((2, 1337),), ((3, 42),), ((4, 1337),)]
def test_ext_del(self):
obs_list = ObsList(xrange(10))
delitem_evt = Mock()
obs_list.delitem_evt += delitem_evt
assert obs_list.pop() == 9
assert obs_list.pop(8) == 8
obs_list.remove(7)
assert delitem_evt.call_args_list == [((9, 9),), ((8, 8),), ((7, 7),)]
assert obs_list == list(xrange(7))
def test_reverse(self):
obs_list = ObsList(xrange(10))
obs_list.reverse()
assert obs_list == list(reversed(xrange(10)))
def test_updated_item(self):
obs_list = ObsList(['a', 'b'])
update_evt = Mock()
obs_list.update_evt += update_evt
obs_list.updated_item('b')
assert update_evt.call_args_list == [((1, 'b'),)]
class TestObsDict(object):
def test_basic(self):
obs_dict = ObsDict(a='A')
setitem_evt = Mock()
obs_dict.setitem_evt += setitem_evt
delitem_evt = Mock()
obs_dict.delitem_evt += delitem_evt
obs_dict['a'] = 'A'
obs_dict['a'] = 'X'
del obs_dict['a']
obs_dict['b'] = 'B'
assert obs_dict == dict(b='B')
assert setitem_evt.call_args_list == [(('a', 'A', 'X'),),
(('b', None, 'B'),)]
assert delitem_evt.call_args_list == [(('a', 'X'),)]
def test_pop(self):
obs_dict = ObsDict(a='A', b='B')
delitem_evt = Mock()
obs_dict.delitem_evt += delitem_evt
assert obs_dict.pop('a') == 'A'
assert obs_dict.pop('a', 'X') == 'X'
assert obs_dict.pop('b', 'X') == 'B'
assert obs_dict == {}
assert delitem_evt.call_args_list == [(('a', 'A'),), (('b', 'B'),)]
def test_popitem(self):
obs_dict = ObsDict(a='A', b='B')
delitem_evt = Mock()
obs_dict.delitem_evt += delitem_evt
k, v = obs_dict.popitem()
assert v == k.upper()
assert len(obs_dict) == 1
assert delitem_evt.call_args_list == [((k, v),)]
def test_clear(self):
obs_dict = ObsDict(a='A', b='B')
delitem_evt = Mock()
obs_dict.delitem_evt += delitem_evt
obs_dict.clear()
assert delitem_evt.call_args_list == [(('a', 'A'),), (('b', 'B'),)]
def test_update(self):
obs_dict = ObsDict()
setitem_evt = Mock()
obs_dict.setitem_evt += setitem_evt
obs_dict.update({'a': 'A'}, b='B')
obs_dict.update((('c', 'C'),))
assert obs_dict == dict(a='A', b='B', c='C')
assert setitem_evt.call_args_list == [
(('a', None, 'A'),), (('b', None, 'B'),), (('c', None, 'C'),)]
def test_setdefault(self):
obs_dict = ObsDict(a='A')
setitem_evt = Mock()
obs_dict.setitem_evt += setitem_evt
assert obs_dict.setdefault('a') == 'A'
assert obs_dict.setdefault('b', 'B') == 'B'
assert obs_dict == dict(a='A', b='B')
assert setitem_evt.call_args_list == [(('b', None, 'B'),)]
def test_updated_item(self):
obs_dict = ObsDict({'a': 'A', 'b': 'B'})
update_evt = Mock()
obs_dict.update_evt += update_evt
obs_dict.updated_item('b')
assert update_evt.call_args_list == [(('b', 'B'),)]

View file

@ -0,0 +1,111 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
def _callback(*args, **kwds): # pragma: no cover
print ('callback', args, kwds)
def _test_accounts_view(): # pragma: no cover
accounts_view = AccountsView()
Controller(controller.AccountsController, accounts_view)
accounts_view.window.connect('destroy', lambda w: gtk.main_quit())
for i in xrange(10):
accounts_view.accounts.append(("psyc://server/~account%i" % i, True))
accounts_view.accounts[4] = ("psyc://server/~updatedaccount4", False)
#return
from pypsyc.client.model import Account
account = Account(None, "", "", "", False, False)
accounts_view.show_addedit_dialog(account.__dict__, True, _callback)
def _test_tabs_view(): # pragma: no cover
status_icon = gtk.StatusIcon()
status_icon.set_from_file('pypsyc/client/psyc.ico')
status_icon.connect('activate', lambda w: tabs_view.on_status_icon_click())
tabs_view = TabsView(status_icon)
tabs_view.window.connect('destroy', lambda w: gtk.main_quit())
Controller(controller.TabsController, tabs_view)
conversation_view = tabs_view.show_conversation("Conversation 1")
Controller(controller.ConversationController, conversation_view)
tabs_view.focus_tab(conversation_view)
conference_view = tabs_view.show_conference("Conversation 2")
Controller(controller.ConferenceController, conference_view)
def show():
for i in xrange(40):
conversation_view.show_message("Message %02i" % i)
for i in xrange(40):
conference_view.members.append(("psyc://server/~person%02i" % i,
"person%02i" % i))
conference_view.show_message("Message %02i" % i)
conference_view.members[20] = ("psyc://server/~longpersonname20",
"longpersonname20")
idle_add(show)
def _test_dump_view(): # pragma: no cover
dump_view = DumpView()
Controller(controller.DumpController, dump_view)
dump_view.show_line('o', 'a', 'psyc://server/~account')
dump_view.show_line('i', ':_tag_relay\t\xc8\xe6', 'psyc://server/~account')
def _test_main_view(): # pragma: no cover
main_view = MainView()
Controller(controller.MainController, main_view)
Controller(controller.FriendListController, main_view.friends_view)
for i in xrange(40):
main_view.friends_view.friends.append(("Friend %02i" % i, False,
'pending'))
for i in xrange(0, 40, 2):
main_view.friends_view.friends[i] = ("Friend %02i updated" % i, False,
'offered')
for i in xrange(0, 40, 3):
main_view.friends_view.friends[i] = ("Friend %02i updated 2" % i, True,
'established')
#return
account_dict = {'password': '', 'save_password': False}
main_view.show_password_dialog("psyc://server/~account", account_dict,
_callback)
main_view.show_no_such_user("psyc://server/~account")
main_view.show_auth_error("psyc://server/~account", "Error description")
main_view.show_open_conv_dialog(["psyc://server/~person1",
"psyc://server/~person2"], _callback)
main_view.show_open_conf_dialog(["psyc://server/~person1",
"psyc://server/~person2"], _callback)
main_view.show_add_friend_dialog(["psyc://server/~person1",
"psyc://server/~person2"], _callback)
if __name__ == '__main__': # pragma: no cover
class Controller(object):
def __init__(self, controller, view):
self.controller = controller
self.c_name = controller.__name__
view.controller = self
def __getattr__(self, attr):
m = getattr(self.controller, attr, None)
assert m, "%s has no method %s" % (self.c_name, attr)
def f(*args, **kwds):
m_argcount = m.__code__.co_argcount - 1 # minus self
f_argcount = len(args) + len(kwds)
assert m_argcount == f_argcount, \
"%s.%s has %s arguments, called with %s arguments" % (
self.c_name, attr, m_argcount, f_argcount)
print "%s.%s called: %s, %s" % (self.c_name, attr, args, kwds)
return f
from gobject import idle_add
import gtk
from pypsyc.client.view import AccountsView, TabsView, DumpView, MainView
from pypsyc.client import controller
# _test_accounts_view()
# _test_tabs_view()
# _test_dump_view()
# _test_main_view()
gtk.main()

View file

@ -0,0 +1,97 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from nose.tools import assert_raises
from twisted.protocols.loopback import loopbackAsync as loopback_async
from pypsyc.core.mmp import Uni, Header, Circuit
UNI = 'psyc://server/foo/bar'
class TestUni(object):
def test_uni(self):
uni = Uni(UNI)
assert uni == UNI
assert uni.prefix == 'psyc'
def test_parts(self):
uni = Uni(UNI)
assert uni.into_parts() == ['server', 'foo', 'bar']
assert Uni.from_parts(uni.into_parts()) == uni
def test_descendant_ancestor(self):
uni = Uni(UNI)
assert uni.is_descendant_of('psyc://server/foo')
assert not uni.is_descendant_of('psyc://server/spam')
assert uni.is_ancestor_of('psyc://server/foo/bar/child')
assert not uni.is_ancestor_of('psyc://server/spam/eggs/child')
assert uni.is_descendant_of('psyc://server/')
assert Uni('psyc://server/').is_ancestor_of('psyc://server/foo/bar')
def test_chain(self):
assert Uni(UNI).chain('foobar') == 'psyc://server/foo/bar/foobar'
assert Uni('psyc://server/').chain('foo') == 'psyc://server/foo'
class TestHeader(object):
def test_empty(self):
header = Header()
assert header == {}
header._init()
assert header.source is None
assert header.target is None
assert header.context is None
def test_header(self):
header_dict = {
'_source': 'psyc://server/uni1',
'_target': 'psyc://server/uni2',
'_context': 'psyc://server/@place'
}
header = Header(header_dict)
assert header == header_dict
header._init()
assert header.source == Uni('psyc://server/uni1')
assert header.target == Uni('psyc://server/uni2')
assert header.context == Uni('psyc://server/@place')
class TestCircuit(object):
def setup(self):
self.success = False
def test_render_empty(self):
self._test({}, [])
def test_onlyvars(self):
self._test({'_target': 'psyc://example.org/'}, [])
def test_onlycontent(self):
self._test({}, ['content'])
def test_packet(self):
self._test({'_target': 'psyc://example.org/'}, ['content'])
def _test(self, header, content):
def received(header_, content_):
assert header_ == header
assert content_ == content
self.success = True
circuit1 = Circuit()
circuit1.packet_received = received
circuit2 = Circuit()
circuit2.initiator = True
circuit2.inited = lambda: circuit2.send(header, iter(content))
loopback_async(circuit1, circuit2)
assert self.success
def test_subclass(self):
circuit = Circuit()
circuit.lineReceived('|')
assert_raises(NotImplementedError, circuit.lineReceived, '|')

View file

@ -0,0 +1,151 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from mock import Mock
from nose.tools import assert_raises
from tests.constants import USER1_UNI, USER2_UNI
from tests.helpers import check_success, rendered
from pypsyc.core.psyc import PSYCPacket, PSYCObject
from pypsyc.util import schedule
class TestPSYCPacket(object):
def test_vars(self):
packet = PSYCPacket(
modifiers={
':': {'_foo': 'bar'},
'=': {'_spam': 'eggs'}
}
)
self._test(packet, [':_foo\tbar', '=_spam\teggs'])
def test_method(self):
packet = PSYCPacket(mc='_notice_foo')
self._test(packet, ['_notice_foo'])
def test_packet(self):
packet = PSYCPacket(
modifiers={
':': {'_foo': 'bar'}
},
mc='_message_foo',
data='this is\ndata'
)
self._test(packet, [':_foo\tbar', '_message_foo', 'this is\ndata'])
def test_binary1(self):
packet = PSYCPacket({':': {'_foo': 'foo\nbar'}})
self._test(packet, [':_foo 7\tfoo\nbar'])
assert PSYCPacket.parse([':_foo 7\tfoo', 'bar']) == packet
def test_binary2(self):
packet = PSYCPacket({':': {'_foo': 'foo\n\nbar'}})
self._test(packet, [':_foo 8\tfoo\n\nbar'])
assert PSYCPacket.parse([':_foo 8\tfoo', '', 'bar']) == packet
def _test(self, packet, rendered_):
assert PSYCPacket.parse(packet.render()) == packet
assert rendered(packet) == rendered_
def test_nomethod(self):
packet = PSYCPacket(data='foobar')
assert_raises(AssertionError, list, packet.render())
def test_repr(self):
s = '\n'.join((
r"PSYCPacket(",
r" modifiers={",
r" ':': {'_foo': 'bar'},",
r" '=': {'_foo': 'bar'}",
r" },",
r" mc='_message_foo',",
r" data='this is\ndata'",
r")"
))
assert repr(eval(s)) == s
def test_equal(self):
assert PSYCPacket() == PSYCPacket()
assert not PSYCPacket() != PSYCPacket()
def test_empty(self):
packet = PSYCPacket()
self._test(packet, [])
assert packet.modifiers == {':': {}}
assert packet.mc is None
assert packet.data == ''
def test_from_kwds(self):
packet1 = PSYCPacket.from_kwds(mc='_message_public',
data="hello", _somevar='foo')
packet2 = PSYCPacket(mc='_message_public', data="hello",
modifiers={':': {'_somevar': 'foo'}})
assert packet1 == packet2
class TestPSYCObject(object):
def test_handle_packet(self):
psyc = PSYCObject(None)
psyc.handlers['_message'] = message = Mock()
psyc.handlers['_message_public'] = message_public = Mock()
p1 = PSYCPacket() # psyc_packet should return
p2 = PSYCPacket(mc='_message_public')
p3 = PSYCPacket(mc='_message_private')
assert psyc.handle_packet({}, p1.render()) == p1
assert psyc.handle_packet({}, p2.render()) == p2
assert psyc.handle_packet({}, p3.render()) == p3
assert message_public.call_args_list == [((p2,),)]
assert message.call_args_list == [((p3,),)]
def test_handle_packet_internal_error(self):
psyc = PSYCObject(None)
psyc.handlers['_message_public'] = Mock(side_effect=Exception)
packet = PSYCPacket(mc='_message_public')
assert psyc.handle_packet({}, packet.render()) == packet
def test_sendmsg_packet(self):
packet = PSYCPacket()
sendfunc = Mock()
psyc = PSYCObject(sendfunc, USER1_UNI)
psyc.sendmsg(USER2_UNI, packet)
header = {'_source': USER1_UNI, '_target': USER2_UNI}
assert sendfunc.call_args_list == [((header, rendered(packet)),)]
def test_sendmsg_kwds(self):
packet = PSYCPacket({':': {'_somevar': 'foo'}}, mc='_message_private')
sendfunc = Mock()
psyc = PSYCObject(sendfunc, USER1_UNI)
psyc.sendmsg(USER2_UNI, mc='_message_private', _somevar='foo')
header = {'_source': USER1_UNI, '_target': USER2_UNI}
assert sendfunc.call_args_list == [((header, rendered(packet)),)]
@check_success
def test_async(self):
MC = '_request_foo'
ECHO = PSYCPacket(mc='_echo_foo')
o1 = PSYCObject(lambda *args: o2.handle_packet(*args), USER1_UNI)
o2 = PSYCObject(lambda *args: o1.handle_packet(*args), USER2_UNI)
o2.handlers[MC] = lambda _: ECHO
def _test():
ret = o1.sendmsg(USER2_UNI, mc=MC)
assert ret == ECHO
self.success = True
schedule(_test)
def test_async_internal_error(self):
MC = '_request_foo'
ERROR = PSYCPacket(mc='_error_internal')
o1 = PSYCObject(lambda *args: o2.handle_packet(*args), USER1_UNI)
o2 = PSYCObject(lambda *args: o1.handle_packet(*args), USER2_UNI)
o2.handlers[MC] = Mock(side_effect=Exception)
ret = o1.sendmsg(USER2_UNI, mc=MC)
assert ret == ERROR

View file

@ -0,0 +1,396 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
import hmac
from hashlib import sha256
from mock import Mock
from nose.tools import assert_raises
from tests.constants import (SERVER1, USER1, USER2, USER1_UNI, USER2_UNI,
USER1_NICK, RESOURCE, RESOURCE1_UNI, RESOURCE2_UNI, PLACE, PLACE_UNI,
INTERFACE, VARIABLES, PASSWORD, MESSAGE, ONLINE, PENDING, OFFERED,
ESTABLISHED, ERROR)
from tests.helpers import connect_circuits, PlaceHolder
from pypsyc.client.model import ClientCircuit
from pypsyc.core.psyc import PSYCPacket
from pypsyc.protocol import (UnknownTargetError, DeliveryFailedError,
RoutingErrorRoot, RoutingErrorRelaying, RoutingErrorClient,
AuthenticationError, LinkingServer, LinkingClient, Messaging,
MessageRelaying, ConferencingServer, ConferencingClient, EntryDeniedError,
ContextMaster, ContextSlave, UnauthorizedError, ClientInterfaceServer,
ClientInterfaceClient, FriendshipServer, FriendshipClient)
from pypsyc.server import Entity
from pypsyc.server.person import Resource
from pypsyc.server.routing import Routing
def _setup():
server = Mock()
server.hostname = SERVER1
routing = Routing(server.hostname, INTERFACE)
server.routing = routing
routing.init(_entity(server=server))
return routing
def _entity(*args, **kwds):
entity = Entity(*args, **kwds)
entity.package = Mock()
entity.package.entity = entity
return entity
def _c2s_circuit(routing, link_to=None):
sc, cc = connect_circuits(routing.buildProtocol(None), ClientCircuit())
cc.package = Mock()
cc.package.psyc = cc.psyc
if link_to is not None:
Resource(link_to, RESOURCE, sc)
cc.psyc.uni = link_to.uni.chain(RESOURCE)
return sc, cc
def _enter(routing, entity, sc):
routing.mrouting_table[entity.uni].add(sc)
state = entity.context_master.add_member(USER1_UNI)
sc.send({'_context': entity.uni}, PSYCPacket({'=': state}).render())
class TestRoutingErrorProtocol(object):
def setup(self):
routing = _setup()
self.root = routing.root
self.user1 = _entity(routing.root, USER1)
self.sc, self.client = _c2s_circuit(routing, link_to=self.user1)
def test_unknown_target_error(self):
rer = RoutingErrorRoot(self.root.package)
self.client.psyc.add_handler(RoutingErrorClient(self.client.package))
rer.send_unknown_target_error(RESOURCE1_UNI, USER2_UNI)
assert self.client.package.method_calls == [
('unknown_target_error', (USER2_UNI,))]
def test_relay_unknown_target_error1(self):
rer = RoutingErrorRoot(self.root.package)
self.user1.add_handler(RoutingErrorRelaying(self.user1.package))
rer.send_unknown_target_error(USER1_UNI, USER2_UNI)
assert self.user1.package.method_calls == [
('unknown_target_error', (USER2_UNI,))]
def test_relay_unknown_target_error2(self):
rer = RoutingErrorRelaying(self.root.package)
self.client.psyc.add_handler(RoutingErrorClient(self.client.package))
rer.relay_unknown_target_error(RESOURCE1_UNI, USER2_UNI)
assert self.client.package.method_calls == [
('unknown_target_error', (USER2_UNI,))]
def test_delivery_failed_error(self):
rer = RoutingErrorRoot(self.root.package)
self.client.psyc.add_handler(RoutingErrorClient(self.client.package))
rer.send_delivery_failed_error(RESOURCE1_UNI, USER2_UNI, ERROR)
assert self.client.package.method_calls == [
('delivery_failed_error', (USER2_UNI, ERROR))]
def test_relay_delivery_failed_error1(self):
rer = RoutingErrorRoot(self.root.package)
self.user1.add_handler(RoutingErrorRelaying(self.user1.package))
rer.send_delivery_failed_error(USER1_UNI, USER2_UNI, ERROR)
assert self.user1.package.method_calls == [
('delivery_failed_error', (USER2_UNI, ERROR))]
def test_relay_delivery_failed_error2(self):
rer = RoutingErrorRelaying(self.root.package)
self.client.psyc.add_handler(RoutingErrorClient(self.client.package))
rer.relay_delivery_failed_error(RESOURCE1_UNI, USER2_UNI, ERROR)
assert self.client.package.method_calls == [
('delivery_failed_error', (USER2_UNI, ERROR))]
class TestLinkingProtocol(object):
def setup(self):
routing = _setup()
self.user1 = _entity(routing.root, USER1)
self.sc, self.client = _c2s_circuit(routing)
def test_linking(self):
lc = LinkingClient(self.client.package)
self.user1.add_handler(LinkingServer(self.user1.package))
pw = PlaceHolder()
lc.link(USER1_UNI, RESOURCE, PASSWORD)
assert self.user1.package.method_calls == [
('authenticate', (pw, self.sc, RESOURCE))]
assert pw.obj[0] == 'hmac'
assert pw.obj[1] == hmac.new(PASSWORD, pw.obj[2], sha256).digest()
def test_incorrect_password(self):
lc = LinkingClient(self.client.package)
self.user1.add_handler(LinkingServer(self.user1.package))
self.user1.package.authenticate.side_effect = AuthenticationError('xy')
with assert_raises(AuthenticationError) as cm:
lc.link(USER1_UNI, RESOURCE, 'pw')
assert cm.exception.args == ('xy',)
class TestMessagingProtocol(object):
def setup(self):
routing = _setup()
self.user1 = _entity(routing.root, USER1)
self.user2 = _entity(routing.root, USER2)
sc1, self.client1 = _c2s_circuit(routing, link_to=self.user1)
sc2, self.client2 = _c2s_circuit(routing, link_to=self.user2)
def test_private_message(self):
msg1 = Messaging(self.client1.package)
self.client2.psyc.add_handler(Messaging(self.client2.package))
msg1.send_private_message(RESOURCE2_UNI, MESSAGE)
assert self.client2.package.method_calls == [
('private_message', (RESOURCE1_UNI, MESSAGE))]
def test_message_relaying1(self):
msg1 = Messaging(self.client1.package)
self.user1.add_handler(MessageRelaying(self.user1.package))
msg1.send_private_message(USER2_UNI, MESSAGE, relay=USER1_UNI)
assert self.user1.package.method_calls == [
('private_message_relay', (RESOURCE1_UNI, USER2_UNI, MESSAGE))]
def test_message_relaying2(self):
msg_relaying1 = MessageRelaying(self.user1.package)
self.user2.add_handler(MessageRelaying(self.user2.package))
msg_relaying1.send_private_message(USER2_UNI, MESSAGE)
assert self.user2.package.method_calls == [
('private_message', (USER1_UNI, MESSAGE))]
def test_message_relaying3(self):
msg_relaying2 = MessageRelaying(self.user2.package)
self.client2.psyc.add_handler(Messaging(self.client2.package))
msg_relaying2.relay_private_message(USER1_UNI, RESOURCE2_UNI, MESSAGE)
assert self.client2.package.method_calls == [
('private_message', (USER1_UNI, MESSAGE))]
class TestConferencingProtocol(object):
def setup(self):
routing = self.routing = _setup()
self.place = _entity(routing.root, PLACE)
self.user1 = _entity(routing.root, USER1)
self.user2 = _entity(routing.root, USER2)
self.sc1, self.client1 = _c2s_circuit(routing, link_to=self.user1)
self.sc2, self.client2 = _c2s_circuit(routing, link_to=self.user2)
_enter(routing, self.place, self.sc1)
def test_cast_member(self):
con_server = ConferencingServer(self.place.package)
self.client1.add_pvar_handler(ConferencingClient(self.client1.package))
self.client2.add_pvar_handler(ConferencingClient(self.client2.package))
con_server.cast_member_entered(USER1_UNI, USER1_NICK)
assert self.client1.package.method_calls == [
('member_entered', (PLACE_UNI, USER1_UNI, USER1_NICK))]
_enter(self.routing, self.place, self.sc2)
assert self.client2.package.method_calls == [
('member_entered', (PLACE_UNI, USER1_UNI, USER1_NICK))]
self.client1.package.reset_mock()
con_server.cast_member_left(USER1_UNI)
assert self.client1.package.method_calls == [
('member_left', (PLACE_UNI, USER1_UNI))]
def test_public_message1(self):
con_client = ConferencingClient(self.client1.package)
self.place.add_handler(ConferencingServer(self.place.package))
con_client.send_public_message(PLACE_UNI, MESSAGE)
assert self.place.package.method_calls == [
('public_message', (RESOURCE1_UNI, MESSAGE))]
def test_public_message2(self):
con_server = ConferencingServer(self.place.package)
self.client1.psyc.add_handler(ConferencingClient(self.client1.package))
self.client2.psyc.add_handler(ConferencingClient(self.client2.package))
con_server.cast_public_message(USER1_UNI, MESSAGE)
assert self.client1.package.method_calls == [
('public_message', (PLACE_UNI, USER1_UNI, MESSAGE))]
class TestContextProtocol(object):
def setup(self):
routing = _setup()
self.place = _entity(routing.root, PLACE)
self.user1 = _entity(routing.root, USER1)
def test_enter(self):
cs = ContextSlave(self.user1.package)
self.place.add_handler(ContextMaster(self.place.package))
self.place.package.enter_request.return_value = VARIABLES
state = cs.enter(PLACE_UNI)
assert state == VARIABLES
assert self.place.package.method_calls == [
('enter_request', (USER1_UNI,))]
def test_enter_denied(self):
cs = ContextSlave(self.user1.package)
self.place.add_handler(ContextMaster(self.place.package))
self.place.package.enter_request.side_effect = EntryDeniedError('xy')
with assert_raises(EntryDeniedError) as cm:
cs.enter(PLACE_UNI)
assert cm.exception.args == ('xy',)
def test_leave(self):
cs = ContextSlave(self.user1.package)
self.place.add_handler(ContextMaster(self.place.package))
cs.leave(PLACE_UNI)
assert self.place.package.method_calls == [
('leave_context', (USER1_UNI,))]
class TestClientInterface(object):
def setup(self):
routing = self.routing = _setup()
self.user1 = _entity(routing.root, USER1)
_, self.client = _c2s_circuit(routing, link_to=self.user1)
self.client.package.uni = USER1_UNI
self.ci_client = ClientInterfaceClient(self.client.package)
self.user1.add_handler(ClientInterfaceServer(self.user1.package))
def test_unauthorized(self):
user2 = _entity(self.routing.root, USER2)
_, client2 = _c2s_circuit(self.routing, link_to=user2)
client2.package.uni = USER1_UNI
ci_client2 = ClientInterfaceClient(client2.package)
assert_raises(UnauthorizedError, ci_client2.subscribe, PLACE_UNI)
assert self.user1.package.method_calls == []
def test_unknown_target_error(self):
error = UnknownTargetError('xy')
self.user1.package.client_subscribe.side_effect = error
with assert_raises(UnknownTargetError) as cm:
self.ci_client.subscribe(PLACE_UNI)
assert cm.exception.args == ('xy',)
def test_delivery_failed_error(self):
error = DeliveryFailedError('x', 'y')
self.user1.package.client_subscribe.side_effect = error
with assert_raises(DeliveryFailedError) as cm:
self.ci_client.subscribe(PLACE_UNI)
assert cm.exception.args == ('x', 'y')
def test_subscribe(self):
self.ci_client.subscribe(PLACE_UNI)
assert self.user1.package.method_calls == [
('client_subscribe', (PLACE_UNI, RESOURCE1_UNI))]
def test_unsubscribe(self):
self.ci_client.unsubscribe(PLACE_UNI)
assert self.user1.package.method_calls == [
('client_unsubscribe', (PLACE_UNI, RESOURCE1_UNI))]
def test_presence(self):
self.ci_client.cast_presence(ONLINE)
assert self.user1.package.method_calls == [
('client_presence', (ONLINE,))]
def test_add_friend(self):
self.ci_client.add_friend(USER2_UNI)
assert self.user1.package.method_calls == [
('client_add_friend', (USER2_UNI,))]
def test_remove_friend(self):
self.ci_client.remove_friend(USER2_UNI)
assert self.user1.package.method_calls == [
('client_remove_friend', (USER2_UNI,))]
class TestFriendshipProtocol(object):
def setup(self):
routing = _setup()
self.user1 = _entity(routing.root, USER1)
self.user2 = _entity(routing.root, USER2)
sc1, self.client1 = _c2s_circuit(routing, link_to=self.user1)
sc2, self.client2 = _c2s_circuit(routing, link_to=self.user2)
routing.mrouting_table[USER1_UNI] = [sc2]
def test_establish_pending(self):
friendship_server1 = FriendshipServer(self.user1.package)
self.user2.add_handler(FriendshipServer(self.user2.package))
self.user2.package.friendship_request.return_value = PENDING
state = friendship_server1.establish(USER2_UNI)
assert state == PENDING
assert self.user2.package.method_calls == [
('friendship_request', (USER1_UNI,))]
def test_establish_established(self):
friendship_server1 = FriendshipServer(self.user1.package)
self.user2.add_handler(FriendshipServer(self.user2.package))
self.user2.package.friendship_request.return_value = ESTABLISHED
state = friendship_server1.establish(USER2_UNI)
assert state == ESTABLISHED
assert self.user2.package.method_calls == [
('friendship_request', (USER1_UNI,))]
def test_remove(self):
friendship_server1 = FriendshipServer(self.user1.package)
self.user2.add_handler(FriendshipServer(self.user2.package))
friendship_server1.remove(USER2_UNI)
assert self.user2.package.method_calls == [
('friendship_cancel', (USER1_UNI,))]
def test_friendships(self):
friendship_server = FriendshipServer(self.user1.package)
self.client1.psyc.add_handler(FriendshipClient(self.client1.package))
friendship_server.send_friendships(RESOURCE1_UNI, {
USER1_UNI: {'state': ESTABLISHED},
USER2_UNI: {'state': OFFERED}})
friendship_server.send_friendships(RESOURCE1_UNI, {})
assert self.client1.package.method_calls == [
('friendship', (USER1_UNI, ESTABLISHED)),
('friendship', (USER2_UNI, OFFERED))]
def test_updated_friendship(self):
friendship_server = FriendshipServer(self.user1.package)
self.client1.psyc.add_handler(FriendshipClient(self.client1.package))
friendship_server.send_updated_friendship(RESOURCE1_UNI, USER1_UNI,
{'state': 'established'})
assert self.client1.package.method_calls == [
('friendship', (USER1_UNI, ESTABLISHED))]
def test_removed_friendship(self):
friendship_server = FriendshipServer(self.user1.package)
self.client1.psyc.add_handler(FriendshipClient(self.client1.package))
friendship_server.send_removed_friendship(RESOURCE1_UNI, USER1_UNI)
assert self.client1.package.method_calls == [
('friendship_removed', (USER1_UNI,))]
def test_presence(self):
friendship_server = FriendshipServer(self.user1.package)
self.client2.add_pvar_handler(FriendshipClient(self.client2.package))
friendship_server.cast_presence(ONLINE)
assert self.client2.package.method_calls == [
('presence', (USER1_UNI, ONLINE))]

View file

@ -0,0 +1,50 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from greenlet import greenlet
from nose.tools import assert_raises
from tests.helpers import mockify, mockified, check_success
from pypsyc.server.db import Database
class TestDatabase:
def test_sync(self):
db = Database(':memory:')
db.execute('CREATE TABLE test(test TEXT)')
db.execute("INSERT INTO test VALUES ('test')")
result = db.fetch('SELECT test FROM test')
assert result == [('test',)]
assert isinstance(result[0][0], str)
db.stop()
@check_success
@mockified('pypsyc.server.db',['sqlite3', 'Thread', 'reactor'])
def test_async(self, sqlite3, Thread, reactor):
db = Database('')
mockify(db, ['_execute', '_fetch'])
e = Exception()
db._execute.side_effect = e
def f():
assert_raises(Exception, db.execute)
assert db.fetch() == db._fetch.return_value
self.success = True
gl = greenlet(f)
gl.switch()
# emulate reactor calling this methods
gl.throw(e)
gl.switch(db._fetch.return_value)
db.stop()
assert db.thread.method_calls == [('start',), ('join',)]
db.run_async()
assert sqlite3.method_calls == [('connect', ('',))]
assert reactor.method_calls == [
('callFromThread', (gl.throw, e)),
('callFromThread', (gl.switch, db._fetch.return_value))]

View file

@ -0,0 +1,162 @@
"""
::copyright: 2010 by Manuel Jacob
:license: MIT
"""
from mock import Mock
from tests.constants import (SERVER1, SERVER2, SERVER1_UNI, SERVER2_UNI, USER1, USER2,
USER1_UNI, USER2_UNI, RESOURCE, PLACE_UNI, VARIABLES)
from tests.helpers import mockified, rendered
from pypsyc.core.psyc import PSYCPacket
from pypsyc.server import Entity
from pypsyc.server.multicast import ContextSlave
from pypsyc.server.person import Resource
EXTERN_USER_UNI = SERVER2_UNI.chain(USER1)
SET_PACKET = PSYCPacket({'=': VARIABLES})
ADD_PACKET = PSYCPacket({'+': VARIABLES})
REMOVE_PACKET = PSYCPacket({'-': VARIABLES})
class TestContextMaster(object):
def setup(self):
self.server = Mock()
self.server.hostname = SERVER1
self.server.routing.mrouting_table = self.mrouting_table = {}
root = Entity(server=self.server)
self.user1 = Entity(root, USER1)
self.user1.castmsg = Mock()
user2 = Entity(root, USER2)
Resource(user2, RESOURCE, Mock())
def test_extern_member(self):
circuit = Mock()
self.server.routing.srouting_table = {SERVER2: circuit}
self.user1.context_master.add_member(EXTERN_USER_UNI)
assert self.mrouting_table[USER1_UNI] == set([circuit])
self.user1.context_master.remove_member(EXTERN_USER_UNI)
assert self.mrouting_table[USER1_UNI] == set()
def test_set_persistent(self):
self.user1.context_master.state_set(**VARIABLES)
assert self.user1.castmsg.call_args_list == [((SET_PACKET,),),]
state = self.user1.context_master.add_member(USER2_UNI)
assert state == VARIABLES
def test_persistent_list(self):
self.user1.context_master.state_add(**VARIABLES)
assert self.user1.castmsg.call_args_list == [((ADD_PACKET,),)]
self.user1.castmsg.reset_mock()
state = self.user1.context_master.add_member(USER2_UNI)
assert state == VARIABLES
self.user1.context_master.state_remove(**VARIABLES)
assert self.user1.castmsg.call_args_list == [((REMOVE_PACKET,),)]
state = self.user1.context_master.add_member(USER2_UNI)
assert state == {}
def test_remove_inheritance(self):
self.user1.context_master.state_add(_a='a', _a_b='b')
self.user1.context_master.state_remove(_a='a')
state = self.user1.context_master.add_member(USER2_UNI)
assert state == {}
RESOURCE1 = '*resource1'
RESOURCE2 = '*resource2'
USER1_RESOURCE1_UNI = USER1_UNI.chain(RESOURCE1)
USER1_RESOURCE2_UNI = USER1_UNI.chain(RESOURCE2)
class TestContextSlave(object):
@mockified('pypsyc.server.multicast', ['ContextSlaveProtocol'])
def setup(self, ContextSlaveProtocol):
person = Mock()
self.entity = person.entity
self.entity._root.uni = SERVER1_UNI
self.entity.uni = USER1_UNI
self.entity.server.routing.mrouting_table = self.mrouting_table = {}
self.entity.children = {}
self.entity.children[RESOURCE1] = self.resource1 = Mock()
self.entity.children[RESOURCE2] = self.resource2 = Mock()
self.protocol = ContextSlaveProtocol.return_value
self.protocol.enter.return_value = VARIABLES
self.context_slave = ContextSlave(person)
assert ContextSlaveProtocol.call_args_list == [((person,),)]
def test_enter_leave(self):
self.context_slave.enter(PLACE_UNI, USER1_RESOURCE1_UNI)
assert self.protocol.method_calls == [('enter', (PLACE_UNI,))]
assert self.mrouting_table[PLACE_UNI] == set([self.resource1.circuit])
assert self.resource1.circuit.method_calls == [
('send', ({'_context': PLACE_UNI}, rendered(SET_PACKET)))]
self.protocol.reset_mock()
self.context_slave.leave(PLACE_UNI, USER1_RESOURCE1_UNI)
assert self.protocol.method_calls == [('leave', (PLACE_UNI,))]
assert self.mrouting_table[PLACE_UNI] == set()
def test_enter_leave_all_resources(self):
self.context_slave.enter(PLACE_UNI)
assert self.protocol.method_calls == [('enter', (PLACE_UNI,))]
assert self.mrouting_table[PLACE_UNI] == set([self.resource1.circuit,
self.resource2.circuit])
assert self.resource1.circuit.method_calls == [
('send', ({'_context': PLACE_UNI}, rendered(SET_PACKET)),)]
assert self.resource2.circuit.method_calls == [
('send', ({'_context': PLACE_UNI}, rendered(SET_PACKET)),)]
self.protocol.reset_mock()
self.context_slave.leave(PLACE_UNI)
assert self.protocol.method_calls == [('leave', (PLACE_UNI,))]
assert self.mrouting_table[PLACE_UNI] == set()
def test_enter_leave_two_resources(self):
extern_circuit = Mock()
self.mrouting_table[PLACE_UNI] = set([extern_circuit])
self.context_slave.enter(PLACE_UNI, USER1_RESOURCE1_UNI)
self.context_slave.enter(PLACE_UNI, USER1_RESOURCE2_UNI)
assert self.protocol.method_calls == [('enter', (PLACE_UNI,))]
assert self.mrouting_table[PLACE_UNI] == set([extern_circuit,
self.resource1.circuit,
self.resource2.circuit])
assert self.resource1.circuit.method_calls == [
('send', ({'_context': PLACE_UNI}, rendered(SET_PACKET)))]
self.protocol.reset_mock()
self.context_slave.leave(PLACE_UNI, USER1_RESOURCE1_UNI)
assert self.protocol.method_calls == []
self.context_slave.leave(PLACE_UNI, USER1_RESOURCE2_UNI)
assert self.protocol.method_calls == [('leave', (PLACE_UNI,))]
assert self.mrouting_table[PLACE_UNI] == set([extern_circuit])
def test_enter_leave_extern(self):
self.context_slave.enter(EXTERN_USER_UNI, USER1_RESOURCE1_UNI)
assert self.protocol.method_calls == [('enter', (EXTERN_USER_UNI,))]
assert self.mrouting_table[EXTERN_USER_UNI] == \
set([self.resource1.circuit])
assert self.resource1.circuit.method_calls == [
('send', ({'_context':EXTERN_USER_UNI}, rendered(SET_PACKET)))]
self.protocol.reset_mock()
self.context_slave.leave(EXTERN_USER_UNI, USER1_RESOURCE1_UNI)
assert self.protocol.method_calls == [('leave', (EXTERN_USER_UNI,))]
assert EXTERN_USER_UNI not in self.mrouting_table
def test_leave_all(self):
self.context_slave.enter(PLACE_UNI, USER1_RESOURCE1_UNI)
self.protocol.reset_mock()
self.context_slave.leave_all()
assert self.protocol.method_calls == [('leave', (PLACE_UNI,))]
assert self.mrouting_table[PLACE_UNI] == set()
def test_not_leave(self):
self.context_slave.leave(PLACE_UNI)
assert self.protocol.method_calls == []

View file

@ -0,0 +1,268 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
import hmac
from hashlib import sha256
from mock import Mock
from nose.tools import assert_raises
from tests.constants import (SERVER1, USER1, USER1_UNI, USER2_UNI, RESOURCE,
RESOURCE1_UNI, RESOURCE2_UNI, PLACE_UNI, VARIABLES, PASSWORD, MESSAGE,
ONLINE, ERROR)
from tests.helpers import mockified
from pypsyc.protocol import (AuthenticationError, FriendshipPendingError,
FriendshipEstablishedError, EntryDeniedError)
from pypsyc.server import Entity
from pypsyc.server.db import Database
from pypsyc.server.person import Person
class TestPerson(object):
def setup(self):
self.server = Mock()
self.server.hostname = SERVER1
self.server.database = Database(':memory:')
root = Entity(server=self.server)
self.entity = Entity(root, USER1)
@mockified('pypsyc.server.person', ['RoutingErrorRelaying'])
def test_unknown_target_error(self, RoutingErrorRelaying):
RESOURCE1 = USER1_UNI.chain('*resource1')
RESOURCE2 = USER1_UNI.chain('*resource2')
Entity(self.entity, '*resource1')
Entity(self.entity, '*resource2')
routing_error_relaying = RoutingErrorRelaying.return_value
person = Person(self.entity)
assert RoutingErrorRelaying.call_args_list == [((person,),)]
person.unknown_target_error(USER2_UNI)
assert routing_error_relaying.method_calls == [
('relay_unknown_target_error', (RESOURCE1, USER2_UNI)),
('relay_unknown_target_error', (RESOURCE2, USER2_UNI))]
@mockified('pypsyc.server.person', ['RoutingErrorRelaying'])
def test_unknown_target_error(self, RoutingErrorRelaying):
RESOURCE1 = USER1_UNI.chain('*resource1')
RESOURCE2 = USER1_UNI.chain('*resource2')
Entity(self.entity, '*resource1')
Entity(self.entity, '*resource2')
routing_error_relaying = RoutingErrorRelaying.return_value
person = Person(self.entity)
assert RoutingErrorRelaying.call_args_list == [((person,),)]
person.delivery_failed_error(USER2_UNI, ERROR)
assert routing_error_relaying.method_calls == [
('relay_delivery_failed_error', (RESOURCE1, USER2_UNI, ERROR)),
('relay_delivery_failed_error', (RESOURCE2, USER2_UNI, ERROR))]
@mockified('pypsyc.server.person', ['LinkingServer', 'FriendshipProtocol',
'ContextSlave'])
def test_authenticate(self, LinkingServer, FriendshipProtocol,
ContextSlave):
NONCE = 'random_nonce'
DIGEST = hmac.new(PASSWORD, NONCE, sha256).digest()
circuit = Mock()
circuit.allowed_sources = []
friendship_protocol = FriendshipProtocol.return_value
context_slave = ContextSlave.return_value
person = Person(self.entity)
person.register(PASSWORD)
assert LinkingServer.call_args_list == [((person,),)]
assert_raises(AuthenticationError,
person.authenticate, ('hmac', 'wrong', NONCE), None, RESOURCE)
sql = "INSERT INTO friendships VALUES(?, ?, 'established')"
self.server.database.execute(sql, USER1_UNI, USER2_UNI)
person.authenticate(('hmac', DIGEST, NONCE), circuit, RESOURCE)
assert self.entity.children[RESOURCE].circuit == circuit
assert circuit.allowed_sources == [RESOURCE1_UNI]
friendships = {USER2_UNI: {'state': 'established'}}
assert friendship_protocol.method_calls == [
('cast_presence', (7,)),
('send_friendships', (RESOURCE1_UNI, friendships))]
assert context_slave.method_calls == [
('enter', (USER2_UNI, RESOURCE1_UNI))]
friendship_protocol.reset_mock()
context_slave.reset_mock()
person.unlink(RESOURCE)
assert self.entity.children == {}
assert friendship_protocol.method_calls == [('cast_presence', (1,))]
assert context_slave.method_calls == [('leave_all',)]
@mockified('pypsyc.server.person', ['MessageRelaying'])
def test_message_relay(self, MessageRelaying):
message_relaying = MessageRelaying.return_value
person = Person(self.entity)
assert MessageRelaying.call_args_list == [((person,),)]
person.private_message_relay(RESOURCE1_UNI, USER2_UNI, MESSAGE)
person.private_message_relay(RESOURCE2_UNI, USER2_UNI, MESSAGE)
assert message_relaying.method_calls == [
('send_private_message', (USER2_UNI, MESSAGE))]
@mockified('pypsyc.server.person', ['MessageRelaying'])
def test_message(self, MessageRelaying):
RESOURCE1 = USER1_UNI.chain('*resource1')
RESOURCE2 = USER1_UNI.chain('*resource2')
Entity(self.entity, '*resource1')
Entity(self.entity, '*resource2')
message_relaying = MessageRelaying.return_value
person = Person(self.entity)
person.private_message(USER2_UNI, MESSAGE)
assert message_relaying.method_calls == [
('relay_private_message', (USER2_UNI, RESOURCE1, MESSAGE)),
('relay_private_message', (USER2_UNI, RESOURCE2, MESSAGE))]
@mockified('pypsyc.server.person', ['FriendshipProtocol', 'ContextSlave'])
def test_outgoing_friendship(self, FriendshipProtocol, ContextSlave):
friendship_protocol = FriendshipProtocol.return_value
context_slave = ContextSlave.return_value
person = Person(self.entity)
person.register('')
Entity(self.entity, RESOURCE)
person.client_add_friend(USER2_UNI)
fs = {'state': 'pending'}
assert friendship_protocol.method_calls == [
('establish', (USER2_UNI,)),
('send_updated_friendship', (RESOURCE1_UNI, USER2_UNI, fs))]
friendship_protocol.reset_mock()
assert_raises(FriendshipPendingError, person.client_add_friend,
USER2_UNI)
state = person.friendship_request(USER2_UNI)
assert state == 'established'
state = person.friendship_request(USER2_UNI)
assert state == 'established'
fs = {'state': 'established'}
assert friendship_protocol.method_calls == [
('send_updated_friendship', (RESOURCE1_UNI, USER2_UNI, fs))]
assert context_slave.method_calls == [('enter', (USER2_UNI,))]
assert_raises(FriendshipEstablishedError, person.client_add_friend,
USER2_UNI)
@mockified('pypsyc.server.person', ['FriendshipProtocol', 'ContextSlave'])
def test_incoming_friendship(self, FriendshipProtocol, ContextSlave):
friendship_protocol = FriendshipProtocol.return_value
context_slave = ContextSlave.return_value
person = Person(self.entity)
person.register('')
Entity(self.entity, RESOURCE)
state = person.friendship_request(USER2_UNI)
assert state == 'pending'
state = person.friendship_request(USER2_UNI)
assert state == 'pending'
fs = {'state': 'offered'}
assert friendship_protocol.method_calls == [
('send_updated_friendship', (RESOURCE1_UNI, USER2_UNI, fs))]
friendship_protocol.reset_mock()
person.client_add_friend(USER2_UNI)
fs = {'state': 'established'}
assert friendship_protocol.method_calls == [
('establish', (USER2_UNI,)),
('send_updated_friendship', (RESOURCE1_UNI, USER2_UNI, fs))]
assert context_slave.method_calls == [('enter', (USER2_UNI,))]
assert_raises(FriendshipEstablishedError, person.client_add_friend,
USER2_UNI)
@mockified('pypsyc.server.person', ['FriendshipProtocol', 'ContextSlave'])
def test_cancel_friendship(self, FriendshipProtocol, ContextSlave):
friendship_protocol = FriendshipProtocol.return_value
context_slave = ContextSlave.return_value
person = Person(self.entity)
person.register('')
Entity(self.entity, RESOURCE)
person.friendship_cancel(USER2_UNI)
assert context_slave.method_calls == [('leave', (USER2_UNI,))]
assert friendship_protocol.method_calls == [
('send_removed_friendship', (RESOURCE1_UNI, USER2_UNI))]
@mockified('pypsyc.server.person', ['FriendshipProtocol', 'ContextSlave'])
def test_remove_friend(self, FriendshipProtocol, ContextSlave):
friendship_protocol = FriendshipProtocol.return_value
context_slave = ContextSlave.return_value
person = Person(self.entity)
person.register('')
Entity(self.entity, RESOURCE)
person.client_remove_friend(USER2_UNI)
assert context_slave.method_calls == [('leave', (USER2_UNI,))]
assert friendship_protocol.method_calls == [
('remove', (USER2_UNI,)),
('send_removed_friendship', (RESOURCE1_UNI, USER2_UNI))]
@mockified('pypsyc.server.person', ['FriendshipProtocol', 'ContextSlave',
'ContextMasterProtocol'])
def test_enter_context(self, FriendshipProtocol, ContextSlave,
ContextMasterProtocol):
cm = self.entity.context_master = Mock()
cm.add_member.return_value = VARIABLES
person = Person(self.entity)
person.register('')
person.friendship_request(USER2_UNI)
person.client_add_friend(USER2_UNI)
assert ContextMasterProtocol.call_args_list == [((person,),)]
state = person.enter_request(USER2_UNI)
assert state == VARIABLES
assert cm.method_calls == [('add_member', (USER2_UNI,))]
def test_enter_context_entry_denied(self):
person = Person(self.entity)
person.register('')
assert_raises(EntryDeniedError, person.enter_request, USER2_UNI)
def test_leave_context(self):
cm = self.entity.context_master = Mock()
person = Person(self.entity)
person.leave_context(USER2_UNI)
assert cm.method_calls == [('remove_member', (USER2_UNI,))]
@mockified('pypsyc.server.person', ['FriendshipProtocol'])
def test_client_presence(self, FriendshipProtocol):
friendship_protocol = FriendshipProtocol.return_value
person = Person(self.entity)
assert FriendshipProtocol.call_args_list == [((person,),)]
person.client_presence(ONLINE)
assert friendship_protocol.method_calls == [
('cast_presence', (ONLINE,))]
@mockified('pypsyc.server.person', ['ContextSlave',
'ClientInterfaceProtocol'])
def test_client_subscribe(self, ContextSlave, ClientInterfaceProtocol):
context_slave = ContextSlave.return_value
person = Person(self.entity)
assert ContextSlave.call_args_list == [((person,),)]
assert ClientInterfaceProtocol.call_args_list == [((person,),)]
person.client_subscribe(PLACE_UNI, RESOURCE1_UNI)
assert context_slave.method_calls == [
('enter', (PLACE_UNI, RESOURCE1_UNI))]
@mockified('pypsyc.server.person', ['ContextSlave'])
def test_client_unsubscribe(self, ContextSlave):
context_slave = ContextSlave.return_value
person = Person(self.entity)
person.client_unsubscribe(PLACE_UNI, RESOURCE1_UNI)
assert context_slave.method_calls == [
('leave', (PLACE_UNI, RESOURCE1_UNI))]

View file

@ -0,0 +1,68 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from mock import Mock
from tests.constants import (SERVER1, USER1_UNI, USER2_UNI, USER1_NICK,
RESOURCE1_UNI, RESOURCE2_UNI, PLACE, VARIABLES, MESSAGE)
from tests.helpers import mockified
from pypsyc.server import Entity
from pypsyc.server.place import Place
class TestPlace(object):
def setup(self):
self.server = Mock()
self.server.hostname = SERVER1
root = Entity(server=self.server)
self.entity = Entity(root, PLACE)
self.entity.context_master = Mock()
@mockified('pypsyc.server.place', ['ContextProtocol',
'ConferencingProtocol'])
def test_subscription(self, ContextProtocol, ConferencingProtocol):
conferencing_protocol = ConferencingProtocol.return_value
self.entity.context_master.add_member.return_value = VARIABLES
place = Place(self.entity)
assert ContextProtocol.call_args_list == [((place,),)]
state = place.enter_request(USER1_UNI)
assert state == VARIABLES
assert conferencing_protocol.method_calls == [
('cast_member_entered', (USER1_UNI, USER1_NICK))]
assert self.entity.context_master.method_calls == [
('add_member', (USER1_UNI,))]
@mockified('pypsyc.server.place', ['ConferencingProtocol'])
def test_leave(self, ConferencingProtocol):
conferencing_protocol = ConferencingProtocol.return_value
place = Place(self.entity)
place.enter_request(USER1_UNI)
self.entity.context_master.reset_mock()
conferencing_protocol.reset_mock()
place.leave_context(USER1_UNI)
assert self.entity.context_master.method_calls == [
('remove_member', (USER1_UNI,))]
assert conferencing_protocol.method_calls == [
('cast_member_left', (USER1_UNI,))]
@mockified('pypsyc.server.place', ['ConferencingProtocol'])
def test_public_message(self, ConferencingProtocol):
conferencing_protocol = ConferencingProtocol.return_value
place = Place(self.entity)
assert ConferencingProtocol.call_args_list == [((place,),)]
place.enter_request(USER1_UNI)
place.enter_request(USER2_UNI)
place.leave_context(USER2_UNI)
conferencing_protocol.reset_mock()
place.public_message(RESOURCE2_UNI, MESSAGE)
place.public_message(RESOURCE1_UNI, MESSAGE)
assert conferencing_protocol.method_calls == [
('cast_public_message', (USER1_UNI, MESSAGE))]

View file

@ -0,0 +1,21 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from mock import Mock
from tests.constants import SERVER1
from pypsyc.server import Entity
from pypsyc.server.root import Root
class TestRoot(object):
def setup(self):
server = Mock()
server.hostname = SERVER1
root_entity = Entity(server=server)
self.root = Root(root_entity)
def test_root(self):
pass

View file

@ -0,0 +1,353 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from mock import Mock
from nose.tools import assert_raises
from tests.constants import (SERVER1, SERVER2, SERVER1_UNI, SERVER2_UNI,
SERVER3_UNI, USER1, USER2, USER1_UNI, USER2_UNI, RESOURCE, RESOURCE1_UNI,
RESOURCE2_UNI, PLACE_UNI, INTERFACE, IP, PORT, CONTENT)
from tests.helpers import (inited_header, connect_circuits, mockified,
AsyncMethod, PlaceHolder)
from pypsyc.core.mmp import Uni
from pypsyc.protocol import Error
from pypsyc.server.routing import (InvalidTargetError, InvalidSourceError,
ServerCircuit, _TreeNode, Routing)
from pypsyc.util import DNSError
class TestServerCircuit(object):
def setup(self):
self.sc = ServerCircuit()
self.sc.factory = self.routing = Mock()
self.sc.psyc = Mock()
self.sc.allowed_sources.append(SERVER2_UNI)
def _send(self, header):
self.sc.packet_received(inited_header(header), CONTENT)
def test_withtarget(self):
HEADER1 = {'_target': SERVER1_UNI}
HEADER2 = {'_target': SERVER1_UNI, '_source': SERVER2_UNI}
HEADER3 = {'_target': SERVER1_UNI, '_source': SERVER3_UNI}
self._send(HEADER1)
assert self.routing.method_calls == [
('route_singlecast', (HEADER1, CONTENT))]
self._send(HEADER2)
assert self.routing.method_calls == [
('route_singlecast', (HEADER1, CONTENT)),
('route_singlecast', (HEADER2, CONTENT))]
self._send(HEADER3)
assert self.routing.method_calls == [
('route_singlecast', (HEADER1, CONTENT)),
('route_singlecast', (HEADER2, CONTENT))]
def test_withouttarget(self):
HEADER1 = {}
HEADER2 = {'_source': SERVER2_UNI}
HEADER3 = {'_source': SERVER3_UNI}
self._send(HEADER1)
assert self.routing.method_calls == []
assert self.sc.psyc.method_calls == [
('handle_packet', (HEADER1, CONTENT))]
self._send(HEADER2)
assert self.routing.method_calls == []
assert self.sc.psyc.method_calls == [
('handle_packet', (HEADER1, CONTENT)),
('handle_packet', (HEADER2, CONTENT))]
self._send(HEADER3)
assert self.routing.method_calls == []
assert self.sc.psyc.method_calls == [
('handle_packet', (HEADER1, CONTENT)),
('handle_packet', (HEADER2, CONTENT))]
def test_context(self):
HEADER1 = {'_context': PLACE_UNI}
HEADER2 = {'_context': PLACE_UNI, '_target': USER1_UNI}
self._send(HEADER1)
assert self.routing.method_calls == [
('route_multicast', (HEADER1, CONTENT))]
self._send(HEADER2)
assert self.routing.method_calls == [
('route_multicast', (HEADER1, CONTENT)),
('route_singlecast', (HEADER2, CONTENT))]
def test_context_withsource(self):
HEADER1 = {'_context': PLACE_UNI, '_source': USER1_UNI}
HEADER2 = {'_context': PLACE_UNI, '_source': USER2_UNI,
'_target': USER1_UNI}
assert_raises(NotImplementedError, self._send, HEADER1)
assert self.routing.method_calls == []
assert_raises(NotImplementedError, self._send, HEADER2)
assert self.routing.method_calls == []
def test_verification(self):
sc1, sc2 = connect_circuits(ServerCircuit(), ServerCircuit())
sc2.factory = Mock()
sc1.request_verification(SERVER1_UNI, SERVER2_UNI)
assert sc2.factory.method_calls == [
('verify_address', (sc2, SERVER1_UNI, SERVER2_UNI))]
assert type(sc2.factory.method_calls[0][1][1]) is Uni
assert sc1.allowed_sources == [SERVER2_UNI]
assert sc2.allowed_sources == [SERVER1_UNI]
assert type(sc2.allowed_sources[0]) is Uni
def test_verification_invalid_source(self):
sc1, sc2 = connect_circuits(ServerCircuit(), ServerCircuit())
sc2.factory = Mock()
sc2.factory.verify_address.side_effect = InvalidSourceError
assert_raises(InvalidSourceError, sc1.request_verification,
SERVER1_UNI, SERVER2_UNI)
assert sc1.allowed_sources == []
assert sc2.allowed_sources == []
def test_verification_invalid_target(self):
sc1, sc2 = connect_circuits(ServerCircuit(), ServerCircuit())
sc2.factory = Mock()
sc2.factory.verify_address.side_effect = InvalidTargetError
assert_raises(InvalidTargetError, sc1.request_verification,
SERVER1_UNI, SERVER2_UNI)
assert sc1.allowed_sources == []
assert sc2.allowed_sources == []
def test_connection_lost(self):
root = self.routing.root = _TreeNode()
person = Mock()
person_entity = _TreeNode(root, USER1)
person_entity.packages = {'person': person}
self.sc.allowed_sources.append(RESOURCE1_UNI)
self.routing.srouting_table = {SERVER2: Mock()}
self.sc.connectionLost(None)
assert self.routing.srouting_table == {}
assert person.method_calls == [('unlink', (RESOURCE,))]
def test_treenode():
root = _TreeNode()
assert root._root == root
n1 = _TreeNode(root, 'n1')
assert root.children == {'n1': n1}
assert n1._parent == root
assert n1._root == root
n2 = _TreeNode(n1, 'n2')
assert n1.children == {'n2': n2}
assert n2._parent == n1
assert n2._root == root
class StubEntity(_TreeNode):
def __init__(self, *args, **kwds):
_TreeNode.__init__(self, *args, **kwds)
self.headers = []
def handle_packet(self, header, contents):
self.headers.append(header)
EXTERN_HEADER = {'_source': USER1_UNI, '_target': SERVER2_UNI}
class TestRouting(object):
def test_sroute_local(self):
HEADER1 = {'_target': SERVER1_UNI}
HEADER2 = {'_target': USER1_UNI}
HEADER3 = {'_target': RESOURCE2_UNI}
root = StubEntity()
user1 = StubEntity(root, USER1)
user2 = StubEntity(root, USER2)
home = StubEntity(user2, RESOURCE)
routing = Routing(SERVER1, INTERFACE)
routing.init(root)
routing.route_singlecast(inited_header(HEADER1), CONTENT)
routing.route_singlecast(inited_header(HEADER2), CONTENT)
routing.route_singlecast(inited_header(HEADER3), CONTENT)
assert root.headers == [HEADER1]
assert user1.headers == [HEADER2]
assert user2.headers == []
assert home.headers == [HEADER3]
def test_sroute_unkown_target(self):
HEADER1 = inited_header({'_source': USER1_UNI, '_target': USER2_UNI})
HEADER2 = inited_header({'_target': USER2_UNI, '_tag': 'tag'})
KWDS = {'mc': '_error_unknown_target', '_uni': USER2_UNI, 'data': None}
root = StubEntity()
root.sendmsg = Mock()
routing = Routing(SERVER1, INTERFACE)
routing.init(root)
routing.route_singlecast(HEADER1, CONTENT)
routing.route_singlecast(HEADER2, CONTENT)
assert root.sendmsg.call_args_list == [
((USER1_UNI, None, None), KWDS),
((None, None, {'_tag_relay': 'tag'}), KWDS)]
assert root.headers == []
def test_sroute_extern(self):
routing = Routing(SERVER1, INTERFACE)
circuit = routing.srouting_table[SERVER2] = Mock()
routing.route_singlecast(inited_header(EXTERN_HEADER), CONTENT)
assert circuit.method_calls == [(('send'), (EXTERN_HEADER, CONTENT))]
@mockified('pypsyc.server.routing', ['resolve_hostname', 'connect'])
def test_sroute_extern_queued(self, resolve_hostname, connect):
resolve_hostname.return_value = IP, PORT
connected = connect.side_effect = AsyncMethod()
root = Mock()
root.uni = SERVER1_UNI
routing = Routing(SERVER1, INTERFACE)
routing.init(root)
routing.route_singlecast(inited_header(EXTERN_HEADER), CONTENT)
routing.route_singlecast(inited_header(EXTERN_HEADER), CONTENT)
assert connect.call_args_list == [
((IP, PORT, routing), {'bindAddress': (INTERFACE, 0)})]
circuit = Mock()
connected.callback(circuit)
assert circuit.method_calls == [
('request_verification', (SERVER1_UNI, SERVER2_UNI)),
('send', (EXTERN_HEADER, CONTENT)),
('send', (EXTERN_HEADER, CONTENT))]
assert type(circuit.method_calls[0][1][1]) is Uni
assert routing.srouting_table == {SERVER2: circuit}
assert routing.queues == {}
@mockified('pypsyc.server.routing', ['resolve_hostname'])
def test_sroute_extern_resolution_fail(self, resolve_hostname):
KWDS = {'mc': '_failure_unsuccessful_delivery', '_uni': SERVER2_UNI}
resolved = resolve_hostname.side_effect = AsyncMethod()
data_ph = KWDS['data'] = PlaceHolder()
root = Mock()
routing = Routing(SERVER1, INTERFACE)
routing.init(root)
routing.route_singlecast(inited_header(EXTERN_HEADER), CONTENT)
routing.route_singlecast(inited_header(EXTERN_HEADER), CONTENT)
resolved.errback(DNSError)
assert root.method_calls == [
('sendmsg', (USER1_UNI, None, None), KWDS)] * 2
assert 'resolve' in data_ph.obj
assert routing.queues == {}
@mockified('pypsyc.server.routing', ['resolve_hostname', 'connect'])
def test_sroute_extern_connection_fail(self, resolve_hostname, connect):
KWDS = {'mc': '_failure_unsuccessful_delivery', '_uni': SERVER2_UNI}
resolve_hostname.return_value = None, None
connected = connect.side_effect = AsyncMethod()
data_ph = KWDS['data'] = PlaceHolder()
root = Mock()
routing = Routing(SERVER1, INTERFACE)
routing.init(root)
routing.route_singlecast(inited_header(EXTERN_HEADER), CONTENT)
connected.errback(Exception('error'))
assert root.method_calls == [
('sendmsg', (USER1_UNI, None, None), KWDS)]
assert 'connect' in data_ph.obj
assert routing.queues == {}
@mockified('pypsyc.server.routing', ['resolve_hostname', 'connect'])
def test_sroute_extern_verification_fail(self, resolve_hostname, connect):
KWDS = {'mc': '_failure_unsuccessful_delivery', '_uni': SERVER2_UNI}
resolve_hostname.return_value = None, None
circuit = connect.return_value
verified = circuit.request_verification.side_effect = AsyncMethod()
data_ph = KWDS['data'] = PlaceHolder()
root = Mock()
routing = Routing(SERVER1, INTERFACE)
routing.init(root)
routing.route_singlecast(inited_header(EXTERN_HEADER), CONTENT)
verified.errback(Error)
assert root.method_calls == [
('sendmsg', (USER1_UNI, None, None), KWDS)]
assert 'verify' in data_ph.obj
assert routing.queues == {}
@mockified('pypsyc.server.routing', ['resolve_hostname', 'connect'])
def test_sroute_extern_no_source(self, resolve_hostname, connect):
header = inited_header({'_target': SERVER2_UNI})
header.source = Mock()
routing = Routing(SERVER1, INTERFACE)
routing.route_singlecast(header, CONTENT)
header['_source'] = ''
routing.route_singlecast(header, CONTENT)
assert resolve_hostname.call_args_list == []
assert connect.call_args_list == []
assert routing.srouting_table == {}
assert routing.queues == {}
def test_mroute(self):
HEADER = {'_context': PLACE_UNI}
circuit1 = Mock()
circuit2 = Mock()
routing = Routing(SERVER1, INTERFACE)
routing.mrouting_table[PLACE_UNI] = [circuit1, circuit2]
routing.route_multicast(inited_header(HEADER), iter(CONTENT))
assert circuit1.method_calls == [('send', (HEADER, CONTENT))]
assert circuit2.method_calls == [('send', (HEADER, CONTENT))]
@mockified('pypsyc.server.routing', ['reactor'])
def test_listen(self, reactor):
routing = Routing(SERVER1, INTERFACE)
routing.listen(PORT)
assert reactor.method_calls == [
('listenTCP', (PORT, routing), {'interface': INTERFACE})]
def _setup_verification(self):
root = Mock()
root.uni = SERVER1_UNI
routing = Routing(SERVER1, INTERFACE)
routing.init(root)
circuit = Mock()
circuit.transport.client = IP, 35771
return routing, circuit
@mockified('pypsyc.server.routing', ['resolve_hostname'])
def test_verification(self, resolve_hostname):
resolve_hostname.return_value = IP, PORT
routing, circuit = self._setup_verification()
routing.verify_address(circuit, SERVER2_UNI, SERVER1_UNI)
assert resolve_hostname.call_args_list == [((SERVER2,),)]
assert routing.srouting_table == {SERVER2: circuit}
@mockified('pypsyc.server.routing', ['resolve_hostname'])
def test_verification_invalid_target(self, resolve_hostname):
routing, circuit = self._setup_verification()
assert_raises(InvalidTargetError, routing.verify_address,
circuit, SERVER2_UNI, SERVER3_UNI)
assert resolve_hostname.call_args_list == []
assert routing.srouting_table == {}
@mockified('pypsyc.server.routing', ['resolve_hostname'])
def test_verification_invalid_source(self, resolve_hostname):
resolve_hostname.return_value = '10.0.0.2', PORT
routing, circuit = self._setup_verification()
assert_raises(InvalidSourceError, routing.verify_address,
circuit, SERVER2_UNI, SERVER1_UNI)
assert resolve_hostname.call_args_list == [((SERVER2,),)]
assert routing.srouting_table == {}

View file

@ -0,0 +1,134 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from contextlib import contextmanager
from mock import Mock
from nose.tools import assert_raises
from tests.constants import (SERVER1, SERVER1_UNI, USER1, USER1_UNI, PLACE,
INTERFACE, PORT, PASSWORD)
from tests.helpers import mockified, rendered, AsyncMethod
from pypsyc.core.psyc import PSYCPacket
from pypsyc.server import Entity, Server
from pypsyc.server.routing import _TreeNode
class TestEntity(object):
def setup(self):
self.server = Mock()
self.server.hostname = SERVER1
self.entity = Entity(server=self.server)
def test_uni(self):
assert self.entity.uni == SERVER1_UNI
assert Entity(self.entity, USER1).uni == USER1_UNI
def test_castmsg(self):
HEADER = {'_context': self.entity.uni}
PACKET = PSYCPacket(mc='_message_public', data="Hello")
self.entity.castmsg(PACKET)
assert self.server.routing.method_calls == [
('route_multicast', (HEADER, rendered(PACKET)))]
def test_castmsg_kwds(self):
HEADER = {'_context': self.entity.uni}
PACKET = PSYCPacket(mc='_message_public', data="Hello")
self.entity.castmsg(mc='_message_public', data="Hello")
assert self.server.routing.method_calls == [
('route_multicast', (HEADER, rendered(PACKET)))]
def StubEntity(*args, **kwds):
entity = _TreeNode(*args, **kwds)
entity.packages = {}
return entity
class TestServer(object):
@mockified('pypsyc.server', ['Routing', 'Entity', 'run_webif', 'signal'])
def test_server1(self, Routing, Entity, run_webif, signal):
WEBIF_PORT = 8080
routing = Routing.return_value
root = Entity.return_value = StubEntity()
run_webif.side_effect = AsyncMethod()
server = Server(SERVER1, INTERFACE, PORT, WEBIF_PORT, ':memory:')
assert Routing.call_args_list == [((SERVER1, INTERFACE),)]
assert Entity.call_args_list == [({'server': server},)]
assert routing.method_calls == [('init', (root,)), ('listen', (PORT,))]
assert run_webif.call_args_list == [
((server, INTERFACE, WEBIF_PORT, None),)]
assert signal.signal.called
with mockified('pypsyc.server', ['iter_entry_points', 'Entity']) as x:
with self._test_load_package(root, *x) as packages:
assert server.add_package(None, 'package') == packages[0]
assert server.add_place('place') == packages[1]
assert server.add_package(PLACE, 'package') == packages[2]
assert server.add_package(USER1, 'package') == packages[3]
person = server.register_person('user1', PASSWORD)
assert person == packages[4]
assert person.method_calls == [('register', (PASSWORD,))]
assert_raises(AssertionError, server.add_package, None, 'package')
self._test_server2(server.database)
@mockified('pypsyc.server', ['Routing', 'Entity', 'Database', 'run_webif'])
def _test_server2(self, database, Routing, Entity, Database, run_webif):
routing = Routing.return_value
root = Entity.return_value = StubEntity()
Database.return_value = database
executed = database.execute = AsyncMethod()
server = Server(SERVER1, INTERFACE, 0, 0, ':memory:')
assert routing.method_calls == [('init', (root,))]
assert run_webif.call_args_list == []
with mockified('pypsyc.server', ['iter_entry_points', 'Entity']) as x:
with self._test_load_package(root, *x):
executed.callback()
assert_raises(AssertionError, server.add_package, None, 'package1')
@contextmanager
def _test_load_package(self, root, iter_entry_points, Entity):
package_classes = [Mock(), Mock(), Mock(), Mock(), Mock()]
entrypoint = Mock()
entrypoint.load.side_effect = iter(package_classes).next
iter_entry_points.return_value = [entrypoint]
Entity.side_effect = StubEntity
packages = [package.return_value for package in package_classes]
yield packages
assert Entity.call_args_list == [((root, PLACE),), ((root, USER1),)]
assert iter_entry_points.call_args_list == [
(('pypsyc.server.packages', 'package'),),
(('pypsyc.server.packages', 'place'),),
(('pypsyc.server.packages', 'package'),),
(('pypsyc.server.packages', 'package'),),
(('pypsyc.server.packages', 'person'),)]
place = root.children[PLACE]
person = root.children[USER1]
assert package_classes[0].call_args_list == [((root,),)]
assert package_classes[1].call_args_list == [((place,),)]
assert package_classes[2].call_args_list == [((place,),)]
assert package_classes[3].call_args_list == [((person,),)]
assert package_classes[4].call_args_list == [((person,),)]
assert root.packages == {'package': packages[0]}
assert place.packages == {'place': packages[1], 'package': packages[2]}
assert person.packages == {'package': packages[3],
'person': packages[4]}
@mockified('pypsyc.server', ['Routing', 'Entity', 'Database', 'signal',
'reactor'])
def test_shutdown(self, Routing, Entity, Database, signal, reactor):
database = Database.return_value
database.fetch.return_value = ()
server = Server(SERVER1, INTERFACE, 0, 0, ':memory')
database.reset_mock()
server.shutdown()
assert database.method_calls == [('stop',)]
assert reactor.method_calls == [('stop',)]

View file

@ -0,0 +1,139 @@
"""
:copyright: 2010 by Manuel Jacob
:license: MIT
"""
from mock import Mock, sentinel
from nose.tools import assert_raises
from tests.constants import USER1, USER1_NICK, PASSWORD
from tests.helpers import mockified, PlaceHolder
from pypsyc.server import webif
from pypsyc.server.db import Database
from pypsyc.server.webif import app, PersistentStore, run_webif
class TestViews(object):
@classmethod
def setup_class(cls):
app.secret_key = 'testing key'
def setup(self):
self.server = webif.server = Mock()
self.server.root.children = {}
self.client = app.test_client()
def test_index(self):
rv = self.client.get('/')
assert 'register' in rv.data
def _register(self, username, password, password2):
return self.client.post('/register', data=dict(
username=username, password=password, password2=password2
), follow_redirects=True)
def test_register_get(self):
rv = self.client.get('/register')
assert 'Username' in rv.data
assert 'Register' in rv.data
def test_register_post(self):
rv = self._register(USER1_NICK, PASSWORD, PASSWORD)
assert 'you were registered' in rv.data
assert self.server.method_calls == [
('register_person', (USER1_NICK, PASSWORD))]
def test_register_nousername(self):
rv = self._register('', '', '')
assert 'please specify a valid username' in rv.data
def test_register_username_inuse(self):
self.server.root.children = {USER1: True}
rv = self._register(USER1_NICK, '', '')
assert 'username already in use' in rv.data
def test_register_nopassword(self):
rv = self._register(USER1_NICK, '', '')
assert 'your password must have at least 6 characters' in rv.data
def test_register_shortpassword(self):
rv = self._register(USER1_NICK, 'passw', 'passw')
assert 'your password must have at least 6 characters' in rv.data
def test_register_unmatching_passwords(self):
rv = self._register(USER1_NICK, PASSWORD, 'password2')
assert 'the two passwords do not match' in rv.data
def test_persistent_store():
webif.server = Mock()
webif.server.database = Database(':memory:')
store = PersistentStore()
assert_raises(KeyError, store.__getitem__, 'key')
assert dict(store) == {}
assert len(store) == 0
store['key'] = 'value'
assert store['key'] == 'value'
assert len(store) == 1
store['key'] = 'value2'
assert dict(store) == {'key': 'value2'}
assert len(store) == 1
del store['key']
assert dict(store) == {}
assert len(store) == 0
@mockified('pypsyc.server.webif', ['PersistentStore', 'urandom',
'WSGIResource', 'Site', 'reactor',
'greenlet'])
def test_run_webif_ssl(PersistentStore, urandom, WSGIResource, Site, reactor,
greenlet):
store = PersistentStore.return_value = {'secret_key': 'key1'*5}
reactor_ph = PlaceHolder()
threadpool_ph = PlaceHolder()
wsgi_resource = WSGIResource.return_value
site = Site.return_value
run_webif(sentinel.server, sentinel.interface, sentinel.port,
sentinel.context_factory)
assert webif.server == sentinel.server
assert PersistentStore.call_args_list == [()]
assert webif.store == store
assert app.secret_key == 'key1'*5
assert not urandom.called
assert WSGIResource.call_args_list == [
((reactor_ph, threadpool_ph, app.wsgi_app),)]
assert Site.call_args_list == [((wsgi_resource,),)]
assert reactor.method_calls == [
('listenSSL', (sentinel.port, site, sentinel.context_factory),
{'interface': sentinel.interface})]
func = Mock()
reactor_ph.obj.callFromThread(func, sentinel.a, b=sentinel.b)
assert func.call_args_list == [((sentinel.a,), {'b': sentinel.b})]
threadpool_ph.obj.callInThread(sentinel.func, sentinel.a, b=sentinel.b)
assert greenlet.call_args_list == [((sentinel.func,),)]
assert greenlet.return_value.method_calls == [
('switch', (sentinel.a,), {'b': sentinel.b})]
@mockified('pypsyc.server.webif', ['PersistentStore', 'urandom',
'WSGIResource', 'Site', 'reactor'])
def test_run_webif_tcp(PersistentStore, urandom, WSGIResource, Site, reactor):
store = PersistentStore.return_value = {}
rand = urandom.return_value = 'key2'*5
wsgi_resource = WSGIResource.return_value
site = Site.return_value
run_webif(sentinel.server, sentinel.interface, sentinel.port, None)
assert urandom.call_args_list == [((20,),)]
assert app.secret_key == rand
assert store['secret_key'] == rand
assert Site.call_args_list == [((wsgi_resource,),)]
assert reactor.method_calls == [
('listenTCP', (sentinel.port, site), {'interface': 'localhost'})]

206
mjacob2/tests/test_util.py Normal file
View file

@ -0,0 +1,206 @@
"""
: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})]