def assert_modifying_ethereum_tokens(server, data, ethereum_accounts, setup, expected_tokens): """Helper function to test the outcome of adding/removing ethereum tokens via the API""" assert_eth_balances_result( rotki=server.rest_api.rotkehlchen, json_data=data, eth_accounts=ethereum_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=False, ) # And also query tokens to see that it's properly added to the tracked tokens response = requests.get(api_url_for( server, "ethereumtokensresource", )) assert_proper_response(response) data = response.json() assert data['message'] == '' assert data['result']['owned_eth_tokens'] == expected_tokens
def test_multiple_balance_queries_not_concurrent( rotkehlchen_api_server_with_exchanges, ethereum_accounts, btc_accounts, separate_blockchain_calls, ): """Test multiple different balance query requests happening concurrently This tests that if multiple balance query requests happen concurrently we do not end up doing them multiple times, but reuse the results thanks to cache. Try running both all blockchain balances in one call and each blockchain call separately. """ rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen setup = setup_balances(rotki, ethereum_accounts, btc_accounts) multieth_balance_patch = patch.object( rotki.chain_manager.ethereum, 'get_multieth_balance', wraps=rotki.chain_manager.ethereum.get_multieth_balance, ) btc_balances_patch = patch( 'rotkehlchen.chain.manager.get_bitcoin_addresses_balances', wraps=get_bitcoin_addresses_balances, ) binance = rotki.exchange_manager.connected_exchanges['binance'] binance_querydict_patch = patch.object(binance, 'api_query_dict', wraps=binance.api_query_dict) # Test all balances request by requesting to not save the data with ExitStack() as stack: setup.enter_all_patches(stack) eth = stack.enter_context(multieth_balance_patch) btc = stack.enter_context(btc_balances_patch) bn = stack.enter_context(binance_querydict_patch) response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), json={'async_query': True}, ) task_id_all = assert_ok_async_response(response) response = requests.get(api_url_for( rotkehlchen_api_server_with_exchanges, "named_exchanges_balances_resource", name='binance', ), json={'async_query': True}) task_id_one_exchange = assert_ok_async_response(response) if separate_blockchain_calls: response = requests.get(api_url_for( rotkehlchen_api_server_with_exchanges, "blockchainbalancesresource", ), json={ 'async_query': True, 'blockchain': 'ETH' }) task_id_blockchain_eth = assert_ok_async_response(response) response = requests.get(api_url_for( rotkehlchen_api_server_with_exchanges, "blockchainbalancesresource", ), json={ 'async_query': True, 'blockchain': 'BTC' }) task_id_blockchain_btc = assert_ok_async_response(response) else: response = requests.get(api_url_for( rotkehlchen_api_server_with_exchanges, "blockchainbalancesresource", ), json={'async_query': True}) task_id_blockchain = assert_ok_async_response(response) outcome_all = wait_for_async_task_with_result( rotkehlchen_api_server_with_exchanges, task_id_all, timeout=ASYNC_TASK_WAIT_TIMEOUT * 2, ) outcome_one_exchange = wait_for_async_task( rotkehlchen_api_server_with_exchanges, task_id_one_exchange, timeout=ASYNC_TASK_WAIT_TIMEOUT * 2, ) if separate_blockchain_calls: outcome_eth = wait_for_async_task_with_result( rotkehlchen_api_server_with_exchanges, task_id_blockchain_eth, timeout=ASYNC_TASK_WAIT_TIMEOUT * 2, ) outcome_btc = wait_for_async_task_with_result( rotkehlchen_api_server_with_exchanges, task_id_blockchain_btc, timeout=ASYNC_TASK_WAIT_TIMEOUT * 2, ) else: outcome_blockchain = wait_for_async_task_with_result( rotkehlchen_api_server_with_exchanges, task_id_blockchain, timeout=ASYNC_TASK_WAIT_TIMEOUT * 2, ) assert eth.call_count == 1, 'eth balance query should only fire once' assert btc.call_count == 1, 'btc balance query should only happen once' assert bn.call_count == 3, 'binance balance query should do 2 calls' assert_all_balances( result=outcome_all, db=rotki.data.db, expected_data_in_db=True, setup=setup, ) assert_binance_balances_result(outcome_one_exchange['result']) if not separate_blockchain_calls: outcome_eth = outcome_blockchain outcome_btc = outcome_blockchain assert_eth_balances_result( rotki=rotki, result=outcome_eth, eth_accounts=ethereum_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=not separate_blockchain_calls, ) assert_btc_balances_result( result=outcome_btc, btc_accounts=btc_accounts, btc_balances=setup.btc_balances, also_eth=not separate_blockchain_calls, )
def test_remove_blockchain_accounts_async( rotkehlchen_api_server, ethereum_accounts, btc_accounts, number_of_eth_accounts, ): """A simpler version of the above test for removing blockchain accounts for async The main purpose of this test is to see that querying the endpoint asynchronously also works""" # Disable caching of query results rotki = rotkehlchen_api_server.rest_api.rotkehlchen rotki.blockchain.cache_ttl_secs = 0 # Test by having balances queried before removing an account removed_eth_accounts = [ethereum_accounts[0], ethereum_accounts[2]] eth_accounts_after_removal = [ethereum_accounts[1], ethereum_accounts[3]] all_eth_balances = ['1000000', '2000000', '3000000', '4000000'] token_balances = {'RDN': ['0', '250000000', '450000000', '0']} eth_balances_after_removal = ['2000000', '4000000'] token_balances_after_removal = {'RDN': ['250000000', '0']} setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=btc_accounts, eth_balances=all_eth_balances, token_balances=token_balances, ) with setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "blockchainbalancesresource", )) setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=btc_accounts, eth_balances=all_eth_balances, token_balances=token_balances, ) # The application has started with 4 ethereum accounts. Remove two and see that balances match with setup.etherscan_patch: response = requests.delete(api_url_for( rotkehlchen_api_server, "blockchainsaccountsresource", blockchain='ETH', ), json={ 'accounts': removed_eth_accounts, 'async_query': True }) task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert_eth_balances_result( rotki=rotki, json_data=outcome, eth_accounts=eth_accounts_after_removal, eth_balances=eth_balances_after_removal, token_balances=token_balances_after_removal, also_btc=True, # We queried all balances at the start ) # Also make sure they are removed from the DB accounts = rotki.data.db.get_blockchain_accounts() assert len(accounts.eth) == 2 assert all(acc in accounts.eth for acc in eth_accounts_after_removal) assert len(accounts.btc) == 2 assert all(acc in accounts.btc for acc in btc_accounts) # Now try to query all balances to make sure the result is the stored with setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "blockchainbalancesresource", )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_eth_balances_result( rotki=rotki, json_data=json_data, eth_accounts=eth_accounts_after_removal, eth_balances=eth_balances_after_removal, token_balances=token_balances_after_removal, also_btc=True, ) # Now we will try to remove a BTC account. Setup the mocking infrastructure again all_btc_accounts = [UNIT_BTC_ADDRESS1, UNIT_BTC_ADDRESS2] btc_accounts_after_removal = [UNIT_BTC_ADDRESS2] setup = setup_balances( rotki, ethereum_accounts=eth_accounts_after_removal, btc_accounts=all_btc_accounts, eth_balances=eth_balances_after_removal, token_balances=token_balances_after_removal, btc_balances=['3000000', '5000000'], ) # remove the new BTC account with setup.bitcoin_patch: response = requests.delete(api_url_for( rotkehlchen_api_server, "blockchainsaccountsresource", blockchain='BTC', ), json={ 'accounts': [UNIT_BTC_ADDRESS1], 'async_query': True }) task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert_btc_balances_result( json_data=outcome, btc_accounts=btc_accounts_after_removal, btc_balances=['5000000'], also_eth=True, ) # Also make sure it's removed from the DB accounts = rotki.data.db.get_blockchain_accounts() assert len(accounts.eth) == 2 assert all(acc in accounts.eth for acc in eth_accounts_after_removal) assert len(accounts.btc) == 1 assert all(acc in accounts.btc for acc in btc_accounts_after_removal) # Now try to query all balances to make sure the result is also stored with setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "blockchainbalancesresource", )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_btc_balances_result( json_data=json_data, btc_accounts=btc_accounts_after_removal, btc_balances=['5000000'], also_eth=True, )
def test_multiple_balance_queries_not_concurrent( rotkehlchen_api_server_with_exchanges, ethereum_accounts, btc_accounts, ): """Test multiple different balance query requests happening concurrently This tests that if multiple balance query requests happen concurrently we do not end up doing them multiple times, but reuse the results thanks to cache. """ rotki = rotkehlchen_api_server_with_exchanges.rest_api.rotkehlchen setup = setup_balances(rotki, ethereum_accounts, btc_accounts) multieth_balance_patch = patch.object( rotki.chain_manager.ethereum, 'get_multieth_balance', wraps=rotki.chain_manager.ethereum.get_multieth_balance, ) binance = rotki.exchange_manager.connected_exchanges['binance'] binance_querydict_patch = patch.object(binance, 'api_query_dict', wraps=binance.api_query_dict) # Test all balances request by requesting to not save the data with ExitStack() as stack: setup.enter_all_patches(stack) eth = stack.enter_context(multieth_balance_patch) bn = stack.enter_context(binance_querydict_patch) response = requests.get( api_url_for( rotkehlchen_api_server_with_exchanges, "allbalancesresource", ), json={'async_query': True}, ) task_id_all = assert_ok_async_response(response) response = requests.get(api_url_for( rotkehlchen_api_server_with_exchanges, "named_exchanges_balances_resource", name='binance', ), json={'async_query': True}) task_id_one_exchange = assert_ok_async_response(response) response = requests.get(api_url_for( rotkehlchen_api_server_with_exchanges, "blockchainbalancesresource", ), json={'async_query': True}) task_id_blockchain = assert_ok_async_response(response) outcome_all = wait_for_async_task_with_result( rotkehlchen_api_server_with_exchanges, task_id_all, ) outcome_one_exchange = wait_for_async_task( rotkehlchen_api_server_with_exchanges, task_id_one_exchange, ) outcome_blockchain = wait_for_async_task_with_result( rotkehlchen_api_server_with_exchanges, task_id_blockchain, ) assert eth.call_count == 1, 'blockchain balance call should not happen concurrently' assert bn.call_count == 1, 'binance balance call should not happen concurrently' assert_all_balances( result=outcome_all, db=rotki.data.db, expected_data_in_db=True, setup=setup, ) assert_binance_balances_result(outcome_one_exchange['result']) assert_eth_balances_result( rotki=rotki, result=outcome_blockchain, eth_accounts=ethereum_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=True, )
def test_remove_blockchain_accounts( rotkehlchen_api_server, ethereum_accounts, btc_accounts, number_of_eth_accounts, query_balances_before_first_modification, ): """Test that the endpoint removing blockchain accounts works properly""" # Disable caching of query results rotki = rotkehlchen_api_server.rest_api.rotkehlchen rotki.blockchain.cache_ttl_secs = 0 removed_eth_accounts = [ethereum_accounts[0], ethereum_accounts[2]] eth_accounts_after_removal = [ethereum_accounts[1], ethereum_accounts[3]] all_eth_balances = ['1000000', '2000000', '3000000', '4000000'] token_balances = {'RDN': ['0', '0', '450000000', '0']} eth_balances_after_removal = ['2000000', '4000000'] token_balances_after_removal = {'RDN': ['0', '0']} if query_balances_before_first_modification: # Also test by having balances queried before removing an account setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=btc_accounts, eth_balances=all_eth_balances, token_balances=token_balances, ) with setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "blockchainbalancesresource", )) setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=btc_accounts, eth_balances=all_eth_balances, token_balances=token_balances, ) # The application has started with 4 ethereum accounts. Remove two and see that balances match with setup.etherscan_patch: response = requests.delete(api_url_for( rotkehlchen_api_server, "blockchainsaccountsresource", blockchain='ETH', ), json={'accounts': removed_eth_accounts}) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_eth_balances_result( rotki=rotki, json_data=json_data, eth_accounts=eth_accounts_after_removal, eth_balances=eth_balances_after_removal, token_balances=token_balances_after_removal, also_btc=query_balances_before_first_modification, ) # Also make sure they are removed from the DB accounts = rotki.data.db.get_blockchain_accounts() assert len(accounts.eth) == 2 assert all(acc in accounts.eth for acc in eth_accounts_after_removal) assert len(accounts.btc) == 2 assert all(acc in accounts.btc for acc in btc_accounts) # Now try to query all balances to make sure the result is the stored with setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "blockchainbalancesresource", )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_eth_balances_result( rotki=rotki, json_data=json_data, eth_accounts=eth_accounts_after_removal, eth_balances=eth_balances_after_removal, token_balances=token_balances_after_removal, also_btc=True, ) # Now we will try to remove a BTC account. Setup the mocking infrastructure again all_btc_accounts = [UNIT_BTC_ADDRESS1, UNIT_BTC_ADDRESS2] btc_accounts_after_removal = [UNIT_BTC_ADDRESS2] setup = setup_balances( rotki, ethereum_accounts=eth_accounts_after_removal, btc_accounts=all_btc_accounts, eth_balances=eth_balances_after_removal, token_balances=token_balances_after_removal, btc_balances=['3000000', '5000000'], ) # remove the new BTC account with setup.bitcoin_patch: response = requests.delete(api_url_for( rotkehlchen_api_server, "blockchainsaccountsresource", blockchain='BTC', ), json={'accounts': [UNIT_BTC_ADDRESS1]}) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_btc_balances_result( json_data=json_data, btc_accounts=btc_accounts_after_removal, btc_balances=['5000000'], also_eth=True, ) # Also make sure it's removed from the DB accounts = rotki.data.db.get_blockchain_accounts() assert len(accounts.eth) == 2 assert all(acc in accounts.eth for acc in eth_accounts_after_removal) assert len(accounts.btc) == 1 assert all(acc in accounts.btc for acc in btc_accounts_after_removal) # Now try to query all balances to make sure the result is also stored with setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "blockchainbalancesresource", )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_btc_balances_result( json_data=json_data, btc_accounts=btc_accounts_after_removal, btc_balances=['5000000'], also_eth=True, )
def test_add_blockchain_accounts_async( rotkehlchen_api_server, ethereum_accounts, btc_accounts, number_of_eth_accounts, ): """A simpler version of the above test for adding blockchain accounts for async The main purpose of this test is to see that querying the endpoint asynchronously also works""" # Disable caching of query results rotki = rotkehlchen_api_server.rest_api.rotkehlchen rotki.blockchain.cache_ttl_secs = 0 # Test by having balances queried before adding an account eth_balances = ['1000000', '2000000'] token_balances = {'RDN': ['0', '4000000']} setup = setup_balances( rotki, ethereum_accounts=ethereum_accounts, btc_accounts=btc_accounts, eth_balances=eth_balances, token_balances=token_balances, ) new_eth_accounts = [make_ethereum_address(), make_ethereum_address()] all_eth_accounts = ethereum_accounts + new_eth_accounts eth_balances = ['1000000', '2000000', '3000000', '4000000'] token_balances = {'RDN': ['0', '4000000', '0', '250000000']} setup = setup_balances( rotki, ethereum_accounts=all_eth_accounts, btc_accounts=btc_accounts, eth_balances=eth_balances, token_balances=token_balances, ) # The application has started only with 2 ethereum accounts. Let's add two more with setup.etherscan_patch: response = requests.put(api_url_for( rotkehlchen_api_server, "blockchainsaccountsresource", blockchain='ETH', ), json={ 'accounts': new_eth_accounts, 'async_query': True }) task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert_eth_balances_result( rotki=rotki, json_data=outcome, eth_accounts=all_eth_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=False, # All blockchain assets have not been queried yet ) # Also make sure they are added in the DB accounts = rotki.data.db.get_blockchain_accounts() assert len(accounts.eth) == 4 assert all(acc in accounts.eth for acc in all_eth_accounts) assert len(accounts.btc) == 2 assert all(acc in accounts.btc for acc in btc_accounts) # Now try to query all balances to make sure the result is the stored with setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "blockchainbalancesresource", )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_eth_balances_result( rotki=rotki, json_data=json_data, eth_accounts=all_eth_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=True, ) # Now we will try to add a new BTC account. Setup the mocking infrastructure again all_btc_accounts = btc_accounts + [UNIT_BTC_ADDRESS3] setup = setup_balances( rotki, ethereum_accounts=all_eth_accounts, btc_accounts=all_btc_accounts, eth_balances=eth_balances, token_balances=token_balances, btc_balances=['3000000', '5000000', '600000000'], ) # add the new BTC account with setup.bitcoin_patch: response = requests.put(api_url_for( rotkehlchen_api_server, "blockchainsaccountsresource", blockchain='BTC', ), json={ 'accounts': [UNIT_BTC_ADDRESS3], 'async_query': True }) task_id = assert_ok_async_response(response) outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert_btc_balances_result( json_data=outcome, btc_accounts=all_btc_accounts, btc_balances=setup.btc_balances, also_eth=True, ) # Also make sure it's added in the DB accounts = rotki.data.db.get_blockchain_accounts() assert len(accounts.eth) == 4 assert all(acc in accounts.eth for acc in all_eth_accounts) assert len(accounts.btc) == 3 assert all(acc in accounts.btc for acc in all_btc_accounts) # Now try to query all balances to make sure the result is also stored with setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "blockchainbalancesresource", )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_btc_balances_result( json_data=json_data, btc_accounts=all_btc_accounts, btc_balances=setup.btc_balances, also_eth=True, )
def test_query_blockchain_balances( rotkehlchen_api_server, ethereum_accounts, btc_accounts, number_of_eth_accounts, ): """Test that the query blockchain balances endpoint works correctly. That is: - Querying only ETH chain returns only ETH and token balances - Querying only BTC chain returns only BTC account balances - Querying with no chain returns all balances (ETH, tokens and BTC) """ # Disable caching of query results rotki = rotkehlchen_api_server.rest_api.rotkehlchen rotki.blockchain.cache_ttl_secs = 0 setup = setup_balances(rotki, ethereum_accounts=ethereum_accounts, btc_accounts=btc_accounts) # First query only ETH and token balances with setup.etherscan_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "named_blockchain_balances_resource", blockchain='ETH', )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_eth_balances_result( rotki=rotki, json_data=json_data, eth_accounts=ethereum_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=False, ) # Then query only BTC balances with setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "named_blockchain_balances_resource", blockchain='BTC', )) assert_proper_response(response) assert json_data['message'] == '' json_data = response.json() assert_btc_balances_result( json_data=json_data, btc_accounts=btc_accounts, btc_balances=setup.btc_balances, also_eth=False, ) # Finally query all balances with setup.etherscan_patch, setup.bitcoin_patch: response = requests.get( api_url_for( rotkehlchen_api_server, "blockchainbalancesresource", )) assert_proper_response(response) assert json_data['message'] == '' json_data = response.json() assert_eth_balances_result( rotki=rotki, json_data=json_data, eth_accounts=ethereum_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=True, ) assert_btc_balances_result( json_data=json_data, btc_accounts=btc_accounts, btc_balances=setup.btc_balances, also_eth=True, ) # Try to query not existing blockchain response = requests.get( api_url_for( rotkehlchen_api_server, "named_blockchain_balances_resource", blockchain='NOTEXISTING', )) assert_error_response( response=response, contained_in_msg= 'Unrecognized value NOTEXISTING given for blockchain name', )
def test_query_blockchain_balances_ignore_cache( rotkehlchen_api_server, ethereum_accounts, btc_accounts, number_of_eth_accounts, ): """Test that the query blockchain balances endpoint can ignore the cache""" rotki = rotkehlchen_api_server.rest_api.rotkehlchen setup = setup_balances(rotki, ethereum_accounts=ethereum_accounts, btc_accounts=btc_accounts) eth_query = patch.object( rotki.blockchain, 'query_ethereum_balances', wraps=rotki.blockchain.query_ethereum_balances, ) tokens_query = patch.object( rotki.blockchain, 'query_ethereum_tokens', wraps=rotki.blockchain.query_ethereum_tokens, ) with setup.etherscan_patch, setup.bitcoin_patch, eth_query as eth_mock, tokens_query as tokens_mock: # noqa: E501 # Query ETH and token balances once response = requests.get( api_url_for( rotkehlchen_api_server, "named_blockchain_balances_resource", blockchain='ETH', )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_eth_balances_result( rotki=rotki, json_data=json_data, eth_accounts=ethereum_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=False, ) assert eth_mock.call_count == 1 assert tokens_mock.call_count == 1 # Query again and make sure this time cache is used response = requests.get( api_url_for( rotkehlchen_api_server, "named_blockchain_balances_resource", blockchain='ETH', )) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_eth_balances_result( rotki=rotki, json_data=json_data, eth_accounts=ethereum_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=False, ) assert eth_mock.call_count == 1 assert tokens_mock.call_count == 1 # Finally query with ignoring the cache response = requests.get(api_url_for( rotkehlchen_api_server, "named_blockchain_balances_resource", blockchain='ETH', ), json={'ignore_cache': True}) assert_proper_response(response) json_data = response.json() assert json_data['message'] == '' assert_eth_balances_result( rotki=rotki, json_data=json_data, eth_accounts=ethereum_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=False, ) assert eth_mock.call_count == 2 assert tokens_mock.call_count == 2
def test_query_blockchain_balances_async( rotkehlchen_api_server, ethereum_accounts, btc_accounts, number_of_eth_accounts, ): """Test that the query blockchain balances endpoint works when queried asynchronously """ # Disable caching of query results rotki = rotkehlchen_api_server.rest_api.rotkehlchen rotki.blockchain.cache_ttl_secs = 0 setup = setup_balances(rotki, ethereum_accounts=ethereum_accounts, btc_accounts=btc_accounts) # First query only ETH and token balances response = requests.get(api_url_for( rotkehlchen_api_server, "named_blockchain_balances_resource", blockchain='ETH', ), json={'async_query': True}) task_id = assert_ok_async_response(response) with setup.etherscan_patch: outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert_eth_balances_result( rotki=rotki, json_data=outcome, eth_accounts=ethereum_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=False, ) # Then query only BTC balances response = requests.get(api_url_for( rotkehlchen_api_server, "named_blockchain_balances_resource", blockchain='BTC', ), json={'async_query': True}) task_id = assert_ok_async_response(response) with setup.bitcoin_patch: outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert_btc_balances_result( json_data=outcome, btc_accounts=btc_accounts, btc_balances=setup.btc_balances, also_eth=False, ) # Finally query all balances response = requests.get(api_url_for( rotkehlchen_api_server, "blockchainbalancesresource", ), json={'async_query': True}) task_id = assert_ok_async_response(response) with setup.etherscan_patch, setup.bitcoin_patch: outcome = wait_for_async_task(rotkehlchen_api_server, task_id) assert_eth_balances_result( rotki=rotki, json_data=outcome, eth_accounts=ethereum_accounts, eth_balances=setup.eth_balances, token_balances=setup.token_balances, also_btc=True, ) assert_btc_balances_result( json_data=outcome, btc_accounts=btc_accounts, btc_balances=setup.btc_balances, also_eth=True, )