2
# This Code chunk has to appear before ArmoryUtils is imported
3
# If not, it will run the tests in Mainnet.
4
# TODO: Fix the code base so that nothing is started during imports.
5
sys.argv.append('--testnet')
6
# Uncomment when debugging
7
# sys.argv.append('--debug')
8
sys.argv.append('--nologging')
18
from zipfile import ZipFile
19
from armoryengine.BDM import TheBDM, BlockDataManagerThread, newTheBDM
24
FIRST_WLT_FILE_NAME = "armory_GDHFnMQ2_.wallet"
25
FIRST_WLT_NAME = "GDHFnMQ2"
27
SECOND_WLT_FILE_NAME = "armory_vzgEfJrJ_.wallet"
28
SECOND_WLT_NAME = "vzgEfJrJ"
30
THIRD_WLT_FILE_NAME = "armory_DZMmtb2v_.wallet"
31
THIRD_WLT_NAME = "DZMmtb2v"
34
FIRST_WLT_BALANCE = 964.8997
36
TIAB_SATOSHI_PORT = 19000
38
# runs a Test In a Box (TIAB) bitcoind session. By copying a prebuilt
39
# testnet with a known state
40
# Charles's recommendation is that you keep the TIAB somewhere like ~/.armory/tiab.charles
41
# and export that path in your .bashrc as ARMORY_TIAB_PATH
45
# create a Test In a Box, initializing it and filling it with data
46
# the data comes from a path in the environment unless tiabdatadir is set
47
# tiab_repository is used to name which flavor of box is used if
48
# tiabdatadir is not used - It is intended to be used for when we
49
# have multiple testnets in a box with different properties
50
def __init__(self, tiabZipPath="tiab.zip"):
52
self.tiabDirectory = tempfile.mkdtemp("armory_tiab")
53
self.tiabZipPath = tiabZipPath
62
# exit bitcoind and remove all data
66
TiabSession.numInstances -= 1
67
for x in self.processes:
69
for x in self.processes:
72
shutil.rmtree(self.tiabDirectory)
75
# returns the port the first bitcoind is running on
76
# In future versions of this class, multiple bitcoinds will get different ports,
77
# so therefor, you should call this function to get the port to connect to
78
def port(self, instanceNum):
79
instance = instanceNum
81
return TIAB_SATOSHI_PORT
85
raise RuntimeError("No such instance number")
87
# clean() and then start bitcoind again
89
def callBitcoinD(self, bitcoinDArgs):
90
bitcoinDArgsCopy = copy.copy(bitcoinDArgs)
91
bitcoinDArgsCopy.insert(0, "bitcoind")
92
return self.processes.append(subprocess.Popen(bitcoinDArgsCopy))
96
if TiabSession.numInstances != 0:
97
raise RuntimeError("Cannot have more than one Test-In-A-Box session simultaneously (yet)")
99
TiabSession.numInstances += 1
100
with ZipFile(self.tiabZipPath, "r") as z:
101
z.extractall(self.tiabDirectory)
103
self.callBitcoinD(["-datadir=" + os.path.join(self.tiabDirectory,'tiab','1'), "-debug"])
104
self.callBitcoinD(["-datadir=" + os.path.join(self.tiabDirectory,'tiab','2'), "-debug"])
110
TIAB_ZIPFILE_NAME = 'tiab.zip'
111
NEED_TIAB_MSG = "This Test must be run with <TBD>. Copy to the test directory. Actual Block Height is "
113
class TiabTest(unittest.TestCase):
115
def setUpClass(self):
116
# Handle both calling the this test from the context of the test directory
117
# and calling this test from the context of the main directory.
118
# The latter happens if you run all of the tests in the directory
119
if os.path.exists(TIAB_ZIPFILE_NAME):
120
tiabZipPath = TIAB_ZIPFILE_NAME
121
elif os.path.exists(os.path.join('pytest',TIAB_ZIPFILE_NAME)):
122
tiabZipPath = (os.path.join('pytest',TIAB_ZIPFILE_NAME))
124
self.fail(NEED_TIAB_MSG)
125
self.tiab = TiabSession(tiabZipPath=tiabZipPath)
126
# Need to destroy whatever BDM may have been created automatically
127
CppBlockUtils.BlockDataManager().DestroyBDM()
129
TheBDM.setDaemon(True)
131
TheBDM.setSatoshiDir(os.path.join(self.tiab.tiabDirectory,'tiab','1','testnet3'))
132
self.armoryHomeDir = os.path.join(self.tiab.tiabDirectory,'tiab','armory')
133
TheBDM.setLevelDBDir(os.path.join(self.tiab.tiabDirectory,'tiab','armory','databases'))
134
TheBDM.setBlocking(True)
135
TheBDM.setOnlineMode(wait=True)
137
while not TheBDM.getBDMState()=='BlockchainReady' and i < 10:
141
raise RuntimeError("Timeout waiting for TheBDM to get into BlockchainReady state.")
145
def tearDownClass(self):
146
CppBlockUtils.BlockDataManager().DestroyBDM()
149
def verifyBlockHeight(self):
150
blockHeight = TheBDM.getTopBlockHeight()
151
self.assertEqual(blockHeight, TOP_TIAB_BLOCK, NEED_TIAB_MSG + str(blockHeight))