diff --git a/jmclient/test/test_client_protocol.py b/jmclient/test/test_client_protocol.py index 5c58691..1ed50c8 100644 --- a/jmclient/test/test_client_protocol.py +++ b/jmclient/test/test_client_protocol.py @@ -3,15 +3,17 @@ from __future__ import absolute_import '''test client-protocol interfacae.''' from jmclient import load_program_config, Taker, get_log,\ - JMClientProtocolFactory, jm_single + JMClientProtocolFactory, jm_single, Maker from jmclient.client_protocol import JMTakerClientProtocol from twisted.python.log import msg as tmsg from twisted.internet import protocol, reactor, task +from twisted.internet.defer import inlineCallbacks from twisted.internet.error import (ConnectionLost, ConnectionAborted, ConnectionClosed, ConnectionDone) from twisted.protocols.amp import UnknownRemoteError from twisted.protocols import amp from twisted.trial import unittest +from twisted.test import proto_helpers from jmbase.commands import * from taker_test_data import t_raw_signed_tx import json @@ -26,9 +28,11 @@ clientfactory = None runno = 0 jlog = get_log() + def dummy_taker_finished(res, fromtx, waittime=0.0): pass + class DummyTaker(Taker): def set_fail_init(self, val): @@ -72,18 +76,62 @@ class DummyTaker(Taker): return None +class DummyWallet(object): + def get_wallet_id(self): + return 'aaaa' + + +class DummyMaker(Maker): + def __init__(self): + self.aborted = False + self.wallet = DummyWallet() + + def try_to_create_my_orders(self): + pass + + def on_auth_received(self, nick, offer, commitment, cr, amount, kphex): + # success, utxos, auth_pub, cj_addr, change_addr, btc_sig + return True, [], '', '', '', '' + + def on_tx_received(self, nick, txhex, offerinfo): + # success, sigs + return True, [] + + def verify_unsigned_tx(self, txd, offerinfo): + # success, errormsg + return True, None + + def modify_orders(self, to_cancel, to_announce): + pass + + def import_new_addresses(self, addr_list): + pass + + def create_my_orders(self): + return [] + + def oid_to_order(self, cjorder, oid, amount): + # utxos, cj_addr, change_addr + return [], '', '' + + def on_tx_unconfirmed(self, cjorder, txid, removed_utxos): + return [], [] + + def on_tx_confirmed(self, cjorder, confirmations, txid): + return [], [] + + class JMBaseProtocol(amp.AMP): def checkClientResponse(self, response): """A generic check of client acceptance; any failure is considered criticial. """ if 'accepted' not in response or not response['accepted']: - reactor.stop() + raise Exception("unexpected client response") def defaultErrback(self, failure): failure.trap(ConnectionAborted, ConnectionClosed, ConnectionDone, ConnectionLost, UnknownRemoteError) - reactor.stop() def defaultCallbacks(self, d): d.addCallback(self.checkClientResponse) @@ -203,6 +251,7 @@ class DummyClientProtocolFactory(JMClientProtocolFactory): def buildProtocol(self, addr): return JMTakerClientProtocol(self, self.client, nick_priv="aa"*32) + class TrialTestJMClientProto(unittest.TestCase): def setUp(self): @@ -236,9 +285,103 @@ class TrialTestJMClientProto(unittest.TestCase): clientfactories[0]) self.addCleanup(clientconn.disconnect) + def tearDown(self): + for dc in reactor.getDelayedCalls(): + dc.cancel() + def test_waiter(self): print("test_main()") return task.deferLater(reactor, 3, self._called_by_deffered) def _called_by_deffered(self): pass + + +class TestMakerClientProtocol(unittest.TestCase): + """ + very basic test case for JMMakerClientProtocol + + This test does not do much useful things right now, other than making sure + no exceptions are fired. Most argument data is not crafted carefully and + may lead to failing tests if anything changes. + """ + def get_response_cb(self, cmd): + def response_cb(response): + parsed = cmd.parseResponse(response, self.client) + assert parsed['accepted'] is True + return response_cb + + def callClient(self, jmcmd, response_cb=None, error_cb=None, **kwargs): + box = jmcmd.makeArguments(kwargs, self.client) + box[b'_command'] = jmcmd.__name__ + d = self.client.dispatchCommand(box) + d.addCallback(response_cb or self.get_response_cb(jmcmd)) + if error_cb: + d.addErrback(error_cb) + return d + + def setUp(self): + load_program_config() + factory = JMClientProtocolFactory(DummyMaker(), proto_type='MAKER') + self.client = factory.buildProtocol(None) + self.tr = proto_helpers.StringTransport() + self.client.makeConnection(self.tr) + + def tearDown(self): + for dc in reactor.getDelayedCalls(): + dc.cancel() + + def init_client(self): + return self.callClient( + JMInitProto, nick_hash_length=1, nick_max_encoded=2, + joinmarket_nick_header='J', joinmarket_version=5) + + @inlineCallbacks + def test_JMInitProto(self): + yield self.init_client() + + @inlineCallbacks + def test_JMRequestMsgSig(self): + yield self.init_client() + yield self.callClient( + JMRequestMsgSig, nick='dummynickforsign', cmd='command1', + msg='msgforsign', msg_to_be_signed='fullmsgforsign', + hostid='hostid1') + + @inlineCallbacks + def test_JMRequestMsgSigVerify(self): + fullmsg = 'fullmsgforverify' + priv = 'aa'*32 + '01' + pub = bitcoin.privkey_to_pubkey(priv) + sig = bitcoin.ecdsa_sign(fullmsg, priv) + yield self.init_client() + yield self.callClient( + JMRequestMsgSigVerify, msg='msgforverify', fullmsg=fullmsg, + sig=sig, pubkey=pub, nick='dummynickforverify', hashlen=4, + max_encoded=5, hostid='hostid2') + + @inlineCallbacks + def test_JMUp(self): + yield self.init_client() + yield self.callClient(JMUp) + + @inlineCallbacks + def test_JMSetupDone(self): + yield self.init_client() + yield self.callClient(JMSetupDone) + + + @inlineCallbacks + def test_JMAuthReceived(self): + yield self.init_client() + yield self.callClient( + JMAuthReceived, nick='testnick', offer='{}', + commitment='testcommitment', revelation='{}', amount=100000, + kphex='testkphex') + + @inlineCallbacks + def test_JMTXReceived(self): + yield self.init_client() + yield self.callClient( + JMTXReceived, nick='testnick', txhex=t_raw_signed_tx, + offer='{"cjaddr":"2MwfecDHsQTm4Gg3RekQdpqAMR15BJrjfRF"}')