From 7582ccc362707f91d3a52049d8dea8918649e83a Mon Sep 17 00:00:00 2001 From: trentmc Date: Mon, 27 Jan 2025 07:14:18 +0100 Subject: [PATCH] delete many dirs and unit tests. pytest passing, now takes 67.5 s --- pdr_backend/accuracy/app.py | 376 ---------------- pdr_backend/accuracy/output/index | 0 pdr_backend/accuracy/test/test_app.py | 108 ----- pdr_backend/cli/test/test_cli_module.py | 167 ------- pdr_backend/contract/test/conftest.py | 1 - .../contract/test/test_base_contract.py | 81 ---- pdr_backend/contract/test/test_data_nft.py | 68 --- pdr_backend/contract/test/test_dfrewards.py | 19 - .../contract/test/test_erc721_factory.py | 68 --- pdr_backend/contract/test/test_fixed_rate.py | 36 -- .../contract/test/test_predictoor_batcher.py | 150 ------- .../contract/test/test_predictoor_contract.py | 212 --------- pdr_backend/contract/test/test_slot.py | 23 - pdr_backend/contract/test/test_token.py | 44 -- .../contract/test/test_wrapped_token.py | 21 - pdr_backend/dfbuyer/test/conftest.py | 55 --- .../dfbuyer/test/test_dfbuyer_agent.py | 308 ------------- .../test/test_callbacks_common.py | 43 -- .../test/test_callbacks_feeds.py | 284 ------------ .../test/test_callbacks_predictoors.py | 231 ---------- pdr_backend/pred_submitter/test/conftest.py | 0 .../pred_submitter/test/test_deploy.py | 16 - .../test/test_pred_submitter_manager.py | 226 ---------- pdr_backend/predictoor/test/mockutil.py | 117 ----- .../predictoor/test/test_find_shared_slots.py | 64 --- .../predictoor/test/test_predictoor_agent.py | 407 ------------------ .../predictoor/test/test_stakes_per_slot.py | 79 ---- pdr_backend/publisher/test/conftest.py | 1 - .../publisher/test/test_publish_asset.py | 49 --- .../publisher/test/test_publish_assets.py | 71 --- pdr_backend/sim/test/test_sim_engine.py | 43 +- .../statutil/test/test_arima_dash_plots.py | 59 --- pdr_backend/statutil/test/test_seasonal.py | 139 ------ pdr_backend/subgraph/test/resources.py | 24 -- .../subgraph/test/test_core_subgraph.py | 20 - pdr_backend/subgraph/test/test_info725.py | 135 ------ .../test/test_subgraph_consume_so_far.py | 67 --- .../subgraph/test/test_subgraph_feed.py | 82 ---- .../test/test_subgraph_feed_contracts.py | 113 ----- .../subgraph/test/test_subgraph_payout.py | 89 ---- .../test/test_subgraph_pending_payouts.py | 61 --- .../test/test_subgraph_pending_slots.py | 69 --- .../test/test_subgraph_predictions.py | 281 ------------ .../subgraph/test/test_subgraph_slot.py | 109 ----- .../test/test_subgraph_subscriptions.py | 142 ------ .../subgraph/test/test_subgraph_sync.py | 47 -- .../subgraph/test/test_subgraph_trueval.py | 67 --- pdr_backend/subgraph/test/test_trueval.py | 14 - pdr_backend/trueval/test/conftest.py | 36 -- pdr_backend/trueval/test/test_get_trueval.py | 42 -- .../trueval/test/test_trueval_agent.py | 176 -------- pdr_backend/util/test_ganache/__init__.py | 0 pdr_backend/util/test_ganache/conftest.py | 1 - .../util/test_ganache/test_core_accounts.py | 54 --- .../util/test_ganache/test_networkutil.py | 37 -- .../util/test_ganache/test_web3_accounts.py | 93 ---- .../util/test_ganache/test_web3_config.py | 87 ---- system_tests/__init__.py | 0 system_tests/conftest.py | 47 -- system_tests/test_check_network_system.py | 74 ---- system_tests/test_dfbuyer_agent_system.py | 97 ----- .../test_get_predictions_info_system.py | 96 ----- .../test_get_predictoors_info_system.py | 104 ----- system_tests/test_ocean_payout.py | 76 ---- system_tests/test_predictoor_system.py | 108 ----- system_tests/test_publisher_system.py | 39 -- system_tests/test_rose_payout.py | 70 --- system_tests/test_topup_system.py | 69 --- system_tests/test_trader_agent_system.py | 90 ---- system_tests/test_trueval_agent_system.py | 77 ---- 70 files changed, 1 insertion(+), 6358 deletions(-) delete mode 100644 pdr_backend/accuracy/app.py delete mode 100644 pdr_backend/accuracy/output/index delete mode 100644 pdr_backend/accuracy/test/test_app.py delete mode 100644 pdr_backend/contract/test/conftest.py delete mode 100644 pdr_backend/contract/test/test_base_contract.py delete mode 100644 pdr_backend/contract/test/test_data_nft.py delete mode 100644 pdr_backend/contract/test/test_dfrewards.py delete mode 100644 pdr_backend/contract/test/test_erc721_factory.py delete mode 100644 pdr_backend/contract/test/test_fixed_rate.py delete mode 100644 pdr_backend/contract/test/test_predictoor_batcher.py delete mode 100644 pdr_backend/contract/test/test_predictoor_contract.py delete mode 100644 pdr_backend/contract/test/test_slot.py delete mode 100644 pdr_backend/contract/test/test_token.py delete mode 100644 pdr_backend/contract/test/test_wrapped_token.py delete mode 100644 pdr_backend/dfbuyer/test/conftest.py delete mode 100644 pdr_backend/dfbuyer/test/test_dfbuyer_agent.py delete mode 100644 pdr_backend/pdr_dashboard/test/test_callbacks_common.py delete mode 100644 pdr_backend/pdr_dashboard/test/test_callbacks_feeds.py delete mode 100644 pdr_backend/pdr_dashboard/test/test_callbacks_predictoors.py delete mode 100644 pdr_backend/pred_submitter/test/conftest.py delete mode 100644 pdr_backend/pred_submitter/test/test_deploy.py delete mode 100644 pdr_backend/pred_submitter/test/test_pred_submitter_manager.py delete mode 100644 pdr_backend/predictoor/test/mockutil.py delete mode 100644 pdr_backend/predictoor/test/test_find_shared_slots.py delete mode 100644 pdr_backend/predictoor/test/test_predictoor_agent.py delete mode 100644 pdr_backend/predictoor/test/test_stakes_per_slot.py delete mode 100644 pdr_backend/publisher/test/conftest.py delete mode 100644 pdr_backend/publisher/test/test_publish_asset.py delete mode 100644 pdr_backend/publisher/test/test_publish_assets.py delete mode 100644 pdr_backend/statutil/test/test_arima_dash_plots.py delete mode 100644 pdr_backend/statutil/test/test_seasonal.py delete mode 100644 pdr_backend/subgraph/test/resources.py delete mode 100644 pdr_backend/subgraph/test/test_core_subgraph.py delete mode 100644 pdr_backend/subgraph/test/test_info725.py delete mode 100644 pdr_backend/subgraph/test/test_subgraph_consume_so_far.py delete mode 100644 pdr_backend/subgraph/test/test_subgraph_feed.py delete mode 100644 pdr_backend/subgraph/test/test_subgraph_feed_contracts.py delete mode 100644 pdr_backend/subgraph/test/test_subgraph_payout.py delete mode 100644 pdr_backend/subgraph/test/test_subgraph_pending_payouts.py delete mode 100644 pdr_backend/subgraph/test/test_subgraph_pending_slots.py delete mode 100644 pdr_backend/subgraph/test/test_subgraph_predictions.py delete mode 100644 pdr_backend/subgraph/test/test_subgraph_slot.py delete mode 100644 pdr_backend/subgraph/test/test_subgraph_subscriptions.py delete mode 100644 pdr_backend/subgraph/test/test_subgraph_sync.py delete mode 100644 pdr_backend/subgraph/test/test_subgraph_trueval.py delete mode 100644 pdr_backend/subgraph/test/test_trueval.py delete mode 100644 pdr_backend/trueval/test/conftest.py delete mode 100644 pdr_backend/trueval/test/test_get_trueval.py delete mode 100644 pdr_backend/trueval/test/test_trueval_agent.py delete mode 100644 pdr_backend/util/test_ganache/__init__.py delete mode 100644 pdr_backend/util/test_ganache/conftest.py delete mode 100644 pdr_backend/util/test_ganache/test_core_accounts.py delete mode 100644 pdr_backend/util/test_ganache/test_networkutil.py delete mode 100644 pdr_backend/util/test_ganache/test_web3_accounts.py delete mode 100644 pdr_backend/util/test_ganache/test_web3_config.py delete mode 100644 system_tests/__init__.py delete mode 100644 system_tests/conftest.py delete mode 100644 system_tests/test_check_network_system.py delete mode 100644 system_tests/test_dfbuyer_agent_system.py delete mode 100644 system_tests/test_get_predictions_info_system.py delete mode 100644 system_tests/test_get_predictoors_info_system.py delete mode 100644 system_tests/test_ocean_payout.py delete mode 100644 system_tests/test_predictoor_system.py delete mode 100644 system_tests/test_publisher_system.py delete mode 100644 system_tests/test_rose_payout.py delete mode 100644 system_tests/test_topup_system.py delete mode 100644 system_tests/test_trader_agent_system.py delete mode 100644 system_tests/test_trueval_agent_system.py diff --git a/pdr_backend/accuracy/app.py b/pdr_backend/accuracy/app.py deleted file mode 100644 index 54c4377fc..000000000 --- a/pdr_backend/accuracy/app.py +++ /dev/null @@ -1,376 +0,0 @@ -# -# Copyright 2024 Ocean Protocol Foundation -# SPDX-License-Identifier: Apache-2.0 -# -import json -import logging -import threading -from datetime import datetime, timedelta -from typing import Any, Dict, List, Optional, Tuple - -from enforce_typing import enforce_types -from flask import Flask, jsonify - -from pdr_backend.subgraph.subgraph_predictions import ( - fetch_contract_id_and_spe, - ContractIdAndSPE, -) -from pdr_backend.subgraph.legacy.subgraph_slot import ( - fetch_slots_for_all_assets, - PredictSlot, -) -from pdr_backend.util.time_types import UnixTimeS -from pdr_backend.util.constants import WHITELIST_FEEDS_MAINNET -from pdr_backend.subgraph.legacy.subgraph_slot import PredictSlotStatus - -app = Flask(__name__) -JSON_FILE_PATH = "pdr_backend/accuracy/output/accuracy_data.json" -SECONDS_IN_A_DAY = 86400 -logger = logging.getLogger("accuracy_app") - - -@enforce_types -def calculate_prediction_result( - round_sum_stakes_up: float, round_sum_stakes: float -) -> Optional[bool]: - """ - Calculates the prediction result based on the sum of stakes. - - Args: - round_sum_stakes_up: The summed stakes for the 'up' prediction. - round_sum_stakes: The summed stakes for all prediction. - - Returns: - A boolean indicating the predicted direction. - """ - - # checks for to be sure that the division is not by zero - round_sum_stakes_up_float = float(round_sum_stakes_up) - round_sum_stakes_float = float(round_sum_stakes) - - if round_sum_stakes_float == 0.0: - return None - - if round_sum_stakes_up_float == 0.0: - return False - - return (round_sum_stakes_up_float / round_sum_stakes_float) > 0.5 - - -@enforce_types -def process_single_slot( - slot: PredictSlot, end_of_previous_day_timestamp: UnixTimeS -) -> Optional[Tuple[float, float, int, int]]: - """ - Processes a single slot and calculates the staked amounts for yesterday and today, - as well as the count of correct predictions. - - Args: - slot: A PredictSlot TypedDict containing information about a single prediction slot. - end_of_previous_day_timestamp: The Unix timestamp marking the end of the previous day. - - Returns: - A tuple containing staked amounts for yesterday, today, and the counts of correct - predictions and slots evaluated, or None if no stakes were made today. - """ - - staked_yesterday = staked_today = 0.0 - correct_predictions_count = slots_evaluated = 0 - - if float(slot.roundSumStakes) == 0.0: - return None - - # split the id to get the slot timestamp - timestamp = UnixTimeS( - int(slot.ID.split("-")[1]) - ) # Using dot notation for attribute access - - if ( - end_of_previous_day_timestamp - SECONDS_IN_A_DAY - < timestamp - < end_of_previous_day_timestamp - ): - staked_yesterday += float(slot.roundSumStakes) - elif timestamp > end_of_previous_day_timestamp: - staked_today += float(slot.roundSumStakes) - - prediction_result = calculate_prediction_result( - slot.roundSumStakesUp, slot.roundSumStakes - ) - - if prediction_result is None: - return ( - staked_yesterday, - staked_today, - correct_predictions_count, - slots_evaluated, - ) - - true_values: List[Dict[str, Any]] = slot.trueValues or [] - true_value: Optional[bool] = true_values[0]["trueValue"] if true_values else None - - if ( - len(true_values) > 0 - and prediction_result == true_value - and (slot.status != PredictSlotStatus.CANCELED) - ): - correct_predictions_count += 1 - - if ( - len(true_values) > 0 - and true_value is not None - and (slot.status != PredictSlotStatus.CANCELED) - ): - slots_evaluated += 1 - - return staked_yesterday, staked_today, correct_predictions_count, slots_evaluated - - -@enforce_types -def aggregate_statistics( - slots: List[PredictSlot], end_of_previous_day_timestamp: UnixTimeS -) -> Tuple[float, float, int, int]: - """ - Aggregates statistics across all provided slots for an asset. - - Args: - slots: A list of PredictSlot TypedDicts containing information - about multiple prediction slots. - end_of_previous_day_timestamp: The Unix timestamp marking the end of the previous day. - - Returns: - A tuple containing the total staked amounts for yesterday, today, - and the total counts of correct predictions and slots evaluated. - """ - - total_staked_yesterday = total_staked_today = total_correct_predictions = ( - total_slots_evaluated - ) = 0 - for slot in slots: - slot_results = process_single_slot(slot, end_of_previous_day_timestamp) - if slot_results: - ( - staked_yesterday, - staked_today, - correct_predictions_count, - slots_evaluated, - ) = slot_results - total_staked_yesterday += staked_yesterday - total_staked_today += staked_today - total_correct_predictions += correct_predictions_count - total_slots_evaluated += slots_evaluated - return ( - total_staked_yesterday, - total_staked_today, - total_correct_predictions, - total_slots_evaluated, - ) - - -@enforce_types -def calculate_statistics_for_all_assets( - asset_ids: List[str], - contracts_list: List[ContractIdAndSPE], - start_ts_param: UnixTimeS, - end_ts_param: UnixTimeS, - network: str = "mainnet", -) -> Dict[str, Dict[str, Any]]: - """ - Calculates statistics for all provided assets based on - slot data within a specified time range. - - Args: - asset_ids: A list of asset identifiers for which statistics will be calculated. - start_ts_param: The Unix timestamp for the start of the time range. - end_ts_param: The Unix timestamp for the end of the time range. - network: The blockchain network to query ('mainnet' or 'testnet'). - - Returns: - A dictionary mapping asset IDs to another dictionary with - calculated statistics such as average accuracy and total staked amounts. - """ - slots_by_asset = fetch_slots_for_all_assets( - asset_ids, start_ts_param, end_ts_param, network - ) - - overall_stats = {} - for asset_id, slots in slots_by_asset.items(): - ( - staked_yesterday, - staked_today, - correct_predictions_count, - slots_evaluated, - ) = aggregate_statistics(slots, UnixTimeS(end_ts_param - SECONDS_IN_A_DAY)) - average_accuracy = ( - 0 - if correct_predictions_count == 0 - else (correct_predictions_count / slots_evaluated) * 100 - ) - - # filter contracts to get the contract with the current asset id - contract_item = next( - ( - contract_item - for contract_item in contracts_list - if contract_item["ID"] == asset_id - ), - None, - ) - - overall_stats[asset_id] = { - "token_name": contract_item["name"] if contract_item else None, - "average_accuracy": average_accuracy, - "total_staked_yesterday": staked_yesterday, - "total_staked_today": staked_today, - } - - return overall_stats - - -@enforce_types -def calculate_timeframe_timestamps( - contract_timeframe: str, -) -> Tuple[UnixTimeS, UnixTimeS]: - """ - Calculates and returns a tuple of Unix timestamps for a start and end time - based on a given contract timeframe. The start time is determined to be either - 2 weeks or 4 weeks in the past, depending on whether the contract timeframe is - 5 minutes or 1 hour, respectively. The end time is the current timestamp. - - Args: - contract_timeframe (str): The contract timeframe, '5m' for 5 minutes or - other string values for different timeframes. - - Returns: - Tuple[int, int]: A tuple containing the start and end Unix timestamps. - """ - - end_ts = UnixTimeS(int(datetime.utcnow().timestamp())) - time_delta = ( - timedelta(weeks=1) - if contract_timeframe == "5m" - else timedelta(weeks=4) - # timedelta(days=1) - # if contract_timeframe == "5m" - # else timedelta(days=1) - ) - start_ts = UnixTimeS(int((datetime.utcnow() - time_delta).timestamp())) - - return start_ts, end_ts - - -@enforce_types -def save_statistics_to_file(): - """ - Periodically fetches and saves statistical data to a JSON file. - - This function runs an infinite loop that every 5 minutes triggers - data fetching for contract statistics. It uses prefetched contract - addresses and timeframes to gather statistics and save them to a file - in JSON format. - - If the process encounters an exception, it prints an error message and - continues after the next interval. - - The data includes statistics for each contract based on the 'seconds per epoch' - value defined for each statistic type. - """ - - network_param = "mainnet" # or 'testnet' depending on your preference - - statistic_types = [ - { - "alias": "5m", - "seconds_per_epoch": 300, - }, - { - "alias": "1h", - "seconds_per_epoch": 3600, - }, - ] - - contract_addresses = WHITELIST_FEEDS_MAINNET - - contracts_list_unfiltered = fetch_contract_id_and_spe( - contract_addresses, - network_param, - ) - - while True: - try: - output = [] - - for statistic_type in statistic_types: - seconds_per_epoch = statistic_type["seconds_per_epoch"] - contracts_list = list( - filter( - lambda item, spe=seconds_per_epoch: int( - item["seconds_per_epoch"] - ) - == spe, - contracts_list_unfiltered, - ) - ) - - start_ts_param, end_ts_param = calculate_timeframe_timestamps( - statistic_type["alias"] - ) - - contract_ids = [contract_item["ID"] for contract_item in contracts_list] - - statistics = calculate_statistics_for_all_assets( - contract_ids, - contracts_list, - start_ts_param, - end_ts_param, - network_param, - ) - - output.append( - { - "alias": statistic_type["alias"], - "statistics": statistics, - } - ) - - with open(JSON_FILE_PATH, "w") as f: - json.dump(output, f) - - logger.info("Data saved to JSON") - except Exception as e: - logger.error("Error: %s", e) - - threading.Event().wait(300) # Wait for 5 minutes (300 seconds) - - -@enforce_types -@app.route("/statistics", methods=["GET"]) -def serve_statistics_from_file(): - """ - Serves statistical data from a JSON file via a GET request. - - When a GET request is made to the '/statistics' route, - this function reads the statistical data from the JSON file - and returns it as a JSON response. - - If the file cannot be read or another error occurs, it returns a 500 Internal Server Error. - """ - - try: - with open(JSON_FILE_PATH, "r") as f: - data = json.load(f) - response = jsonify(data) - response.headers.add("Access-Control-Allow-Origin", "*") # Allow any origin - return response - except Exception as e: - response = jsonify({"error": "Internal Server Error", "message": str(e)}) - response.headers.add("Access-Control-Allow-Origin", "*") # Allow any origin - return response, 500 - - -if __name__ == "__main__": - # Start the thread to save predictions data to a file every 5 minutes - thread = threading.Thread(target=save_statistics_to_file) - thread.start() - - app.run(debug=False) diff --git a/pdr_backend/accuracy/output/index b/pdr_backend/accuracy/output/index deleted file mode 100644 index e69de29bb..000000000 diff --git a/pdr_backend/accuracy/test/test_app.py b/pdr_backend/accuracy/test/test_app.py deleted file mode 100644 index 688bdbdaa..000000000 --- a/pdr_backend/accuracy/test/test_app.py +++ /dev/null @@ -1,108 +0,0 @@ -from typing import List -from unittest.mock import patch - -from enforce_typing import enforce_types - -from pdr_backend.subgraph.subgraph_predictions import ContractIdAndSPE -from pdr_backend.accuracy.app import ( - calculate_prediction_result, - process_single_slot, - aggregate_statistics, - calculate_statistics_for_all_assets, -) -from pdr_backend.subgraph.legacy.subgraph_slot import PredictSlot, PredictSlotStatus -from pdr_backend.util.time_types import UnixTimeS - -# Sample data for tests -SAMPLE_PREDICT_SLOT = PredictSlot( - ID="0xAsset-12345", - slot="12345", - status=PredictSlotStatus.PAYING, - trueValues=[{"ID": "1", "trueValue": True}], - roundSumStakesUp=150.0, - roundSumStakes=100.0, -) - -SAMPLE_PREDICT_SLOT_CANCELED = PredictSlot( - ID="0xAsset-12345", - slot="12345", - status=PredictSlotStatus.CANCELED, - trueValues=[{"ID": "1", "trueValue": True}], - roundSumStakesUp=150.0, - roundSumStakes=100.0, -) - - -@enforce_types -def test_calculate_prediction_result(): - - # Test the calculate_prediction_prediction_result function with expected inputs - result = calculate_prediction_result(150.0, 200.0) - assert result - - result = calculate_prediction_result(100.0, 250.0) - assert not result - - -@enforce_types -def test_process_single_slot(): - # Test the process_single_slot function - ( - staked_yesterday, - staked_today, - correct_predictions, - slots_evaluated, - ) = process_single_slot( - slot=SAMPLE_PREDICT_SLOT, end_of_previous_day_timestamp=UnixTimeS(12340) - ) - - assert staked_yesterday == 0.0 - assert staked_today == 100.0 - assert correct_predictions == 1 - assert slots_evaluated == 1 - - -@enforce_types -def test_aggregate_statistics(): - # Test the aggregate_statistics function - ( - total_staked_yesterday, - total_staked_today, - total_correct_predictions, - total_slots_evaluated, - ) = aggregate_statistics( - slots=[SAMPLE_PREDICT_SLOT, SAMPLE_PREDICT_SLOT_CANCELED], - end_of_previous_day_timestamp=UnixTimeS(12340), - ) - assert total_staked_yesterday == 0.0 - assert total_staked_today == 200.0 - assert total_correct_predictions == 1 - assert total_slots_evaluated == 1 - - -@enforce_types -@patch("pdr_backend.accuracy.app.fetch_slots_for_all_assets") -def test_calculate_statistics_for_all_assets(mock_fetch_slots): - # Mocks - mock_fetch_slots.return_value = { - "0xAsset": [SAMPLE_PREDICT_SLOT, SAMPLE_PREDICT_SLOT_CANCELED] * 500 - } - contracts_list: List[ContractIdAndSPE] = [ - {"ID": "0xAsset", "seconds_per_epoch": 300, "name": "TEST/USDT"} - ] - - # Main work - statistics = calculate_statistics_for_all_assets( - asset_ids=["0xAsset"], - contracts_list=contracts_list, - start_ts_param=UnixTimeS(91000), - end_ts_param=UnixTimeS(92000), - network="mainnet", - ) - - print("test_calculate_statistics_for_all_assets", statistics) - # Verify - assert statistics["0xAsset"]["average_accuracy"] == 100.0 - mock_fetch_slots.assert_called_once_with( - ["0xAsset"], UnixTimeS(91000), UnixTimeS(92000), "mainnet" - ) diff --git a/pdr_backend/cli/test/test_cli_module.py b/pdr_backend/cli/test/test_cli_module.py index 370f8291d..c1d6f7e17 100644 --- a/pdr_backend/cli/test/test_cli_module.py +++ b/pdr_backend/cli/test/test_cli_module.py @@ -9,27 +9,10 @@ from pdr_backend.cli.cli_module import ( # main tools do_sim, - do_predictoor, do_trader, - do_claim_OCEAN, - do_claim_ROSE, # power tools do_multisim, do_ohlcv, - # utilities - do_get_predictoors_info, - do_get_predictions_info, - do_get_traction_info, - do_check_network, - do_create_accounts, - do_print_balances, - do_fund_accounts, - # tools for core team - do_trueval, - do_dfbuyer, - do_publisher, - do_topup, - # (and, main) _do_main, ) from pdr_backend.ppss.ppss import PPSS as PPSSClass @@ -234,13 +217,6 @@ def test_do_sim(monkeypatch): mock_f.assert_called() -@enforce_types -def test_do_predictoor(monkeypatch): - monkeypatch.setattr(f"{_CLI_PATH}.PredictoorAgent", MockAgent) - - do_predictoor(MockArgParser_APPROACH_PPSS_NETWORK().parse_args()) - assert MockAgent.was_run - @enforce_types def test_do_trader(monkeypatch): @@ -258,38 +234,6 @@ def test_do_trader(monkeypatch): do_trader(MockArgParser_APPROACH_PPSS_NETWORK(_APPROACH_BAD).parse_args()) -@enforce_types -def test_do_claim_OCEAN(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.do_ocean_payout", mock_f) - - do_claim_OCEAN(MockArgParser_PPSS().parse_args()) - mock_f.assert_called() - - -@enforce_types -def test_do_claim_ROSE(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.do_rose_payout", mock_f) - - do_claim_ROSE(MockArgParser_PPSS().parse_args()) - mock_f.assert_called() - - -# --------------------------------------------------------------- -# test: Power tools - - -@enforce_types -def test_do_multisim(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.MultisimEngine.run", mock_f) - - ppss = MockArgParser_PPSS().parse_args() - do_multisim(ppss) - - mock_f.assert_called() - @enforce_types def test_do_ohlcv(monkeypatch): @@ -300,117 +244,6 @@ def test_do_ohlcv(monkeypatch): mock_f.assert_called() -# --------------------------------------------------------------- -# test: Utilities - - -@enforce_types -def test_do_get_predictoors_info(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.get_predictoors_info_main", mock_f) - - do_get_predictoors_info(MockArgParser_ST_END_PQDIR_NETWORK_PPSS_PDRS().parse_args()) - mock_f.assert_called() - - -@enforce_types -def test_do_get_predictions_info(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.get_predictions_info_main", mock_f) - - do_get_predictions_info( - MockArgParser_ST_END_PQDIR_NETWORK_PPSS_FEEDS().parse_args() - ) - mock_f.assert_called() - - -@enforce_types -def test_do_get_traction_info(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.get_traction_info_main", mock_f) - - do_get_traction_info(MockArgParser_ST_END_PQDIR_NETWORK_PPSS_FEEDS().parse_args()) - mock_f.assert_called() - - -@enforce_types -def test_do_check_network(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.check_network_main", mock_f) - - do_check_network(MockArgParser_PPSS_NETWORK_LOOKBACK().parse_args()) - mock_f.assert_called() - - -@enforce_types -def test_do_create_accounts(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.create_accounts", mock_f) - - do_create_accounts(MockArgParser_NUM().parse_args()) - mock_f.assert_called() - - -@enforce_types -def test_do_print_balances(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.print_balances", mock_f) - - do_print_balances(MockArgParser_ACCOUNT_PPSS_NETWORK().parse_args()) - mock_f.assert_called() - - -@enforce_types -def test_do_fund_accounts(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.fund_accounts", mock_f) - - do_fund_accounts( - MockArgParser_TOKEN_AMOUNT_ACCOUNTS_TOKEN_PPSS_NETWORK().parse_args() - ) - mock_f.assert_called() - - -# --------------------------------------------------------------- -# test: Tools for core team - - -@enforce_types -def test_do_trueval(monkeypatch): - monkeypatch.setattr(f"{_CLI_PATH}.TruevalAgent", MockAgent) - - do_trueval(MockArgParser_PPSS_NETWORK().parse_args()) - assert MockAgent.was_run - - -@enforce_types -def test_do_dfbuyer(monkeypatch): - monkeypatch.setattr(f"{_CLI_PATH}.DFBuyerAgent", MockAgent) - - do_dfbuyer(MockArgParser_PPSS_NETWORK().parse_args()) - assert MockAgent.was_run - - -@enforce_types -def test_do_publisher(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.publish_assets", mock_f) - - do_publisher(MockArgParser_PPSS_NETWORK().parse_args()) - mock_f.assert_called() - - -@enforce_types -def test_do_topup(monkeypatch): - mock_f = Mock() - monkeypatch.setattr(f"{_CLI_PATH}.topup_main", mock_f) - - do_topup(MockArgParser_PPSS_NETWORK().parse_args()) - mock_f.assert_called() - - -# --------------------------------------------------------------- -# (test _do_main) @enforce_types diff --git a/pdr_backend/contract/test/conftest.py b/pdr_backend/contract/test/conftest.py deleted file mode 100644 index fc9ed034c..000000000 --- a/pdr_backend/contract/test/conftest.py +++ /dev/null @@ -1 +0,0 @@ -from pdr_backend.conftest_ganache import * # pylint: disable=wildcard-import diff --git a/pdr_backend/contract/test/test_base_contract.py b/pdr_backend/contract/test/test_base_contract.py deleted file mode 100644 index 529fc3093..000000000 --- a/pdr_backend/contract/test/test_base_contract.py +++ /dev/null @@ -1,81 +0,0 @@ -import os -from unittest.mock import Mock - -import pytest -from enforce_typing import enforce_types - -from pdr_backend.contract.token import Token - - -@pytest.fixture -def mock_send_encrypted_sapphire_tx(monkeypatch): - mock_function = Mock(return_value=(0, "dummy_tx_hash")) - monkeypatch.setattr("sapphirepy.wrapper.send_encrypted_sapphire_tx", mock_function) - return mock_function - - -@enforce_types -def test_base_contract(web3_pp, web3_config): - OCEAN_address = web3_pp.OCEAN_address - - # success - Token(web3_pp, OCEAN_address) - - # catch failure - web3_config = web3_pp.web3_config - with pytest.raises(ValueError): - Token(web3_config, OCEAN_address) - - -@enforce_types -def test_send_encrypted_tx( - mock_send_encrypted_sapphire_tx, # pylint: disable=redefined-outer-name - OCEAN, - web3_pp, -): - OCEAN_address = web3_pp.OCEAN_address - contract = Token(web3_pp, OCEAN_address) - - # Set up dummy return value for the mocked function - mock_send_encrypted_sapphire_tx.return_value = ( - 0, - "dummy_tx_hash", - ) - - # Sample inputs for send_encrypted_tx - function_name = "transfer" - args = [web3_pp.web3_config.owner, 100] - sender = web3_pp.web3_config.owner - receiver = web3_pp.web3_config.w3.eth.accounts[1] - rpc_url = web3_pp.rpc_url - value = 0 - gasLimit = 10000000 - gasCost = 0 - nonce = 0 - pk = os.getenv("PRIVATE_KEY") - - tx_hash, encrypted_data = contract.send_encrypted_tx( - function_name, - args, - sender, - receiver, - pk, - value, - gasLimit, - gasCost, - nonce, - ) - assert tx_hash == 0 - assert encrypted_data == "dummy_tx_hash" - - mock_send_encrypted_sapphire_tx.assert_called_once_with( - pk, - sender, - receiver, - rpc_url, - value, - gasLimit, - OCEAN.contract_instance.encode_abi(fn_name=function_name, args=args), - gasCost, - nonce, - ) diff --git a/pdr_backend/contract/test/test_data_nft.py b/pdr_backend/contract/test/test_data_nft.py deleted file mode 100644 index 083c07acf..000000000 --- a/pdr_backend/contract/test/test_data_nft.py +++ /dev/null @@ -1,68 +0,0 @@ -import json -import os - -from enforce_typing import enforce_types -from eth_account import Account -from web3.logs import DISCARD - -from pdr_backend.contract.data_nft import DataNft -from pdr_backend.contract.erc721_factory import Erc721Factory -from pdr_backend.util.constants import MAX_UINT -from pdr_backend.util.currency_types import Eth - - -@enforce_types -def test_set_ddo(web3_pp, web3_config): - private_key = os.getenv("PRIVATE_KEY") - - path = os.path.join( - os.path.dirname(__file__), "../../tests/resources/ddo_v4_sample.json" - ) - - with open(path, "r") as file_handle: - content = file_handle.read() - ddo = json.loads(content) - - owner = Account.from_key( # pylint:disable=no-value-for-parameter - private_key=private_key - ) - factory = Erc721Factory(web3_pp) - ocean_address = web3_pp.OCEAN_address - fre_address = web3_pp.get_address("FixedPrice") - - feeCollector = owner.address - - nft_data = ("NFT1", "NFT1", 1, "", True, owner.address) - erc_data = ( - 3, - ["ERC20", "ERC20"], - [ - owner.address, - owner.address, - feeCollector, - ocean_address, - ocean_address, - ], - [MAX_UINT, 0, 300, 300 * 24, 4 * 12 * 300], - [], - ) - - rate = Eth(3).to_wei().amt_wei - cut = Eth(0.2).to_wei().amt_wei - fre_data = ( - fre_address, - [ocean_address, owner.address, feeCollector, owner.address], - [18, 18, rate, cut, 1], - ) - logs_nft, _ = factory.createNftWithErc20WithFixedRate(nft_data, erc_data, fre_data) - data_nft_address = logs_nft["newTokenAddress"] - print(f"Deployed NFT: {data_nft_address}") - data_nft = DataNft(web3_pp, data_nft_address) - - tx = data_nft.set_ddo(ddo, wait_for_receipt=True) - receipt = web3_config.w3.eth.wait_for_transaction_receipt(tx) - event = data_nft.contract_instance.events.MetadataCreated().process_receipt( - receipt, errors=DISCARD - )[0] - - assert event diff --git a/pdr_backend/contract/test/test_dfrewards.py b/pdr_backend/contract/test/test_dfrewards.py deleted file mode 100644 index bc846e791..000000000 --- a/pdr_backend/contract/test/test_dfrewards.py +++ /dev/null @@ -1,19 +0,0 @@ -from enforce_typing import enforce_types - -from pdr_backend.contract.dfrewards import DFRewards -from pdr_backend.util.currency_types import Eth - - -@enforce_types -def test_dfrewards(web3_pp, web3_config): - dfrewards_addr = web3_pp.get_address("DFRewards") - assert isinstance(dfrewards_addr, str) - - ocean_addr = web3_pp.OCEAN_address - assert isinstance(dfrewards_addr, str) - - contract = DFRewards(web3_pp, dfrewards_addr) - rewards = contract.get_claimable_rewards(web3_config.owner, ocean_addr) - assert rewards == Eth(0) - - contract.claim_rewards(web3_config.owner, ocean_addr) diff --git a/pdr_backend/contract/test/test_erc721_factory.py b/pdr_backend/contract/test/test_erc721_factory.py deleted file mode 100644 index 2651d1761..000000000 --- a/pdr_backend/contract/test/test_erc721_factory.py +++ /dev/null @@ -1,68 +0,0 @@ -from unittest.mock import Mock, patch - -import pytest -from enforce_typing import enforce_types - -from pdr_backend.contract.erc721_factory import Erc721Factory -from pdr_backend.util.currency_types import Eth - - -@enforce_types -def test_Erc721Factory(web3_pp, web3_config): - factory = Erc721Factory(web3_pp) - assert factory is not None - - ocean_address = web3_pp.OCEAN_address - fre_address = web3_pp.get_address("FixedPrice") - - rate = Eth(3).to_wei().amt_wei - cut = Eth(0.2).to_wei().amt_wei - - nft_data = ("TestToken", "TT", 1, "", True, web3_config.owner) - erc_data = ( - 3, - ["ERC20Test", "ET"], - [ - web3_config.owner, - web3_config.owner, - web3_config.owner, - ocean_address, - ocean_address, - ], - [2**256 - 1, 0, 300, 3000, 30000], - [], - ) - fre_data = ( - fre_address, - [ - ocean_address, - web3_config.owner, - web3_config.owner, - web3_config.owner, - ], - [ - 18, - 18, - rate, - cut, - 1, - ], - ) - - logs_nft, logs_erc = factory.createNftWithErc20WithFixedRate( - nft_data, erc_data, fre_data - ) - - assert len(logs_nft) > 0 - assert len(logs_erc) > 0 - - config = Mock() - receipt = {"status": 0} - config.w3.eth.wait_for_transaction_receipt.return_value = receipt - - -@enforce_types -def test_Erc721Factory_no_address(web3_pp): - with patch.object(web3_pp, "get_address", return_value=None): - with pytest.raises(ValueError): - Erc721Factory(web3_pp) diff --git a/pdr_backend/contract/test/test_fixed_rate.py b/pdr_backend/contract/test/test_fixed_rate.py deleted file mode 100644 index bf5d019a0..000000000 --- a/pdr_backend/contract/test/test_fixed_rate.py +++ /dev/null @@ -1,36 +0,0 @@ -from enforce_typing import enforce_types -from pytest import approx - -from pdr_backend.contract.fixed_rate import FixedRate -from pdr_backend.util.currency_types import Eth, Wei - - -@enforce_types -def test_FixedRate(feed_contract1, web3_pp): - exchanges = feed_contract1.get_exchanges() - print(exchanges) - - address = exchanges[0][0] - exchangeId = exchanges[0][1] - - # constructor - exchange = FixedRate(web3_pp, address) - - # test get_dt_price() - tup = exchange.get_dt_price(exchangeId) - ( - baseTokenAmt_wei, - oceanFeeAmt_wei, - publishMktFeeAmt_wei, - consumeMktFeeAmt_wei, - ) = tup - - assert baseTokenAmt_wei.to_eth().amt_eth == approx(3.603) - - assert oceanFeeAmt_wei.to_eth().amt_eth == approx(0.003) - assert publishMktFeeAmt_wei.to_eth().amt_eth == approx(0.6) - assert consumeMktFeeAmt_wei.to_eth().amt_eth == 0 - - # test calcBaseInGivenOutDT() - tup2 = exchange.calcBaseInGivenOutDT(exchangeId, Eth(1).to_wei(), Wei(0)) - assert tup == tup2 diff --git a/pdr_backend/contract/test/test_predictoor_batcher.py b/pdr_backend/contract/test/test_predictoor_batcher.py deleted file mode 100644 index fc69a143c..000000000 --- a/pdr_backend/contract/test/test_predictoor_batcher.py +++ /dev/null @@ -1,150 +0,0 @@ -from unittest.mock import Mock - -from enforce_typing import enforce_types -from web3.types import RPCEndpoint - -from pdr_backend.conftest_ganache import S_PER_EPOCH -from pdr_backend.contract.data_nft import DataNft -from pdr_backend.contract.predictoor_batcher import mock_predictoor_batcher -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.util.currency_types import Wei - - -@enforce_types -def test_submit_truevals(feed_contract1, web3_pp, predictoor_batcher): - web3_config = web3_pp.web3_config - current_epoch = feed_contract1.get_current_epoch_ts() - - # fast forward time - web3_config.w3.provider.make_request( - RPCEndpoint("evm_increaseTime"), [S_PER_EPOCH * 10] - ) - web3_config.w3.provider.make_request(RPCEndpoint("evm_mine"), []) - - end_epoch = current_epoch + S_PER_EPOCH * 10 - - # get trueval for epochs - epochs = list(range(current_epoch, end_epoch, S_PER_EPOCH)) - truevals = [True] * len(epochs) - cancels = [False] * len(epochs) - - # add predictoor helper as ercdeployer - erc721addr = feed_contract1.erc721_addr() - datanft = DataNft(web3_pp, erc721addr) - datanft.add_to_create_erc20_list(predictoor_batcher.contract_address) - - truevals_before = [ - feed_contract1.contract_instance.functions.trueValues(i).call() for i in epochs - ] - for trueval in truevals_before: - assert trueval is False - - predictoor_batcher.submit_truevals( - feed_contract1.contract_address, epochs, truevals, cancels - ) - - truevals_after = [ - feed_contract1.contract_instance.functions.trueValues(i).call() for i in epochs - ] - for trueval in truevals_after: - assert trueval is True - - -@enforce_types -def test_submit_truevals_contracts( - feed_contract1, - feed_contract2, - web3_pp, - web3_config, - predictoor_batcher, -): - current_epoch = feed_contract1.get_current_epoch_ts() - - # fast forward time - web3_config.w3.provider.make_request( - RPCEndpoint("evm_increaseTime"), [S_PER_EPOCH * 10] - ) - web3_config.w3.provider.make_request(RPCEndpoint("evm_mine"), []) - - end_epoch = current_epoch + S_PER_EPOCH * 10 - - # get trueval for epochs - epochs1 = list(range(current_epoch, end_epoch, S_PER_EPOCH)) - epochs2 = list(range(current_epoch + S_PER_EPOCH * 2, end_epoch, S_PER_EPOCH)) - epochs = [epochs1, epochs2] - truevals = [[True] * len(epochs1), [True] * len(epochs2)] - cancels = [[False] * len(epochs1), [False] * len(epochs2)] - addresses = [ - feed_contract1.contract_address, - feed_contract2.contract_address, - ] - - # add predictoor helper as ercdeployer - erc721addr = feed_contract1.erc721_addr() - datanft = DataNft(web3_pp, erc721addr) - datanft.add_to_create_erc20_list(predictoor_batcher.contract_address) - erc721addr = feed_contract2.erc721_addr() - datanft = DataNft(web3_pp, erc721addr) - datanft.add_to_create_erc20_list(predictoor_batcher.contract_address) - - truevals_before_1 = [ - feed_contract1.contract_instance.functions.trueValues(i).call() for i in epochs1 - ] - - truevals_before_2 = [ - feed_contract2.contract_instance.functions.trueValues(i).call() for i in epochs1 - ] - - for trueval in truevals_before_1: - assert trueval is False - - for trueval in truevals_before_2: - assert trueval is False - - predictoor_batcher.submit_truevals_contracts(addresses, epochs, truevals, cancels) - - truevals_after_1 = [ - feed_contract1.contract_instance.functions.trueValues(i).call() for i in epochs1 - ] - - truevals_after_2 = [ - feed_contract2.contract_instance.functions.trueValues(i).call() for i in epochs1 - ] - - for trueval in truevals_after_1: - assert trueval is True - - for trueval in truevals_after_2[:2]: # did not include first two epochs - assert trueval is False - - for trueval in truevals_after_2[2:]: - assert trueval is True - - -@enforce_types -def test_consume_multiple(feed_contract1, OCEAN, predictoor_batcher): - owner = OCEAN.config.owner - - price = feed_contract1.get_price() - print(price) - - times = 10 - cost = Wei(times * price.amt_wei) - - OCEAN.approve(predictoor_batcher.contract_address, cost) - balance_before = OCEAN.balanceOf(owner) - - predictoor_batcher.consume_multiple( - [feed_contract1.contract_address], [times], OCEAN.contract_address - ) - - balance_after = OCEAN.balanceOf(owner) - assert balance_after + cost == balance_before - - -@enforce_types -def test_mock_predictoor_batcher(): - web3_pp = Mock(spec=Web3PP) - b = mock_predictoor_batcher(web3_pp) - assert id(b.web3_pp) == id(web3_pp) - assert b.contract_address == "0xPdrBatcherAddr" diff --git a/pdr_backend/contract/test/test_predictoor_contract.py b/pdr_backend/contract/test/test_predictoor_contract.py deleted file mode 100644 index 2c02dc5cb..000000000 --- a/pdr_backend/contract/test/test_predictoor_contract.py +++ /dev/null @@ -1,212 +0,0 @@ -from unittest.mock import Mock, patch - -import pytest -from enforce_typing import enforce_types -from pytest import approx - -from pdr_backend.conftest_ganache import S_PER_EPOCH -from pdr_backend.contract.feed_contract import ( - FeedContract, - mock_feed_contract, -) -from pdr_backend.contract.token import Token -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.publisher.publish_asset import MAX_UINT256 -from pdr_backend.util.currency_types import Eth, Wei - - -@enforce_types -def test_get_id(feed_contract1): - id_ = feed_contract1.getid() - assert id_ == 3 - - -@enforce_types -def test_is_valid_subscription_initially(feed_contract1): - is_valid_sub = feed_contract1.is_valid_subscription() - assert not is_valid_sub - - -@enforce_types -def test_buy_and_start_subscription(feed_contract1): - receipt = feed_contract1.buy_and_start_subscription() - assert receipt["status"] == 1 - is_valid_sub = feed_contract1.is_valid_subscription() - assert is_valid_sub - - -@enforce_types -def test_buy_and_start_subscription_empty(feed_contract_empty): - with pytest.raises(ValueError): - assert feed_contract_empty.buy_and_start_subscription() - - -@enforce_types -def test_buy_many(feed_contract1): - receipts = feed_contract1.buy_many(2, None, True) - assert len(receipts) == 2 - - assert feed_contract1.buy_many(0, None, True) is None - - -@enforce_types -def test_get_exchanges(feed_contract1): - exchanges = feed_contract1.get_exchanges() - assert exchanges[0][0].startswith("0x") - - -@enforce_types -def test_get_stake_token(feed_contract1, web3_pp): - stake_token = feed_contract1.get_stake_token() - assert stake_token == web3_pp.OCEAN_address - - -@enforce_types -def test_get_price(feed_contract1): - price = feed_contract1.get_price() - assert price.amt_wei / 1e18 == approx(3.603) - - -@enforce_types -def test_get_price_no_exchanges(feed_contract_empty): - feed_contract_empty.get_exchanges = Mock(return_value=[]) - with pytest.raises(ValueError): - feed_contract_empty.get_price() - - -@enforce_types -def test_get_current_epoch(feed_contract1): - current_epoch = feed_contract1.get_current_epoch() - now = feed_contract1.config.get_block("latest").timestamp - assert current_epoch == int(now // S_PER_EPOCH) - - -@enforce_types -def test_get_current_epoch_ts(feed_contract1): - current_epoch = feed_contract1.get_current_epoch_ts() - now = feed_contract1.config.get_block("latest").timestamp - assert current_epoch == int(now // S_PER_EPOCH) * S_PER_EPOCH - - -@enforce_types -def test_get_seconds_per_epoch(feed_contract1): - seconds_per_epoch = feed_contract1.get_secondsPerEpoch() - assert seconds_per_epoch == S_PER_EPOCH - - -@enforce_types -def test_get_aggpredval(feed_contract1): - current_epoch = feed_contract1.get_current_epoch_ts() - aggpredval = feed_contract1.get_agg_predval(current_epoch) - assert aggpredval == (Eth(0), Eth(0)) - - -@enforce_types -def test_soonest_timestamp_to_predict(feed_contract1): - current_epoch = feed_contract1.get_current_epoch_ts() - soonest_timestamp = feed_contract1.soonest_timestamp_to_predict(current_epoch) - assert soonest_timestamp == current_epoch + S_PER_EPOCH * 2 - - -@enforce_types -def test_get_trueValSubmitTimeout(feed_contract1): - trueValSubmitTimeout = feed_contract1.get_trueValSubmitTimeout() - assert trueValSubmitTimeout == 3 * 24 * 60 * 60 - - -@enforce_types -def test_submit_prediction_trueval_payout( - feed_contract1, - OCEAN: Token, -): - w3 = feed_contract1.config.w3 - owner_addr = feed_contract1.config.owner - OCEAN_before = OCEAN.balanceOf(owner_addr).to_eth() - cur_epoch = feed_contract1.get_current_epoch_ts() - soonest_ts = feed_contract1.soonest_timestamp_to_predict(cur_epoch) - predval = True - stake_amt = Eth(1.0) - receipt = feed_contract1.submit_prediction( - predval, - stake_amt, - soonest_ts, - wait_for_receipt=True, - ) - assert receipt["status"] == 1 - - OCEAN_after = OCEAN.balanceOf(owner_addr).to_eth() - assert (OCEAN_before.amt_eth - OCEAN_after.amt_eth) == approx( - stake_amt.amt_eth, 1e-8 - ) - - pred_tup = feed_contract1.get_prediction( - soonest_ts, - feed_contract1.config.owner, - ) - assert pred_tup[0] == predval - assert pred_tup[1] == stake_amt.amt_wei - - w3.provider.make_request("evm_increaseTime", [S_PER_EPOCH * 2]) - w3.provider.make_request("evm_mine", []) - trueval = True - receipt = feed_contract1.submit_trueval( - trueval, - soonest_ts, - cancel_round=False, - wait_for_receipt=True, - ) - assert receipt["status"] == 1 - - receipt = feed_contract1.payout(soonest_ts, wait_for_receipt=True) - assert receipt["status"] == 1 - OCEAN_final = OCEAN.balanceOf(owner_addr).to_eth() - assert OCEAN_before.amt_eth == approx(OCEAN_final.amt_eth, 2.0) # + sub revenue - - -@enforce_types -def test_redeem_unused_slot_revenue(feed_contract1): - cur_epoch = feed_contract1.get_current_epoch_ts() - S_PER_EPOCH * 123 - receipt = feed_contract1.redeem_unused_slot_revenue(cur_epoch, True) - assert receipt["status"] == 1 - - -@enforce_types -def test_mock_feed_contract(): - c = mock_feed_contract("0x123", (3, 4)) - assert c.contract_address == "0x123" - assert c.get_agg_predval() == (3, 4) - - -@enforce_types -def test_allowance_update(): - web3_pp = Mock(spec=Web3PP) - mock_token = Mock(spec=Token) - address = "0x123" - with patch( - "pdr_backend.contract.feed_contract.Token", - autospec=True, - return_value=mock_token, - ): - contract = FeedContract(web3_pp, address) - - contract.config.owner = "0xowner" - contract.contract_address = "0xcontract" - contract.send_encrypted_tx = Mock() - contract.send_encrypted_tx.return_value = (1, 2) - - allowance = contract.last_allowance[contract.config.owner] - assert allowance == Wei(0) - - contract.token.allowance.return_value = Wei(1000) - contract.token.approve = Mock() - - stake_amt = Wei(10) - contract.submit_prediction( - predicted_value=True, - stake_amt=stake_amt, - prediction_ts=123, - wait_for_receipt=True, - ) - - allowance = contract.last_allowance[contract.config.owner] - assert allowance == Wei(MAX_UINT256) - stake_amt diff --git a/pdr_backend/contract/test/test_slot.py b/pdr_backend/contract/test/test_slot.py deleted file mode 100644 index 42963bb25..000000000 --- a/pdr_backend/contract/test/test_slot.py +++ /dev/null @@ -1,23 +0,0 @@ -from pdr_backend.contract.slot import Slot -from pdr_backend.subgraph.subgraph_feed import SubgraphFeed - - -def test_slot_initialization(): - feed = SubgraphFeed( - "Contract Name", - "0x12345", - "test", - 60, - 15, - "0xowner", - "BTC/ETH", - "1h", - "binance", - ) - - slot_number = 5 - slot = Slot(slot_number, feed) - - assert slot.slot_number == slot_number - assert slot.feed == feed - assert isinstance(slot.feed, SubgraphFeed) diff --git a/pdr_backend/contract/test/test_token.py b/pdr_backend/contract/test/test_token.py deleted file mode 100644 index 1396d8be2..000000000 --- a/pdr_backend/contract/test/test_token.py +++ /dev/null @@ -1,44 +0,0 @@ -import time -from unittest.mock import patch - -from enforce_typing import enforce_types - -from pdr_backend.contract.token import Token -from pdr_backend.util.currency_types import Wei - - -@enforce_types -def test_token(web3_pp, web3_config): - token_address = web3_pp.OCEAN_address - token = Token(web3_pp, token_address) - - accounts = web3_config.w3.eth.accounts - owner_addr = web3_config.owner - alice = accounts[1] - - call_params = web3_pp.tx_call_params() - token.contract_instance.functions.mint(owner_addr, 1000000000).transact(call_params) - - allowance_start = token.allowance(owner_addr, alice) - token.approve(alice, allowance_start + 100, True) - time.sleep(1) - allowance_end = token.allowance(owner_addr, alice) - assert allowance_end - allowance_start == Wei(100) - - balance_start = token.balanceOf(alice) - token.transfer(alice, Wei(100), owner_addr) - balance_end = token.balanceOf(alice) - assert balance_end - balance_start == Wei(100) - - -@enforce_types -def test_native_token(web3_pp): - token = web3_pp.NativeToken - assert token.w3 - - owner = web3_pp.web3_config.owner - assert token.balanceOf(owner) - - with patch("web3.eth.Eth.send_transaction") as mock: - token.transfer(owner, Wei(100), "0x123", False) - assert mock.called diff --git a/pdr_backend/contract/test/test_wrapped_token.py b/pdr_backend/contract/test/test_wrapped_token.py deleted file mode 100644 index 933df3ad8..000000000 --- a/pdr_backend/contract/test/test_wrapped_token.py +++ /dev/null @@ -1,21 +0,0 @@ -from unittest.mock import Mock, patch - -from enforce_typing import enforce_types - -from pdr_backend.contract.wrapped_token import WrappedToken -from pdr_backend.util.currency_types import Wei - - -@enforce_types -def test_native_token(web3_pp): - token_address = web3_pp.get_address("Ocean") - mock_wrapped_contract = Mock() - mock_transaction = Mock() - mock_transaction.transact.return_value = "mock_tx" - mock_wrapped_contract.functions.withdraw.return_value = mock_transaction - - with patch("web3.eth.Eth.contract") as mock: - mock.return_value = mock_wrapped_contract - token = WrappedToken(web3_pp, token_address) - - assert token.withdraw(Wei(100), False) == "mock_tx" diff --git a/pdr_backend/dfbuyer/test/conftest.py b/pdr_backend/dfbuyer/test/conftest.py deleted file mode 100644 index 2c7184249..000000000 --- a/pdr_backend/dfbuyer/test/conftest.py +++ /dev/null @@ -1,55 +0,0 @@ -from unittest.mock import MagicMock, patch - -import pytest - -from pdr_backend.contract.predictoor_batcher import mock_predictoor_batcher -from pdr_backend.dfbuyer.dfbuyer_agent import DFBuyerAgent -from pdr_backend.ppss.ppss import mock_feed_ppss -from pdr_backend.ppss.web3_pp import inplace_mock_feedgetters -from pdr_backend.util.constants import MAX_UINT, ZERO_ADDRESS - -PATH = "pdr_backend.dfbuyer.dfbuyer_agent" - - -@pytest.fixture() -def mock_token(): - with patch("pdr_backend.ppss.web3_pp.Token") as mock_token_class: - mock_token_instance = MagicMock() - mock_token_instance.allowance.return_value = MAX_UINT - mock_token_class.return_value = mock_token_instance - yield mock_token_class - - -_MOCK_FEED_PPSS = None # (feed, ppss) - - -def _mock_feed_ppss(): - global _MOCK_FEED_PPSS - if _MOCK_FEED_PPSS is None: - feed, ppss = mock_feed_ppss("5m", "binance", "BTC/USDT") - inplace_mock_feedgetters(ppss.web3_pp, feed) # mock publishing feeds - _MOCK_FEED_PPSS = (feed, ppss) - return _MOCK_FEED_PPSS - - -@pytest.fixture -def mock_ppss(): - _, ppss = _mock_feed_ppss() - return ppss - - -@pytest.fixture -def mock_PredictoorBatcher(mock_ppss): # pylint: disable=redefined-outer-name - with patch(f"{PATH}.PredictoorBatcher") as mock: - mock.return_value = mock_predictoor_batcher(mock_ppss.web3_pp) - yield mock - - -@pytest.fixture -def mock_dfbuyer_agent( # pylint: disable=unused-argument, redefined-outer-name - mock_token, - mock_ppss, - mock_PredictoorBatcher, -): - with patch.object(mock_ppss.web3_pp, "get_address", return_value=ZERO_ADDRESS): - return DFBuyerAgent(mock_ppss) diff --git a/pdr_backend/dfbuyer/test/test_dfbuyer_agent.py b/pdr_backend/dfbuyer/test/test_dfbuyer_agent.py deleted file mode 100644 index 1b68e19fc..000000000 --- a/pdr_backend/dfbuyer/test/test_dfbuyer_agent.py +++ /dev/null @@ -1,308 +0,0 @@ -from unittest.mock import MagicMock, call, patch - -import pytest -from ccxt.base.exchange import math -from enforce_typing import enforce_types - -from pdr_backend.contract.predictoor_batcher import PredictoorBatcher -from pdr_backend.dfbuyer.dfbuyer_agent import WEEK, DFBuyerAgent -from pdr_backend.ppss.dfbuyer_ss import DFBuyerSS -from pdr_backend.ppss.ppss import PPSS -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.util.constants import MAX_UINT, ZERO_ADDRESS -from pdr_backend.util.web3_config import Web3Config -from pdr_backend.util.time_types import UnixTimeS -from pdr_backend.util.currency_types import Eth, Wei - -PATH = "pdr_backend.dfbuyer.dfbuyer_agent" - - -@enforce_types -def test_dfbuyer_agent_constructor( # pylint: disable=unused-argument - mock_token, - mock_ppss, - mock_PredictoorBatcher, -): - mock_token.return_value.allowance.return_value = 0 - - agent = DFBuyerAgent(mock_ppss) - - mock_token.assert_called_with(mock_ppss.web3_pp, agent.OCEAN_addr) - mock_token_instance = mock_token() - mock_token_instance.approve.assert_called_with( - agent.predictoor_batcher.contract_address, int(MAX_UINT), True - ) - - -@enforce_types -def test_dfbuyer_agent_constructor_empty(): - # test with no feeds - mock_ppss_empty = MagicMock(spec=PPSS) - mock_ppss_empty.dfbuyer_ss = MagicMock(spec=DFBuyerSS) - mock_ppss_empty.dfbuyer_ss.filter_feeds_from_candidates.return_value = {} - mock_ppss_empty.web3_pp = MagicMock(spec=Web3PP) - mock_ppss_empty.web3_pp.query_feed_contracts.return_value = {} - - with pytest.raises(ValueError, match="No feeds found"): - DFBuyerAgent(mock_ppss_empty) - - -@enforce_types -def test_dfbuyer_agent_get_expected_amount_per_feed(mock_dfbuyer_agent): - ts = UnixTimeS(1695211135) - amount_per_feed_per_interval = ( - mock_dfbuyer_agent.ppss.dfbuyer_ss.amount_per_interval - / len(mock_dfbuyer_agent.feeds) - ) - week_start = (math.floor(ts / WEEK)) * WEEK - time_passed = ts - week_start - n_intervals = ( - int(time_passed / mock_dfbuyer_agent.ppss.dfbuyer_ss.consume_interval_seconds) - + 1 - ) - expected_result = n_intervals * amount_per_feed_per_interval - result = mock_dfbuyer_agent._get_expected_amount_per_feed(ts) - assert result == expected_result - - -def test_dfbuyer_agent_get_expected_amount_per_feed_hardcoded(mock_dfbuyer_agent): - ts = UnixTimeS(1695859200) - end = ts + WEEK - 86400 # last day - just_before_new_week = ts + WEEK - 1 # 1 second before next week - - amount_per_feed_per_interval = ( - mock_dfbuyer_agent.ppss.dfbuyer_ss.amount_per_interval - / len(mock_dfbuyer_agent.feeds) - ) - result1 = mock_dfbuyer_agent._get_expected_amount_per_feed(ts) - assert result1 == amount_per_feed_per_interval - assert result1 * len(mock_dfbuyer_agent.feeds) == 37000 / 7 # first day - - result2 = mock_dfbuyer_agent._get_expected_amount_per_feed(end) - assert result2 == amount_per_feed_per_interval * 7 - assert ( - result2 * len(mock_dfbuyer_agent.feeds) == 37000 - ) # last day, should distribute all - - result3 = mock_dfbuyer_agent._get_expected_amount_per_feed(just_before_new_week) - assert result3 == amount_per_feed_per_interval * 7 - assert result3 * len(mock_dfbuyer_agent.feeds) == 37000 # still last day - - -@enforce_types -@patch(f"{PATH}.get_consume_so_far_per_contract") -def test_dfbuyer_agent_get_consume_so_far(mock_get_consume_so_far, mock_dfbuyer_agent): - agent = MagicMock() - agent.ppss.web3_pp.web3_config.owner = "0x123" - agent.feeds = {"feed1": "0x1", "feed2": "0x2"} - mock_get_consume_so_far.return_value = {"0x1": 10.5} - expected_result = {"0x1": 10.5} - result = mock_dfbuyer_agent._get_consume_so_far(0) - assert result == expected_result - - -@enforce_types -@patch(f"{PATH}.FeedContract") -def test_dfbuyer_agent_get_prices(mock_contract, mock_dfbuyer_agent): - mock_contract_instance = MagicMock() - mock_contract.return_value = mock_contract_instance - mock_contract_instance.get_price.return_value = Wei(10000) - result = mock_dfbuyer_agent._get_prices(["0x1", "0x2"]) - assert result["0x1"] == Wei(10000).to_eth() - assert result["0x2"] == Wei(10000).to_eth() - - -@enforce_types -def test_dfbuyer_agent_prepare_batches(mock_dfbuyer_agent): - addresses = [ZERO_ADDRESS[: -len(str(i))] + str(i) for i in range(1, 7)] - consume_times = dict(zip(addresses, [10, 30, 14, 6, 24, 16])) - result = mock_dfbuyer_agent._prepare_batches(consume_times) - - expected_result = [ - ([addresses[0], addresses[1]], [10, 10]), - ([addresses[1]], [20]), - ([addresses[2], addresses[3]], [14, 6]), - ([addresses[4]], [20]), - ([addresses[4], addresses[5]], [4, 16]), - ] - assert result == expected_result - - -@enforce_types -def test_dfbuyer_agent_get_missing_consumes( # pylint: disable=unused-argument - mock_token, - monkeypatch, -): - ppss = MagicMock(spec=PPSS) - ppss.web3_pp = MagicMock(spec=Web3PP) - - addresses = [ZERO_ADDRESS[: -len(str(i))] + str(i) for i in range(1, 7)] - feeds = {address: MagicMock() for address in addresses} - ppss.web3_pp.query_feed_contracts = MagicMock() - ppss.web3_pp.query_feed_contracts.return_value = feeds - ppss.web3_pp.OCEAN_Token.allowance.return_value = MAX_UINT - - ppss.dfbuyer_ss = MagicMock(spec=DFBuyerSS) - ppss.dfbuyer_ss.batch_size = 3 - ppss.dfbuyer_ss.filter_feeds_from_candidates.return_value = feeds - - batcher_class = MagicMock(spec=PredictoorBatcher) - monkeypatch.setattr(f"{PATH}.PredictoorBatcher", batcher_class) - - dfbuyer_agent = DFBuyerAgent(ppss) - - consume_amts = dict(zip(addresses, [10, 11, 32, 24, 41, 0])) - dfbuyer_agent._get_consume_so_far = MagicMock() - dfbuyer_agent._get_consume_so_far.return_value = consume_amts - - dfbuyer_agent._get_expected_amount_per_feed = MagicMock() - dfbuyer_agent._get_expected_amount_per_feed.return_value = 15 - - ts = 0 - result = dfbuyer_agent._get_missing_consumes(ts) - expected_consume = dfbuyer_agent._get_expected_amount_per_feed(ts) - expected_result = { - address: expected_consume - consume_amts[address] - for address in addresses - if expected_consume - consume_amts[address] >= 0 - } - assert result == expected_result - dfbuyer_agent._get_consume_so_far.assert_called_once_with(ts) - - -@enforce_types -def test_dfbuyer_agent_get_missing_consume_times(mock_dfbuyer_agent): - missing_consumes = {"0x1": Eth(10.5), "0x2": Eth(20.3), "0x3": Eth(30.7)} - prices = {"0x1": Eth(2.5), "0x2": Eth(3.3), "0x3": Eth(4.7)} - result = mock_dfbuyer_agent._get_missing_consume_times(missing_consumes, prices) - expected_result = {"0x1": 5, "0x2": 7, "0x3": 7} - assert result == expected_result - - -@enforce_types -@patch(f"{PATH}.wait_until_subgraph_syncs") -@patch("time.sleep", return_value=None) -@patch.object(DFBuyerAgent, "_get_missing_consumes") -@patch.object(DFBuyerAgent, "_get_prices") -@patch.object(DFBuyerAgent, "_get_missing_consume_times") -@patch.object(DFBuyerAgent, "_batch_txs") -@patch.object(Web3Config, "get_block") -# pylint: disable=too-many-positional-arguments -def test_dfbuyer_agent_take_step( - mock_get_block, - mock_batch_txs, - mock_get_missing_consume_times, - mock_get_prices, - mock_get_missing_consumes, - mock_sleep, - mock_subgraph_sync, # pylint: disable=unused-argument - mock_dfbuyer_agent, -): - ts = 0 - mock_get_missing_consumes.return_value = { - "0x1": Eth(10.5), - "0x2": Eth(20.3), - "0x3": Eth(30.7), - } - mock_get_prices.return_value = {"0x1": Eth(2.5), "0x2": Eth(3.3), "0x3": Eth(4.7)} - mock_get_missing_consume_times.return_value = {"0x1": 5, "0x2": 7, "0x3": 7} - mock_get_block.return_value = {"timestamp": 120} - mock_batch_txs.return_value = False - mock_dfbuyer_agent.take_step(ts) - mock_get_missing_consumes.assert_called_once_with(ts) - mock_get_prices.assert_called_once_with( - list(mock_get_missing_consumes.return_value.keys()) - ) - mock_get_missing_consume_times.assert_called_once_with( - mock_get_missing_consumes.return_value, mock_get_prices.return_value - ) - mock_batch_txs.assert_called_once_with(mock_get_missing_consume_times.return_value) - mock_get_block.assert_called_once_with("latest") - mock_sleep.assert_called_once_with(86400 - 60) - - # empty feeds - mock_dfbuyer_agent.feeds = [] - assert mock_dfbuyer_agent.take_step(ts) is None - - -@enforce_types -@patch.object(DFBuyerAgent, "take_step") -@patch.object(Web3Config, "get_block") -def test_dfbuyer_agent_run(mock_get_block, mock_take_step, mock_dfbuyer_agent): - mock_get_block.return_value = {"timestamp": 0} - mock_dfbuyer_agent.run(testing=True) - mock_get_block.assert_called_once_with("latest") - mock_take_step.assert_called_once_with(mock_get_block.return_value["timestamp"]) - - # empty feeds - mock_dfbuyer_agent.feeds = [] - assert mock_dfbuyer_agent.run(testing=True) is None - - -@enforce_types -@patch(f"{PATH}.time.sleep", return_value=None) -def test_dfbuyer_agent_consume_method(mock_sleep, mock_dfbuyer_agent): - mock_batcher = mock_dfbuyer_agent.predictoor_batcher - - addresses_to_consume = ["0x1", "0x2"] - times_to_consume = [2, 3] - - successful_tx = {"transactionHash": b"some_hash", "status": 1} - failed_tx = {"transactionHash": b"some_hash", "status": 0} - exception_tx = Exception("Error") - - mock_batcher.consume_multiple.return_value = successful_tx - assert mock_dfbuyer_agent._consume(addresses_to_consume, times_to_consume) - - mock_batcher.consume_multiple.return_value = failed_tx - assert not mock_dfbuyer_agent._consume(addresses_to_consume, times_to_consume) - - mock_batcher.consume_multiple.side_effect = exception_tx - with pytest.raises(Exception, match="Error"): - mock_dfbuyer_agent._consume(addresses_to_consume, times_to_consume) - - assert mock_sleep.call_count == mock_dfbuyer_agent.ppss.dfbuyer_ss.max_request_tries - - -@enforce_types -def test_dfbuyer_agent_consume_batch_method(mock_dfbuyer_agent): - addresses_to_consume = ["0x1", "0x2"] - times_to_consume = [2, 3] - - with patch.object( - mock_dfbuyer_agent, "_consume", side_effect=[False, True, False, False, True] - ) as mock_consume: - mock_dfbuyer_agent._consume_batch(addresses_to_consume, times_to_consume) - calls = [ - call(addresses_to_consume, times_to_consume), - call([addresses_to_consume[0]], [times_to_consume[0]]), - call([addresses_to_consume[1]], [times_to_consume[1]]), - call([addresses_to_consume[1]], [times_to_consume[1] // 2]), - call( - [addresses_to_consume[1]], - [times_to_consume[1] // 2 + times_to_consume[1] % 2], - ), - ] - mock_consume.assert_has_calls(calls) - - -@enforce_types -def test_dfbuyer_agent_batch_txs(mock_dfbuyer_agent): - addresses = [ZERO_ADDRESS[: -len(str(i))] + str(i) for i in range(1, 7)] - consume_times = dict(zip(addresses, [10, 30, 14, 6, 24, 16])) - - with patch.object( - mock_dfbuyer_agent, - "_consume_batch", - side_effect=[False, True, False, True, True], - ): - failures = mock_dfbuyer_agent._batch_txs(consume_times) - - assert failures - - with patch.object( - mock_dfbuyer_agent, "_consume_batch", side_effect=[True, True, True, True, True] - ): - failures = mock_dfbuyer_agent._batch_txs(consume_times) - - assert failures diff --git a/pdr_backend/pdr_dashboard/test/test_callbacks_common.py b/pdr_backend/pdr_dashboard/test/test_callbacks_common.py deleted file mode 100644 index e131def7d..000000000 --- a/pdr_backend/pdr_dashboard/test/test_callbacks_common.py +++ /dev/null @@ -1,43 +0,0 @@ -import time -from datetime import UTC, datetime - -from pdr_backend.pdr_dashboard.test.resources import start_server_and_wait - - -def test_navigation(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - # Default page is Home - dash_duo.wait_for_element_by_id("plots_container", timeout=10) - - # Navigate to Feeds - dash_duo.wait_for_element("#navbar-container a[href='/feeds']").click() - dash_duo.wait_for_element_by_id("feeds_page_metrics_row", timeout=10) - dash_duo.wait_for_element_by_id("feeds_page_table", timeout=10) - - # Navigate to Home - dash_duo.wait_for_element("#navbar-container a[href='/']").click() - dash_duo.wait_for_element_by_id("plots_container", timeout=10) - - -def test_set_period_start_date(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - # Default page is Home - dash_duo.wait_for_element_by_id("plots_container", timeout=10) - - # Set period start date - assert app.data.start_date is None - dash_duo.find_elements("#general-lake-date-period-radio-items label")[0].click() - time.sleep(1) - assert app.data.start_date is not None - - delta = datetime.now(UTC) - app.data.start_date - assert delta.days == 1 - assert delta.seconds < 120 - - dash_duo.find_elements("#general-lake-date-period-radio-items label")[3].click() - time.sleep(1) - assert app.data.start_date is None diff --git a/pdr_backend/pdr_dashboard/test/test_callbacks_feeds.py b/pdr_backend/pdr_dashboard/test/test_callbacks_feeds.py deleted file mode 100644 index ef29c04c6..000000000 --- a/pdr_backend/pdr_dashboard/test/test_callbacks_feeds.py +++ /dev/null @@ -1,284 +0,0 @@ -import json -import time -from typing import Any, Callable - -from selenium.webdriver.common.by import By - -from pdr_backend.pdr_dashboard.test.resources import ( - _assert_table_row_count, - _clear_feeds_filters, - _navigate_to_feeds_page, - _remove_tags, - _set_dropdown_and_verify_row_count, - _set_input_value_and_submit, - _set_searchbar_value, - start_server_and_wait, -) - - -def _prepare_table_data_to_be_saved_as_json(table): - rows = table.find_elements(By.XPATH, ".//tr") - header = rows[0].find_elements(By.XPATH, ".//th") - - headers = [_remove_tags(th.text) for th in header] - - table_data = [] - - for row in rows[1:]: # Skip header row - cells = row.find_elements(By.XPATH, ".//td") - row_data = {headers[i]: _remove_tags(cells[i].text) for i in range(len(cells))} - table_data.append(row_data) - - return table_data - - -def _verify_table_data_order( - table, filename, skip_condition: Callable[[Any], bool] = lambda x: False -): - table_data = _prepare_table_data_to_be_saved_as_json(table) - - with open("pdr_backend/pdr_dashboard/test/json_fixtures/" + filename) as f: - expected_data = json.load(f) - - for i, row in enumerate(table_data): - if skip_condition(expected_data[i]): - continue - - assert row == expected_data[i] - - -def _verify_table_data(table, filename): - table_data = _prepare_table_data_to_be_saved_as_json(table) - - with open("pdr_backend/pdr_dashboard/test/json_fixtures/" + filename) as f: - expected_data = json.load(f) - - for _, row in enumerate(table_data): - assert row in expected_data - - -def _save_table_data(table, filename): - table_data = _prepare_table_data_to_be_saved_as_json(table) - - with open("pdr_backend/pdr_dashboard/test/json_fixtures/" + filename, "w") as f: - json.dump(table_data, f) - - -def test_feeds_table(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_feeds_page(dash_duo) - - dash_duo.wait_for_element("#feeds_page_table table") - - table = dash_duo.find_element("#feeds_page_table table") - - time.sleep(3) - # Validate row and column count - rows = table.find_elements(By.XPATH, ".//tr") - assert len(rows) == 21 - - header = rows[0].find_elements(By.XPATH, ".//th") - columns = header - assert len(columns) == 12 - - # Validate headers - header_texts = [_remove_tags(c.text) for c in columns] - - expected_headers = [ - "", - "Addr", - "Base Token", - "Quote Token", - "Source", - "Timeframe", - "Accuracy", - "Avg Stake Per Epoch (Ocean)", - "Volume (Ocean)", - "Price (Ocean)", - "Sales", - "Sales Revenue (Ocean)", - ] - assert header_texts == expected_headers - - _verify_table_data(table, "expected_feeds_table_data.json") - - -def test_feeds_page_metrics_row(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_feeds_page(dash_duo) - dash_duo.wait_for_element("#feeds_page_metrics_row") - - metrics_row = dash_duo.find_element("#feeds_page_metrics_row") - - # Validate metrics - # select first level divs - metrics = metrics_row.find_elements(By.XPATH, "./div") - assert len(metrics) == 5 - - metric_texts = [_remove_tags(m.text) for m in metrics] - expected_metrics = [ - "Feeds", - "", - "Volume", - "Sales", - "Revenue", - ] - - for i, metric in enumerate(expected_metrics): - assert metric in metric_texts[i] - - -def test_feeds_table_filters(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_feeds_page(dash_duo) - dash_duo.wait_for_element("#feeds_page_table") - dash_duo.wait_for_element("#base_token") - - table = dash_duo.find_element("#feeds_page_table table") - - # Test filtering with base token - _set_dropdown_and_verify_row_count(dash_duo, "#base_token", "ETH", 3) - _verify_table_data(table, "filtered_base_token_eth.json") - - # Test filtering with timeframe - _set_dropdown_and_verify_row_count(dash_duo, "#timeframe", "5m", 2) - _verify_table_data(table, "filtered_base_token_eth_5m.json") - - _clear_feeds_filters(dash_duo) - _assert_table_row_count(dash_duo, "#feeds_page_table", 21) - _verify_table_data(table, "expected_feeds_table_data.json") - - # Test filtering with ADA base token and accuracy range - _set_dropdown_and_verify_row_count(dash_duo, "#base_token", "ADA", 3) - _verify_table_data(table, "filtered_base_token_ada.json") - - _clear_feeds_filters(dash_duo) - # Test filtering with accuracy min value - _set_input_value_and_submit( - dash_duo, "#accuracy_dropdown", "#accuracy_min", "90", "#accuracy_button" - ) - _assert_table_row_count(dash_duo, "#feeds_page_table", 1) - _verify_table_data(table, "filtered_accuracy_min_90.json") - - # Test filtering with accuracy min value - _set_input_value_and_submit( - dash_duo, None, "#accuracy_min", "55", "#accuracy_button" - ) - _assert_table_row_count(dash_duo, "#feeds_page_table", 2) - _verify_table_data(table, "filtered_accuracy_min_55.json") - - # Test filtering with volume max value - _set_input_value_and_submit( - dash_duo, "#volume_dropdown", "#volume_max", "14000", "#volume_button" - ) - _assert_table_row_count(dash_duo, "#feeds_page_table", 1) - _verify_table_data(table, "filtered_volume_max_1400.json") - - _clear_feeds_filters(dash_duo) - _assert_table_row_count(dash_duo, "#feeds_page_table", 21) - _verify_table_data(table, "expected_feeds_table_data.json") - - -def test_feeds_table_modal(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_feeds_page(dash_duo) - dash_duo.wait_for_element("#feeds_page_table") - - # Select a row - table = dash_duo.find_element("#feeds_page_table") - table.find_element(By.XPATH, "//tr[2]//td[1]//input[@type='radio']").click() - time.sleep(1) - - base_token = table.find_element(By.XPATH, "//tr[2]//td[3]//div").text - quote_token = table.find_element(By.XPATH, "//tr[2]//td[4]//div").text - timeframe = table.find_element(By.XPATH, "//tr[2]//td[6]//div").text - source = table.find_element(By.XPATH, "//tr[2]//td[5]//div").text - - dash_duo.wait_for_element("#feeds_modal", timeout=4) - - # Validate modal content - modal = dash_duo.find_element("#feeds_modal") - header_text = modal.find_element( - By.XPATH, "//div[@id='feeds_modal-header']//span" - ).text - assert header_text == f"{base_token}-{quote_token} {timeframe} {source}" - - number_of_plots = len( - modal.find_element(By.ID, "feeds_modal-body").find_elements( - By.CLASS_NAME, "dash-graph" - ) - ) - assert number_of_plots == 6 - - # Close modal by clicking the background - dash_duo.find_element(".modal").click() - - # Ensure no row is selected - assert not any( - "selected" in row.get_attribute("class") - for row in table.find_elements(By.XPATH, ".//tr") - ) - - -def test_feeds_searchbar(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_feeds_page(dash_duo) - dash_duo.wait_for_element("#search-input-feeds-table") - table = dash_duo.find_element("#feeds_page_table") - _set_searchbar_value( - dash_duo, "#search-input-feeds-table", "ETH", "#feeds_page_table", 3 - ) - _verify_table_data(table, "search_eth.json") - - _set_searchbar_value( - dash_duo, "#search-input-feeds-table", "ADA", "#feeds_page_table", 3 - ) - _verify_table_data(table, "search_ada.json") - - _set_searchbar_value( - dash_duo, "#search-input-feeds-table", "6f3bc", "#feeds_page_table", 2 - ) - _verify_table_data(table, "search_6f3bc.json") - - _set_searchbar_value( - dash_duo, "#search-input-feeds-table", "NO_ROWS", "#feeds_page_table", 1 - ) - _verify_table_data(table, "search_no_rows.json") - - -def test_sort_table(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_feeds_page(dash_duo) - - # Wait for the table to be fully rendered - dash_duo.wait_for_element("#feeds_page_table") - - # Select the table element - table = dash_duo.find_element("#feeds_page_table") - - actionables = table.find_elements( - By.XPATH, "//div//div[@class='column-actions']//span" - )[6] - - actionables.click() - # Wait for the sort to apply - time.sleep(2) # Sometimes sorting might take a moment - - # Check if the data is sorted ascending - _verify_table_data_order( - table, - "sorted_feeds_table_asc_by_avg_stake.json", - lambda x: x["Avg Stake Per Epoch (Ocean)"] == "0", - ) diff --git a/pdr_backend/pdr_dashboard/test/test_callbacks_predictoors.py b/pdr_backend/pdr_dashboard/test/test_callbacks_predictoors.py deleted file mode 100644 index d5ad5c9dc..000000000 --- a/pdr_backend/pdr_dashboard/test/test_callbacks_predictoors.py +++ /dev/null @@ -1,231 +0,0 @@ -import time - -from selenium.webdriver.common.by import By - -from pdr_backend.pdr_dashboard.test.resources import ( - _assert_table_row_count, - _clear_predictoors_filters, - _navigate_to_predictoors_page, - _remove_tags, - _set_input_value_and_submit, - _set_searchbar_value, - start_server_and_wait, -) -from pdr_backend.pdr_dashboard.test.test_callbacks_feeds import ( - _verify_table_data, - _verify_table_data_order, - _save_table_data, -) - - -def test_predictoors_table(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_predictoors_page(dash_duo) - dash_duo.wait_for_element("#predictoors_page_table table") - - time.sleep(5) - table = dash_duo.find_element("#predictoors_page_table table") - - # Validate row and column count - rows = table.find_elements(By.XPATH, ".//tr") - assert len(rows) == 58 - - header = rows[0].find_elements(By.XPATH, ".//th") - columns = header - assert len(columns) == 10 - - # Validate headers - header_texts = [_remove_tags(c.text) for c in columns] - expected_headers = [ - "", - "Addr", - "Apr", - "Accuracy", - "Number Of Feeds", - "Staked (Ocean)", - "Gross Income (Ocean)", - "Stake Loss (Ocean)", - "Tx Costs (Ocean)", - "Profit (Ocean)", - ] - assert header_texts == expected_headers - - _verify_table_data(table, "expected_predictoors_table_data.json") - - -def test_predictoors_page_metrics_row(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_predictoors_page(dash_duo) - - dash_duo.wait_for_element("#predictoors_page_metrics_row") - - time.sleep(5) - metrics_row = dash_duo.find_element("#predictoors_page_metrics_row") - - # Validate metrics - # select first level divs - metrics = metrics_row.find_elements(By.XPATH, "./div") - assert len(metrics) == 5 - - metric_texts = [_remove_tags(m.text) for m in metrics] - expected_metrics = [ - "Predictoors", - "Accuracy(avg)", - "Staked", - "Gross Income", - "Clipped Payout", - ] - - for i, metric in enumerate(expected_metrics): - assert metric in metric_texts[i] - - -def test_predictoors_table_filters(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_predictoors_page(dash_duo) - dash_duo.wait_for_element("#predictoors_page_table") - dash_duo.wait_for_element("#p_avg_accuracy_dropdown") - - table = dash_duo.find_element("#predictoors_page_table table") - - _clear_predictoors_filters(dash_duo) - # Test filtering with accuracy min value - _set_input_value_and_submit( - dash_duo, - "#p_avg_accuracy_dropdown", - "#p_avg_accuracy_min", - "90", - "#p_avg_accuracy_button", - ) - - _assert_table_row_count(dash_duo, "#predictoors_page_table", 1) - _verify_table_data(table, "filtered_p_avg_accuracy_min_90.json") - - # Test filtering with accuracy min value - _set_input_value_and_submit( - dash_duo, None, "#p_avg_accuracy_min", "55", "#p_avg_accuracy_button" - ) - _assert_table_row_count(dash_duo, "#predictoors_page_table", 4) - _verify_table_data(table, "filtered_p_avg_accuracy_min_55.json") - - # Test filtering with staked max value + natural language - _set_input_value_and_submit( - dash_duo, "#staked_dropdown", "#staked_max", "4K", "#staked_button" - ) - _assert_table_row_count(dash_duo, "#predictoors_page_table", 1) - _verify_table_data(table, "filtered_staked_max_4K.json") - - _clear_predictoors_filters(dash_duo) - _assert_table_row_count(dash_duo, "#predictoors_page_table", 58) - _verify_table_data(table, "expected_predictoors_table_data.json") - - -def test_predictoors_table_modal(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_predictoors_page(dash_duo) - dash_duo.wait_for_element("#predictoors_page_table") - - # Select a row - table = dash_duo.find_element("#predictoors_page_table") - table.find_element(By.XPATH, "//tr[2]//td[1]//input[@type='radio']").click() - time.sleep(1) - - addr_short = table.find_element(By.XPATH, "//tr[2]//td[2]//div").text - - dash_duo.wait_for_element("#predictoors_modal", timeout=4) - - # Validate modal content - modal = dash_duo.find_element("#predictoors_modal") - header_text = modal.find_element( - By.XPATH, "//div[@id='predictoors_modal-header']//span" - ).text - assert ( - header_text == addr_short[:5] + "..." + addr_short[-5:] + " - Predictoor Data" - ) - - number_of_plots = len( - modal.find_element(By.ID, "predictoors_modal-body").find_elements( - By.CLASS_NAME, "dash-graph" - ) - ) - assert number_of_plots == 5 - - # Close modal by clicking the background - dash_duo.find_element(".modal").click() - - # Ensure no row is selected - assert not any( - "selected" in row.get_attribute("class") - for row in table.find_elements(By.XPATH, ".//tr") - ) - - -def test_predictoors_searchbar(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_predictoors_page(dash_duo) - - time.sleep(5) - dash_duo.wait_for_element("#search-input-predictoors-table") - table = dash_duo.find_element("#predictoors_page_table") - - _set_searchbar_value( - dash_duo, - "#search-input-predictoors-table", - "xac8", - "#predictoors_page_table", - 2, - ) - - _verify_table_data(table, "search_p_xac8.json") - - -def test_sort_table(_sample_app, dash_duo): - app = _sample_app - start_server_and_wait(dash_duo, app) - - _navigate_to_predictoors_page(dash_duo) - - time.sleep(4) - # Wait for the table to be fully rendered - dash_duo.wait_for_element("#predictoors_page_table") - - # Select the table element - table = dash_duo.find_element("#predictoors_page_table") - - # Click the 'Staked' column header to sort - actionables = table.find_elements( - By.XPATH, "//div//div[@class='column-actions']//span" - )[4] - actionables.click() - - # Wait for the sort to apply - time.sleep(4) # Sometimes sorting might take a moment - - # Check if the data is sorted ascending - _verify_table_data_order( - table, - "sorted_predictoors_table_asc_by_stake.json", - lambda x: x["Staked (Ocean)"] == "0", - ) - - # Click again to sort descending - actionables.click() - time.sleep(3) # Wait for the sort to apply - - _save_table_data(table, "sorted_predictoors_table_desc_by_stake.json") - # Check if the data is sorted descending - _verify_table_data_order( - table, - "sorted_predictoors_table_desc_by_stake.json", - lambda x: x["Staked (Ocean)"] == "0", - ) diff --git a/pdr_backend/pred_submitter/test/conftest.py b/pdr_backend/pred_submitter/test/conftest.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/pdr_backend/pred_submitter/test/test_deploy.py b/pdr_backend/pred_submitter/test/test_deploy.py deleted file mode 100644 index 4bf12fe7b..000000000 --- a/pdr_backend/pred_submitter/test/test_deploy.py +++ /dev/null @@ -1,16 +0,0 @@ -from pdr_backend.conftest_ganache import * # pylint: disable=wildcard-import -from pdr_backend.contract.pred_submitter_mgr import ( - PredSubmitterMgr, -) -from pdr_backend.pred_submitter.deploy import ( - deploy_pred_submitter_mgr_contract, -) - - -# pylint: disable=redefined-outer-name -def test_deploy(web3_pp): - deployed_address = deploy_pred_submitter_mgr_contract(web3_pp) - assert deployed_address - - contract = PredSubmitterMgr(web3_pp, deployed_address) - assert contract.version() diff --git a/pdr_backend/pred_submitter/test/test_pred_submitter_manager.py b/pdr_backend/pred_submitter/test/test_pred_submitter_manager.py deleted file mode 100644 index 91928497b..000000000 --- a/pdr_backend/pred_submitter/test/test_pred_submitter_manager.py +++ /dev/null @@ -1,226 +0,0 @@ -# pylint: disable=redefined-outer-name -from web3.types import RPCEndpoint - -from pdr_backend.conftest_ganache import * # pylint: disable=wildcard-import -from pdr_backend.contract.dfrewards import DFRewards -from pdr_backend.contract.pred_submitter_mgr import ( - PredSubmitterMgr, -) - -from pdr_backend.util.currency_types import Wei -from pdr_backend.util.time_types import UnixTimeS - - -def test_version( - pred_submitter_mgr: PredSubmitterMgr, -): - version = pred_submitter_mgr.version() - assert version == "0.1.0", "Version should be 0.1.0" - - -def test_get_up_predictoor_address( - pred_submitter_mgr: PredSubmitterMgr, -): - address = pred_submitter_mgr.pred_submitter_up_address() - assert address - - -def test_get_down_predictoor_address( - pred_submitter_mgr: PredSubmitterMgr, -): - address = pred_submitter_mgr.pred_submitter_down_address() - assert address - - -def test_approve( - pred_submitter_mgr: PredSubmitterMgr, - feed_contract1, - feed_contract2, - OCEAN, -): - pmup = pred_submitter_mgr.pred_submitter_up_address() - pmdown = pred_submitter_mgr.pred_submitter_down_address() - pc1 = feed_contract1.contract_address - pc2 = feed_contract2.contract_address - assert OCEAN.allowance(pmup, pc1) == 0 - assert OCEAN.allowance(pmup, pc2) == 0 - assert OCEAN.allowance(pmdown, pc2) == 0 - assert OCEAN.allowance(pmdown, pc2) == 0 - - contract_addrs = [ - pc1, - pc2, - ] - tx_receipt = pred_submitter_mgr.approve_ocean(contract_addrs, True) - assert tx_receipt.status == 1, "Transaction failed" - - assert OCEAN.allowance(pmup, pc1).amt_wei == 2**256 - 1 - assert OCEAN.allowance(pmup, pc2).amt_wei == 2**256 - 1 - assert OCEAN.allowance(pmdown, pc1).amt_wei == 2**256 - 1 - assert OCEAN.allowance(pmdown, pc2).amt_wei == 2**256 - 1 - - -def test_transfer_erc20(pred_submitter_mgr: PredSubmitterMgr, OCEAN, web3_config): - OCEAN.transfer(pred_submitter_mgr.contract_address, Wei(100), web3_config.owner) - assert OCEAN.balanceOf(pred_submitter_mgr.contract_address) == Wei(100) - before = OCEAN.balanceOf(web3_config.owner) - pred_submitter_mgr.transfer_erc20( - OCEAN.contract_address, web3_config.owner, Wei(100) - ) - after = OCEAN.balanceOf(web3_config.owner) - assert Wei(after.amt_wei - before.amt_wei) == Wei(100) - assert OCEAN.balanceOf(pred_submitter_mgr.contract_address) == 0 - - -def test_transfer(pred_submitter_mgr: PredSubmitterMgr, web3_config): - tx = web3_config.w3.eth.send_transaction( - { - "to": pred_submitter_mgr.contract_address, - "value": 100, - "gasPrice": web3_config.w3.eth.gas_price, - "from": web3_config.owner, - } - ) - web3_config.w3.eth.wait_for_transaction_receipt(tx) - assert web3_config.w3.eth.get_balance(pred_submitter_mgr.contract_address) == 100 - before = web3_config.w3.eth.get_balance(web3_config.owner) - pred_submitter_mgr.transfer() - after = web3_config.w3.eth.get_balance(web3_config.owner) - assert after - before == 100 - assert web3_config.w3.eth.get_balance(pred_submitter_mgr.contract_address) == 0 - - -def test_claim_dfrewards(pred_submitter_mgr: PredSubmitterMgr, web3_pp, OCEAN): - dfrewards_addr = web3_pp.get_address("DFRewards") - dfrewards = DFRewards(web3_pp, dfrewards_addr) - - pmup = pred_submitter_mgr.pred_submitter_up_address() - pmdown = pred_submitter_mgr.pred_submitter_down_address() - - # approve rewards - OCEAN.approve(dfrewards_addr, Wei(200), web3_pp.web3_config.owner) - - # allocate rewards - tx = dfrewards.contract_instance.functions.allocate( - [pmup, pmdown], - [100, 100], - OCEAN.contract_address, - ).transact(web3_pp.tx_call_params()) - web3_pp.web3_config.w3.eth.wait_for_transaction_receipt(tx) - - # record before balances - before_up = OCEAN.balanceOf(pmup) - before_down = OCEAN.balanceOf(pmdown) - - # claim rewards - pred_submitter_mgr.claim_dfrewards(OCEAN.contract_address, dfrewards_addr) - - # record after balances - after_up = OCEAN.balanceOf(pmup) - after_down = OCEAN.balanceOf(pmdown) - - # assert - assert after_up - before_up == Wei(100) - assert after_down - before_down == Wei(100) - - -def test_submit_prediction_and_payout( - pred_submitter_mgr: PredSubmitterMgr, - web3_config, - feed_contract1: FeedContract, - feed_contract2, - OCEAN, -): - # the user approves 100 OCEAN tokens to the prediction manager - OCEAN.approve(pred_submitter_mgr.contract_address, Wei(100), web3_config.owner) - - # get the next prediction epoch - current_epoch = feed_contract1.get_current_epoch_ts() - - # set prediction epoch - prediction_epoch = UnixTimeS(current_epoch + S_PER_EPOCH * 3) - - # get the OCEAN balance of the owner before submitting - bal_before = OCEAN.balanceOf(web3_config.owner) - assert bal_before > Wei(100), "Not enough balance to execute the test" - - feed_addrs = [ - feed_contract1.contract_address, - feed_contract2.contract_address, - ] - # give allowance - tx_receipt = pred_submitter_mgr.approve_ocean(feed_addrs) - assert tx_receipt.status == 1, "Transaction failed" - - # submit prediction - # first feed up 20, down 30 - # second feed up 40, down 10 - tx_receipt = pred_submitter_mgr.submit_prediction( - stakes_up=[Wei(20), Wei(30)], - stakes_down=[Wei(40), Wei(10)], - feed_addrs=feed_addrs, - epoch=prediction_epoch, - wait_for_receipt=True, - ) - assert tx_receipt.status == 1, "Transaction failed" - - # get the OCEAN balance of the contract after submitting - bal_after = OCEAN.balanceOf(web3_config.owner) - assert bal_before - bal_after == Wei(100), "Should have spent 100 OCEAN" - - # fast forward time to get payout - web3_config.w3.provider.make_request( - RPCEndpoint("evm_increaseTime"), [S_PER_EPOCH * 5] - ) - web3_config.w3.provider.make_request(RPCEndpoint("evm_mine"), []) - - # submit the trueval: True for first contract, False for second - feed_contract1.submit_trueval(True, prediction_epoch, False, True) - feed_contract2.submit_trueval(False, prediction_epoch, False, True) - - # time to claim payouts - - # get the OCEAN balance of the contract before claiming - bal_before = OCEAN.balanceOf(web3_config.owner) - - # claim - pred_submitter_mgr.get_payout([prediction_epoch], feed_addrs, wait_for_receipt=True) - - # get the OCEAN balance of the owner after claiming - bal_after = OCEAN.balanceOf(web3_config.owner) - - assert bal_after - bal_before == Wei(100), "Payout should be 100 OCEAN" - - # check predictions one by one - pmup = pred_submitter_mgr.pred_submitter_up_address() - pmdown = pred_submitter_mgr.pred_submitter_down_address() - - pred_down_first_feed = feed_contract1.get_prediction(prediction_epoch, pmdown) - pred_down_second_feed = feed_contract2.get_prediction(prediction_epoch, pmdown) - pred_up_first_feed = feed_contract1.get_prediction(prediction_epoch, pmup) - pred_up_second_feed = feed_contract2.get_prediction(prediction_epoch, pmup) - - assert pred_down_first_feed == ( - False, - 40, - pmdown, - True, - ), "Prediction should be False, 30" - assert pred_down_second_feed == ( - False, - 10, - pmdown, - True, - ), "Prediction should be True, 10" - assert pred_up_first_feed == ( - True, - 20, - pmup, - True, - ), "Prediction should be False, 20" - assert pred_up_second_feed == ( - True, - 30, - pmup, - True, - ), "Prediction should be True, 40" diff --git a/pdr_backend/predictoor/test/mockutil.py b/pdr_backend/predictoor/test/mockutil.py deleted file mode 100644 index 41640b6c4..000000000 --- a/pdr_backend/predictoor/test/mockutil.py +++ /dev/null @@ -1,117 +0,0 @@ -import os -from typing import List -from unittest.mock import Mock - -from enforce_typing import enforce_types - -from pdr_backend.ppss.ppss import mock_feed_ppss, mock_ppss -from pdr_backend.ppss.web3_pp import ( - inplace_mock_query_feed_contracts, - inplace_mock_w3_and_contract_with_tracking, -) -from pdr_backend.subgraph.subgraph_feed import mock_feed, SubgraphFeed -from pdr_backend.util.time_types import UnixTimeS - -PRIV_KEY = str(os.getenv("PRIVATE_KEY")) -PRIV_KEY2 = PRIV_KEY[:-4] + "0000" -OWNER_ADDR = "0xowner" -INIT_TIMESTAMP = UnixTimeS(107) -INIT_BLOCK_NUMBER = 13 - - -@enforce_types -def mock_ppss_1feed(approach: int, tmpdir: str, monkeypatch, pred_submitter_mgr=None): - """ - @description - Initialize the agent, and return it along with related info - For 1 feed (vs 2 or other). - - @return - feed -- SubgraphFeed, eg for binance BTC/USDT 5m - ppss -- PPSS - pdr_contract -- FeedContract corresponding to the feed - """ - # mock ppss, feed - monkeypatch.setenv("PRIVATE_KEY", PRIV_KEY) - monkeypatch.setenv("PRIVATE_KEY2", PRIV_KEY2) - feed, ppss = mock_feed_ppss( - "5m", - "binanceus", - "BTC/USDT", - network="development", - tmpdir=tmpdir, - pred_submitter_mgr=pred_submitter_mgr, - ) - ppss.predictoor_ss.set_approach(approach) - - # mock ppss.web3_pp.query_feed_contracts() - inplace_mock_query_feed_contracts(ppss.web3_pp, feed) - - # mock w3, pdr contract - pdr_contract = inplace_mock_w3_and_contract_with_tracking( - ppss.web3_pp, - INIT_TIMESTAMP, - INIT_BLOCK_NUMBER, - feed.seconds_per_epoch, - feed.address, - monkeypatch, - ) - - return (feed, ppss, pdr_contract) - - -@enforce_types -def mock_ppss_2feeds(approach: int, tmpdir: str, monkeypatch, pred_submitter_mgr=None): - """ - @description - Initialize the agent, and return it along with related info - For 2 feeds (vs 1 or other) - - @return - feeds -- list of SubgraphFeed, eg for binance {BTC,ETH}/USDT 5m - ppss -- PPSS - """ - monkeypatch.setenv("PRIVATE_KEY", PRIV_KEY) - monkeypatch.setenv("PRIVATE_KEY2", PRIV_KEY2) - - # mock ppss, feeds - exchange, timescale, quote = "binanceus", "5m", "USDT" - coins = ["BTC", "ETH"] - feeds: List[SubgraphFeed] = [ - mock_feed(timescale, exchange, f"{c}/{quote}") for c in coins - ] - ppss = mock_ppss( - [ - { - "predict": f"{exchange} {c}/{quote} c {timescale}", - "train_on": [f"{exchange} {c}/{quote} c {timescale}" for c in coins], - } - for c in coins - ], - network="development", - tmpdir=tmpdir, - pred_submitter_mgr=pred_submitter_mgr, - ) - ppss.predictoor_ss.set_approach(approach) - - # mock ppss.web3_pp.query_feed_contracts() - ppss.web3_pp.query_feed_contracts = Mock() - ppss.web3_pp.query_feed_contracts.return_value = { - feed.address: feed for feed in feeds - } - - # mock w3 - ppss.web3_pp._web3_config = Mock() - ppss.web3_pp._web3_config.w3 = Mock() - ppss.web3_pp._web3_config.w3.eth = Mock() - - # mock pdr contract - pdr_contract = Mock() - contract_func = Mock() - contract_func.return_value = pdr_contract - monkeypatch.setattr( - "pdr_backend.contract.feed_contract.FeedContract", - contract_func, - ) - - return (feeds, ppss) diff --git a/pdr_backend/predictoor/test/test_find_shared_slots.py b/pdr_backend/predictoor/test/test_find_shared_slots.py deleted file mode 100644 index 689e04a8b..000000000 --- a/pdr_backend/predictoor/test/test_find_shared_slots.py +++ /dev/null @@ -1,64 +0,0 @@ -from pdr_backend.predictoor.util import find_shared_slots - - -def test_shared_slots_basic(): - pending_slots = {"addr1": [1, 2, 3, 4], "addr2": [1, 2, 3, 4, 5], "addr3": [2]} - expected = [ - (["addr1", "addr2"], [1, 3, 4]), - (["addr1", "addr2", "addr3"], [2]), - (["addr2"], [5]), - ] - assert find_shared_slots(pending_slots, 100) == expected - - -def test_no_shared_slots(): - pending_slots = { - "addr1": [1, 2], - "addr2": [3, 4], - } - expected = [ - (["addr1"], [1, 2]), - (["addr2"], [3, 4]), - ] - assert find_shared_slots(pending_slots, 100) == expected - - -def test_single_address_multiple_slots(): - pending_slots = {"addr1": [1, 2, 3]} - expected = [ - (["addr1"], [1, 2, 3]), - ] - assert find_shared_slots(pending_slots, 100) == expected - - -def test_empty_input(): - pending_slots = {} - expected = [] - assert find_shared_slots(pending_slots, 100) == expected - - -def test_batch_size_1(): - pending_slots = {"addr1": [1, 2, 3, 4], "addr2": [1, 2, 3, 4, 5], "addr3": [2]} - expected = [ - (["addr1", "addr2"], [1]), - (["addr1", "addr2"], [3]), - (["addr1", "addr2"], [4]), - (["addr1", "addr2", "addr3"], [2]), - (["addr2"], [5]), - ] - assert find_shared_slots(pending_slots, 1) == expected - - -def test_batch_size_3(): - pending_slots = { - "addr1": [1, 2, 3, 4, 5], - "addr2": [1, 2, 3, 4, 5, 6], - "addr3": [2], - } - expected = [ - (["addr1", "addr2"], [1, 3, 4]), - (["addr1", "addr2"], [5]), - (["addr1", "addr2", "addr3"], [2]), - (["addr2"], [6]), - ] - assert find_shared_slots(pending_slots, 3) == expected diff --git a/pdr_backend/predictoor/test/test_predictoor_agent.py b/pdr_backend/predictoor/test/test_predictoor_agent.py deleted file mode 100644 index 93eb570c6..000000000 --- a/pdr_backend/predictoor/test/test_predictoor_agent.py +++ /dev/null @@ -1,407 +0,0 @@ -# pylint: disable=redefined-outer-name - -from unittest.mock import MagicMock, Mock, patch - -import pytest -import numpy as np -import polars as pl - -from enforce_typing import enforce_types -from numpy.testing import assert_array_equal - -from pdr_backend.cli.predict_train_feedsets import PredictTrainFeedset -from pdr_backend.ppss.ppss import PPSS -from pdr_backend.ppss.predictoor_ss import PredictoorSS -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.predictoor.predictoor_agent import PredictoorAgent -from pdr_backend.predictoor.test.mockutil import ( - INIT_TIMESTAMP, - INIT_BLOCK_NUMBER, - mock_ppss_1feed, - mock_ppss_2feeds, -) -from pdr_backend.util.currency_types import Eth -from pdr_backend.subgraph.subgraph_feed import SubgraphFeed - -# =========================================================================== -# test approach {1, 2, 3} - main loop - -# do _not_ parameterize these. It's much easier to test them individually -# and debug when they're separate - - -@enforce_types -def test_predictoor_agent_main1(tmpdir, monkeypatch, pred_submitter_mgr): - _test_predictoor_agent_main(1, str(tmpdir), monkeypatch, pred_submitter_mgr) - - -@enforce_types -def test_predictoor_agent_main2(tmpdir, monkeypatch, pred_submitter_mgr): - _test_predictoor_agent_main(2, str(tmpdir), monkeypatch, pred_submitter_mgr) - - -def test_predictoor_agent_main3(tmpdir, monkeypatch, pred_submitter_mgr): - _test_predictoor_agent_main(3, str(tmpdir), monkeypatch, pred_submitter_mgr) - - -@pytest.fixture() -def pred_submitter_mgr(): - with patch("pdr_backend.predictoor.predictoor_agent.PredSubmitterMgr") as mock: - mock.submit_prediction.return_value = {"transactionHash": b"hello", "status": 1} - mock.contract_address = "0x123" - yield mock - - -@enforce_types -def _test_predictoor_agent_main( - approach: int, tmpdir: str, monkeypatch, pred_submitter_mgr -): - """ - @description - Run the agent for a while, and then do some basic sanity checks. - Uses get_agent_1feed, *not* 2feeds. - """ - assert approach in [1, 2, 3] - - # mock tokens - mock_token = Mock() - mock_token.balanceOf.return_value = Eth(1000).to_wei() - - with patch("pdr_backend.ppss.web3_pp.Token", return_value=mock_token), patch( - "pdr_backend.ppss.web3_pp.NativeToken", return_value=mock_token - ): - _, ppss, _mock_pdr_contract = mock_ppss_1feed( - approach, - tmpdir, - monkeypatch, - ) - assert ppss.predictoor_ss.approach == approach - ppss.predictoor_ss.d["bot_only"][ - "pred_submitter_mgr" - ] = pred_submitter_mgr.contract_address - feed_contracts = ppss.web3_pp.query_feed_contracts() - web3_config = ppss.web3_pp.web3_config - w3 = ppss.web3_pp.w3 - mock_token = Mock() - mock_token.balanceOf.return_value = Eth(1000).to_wei() - ppss.web3_pp = MagicMock(spec=Web3PP) - ppss.web3_pp.OCEAN_Token = mock_token - ppss.web3_pp.NativeToken = mock_token - ppss.web3_pp.get_single_contract.return_value = _mock_pdr_contract - ppss.web3_pp.query_feed_contracts.return_value = feed_contracts - ppss.web3_pp.web3_config = web3_config - ppss.web3_pp.w3 = w3 - # now we're done the mocking, time for the real work!! - - # real work: main iterations - agent = PredictoorAgent(ppss) - for _ in range(500): - agent.take_step() - - # log some final results for debubbing / inspection - mock_w3 = ppss.web3_pp.web3_config.w3 - print("\n" + "/" * 160) - print("Done iterations") - print( - f"init block_number = {INIT_BLOCK_NUMBER}" - f", final = {mock_w3.eth.block_number}" - ) - print() - print(f"init timestamp = {INIT_TIMESTAMP}, final = {mock_w3.eth.timestamp}") - print(f"all timestamps seen = {mock_w3.eth._timestamps_seen}") - print() - print( - "unique prediction_slots = " - f"{sorted(set(_mock_pdr_contract._prediction_slots))}" - ) - print(f"all prediction_slots = {_mock_pdr_contract._prediction_slots}") - - # relatively basic sanity tests - # TO-DO Use the Prediction Submitter Manager to check these, commented out for now - # assert _mock_pdr_contract._prediction_slots - # assert (mock_w3.eth.timestamp + 2 * ppss.predictoor_ss.timeframe_s) >= max( - # _mock_pdr_contract._prediction_slots - # ) - - -# =========================================================================== -# test constructor - - -@enforce_types -def test_predictoor_agent_init_empty(pred_submitter_mgr): - """ - @description - Basic test: when there's no feeds, does it complain? - """ - # test with no feeds - pred_submitter_mgr_addr = pred_submitter_mgr.contract_address - mock_ppss_empty = MagicMock(spec=PPSS) - mock_ppss_empty.predictoor_ss = MagicMock(spec=PredictoorSS) - mock_ppss_empty.predictoor_ss.get_feed_from_candidates.return_value = [] - mock_ppss_empty.predictoor_ss.pred_submitter_mgr = pred_submitter_mgr_addr - mock_ppss_empty.web3_pp = MagicMock(spec=Web3PP) - mock_ppss_empty.web3_pp.query_feed_contracts.return_value = {} - - with pytest.raises(ValueError, match="No feeds found"): - PredictoorAgent(mock_ppss_empty) - - -# =========================================================================== -# test approach 3 - get_prediction() - -BTC_CLOSE_VALS = [10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0] -ETH_CLOSE_VALS = [30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0] - - -def mock_get_ohlcv_data2(*args, **kwargs): # pylint: disable=unused-argument - d = { - "timestamp": [100, 101, 102, 103, 104, 105, 106, 107, 108, 109], - "binanceus:BTC/USDT:open": [1.0] * 10, - "binanceus:BTC/USDT:high": [1.0] * 10, - "binanceus:BTC/USDT:low": [1.0] * 10, - "binanceus:BTC/USDT:close": BTC_CLOSE_VALS, - "binanceus:BTC/USDT:volume": [1.0] * 10, - "binanceus:ETH/USDT:open": [1.0] * 10, - "binanceus:ETH/USDT:high": [1.0] * 10, - "binanceus:ETH/USDT:low": [1.0] * 10, - "binanceus:ETH/USDT:close": ETH_CLOSE_VALS, - "binanceus:ETH/USDT:volume": [1.0] * 10, - } - mergedohlcv_df = pl.DataFrame(d) - return mergedohlcv_df - - -class MockModel: - """scikit-learn style model""" - - def __init__(self): - self.aimodel_data_ss = None # fill this in later, after patch applied - self.last_X = None # for tracking test results - self.last_yptrue = None # "" - - def predict_ptrue(self, X: np.ndarray) -> np.ndarray: - (n_points, _) = X.shape - assert n_points == 1 # this mock can only handle 1 input point - - CLOSE_VALS = X - prob_up = np.sum(CLOSE_VALS) / 1e6 - assert 0.0 <= prob_up <= 1.0 - yptrue = np.array([prob_up]) - - self.last_X, self.last_yptrue = X, yptrue # cache for testing - return yptrue - - -@enforce_types -def test_predictoor_agent_calc_stakes2_1feed(tmpdir, monkeypatch, pred_submitter_mgr): - """ - @description - Test calc_stakes2() on 1 feed. - - Approach to test: - - mergedohlcv_df has simple pre-set values: CLOSE_VALS - - prob_up = model.predict_ptrue(X) is a simple sum of X-values - - then, test that sum(CLOSE_VALS[-ar_n:])/1e6 == prob_up - - where ar_n = autoregressive_n = 3 - - where the /1e6 is so 0 <= prob_up <= 1.0 when summing BTC prices - """ - mock_model = MockModel() - - def mock_build(*args, **kwargs): # pylint: disable=unused-argument - return mock_model - - d = "pdr_backend.predictoor.predictoor_agent" - with patch(f"{d}.PredictoorAgent.get_ohlcv_data", mock_get_ohlcv_data2), patch( - f"{d}.AimodelFactory.build", mock_build - ): - - # initialize agent - _, ppss, _ = mock_ppss_1feed( - 2, str(tmpdir), monkeypatch, pred_submitter_mgr.contract_address - ) - - # do prediction - mock_model.aimodel_data_ss = ppss.predictoor_ss.aimodel_data_ss - - feed_contracts = ppss.web3_pp.query_feed_contracts() - ppss.web3_pp = Mock(spec=Web3PP) - ppss.web3_pp.query_feed_contracts.return_value = feed_contracts - - ar_n = 3 - ppss.predictoor_ss.aimodel_data_ss.set_autoregressive_n(ar_n) - ppss.predictoor_ss.aimodel_data_ss.set_max_n_train(5) - - agent = PredictoorAgent(ppss) - feed = ppss.predictoor_ss.predict_train_feedsets[0] - agent.calc_stakes2(feed) - - assert mock_model.last_X.shape == (1, 3) == (1, ar_n * 1) - expected_X = np.array([BTC_CLOSE_VALS[-ar_n:]]) # [17.0, 18.0, 19.0] - expected_prob_up = sum(BTC_CLOSE_VALS[-ar_n:]) / 1e6 - expected_yptrue = np.array([expected_prob_up]) - - assert_array_equal(expected_X, mock_model.last_X) - assert_array_equal(expected_yptrue, mock_model.last_yptrue) - - -@enforce_types -def test_predictoor_agent_calc_stakes2_2feeds(tmpdir, monkeypatch, pred_submitter_mgr): - """ - @description - Test calc_stakes2(), when X has >1 input feed - """ - mock_model = MockModel() - - def mock_build(*args, **kwargs): # pylint: disable=unused-argument - return mock_model - - d = "pdr_backend.predictoor.predictoor_agent" - with patch(f"{d}.PredictoorAgent.get_ohlcv_data", mock_get_ohlcv_data2), patch( - f"{d}.AimodelFactory.build", mock_build - ): - - # initialize agent - feeds, ppss = mock_ppss_2feeds( - 2, str(tmpdir), monkeypatch, pred_submitter_mgr.contract_address - ) - assert ppss.predictoor_ss.approach == 2 - feed_contracts = ppss.web3_pp.query_feed_contracts() - ppss.web3_pp = Mock(spec=Web3PP) - ppss.web3_pp.query_feed_contracts.return_value = feed_contracts - - ar_n = 3 - ppss.predictoor_ss.aimodel_data_ss.set_autoregressive_n(ar_n) - ppss.predictoor_ss.aimodel_data_ss.set_max_n_train(5) - - assert len(feeds) == 2 - - # do prediction - mock_model.aimodel_data_ss = ppss.predictoor_ss.aimodel_data_ss - agent = PredictoorAgent(ppss) - feed = ppss.predictoor_ss.predict_train_feedsets[0] - agent.calc_stakes2(feed) - - assert mock_model.last_X.shape == (1, 6) == (1, ar_n * 2) - - # [17.0, 18.0, 19.0, 37.0, 38.0, 39.0] - expected_X = np.array([BTC_CLOSE_VALS[-ar_n:] + ETH_CLOSE_VALS[-ar_n:]]) - - expected_prob_up = sum(BTC_CLOSE_VALS[-ar_n:] + ETH_CLOSE_VALS[-ar_n:]) / 1e6 - expected_yptrue = np.array([expected_prob_up]) - - assert_array_equal(expected_X, mock_model.last_X) - assert_array_equal(expected_yptrue, mock_model.last_yptrue) - - -@enforce_types -@pytest.mark.parametrize( - "OCEAN, ROSE, expected", - [ - ( - Eth(100).to_wei(), - Eth(2).to_wei(), - True, - ), # All balances are sufficient - ( - Eth(0).to_wei(), - Eth(2).to_wei(), - False, - ), # OCEAN balance too low - ( - Eth(100).to_wei(), - Eth(0).to_wei(), - False, - ), # ROSE balance too low - ( - Eth(0).to_wei(), - Eth(0).to_wei(), - False, - ), # Both balances too low - ], -) -def test_balance_check(tmpdir, monkeypatch, OCEAN, ROSE, expected, pred_submitter_mgr): - mock_model = MockModel() - _, ppss = mock_ppss_2feeds( - 2, str(tmpdir), monkeypatch, pred_submitter_mgr.contract_address - ) - - mock_model.aimodel_data_ss = ppss.predictoor_ss.aimodel_data_ss - - feed_contracts = ppss.web3_pp.query_feed_contracts() - mock_OCEAN = Mock() - mock_OCEAN.balanceOf.return_value = OCEAN - mock_ROSE = Mock() - mock_ROSE.balanceOf.return_value = ROSE - ppss.web3_pp = Mock(spec=Web3PP) - ppss.web3_pp.OCEAN_Token = mock_OCEAN - ppss.web3_pp.NativeToken = mock_ROSE - ppss.web3_pp.query_feed_contracts.return_value = feed_contracts - - agent = PredictoorAgent(ppss) - - assert agent.check_balances(Eth(100)) == expected - - -def test_calc_stakes_across_feeds(tmpdir, monkeypatch): - _, ppss, _mock_pdr_contract = mock_ppss_1feed( - 1, - str(tmpdir), - monkeypatch, - ) - feed_contracts = ppss.web3_pp.query_feed_contracts() - predictoor_ss = ppss.predictoor_ss - predictoor_ss.d["bot_only"]["pred_submitter_mgr"] = "0x1" - predictoor_ss.d["stake_amount"] = 1.0 - predictoor_ss.d["bot_only"]["s_until_epoch_end"] = 50000 - web3_config = ppss.web3_pp.web3_config - w3 = ppss.web3_pp.w3 - - contract_mock = Mock() - contract_mock.get_current_epoch.return_value = 30 - ppss.web3_pp.get_single_contract = Mock() - ppss.web3_pp.get_single_contract.return_value = contract_mock - - feeds = [ - SubgraphFeed("BTC/USDT 5m", "0x1", "", 300, 0, "", "", "5m", ""), - SubgraphFeed("BTC/USDT 1h", "0x2", "", 3600, 0, "", "", "1h", ""), - ] - predict_train_feedsets = [ - PredictTrainFeedset.from_dict( - { - "predict": "binance BTC/USDT o 5m", - "train_on": "binance BTC/USDT ETH/USDT o 5m", - } - ), - PredictTrainFeedset.from_dict( - { - "predict": "binance LTC/USDT o 1h", - "train_on": "binance LTC/USDT ADA/USDT o 1h", - } - ), - ] - predictoor_ss.get_predict_train_feedset = Mock() - predictoor_ss.get_predict_train_feedset.side_effect = predict_train_feedsets - - ppss = MagicMock(spec=PPSS) - ppss.predictoor_ss = predictoor_ss - ppss.web3_pp = MagicMock(spec=Web3PP) - ppss.web3_pp.get_single_contract.return_value = _mock_pdr_contract - ppss.web3_pp.query_feed_contracts.return_value = feed_contracts - ppss.web3_pp.web3_config = web3_config - ppss.web3_pp.w3 = w3 - with patch("pdr_backend.predictoor.predictoor_agent.PredSubmitterMgr"): - agent = PredictoorAgent(ppss=ppss) - - stakes = agent.calc_stakes_across_feeds(feeds) - assert 600 in stakes.slots, "Must have a prediction for next 5m slot" - assert 7200 in stakes.slots, "Must have a prediction for next 1h slot" - - target_slots = stakes.target_slots - preds_5m = target_slots[600] - assert preds_5m[0].feed == feeds[0], "Must have a prediction for BTC/USDT 5m" - assert preds_5m[0].stake_up + preds_5m[0].stake_down == Eth(1.0), "sum up to 1.0" - - preds_1h = target_slots[7200] - assert preds_1h[0].feed == feeds[1], "Must have a prediction for BTC/USDT 1h" - assert preds_1h[0].stake_up + preds_1h[0].stake_down == Eth(1.0), "sum up to 1.0" diff --git a/pdr_backend/predictoor/test/test_stakes_per_slot.py b/pdr_backend/predictoor/test/test_stakes_per_slot.py deleted file mode 100644 index 952393cf5..000000000 --- a/pdr_backend/predictoor/test/test_stakes_per_slot.py +++ /dev/null @@ -1,79 +0,0 @@ -from unittest.mock import Mock - -from enforce_typing import enforce_types - -from pdr_backend.predictoor.stakes_per_slot import ( - StakeTup, - StakeTups, - StakesPerSlot, -) -from pdr_backend.subgraph.subgraph_feed import SubgraphFeed -from pdr_backend.util.currency_types import Eth -from pdr_backend.util.time_types import UnixTimeS - -FEED0 = Mock(spec=SubgraphFeed) -FEED1 = Mock(spec=SubgraphFeed) -FEED0.address = "0xFeed0" -FEED1.address = "0xFeed1" - -STAKE_UP0, STAKE_DOWN0 = Eth(10.0), Eth(20.0) -STAKE_UP1, STAKE_DOWN1 = Eth(11.0), Eth(21.0) -STAKE_UP2, STAKE_DOWN2 = Eth(12.0), Eth(22.0) -STAKE_UP3, STAKE_DOWN3 = Eth(13.0), Eth(23.0) - -TUP0 = StakeTup(FEED0, STAKE_UP0, STAKE_DOWN0) -TUP1 = StakeTup(FEED0, STAKE_UP1, STAKE_DOWN1) -TUP2 = StakeTup(FEED1, STAKE_UP2, STAKE_DOWN2) -TUP3 = StakeTup(FEED1, STAKE_UP3, STAKE_DOWN3) - -TIMESLOT0 = UnixTimeS(1000) -TIMESLOT1 = UnixTimeS(2000) - - -@enforce_types -def test_StakeTup(): - assert TUP0.feed == FEED0 - assert TUP0.stake_up == STAKE_UP0 - assert TUP0.stake_down == STAKE_DOWN0 - - -@enforce_types -def test_StakeTups(): - tups = StakeTups([TUP0, TUP1]) - assert tups[0] == TUP0 - assert tups[1] == TUP1 - - -@enforce_types -def test_StakesPerSlot(): - # empty to start - stakes = StakesPerSlot() - assert stakes.target_slots == {} - assert stakes.slots == [] - assert stakes.get_stakes_at_slot(TIMESLOT0) == [] - assert stakes.get_stakes_at_slot(TIMESLOT1) == [] - - # add at one timeslot - stakes.add_stake_at_slot(TIMESLOT0, TUP0) - stakes.add_stake_at_slot(TIMESLOT0, TUP1) - assert stakes.slots == [TIMESLOT0] - assert stakes.get_stakes_at_slot(TIMESLOT0) == [TUP0, TUP1] - assert stakes.get_stakes_at_slot(TIMESLOT1) == [] - - # add at another timeslot - stakes.add_stake_at_slot(TIMESLOT1, TUP2) - stakes.add_stake_at_slot(TIMESLOT1, TUP3) - assert stakes.slots == [TIMESLOT0, TIMESLOT1] - assert stakes.get_stakes_at_slot(TIMESLOT0) == [TUP0, TUP1] - assert stakes.get_stakes_at_slot(TIMESLOT1) == [TUP2, TUP3] - - # test get_stake_lists - (stakes_up, stakes_down, feed_addrs) = stakes.get_stake_lists(TIMESLOT0) - assert stakes_up == [STAKE_UP0, STAKE_UP1] - assert stakes_down == [STAKE_DOWN0, STAKE_DOWN1] - assert feed_addrs == ["0xFeed0", "0xFeed0"] - - (stakes_up, stakes_down, feed_addrs) = stakes.get_stake_lists(TIMESLOT1) - assert stakes_up == [STAKE_UP2, STAKE_UP3] - assert stakes_down == [STAKE_DOWN2, STAKE_DOWN3] - assert feed_addrs == ["0xFeed1", "0xFeed1"] diff --git a/pdr_backend/publisher/test/conftest.py b/pdr_backend/publisher/test/conftest.py deleted file mode 100644 index fc9ed034c..000000000 --- a/pdr_backend/publisher/test/conftest.py +++ /dev/null @@ -1 +0,0 @@ -from pdr_backend.conftest_ganache import * # pylint: disable=wildcard-import diff --git a/pdr_backend/publisher/test/test_publish_asset.py b/pdr_backend/publisher/test/test_publish_asset.py deleted file mode 100644 index 504bd3559..000000000 --- a/pdr_backend/publisher/test/test_publish_asset.py +++ /dev/null @@ -1,49 +0,0 @@ -from enforce_typing import enforce_types -from pytest import approx - -from pdr_backend.contract.feed_contract import FeedContract -from pdr_backend.publisher.publish_asset import publish_asset -from pdr_backend.cli.arg_feed import ArgFeed -from pdr_backend.util.currency_types import Eth - - -@enforce_types -def test_publish_asset(web3_pp, web3_config): - feed = ArgFeed("kraken", None, "ETH/USDT", "5m") - seconds_per_epoch = 300 - seconds_per_subscription = 60 * 60 * 24 - nft_data, _, _, _, logs_erc = publish_asset( - s_per_epoch=seconds_per_epoch, - s_per_subscription=seconds_per_subscription, - feed=feed, - trueval_submitter_addr=web3_config.owner, - feeCollector_addr=web3_config.owner, - rate=Eth(3), - cut=Eth(0.2), - web3_pp=web3_pp, - ) - - base = feed.pair.base_str - quote = feed.pair.quote_str - source = str(feed.exchange) - timeframe = str(feed.timeframe) - - nft_name = base + "-" + quote + "-" + source + "-" + timeframe - nft_symbol = base + "/" + quote - assert nft_data == (nft_name, nft_symbol, 1, "", True, web3_config.owner) - - dt_addr = logs_erc["newTokenAddress"] - assert web3_config.w3.is_address(dt_addr) - - contract = FeedContract(web3_pp, dt_addr) - - assert contract.get_secondsPerEpoch() == seconds_per_epoch - assert ( - contract.contract_instance.functions.secondsPerSubscription().call() - == seconds_per_subscription - ) - assert contract.get_price().amt_wei / 1e18 == approx(3 * (1.201)) - - assert contract.get_stake_token() == web3_pp.OCEAN_address - - assert contract.get_trueValSubmitTimeout() == 3 * 24 * 60 * 60 diff --git a/pdr_backend/publisher/test/test_publish_assets.py b/pdr_backend/publisher/test/test_publish_assets.py deleted file mode 100644 index 5c4ea25fd..000000000 --- a/pdr_backend/publisher/test/test_publish_assets.py +++ /dev/null @@ -1,71 +0,0 @@ -from unittest.mock import Mock - -from enforce_typing import enforce_types - -from pdr_backend.cli.arg_feed import ArgFeed -from pdr_backend.ppss.publisher_ss import mock_publisher_ss -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.publisher.publish_assets import publish_assets -from pdr_backend.util.currency_types import Eth - -_PATH = "pdr_backend.publisher.publish_assets" - - -def test_publish_assets_development(monkeypatch): - _test_barge("development", monkeypatch) - - -def test_publish_assets_barge_pytest(monkeypatch): - _test_barge("barge-pytest", monkeypatch) - - -def test_publish_assets_barge_pdr_bot(monkeypatch): - _test_barge("barge-predictoor-bot", monkeypatch) - - -@enforce_types -def _test_barge(network, monkeypatch): - mock_publish_asset, web3_pp = _setup_and_publish(network, monkeypatch) - - n_calls = len(mock_publish_asset.call_args_list) - assert n_calls == 1 * 3 - mock_publish_asset.assert_any_call( - s_per_epoch=300, - s_per_subscription=60 * 60 * 24, - feed=ArgFeed("binance", "close", "ETH/USDT", "5m"), - trueval_submitter_addr="0xe2DD09d719Da89e5a3D0F2549c7E24566e947260", - feeCollector_addr="0xe2DD09d719Da89e5a3D0F2549c7E24566e947260", - rate=Eth(3 / (1 + 0.2 + 0.001)), - cut=Eth(0.2), - web3_pp=web3_pp, - ) - - -def test_publish_assets_sapphire_testnet(monkeypatch): - _test_sapphire("sapphire-testnet", monkeypatch) - - -def test_publish_assets_sapphire_mainnet(monkeypatch): - _test_sapphire("sapphire-mainnet", monkeypatch) - - -@enforce_types -def _test_sapphire(network, monkeypatch): - mock_publish_asset, _ = _setup_and_publish(network, monkeypatch) - - n_calls = len(mock_publish_asset.call_args_list) - assert n_calls == 2 * 10 - - -def _setup_and_publish(network, monkeypatch): - web3_pp = Mock(spec=Web3PP) - web3_pp.network = "development" - publisher_ss = mock_publisher_ss(network) - - mock_publish_asset = Mock() - monkeypatch.setattr(f"{_PATH}.publish_asset", mock_publish_asset) - - # main call - publish_assets(web3_pp, publisher_ss) - - return mock_publish_asset, web3_pp diff --git a/pdr_backend/sim/test/test_sim_engine.py b/pdr_backend/sim/test/test_sim_engine.py index ed8601b00..e1b25eb52 100644 --- a/pdr_backend/sim/test/test_sim_engine.py +++ b/pdr_backend/sim/test/test_sim_engine.py @@ -1,9 +1,7 @@ import os import pytest -from dash import Dash from enforce_typing import enforce_types -from selenium.common.exceptions import NoSuchElementException # type: ignore[import-untyped] from pdr_backend.aimodel.aimodel import Aimodel from pdr_backend.cli.predict_train_feedsets import PredictTrainFeedsets @@ -11,14 +9,12 @@ from pdr_backend.ppss.ppss import PPSS, fast_test_yaml_str from pdr_backend.ppss.predictoor_ss import PredictoorSS, predictoor_ss_test_dict from pdr_backend.ppss.sim_ss import SimSS, sim_ss_test_dict -from pdr_backend.sim.dash_plots.callbacks import get_callbacks -from pdr_backend.sim.dash_plots.view_elements import get_layout from pdr_backend.sim.sim_engine import SimEngine @enforce_types # pylint: disable=unused-argument -def test_sim_engine(tmpdir, check_chromedriver, dash_duo): +def test_sim_engine(tmpdir): s = fast_test_yaml_str(tmpdir) ppss = PPSS(yaml_str=s, network="development") @@ -63,40 +59,3 @@ def test_sim_engine(tmpdir, check_chromedriver, dash_duo): assert sim_engine.model is None sim_engine.run() assert isinstance(sim_engine.model, Aimodel) - - app = Dash("pdr_backend.sim.sim_dash") - app.config["suppress_callback_exceptions"] = True - app.run_id = sim_engine.multi_id - app.layout = get_layout() - get_callbacks(app) - - dash_duo.start_server(app) - dash_duo.wait_for_text_to_equal( - "#sim_state_text", f"Simulation ID: {sim_engine.multi_id}", timeout=100 - ) - - # default visibility: shows figure from first tab - dash_duo.find_element("#pdr_profit_vs_time") - - # does not show figures from other tabs - with pytest.raises(NoSuchElementException): - dash_duo.find_element("#trader_profit_vs_time") - - with pytest.raises(NoSuchElementException): - dash_duo.find_element("#model_performance_vs_time") - - tabs = { - "predictor_profit_tab": ["pdr_profit_vs_time", "pdr_profit_vs_ptrue"], - "trader_profit_tab": ["trader_profit_vs_time", "trader_profit_vs_ptrue"], - "model_performance_tab": ["model_performance_vs_time"], - "model_response_tab": ["aimodel_response", "aimodel_varimps"], - "model_residuals_tab": ["prediction_residuals_other"], - } - - for tab_name, figures in tabs.items(): - # when tab is clicked, it shows its figures - tab = dash_duo.find_element(f".{tab_name}") - tab.click() - assert "tab--selected" in tab.get_attribute("class") - for figure_name in figures: - dash_duo.find_element(f"#{figure_name}") diff --git a/pdr_backend/statutil/test/test_arima_dash_plots.py b/pdr_backend/statutil/test/test_arima_dash_plots.py deleted file mode 100644 index c943af8bd..000000000 --- a/pdr_backend/statutil/test/test_arima_dash_plots.py +++ /dev/null @@ -1,59 +0,0 @@ -from dash import dcc, html -from plotly.graph_objs import Figure - -from pdr_backend.statutil.dash_plots.view_elements import ( - get_graphs_container, - display_plots_view, - display_on_column, - get_column_graphs, - get_input_elements, -) - - -def test_display_plots_view(): - col1 = html.Div(id="column1") - col2 = html.Div(id="column2") - columns = [col1, col2] - result = display_plots_view(columns) - assert len(columns) == len(result.children) - assert "column1" in result.children[0].id - assert "column2" in result.children[1].id - - -def test_get_column_graphs(): - fig1 = Figure([]) - fig2 = Figure([]) - figure_data = [ - {"parent_id": "fig1_graph", "fig": fig1, "graph_id": "fig1_graph"}, - {"parent_id": "fig2_graph", "fig": fig2, "graph_id": "fig2_graph"}, - ] - result = get_column_graphs("fig1_graph", figure_data, "title1", "") - assert len(result) == 1 - assert len(result[0].children) == len(figure_data) + 2 - assert figure_data[0]["parent_id"] + "-title" == result[0].children[0].id - assert figure_data[0]["parent_id"] == result[0].children[2].id - assert figure_data[1]["parent_id"] == result[0].children[3].id - - -def test_display_on_column(): - div_id = "test_id" - result = display_on_column(div_id) - assert div_id in result.id - assert "column" in result.style["flexDirection"] - - -def test_get_input_elements(): - result = get_input_elements() - assert len(result.children) == 2 - assert isinstance(result.children[0].children[0], dcc.Dropdown) - assert isinstance(result.children[0].children[1], dcc.DatePickerRange) - assert isinstance(result.children[1].children[0], html.Label) - assert isinstance(result.children[1].children[1], dcc.Input) - - -def test_get_graphs_container(): - result = get_graphs_container() - assert len(result.children) == 3 - assert result.children[0].id == "transition_column" - assert result.children[1].id == "seasonal_column" - assert result.children[2].id == "autocorelation_column" diff --git a/pdr_backend/statutil/test/test_seasonal.py b/pdr_backend/statutil/test/test_seasonal.py deleted file mode 100644 index e6693cd6e..000000000 --- a/pdr_backend/statutil/test/test_seasonal.py +++ /dev/null @@ -1,139 +0,0 @@ -import os -import shutil - -import pandas as pd -from dash import Dash -from enforce_typing import enforce_types - -from pdr_backend.cli.arg_timeframe import ArgTimeframe -from pdr_backend.statutil.dash_plots.callbacks import get_callbacks -from pdr_backend.statutil.dash_plots.view_elements import get_layout -from pdr_backend.statutil.seasonal import ( - SeasonalDecomposeFactory, - SeasonalPlotdata, - plot_seasonal, -) -from pdr_backend.util.mathutil import has_nan -from pdr_backend.util.time_types import UnixTimeMs - -DATA_FILE = ( - "./pdr_backend/lake/test/merged_ohlcv_df_BTC-ETH_2024-02-01_to_2024-03-08.csv" -) -BTC_COL = "binance:BTC/USDT:close" - -# set env variable as true to show plots -SHOW_PLOT = os.getenv("SHOW_PLOT", "false").lower() == "true" - - -@enforce_types -def test_relative_energy(): - (_, t, y) = _get_data() - - dr = SeasonalDecomposeFactory.build(t, y) - es = dr.relative_energy - assert not has_nan(es) - assert 0 < min(es) < max(es) <= 1.0 - assert es[0] == 1.0 - - -@enforce_types -def test_seasonal(): - (st, t, y) = _get_data() - - dr = SeasonalDecomposeFactory.build(t, y) - assert ( - y.shape - == dr.observed.shape - == dr.seasonal.shape - == dr.trend.shape - == dr.resid.shape - ) - - plotdata = SeasonalPlotdata(st, dr) - - fig = plot_seasonal(plotdata) - - if SHOW_PLOT: - fig.show() - - -@enforce_types -# pylint: disable=unused-argument -def test_empty_dashboard(tmpdir, check_chromedriver, dash_duo): - app = Dash("pdr_backend.statutil.arima_dash") - app.config["suppress_callback_exceptions"] = True - app.layout = get_layout() - app.layout.children[0].data = str(tmpdir) - get_callbacks(app) - - dash_duo.start_server(app) - dash_duo.wait_for_text_to_equal( - "#error-message h2", - "No data found! Fetch ohlcv data before running the ARIMA plots.", - ) - - -@enforce_types -# pylint: disable=unused-argument -def test_dashboard(tmpdir, check_chromedriver, dash_duo): - test_dir = str(tmpdir) - - # Sample Parquet files - src = os.path.join( - os.path.dirname(__file__), "../../tests/resources/binance_BTC-USDT_5m.parquet" - ) - shutil.copyfile(src, test_dir + "/binance_BTC-USDT_5m.parquet") - - src = os.path.join( - os.path.dirname(__file__), "../../tests/resources/binance_ETH-USDT_5m.parquet" - ) - shutil.copyfile(src, test_dir + "/binance_ETH-USDT_5m.parquet") - - app = Dash("pdr_backend.statutil.arima_dash") - app.config["suppress_callback_exceptions"] = True - app.layout = get_layout() - app.layout.children[0].data = test_dir - get_callbacks(app) - - dash_duo.start_server(app) - dash_duo.wait_for_text_to_equal("#error-message", "") - dash_duo.find_element("#arima-graphs") - - dash_duo.find_element(".Select-input input").send_keys("binance_ETH-USDT_5m") - _check_dashboard(dash_duo) - dash_duo.find_element("#autocorelation-lag").send_keys("12") - _check_dashboard(dash_duo) - dash_duo.find_element(".DateInput_input_1").send_keys("06/03/2024") - _check_dashboard(dash_duo) - dash_duo.find_element(".Select-input input").send_keys("binance_BTC-USDT_5m") - _check_dashboard(dash_duo) - dash_duo.find_element("input[type='radio']").click() - _check_dashboard(dash_duo, adf_text="BC=F,D=0") - - -def _check_dashboard(dash_duo, adf_text="BC=T,D=1"): - dash_duo.wait_for_element("#seasonal_column #relativeEnergies") - dash_duo.wait_for_element("#seasonal_column #seasonal_plots") - dash_duo.wait_for_text_to_equal( - "#seasonal_column #Seasonal-title", - f"Seasonal Decomp. for {adf_text} ⓘ", - timeout=30, - ) - dash_duo.wait_for_element("#autocorelation_column #autocorelation") - dash_duo.wait_for_element("#autocorelation_column #pautocorelation") - dash_duo.wait_for_text_to_equal( - "#autocorelation_column #Autocorelation-title", f"ACF & PACF for {adf_text} ⓘ" - ) - dash_duo.wait_for_element("#transition_column #transition_table") - dash_duo.wait_for_text_to_equal("#transition_column #Transition-title", "ADF ⓘ") - - -@enforce_types -def _get_data(): - """Return (start_ut, timeframe, yvals) for BTC 5min""" - df = pd.read_csv(DATA_FILE) # all data start_time = UnixTimeMs(df["timestamp"][0]) - st = UnixTimeMs(df["timestamp"][0]) - t = ArgTimeframe("5m") - y = df[BTC_COL].array - - return (st, t, y) diff --git a/pdr_backend/subgraph/test/resources.py b/pdr_backend/subgraph/test/resources.py deleted file mode 100644 index 955a4e4dc..000000000 --- a/pdr_backend/subgraph/test/resources.py +++ /dev/null @@ -1,24 +0,0 @@ -from enforce_typing import enforce_types - - -@enforce_types -class MockResponse: - def __init__(self, contract_list: list, status_code: int): - self.contract_list = contract_list - self.status_code = status_code - self.num_queries = 0 - - def json(self) -> dict: - self.num_queries += 1 - if self.num_queries > 1: - self.contract_list = [] - return {"data": {"predictContracts": self.contract_list}} - - -@enforce_types -class MockPost: - def __init__(self, contract_list: list = [], status_code: int = 200): - self.response = MockResponse(contract_list, status_code) - - def __call__(self, *args, **kwargs): - return self.response diff --git a/pdr_backend/subgraph/test/test_core_subgraph.py b/pdr_backend/subgraph/test/test_core_subgraph.py deleted file mode 100644 index 4256e29f5..000000000 --- a/pdr_backend/subgraph/test/test_core_subgraph.py +++ /dev/null @@ -1,20 +0,0 @@ -import pytest -import requests -from enforce_typing import enforce_types - -from pdr_backend.subgraph.core_subgraph import query_subgraph -from pdr_backend.subgraph.test.resources import MockPost - - -@enforce_types -def test_query_subgraph_happypath(monkeypatch): - monkeypatch.setattr(requests, "post", MockPost(status_code=200)) - result = query_subgraph(subgraph_url="foo", query="bar") - assert result == {"data": {"predictContracts": []}} - - -@enforce_types -def test_query_subgraph_badpath(monkeypatch): - monkeypatch.setattr(requests, "post", MockPost(status_code=400)) - with pytest.raises(Exception): - query_subgraph(subgraph_url="foo", query="bar") diff --git a/pdr_backend/subgraph/test/test_info725.py b/pdr_backend/subgraph/test/test_info725.py deleted file mode 100644 index aa8974f6e..000000000 --- a/pdr_backend/subgraph/test/test_info725.py +++ /dev/null @@ -1,135 +0,0 @@ -from enforce_typing import enforce_types -from web3 import Web3 - -from pdr_backend.subgraph.info725 import ( - get_pair_timeframe_source_from_contract, - info725_to_info, - info_to_info725, - key_to_key725, - value725_to_value, - value_to_value725, -) - - -@enforce_types -def test_key(): - key = "name" - key725 = key_to_key725(key) - assert key725 == Web3.keccak(key.encode("utf-8")).hex() - - -@enforce_types -def test_value(): - value = "ETH/USDT" - value725 = value_to_value725(value) - value_again = value725_to_value(value725) - - assert value == value_again - assert value == Web3.to_text(hexstr=value725) - - -@enforce_types -def test_value_None(): - assert value_to_value725(None) is None - assert value725_to_value(None) is None - - -@enforce_types -def test_info_to_info725_and_back(): - info = {"pair": "BTC/USDT", "timeframe": "5m", "source": "binance"} - info725 = [ - {"key": key_to_key725("pair"), "value": value_to_value725("BTC/USDT")}, - {"key": key_to_key725("timeframe"), "value": value_to_value725("5m")}, - {"key": key_to_key725("source"), "value": value_to_value725("binance")}, - ] - assert info_to_info725(info) == info725 - assert info725_to_info(info725) == info - - -@enforce_types -def test_info_to_info725_and_back__some_None(): - info = {"pair": "BTC/USDT", "timeframe": "5m", "source": None} - info725 = [ - {"key": key_to_key725("pair"), "value": value_to_value725("BTC/USDT")}, - {"key": key_to_key725("timeframe"), "value": value_to_value725("5m")}, - {"key": key_to_key725("source"), "value": None}, - ] - assert info_to_info725(info) == info725 - assert info725_to_info(info725) == info - - -@enforce_types -def test_info_to_info725__extraval(): - info = { - "pair": "BTC/USDT", - "timeframe": "5m", - "source": "binance", - "extrakey": "extraval", - } - info725 = [ - {"key": key_to_key725("pair"), "value": value_to_value725("BTC/USDT")}, - {"key": key_to_key725("timeframe"), "value": value_to_value725("5m")}, - {"key": key_to_key725("source"), "value": value_to_value725("binance")}, - {"key": key_to_key725("extrakey"), "value": value_to_value725("extraval")}, - ] - assert info_to_info725(info) == info725 - - -@enforce_types -def test_info_to_info725__missingkey(): - info = {"pair": "BTC/USDT", "timeframe": "5m"} # no "source" - info725 = [ - {"key": key_to_key725("pair"), "value": value_to_value725("BTC/USDT")}, - {"key": key_to_key725("timeframe"), "value": value_to_value725("5m")}, - {"key": key_to_key725("source"), "value": None}, - ] - assert info_to_info725(info) == info725 - - -@enforce_types -def test_get_pair_timeframe_source_from_contract_nft_data(): - contract_data = { - "token": { - "nft": { - "nftData": [ - { - "key": key_to_key725("pair"), - "value": value_to_value725("ETH/USDT"), - }, - { - "key": key_to_key725("timeframe"), - "value": value_to_value725("5m"), - }, - { - "key": key_to_key725("source"), - "value": value_to_value725("binance"), - }, - ] - } - } - } - - pair, timeframe, source = get_pair_timeframe_source_from_contract(contract_data) - assert pair == "ETH/USDT" - assert timeframe == "5m" - assert source == "binance" - - -@enforce_types -def test_get_pair_timeframe_source_from_contract_nft_data__missingkey(): - contract = { - "id": "0x3fb744c3702ff2237fc65f261046ead36656f3bc", - "secondsPerEpoch": "300", - "token": { - "id": "0x3fb744c3702ff2237fc65f261046ead36656f3bc", - "name": "BTC/USDT", - "symbol": "BTC/USDT", - "nft": None, - }, - } - - pair, timeframe, source = get_pair_timeframe_source_from_contract(contract) - - assert pair == "BTC/USDT" - assert timeframe == "5m" - assert source == "binance" diff --git a/pdr_backend/subgraph/test/test_subgraph_consume_so_far.py b/pdr_backend/subgraph/test/test_subgraph_consume_so_far.py deleted file mode 100644 index b2c76d662..000000000 --- a/pdr_backend/subgraph/test/test_subgraph_consume_so_far.py +++ /dev/null @@ -1,67 +0,0 @@ -from unittest.mock import patch - -from enforce_typing import enforce_types -from pytest import approx - -from pdr_backend.subgraph.subgraph_consume_so_far import get_consume_so_far_per_contract -from pdr_backend.util.time_types import UnixTimeS - - -SAMPLE_CONTRACT_DATA = [ - { - "user": {"id": "0xff8dcdfc0a76e031c72039b7b1cd698f8da81a0a"}, - "predictContract": {"id": "contract1"}, - }, - { - "user": {"id": "0xff8dcdfc0a76e031c72039b7b1cd698f8da81a0a"}, - "predictContract": {"id": "contract1"}, - }, -] - - -@enforce_types -def test_get_consume_so_far_per_contract(): - call_count = 0 - - def mock_query_subgraph( - subgraph_url, query, tries, timeout - ): # pylint:disable=unused-argument - nonlocal call_count - slot_data = SAMPLE_CONTRACT_DATA - - if call_count > 0: - slot_data = [] - - call_count += 1 - return {"data": {"predictSubscriptions": slot_data}} - - PATH = "pdr_backend.subgraph.subgraph_consume_so_far" - with patch(f"{PATH}.query_subgraph", mock_query_subgraph): - consumes = get_consume_so_far_per_contract( - subgraph_url="foo", - user_address="0xff8dcdfc0a76e031c72039b7b1cd698f8da81a0a", - since_timestamp=UnixTimeS(2000), - contract_addresses=["contract1"], - ) - - assert consumes["contract1"] == approx(6, 0.001) - - -@enforce_types -def test_get_consume_so_far_per_contract_empty_data(): - PATH = "pdr_backend.subgraph.subgraph_consume_so_far" - - def mock_query_subgraph( - subgraph_url, query, tries, timeout - ): # pylint:disable=unused-argument - return {"data": {"predictSubscriptions": []}} - - with patch(f"{PATH}.query_subgraph", mock_query_subgraph): - consumes = get_consume_so_far_per_contract( - subgraph_url="foo", - user_address="0xff8dcdfc0a76e031c72039b7b1cd698f8da81a0a", - since_timestamp=UnixTimeS(2000), - contract_addresses=["contract1"], - ) - - assert consumes == {} diff --git a/pdr_backend/subgraph/test/test_subgraph_feed.py b/pdr_backend/subgraph/test/test_subgraph_feed.py deleted file mode 100644 index eda39f14e..000000000 --- a/pdr_backend/subgraph/test/test_subgraph_feed.py +++ /dev/null @@ -1,82 +0,0 @@ -from enforce_typing import enforce_types - -from pdr_backend.subgraph.subgraph_feed import SubgraphFeed, mock_feed, print_feeds - - -@enforce_types -def test_feed(): - feed = SubgraphFeed( - "Contract Name", - "0x12345", - "SYM:TEST", - 60, - 15, - "0xowner", - "BTC/USDT", - "5m", - "binance", - ) - - assert feed.name == "Contract Name" - assert feed.address == "0x12345" - assert feed.symbol == "SYM:TEST" - assert feed.seconds_per_subscription == 60 - assert feed.trueval_submit_timeout == 15 - assert feed.owner == "0xowner" - assert feed.pair == "BTC/USDT" - assert feed.timeframe == "5m" - assert feed.source == "binance" - - assert feed.seconds_per_epoch == 5 * 60 - assert feed.quote == "USDT" - assert feed.base == "BTC" - - assert str(feed) == feed.shortstr() - s = str(feed) - for want_s in ["Feed", "5m", "BTC/USDT", "binance", feed.address]: - assert want_s in s - - -@enforce_types -def test_mock_feed(): - feed = mock_feed("5m", "binance", "BTC/USDT") - assert feed.timeframe == "5m" - assert feed.source == "binance" - assert feed.pair == "BTC/USDT" - assert feed.address[:2] == "0x" - assert len(feed.address) == 42 # ethereum sized address - - -@enforce_types -def test_feed__seconds_per_epoch(): - # 5m - feed = mock_feed("5m", "binance", "BTC/USDT") - assert feed.timeframe == "5m" - assert feed.seconds_per_epoch == 5 * 60 - - # 1h - feed = mock_feed("1h", "binance", "BTC/USDT") - assert feed.timeframe == "1h" - assert feed.seconds_per_epoch == 60 * 60 - - -@enforce_types -def test_feed__convert_pair(): - # start with '/', no convert needed - feed = mock_feed("5m", "binance", "BTC/USDT") - assert feed.pair == "BTC/USDT" - - # start with '-', convert to '/' - feed = mock_feed("5m", "binance", "BTC-USDT") - assert feed.pair == "BTC/USDT" - - -@enforce_types -def test_print_feeds(): - f1 = mock_feed("5m", "binance", "BTC/USDT") - f2 = mock_feed("1h", "kraken", "BTC/USDT") - feeds = {f1.address: f1, f2.address: f2} - - print_feeds(feeds) - print_feeds(feeds, label=None) - print_feeds(feeds, "my feeds") diff --git a/pdr_backend/subgraph/test/test_subgraph_feed_contracts.py b/pdr_backend/subgraph/test/test_subgraph_feed_contracts.py deleted file mode 100644 index afab30e03..000000000 --- a/pdr_backend/subgraph/test/test_subgraph_feed_contracts.py +++ /dev/null @@ -1,113 +0,0 @@ -import pytest -import requests -from enforce_typing import enforce_types - -from pdr_backend.cli.arg_timeframe import ArgTimeframe -from pdr_backend.subgraph.info725 import info_to_info725 -from pdr_backend.subgraph.subgraph_feed import SubgraphFeed -from pdr_backend.subgraph.subgraph_feed_contracts import query_feed_contracts -from pdr_backend.subgraph.test.resources import MockPost - - -@enforce_types -def mock_contract(info: dict, symbol: str) -> dict: - info725 = info_to_info725(info) - - contract = { - "id": "0xNFT1", - "token": { - "id": "0xDT1", - "name": f"Name:{symbol}", - "symbol": symbol, - "nft": { - "owner": { - "id": "0xowner1", - }, - "nftData": info725, - }, - }, - "secondsPerEpoch": ArgTimeframe(info["timeframe"]).s, - "secondsPerSubscription": 700, - "truevalSubmitTimeout": 5, - } - return contract - - -@enforce_types -def test_query_feed_contracts__emptychain(monkeypatch): - contract_list = [] - monkeypatch.setattr(requests, "post", MockPost(contract_list)) - contracts = query_feed_contracts(subgraph_url="foo") - assert contracts == {} - - -@enforce_types -def test_query_feed_contracts__fullchain(monkeypatch): - # This test is a simple-as-possible happy path. Start here. - # Then follow up with test_filter() below, which is complex but thorough - - info = {"pair": "BTC-USDT", "timeframe": "5m", "source": "binance"} - contract = mock_contract(info, "contract1") - contract_addr = contract["id"] - - contract_list = [contract] - monkeypatch.setattr(requests, "post", MockPost(contract_list)) - - feeds = query_feed_contracts(subgraph_url="foo") - - assert len(feeds) == 1 - assert contract_addr in feeds - feed = feeds[contract_addr] - assert isinstance(feed, SubgraphFeed) - - assert feed.name == "Name:contract1" - assert feed.address == "0xNFT1" - assert feed.symbol == "contract1" - assert feed.seconds_per_subscription == 700 - assert feed.trueval_submit_timeout == 5 - assert feed.owner == "0xowner1" - assert feed.pair == "BTC/USDT" - assert feed.timeframe == "5m" - assert feed.source == "binance" - assert feed.seconds_per_epoch == 5 * 60 - - -@enforce_types -@pytest.mark.parametrize( - "expect_result, owners", - [ - (True, None), - (True, ""), - (True, "0xowner1"), - (False, "0xowner2"), - (True, "0xowner1,0xowner2"), - (False, "0xowner2,0xowner3"), - ], -) -def test_query_feed_contracts__filter(monkeypatch, expect_result, owners): - info = {"pair": "BTC/USDT", "timeframe": "5m", "source": "binance"} - info725 = info_to_info725(info) - - contract1 = { - "id": "contract1", - "token": { - "id": "token1", - "name": "ether", - "symbol": "ETH", - "nft": { - "owner": { - "id": "0xowner1", - }, - "nftData": info725, - }, - }, - "secondsPerEpoch": 7, - "secondsPerSubscription": 700, - "truevalSubmitTimeout": 5, - } - contract_list = [contract1] - - monkeypatch.setattr(requests, "post", MockPost(contract_list)) - feed_dicts = query_feed_contracts("foo", owners) - - assert bool(feed_dicts) == bool(expect_result) diff --git a/pdr_backend/subgraph/test/test_subgraph_payout.py b/pdr_backend/subgraph/test/test_subgraph_payout.py deleted file mode 100644 index 40aab7c0a..000000000 --- a/pdr_backend/subgraph/test/test_subgraph_payout.py +++ /dev/null @@ -1,89 +0,0 @@ -from typing import Dict -from unittest.mock import patch - -from enforce_typing import enforce_types - -from pdr_backend.subgraph.subgraph_payout import ( - Payout, - get_payout_query, - fetch_payouts, -) -from pdr_backend.util.time_types import UnixTimeS - -# pylint: disable=line-too-long -MOCK_PAYOUT_QUERY_RESPONSE = { - "data": { - "predictPayouts": [ - { - "id": "0x18f54cc21b7a2fdd011bea06bba7801b280e3151-1696880700-0xd2a24cb4ff2584bad80ff5f109034a891c3d88dd", - "timestamp": 1698527000, - "payout": "0", - "predictedValue": True, - "trueValue": True, - "prediction": { - "stake": "1.2", - "user": {"id": "0xd2a24cb4ff2584bad80ff5f109034a891c3d88dd"}, - "slot": { - "id": "0x18f54cc21b7a2fdd011bea06bba7801b280e3151-1696880700", - "predictContract": { - "id": "0x18f54cc21b7a2fdd011bea06bba7801b280e3151", - "token": {"name": "ADA/USDT"}, - }, - "revenue": "0.919372744934776618", - "roundSumStakesUp": "7.635901006590730052", - "roundSumStakes": "17.728238320965607921", - }, - }, - } - ] - } -} - -MOCK_PAYOUT_QUERY_SECOND_RESPONSE: Dict[str, dict] = {"data": {"predictPayouts": []}} - - -def test_get_payout_query(): - payout_query = get_payout_query( - ["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - UnixTimeS(1622547000), - UnixTimeS(1622548800), - 1, - 1, - ) - - assert "1622547000" in payout_query - assert "1622548800" in payout_query - assert "0x18f54cc21b7a2fdd011bea06bba7801b280e3151" in payout_query - - -@enforce_types -@patch("pdr_backend.subgraph.subgraph_payout.query_subgraph") -def test_fetch_payouts(mock_query_subgraph): - mock_query_subgraph.side_effect = [ - MOCK_PAYOUT_QUERY_RESPONSE, - MOCK_PAYOUT_QUERY_SECOND_RESPONSE, - ] - - payouts = fetch_payouts( - addresses=["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - start_ts=UnixTimeS(1622547000), - end_ts=UnixTimeS(1622548800), - first=1000, - skip=1, - network="mainnet", - ) - assert len(payouts) == 1 - assert isinstance(payouts[0], Payout) - assert ( - payouts[0].ID - == "0x18f54cc21b7a2fdd011bea06bba7801b280e3151-1696880700-0xd2a24cb4ff2584bad80ff5f109034a891c3d88dd" - ) - assert payouts[0].token == "ADA/USDT" - assert payouts[0].timestamp == 1698527000 - assert payouts[0].slot == 1696880700 - assert payouts[0].payout == float(0) - assert payouts[0].predvalue is True - assert payouts[0].truevalue is True - assert payouts[0].user == "0xd2a24cb4ff2584bad80ff5f109034a891c3d88dd" - assert payouts[0].stake == float(1.2) - assert mock_query_subgraph.call_count == 1 diff --git a/pdr_backend/subgraph/test/test_subgraph_pending_payouts.py b/pdr_backend/subgraph/test/test_subgraph_pending_payouts.py deleted file mode 100644 index 6c926837f..000000000 --- a/pdr_backend/subgraph/test/test_subgraph_pending_payouts.py +++ /dev/null @@ -1,61 +0,0 @@ -from unittest.mock import patch - -from enforce_typing import enforce_types - -from pdr_backend.subgraph.subgraph_pending_payouts import query_pending_payouts - -SAMPLE_PENDING_DATA = [ - { - "id": "slot1", - "timestamp": 1000, - "slot": { - "id": "slot1", - "slot": 2000, - "predictContract": { - "id": "contract1", - }, - }, - } -] - - -@enforce_types -def test_query_pending_payouts(): - call_count = 0 - - def mock_query_subgraph(subgraph_url, query): # pylint:disable=unused-argument - nonlocal call_count - pending_payout_data = SAMPLE_PENDING_DATA if call_count < 1 else [] - call_count += 1 - return {"data": {"predictPredictions": pending_payout_data}} - - PATH = "pdr_backend.subgraph.subgraph_pending_payouts" - with patch(f"{PATH}.query_subgraph", mock_query_subgraph): - pending_payouts = query_pending_payouts( - subgraph_url="foo", - addr="0x123", - ) - - assert pending_payouts == {"contract1": [2000]} - - -@enforce_types -def test_query_pending_payouts_edge_cases(): - def mock_query_subgraph(subgraph_url, query): # pylint:disable=unused-argument - return {"data": {}} - - PATH = "pdr_backend.subgraph.subgraph_pending_payouts" - with patch(f"{PATH}.query_subgraph", mock_query_subgraph): - query_pending_payouts( - subgraph_url="foo", - addr="0x123", - ) - - def mock_query_subgraph_2(subgraph_url, query): # pylint:disable=unused-argument - return {"data": {"predictPredictions": []}} - - with patch(f"{PATH}.query_subgraph", mock_query_subgraph_2): - query_pending_payouts( - subgraph_url="foo", - addr="0x123", - ) diff --git a/pdr_backend/subgraph/test/test_subgraph_pending_slots.py b/pdr_backend/subgraph/test/test_subgraph_pending_slots.py deleted file mode 100644 index 448206be2..000000000 --- a/pdr_backend/subgraph/test/test_subgraph_pending_slots.py +++ /dev/null @@ -1,69 +0,0 @@ -from unittest.mock import patch - -from enforce_typing import enforce_types - -from pdr_backend.contract.slot import Slot -from pdr_backend.subgraph.info725 import key_to_key725, value_to_value725 -from pdr_backend.subgraph.subgraph_pending_slots import get_pending_slots - -SAMPLE_SLOT_DATA = [ - { - "id": "slot1", - "slot": 1000, - "trueValues": [], - "predictContract": { - "id": "contract1", - "token": { - "id": "token1", - "name": "ether", - "symbol": "ETH", - "nft": { - "owner": {"id": "0xowner1"}, - "nftData": [ - { - "key": key_to_key725("pair"), - "value": value_to_value725("ETH/USDT"), - }, - { - "key": key_to_key725("timeframe"), - "value": value_to_value725("5m"), - }, - { - "key": key_to_key725("source"), - "value": value_to_value725("binance"), - }, - ], - }, - }, - "secondsPerEpoch": 7, - "secondsPerSubscription": 700, - "truevalSubmitTimeout": 5, - }, - } -] - - -@enforce_types -def test_get_pending_slots(): - call_count = 0 - - def mock_query_subgraph(subgraph_url, query): # pylint:disable=unused-argument - nonlocal call_count - slot_data = SAMPLE_SLOT_DATA if call_count <= 1 else [] - call_count += 1 - return {"data": {"predictSlots": slot_data}} - - PATH = "pdr_backend.subgraph.subgraph_pending_slots" - with patch(f"{PATH}.query_subgraph", mock_query_subgraph): - slots = get_pending_slots( - subgraph_url="foo", - timestamp=2000, - owner_addresses=None, - allowed_feeds=None, - ) - - assert len(slots) == 2 - slot0 = slots[0] - assert isinstance(slot0, Slot) - assert slot0.slot_number == 1000 - assert slot0.feed.name == "ether" diff --git a/pdr_backend/subgraph/test/test_subgraph_predictions.py b/pdr_backend/subgraph/test/test_subgraph_predictions.py deleted file mode 100644 index 1707fca27..000000000 --- a/pdr_backend/subgraph/test/test_subgraph_predictions.py +++ /dev/null @@ -1,281 +0,0 @@ -from typing import Dict -from unittest.mock import patch - -import pytest -from enforce_typing import enforce_types - -from pdr_backend.subgraph.subgraph_predictions import ( - Prediction, - fetch_contract_id_and_spe, - fetch_filtered_predictions, - get_all_contract_ids_by_owner, -) -from pdr_backend.util.time_types import UnixTimeS - -ADA_CONTRACT_ADDRESS = "0x18f54cc21b7a2fdd011bea06bba7801b280e3151" - -SAMPLE_PREDICTION = Prediction( - # pylint: disable=line-too-long - ID="0x18f54cc21b7a2fdd011bea06bba7801b280e3151-1698527100-0xd2a24cb4ff2584bad80ff5f109034a891c3d88dd", - contract="0x18f54cc21b7a2fdd011bea06bba7801b280e3151", - pair="ADA-USDT", - timeframe="5m", - predvalue=True, - stake=0.050051425480971974, - truevalue=False, - timestamp=UnixTimeS(1698527000), - source="binance", - payout=0.0, - slot=UnixTimeS(1698527100), - user="0xd2a24cb4ff2584bad80ff5f109034a891c3d88dd", -) - -# pylint: disable=line-too-long -_PREDICTION = { - "id": "0x18f54cc21b7a2fdd011bea06bba7801b280e3151-1698527100-0xd2a24cb4ff2584bad80ff5f109034a891c3d88dd", - "user": {"id": "0xd2a24cb4ff2584bad80ff5f109034a891c3d88dd"}, - "stake": "0.050051425480971974", - "timestamp": 1698527000, - "payout": {"payout": "0", "trueValue": False, "predictedValue": True}, - "slot": { - "slot": 1698527100, - "predictContract": { - "id": "0x18f54cc21b7a2fdd011bea06bba7801b280e3151", - "secondsPerEpoch": "300", - "token": { - "id": "0x18f54cc21b7a2fdd011bea06bba7801b280e3151", - "name": "ADA-USDT", - "nft": { - "nftData": [ - { - "key": "0x238ad53218834f943da60c8bafd36c36692dcb35e6d76bdd93202f5c04c0baff", - "value": "0x55534454", - }, - { - "key": "0x2cef5778d97683b4f64607f72e862fc0c92376e44cc61195ef72a634c0b1793e", - "value": "0x4144412f55534454", - }, - { - "key": "0x49435d2ff85f9f3594e40e887943d562765d026d50b7383e76891f8190bff4c9", - "value": "0x356d", - }, - { - "key": "0xf1f3eb40f5bc1ad1344716ced8b8a0431d840b5783aea1fd01786bc26f35ac0f", - "value": "0x414441", - }, - { - "key": "0xf7e3126f87228afb82c9b18537eed25aaeb8171a78814781c26ed2cfeff27e69", - "value": "0x62696e616e6365", - }, - ] - }, - }, - }, - }, -} - -MOCK_PREDICTIONS_RESPONSE_FIRST_CALL = {"data": {"predictPredictions": [_PREDICTION]}} - -MOCK_PREDICTIONS_RESPONSE_SECOND_CALL: Dict[str, dict] = {} - -MOCK_PREDICTIONS_RESPONSE_1000 = { - "data": {"predictPredictions": [_PREDICTION for i in range(0, 1000)]} -} - -MOCK_CONTRACTS_RESPONSE = { - "data": { - "tokens": [ - {"id": "token1"}, - {"id": "token2"}, - ] - } -} - -MOCK_CONTRACT_DETAILS_RESPONSE = { - "data": { - "predictContracts": [ - {"id": "contract1", "secondsPerEpoch": 300, "token": {"name": "token1"}}, - {"id": "contract2", "secondsPerEpoch": 600, "token": {"name": "token2"}}, - ] - } -} - - -@enforce_types -@patch("pdr_backend.subgraph.subgraph_predictions.query_subgraph") -def test_fetch_filtered_predictions(mock_query_subgraph): - """ - @description - Test that fetch_filtered_predictions() can fetch predictions from subgraph - and return them as a list of Prediction objects. - """ - # show the system can fetch multiple times, and handle empty responses - mock_query_subgraph.side_effect = [ - MOCK_PREDICTIONS_RESPONSE_1000, - MOCK_PREDICTIONS_RESPONSE_1000, - MOCK_PREDICTIONS_RESPONSE_SECOND_CALL, - ] - predictions = fetch_filtered_predictions( - start_ts=UnixTimeS(1622547000), - end_ts=UnixTimeS(1622548800), - first=1000, - skip=0, - addresses=["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - network="mainnet", - ) - - assert len(predictions) == 1000 - assert isinstance(predictions[0], Prediction) - assert predictions[0].user == "0xd2a24cb4ff2584bad80ff5f109034a891c3d88dd" - assert predictions[0].pair == "ADA/USDT" - assert predictions[0].contract == "0x18f54cc21b7a2fdd011bea06bba7801b280e3151" - assert predictions[0].truevalue is False - assert predictions[0].predvalue is True - assert mock_query_subgraph.call_count == 1 - - -@enforce_types -@patch("pdr_backend.subgraph.subgraph_predictions.query_subgraph") -def test_fetch_filtered_predictions_exception(mock_query_subgraph): - """ - @description - Verifies that fetch_filtered_predictions() can handle exceptions from subgraph - and return the predictions that were fetched before the exception. - """ - num_successful_fetches = 1 - - # we're going to simulate an exception from subgraph on the second call - # pylint: disable=unused-argument - def simulate_exception(*args, **kwargs): - if simulate_exception.call_count < num_successful_fetches: - simulate_exception.call_count += 1 - return MOCK_PREDICTIONS_RESPONSE_1000 - raise Exception(f"Simulated exception on call #{num_successful_fetches+1}") - - simulate_exception.call_count = 0 - - # Patch query_subgraph to use our simulate_exception function - mock_query_subgraph.side_effect = simulate_exception - - predictions = fetch_filtered_predictions( - start_ts=UnixTimeS(1622547000), - end_ts=UnixTimeS(1622548800), - first=1000, - skip=0, - addresses=["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - network="mainnet", - ) - - assert len(predictions) == num_successful_fetches * 1000 - assert mock_query_subgraph.call_count == num_successful_fetches - - -@enforce_types -def test_fetch_filtered_predictions_no_data(): - # network not supported - with pytest.raises(Exception): - fetch_filtered_predictions( - start_ts=UnixTimeS(1622547000), - end_ts=UnixTimeS(1622548800), - first=1000, - skip=0, - addresses=["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - network="xyz", - ) - - with patch( - "pdr_backend.subgraph.subgraph_predictions.query_subgraph" - ) as mock_query_subgraph: - mock_query_subgraph.return_value = {"data": {}} - predictions = fetch_filtered_predictions( - start_ts=UnixTimeS(1622547000), - end_ts=UnixTimeS(1622548800), - first=1000, - skip=0, - addresses=["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - network="mainnet", - ) - assert len(predictions) == 0 - - with patch( - "pdr_backend.subgraph.subgraph_predictions.query_subgraph" - ) as mock_query_subgraph: - mock_query_subgraph.return_value = {"data": {"predictPredictions": []}} - predictions = fetch_filtered_predictions( - start_ts=UnixTimeS(1622547000), - end_ts=UnixTimeS(1622548800), - first=1000, - skip=0, - addresses=["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - network="mainnet", - ) - assert len(predictions) == 0 - - -@enforce_types -@patch( - "pdr_backend.subgraph.subgraph_predictions.query_subgraph", - return_value=MOCK_CONTRACTS_RESPONSE, -) -def test_get_all_contract_ids_by_owner( - mock_query_subgraph, -): # pylint: disable=unused-argument - contract_ids = get_all_contract_ids_by_owner( - owner_address="0xOwner", network="mainnet" - ) - - assert len(contract_ids) == 2 - assert "token1" in contract_ids - assert "token2" in contract_ids - mock_query_subgraph.assert_called_once() - - with patch( - "pdr_backend.subgraph.subgraph_predictions.query_subgraph", - return_value={"data": {}}, - ): - with pytest.raises(Exception): - get_all_contract_ids_by_owner(owner_address="0xOwner", network="mainnet") - - # network not supported - with pytest.raises(Exception): - get_all_contract_ids_by_owner(owner_address="0xOwner", network="xyz") - - -@enforce_types -@patch( - "pdr_backend.subgraph.subgraph_predictions.query_subgraph", - return_value=MOCK_CONTRACT_DETAILS_RESPONSE, -) -def test_fetch_contract_id_and_spe( - mock_query_subgraph, -): # pylint: disable=unused-argument - contracts_list = fetch_contract_id_and_spe( - contract_addresses=["contract1", "contract2"], network="mainnet" - ) - - assert len(contracts_list) == 2 - - c0, c1 = contracts_list # pylint: disable=unbalanced-tuple-unpacking - assert c0["ID"] == "contract1" - assert c0["seconds_per_epoch"] == 300 - assert c0["name"] == "token1" - assert c1["ID"] == "contract2" - assert c1["seconds_per_epoch"] == 600 - assert c1["name"] == "token2" - - mock_query_subgraph.assert_called_once() - - with patch( - "pdr_backend.subgraph.subgraph_predictions.query_subgraph", - return_value={"data": {}}, - ): - with pytest.raises(Exception): - fetch_contract_id_and_spe( - contract_addresses=["contract1", "contract2"], network="mainnet" - ) - - # network not supported - with pytest.raises(Exception): - fetch_contract_id_and_spe( - contract_addresses=["contract1", "contract2"], network="xyz" - ) diff --git a/pdr_backend/subgraph/test/test_subgraph_slot.py b/pdr_backend/subgraph/test/test_subgraph_slot.py deleted file mode 100644 index 9e9425ce6..000000000 --- a/pdr_backend/subgraph/test/test_subgraph_slot.py +++ /dev/null @@ -1,109 +0,0 @@ -from typing import Dict -from unittest.mock import patch - -from enforce_typing import enforce_types - -from pdr_backend.subgraph.subgraph_slot import ( - fetch_slots, - get_predict_slots_query, - get_slots, -) -from pdr_backend.lake.slot import Slot -from pdr_backend.util.time_types import UnixTimeS - - -@enforce_types -def test_get_predict_slots_query(): - # Test the get_predict_slots_query function with expected inputs and outputs - query = get_predict_slots_query( - asset_ids=["0xAsset"], - initial_slot=UnixTimeS(1000), - last_slot=UnixTimeS(2000), - first=10, - skip=0, - ) - assert "predictSlots" in query - assert "0xAsset" in query - assert "1000" in query - assert "2000" in query - - -# Sample data for tests -SAMPLE_PREDICT_QUERY_RESULT_ITEM = { - "id": "0xAsset-12345", - "slot": 12345, - "trueValues": [{"ID": "1", "trueValue": True}], - "roundSumStakesUp": 150.0, - "roundSumStakes": 100.0, -} - - -MOCK_QUERY_RESPONSE = {"data": {"predictSlots": [SAMPLE_PREDICT_QUERY_RESULT_ITEM]}} - -MOCK_QUERY_RESPONSE_FIRST_CALL = { - "data": { - "predictSlots": [SAMPLE_PREDICT_QUERY_RESULT_ITEM] - * 1000 # Simulate a full page of results - } -} - -MOCK_QUERY_RESPONSE_SECOND_CALL: Dict[str, Dict[str, list]] = { - "data": {"predictSlots": []} # Simulate no further results, stopping the recursion -} - - -@enforce_types -@patch("pdr_backend.subgraph.subgraph_slot.query_subgraph") -def test_get_slots(mock_query_subgraph): - # Configure the mock to return a full page of results on the first call, - # and no results on the second call - mock_query_subgraph.side_effect = [ - MOCK_QUERY_RESPONSE_FIRST_CALL, - MOCK_QUERY_RESPONSE_SECOND_CALL, - ] - - result_slots = get_slots( - end_ts_param=UnixTimeS(2000), - start_ts_param=UnixTimeS(1000), - addresses=["0xAsset"], - first=1000, - skip=0, - slots=[], - network="mainnet", - ) - - print("test_get_slots", result_slots) - - # Verify that the mock was called twice (once for the initial call, once for the recursive call) - assert mock_query_subgraph.call_count == 1 - # Verify that the result contains the expected number of slots - assert len(result_slots) == 1000 - # Verify that the slots contain instances of Slot - assert isinstance(result_slots[0], Slot) - # Verify the first slot's data matches the sample - assert result_slots[0].ID == "0xAsset-12345" - - -@enforce_types -@patch( - "pdr_backend.subgraph.subgraph_slot.query_subgraph", - return_value=MOCK_QUERY_RESPONSE, -) -def test_fetch_slots_for_all_contracts(mock_query_subgraph): - # Test logic for fetching slots for all contracts - result = fetch_slots( - start_ts_param=UnixTimeS(1000), - end_ts_param=UnixTimeS(2000), - contracts=["0xAsset"], - first=1000, - skip=0, - network="mainnet", - ) - - print("test_fetch_slots_for_all_contracts", result) - # Verify that the result is structured correctly - print(result[0]) - assert len(result) == 1 - assert result[0].ID == "0xAsset-12345" - # Verify that the mock was called - mock_query_subgraph.assert_called() diff --git a/pdr_backend/subgraph/test/test_subgraph_subscriptions.py b/pdr_backend/subgraph/test/test_subgraph_subscriptions.py deleted file mode 100644 index fb2b29cc8..000000000 --- a/pdr_backend/subgraph/test/test_subgraph_subscriptions.py +++ /dev/null @@ -1,142 +0,0 @@ -from typing import Dict -from unittest.mock import patch - -import pytest -from enforce_typing import enforce_types - -from pdr_backend.subgraph.subgraph_subscriptions import ( - Subscription, - fetch_filtered_subscriptions, -) -from pdr_backend.util.time_types import UnixTimeS - -SAMPLE_PREDICTION = Subscription( - # pylint: disable=line-too-long - ID="0x18f54cc21b7a2fdd011bea06bba7801b280e3151-0x00d1e4950e0de743fe88956f02f44b16d22a1827f8c29ff561b69716dbcc2677-14", - pair="ADA-USDT", - timeframe="5m", - source="binance", - timestamp=UnixTimeS(1701129777), - tx_id="0x00d1e4950e0de743fe88956f02f44b16d22a1827f8c29ff561b69716dbcc2677", - last_price_value=float("2.4979184013322233") * 1.201, - user="0x2433e002ed10b5d6a3d8d1e0c5d2083be9e37f1d", -) - -# pylint: disable=line-too-long -MOCK_SUBSCRIPTIONS_RESPONSE_FIRST_CALL = { - "data": { - "predictSubscriptions": [ - { - "id": "0x18f54cc21b7a2fdd011bea06bba7801b280e3151-0x00d1e4950e0de743fe88956f02f44b16d22a1827f8c29ff561b69716dbcc2677-14", - "predictContract": { - "id": "0x18f54cc21b7a2fdd011bea06bba7801b280e3151", - "token": { - "id": "0x18f54cc21b7a2fdd011bea06bba7801b280e3151", - "name": "ADA-USDT", - "nft": { - "nftData": [ - { - "key": "0x238ad53218834f943da60c8bafd36c36692dcb35e6d76bdd93202f5c04c0baff", - "value": "0x55534454", - }, - { - "key": "0x2cef5778d97683b4f64607f72e862fc0c92376e44cc61195ef72a634c0b1793e", - "value": "0x4144412f55534454", - }, - { - "key": "0x49435d2ff85f9f3594e40e887943d562765d026d50b7383e76891f8190bff4c9", - "value": "0x356d", - }, - { - "key": "0xf1f3eb40f5bc1ad1344716ced8b8a0431d840b5783aea1fd01786bc26f35ac0f", - "value": "0x414441", - }, - { - "key": "0xf7e3126f87228afb82c9b18537eed25aaeb8171a78814781c26ed2cfeff27e69", - "value": "0x62696e616e6365", - }, - ] - }, - "lastPriceValue": "2.4979184013322233", - }, - "secondsPerSubscription": "86400", - "secondsPerEpoch": "300", - }, - "user": {"id": "0x2433e002ed10b5d6a3d8d1e0c5d2083be9e37f1d"}, - "expireTime": "1701216000", - "eventIndex": 14, - "block": 1342747, - "timestamp": 1701129777, - "txId": "0x00d1e4950e0de743fe88956f02f44b16d22a1827f8c29ff561b69716dbcc2677", - } - ] - } -} - -MOCK_SUBSCRIPTIONS_RESPONSE_SECOND_CALL: Dict[str, dict] = {} - - -@enforce_types -@patch("pdr_backend.subgraph.subgraph_subscriptions.query_subgraph") -def test_fetch_filtered_subscriptions(mock_query_subgraph): - mock_query_subgraph.side_effect = [ - MOCK_SUBSCRIPTIONS_RESPONSE_FIRST_CALL, - MOCK_SUBSCRIPTIONS_RESPONSE_SECOND_CALL, - ] - subscriptions = fetch_filtered_subscriptions( - start_ts=UnixTimeS(1701129700), - end_ts=UnixTimeS(1701129800), - first=1000, - skip=0, - contracts=["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - network="mainnet", - ) - - assert len(subscriptions) == 1 - assert isinstance(subscriptions[0], Subscription) - assert subscriptions[0].user == "0x2433e002ed10b5d6a3d8d1e0c5d2083be9e37f1d" - assert subscriptions[0].pair == "ADA/USDT" - assert mock_query_subgraph.call_count == 1 - - -@enforce_types -def test_fetch_filtered_subscriptions_no_data(): - # network not supported - with pytest.raises(Exception): - fetch_filtered_subscriptions( - start_ts=UnixTimeS(1701129700), - end_ts=UnixTimeS(1701129800), - first=1000, - skip=0, - contracts=["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - network="xyz", - ) - - with patch( - "pdr_backend.subgraph.subgraph_subscriptions.query_subgraph" - ) as mock_query_subgraph: - mock_query_subgraph.return_value = {"data": {}} - subscriptions = fetch_filtered_subscriptions( - start_ts=UnixTimeS(1701129700), - end_ts=UnixTimeS(1701129800), - first=1000, - skip=0, - contracts=["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - network="mainnet", - ) - assert len(subscriptions) == 0 - - with patch( - "pdr_backend.subgraph.subgraph_subscriptions.query_subgraph" - ) as mock_query_subgraph: - mock_query_subgraph.return_value = {"data": {"predictPredictions": []}} - subscriptions = fetch_filtered_subscriptions( - start_ts=UnixTimeS(1701129700), - end_ts=UnixTimeS(1701129800), - first=1000, - skip=0, - contracts=["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - network="mainnet", - ) - - assert len(subscriptions) == 0 diff --git a/pdr_backend/subgraph/test/test_subgraph_sync.py b/pdr_backend/subgraph/test/test_subgraph_sync.py deleted file mode 100644 index df1efbf47..000000000 --- a/pdr_backend/subgraph/test/test_subgraph_sync.py +++ /dev/null @@ -1,47 +0,0 @@ -from unittest.mock import Mock, patch - -from enforce_typing import enforce_types - -from pdr_backend.subgraph.subgraph_sync import ( - block_number_is_synced, - wait_until_subgraph_syncs, -) -from pdr_backend.util.web3_config import Web3Config - - -@enforce_types -def test_block_number_is_synced(): - def mock_response(url: str, query: str): # pylint:disable=unused-argument - if "number:50" in query: - return { - "errors": [ - { - # pylint: disable=line-too-long - "message": "Failed to decode `block.number` value: `subgraph QmaGAi4jQw5L8J2xjnofAJb1PX5LLqRvGjsWbVehBELAUx only has data starting at block number 499 and data for block number 500 is therefore not available`" - } - ] - } - - return {"data": {"predictContracts": [{"id": "sample_id"}]}} - - with patch( - "pdr_backend.subgraph.subgraph_sync.query_subgraph", - side_effect=mock_response, - ): - assert block_number_is_synced("foo", 499) is True - assert block_number_is_synced("foo", 500) is False - assert block_number_is_synced("foo", 501) is False - - -@enforce_types -def test_wait_until_subgraph_syncs(): - mock_web3_config = Mock(spec=Web3Config) - mock_web3_config.w3 = Mock() - mock_web3_config.w3.eth = Mock() - mock_web3_config.w3.eth.block_number = 500 - - with patch( - "pdr_backend.subgraph.subgraph_sync.block_number_is_synced", - side_effect=[False, True], - ): - wait_until_subgraph_syncs(mock_web3_config, "foo") diff --git a/pdr_backend/subgraph/test/test_subgraph_trueval.py b/pdr_backend/subgraph/test/test_subgraph_trueval.py deleted file mode 100644 index 72e76f0b6..000000000 --- a/pdr_backend/subgraph/test/test_subgraph_trueval.py +++ /dev/null @@ -1,67 +0,0 @@ -from unittest.mock import patch - -from enforce_typing import enforce_types - -from pdr_backend.subgraph.subgraph_trueval import ( - Trueval, - get_truevals_query, - fetch_truevals, -) -from pdr_backend.util.time_types import UnixTimeS - -# pylint: disable=line-too-long -MOCK_TRUEVAL_QUERY_RESPONSE = { - "data": { - "predictTrueVals": [ - { - "id": "0x18f54cc21b7a2fdd011bea06bba7801b280e3151-1698527100", - "timestamp": 1698527000, - "trueValue": True, - "slot": { - "slot": 1698527100, - "predictContract": { - "token": {"name": "ADA/USDT"}, - }, - }, - } - ] - } -} - - -def test_get_trueval_query(): - trueval_query = get_truevals_query( - ["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - UnixTimeS(1622547000), - UnixTimeS(1622548800), - 1000, - 0, - ) - - assert "1622547000" in trueval_query - assert "1622548800" in trueval_query - assert "0x18f54cc21b7a2fdd011bea06bba7801b280e3151" in trueval_query - - -@enforce_types -@patch("pdr_backend.subgraph.subgraph_trueval.query_subgraph") -def test_fetch_filtered_truevals(mock_query_subgraph): - mock_query_subgraph.return_value = MOCK_TRUEVAL_QUERY_RESPONSE - - truevals = fetch_truevals( - start_ts=UnixTimeS(1698526000), - end_ts=UnixTimeS(1698528000), - first=1000, - skip=0, - addresses=["0x18f54cc21b7a2fdd011bea06bba7801b280e3151"], - network="mainnet", - ) - print(truevals) - assert len(truevals) == 1 - assert isinstance(truevals[0], Trueval) - assert truevals[0].ID == "0x18f54cc21b7a2fdd011bea06bba7801b280e3151-1698527100" - assert truevals[0].token == "ADA/USDT" - assert truevals[0].timestamp == 1698527000 - assert truevals[0].slot == 1698527100 - assert truevals[0].truevalue is True - assert mock_query_subgraph.call_count == 1 diff --git a/pdr_backend/subgraph/test/test_trueval.py b/pdr_backend/subgraph/test/test_trueval.py deleted file mode 100644 index bfe0b243f..000000000 --- a/pdr_backend/subgraph/test/test_trueval.py +++ /dev/null @@ -1,14 +0,0 @@ -from enforce_typing import enforce_types - -from pdr_backend.lake.trueval import Trueval, mock_truevals - - -@enforce_types -def test_truevals(): - truevals = mock_truevals() - - assert len(truevals) == 6 - assert isinstance(truevals[0], Trueval) - assert isinstance(truevals[1], Trueval) - assert truevals[0].ID == "0x8165caab33131a4ddbf7dc79f0a8a4920b0b2553-1696838400" - assert truevals[1].ID == "0x8165caab33131a4ddbf7dc79f0a8a4920b0b2553-1696838100" diff --git a/pdr_backend/trueval/test/conftest.py b/pdr_backend/trueval/test/conftest.py deleted file mode 100644 index 99a483970..000000000 --- a/pdr_backend/trueval/test/conftest.py +++ /dev/null @@ -1,36 +0,0 @@ -from unittest.mock import Mock, patch - -from pdr_backend.conftest_ganache import * # pylint: disable=wildcard-import -from pdr_backend.contract.slot import Slot -from pdr_backend.ppss.ppss import PPSS, fast_test_yaml_str -from pdr_backend.subgraph.subgraph_feed import mock_feed - - -@pytest.fixture() -def slot(): - feed = mock_feed("5m", "kraken", "ETH/USDT") - return Slot( - feed=feed, - slot_number=1692943200, - ) - - -@pytest.fixture() -def mock_ppss(tmpdir): - return PPSS(yaml_str=fast_test_yaml_str(tmpdir), network="development") - - -@pytest.fixture() -def feed_contract_mock(): - def mock_contract(*args, **kwarg): # pylint: disable=unused-argument - m = Mock() - m.get_secondsPerEpoch.return_value = 60 - m.submit_trueval.return_value = {"tx": "0x123"} - m.contract_address = "0x1" - return m - - with patch( - "pdr_backend.trueval.trueval_agent.FeedContract", - return_value=mock_contract(), - ) as mock_feed_contract_mock: - yield mock_feed_contract_mock diff --git a/pdr_backend/trueval/test/test_get_trueval.py b/pdr_backend/trueval/test/test_get_trueval.py deleted file mode 100644 index 1e18972f5..000000000 --- a/pdr_backend/trueval/test/test_get_trueval.py +++ /dev/null @@ -1,42 +0,0 @@ -import pytest -from enforce_typing import enforce_types - -from pdr_backend.subgraph.subgraph_feed import mock_feed -from pdr_backend.trueval.get_trueval import get_trueval -from pdr_backend.util.time_types import UnixTimeS - -_PATH = "pdr_backend.trueval.get_trueval" - - -@enforce_types -def test_get_trueval_success(monkeypatch): - def mock_fetch_ohlcv(*args, **kwargs): # pylint: disable=unused-argument - since = kwargs.get("since") - if since == 0: - return [[0, 0, 0, 0, 100], [300000, 0, 0, 0, 200]] - raise ValueError(f"Invalid timestamp: since={since}") - - monkeypatch.setattr(f"{_PATH}.fetch_ohlcv", mock_fetch_ohlcv) - - feed = mock_feed("5m", "kraken", "ETH/USDT") - - init_ts = UnixTimeS(feed.seconds_per_epoch) - end_ts = UnixTimeS(init_ts + feed.seconds_per_epoch) - result = get_trueval(feed, init_ts, end_ts) - assert result == (True, False) - - -@enforce_types -def test_get_trueval_fail(monkeypatch): - def mock_fetch_ohlcv_fail(*args, **kwargs): # pylint: disable=unused-argument - return [[0, 0, 0, 0, 0], [300000, 0, 0, 0, 200]] - - monkeypatch.setattr(f"{_PATH}.fetch_ohlcv", mock_fetch_ohlcv_fail) - - feed = mock_feed("5m", "kraken", "eth-usdt") - - init_ts = UnixTimeS(feed.seconds_per_epoch) - end_ts = UnixTimeS(init_ts + feed.seconds_per_epoch) - with pytest.raises(Exception): - result = get_trueval(feed, init_ts, end_ts) - assert result == (False, True) # 2nd True because failed diff --git a/pdr_backend/trueval/test/test_trueval_agent.py b/pdr_backend/trueval/test/test_trueval_agent.py deleted file mode 100644 index 755e2e550..000000000 --- a/pdr_backend/trueval/test/test_trueval_agent.py +++ /dev/null @@ -1,176 +0,0 @@ -from copy import deepcopy -from unittest.mock import MagicMock, Mock, patch - -import pytest -from enforce_typing import enforce_types - -from pdr_backend.trueval.trueval_agent import TruevalAgent, TruevalSlot -from pdr_backend.util.constants import ZERO_ADDRESS - -PATH = "pdr_backend.trueval.trueval_agent" - - -@enforce_types -def test_trueval_agent_constructor(mock_ppss): - agent_ = TruevalAgent(mock_ppss, ZERO_ADDRESS) - assert agent_.ppss == mock_ppss - assert agent_.predictoor_batcher.contract_address == ZERO_ADDRESS - - -@enforce_types -def test_get_contract_info_caching(agent, feed_contract_mock): - agent.get_contract_info("0x1") - agent.get_contract_info("0x1") - assert feed_contract_mock.call_count == 1 - feed_contract_mock.assert_called_once_with(agent.ppss.web3_pp, "0x1") - - -@enforce_types -def test_get_trueval_slot( - agent, slot, feed_contract_mock -): # pylint: disable=unused-argument - for trueval, cancel in [ - (True, True), # up - (False, True), # down - (True, False), # cancel - ]: - with patch(f"{PATH}.get_trueval", Mock(return_value=(trueval, cancel))): - result = agent.get_trueval_slot(slot) - assert result == (trueval, cancel) - - -@enforce_types -def test_get_trueval_slot_too_many_requests_retry( - agent, slot, feed_contract_mock -): # pylint: disable=unused-argument - mock_get_trueval = MagicMock( - side_effect=[Exception("Too many requests"), (True, True)] - ) - with patch(f"{PATH}.get_trueval", mock_get_trueval), patch( - "time.sleep", return_value=None - ) as mock_sleep: - result = agent.get_trueval_slot(slot) - mock_sleep.assert_called_once_with(60) - assert result == (True, True) - assert mock_get_trueval.call_count == 2 - - -@enforce_types -def test_trueval_agent_run(agent): - mock_take_step = Mock() - with patch.object(agent, "take_step", mock_take_step): - agent.run(testing=True) - - mock_take_step.assert_called_once() - - -@enforce_types -def test_trueval_agent_get_init_and_ts(agent): - ts = 2000 - seconds_per_epoch = 300 - - (initial_ts, end_ts) = agent.get_init_and_ts(ts, seconds_per_epoch) - assert initial_ts == ts - 300 - assert end_ts == ts - - -@enforce_types -def test_process_trueval_slot( - agent, slot, feed_contract_mock -): # pylint: disable=unused-argument - for trueval, cancel in [ - (True, True), # up - (False, True), # down - (True, False), # cancel - ]: - with patch(f"{PATH}.get_trueval", Mock(return_value=(trueval, cancel))): - slot = TruevalSlot(slot_number=slot.slot_number, feed=slot.feed) - agent.process_trueval_slot(slot) - - assert slot.trueval == trueval - assert slot.cancel == cancel - - -@enforce_types -def test_batch_submit_truevals(agent, slot): - times = 3 - slot.feed.address = "0x0000000000000000000000000000000000c0ffee" - trueval_slots = [ - TruevalSlot(feed=slot.feed, slot_number=i) for i in range(0, times) - ] - for i in trueval_slots: - i.set_trueval(True) - i.set_cancel(False) - - slot2 = deepcopy(slot) - slot2.feed.address = "0x0000000000000000000000000000000000badbad" - trueval_slots_2 = [ - TruevalSlot(feed=slot2.feed, slot_number=i) for i in range(0, times) - ] - for i in trueval_slots_2: - i.set_trueval(True) - i.set_cancel(False) - - trueval_slots.extend(trueval_slots_2) - - contract_addrs = [ - "0x0000000000000000000000000000000000C0FFEE", - "0x0000000000000000000000000000000000baDbad", - ] # checksum - epoch_starts = [list(range(0, times))] * 2 - truevals = [[True] * times, [True] * times] - cancels = [[False] * times, [False] * times] - - with patch.object( - agent.predictoor_batcher, - "submit_truevals_contracts", - return_value={"transactionHash": bytes.fromhex("badc0ffeee")}, - ) as mock: - tx = agent.batch_submit_truevals(trueval_slots) - assert tx == "badc0ffeee" - mock.assert_called_with(contract_addrs, epoch_starts, truevals, cancels, True) - - -@enforce_types -def test_trueval_agent_take_step(agent, slot): - with patch(f"{PATH}.wait_until_subgraph_syncs"), patch.object( - agent, "get_batch", return_value=[slot] - ) as mock_get_batch, patch.object( - agent, "process_trueval_slot" - ) as mock_process_trueval_slot, patch( - "time.sleep" - ), patch.object( - agent, "batch_submit_truevals" - ) as mock_batch_submit_truevals: - agent.take_step() - - mock_get_batch.assert_called_once() - call_args = mock_process_trueval_slot.call_args[0][0] - assert call_args.slot_number == slot.slot_number - assert call_args.feed == slot.feed - - call_args = mock_batch_submit_truevals.call_args[0][0] - assert call_args[0].slot_number == slot.slot_number - assert call_args[0].feed == slot.feed - - -@enforce_types -def test_trueval_agent_get_batch(agent, slot): - with patch.object(agent.ppss.web3_pp, "get_pending_slots", return_value=[slot]): - batch = agent.get_batch() - - assert batch == [slot] - - with patch.object(agent.ppss.web3_pp, "get_pending_slots", return_value=[]): - batch = agent.get_batch() - - assert batch == [] - - -# ---------------------------------------------- -# Fixtures - - -@pytest.fixture(name="agent") -def agent_fixture(mock_ppss): - return TruevalAgent(mock_ppss, ZERO_ADDRESS) diff --git a/pdr_backend/util/test_ganache/__init__.py b/pdr_backend/util/test_ganache/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/pdr_backend/util/test_ganache/conftest.py b/pdr_backend/util/test_ganache/conftest.py deleted file mode 100644 index fc9ed034c..000000000 --- a/pdr_backend/util/test_ganache/conftest.py +++ /dev/null @@ -1 +0,0 @@ -from pdr_backend.conftest_ganache import * # pylint: disable=wildcard-import diff --git a/pdr_backend/util/test_ganache/test_core_accounts.py b/pdr_backend/util/test_ganache/test_core_accounts.py deleted file mode 100644 index f6b9ff4de..000000000 --- a/pdr_backend/util/test_ganache/test_core_accounts.py +++ /dev/null @@ -1,54 +0,0 @@ -import os -from unittest.mock import Mock, call - -from enforce_typing import enforce_types -from eth_account import Account - -from pdr_backend.contract.token import Token -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.util.core_accounts import _fund_accounts, fund_accounts_with_OCEAN -from pdr_backend.util.currency_types import Eth, Wei - - -@enforce_types -def test_fund_accounts_with_OCEAN(monkeypatch): - if os.getenv("NETWORK_OVERRIDE"): - monkeypatch.delenv("NETWORK_OVERRIDE") - - web3_pp = Mock(spec=Web3PP) - web3_pp.network = "development" - web3_pp.OCEAN_Token = Mock(spec=Token) - web3_pp.web3_config = Mock() - web3_pp.web3_config.owner = "0x123" - - path = "pdr_backend.util.core_accounts" - mock_f = Mock() - monkeypatch.setattr(f"{path}._fund_accounts", mock_f) - - fund_accounts_with_OCEAN(web3_pp) - mock_f.assert_called() - - -@enforce_types -def test_fund_accounts(monkeypatch): - pk = os.getenv("PRIVATE_KEY") - monkeypatch.setenv("PREDICTOOR_PRIVATE_KEY", pk) - monkeypatch.setenv("PREDICTOOR2_PRIVATE_KEY", pk) - - mock_token = Mock(spec=Token) - mock_account = Mock(spec=str) - - accounts_to_fund = [ - ("PREDICTOOR_PRIVATE_KEY", Eth(2000)), - ("PREDICTOOR2_PRIVATE_KEY", Eth(3000)), - ] - - _fund_accounts(accounts_to_fund, mock_account, mock_token) - - a = Account.from_key(private_key=pk) # pylint: disable=no-value-for-parameter - mock_token.transfer.assert_has_calls( - [ - call(a.address, Wei(2e21), mock_account), - call(a.address, Wei(3e21), mock_account), - ] - ) diff --git a/pdr_backend/util/test_ganache/test_networkutil.py b/pdr_backend/util/test_ganache/test_networkutil.py deleted file mode 100644 index 4a3be329c..000000000 --- a/pdr_backend/util/test_ganache/test_networkutil.py +++ /dev/null @@ -1,37 +0,0 @@ -import pytest -from enforce_typing import enforce_types - -from pdr_backend.util.networkutil import ( - get_sapphire_postfix, - get_subgraph_url, -) - - -@enforce_types -def test_get_sapphire_postfix(): - assert get_sapphire_postfix("sapphire-testnet"), "testnet" - assert get_sapphire_postfix("sapphire-mainnet"), "mainnet" - - unwanteds = [ - "oasis_saphire_testnet", - "saphire_mainnet", - "barge-pytest", - "barge-predictoor-bot", - "development", - "foo", - "", - ] - for unwanted in unwanteds: - with pytest.raises(ValueError): - assert get_sapphire_postfix(unwanted) - - -def test_get_subgraph(): - expected = ( - "https://v4.subgraph.sapphire-testnet.oceanprotocol.com/" - "subgraphs/name/oceanprotocol/ocean-subgraph" - ) - assert get_subgraph_url("testnet") == expected - - with pytest.raises(ValueError): - get_subgraph_url("sapphire-testnet") diff --git a/pdr_backend/util/test_ganache/test_web3_accounts.py b/pdr_backend/util/test_ganache/test_web3_accounts.py deleted file mode 100644 index 0df56cf07..000000000 --- a/pdr_backend/util/test_ganache/test_web3_accounts.py +++ /dev/null @@ -1,93 +0,0 @@ -from unittest.mock import patch - -from enforce_typing import enforce_types - -from pdr_backend.ppss.web3_pp import mock_web3_pp -from pdr_backend.util.web3_accounts import ( - create_accounts, - fund_accounts, - print_balances, -) -from pdr_backend.util.currency_types import Eth - - -@enforce_types -@patch("eth_account.Account.create") -def test_create_accounts(mock_create): - create_accounts(2) - - # assert mock_create was called twice - assert mock_create.call_count == 2 - - -@enforce_types -@patch("pdr_backend.ppss.web3_pp.Token") -@patch("pdr_backend.ppss.web3_pp.NativeToken") -@patch("pdr_backend.ppss.web3_pp.Web3PP.get_address") -def test_print_balances(mock_get_address, mock_native_token, mock_token): - web3_pp = mock_web3_pp("development") - - # Create Mock instances for NativeToken and Token - ROSE = mock_native_token.return_value - OCEAN = mock_token.return_value - - # Set the return values for balanceOf methods - ROSE.balanceOf.return_value = Eth(2).to_wei() - OCEAN.balanceOf.return_value = Eth(1).to_wei() - - # Set the return value for get_address - mock_get_address.return_value = "0xOCEAN" - - print_balances("0x123", web3_pp) - - # Assert methods are returning right values - assert mock_get_address(web3_pp, "Ocean") == "0xOCEAN" - assert ROSE.balanceOf(mock_get_address) == Eth(2).to_wei() - assert OCEAN.balanceOf(mock_get_address) == Eth(1).to_wei() - - # Assert methods were called the right amount of times - assert ROSE.balanceOf.call_count == 2 - assert OCEAN.balanceOf.call_count == 2 - assert mock_get_address.call_count == 2 - - -@enforce_types -@patch("eth_account.Account.from_key") -@patch("pdr_backend.ppss.web3_pp.Token") -@patch("pdr_backend.ppss.web3_pp.NativeToken") -@patch("pdr_backend.ppss.web3_pp.Web3PP.get_address") -def test_fund_accounts( - mock_get_address, mock_native_token, mock_token, mock_account_from_key -): - web3_pp = mock_web3_pp("sapphire-mainnet") - - # Create Mock instances for NativeToken and Token - native_token_instance = mock_native_token.return_value - token_instance = mock_token.return_value - - # Set the return value for get_address - mock_get_address.return_value = "0xOCEAN" - - # Create Mock instances for Account - account_instance = mock_account_from_key.return_value - - # Set the return value for Account.from_key - mock_account_from_key.return_value = account_instance - - # Set the return value for Account.from_key - account_instance.address = "0x123" - - # Set the return value for token.transfer - token_instance.transfer.return_value = True - - # Test both Native & Token transfers - fund_accounts(Eth(1.0), ["0x123", "0x124"], web3_pp, False) - fund_accounts(Eth(3.5), ["0x125", "0x126", "0x127"], web3_pp, True) - - # Assert internals were called twice, but get_address is only called once - assert mock_account_from_key.call_count == 2 - assert mock_get_address.call_count == 1 - - # Assert 3 native token vs. 2 token transfers - assert token_instance.transfer.call_count == 2 - assert native_token_instance.transfer.call_count == 3 diff --git a/pdr_backend/util/test_ganache/test_web3_config.py b/pdr_backend/util/test_ganache/test_web3_config.py deleted file mode 100644 index 5c4aceb79..000000000 --- a/pdr_backend/util/test_ganache/test_web3_config.py +++ /dev/null @@ -1,87 +0,0 @@ -import os - -import pytest -from enforce_typing import enforce_types - -from pdr_backend.util.constants import MAX_UINT -from pdr_backend.util.web3_config import Web3Config - - -@enforce_types -def test_Web3Config_bad_rpc(): - private_key = os.getenv("PRIVATE_KEY") - with pytest.raises(TypeError): - Web3Config(rpc_url=None, private_key=private_key) - - -@enforce_types -def test_Web3Config_bad_key(rpc_url): - with pytest.raises(ValueError): - Web3Config(rpc_url=rpc_url, private_key="foo") - - -@enforce_types -def test_Web3Config_happy_noPrivateKey(rpc_url): - c = Web3Config(rpc_url=rpc_url, private_key=None) - - assert c.w3 is not None - assert not hasattr(c, "account") - assert not hasattr(c, "owner") - assert not hasattr(c, "private_key") - - -@enforce_types -def test_Web3Config_happy_havePrivateKey_noKeywords(rpc_url): - private_key = os.getenv("PRIVATE_KEY") - c = Web3Config(rpc_url, private_key) - assert c.account - assert c.owner == c.account.address - assert c.private_key == private_key - - -@enforce_types -def test_Web3Config_happy_havePrivateKey_withKeywords(rpc_url): - private_key = os.getenv("PRIVATE_KEY") - c = Web3Config(rpc_url=rpc_url, private_key=private_key) - assert c.account - assert c.owner == c.account.address - assert c.private_key == private_key - - -@enforce_types -def test_Web3Config_get_block_latest(rpc_url): - private_key = os.getenv("PRIVATE_KEY") - c = Web3Config(rpc_url=rpc_url, private_key=private_key) - block = c.get_block("latest") - assert block - assert block["timestamp"] > 0 - - -@enforce_types -def test_Web3Config_get_block_0(rpc_url): - private_key = os.getenv("PRIVATE_KEY") - c = Web3Config(rpc_url=rpc_url, private_key=private_key) - block = c.get_block(0) - assert block - assert block["timestamp"] > 0 - - -@enforce_types -def test_Web3Config_get_auth_signature(rpc_url): - private_key = os.getenv("PRIVATE_KEY") - c = Web3Config(rpc_url=rpc_url, private_key=private_key) - auth = c.get_auth_signature() - - # just a super basic test - assert sorted(auth.keys()) == sorted(["userAddress", "v", "r", "s", "validUntil"]) - - -@enforce_types -def test_get_max_gas(rpc_url): - private_key = os.getenv("PRIVATE_KEY") - web3_config = Web3Config(rpc_url=rpc_url, private_key=private_key) - max_gas = web3_config.get_max_gas() - assert 0 < max_gas < MAX_UINT - - target_max_gas = int(web3_config.get_block("latest").gasLimit * 0.99) - assert max_gas == target_max_gas diff --git a/system_tests/__init__.py b/system_tests/__init__.py deleted file mode 100644 index e69de29bb..000000000 diff --git a/system_tests/conftest.py b/system_tests/conftest.py deleted file mode 100644 index 2223a6b6c..000000000 --- a/system_tests/conftest.py +++ /dev/null @@ -1,47 +0,0 @@ -import os -import sys - -from pdr_backend.subgraph.subgraph_feed import SubgraphFeed - -# Add the root directory to the path -sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))) -from pdr_backend.conftest_ganache import * # pylint: disable=wildcard-import,wrong-import-position - - -@pytest.fixture(scope="session", autouse=True) -def set_test_env_var(): - previous = os.getenv("TEST") - os.environ["TEST"] = "true" - yield - if previous is None: - del os.environ["TEST"] - else: - os.environ["TEST"] = previous - - -@pytest.fixture(scope="session") -def mock_feeds(): - feeds = { - "0x1": SubgraphFeed( - "Feed: binance | BTC/USDT | 5m", - "0x1", - "BTC", - 100, - 300, - "0xf", - "BTC/USDT", - "5m", - "binance", - ) - } - return feeds - - -@pytest.fixture(scope="session") -def mock_feed_contract(): - mock_contract = Mock(spec=FeedContract) - mock_contract.payout_multiple.return_value = None - mock_contract.get_agg_predval.return_value = (12, 23) - mock_contract.get_current_epoch.return_value = 100 - mock_contract.web3_pp = Mock() - return mock_contract diff --git a/system_tests/test_check_network_system.py b/system_tests/test_check_network_system.py deleted file mode 100644 index ac51432ee..000000000 --- a/system_tests/test_check_network_system.py +++ /dev/null @@ -1,74 +0,0 @@ -import sys - -from unittest.mock import Mock, patch, MagicMock - -from pdr_backend.cli import cli_module -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.util.constants_opf_addrs import get_opf_addresses -from pdr_backend.util.web3_config import Web3Config -from pdr_backend.util.currency_types import Wei - - -@patch("pdr_backend.analytics.check_network.print_stats") -@patch("pdr_backend.analytics.check_network.check_dfbuyer") -def test_check_network(mock_print_stats, mock_check_dfbuyer, caplog): - mock_web3_pp = MagicMock(spec=Web3PP) - mock_web3_pp.network = "sapphire-mainnet" - mock_web3_pp.subgraph_url = ( - "http://localhost:8000/subgraphs/name/oceanprotocol/ocean-subgraph" - ) - - mock_web3_config = Mock(spec=Web3Config) - mock_web3_config.w3 = Mock() - mock_web3_pp.web3_config = mock_web3_config - mock_web3_pp.web3_config.owner = "0xowner" - - mock_token = MagicMock() - mock_token.balanceOf.return_value = Wei(int(5e18)) - mock_token.transfer.return_value = True - - mock_web3_pp.OCEAN_Token = mock_token - mock_web3_pp.NativeToken = mock_token - mock_web3_pp.get_token_balance.return_value = 100 - mock_web3_pp.w3.eth.block_number = 100 - - mock_query_subgraph = Mock() - mock_query_subgraph.return_value = { - "data": { - "predictContracts": [ - {}, - {}, - {}, - ] - } - } - with patch("pdr_backend.ppss.ppss.Web3PP", return_value=mock_web3_pp), patch( - "sys.exit" - ), patch("pdr_backend.analytics.check_network.query_subgraph", mock_query_subgraph): - # Mock sys.argv - sys.argv = ["pdr", "check_network", "ppss.yaml", "development"] - - cli_module._do_main() - - addresses = get_opf_addresses("sapphire-mainnet") - # Verifying outputs - assert "pdr check_network: Begin" in caplog.text - assert "Arguments:" in caplog.text - assert "PPSS_FILE=ppss.yaml" in caplog.text - assert "NETWORK=development" in caplog.text - assert "Number of Predictoor contracts: 3" in caplog.text - assert "Predictions:" in caplog.text - assert "True Values:" in caplog.text - assert "Checking account balances" in caplog.text - - for key in addresses.values(): - if key.startswith("pred"): - assert ( - f"{key}: OCEAN: 5.00 WARNING LOW OCEAN BALANCE!, " - "Native: 0.00 WARNING LOW NATIVE BALANCE!" - ) in caplog.text - - # Additional assertions - mock_print_stats.assert_called() - mock_check_dfbuyer.assert_called() - mock_token.balanceOf.assert_called() diff --git a/system_tests/test_dfbuyer_agent_system.py b/system_tests/test_dfbuyer_agent_system.py deleted file mode 100644 index 44b7597dc..000000000 --- a/system_tests/test_dfbuyer_agent_system.py +++ /dev/null @@ -1,97 +0,0 @@ -import sys - -from unittest.mock import Mock, patch, MagicMock - -from pdr_backend.cli import cli_module -from pdr_backend.contract.predictoor_batcher import PredictoorBatcher -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.subgraph.subgraph_feed import SubgraphFeed -from pdr_backend.util.constants import SAPPHIRE_MAINNET_CHAINID -from pdr_backend.util.web3_config import Web3Config - - -@patch("pdr_backend.dfbuyer.dfbuyer_agent.wait_until_subgraph_syncs") -@patch("pdr_backend.dfbuyer.dfbuyer_agent.time.sleep") -def test_dfbuyer_agent(mock_wait_until_subgraph_syncs, mock_time_sleep, caplog): - _ = mock_wait_until_subgraph_syncs - mock_web3_pp = MagicMock(spec=Web3PP) - mock_web3_pp.network = "sapphire-mainnet" - mock_web3_pp.subgraph_url = ( - "http://localhost:8000/subgraphs/name/oceanprotocol/ocean-subgraph" - ) - feeds = { - "0x1": SubgraphFeed( - "Feed: binance | BTC/USDT | 5m", - "0x1", - "BTC", - 100, - 300, - "0xf", - "BTC/USDT", - "5m", - "binance", - ) - } - mock_web3_pp.query_feed_contracts.return_value = feeds - - mock_token = MagicMock() - mock_token.balanceOf.return_value = 100 * 1e18 - mock_token.allowance.return_value = 1e128 - - mock_web3_pp.get_address.return_value = "0x1" - mock_web3_pp.OCEAN_Token = mock_token - - mock_web3_config = Mock(spec=Web3Config) - mock_web3_config.get_block.return_value = {"timestamp": 100} - mock_web3_config.owner = "0x00000000000000000000000000000000000c0ffe" - mock_web3_config.w3 = Mock() - mock_web3_config.w3.eth.block_number = 100 - mock_web3_config.w3.eth.chain_id = SAPPHIRE_MAINNET_CHAINID - mock_web3_config.w3.to_checksum_address.return_value = "0x1" - mock_web3_config.get_current_timestamp.return_value = 100 - - mock_web3_pp.web3_config = mock_web3_config - - mock_get_consume_so_far_per_contract = Mock() - mock_get_consume_so_far_per_contract.return_value = {"0x1": 120} - - mock_predictoor_batcher = Mock(spec=PredictoorBatcher) - mock_predictoor_batcher.contract_address = "0xpredictoor_batcher" - mock_predictoor_batcher.consume_multiple.return_value = { - "transactionHash": b"0xbatch_submit_tx", - "status": 1, - } - - with patch("pdr_backend.ppss.ppss.Web3PP", return_value=mock_web3_pp), patch( - "pdr_backend.dfbuyer.dfbuyer_agent.PredictoorBatcher", - return_value=mock_predictoor_batcher, - ), patch( - "pdr_backend.dfbuyer.dfbuyer_agent.get_consume_so_far_per_contract", - mock_get_consume_so_far_per_contract, - ), patch( - "pdr_backend.dfbuyer.dfbuyer_agent.DFBuyerAgent._get_prices", - return_value={"0x1": 100}, - ): - # Mock sys.argv - sys.argv = ["pdr", "dfbuyer", "ppss.yaml", "development"] - - cli_module._do_main() - - # Verifying outputs - assert "pdr dfbuyer: Begin" in caplog.text - assert "Arguments:" in caplog.text - assert "PPSS_FILE=ppss.yaml" in caplog.text - assert "NETWORK=development" in caplog.text - assert "Feed: 5m binance BTC/USDT 0x1" in caplog.text - assert "Checking allowance..." in caplog.text - assert "Taking step for timestamp: 100" in caplog.text - assert "Missing consume amounts: %s" % {"0x1": 5165.714285714285} in caplog.text - assert "Missing consume times: %s" % {"0x1": 52} in caplog.text - assert "Processing 3 batches" in caplog.text - assert "Consuming contracts ['0x1'] for [20] times." in caplog.text - - # Additional assertions - mock_web3_pp.query_feed_contracts.assert_called() - mock_predictoor_batcher.consume_multiple.assert_called() - mock_time_sleep.assert_called() - mock_get_consume_so_far_per_contract.assert_called() diff --git a/system_tests/test_get_predictions_info_system.py b/system_tests/test_get_predictions_info_system.py deleted file mode 100644 index 0698e205e..000000000 --- a/system_tests/test_get_predictions_info_system.py +++ /dev/null @@ -1,96 +0,0 @@ -import sys -from unittest.mock import MagicMock, Mock, patch - -from pdr_backend.cli import cli_module -from pdr_backend.lake.duckdb_data_store import DuckDBDataStore -from pdr_backend.lake.plutil import _object_list_to_df -from pdr_backend.lake.prediction import Prediction -from pdr_backend.lake.table_pdr_predictions import _transform_timestamp_to_ms -from pdr_backend.ppss.ppss import mock_ppss -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.util.time_types import UnixTimeS -from pdr_backend.util.web3_config import Web3Config - - -@patch("pdr_backend.analytics.get_predictions_info.get_feed_summary_stats") -def test_get_predictions_info_system(mock_get_feed_summary_stats, caplog): - _feed = "0x2d8e2267779d27c2b3ed5408408ff15d9f3a3152" - _user = "0xaaaa4cb4ff2584bad80ff5f109034a891c3d88dd" - - mock_predictions = [ - Prediction( - f"{_feed}-31232-{_user}", - _feed, - "BTC", - "5m", - True, - 100.0, - False, - UnixTimeS(1701532572), - "binance", - 10.0, - UnixTimeS(10), - _user, - ) - ] - - st_timestr = "2023-12-03" - fin_timestr = "2024-12-05" - - ppss = mock_ppss( - [{"predict": "binance BTC/USDT c 5m", "train_on": "binance BTC/USDT c 5m"}], - "sapphire-mainnet", - ".", - st_timestr=st_timestr, - fin_timestr=fin_timestr, - ) - - predictions_df = _object_list_to_df(mock_predictions) - predictions_df = _transform_timestamp_to_ms(predictions_df) - - # DROP TABLE IF EXISTS - DuckDBDataStore(ppss.lake_ss.lake_dir).drop_table("pdr_predictions") - - DuckDBDataStore(ppss.lake_ss.lake_dir).insert_from_df( - predictions_df, "pdr_predictions" - ) - - mock_get_feed_summary_stats.return_value = predictions_df - - mock_web3_pp = MagicMock(spec=Web3PP) - mock_web3_pp.network = "sapphire-mainnet" - mock_web3_pp.subgraph_url = ( - "http://localhost:8000/subgraphs/name/oceanprotocol/ocean-subgraph" - ) - - mock_web3_config = Mock(spec=Web3Config) - mock_web3_config.w3 = Mock() - mock_web3_pp.web3_config = mock_web3_config - mock_web3_pp.owner_addrs = _user - - with patch("pdr_backend.ppss.ppss.Web3PP", return_value=mock_web3_pp): - # Mock sys.argv - sys.argv = [ - "pdr", - "get_predictions_info", - "2023-12-01", - "2023-12-31", - ppss.lake_ss.lake_dir, - "ppss.yaml", - "development", - "--FEEDS", - _feed, - ] - - cli_module._do_main() - - # Verifying outputs - assert "pdr get_predictions_info: Begin" in caplog.text - assert "Arguments:" in caplog.text - assert "PPSS_FILE=ppss.yaml" in caplog.text - assert "NETWORK=development" in caplog.text - assert "FEEDS=['0x2d8e2267779d27C2b3eD5408408fF15D9F3a3152']" in caplog.text - - # # Additional assertions - mock_get_feed_summary_stats.assert_called_once() - mock_get_feed_summary_stats.call_args[0][0].equals(predictions_df) diff --git a/system_tests/test_get_predictoors_info_system.py b/system_tests/test_get_predictoors_info_system.py deleted file mode 100644 index 055f7447d..000000000 --- a/system_tests/test_get_predictoors_info_system.py +++ /dev/null @@ -1,104 +0,0 @@ -import sys -from unittest.mock import MagicMock, Mock, patch - -from pdr_backend.cli import cli_module -from pdr_backend.lake.duckdb_data_store import DuckDBDataStore -from pdr_backend.lake.plutil import _object_list_to_df -from pdr_backend.lake.prediction import Prediction -from pdr_backend.lake.table_pdr_predictions import _transform_timestamp_to_ms -from pdr_backend.ppss.ppss import mock_ppss -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.util.currency_types import Wei -from pdr_backend.util.time_types import UnixTimeS -from pdr_backend.util.web3_config import Web3Config - - -@patch("pdr_backend.analytics.get_predictions_info.get_predictoor_summary_stats") -def test_get_predictoors_info_system(get_get_predictoor_summary_stats, caplog): - mock_web3_pp = MagicMock(spec=Web3PP) - mock_web3_pp.network = "sapphire-mainnet" - mock_web3_pp.subgraph_url = ( - "http://localhost:8000/subgraphs/name/oceanprotocol/ocean-subgraph" - ) - - mock_web3_config = Mock(spec=Web3Config) - mock_web3_config.w3 = Mock() - mock_web3_config.w3.eth.get_balance.return_value = 100 - mock_web3_pp.web3_config = mock_web3_config - mock_web3_pp.web3_config.owner = "0xaaaa4cb4ff2584bad80ff5f109034a891c3d88dd" - mock_web3_pp.owner_addrs = "0xaaaa4cb4ff2584bad80ff5f109034a891c3d88dd" - - mock_token = MagicMock() - mock_token.balanceOf.return_value = Wei(int(5e18)) - mock_token.transfer.return_value = True - feed_addr = "0x2d8e2267779d27c2b3ed5408408ff15d9f3a3152" - user_addr = "0xaaaa4cb4ff2584bad80ff5f109034a891c3d88dd" - - mock_predictions = [ - Prediction( - f"{feed_addr}-31232-{user_addr}", - feed_addr, - "BTC", - "5m", - True, - 100.0, - False, - UnixTimeS(1701532572), - "binance", - 10.0, - UnixTimeS(10), - user_addr, - ) - ] - - st_timestr = "2023-12-03" - fin_timestr = "2024-12-05" - - ppss = mock_ppss( - [{"predict": "binance BTC/USDT c 5m", "train_on": "binance BTC/USDT c 5m"}], - "sapphire-mainnet", - ".", - st_timestr=st_timestr, - fin_timestr=fin_timestr, - ) - - predictions_df = _object_list_to_df(mock_predictions) - predictions_df = _transform_timestamp_to_ms(predictions_df) - - get_get_predictoor_summary_stats.return_value = predictions_df - - # DROP TABLE IF EXISTS - DuckDBDataStore(ppss.lake_ss.lake_dir).drop_table("pdr_predictions") - - DuckDBDataStore(ppss.lake_ss.lake_dir).insert_from_df( - predictions_df, "pdr_predictions" - ) - - with patch("pdr_backend.contract.token.Token", return_value=mock_token), patch( - "pdr_backend.ppss.ppss.Web3PP", return_value=mock_web3_pp - ): - user_addr = "0xaaaa4cb4ff2584bad80ff5f109034a891c3d88dd" - # Mock sys.argv - sys.argv = [ - "pdr", - "get_predictoors_info", - "2023-12-01", - "2023-12-31", - ppss.lake_ss.lake_dir, - "ppss.yaml", - "development", - "--PDRS", - user_addr, - ] - - cli_module._do_main() - - # Verifying outputs - assert "pdr get_predictoors_info: Begin" in caplog.text - assert "Arguments:" in caplog.text - assert "PPSS_FILE=ppss.yaml" in caplog.text - assert "NETWORK=development" in caplog.text - assert "PDRS=['0xaaaA4CB4Ff2584BaD80fF5F109034A891C3D88Dd']" in caplog.text - - # Additional assertions - get_get_predictoor_summary_stats.call_args[0][0].equals(predictions_df) diff --git a/system_tests/test_ocean_payout.py b/system_tests/test_ocean_payout.py deleted file mode 100644 index a124dece9..000000000 --- a/system_tests/test_ocean_payout.py +++ /dev/null @@ -1,76 +0,0 @@ -import sys - -from unittest.mock import Mock, patch, MagicMock - -from pdr_backend.cli import cli_module -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.util.constants import SAPPHIRE_MAINNET_CHAINID -from pdr_backend.util.web3_config import Web3Config - - -@patch("pdr_backend.payout.payout.wait_until_subgraph_syncs") -def test_ocean_payout_test(mock_wait_until_subgraph_syncs, caplog): - _ = mock_wait_until_subgraph_syncs - mock_web3_pp = MagicMock(spec=Web3PP) - mock_web3_pp.network = "sapphire-mainnet" - mock_web3_pp.subgraph_url = ( - "http://localhost:8000/subgraphs/name/oceanprotocol/ocean-subgraph" - ) - - mock_web3_config = Mock(spec=Web3Config) - mock_web3_config.owner = "0x00000000000000000000000000000000000c0ffe" - mock_web3_config.w3 = Mock() - mock_web3_config.w3.eth.chain_id = SAPPHIRE_MAINNET_CHAINID - - def checksum_mock(_, y): - return y - - mock_web3_config.w3.to_checksum_address = lambda x: x - mock_web3_pp.web3_config = mock_web3_config - - mock_contract = Mock() - mock_contract.get_payout = Mock() - mock_contract.get_payout.return_value = {"transactionHash": b"0x1", "status": 1} - mock_contract.pred_submitter_up_address.return_value = "0x1" - mock_contract.pred_submitter_down_address.return_value = "0x1" - - mock_token = MagicMock() - mock_token.balanceOf.return_value = 100 * 1e18 - - mock_query_pending_payouts = Mock() - mock_query_pending_payouts.return_value = {"0x1": [1, 2, 3], "0x2": [5, 6, 7]} - number_of_slots = 6 # 6 slots - - with patch( - "pdr_backend.payout.payout.query_pending_payouts", mock_query_pending_payouts - ), patch("pdr_backend.ppss.ppss.Web3PP", return_value=mock_web3_pp), patch( - "pdr_backend.contract.token.Token", return_value=mock_token - ), patch( - "pdr_backend.payout.payout.to_checksum", checksum_mock - ), patch( - "pdr_backend.payout.payout.WrappedToken", return_value=mock_token - ), patch( - "pdr_backend.payout.payout.PredSubmitterMgr", return_value=mock_contract - ): - # Mock sys.argv - sys.argv = ["pdr", "claim_OCEAN", "ppss.yaml"] - - cli_module._do_main() - - # Verifying outputs - assert "pdr claim_OCEAN: Begin" in caplog.text - assert "Arguments:" in caplog.text - assert "PPSS_FILE=ppss.yaml" in caplog.text - assert "Starting payout" in caplog.text - assert "Finding pending payouts" in caplog.text - assert f"Found {number_of_slots} slots" in caplog.text - assert "Payout tx 1/2: 307831" in caplog.text - assert "Payout tx 1/2: 307831" in caplog.text - assert "Payout done" in caplog.text - - # Additional assertions - mock_query_pending_payouts.assert_called_with(mock_web3_pp.subgraph_url, "0x1") - print(mock_contract.get_payout.call_args_list) - mock_contract.get_payout.assert_any_call([1, 2, 3], ["0x1"]) - mock_contract.get_payout.assert_any_call([5, 6, 7], ["0x2"]) - assert mock_contract.get_payout.call_count == 2 diff --git a/system_tests/test_predictoor_system.py b/system_tests/test_predictoor_system.py deleted file mode 100644 index d594fd705..000000000 --- a/system_tests/test_predictoor_system.py +++ /dev/null @@ -1,108 +0,0 @@ -import sys -from unittest.mock import Mock, patch, MagicMock - -from pdr_backend.cli import cli_module -from pdr_backend.cli.predict_train_feedsets import PredictTrainFeedset -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.subgraph.subgraph_feed import SubgraphFeed -from pdr_backend.util.web3_config import Web3Config - - -def setup_mock_web3_pp(mock_feeds, mock_feed_contract): - mock_web3_pp = MagicMock(spec=Web3PP) - mock_web3_pp.network = "development" - mock_web3_pp.rpc_url = "http://example.com/rpc" - mock_web3_pp.subgraph_url = ( - "http://localhost:8000/subgraphs/name/oceanprotocol/ocean-subgraph" - ) - mock_web3_pp.query_feed_contracts.return_value = mock_feeds - mock_web3_pp.get_single_contract.return_value = mock_feed_contract - mock_web3_pp.w3.eth.block_number = 100 - mock_predictoor_ss = Mock() - mock_predictoor_ss.get_feed_from_candidates.return_value = mock_feeds["0x1"] - mock_predictoor_ss.get_predict_train_feedset.return_value = ( - PredictTrainFeedset.from_dict( - { - "predict": "binance BTC/USDT o 5m", - "train_on": "binance BTC/USDT ETH/USDT o 5m", - } - ) - ) - mock_predictoor_ss.s_until_epoch_end = 100 - mock_predictoor_ss.s_start_payouts = 0 - mock_predictoor_ss.stake_amount = 20 - mock_predictoor_ss.predict_train_feedsets.min_epoch_seconds = 20 - - mock_web3_config = Mock(spec=Web3Config) - mock_web3_config.w3 = Mock() - mock_web3_config.owner = "0xowner" - mock_web3_config.get_block.return_value = {"timestamp": 100} - mock_web3_pp.web3_config = mock_web3_config - - return mock_web3_pp, mock_predictoor_ss - - -def _test_predictoor_system(mock_feeds, mock_feed_contract, approach, caplog): - mock_web3_pp, mock_predictoor_ss = setup_mock_web3_pp( - mock_feeds, mock_feed_contract - ) - mock_predictoor_ss.approach = approach - - merged_ohlcv_df = Mock() - - mock_predictoor_ss.get_feed_from_candidates.return_value = { - "0x1": SubgraphFeed( - "BTC/USDT", "0x1", "BTC", 300, 300, "0x1", "BTC", "5m", "binance" - ) - } - - with patch("pdr_backend.ppss.ppss.Web3PP", return_value=mock_web3_pp), patch( - "pdr_backend.ppss.ppss.PredictoorSS", return_value=mock_predictoor_ss - ), patch( - "pdr_backend.predictoor.predictoor_agent.PredSubmitterMgr", return_value=Mock() - ), patch( - "pdr_backend.lake.ohlcv_data_factory.OhlcvDataFactory.get_mergedohlcv_df", - return_value=merged_ohlcv_df, - ), patch( - "pdr_backend.predictoor.predictoor_agent.PredictoorAgent.calc_stakes_2ss_model", - return_value=(10, 10), - ): - # Mock sys.argv - sys.argv = ["pdr", "predictoor", "ppss.yaml", "development"] - - cli_module._do_main() - - # Verifying outputs - assert "pdr predictoor: Begin" in caplog.text - assert "Arguments:" in caplog.text - assert "PPSS_FILE=ppss.yaml" in caplog.text - assert "NETWORK=development" in caplog.text - assert "Feed: 5m binance BTC/USDT 0x1" in caplog.text - assert "Starting main loop." in caplog.text - assert "Waiting..." in caplog.text - - # Additional assertions - mock_predictoor_ss.get_feed_from_candidates.assert_called_once() - mock_feed_contract.get_current_epoch.assert_called() - - -@patch("pdr_backend.ppss.ppss.PPSS.verify_feed_dependencies") -def test_predictoor_approach_1_system( - mock_verify_feed_dependencies, - mock_feeds, - mock_feed_contract, - caplog, -): - _ = mock_verify_feed_dependencies - _test_predictoor_system(mock_feeds, mock_feed_contract, 1, caplog) - - -@patch("pdr_backend.ppss.ppss.PPSS.verify_feed_dependencies") -def test_predictoor_approach_2_system( - mock_verify_feed_dependencies, - mock_feeds, - mock_feed_contract, - caplog, -): - _ = mock_verify_feed_dependencies - _test_predictoor_system(mock_feeds, mock_feed_contract, 2, caplog) diff --git a/system_tests/test_publisher_system.py b/system_tests/test_publisher_system.py deleted file mode 100644 index dffc9eb60..000000000 --- a/system_tests/test_publisher_system.py +++ /dev/null @@ -1,39 +0,0 @@ -import sys - -from unittest.mock import Mock, patch, MagicMock - -from pdr_backend.cli import cli_module -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.util.web3_config import Web3Config - - -@patch("pdr_backend.cli.cli_module.fund_accounts_with_OCEAN") -@patch("pdr_backend.publisher.publish_assets.publish_asset") -def test_publisher(mock_fund_accounts, mock_publish_asset, caplog): - mock_web3_pp = MagicMock(spec=Web3PP) - mock_web3_pp.network = "development" - mock_web3_pp.subgraph_url = ( - "http://localhost:8000/subgraphs/name/oceanprotocol/ocean-subgraph" - ) - - mock_web3_config = Mock(spec=Web3Config) - mock_web3_config.w3 = Mock() - mock_web3_pp.web3_config = mock_web3_config - - with patch("pdr_backend.ppss.ppss.Web3PP", return_value=mock_web3_pp): - # Mock sys.argv - sys.argv = ["pdr", "publisher", "ppss.yaml", "development"] - - cli_module._do_main() - - # Verifying outputs - assert "pdr publisher: Begin" in caplog.text - assert "Arguments:" in caplog.text - assert "PPSS_FILE=ppss.yaml" in caplog.text - assert "NETWORK=development" in caplog.text - assert "Publish on network = development" in caplog.text - assert "Done publishing." in caplog.text - - # Additional assertions - mock_fund_accounts.assert_called() - mock_publish_asset.assert_called() diff --git a/system_tests/test_rose_payout.py b/system_tests/test_rose_payout.py deleted file mode 100644 index 1ea0d7bf1..000000000 --- a/system_tests/test_rose_payout.py +++ /dev/null @@ -1,70 +0,0 @@ -import sys -from unittest.mock import Mock, call, patch, MagicMock - -from pdr_backend.cli import cli_module -from pdr_backend.contract.pred_submitter_mgr import PredSubmitterMgr -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.util.constants import SAPPHIRE_MAINNET_CHAINID -from pdr_backend.util.currency_types import Wei, Eth - - -def test_rose_payout_test(caplog): - mock_web3_pp = MagicMock(spec=Web3PP) - mock_web3_pp.network = "sapphire-mainnet" - mock_web3_pp.web3_config.w3.eth.chain_id = SAPPHIRE_MAINNET_CHAINID - - mock_dfrewards = MagicMock() - mock_dfrewards.get_claimable_rewards.return_value = Eth(100) - mock_dfrewards.claim_rewards.return_value = None - - mock_contract = Mock(spec=PredSubmitterMgr) - mock_contract.contract_address = "0x0" - mock_contract.get_claimable_rewards = Mock() - mock_contract.get_claimable_rewards.return_value = Eth(100) - mock_contract.claim_dfrewards = Mock() - mock_contract.claim_dfrewards.return_value = { - "transactionHash": b"0x1", - "status": 1, - } - mock_contract.transfer_erc20 = Mock() - mock_contract.transfer_erc20.return_value = {"transactionHash": b"0x1", "status": 1} - mock_contract.pred_submitter_up_address.return_value = "0x1" - mock_contract.pred_submitter_down_address.return_value = "0x2" - - mock_token = MagicMock() - mock_token.balanceOf.return_value = Wei(100 * 1e18) - - with patch( - "pdr_backend.ppss.ppss.Web3PP", return_value=mock_web3_pp - ) as MockPPSS, patch( - "pdr_backend.payout.payout.DFRewards", return_value=mock_dfrewards - ), patch( - "pdr_backend.contract.token.Token", return_value=mock_token - ), patch( - "pdr_backend.payout.payout.WrappedToken", return_value=mock_token - ), patch( - "pdr_backend.payout.payout.PredSubmitterMgr", return_value=mock_contract - ): - mock_ppss_instance = MockPPSS.return_value - mock_ppss_instance.web3_pp = mock_web3_pp - - # Mock sys.argv - sys.argv = ["pdr", "claim_ROSE", "ppss.yaml"] - - cli_module._do_main() - - # Verifying outputs - assert "Found 200 wROSE available to claim" in caplog.text - assert "Claiming wROSE rewards from the manager contract..." in caplog.text - assert "Converting wROSE to ROSE" in caplog.text - assert "Found 100.0 wROSE, converting to ROSE..." in caplog.text - assert "ROSE reward claim done" in caplog.text - - # Additional assertions - mock_dfrewards.get_claimable_rewards.assert_has_calls( - [ - call("0x2", "0x8Bc2B030b299964eEfb5e1e0b36991352E56D2D3"), - call("0x1", "0x8Bc2B030b299964eEfb5e1e0b36991352E56D2D3"), - ], - any_order=True, - ) diff --git a/system_tests/test_topup_system.py b/system_tests/test_topup_system.py deleted file mode 100644 index 8e91bb89e..000000000 --- a/system_tests/test_topup_system.py +++ /dev/null @@ -1,69 +0,0 @@ -import sys - -from unittest.mock import Mock, patch, MagicMock - -from pdr_backend.cli import cli_module -from pdr_backend.contract.token import NativeToken, Token -from pdr_backend.ppss.topup_ss import TopupSS -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.util.web3_config import Web3Config -from pdr_backend.util.currency_types import Wei, Eth - - -def test_topup(caplog): - mock_web3_pp = MagicMock(spec=Web3PP) - mock_web3_pp.network = "sapphire-mainnet" - mock_web3_pp.subgraph_url = ( - "http://localhost:8000/subgraphs/name/oceanprotocol/ocean-subgraph" - ) - - mock_web3_config = Mock(spec=Web3Config) - mock_web3_config.w3 = Mock() - mock_web3_pp.web3_config = mock_web3_config - mock_web3_pp.web3_config.owner = "0xowner" - - mock_token = MagicMock(spec=Token) - balances_arr = [Wei(int(5000 * 1e18))] + [Wei(int(5 * 1e18))] * 100 - mock_token.balanceOf.side_effect = balances_arr - mock_token.transfer.return_value = True - mock_token.name = "OCEAN" - - mock_token_rose = MagicMock(spec=NativeToken) - balances_arr = [Wei(int(5000 * 1e18))] + [Wei(int(5 * 1e18))] * 100 - mock_token_rose.balanceOf.side_effect = balances_arr - mock_token_rose.transfer.return_value = True - mock_token_rose.name = "ROSE" - - mock_web3_pp.OCEAN_Token = mock_token - mock_web3_pp.NativeToken = mock_token_rose - - opf_addresses = { - "predictoor1": "0x1", - "predictoor2": "0x2", - } - topup_ss = MagicMock(spec=TopupSS) - topup_ss.all_topup_addresses.return_value = opf_addresses - topup_ss.get_min_bal.side_effect = [Eth(20), Eth(30), Eth(20), Eth(30)] - topup_ss.get_topup_bal.side_effect = [Eth(20), Eth(30), Eth(20), Eth(30)] - - with patch("pdr_backend.ppss.ppss.Web3PP", return_value=mock_web3_pp), patch( - "pdr_backend.ppss.ppss.TopupSS", return_value=topup_ss - ), patch("sys.exit"): - # Mock sys.argv - sys.argv = ["pdr", "topup", "ppss.yaml", "sapphire-testnet"] - - cli_module._do_main() - - addresses = opf_addresses - # Verifying outputs - for key, value in addresses.items(): - assert f"{key}: 5.00 OCEAN, 5.00 ROSE" in caplog.text - if key.startswith("pred"): - assert f"Transferring 20 OCEAN to {value}..." in caplog.text - assert f"Transferring 30 ROSE to {value}..." in caplog.text - if key.startswith("dfbuyer"): - assert f"Transferring 250 ROSE to {value}..." in caplog.text - - # Additional assertions - mock_token.transfer.assert_called() - mock_token.balanceOf.assert_called() diff --git a/system_tests/test_trader_agent_system.py b/system_tests/test_trader_agent_system.py deleted file mode 100644 index ad1026322..000000000 --- a/system_tests/test_trader_agent_system.py +++ /dev/null @@ -1,90 +0,0 @@ -import sys -from unittest.mock import Mock, patch, MagicMock - -from pdr_backend.cli import cli_module -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.util.constants import SAPPHIRE_MAINNET_CHAINID -from pdr_backend.util.web3_config import Web3Config - - -def setup_mock_objects(mock_web3_pp, mock_feed_contract, feeds): - mock_web3_pp.network = "sapphire-mainnet" - mock_web3_pp.subgraph_url = ( - "http://localhost:8000/subgraphs/name/oceanprotocol/ocean-subgraph" - ) - mock_web3_pp.query_feed_contracts.return_value = feeds - - mock_web3_config = Mock(spec=Web3Config) - mock_web3_config.get_block.return_value = {"timestamp": 100} - mock_web3_config.owner = "0x00000000000000000000000000000000000c0ffe" - mock_web3_config.w3 = Mock() - mock_web3_config.w3.eth.block_number = 100 - mock_web3_config.w3.eth.chain_id = SAPPHIRE_MAINNET_CHAINID - mock_web3_pp.web3_config = mock_web3_config - - mock_token = MagicMock() - mock_token.balanceOf.return_value = 100 * 1e18 - - mock_trader_ss = Mock() - mock_trader_ss.min_buffer = 1 - mock_trader_ss.get_feed_from_candidates.return_value = feeds["0x1"] - mock_trader_ss.exchange_type = "mock" - mock_trader_ss.feed.timeframe.s = 300 - - mock_web3_pp.get_contracts.return_value = {"0x1": mock_feed_contract} - - return mock_web3_pp, mock_token, mock_trader_ss - - -def _test_trader( - mock_time_sleep, mock_run, mock_feed_contract, mock_feeds, approach, caplog -): - mock_web3_pp = MagicMock(spec=Web3PP) - - mock_web3_pp, mock_token, mock_trader_ss = setup_mock_objects( - mock_web3_pp, mock_feed_contract, mock_feeds - ) - - with patch("pdr_backend.ppss.ppss.Web3PP", return_value=mock_web3_pp), patch( - "pdr_backend.contract.token.Token", return_value=mock_token - ), patch("pdr_backend.payout.payout.WrappedToken", return_value=mock_token), patch( - "pdr_backend.payout.payout.FeedContract", - return_value=mock_feed_contract, - ), patch( - "pdr_backend.ppss.ppss.TraderSS", - return_value=mock_trader_ss, - ): - # Mock sys.argv - sys.argv = ["pdr", "trader", str(approach), "ppss.yaml", "development"] - - cli_module._do_main() - - # Verifying outputs - assert "pdr trader: Begin" in caplog.text - assert "Arguments:" in caplog.text - assert f"APPROACH={approach}" in caplog.text - assert "PPSS_FILE=ppss.yaml" in caplog.text - assert "NETWORK=development" in caplog.text - assert "Feed: 5m binance BTC/USDT 0x1" in caplog.text - - # Additional assertions - mock_web3_pp.query_feed_contracts.assert_called() - mock_trader_ss.get_feed_from_candidates.assert_called_with(mock_feeds) - mock_time_sleep.assert_called() - mock_run.assert_called() - - -@patch("pdr_backend.trader.base_trader_agent.BaseTraderAgent.run") -@patch("pdr_backend.trader.base_trader_agent.time.sleep") -def test_trader_approach_1( - mock_time_sleep, mock_run, mock_feed_contract, mock_feeds, caplog -): - _test_trader(mock_time_sleep, mock_run, mock_feed_contract, mock_feeds, 1, caplog) - - -@patch("pdr_backend.trader.base_trader_agent.BaseTraderAgent.run") -@patch("pdr_backend.trader.base_trader_agent.time.sleep") -def test_trader_approach_2( - mock_time_sleep, mock_run, mock_feed_contract, mock_feeds, caplog -): - _test_trader(mock_time_sleep, mock_run, mock_feed_contract, mock_feeds, 2, caplog) diff --git a/system_tests/test_trueval_agent_system.py b/system_tests/test_trueval_agent_system.py deleted file mode 100644 index f251780b8..000000000 --- a/system_tests/test_trueval_agent_system.py +++ /dev/null @@ -1,77 +0,0 @@ -import sys - -from unittest.mock import Mock, patch, MagicMock - -from pdr_backend.cli import cli_module -from pdr_backend.contract.predictoor_batcher import PredictoorBatcher -from pdr_backend.contract.slot import Slot -from pdr_backend.ppss.web3_pp import Web3PP -from pdr_backend.subgraph.subgraph_feed import SubgraphFeed -from pdr_backend.util.constants import SAPPHIRE_MAINNET_CHAINID -from pdr_backend.util.web3_config import Web3Config - - -@patch("pdr_backend.trueval.trueval_agent.wait_until_subgraph_syncs") -@patch("pdr_backend.trueval.trueval_agent.time.sleep") -@patch("pdr_backend.trueval.trueval_agent.TruevalAgent.process_trueval_slot") -def test_trueval_batch( - mock_wait_until_subgraph_syncs, mock_time_sleep, mock_process, caplog -): - _ = mock_wait_until_subgraph_syncs - mock_web3_pp = MagicMock(spec=Web3PP) - mock_web3_pp.network = "sapphire-mainnet" - mock_web3_pp.subgraph_url = ( - "http://localhost:8000/subgraphs/name/oceanprotocol/ocean-subgraph" - ) - feeds = { - "0x1": SubgraphFeed( - "Feed: binance | BTC/USDT | 5m", - "0x1", - "BTC", - 100, - 300, - "0xf", - "BTC/USDT", - "5m", - "binance", - ) - } - mock_web3_pp.get_pending_slots.return_value = [Slot(1, feeds["0x1"])] - mock_web3_pp.get_address.return_value = "0x1" - - mock_web3_config = Mock(spec=Web3Config) - mock_web3_config.get_block.return_value = {"timestamp": 100} - mock_web3_config.owner = "0x00000000000000000000000000000000000c0ffe" - mock_web3_config.w3 = Mock() - mock_web3_config.w3.eth.block_number = 100 - mock_web3_config.w3.eth.chain_id = SAPPHIRE_MAINNET_CHAINID - mock_web3_pp.web3_config = mock_web3_config - - mock_predictoor_batcher = Mock(spec=PredictoorBatcher) - - with patch("pdr_backend.ppss.ppss.Web3PP", return_value=mock_web3_pp), patch( - "pdr_backend.trueval.trueval_agent.PredictoorBatcher", - return_value=mock_predictoor_batcher, - ), patch( - "pdr_backend.trueval.trueval_agent.TruevalAgent.process_trueval_slot" - ), patch( - "pdr_backend.trueval.trueval_agent.TruevalAgent.batch_submit_truevals", - return_value="0xbatch_submit_tx", - ): - # Mock sys.argv - sys.argv = ["pdr", "trueval", "ppss.yaml", "development"] - - cli_module._do_main() - - # Verifying outputs - assert "pdr trueval: Begin" in caplog.text - assert "Arguments:" in caplog.text - assert "PPSS_FILE=ppss.yaml" in caplog.text - assert "NETWORK=development" in caplog.text - assert "Found 1 pending slots, processing 30" in caplog.text - assert "Tx sent: 0xbatch_submit_tx, sleeping for 30 seconds..." in caplog.text - - # Additional assertions - mock_web3_pp.get_pending_slots.assert_called() - mock_time_sleep.assert_called() - mock_process.assert_called()