def __init__(self, router, interface, controller, filter='.*', encryptor_cache=None, make_jack=True): Client.__init__(self, router, interface, encryptor_cache, make_jack) self.controller = py_address(controller) self.set_filter(filter)
def __init__(self, router, interface, **kwargs): Client.__init__(self, router, interface, **kwargs) self.client_data = {} self.default_data = { 'messages': {}, 'chopping_block': [], 'status': { 'total_count': 1000, 'total_space': 32 * 1024, # 32kb of space default 'used_count': 0, 'used_space': 0, }, }
def setUp(self): # Reuse setup, without being subclass and pulling in tests DexterCommandTester.setUp(self) self.j_loc = ["local", None, "jackson"] self.t_loc = ["local", None, "tealc"] self.interface.data = { "identity": self.j_loc, "idcache": { '["local",null,"jackson"]': { "location": self.j_loc, "name": "*****@*****.**", "encryptor": ["rotate", 4], }, '["local",null,"tealc"]': {"location": self.t_loc, "name": "*****@*****.**", "encryptor": ["rotate", 5]}, }, "docname": "example", "docserialized": handler_document("echo_chamber").serialize(), } with self.io: self.interface.do_command("dinit") self.router = self.interface.owner.router self.tealc = Client(self.router, self.t_loc, self.interface.owner.identities) self.daniel = self.interface.owner.client
def __init__(self, interface, router=None, cpsdesc=None): self.interface = interface self.router = router or Router() self.client = Client(self.router, self.interface) self.client.rcv_callback = self.rcv_callback self.cpsdesc = cpsdesc or ('ramdict', ['rotate', 0]) self.storage = Storage([self.cpsdesc]) self.unread = {} self.conversations = {}
def test_sig_verify(self): client = Client(None, ['demo_interface']) client.encryptor_set(client.interface, ['rotate', 41]) original = ['catamaran'] self.assertTrue( client.sig_verify(original, client.interface, client.sign(original)))
def test_client_already_loaded(self): from ejtp.client import Client client = Client(None, (4, 5, 6), make_jack=False) self.router._loadclient(client) self.assertRaisesRegexp(ValueError, 'client already loaded', self.router._loadclient, client)
def test_clients_chat(self): router = Router() c1 = Client(router, ['udp', ['127.0.0.1', 555], 'c1'], make_jack=False) c2 = Client(router, ['udp', ['127.0.0.1', 555], 'c2'], make_jack=False) c1.encryptor_cache = c2.encryptor_cache # Let's only set this stuff once c1.encryptor_set(c1.interface, ['rotate', 3]) c1.encryptor_set(c2.interface, ['rotate', -7]) self.assertEqual(c1.router, c2.router) c1.write_json(c2.interface, "hello") c2.write_json(c1.interface, "goodbye") self.assertInLog( "Client ['udp', ['127.0.0.1', 555], 'c2'] recieved from ['udp', ['127.0.0.1', 555], 'c1']: JSONFrame: RawData((0x6a,0x0,0x22,0x68,0x65,0x6c,0x6c,0x6f,0x22))" ) self.assertInLog( "Client ['udp', ['127.0.0.1', 555], 'c1'] recieved from ['udp', ['127.0.0.1', 555], 'c2']: JSONFrame: RawData((0x6a,0x0,0x22,0x67,0x6f,0x6f,0x64,0x62,0x79,0x65,0x22))" )
class TestDexterDEJEGroupInitialized(DexterCommandTester): def setUp(self): # Reuse setup, without being subclass and pulling in tests DexterCommandTester.setUp(self) self.j_loc = ["local", None, "jackson"] self.t_loc = ["local", None, "tealc"] self.interface.data = { "identity": self.j_loc, "idcache": { '["local",null,"jackson"]': { "location": self.j_loc, "name": "*****@*****.**", "encryptor": ["rotate", 4], }, '["local",null,"tealc"]': {"location": self.t_loc, "name": "*****@*****.**", "encryptor": ["rotate", 5]}, }, "docname": "example", "docserialized": handler_document("echo_chamber").serialize(), } with self.io: self.interface.do_command("dinit") self.router = self.interface.owner.router self.tealc = Client(self.router, self.t_loc, self.interface.owner.identities) self.daniel = self.interface.owner.client def test_basic_assertions(self): self.assertEqual(self.tealc.encryptor_cache, self.daniel.encryptor_cache) def test_enact_event_signal(self): class DemoActionIshThing(object): def hash(self): return String("123456789ABCDEFG") with self.io: signal = self.interface.document.signals["enact-event"] signal.send(DemoActionIshThing()) self.assertEqual(self.interface.get_view("doc").contents, ["Applied event (hash 123456789A...)"]) def test_msg_external_str(self): with self.io: self.tealc.write_json(self.j_loc, "Hello, world") self.assertEqual( self.interface.view.contents, [ "msglog> dinit", "DEJE initialized", '["local",null,"tealc"] : <could not parse>', '["local",null,"jackson"] (ME) : deje-error', ], ) def test_msg_external_map(self): with self.io: self.tealc.write_json(self.j_loc, {"type": "example"}) self.assertEqual( self.interface.view.contents, [ "msglog> dinit", "DEJE initialized", '["local",null,"tealc"] : example', '["local",null,"jackson"] (ME) : deje-error', ], ) def test_msg_external_valid(self): rcvd = [] self.tealc.rcv_callback = lambda msg, client: rcvd.append(msg) with self.io: self.tealc.write_json(self.j_loc, {"type": "deje-sub-list-query", "qid": 5}) self.assertEqual( self.interface.view.contents, [ "msglog> dinit", "DEJE initialized", '["local",null,"tealc"] : deje-sub-list-query', '["local",null,"jackson"] (ME) : deje-sub-list-response', ], ) self.assertEqual(rcvd.pop().unpack(), {"type": "deje-sub-list-response", "qid": 5, "subs": {}}) def test_msg_sent_str(self): with self.io: self.interface.owner.client.write_json(self.t_loc, "Not even a mapping") self.assertEqual( self.interface.view.contents, ["msglog> dinit", "DEJE initialized", '["local",null,"jackson"] (ME) : <msg type not provided>'], ) def test_msg_sent_map(self): with self.io: self.interface.owner.client.write_json(self.t_loc, {"Does not have": "a type key"}) self.assertEqual( self.interface.view.contents, ["msglog> dinit", "DEJE initialized", '["local",null,"jackson"] (ME) : <msg type not provided>'], ) def test_msg_sent_valid(self): with self.io: self.interface.owner.client.write_json(self.t_loc, {"type": "example"}) self.assertEqual( self.interface.view.contents, ["msglog> dinit", "DEJE initialized", '["local",null,"jackson"] (ME) : example'], ) def test_msg_solo_transmit(self): with self.io: self.interface.owner.transmit(self.interface.document, "example", {}, participants=True, subscribers=False) self.assertEqual( self.interface.view.contents, [ "msglog> dinit", "DEJE initialized", '["local",null,"jackson"] (ME) : example', '["local",null,"jackson"] : example', '["local",null,"jackson"] (ME) : deje-error', '["local",null,"jackson"] : deje-error', ], ) def test_devent_wrong_num_args(self): with self.io: self.interface.do_command("devent") self.interface.do_command("devent a b") self.assertEqual( self.interface.view.contents, [ "msglog> dinit", "DEJE initialized", "msglog> devent", "devent takes exactly 1 arg(s), got 0", "msglog> devent a b", "devent takes exactly 1 arg(s), got 2", ], ) def test_devent_no_such_var(self): with self.io: self.interface.do_command("devent eventstuff") self.assertEqual( self.interface.get_view("msglog").contents, ["msglog> dinit", "DEJE initialized", "msglog> devent eventstuff", "No such variable 'eventstuff'"], ) def test_devent(self): with self.io: self.interface.data["eventstuff"] = "example" self.interface.do_command("devent eventstuff") self.assertEqual( self.interface.get_view("msglog").contents, [ "msglog> dinit", "DEJE initialized", "msglog> devent eventstuff", '["local",null,"jackson"] (ME) : deje-paxos-accept', '["local",null,"jackson"] : deje-paxos-accept', '["local",null,"jackson"] (ME) : deje-paxos-accepted', '["local",null,"jackson"] : deje-paxos-accepted', '["local",null,"jackson"] (ME) : deje-paxos-complete', '["local",null,"jackson"] : deje-paxos-complete', '["local",null,"jackson"] (ME) : deje-action-completion', '["local",null,"jackson"] : deje-action-completion', '["local",null,"jackson"] (ME) : deje-paxos-accepted', '["local",null,"jackson"] : deje-paxos-accepted', ], ) self.assertEqual(self.interface.get_view("doc").contents, ["Applied event (hash 56c9a782dc...)"]) self.assertEqual(self.interface.get_view("dbg").contents, ["Event 'example' achieved."]) def test_dget_latest(self): with self.io: self.interface.do_command("dget_latest") self.assertEqual( self.interface.get_view("msglog").contents, [ "msglog> dinit", "DEJE initialized", "msglog> dget_latest", '["local",null,"jackson"] (ME) : deje-paxos-accept', '["local",null,"jackson"] : deje-paxos-accept', '["local",null,"jackson"] (ME) : deje-paxos-accepted', '["local",null,"jackson"] : deje-paxos-accepted', '["local",null,"jackson"] (ME) : deje-paxos-complete', '["local",null,"jackson"] : deje-paxos-complete', '["local",null,"jackson"] (ME) : deje-action-completion', '["local",null,"jackson"] : deje-action-completion', '["local",null,"jackson"] (ME) : deje-paxos-accepted', '["local",null,"jackson"] : deje-paxos-accepted', ], ) # Nnreaaagghhh Python 2 doc_contents = self.interface.get_view("doc").contents self.assertEqual(len(doc_contents), 1) self.assertIn( doc_contents.pop(), ["Document latest version is 'current'", "Document latest version is u'current'"] ) self.assertEqual(self.interface.get_view("dbg").contents, []) def test_dvexport_wrong_num_args(self): with self.io: self.interface.do_command("dvexport") self.interface.do_command("dvexport a b") self.assertEqual( self.interface.view.contents, [ "msglog> dinit", "DEJE initialized", "msglog> dvexport", "dvexport takes exactly 1 arg(s), got 0", "msglog> dvexport a b", "dvexport takes exactly 1 arg(s), got 2", ], ) def test_dvexport(self): with self.io: self.interface.do_command("dvexport x") self.assertEqual(self.interface.view.contents, ["msglog> dinit", "DEJE initialized", "msglog> dvexport x"]) self.assertEqual(self.interface.data["x"], self.interface.document.serialize()) def test_dexport_wrong_num_args(self): with self.io: self.interface.do_command("dexport") self.interface.do_command("dexport a b") self.assertEqual( self.interface.view.contents, [ "msglog> dinit", "DEJE initialized", "msglog> dexport", "dexport takes exactly 1 arg(s), got 0", "msglog> dexport a b", "dexport takes exactly 1 arg(s), got 2", ], ) def test_dexport(self): with Tempfile() as fname: cmd = "dexport " + fname with self.io: self.interface.do_command(cmd) written = open(fname, "r").read() self.assertEqual(json.loads(written), self.interface.document.serialize()) self.assertEqual(self.interface.view.contents, ["msglog> dinit", "DEJE initialized", "msglog> " + cmd])
def __init__(self, *args, **kwargs): Client.__init__(self, *args, **kwargs) self.callbacks = {}
class Mailbox(object): ''' Class for persistent mail storage. >>> m = Mailbox(['udp4', ['localhost',9001], 'ejmail-test']) >>> m.interface ['udp4', ['localhost', 9001], 'ejmail-test'] >>> m.router #doctest: +ELLIPSIS <ejtp.router.Router object at ...> >>> m.cpsdesc ('ramdict', ['rotate', 0]) >>> m.storage #doctest: +ELLIPSIS <dbcps.storage.Storage object at ...> ''' def __init__(self, interface, router=None, cpsdesc=None): self.interface = interface self.router = router or Router() self.client = Client(self.router, self.interface) self.client.rcv_callback = self.rcv_callback self.cpsdesc = cpsdesc or ('ramdict', ['rotate', 0]) self.storage = Storage([self.cpsdesc]) self.unread = {} self.conversations = {} def recv(self, data, addr=None): ''' Interpret an email recieved through EJTP client. >>> m = Mailbox(['udp4', ['localhost',9002], 'ejmail-test']) >>> m.add_conversation("Demonstration") # Add ahead of time so we can set callback >>> def msgcallback(msg): ... print msg.hash ... print msg.content >>> m.conversations["Demonstration"].on_message = msgcallback >>> m.recv({'conversation':'Demonstration', 'content':'Demo content', 'timecode':'not an automatic one'}) 65d35f7482c0c610ada04ff4e7bf4fa66f4769dd Demo content ''' message = Message(data) if addr: self.ack(message, addr) convo = message.conversation self.add_conversation(convo) convo_obj = self.conversations[convo] convo_obj.register_message(message) convo_obj.on_message(message) self.storage[message.hash] = str(message) def add_conversation(self, name): ''' Set up a Conversation object for this mailbox. This is called by self.recv automatically. ''' if not name in self.conversations: self.conversations[name] = Conversation(name) def rcv_callback(self, msg, client): ''' Callback for EJTP client. TODO: Filter out messages where EJTP sender does not match "from" field. ''' msg_dict = json.loads(msg.content) msg_type = msg_dict['type'] msg_data = msg_dict['data'] if msg_type == "ejmail-message": self.recv(msg_data, msg.addr) elif msg_type == "ejmail-mark": saddr = address.str_address(msg.addr) for hash in msg_data: del self.unread[saddr][hash] for unread in self.unread[saddr].values(): self.send(unread, [('Retrying send...', saddr)]) def send(self, msg, recipients=None): ''' Send ejmail.message.Message object to its recipients. >>> import time >>> m3addr = ['udp4', ['localhost',9003], 'britta'] >>> m4addr = ['udp4', ['localhost',9004], 'jeff'] >>> m3 = Mailbox(m3addr) >>> m4 = Mailbox(m4addr) >>> m4.client.encryptor_cache = m3.client.encryptor_cache >>> m3.client.encryptor_set(m3addr, ['rotate', 5]) >>> m3.client.encryptor_set(m4addr, ['rotate', -14]) >>> msg = Message({ ... 'to':[['Jeff Winger', m4addr]], ... 'from':['Britta Perry', m3addr], ... 'conversation':'Wazzaaaappp', ... 'content':"I'm druunnkkkk", ... }) >>> m3.send(msg); time.sleep(0.1) #doctest: +ELLIPSIS UDPJack out: ... >>> m4.conversations.keys() [u'Wazzaaaappp'] >>> m4.conversations['Wazzaaaappp'].timeline()[0].content u"I'm druunnkkkk" >>> m3.unread {'["udp4",["localhost",9004],"jeff"]': {}} ''' convo = msg.conversation self.add_conversation(convo) convo_obj = self.conversations[convo] convo_obj.register_message(msg) recipients = recipients or msg.data['to'] for recipient in recipients: name, addr = recipient self.client.write_json(address.py_address(addr), { 'type':'ejmail-message', 'data':msg.data, }) saddr = address.str_address(addr) if not saddr in self.unread: self.unread[saddr] = {} self.unread[saddr][msg.hash] = msg def ack(self, message, addr): self.client.write_json( address.py_address(addr), { 'type':'ejmail-mark', 'data':[message.hash], } )