Skip to content

Commit

Permalink
Test In a Box code and one that makes use of it by sending a Tx and w…
Browse files Browse the repository at this point in the history
…atching bitcoind react
  • Loading branch information
Charles Samuels committed Feb 21, 2014
1 parent d6e36ff commit 238ffc0
Show file tree
Hide file tree
Showing 2 changed files with 173 additions and 0 deletions.
93 changes: 93 additions & 0 deletions test/SendTx.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import unittest

from armoryengine.ALL import *

from armoryengine.Networking import ArmoryClientFactory
from twisted.internet import reactor

from test import Tiab


class Test:
def __init__(self):
self.success=False

def txReturned(self, tx):
# a round trip was completed
# print "got something back"
#if protoObj.serialize() == tx:
self.factory1.stopTrying()
self.factory2.stopTrying()
reactor.stop()
self.success=True

def timeout(self):
self.factory1.stopTrying()
self.factory2.stopTrying()
reactor.stop()
self.success=False


def run(self):
class T:
def port(self, p):
if p == 0:
return 19000
else:
return 19010

#tiab = T()
tiab = Tiab.TiabSession()
# sends 10BTC from Charles's TIAB wallet to mwxN3Xw7P7kfkKY41KC99eD6cHtFYV9fun (also in that wallet)
tx = hex_to_binary("0100000001cce316f49284cb1e7d0c582064df8bb5dad960a3feeeca938cbb9fec7ba75694010000008b483045022100ad0dd567452c9d6d4b668e7847c360d1e866932a49f687927acfce86bf583d470220212028998cec632e41ea8d1bdd330da4e7c9b33f109bef9d9f8ae3fa85448aa80141043636a37759b535cc29ae611d770efdd7dc18830e0fc3a7a67851c5fe41737ae1a8ec90219aaea2684ec443344c16d385090359832d5eb71a6f07fb07bc06dcfdffffffff02f0c6c99d450000001976a9145d07242295d11e2fddb4535e7b0a5cdbea32db6888ac00ca9a3b000000001976a914b4503c9ef81c2d09f13a51ebd1d92e2368912b2d88ac00000000");

success=False

def sendTx(protoObj):
# print "sent"
pytx = PyTx()
pytx.unserialize(tx)
protoObj.sendMessage(PayloadTx(pytx))

self.factory1 = ArmoryClientFactory(None, sendTx)
reactor.callWhenRunning( \
reactor.connectTCP, '127.0.0.1', \
tiab.port(0), self.factory1)

self.factory2 = ArmoryClientFactory( None, func_inv=self.txReturned)
reactor.callWhenRunning( \
reactor.connectTCP, '127.0.0.1', \
tiab.port(0), self.factory2)


reactor.callLater(15, self.timeout)
reactor.run()

tiab.clean()

return self.success



class TiabSendTxTest(unittest.TestCase):

def setUp(self):
pass

def tearDown(self):
pass

def test_sendtx(self):
self.assertTrue(Test().run())


if not USE_TESTNET:
LOGERROR("Must be run with --testnet")
sys.exit(1)

if __name__ == "__main__":
s = Test().run()
if not s:
print "Failed"

# kate: indent-width 3; replace-tabs on;
80 changes: 80 additions & 0 deletions test/Tiab.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@

import os
import tempfile
import shutil
import subprocess

# runs a Test In a Box (TIAB) bitcoind session. By copying a prebuilt
# testnet with a known state
# Charles's recommendation is that you keep the TIAB somewhere like ~/.armory/tiab.charles
# and export that path in your .bashrc as ARMORY_TIAB_PATH
class TiabSession:
numInstances=0

# create a Test In a Box, initializing it and filling it with data
# the data comes from a path in the environment unless tiabdatadir is set
# tiab_repository is used to name which flavor of box is used if
# tiabdatadir is not used - It is intended to be used for when we
# have multiple testnets in a box with different properties
def __init__(self, tiab_repository="", tiabdatadir=None):
self.tiabdatadir = tiabdatadir
self.processes = []
if not self.tiabdatadir:
self.tiabdatadir = os.environ['ARMORY_TIAB_PATH'+tiab_repository]
# an obvious race condition lives here
self.directory = tempfile.mkdtemp("armory_tiab")

self.running = False

self.restart()

def __del__(self):
self.clean()

# exit bitcoind and remove all data
def clean(self):
if not self.running:
return
TiabSession.numInstances -= 1
try:
for x in self.processes:
x.kill()
for x in self.processes:
x.wait()
self.processes = []
shutil.rmtree(self.directory)
except:
pass
self.running=False

# returns the port the first bitcoind is running on
# In future versions of this class, multiple bitcoinds will get different ports,
# so therefor, you should call this function to get the port to connect to
def port(self, instanceNum):
instance = instanceNum
if instance==0:
return 19000
elif instance==1:
return 19010
else:
raise RuntimeError("No such instance number")

# clean() and then start bitcoind again
def restart(self):
self.clean()
if TiabSession.numInstances != 0:
raise RuntimeError("Cannot have more than one Test-In-A-Box session simultaneously (yet)")

TiabSession.numInstances += 1
os.rmdir(self.directory)
shutil.copytree(self.tiabdatadir, self.directory)
try:
print "executing in datadir " + self.directory
self.processes.append( subprocess.Popen(["bitcoind", "-datadir=" + self.directory + "/1", "-debugnet", "-debug" ]) )
self.processes.append( subprocess.Popen(["bitcoind", "-datadir=" + self.directory + "/2", "-debugnet", "-debug" ]) )
except:
self.clean()
raise
self.running = True

# kate: indent-width 3; replace-tabs on;

0 comments on commit 238ffc0

Please sign in to comment.