def main(): parser = argparse.ArgumentParser() # Network options group_network_container = parser.add_argument_group( title="Network options") group_network = group_network_container.add_mutually_exclusive_group( required=True) group_network.add_argument("--mainnet", action="store_true", default=False, help="Use MainNet") group_network.add_argument("--testnet", action="store_true", default=False, help="Use TestNet") group_network.add_argument("--privnet", action="store_true", default=False, help="Use PrivNet") group_network.add_argument("--coznet", action="store_true", default=False, help="Use CozNet") group_network.add_argument("--config", action="store", help="Use a specific config file") # Ports for RPC and REST api group_modes = parser.add_argument_group(title="Mode(s)") group_modes.add_argument( "--port-rpc", type=int, help="port to use for the json-rpc api (eg. 10332)") group_modes.add_argument("--port-rest", type=int, help="port to use for the rest api (eg. 80)") # Advanced logging setup group_logging = parser.add_argument_group(title="Logging options") group_logging.add_argument("--logfile", action="store", type=str, help="Logfile") group_logging.add_argument( "--syslog", action="store_true", help= "Log to syslog instead of to log file ('user' is the default facility)" ) group_logging.add_argument( "--syslog-local", action="store", type=int, choices=range(0, 7), metavar="[0-7]", help= "Log to a local syslog facility instead of 'user'. Value must be between 0 and 7 (e.g. 0 for 'local0')." ) group_logging.add_argument("--disable-stderr", action="store_true", help="Disable stderr logger") # Where to store stuff parser.add_argument("--datadir", action="store", help="Absolute path to use for database directories") # peers parser.add_argument("--maxpeers", action="store", default=5, help="Max peers to use for P2P Joining") # host parser.add_argument("--host", action="store", type=str, help="Hostname ( for example 127.0.0.1)", default="0.0.0.0") # Now parse args = parser.parse_args() # print(args) if not args.port_rpc and not args.port_rest: print("Error: specify at least one of --port-rpc / --port-rest") parser.print_help() return if args.port_rpc == args.port_rest: print("Error: --port-rpc and --port-rest cannot be the same") parser.print_help() return if args.logfile and (args.syslog or args.syslog_local): print("Error: Cannot only use logfile or syslog at once") parser.print_help() return # Setting the datadir must come before setting the network, else the wrong path is checked at net setup. if args.datadir: settings.set_data_dir(args.datadir) # Network configuration depending on command line arguments. By default, the testnet settings are already loaded. if args.config: settings.setup(args.config) elif args.mainnet: settings.setup_mainnet() elif args.testnet: settings.setup_testnet() elif args.privnet: settings.setup_privnet() elif args.coznet: settings.setup_coznet() if args.maxpeers: settings.set_max_peers(args.maxpeers) if args.syslog or args.syslog_local is not None: # Setup the syslog facility if args.syslog_local is not None: print("Logging to syslog local%s facility" % args.syslog_local) syslog_facility = SysLogHandler.LOG_LOCAL0 + args.syslog_local else: print("Logging to syslog user facility") syslog_facility = SysLogHandler.LOG_USER # Setup logzero to only use the syslog handler logzero.syslog(facility=syslog_facility) else: # Setup file logging if args.logfile: logfile = os.path.abspath(args.logfile) if args.disable_stderr: print("Logging to logfile: %s" % logfile) else: print("Logging to stderr and logfile: %s" % logfile) logzero.logfile(logfile, maxBytes=LOGFILE_MAX_BYTES, backupCount=LOGFILE_BACKUP_COUNT, disableStderrLogger=args.disable_stderr) else: print("Logging to stdout and stderr") # Disable logging smart contract events settings.set_log_smart_contract_events(False) # Write a PID file to easily quit the service write_pid_file() # Setup Twisted and Klein logging to use the logzero setup observer = STDLibLogObserver(name=logzero.LOGZERO_DEFAULT_LOGGER) globalLogPublisher.addObserver(observer) # Instantiate the blockchain and subscribe to notifications blockchain = LevelDBBlockchain(settings.chain_leveldb_path) Blockchain.RegisterBlockchain(blockchain) dbloop = task.LoopingCall(Blockchain.Default().PersistBlocks) dbloop.start(.1) # Setup twisted reactor, NodeLeader and start the NotificationDB reactor.suggestThreadPoolSize(15) NodeLeader.Instance().Start() NotificationDB.instance().start() # Start a thread with custom code d = threading.Thread(target=custom_background_code) d.setDaemon( True ) # daemonizing the thread will kill it when the main thread is quit d.start() if args.port_rpc: logger.info("Starting json-rpc api server on http://%s:%s" % (args.host, args.port_rpc)) api_server_rpc = JsonRpcApi(args.port_rpc) endpoint_rpc = "tcp:port={0}:interface={1}".format( args.port_rpc, args.host) endpoints.serverFromString(reactor, endpoint_rpc).listen( Site(api_server_rpc.app.resource())) # reactor.listenTCP(int(args.port_rpc), server.Site(api_server_rpc)) # api_server_rpc.app.run(args.host, args.port_rpc) if args.port_rest: logger.info("Starting REST api server on http://%s:%s" % (args.host, args.port_rest)) api_server_rest = RestApi() endpoint_rest = "tcp:port={0}:interface={1}".format( args.port_rest, args.host) endpoints.serverFromString(reactor, endpoint_rest).listen( Site(api_server_rest.app.resource())) # api_server_rest.app.run(args.host, args.port_rest) reactor.run() # After the reactor is stopped, gracefully shutdown the database. logger.info("Closing databases...") NotificationDB.close() Blockchain.Default().Dispose() NodeLeader.Instance().Shutdown()
class NotificationDBTestCase(BlockchainFixtureTestCase): app = None # type:RestApi @classmethod def leveldb_testpath(cls): return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain') def setUp(self): self.app = RestApi() def test_1_ok(self): ndb = NotificationDB.instance() events = ndb.get_by_block(9583) self.assertEqual(len(events), 1) def test_2_klein_app(self): self.assertIsNotNone(self.app.notif) def test_3_index(self): mock_req = requestMock(path=b'/') res = self.app.home(mock_req) self.assertIn('endpoints', res) def test_4_by_block(self): mock_req = requestMock(path=b'/block/9583') res = self.app.get_by_block(mock_req, 9583) jsn = json.loads(res) self.assertEqual(jsn['total'], 1) results = jsn['results'] self.assertEqual(len(results), 1) def test_5_block_no_results(self): mock_req = requestMock(path=b'/block/206') res = self.app.get_by_block(mock_req, 206) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, list) self.assertEqual(len(results), 0) def test_6_block_num_too_big(self): mock_req = requestMock(path=b'/block/2060200054055066') res = self.app.get_by_block(mock_req, 2060200054055066) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Higher than current block', jsn['message']) def test_7_by_addr(self): mock_req = requestMock(path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 500) def test_8_bad_addr(self): mock_req = requestMock(path=b'/addr/AcFnRrVC5emrTEkuFuRPufcuTb6KsAJ3v') res = self.app.get_by_addr(mock_req, 'AcFnRrVC5emrTEkuFuRPufcuTb6KsAJ3v') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Could not get notifications', jsn['message']) def test_9_by_tx(self): mock_req = requestMock(path=b'/tx/0xa2a37fd2ab7048d70d51eaa8af2815e0e542400329b05a34274771174180a7e8') res = self.app.get_by_tx(mock_req, '0xa2a37fd2ab7048d70d51eaa8af2815e0e542400329b05a34274771174180a7e8') jsn = json.loads(res) self.assertEqual(jsn['total'], 1) results = jsn['results'] self.assertEqual(len(results), 1) def test_9_by_bad_tx(self): mock_req = requestMock(path=b'/tx/2e4168cb2d563714d3f35ff76b7efc6c7d428360c97b6b45a18b5b1a4faa40') res = self.app.get_by_tx(mock_req, b'2e4168cb2d563714d3f35ff76b7efc6c7d428360c97b6b45a18b5b1a4faa40') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Could not get tx with hash', jsn['message']) def test_get_by_contract(self): mock_req = requestMock(path=b'/contract/b9fbcff6e50fd381160b822207231233dd3c56c2') res = self.app.get_by_contract(mock_req, 'b9fbcff6e50fd381160b822207231233dd3c56c2') jsn = json.loads(res) self.assertEqual(jsn['total'], 1006) results = jsn['results'] self.assertEqual(len(results), 500) def test_get_by_contract_empty(self): mock_req = requestMock(path=b'/contract/910cba960880c75072d0c625dfff459f72aae047') res = self.app.get_by_contract(mock_req, '910cba960880c75072d0c625dfff459f72aae047') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertEqual(len(results), 0) def test_get_tokens(self): mock_req = requestMock(path=b'/tokens') res = self.app.get_tokens(mock_req) jsn = json.loads(res) self.assertEqual(jsn['total'], 5) results = jsn['results'] self.assertIsInstance(results, list) def test_pagination_for_addr_results(self): mock_req = requestMock(path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 500) self.assertEqual(jsn['total_pages'], 3) mock_req = requestMock(path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9?page=1') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 500) mock_req = requestMock(path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9?page=2') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 500) mock_req = requestMock(path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9?page=3') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 7) def test_pagination_page_size_for_addr_results(self): mock_req = requestMock(path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9?pagesize=100') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 100) self.assertEqual(jsn['total_pages'], 11) mock_req = requestMock(path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9?pagesize=100&page=11') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) results = jsn['results'] self.assertEqual(len(results), 7) def test_block_heigher_than_current(self): mock_req = requestMock(path=b'/block/8000000') res = self.app.get_by_block(mock_req, 800000) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Higher than current block', jsn['message'])
def setUp(self): self.app = RestApi()
class NotificationDBTestCase(BlockchainFixtureTestCase): N_FIXTURE_REMOTE_LOC = 'https://s3.us-east-2.amazonaws.com/cityofzion/fixtures/notif_fixture_v3.tar.gz' N_FIXTURE_FILENAME = os.path.join(settings.DATA_DIR_PATH, 'Chains/notif_fixture_v3.tar.gz') N_NOTIFICATION_DB_NAME = os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_notifications') contract_hash = UInt160(data=bytearray(b'\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[')) event_tx = '042e4168cb2d563714d3f35ff76b7efc6c7d428360c97b6b45a18b5b1a4faa40' addr_to = 'AHbmRX5sL8oxp4dJZRNg5crCGUGxuMUyRB' addr_from = 'AcFnRrVC5emrTEkuFuRPufcuTb6KsAJ3vR' app = None # type:RestApi @classmethod def leveldb_testpath(self): return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain') @classmethod def setUpClass(cls): super(NotificationDBTestCase, cls).setUpClass() if not os.path.exists(cls.N_FIXTURE_FILENAME): logzero.logger.info( "downloading fixture notification database from %s. this may take a while" % cls.N_FIXTURE_REMOTE_LOC) response = requests.get(cls.N_FIXTURE_REMOTE_LOC, stream=True) response.raise_for_status() with open(cls.N_FIXTURE_FILENAME, 'wb+') as handle: for block in response.iter_content(1024): handle.write(block) try: tar = tarfile.open(cls.N_FIXTURE_FILENAME) tar.extractall(path=settings.DATA_DIR_PATH) tar.close() except Exception as e: raise Exception("Could not extract tar file - %s. You may want need to remove the fixtures file %s manually to fix this." % (e, cls.N_FIXTURE_FILENAME)) if not os.path.exists(cls.N_NOTIFICATION_DB_NAME): raise Exception("Error downloading fixtures") settings.NOTIFICATION_DB_PATH = cls.N_NOTIFICATION_DB_NAME ndb = NotificationDB.instance() ndb.start() @classmethod def tearDownClass(cls): super(NotificationDBTestCase, cls).tearDownClass() NotificationDB.instance().close() shutil.rmtree(cls.N_NOTIFICATION_DB_NAME) def setUp(self): self.app = RestApi() def test_1_ok(self): ndb = NotificationDB.instance() events = ndb.get_by_block(627529) self.assertEqual(len(events), 1) def test_2_klein_app(self): self.assertIsNotNone(self.app.notif) def test_3_index(self): mock_req = requestMock(path=b'/') res = self.app.home(mock_req) self.assertIn('endpoints', res) def test_4_by_block(self): mock_req = requestMock(path=b'/block/627529') res = self.app.get_by_block(mock_req, 627529) jsn = json.loads(res) self.assertEqual(jsn['total'], 1) results = jsn['results'] self.assertEqual(len(results), 1) def test_5_block_no_results(self): mock_req = requestMock(path=b'/block/206') res = self.app.get_by_block(mock_req, 206) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, list) self.assertEqual(len(results), 0) def test_6_block_num_too_big(self): mock_req = requestMock(path=b'/block/2060200054055066') res = self.app.get_by_block(mock_req, 2060200054055066) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Higher than current block', jsn['message']) def test_7_by_addr(self): mock_req = requestMock(path=b'/addr/AL5e5ZcqtBTKjcQ8reiePrUBMYSD88v59a') res = self.app.get_by_addr(mock_req, 'AL5e5ZcqtBTKjcQ8reiePrUBMYSD88v59a') jsn = json.loads(res) self.assertEqual(jsn['total'], 127) results = jsn['results'] self.assertEqual(len(results), 127) def test_8_bad_addr(self): mock_req = requestMock(path=b'/addr/AcFnRrVC5emrTEkuFuRPufcuTb6KsAJ3v') res = self.app.get_by_addr(mock_req, 'AcFnRrVC5emrTEkuFuRPufcuTb6KsAJ3v') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Could not get notifications', jsn['message']) def test_9_by_tx(self): mock_req = requestMock(path=b'/tx/0x4c927a7f365cb842ea3576eae474a89183c9e43970a8509b23570a86cb4f5121') res = self.app.get_by_tx(mock_req, '0x4c927a7f365cb842ea3576eae474a89183c9e43970a8509b23570a86cb4f5121') jsn = json.loads(res) self.assertEqual(jsn['total'], 1) results = jsn['results'] self.assertEqual(len(results), 1) def test_9_by_bad_tx(self): mock_req = requestMock(path=b'/tx/2e4168cb2d563714d3f35ff76b7efc6c7d428360c97b6b45a18b5b1a4faa40') res = self.app.get_by_tx(mock_req, b'2e4168cb2d563714d3f35ff76b7efc6c7d428360c97b6b45a18b5b1a4faa40') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Could not get tx with hash', jsn['message']) def test_get_by_contract(self): mock_req = requestMock(path=b'/contract/73d2f26ada9cd95861eed99e43f9aafa05630849') res = self.app.get_by_contract(mock_req, '73d2f26ada9cd95861eed99e43f9aafa05630849') jsn = json.loads(res) self.assertEqual(jsn['total'], 4) results = jsn['results'] self.assertEqual(len(results), 4) def test_get_by_contract_empty(self): mock_req = requestMock(path=b'/contract/a3d2f26ada9cd95861eed99e43f9aafa05630849') res = self.app.get_by_contract(mock_req, 'a3d2f26ada9cd95861eed99e43f9aafa05630849') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertEqual(len(results), 0) def test_get_tokens(self): mock_req = requestMock(path=b'/tokens') res = self.app.get_tokens(mock_req) jsn = json.loads(res) self.assertEqual(jsn['total'], 364) results = jsn['results'] self.assertIsInstance(results, list) def test_pagination_for_addr_results(self): mock_req = requestMock(path=b'/addr/AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM') res = self.app.get_by_addr(mock_req, 'AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM') jsn = json.loads(res) self.assertEqual(jsn['total'], 1027) results = jsn['results'] self.assertEqual(len(results), 500) mock_req = requestMock(path=b'/addr/AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM?page=1') res = self.app.get_by_addr(mock_req, 'AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM') jsn = json.loads(res) self.assertEqual(jsn['total'], 1027) results = jsn['results'] self.assertEqual(len(results), 500) mock_req = requestMock(path=b'/addr/AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM?page=2') res = self.app.get_by_addr(mock_req, 'AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM') jsn = json.loads(res) self.assertEqual(jsn['total'], 1027) results = jsn['results'] self.assertEqual(len(results), 27) def test_block_heigher_than_current(self): mock_req = requestMock(path=b'/block/8000000') res = self.app.get_by_block(mock_req, 800000) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Higher than current block', jsn['message'])
class NotificationDBTestCase(BlockchainFixtureTestCase): N_FIXTURE_REMOTE_LOC = 'https://s3.us-east-2.amazonaws.com/cityofzion/fixtures/notif_fixture_v3.tar.gz' N_FIXTURE_FILENAME = os.path.join(settings.DATA_DIR_PATH, 'Chains/notif_fixture_v3.tar.gz') N_NOTIFICATION_DB_NAME = os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_notifications') contract_hash = UInt160(data=bytearray( b'\x11\xc4\xd1\xf4\xfb\xa6\x19\xf2b\x88p\xd3n:\x97s\xe8tp[')) event_tx = '042e4168cb2d563714d3f35ff76b7efc6c7d428360c97b6b45a18b5b1a4faa40' addr_to = 'AHbmRX5sL8oxp4dJZRNg5crCGUGxuMUyRB' addr_from = 'AcFnRrVC5emrTEkuFuRPufcuTb6KsAJ3vR' app = None # type:RestApi @classmethod def leveldb_testpath(self): return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain') @classmethod def setUpClass(cls): super(NotificationDBTestCase, cls).setUpClass() if not os.path.exists(cls.N_FIXTURE_FILENAME): logzero.logger.info( "downloading fixture notification database from %s. this may take a while" % cls.N_FIXTURE_REMOTE_LOC) response = requests.get(cls.N_FIXTURE_REMOTE_LOC, stream=True) response.raise_for_status() with open(cls.N_FIXTURE_FILENAME, 'wb+') as handle: for block in response.iter_content(1024): handle.write(block) try: tar = tarfile.open(cls.N_FIXTURE_FILENAME) tar.extractall(path=settings.DATA_DIR_PATH) tar.close() except Exception as e: raise Exception( "Could not extract tar file - %s. You may want need to remove the fixtures file %s manually to fix this." % (e, cls.N_FIXTURE_FILENAME)) if not os.path.exists(cls.N_NOTIFICATION_DB_NAME): raise Exception("Error downloading fixtures") settings.NOTIFICATION_DB_PATH = cls.N_NOTIFICATION_DB_NAME ndb = NotificationDB.instance() ndb.start() @classmethod def tearDownClass(cls): super(NotificationDBTestCase, cls).tearDownClass() NotificationDB.instance().close() shutil.rmtree(cls.N_NOTIFICATION_DB_NAME) def setUp(self): self.app = RestApi() def test_1_ok(self): ndb = NotificationDB.instance() events = ndb.get_by_block(627529) self.assertEqual(len(events), 1) def test_2_klein_app(self): self.assertIsNotNone(self.app.notif) def test_3_index(self): mock_req = requestMock(path=b'/') res = self.app.home(mock_req) self.assertIn('endpoints', res) def test_4_by_block(self): mock_req = requestMock(path=b'/block/627529') res = self.app.get_by_block(mock_req, 627529) jsn = json.loads(res) self.assertEqual(jsn['total'], 1) results = jsn['results'] self.assertEqual(len(results), 1) def test_5_block_no_results(self): mock_req = requestMock(path=b'/block/206') res = self.app.get_by_block(mock_req, 206) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, list) self.assertEqual(len(results), 0) def test_6_block_num_too_big(self): mock_req = requestMock(path=b'/block/2060200054055066') res = self.app.get_by_block(mock_req, 2060200054055066) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Higher than current block', jsn['message']) def test_7_by_addr(self): mock_req = requestMock( path=b'/addr/AL5e5ZcqtBTKjcQ8reiePrUBMYSD88v59a') res = self.app.get_by_addr(mock_req, 'AL5e5ZcqtBTKjcQ8reiePrUBMYSD88v59a') jsn = json.loads(res) self.assertEqual(jsn['total'], 127) results = jsn['results'] self.assertEqual(len(results), 127) def test_8_bad_addr(self): mock_req = requestMock(path=b'/addr/AcFnRrVC5emrTEkuFuRPufcuTb6KsAJ3v') res = self.app.get_by_addr(mock_req, 'AcFnRrVC5emrTEkuFuRPufcuTb6KsAJ3v') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Could not get notifications', jsn['message']) def test_9_by_tx(self): mock_req = requestMock( path= b'/tx/0x4c927a7f365cb842ea3576eae474a89183c9e43970a8509b23570a86cb4f5121' ) res = self.app.get_by_tx( mock_req, '0x4c927a7f365cb842ea3576eae474a89183c9e43970a8509b23570a86cb4f5121' ) jsn = json.loads(res) self.assertEqual(jsn['total'], 1) results = jsn['results'] self.assertEqual(len(results), 1) def test_9_by_bad_tx(self): mock_req = requestMock( path= b'/tx/2e4168cb2d563714d3f35ff76b7efc6c7d428360c97b6b45a18b5b1a4faa40' ) res = self.app.get_by_tx( mock_req, b'2e4168cb2d563714d3f35ff76b7efc6c7d428360c97b6b45a18b5b1a4faa40') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Could not get tx with hash', jsn['message']) def test_get_by_contract(self): mock_req = requestMock( path=b'/contract/73d2f26ada9cd95861eed99e43f9aafa05630849') res = self.app.get_by_contract( mock_req, '73d2f26ada9cd95861eed99e43f9aafa05630849') jsn = json.loads(res) self.assertEqual(jsn['total'], 4) results = jsn['results'] self.assertEqual(len(results), 4) def test_get_by_contract_empty(self): mock_req = requestMock( path=b'/contract/a3d2f26ada9cd95861eed99e43f9aafa05630849') res = self.app.get_by_contract( mock_req, 'a3d2f26ada9cd95861eed99e43f9aafa05630849') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertEqual(len(results), 0) def test_get_tokens(self): mock_req = requestMock(path=b'/tokens') res = self.app.get_tokens(mock_req) jsn = json.loads(res) self.assertEqual(jsn['total'], 364) results = jsn['results'] self.assertIsInstance(results, list) def test_pagination_for_addr_results(self): mock_req = requestMock( path=b'/addr/AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM') res = self.app.get_by_addr(mock_req, 'AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM') jsn = json.loads(res) self.assertEqual(jsn['total'], 1027) results = jsn['results'] self.assertEqual(len(results), 500) self.assertEqual(jsn['total_pages'], 3) mock_req = requestMock( path=b'/addr/AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM?page=1') res = self.app.get_by_addr(mock_req, 'AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM') jsn = json.loads(res) self.assertEqual(jsn['total'], 1027) results = jsn['results'] self.assertEqual(len(results), 500) mock_req = requestMock( path=b'/addr/AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM?page=2') res = self.app.get_by_addr(mock_req, 'AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM') jsn = json.loads(res) self.assertEqual(jsn['total'], 1027) results = jsn['results'] self.assertEqual(len(results), 500) mock_req = requestMock( path=b'/addr/AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM?page=3') res = self.app.get_by_addr(mock_req, 'AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM') jsn = json.loads(res) self.assertEqual(jsn['total'], 1027) results = jsn['results'] self.assertEqual(len(results), 27) def test_pagination_page_size_for_addr_results(self): mock_req = requestMock( path=b'/addr/AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM?pagesize=100') res = self.app.get_by_addr(mock_req, 'AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM') jsn = json.loads(res) self.assertEqual(jsn['total'], 1027) results = jsn['results'] self.assertEqual(len(results), 100) self.assertEqual(jsn['total_pages'], 11) mock_req = requestMock( path= b'/addr/AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM?pagesize=100&page=11') res = self.app.get_by_addr(mock_req, 'AFmseVrdL9f9oyCzZefL9tG6UbvhPbdYzM') jsn = json.loads(res) results = jsn['results'] self.assertEqual(len(results), 27) def test_block_heigher_than_current(self): mock_req = requestMock(path=b'/block/8000000') res = self.app.get_by_block(mock_req, 800000) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Higher than current block', jsn['message'])
class NotificationDBTestCase(BlockchainFixtureTestCase): N_FIXTURE_REMOTE_LOC = 'https://s3.us-east-2.amazonaws.com/cityofzion/fixtures/notif_fixtures_v8.tar.gz' N_FIXTURE_FILENAME = os.path.join(settings.DATA_DIR_PATH, 'Chains/notif_fixtures_v8.tar.gz') N_NOTIFICATION_DB_NAME = os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_notifications') app = None # type:RestApi @classmethod def leveldb_testpath(self): return os.path.join(settings.DATA_DIR_PATH, 'fixtures/test_chain') @classmethod def setUpClass(cls): super(NotificationDBTestCase, cls).setUpClass() if not os.path.exists(cls.N_FIXTURE_FILENAME): logzero.logger.info( "downloading fixture notification database from %s. this may take a while" % cls.N_FIXTURE_REMOTE_LOC) response = requests.get(cls.N_FIXTURE_REMOTE_LOC, stream=True) response.raise_for_status() with open(cls.N_FIXTURE_FILENAME, 'wb+') as handle: for block in response.iter_content(1024): handle.write(block) try: tar = tarfile.open(cls.N_FIXTURE_FILENAME) tar.extractall(path=settings.DATA_DIR_PATH) tar.close() except Exception as e: raise Exception( "Could not extract tar file - %s. You may want need to remove the fixtures file %s manually to fix this." % (e, cls.N_FIXTURE_FILENAME)) if not os.path.exists(cls.N_NOTIFICATION_DB_NAME): raise Exception("Error downloading fixtures") settings.NOTIFICATION_DB_PATH = cls.N_NOTIFICATION_DB_NAME ndb = NotificationDB.instance() ndb.start() @classmethod def tearDownClass(cls): super(NotificationDBTestCase, cls).tearDownClass() NotificationDB.instance().close() shutil.rmtree(cls.N_NOTIFICATION_DB_NAME) def setUp(self): self.app = RestApi() def test_1_ok(self): ndb = NotificationDB.instance() events = ndb.get_by_block(9583) self.assertEqual(len(events), 1) def test_2_klein_app(self): self.assertIsNotNone(self.app.notif) def test_3_index(self): mock_req = requestMock(path=b'/') res = self.app.home(mock_req) self.assertIn('endpoints', res) def test_4_by_block(self): mock_req = requestMock(path=b'/block/9583') res = self.app.get_by_block(mock_req, 9583) jsn = json.loads(res) self.assertEqual(jsn['total'], 1) results = jsn['results'] self.assertEqual(len(results), 1) def test_5_block_no_results(self): mock_req = requestMock(path=b'/block/206') res = self.app.get_by_block(mock_req, 206) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, list) self.assertEqual(len(results), 0) def test_6_block_num_too_big(self): mock_req = requestMock(path=b'/block/2060200054055066') res = self.app.get_by_block(mock_req, 2060200054055066) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Higher than current block', jsn['message']) def test_7_by_addr(self): mock_req = requestMock( path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 500) def test_8_bad_addr(self): mock_req = requestMock(path=b'/addr/AcFnRrVC5emrTEkuFuRPufcuTb6KsAJ3v') res = self.app.get_by_addr(mock_req, 'AcFnRrVC5emrTEkuFuRPufcuTb6KsAJ3v') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Could not get notifications', jsn['message']) def test_9_by_tx(self): mock_req = requestMock( path= b'/tx/0xa2a37fd2ab7048d70d51eaa8af2815e0e542400329b05a34274771174180a7e8' ) res = self.app.get_by_tx( mock_req, '0xa2a37fd2ab7048d70d51eaa8af2815e0e542400329b05a34274771174180a7e8' ) jsn = json.loads(res) self.assertEqual(jsn['total'], 1) results = jsn['results'] self.assertEqual(len(results), 1) def test_9_by_bad_tx(self): mock_req = requestMock( path= b'/tx/2e4168cb2d563714d3f35ff76b7efc6c7d428360c97b6b45a18b5b1a4faa40' ) res = self.app.get_by_tx( mock_req, b'2e4168cb2d563714d3f35ff76b7efc6c7d428360c97b6b45a18b5b1a4faa40') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Could not get tx with hash', jsn['message']) def test_get_by_contract(self): mock_req = requestMock( path=b'/contract/b9fbcff6e50fd381160b822207231233dd3c56c2') res = self.app.get_by_contract( mock_req, 'b9fbcff6e50fd381160b822207231233dd3c56c2') jsn = json.loads(res) self.assertEqual(jsn['total'], 1006) results = jsn['results'] self.assertEqual(len(results), 500) def test_get_by_contract_empty(self): mock_req = requestMock( path=b'/contract/910cba960880c75072d0c625dfff459f72aae047') res = self.app.get_by_contract( mock_req, '910cba960880c75072d0c625dfff459f72aae047') jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertEqual(len(results), 0) def test_get_tokens(self): mock_req = requestMock(path=b'/tokens') res = self.app.get_tokens(mock_req) jsn = json.loads(res) self.assertEqual(jsn['total'], 5) results = jsn['results'] self.assertIsInstance(results, list) def test_pagination_for_addr_results(self): mock_req = requestMock( path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 500) self.assertEqual(jsn['total_pages'], 3) mock_req = requestMock( path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9?page=1') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 500) mock_req = requestMock( path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9?page=2') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 500) mock_req = requestMock( path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9?page=3') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 7) def test_pagination_page_size_for_addr_results(self): mock_req = requestMock( path=b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9?pagesize=100') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) self.assertEqual(jsn['total'], 1007) results = jsn['results'] self.assertEqual(len(results), 100) self.assertEqual(jsn['total_pages'], 11) mock_req = requestMock( path= b'/addr/AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9?pagesize=100&page=11') res = self.app.get_by_addr(mock_req, 'AXpNr3SDfLXbPHNdqxYeHK5cYpKMHZxMZ9') jsn = json.loads(res) results = jsn['results'] self.assertEqual(len(results), 7) def test_block_heigher_than_current(self): mock_req = requestMock(path=b'/block/8000000') res = self.app.get_by_block(mock_req, 800000) jsn = json.loads(res) self.assertEqual(jsn['total'], 0) results = jsn['results'] self.assertIsInstance(results, type(None)) self.assertIn('Higher than current block', jsn['message'])
async def get_application(self): """ Override the get_app method to return your application. """ self.api_server = RestApi() return self.api_server.app