test_rest_api.py 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. from datetime import datetime
  2. from src.protocol import Protocol
  3. from src.chainbuilder import ChainBuilder
  4. from src.rpc_server import rpc_server
  5. from _thread import start_new_thread
  6. from tests.utils import *
  7. from src.rpc_server import shutdown_server
  8. from tests.test_verifications import block_test
  9. from Crypto.PublicKey import RSA
  10. import requests
  11. sess = requests.Session()
  12. host = "http://localhost:{}/"
  13. port = 2345
  14. NUMBER_FIELDS_IN_BLOCK = 9
  15. def start_server(chain):
  16. """builds a chainbuilder from a Blockchain, appends and starts a rpc server"""
  17. proto = Protocol([], GENESIS_BLOCK, 1337)
  18. chainbuilder = ChainBuilder(proto)
  19. chainbuilder.primary_block_chain = chain
  20. return start_new_thread(rpc_server, (port, chainbuilder, None))
  21. def rpc_test(count):
  22. """starts the rpc server, runs a test and stopps the server"""
  23. def decorator(fn):
  24. @block_test()
  25. def wrapper(gen_chain):
  26. chain = gen_chain
  27. key = Key.generate_private_key()
  28. for i in range(count):
  29. reward_trans = Transaction([], [TransactionTarget(key, chain.compute_blockreward_next_block())], datetime.now())
  30. chain = extend_blockchain(chain, [reward_trans])
  31. start_server(chain)
  32. fn(chain)
  33. res = sess.get(host.format(port) + 'shutdown')
  34. assert res.text == 'Server shutting down...'
  35. return wrapper
  36. return decorator
  37. def get_path(path):
  38. """endpoint link"""
  39. res = sess.get(host.format(port) + path)
  40. assert (res.status_code == 200), "Could not reach endpoint " + path
  41. return res
  42. def get_explorer(path):
  43. """adds path to explorer"""
  44. return get_path("explorer/"+path)
  45. def get_statistics(path):
  46. """adds statistics to path"""
  47. return get_explorer("statistics/"+path)
  48. @rpc_test(10)
  49. def test_explorer_availability(chain):
  50. """explorer check for addresses, transcactions, blocks, lasttransactions, lastblocks, blockat"""
  51. get_explorer('addresses')
  52. get_explorer('transactions')
  53. get_explorer('blocks')
  54. get_explorer('lasttransactions/10')
  55. get_explorer('lastblocks/10')
  56. get_explorer('blockat/10')
  57. @rpc_test(10)
  58. def test_statistics_availability(chain):
  59. """statistics check for hashrate, tps, totalblocks, difficulty, blocktime"""
  60. get_statistics('hashrate')
  61. get_statistics('tps')
  62. get_statistics('totalblocks')
  63. get_statistics('difficulty')
  64. get_statistics('blocktime')
  65. def check_address_data(address):
  66. """check for sender and receiver"""
  67. assert 'received' in address, "response object does not contain a received"
  68. assert 'sent' in address, "response object does not contain a sent"
  69. @rpc_test(1)
  70. def test_address_data(chain):
  71. """gets the first address and checks the closer information"""
  72. hash = get_explorer("addresses").json()[0]
  73. res = get_explorer("sortedtransactions/" + hash)
  74. res_json = res.json()
  75. check_address_data(res_json)
  76. def checkblock_data(block):
  77. """blockcheck for nonce, id, difficulty, height, prev_block_hash, transactions, time, merkle_root_hash, hash"""
  78. assert len(block) == NUMBER_FIELDS_IN_BLOCK, "Wrong number of Fields in response object"
  79. assert 'nonce' in block, "response object does not contain a nonce"
  80. assert 'id' in block, "response object does not contain a id"
  81. assert 'difficulty' in block, "response object does not contain a difficulty"
  82. assert 'height' in block, "response object does not contain a height"
  83. assert 'prev_block_hash' in block, "response object does not contain a prev_block_hash"
  84. assert 'transactions' in block, "response object does not contain a transactions"
  85. assert 'time' in block, "response object does not contain a time"
  86. assert 'merkle_root_hash' in block, "response object does not contain a merkle_root_hash"
  87. assert 'hash' in block, "response object does not contain a hash"
  88. @rpc_test(1)
  89. def test_lastblocks_block_data(chain):
  90. """checks the blockdata"""
  91. res = get_explorer('lastblocks/10')
  92. res_json = res.json()
  93. assert len(res_json) == 2, "Incorrect count of Blocks"
  94. block = res_json[0]
  95. checkblock_data(block)
  96. @rpc_test(1)
  97. def test_transactions_data(chain):
  98. """check in transaction for hash, block_id, targets, timestamp, number_confirmations, block_hash, signatures, inputs"""
  99. res = sess.get(host.format(port) + 'explorer/transactions')
  100. assert (res.status_code == 200)
  101. res_json = res.json()
  102. assert len(res_json) == 1, "Incorrect count of transactions"
  103. transaction = res_json[0]
  104. assert len(transaction) == 8, "Wrong number of Fields in resonse object"
  105. assert 'hash' in transaction, "response object does not contain a hash"
  106. assert 'block_id' in transaction, "response object does not contain a block_id"
  107. assert 'targets' in transaction, "response object does not contain targets"
  108. assert 'timestamp' in transaction, "response object does not contain a timestamp"
  109. assert 'number_confirmations' in transaction, "response object does not contain a number_confirmations"
  110. assert 'block_hash' in transaction, "response object does not contain a block_hash"
  111. assert 'signatures' in transaction, "response object does not contain signatures"
  112. assert 'inputs' in transaction, "response object does not contain inputs"
  113. assert len(transaction["inputs"]) == len(transaction["signatures"]), "Difference in amount of signatures and inputs"
  114. def check_data_count(subpath):
  115. """checks the correctness of the count from the subpath"""
  116. @rpc_test(10)
  117. def inner(chain):
  118. path = "explorer/"+subpath
  119. url = host.format(port) + path + "/" +str(5)
  120. res = sess.get(url)
  121. assert (res.status_code == 200), url
  122. res_json = res.json()
  123. assert len(res_json) == 5, "Incorrect count of " + subpath
  124. url = host.format(port) + path + "/" + str(20)
  125. res = sess.get(url)
  126. assert (res.status_code == 200), url
  127. res_json = res.json()
  128. if(subpath == "lastblocks"):
  129. assert len(res_json) == 11, "Incorrect count of " + subpath
  130. if(subpath == "lasttransactions"):
  131. assert len(res_json) == 10, "Incorrect count of " + subpath
  132. inner()
  133. def test_blocks_count():
  134. check_data_count("lastblocks")
  135. def test_transactions_count():
  136. check_data_count("lasttransactions")