Skip to content
This repository has been archived by the owner on May 13, 2022. It is now read-only.

refactor tests, small improvements #189

Merged
merged 2 commits into from
Aug 23, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions test/commontest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import sys
import os, time
data_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.insert(0, os.path.join(data_dir, 'lib'))
import subprocess
import unittest
import common
from blockchaininterface import *
import bitcoin as btc
import binascii
import pexpect
import random

'''Some helper functions for testing'''


'''This code is intended to provide
subprocess startup cross-platform with
some useful options; it could do with
some simplification/improvement.'''
import platform
OS = platform.system()
PINL = '\r\n' if OS == 'Windows' else '\n'

def local_command(command, bg=False, redirect=''):
if redirect=='NULL':
if OS=='Windows':
command.append(' > NUL 2>&1')
elif OS=='Linux':
command.extend(['>', '/dev/null', '2>&1'])
else:
print "OS not recognised, quitting."
elif redirect:
command.extend(['>', redirect])

if bg:
#using subprocess.PIPE seems to cause problems
FNULL = open(os.devnull,'w')
return subprocess.Popen(command, stdout=FNULL, stderr=subprocess.STDOUT, close_fds=True)
else:
#in case of foreground execution, we can use the output; if not
#it doesn't matter
return subprocess.check_output(command)

def make_wallets(n, wallet_structures = None, mean_amt=1, sdev_amt=0):
'''n: number of wallets to be created
wallet_structure: array of n arrays , each subarray
specifying the number of addresses to be populated with coins
at each depth (for now, this will only populate coins into 'receive' addresses)
mean_amt: the number of coins (in btc units) in each address as above
sdev_amt: if randomness in amouts is desired, specify here.
Returns: a dict of dicts of form {0:{'seed':seed,'wallet':Wallet object},1:..,}'''
if len(wallet_structures) != n:
raise Exception("Number of wallets doesn't match wallet structures")
seeds = common.chunks(binascii.hexlify(os.urandom(15*n)),n)
wallets = {}
for i in range(n):
wallets[i] = {'seed':seeds[i], 'wallet': common.Wallet(seeds[i], max_mix_depth=5)}
for j in range(5):
for k in range(wallet_structures[i][j]):
deviation = sdev_amt*random.random()
amt = mean_amt - sdev_amt/2.0 + deviation
if amt < 0: amt = 0.001
common.bc_interface.grab_coins(wallets[i]['wallet'].get_receive_addr(j),amt)
return wallets

def interact(process, inputs, expected):
if len(inputs) != len(expected):
raise Exception("Invalid inputs to interact()")
for i, inp in enumerate(inputs):
process.expect(expected[i])
process.sendline(inp)
75 changes: 27 additions & 48 deletions test/regtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@
import subprocess
import unittest
import common
import commontest
from blockchaininterface import *
import bitcoin as btc
import binascii

'''Expectations
''' Just some random thoughts to motivate possible tests;
almost none of this has really been done:

Expectations
1. Any bot should run indefinitely irrespective of the input
messages it receives, except bots which perform a finite action

Expand Down Expand Up @@ -39,8 +43,8 @@ def local_command(command, bg=False, redirect=''):
command.extend(['>', redirect])

if bg:
return subprocess.Popen(command, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stdin=subprocess.PIPE)
FNULL = open(os.devnull,'w')
return subprocess.Popen(command, stdout=FNULL, stderr=subprocess.STDOUT, close_fds=True)
else:
#in case of foreground execution, we can use the output; if not
#it doesn't matter
Expand All @@ -49,38 +53,33 @@ def local_command(command, bg=False, redirect=''):


class Join2PTests(unittest.TestCase):
'''This test case intends to simulate
a single join with a single counterparty. In that sense,
it's not realistic, because nobody (should) do joins with only 1 maker,
but this test has the virtue of being the simplest possible thing
that JoinMarket can do. '''
def setUp(self):
#create 2 new random wallets.
#put 100 coins into the first receive address
#put 10 coins into the first receive address
#to allow that bot to start.
seed1, seed2 = [binascii.hexlify(x) for x in [os.urandom(15), os.urandom(15)]]
self.wallets = {}
wallet1 = common.Wallet(seed1)
wallet2 = common.Wallet(seed2)
self.wallets[1] = {'seed':seed1,'wallet':wallet1}
self.wallets[2] = {'seed':seed2,'wallet':wallet2}
#get first address in each wallet
addr1 = wallet1.get_receive_addr(0)
common.debug("address for wallet1: "+addr1)
addr2 = wallet2.get_receive_addr(0)
common.debug("address for wallet2: "+addr2)
common.bc_interface.grab_coins(addr1,10)
common.bc_interface.grab_coins(addr2,10)
self.wallets = commontest.make_wallets(2,
wallet_structures=[[1,0,0,0,0],[1,0,0,0,0]], mean_amt=10)

def run_simple_send(self, n):

def run_simple_send(self, n, m):
#start yield generator with wallet1
yigen_proc = local_command(['python','yield-generator.py',
str(self.wallets[1]['seed'])],redirect=self.wallets[1]['seed'],bg=True)
str(self.wallets[0]['seed'])],bg=True)

#A significant delay is needed to wait for the yield generator to sync its wallet
time.sleep(30)

#run a single sendpayment call with wallet2
amt = 100000000 #in satoshis
amt = n*100000000 #in satoshis
dest_address = btc.privkey_to_address(os.urandom(32), common.get_addr_vbyte())
try:
for i in range(n):
sp_proc = local_command(['python','sendpayment.py','--yes','-N','1', self.wallets[2]['seed'],\
for i in range(m):
sp_proc = local_command(['python','sendpayment.py','--yes','-N','1', self.wallets[1]['seed'],\
str(amt), dest_address])
except subprocess.CalledProcessError, e:
if yigen_proc:
Expand All @@ -91,20 +90,15 @@ def run_simple_send(self, n):

if yigen_proc:
yigen_proc.terminate()

#for cf in [self.wallets[1]['seed']+'_yieldgen.out', self.wallets[2]['seed']+'_send.out']:
# if os.path.isfile(cf):
# with open(cf, 'rb') as f:
# if 'CRASHING' in f.read(): return False


received = common.bc_interface.get_received_by_addr([dest_address], None)['data'][0]['balance']
if received != amt*n:
if received != amt*m:
common.debug('received was: '+str(received)+ ' but amount was: '+str(amt))
return False
return True

def test_simple_send(self):
self.failUnless(self.run_simple_send(2))
self.failUnless(self.run_simple_send(2, 2))


class JoinNPTests(unittest.TestCase):
Expand All @@ -114,17 +108,9 @@ def setUp(self):
#create n+1 new random wallets.
#put 10 coins into the first receive address
#to allow that bot to start.
seeds = map(None, *([iter(os.urandom((self.n+1)*15))]*15))

seeds = [binascii.hexlify(''.join(x)) for x in seeds]
self.wallets = {}
for i, seed in enumerate(seeds):
self.wallets[i] = {'seed':seed, 'wallet':common.Wallet(seed)}

#get first address in each wallet
for i in self.wallets.keys():
common.bc_interface.grab_coins(self.wallets[i]['wallet'].get_receive_addr(0), amt=10)

wallet_structures = [[1,0,0,0,0]]*3
self.wallets = commontest.make_wallets(3, wallet_structures=wallet_structures,
mean_amt=10)
#the sender is wallet (n+1), i.e. index wallets[n]


Expand Down Expand Up @@ -158,13 +144,6 @@ def run_nparty_join(self):
if any(yigen_procs):
for ygp in yigen_procs:
ygp.kill()

crash_files = [self.wallets[i]['seed']+'_yieldgen.out' for i in range(self.n)]
crash_files.append(self.wallets[self.n]['seed']+'_send.out')
for cf in crash_files:
if os.path.isfile(cf): return False
#with open(cf, 'rb') as f:
# if 'CRASHING' in f.read(): return False

received = common.bc_interface.get_received_by_addr([dest_address], None)['data'][0]['balance']
if received != amt:
Expand Down
15 changes: 4 additions & 11 deletions test/wallet-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,12 @@
import subprocess
import unittest
import common
import commontest
from blockchaininterface import *
import bitcoin as btc
import binascii
import pexpect

def interact(process, inputs, expected):
if len(inputs) != len(expected):
raise Exception("Invalid inputs to interact()")
for i, inp in enumerate(inputs):
process.expect(expected[i])
process.sendline(inp)



class TestWalletCreation(unittest.TestCase):

def test_generate(self):
Expand All @@ -40,7 +33,7 @@ def run_generate(self, pwd):
'Input wallet file name']
testlog = open('test/testlog-'+pwd, 'wb')
p = pexpect.spawn('python wallet-tool.py generate', logfile=testlog)
interact(p, test_in, expected)
commontest.interact(p, test_in, expected)
p.expect('saved to')
#time.sleep(2)
p.close()
Expand Down Expand Up @@ -80,7 +73,7 @@ def run_recover(self, seed):
'Reenter wallet encryption passphrase:',
'Input wallet file name']
test_in = [seed, 'abc123', 'abc123', 'test_recover_wallet.json']
interact(p, test_in, expected)
commontest.interact(p, test_in, expected)
p.expect('saved to')
p.close()
testlog.close()
Expand Down
6 changes: 6 additions & 0 deletions test/wnb.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash
for i in {62612..62619}
do
curl -sI --max-time 0.6 http://localhost:$i/walletnotify?$1
done