Skip to content

Commit

Permalink
Add some test coverage (#488)
Browse files Browse the repository at this point in the history
* Adds a line of coverage to test.
* Add coverage for csvs module.
* Add coverage to check_network.
* Add coverage to predictions and traction info.
* Adds coverage to predictoor stats.
* Adds full coverage to arg cli classes.
* Adds cli arguments coverage and fix a wrong parameter in cli arguments.
* Adds coverage to cli module and timeframe.
* Some reformats and coverage in contract module.
* Adds coverage and simplifications to contracts, except token.
* Add some coverage to tokens to complete contract coverage work.
  • Loading branch information
calina-c authored Jan 9, 2024
1 parent 3a5c639 commit 56392e4
Show file tree
Hide file tree
Showing 38 changed files with 719 additions and 353 deletions.
15 changes: 15 additions & 0 deletions pdr_backend/aimodel/test/test_aimodel_factory.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import warnings
from unittest.mock import Mock

import numpy as np
import pytest
from enforce_typing import enforce_types

from pdr_backend.aimodel.aimodel_factory import AimodelFactory
Expand Down Expand Up @@ -82,3 +84,16 @@ def test_aimodel_accuracy_from_create_xy(aimodel_factory):

y_train_hat = aimodel.predict(X_train)
assert sum(abs(y_train - y_train_hat)) < 1e-10 # near-perfect since linear


@enforce_types
def test_aimodel_factory_bad_approach():
aimodel_ss = Mock(spec=AimodelSS)
aimodel_ss.approach = "BAD"
factory = AimodelFactory(aimodel_ss)

X_train, y_train, _, _ = _data()

# forcefully change the model
with pytest.raises(ValueError):
factory.build(X_train, y_train)
9 changes: 5 additions & 4 deletions pdr_backend/analytics/check_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,12 +166,13 @@ def check_network_main(ppss: PPSS, lookback_hours: int):
ocean_bal = from_wei(OCEAN.balanceOf(address))
native_bal = from_wei(web3_pp.web3_config.w3.eth.get_balance(address))

ocean_warning = " WARNING LOW OCEAN BALANCE!" if ocean_bal < 10 else " OK "
ocean_warning = (
" WARNING LOW OCEAN BALANCE!"
if ocean_bal < 10 and name != "trueval"
else " OK "
)
native_warning = " WARNING LOW NATIVE BALANCE!" if native_bal < 10 else " OK "

if name == "trueval":
ocean_warning = " OK "

print(
f"{name}: OCEAN: {ocean_bal:.2f}{ocean_warning}"
f", Native: {native_bal:.2f}{native_warning}"
Expand Down
37 changes: 37 additions & 0 deletions pdr_backend/analytics/test/test_check_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,40 @@ def test_check_network_main( # pylint: disable=unused-argument
assert mock_query_subgraph.call_count == 1
mock_token.assert_called()
ppss.web3_pp.web3_config.w3.eth.get_balance.assert_called()


@enforce_types
@patch(f"{PATH}.check_dfbuyer")
@patch(f"{PATH}.get_opf_addresses")
@patch(f"{PATH}.Token")
def test_check_network_others( # pylint: disable=unused-argument
mock_token,
mock_get_opf_addresses,
mock_check_dfbuyer,
tmpdir,
monkeypatch,
):
ppss = mock_ppss(["binance BTC/USDT c 5m"], "sapphire-mainnet", str(tmpdir))
mock_query_subgraph = Mock()

# test if predictoor contracts are found, iterates through them
with patch(f"{PATH}.query_subgraph") as mock_query_subgraph:
mock_query_subgraph.return_value = {
"data": {
"predictContracts": [
{
"slots": {},
"token": {"name": "aa"},
"secondsPerEpoch": 86400,
},
{
"slots": {},
"token": {"name": "bb"},
"secondsPerEpoch": 86400,
},
]
}
}
check_network_main(ppss, lookback_hours=24)
assert mock_query_subgraph.call_count == 1
assert mock_check_dfbuyer.call_count == 1
23 changes: 23 additions & 0 deletions pdr_backend/analytics/test/test_get_predictions_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,26 @@ def test_get_predictions_info_main_mainnet(
)
mock_save.assert_called()
mock_getstats.assert_called_with(_sample_first_predictions)


@enforce_types
def test_get_predictions_info_empty(tmpdir, capfd):
ppss = mock_ppss(["binance BTC/USDT c 5m"], "sapphire-mainnet", str(tmpdir))

mock_getids = Mock(return_value=[])
mock_fetch = Mock(return_value={})

PATH = "pdr_backend.analytics.get_predictions_info"
with patch(f"{PATH}.get_all_contract_ids_by_owner", mock_getids), patch(
f"{PATH}.fetch_filtered_predictions", mock_fetch
):
st_timestr = "2023-11-02"
fin_timestr = "2023-11-05"

get_predictions_info_main(
ppss, "0x123", st_timestr, fin_timestr, "parquet_data/"
)

assert (
"No records found. Please adjust start and end times" in capfd.readouterr().out
)
21 changes: 21 additions & 0 deletions pdr_backend/analytics/test/test_get_traction_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,3 +73,24 @@ def test_get_traction_info_main_mainnet(
pl.DataFrame.equals(mock_traction_stat.call_args, preds_df)
mock_plot_cumsum.assert_called()
mock_plot_daily.assert_called()


@enforce_types
def test_get_traction_info_empty(
tmpdir,
capfd,
):
ppss = mock_ppss(["binance BTC/USDT c 5m"], "sapphire-mainnet", str(tmpdir))

mock_empty = Mock(return_value=[])

PATH = "pdr_backend.analytics.get_traction_info"
with patch(f"{PATH}.GQLDataFactory.get_gql_dfs", mock_empty):
st_timestr = "2023-11-02"
fin_timestr = "2023-11-05"

get_traction_info_main(ppss, st_timestr, fin_timestr, "parquet_data/")

assert (
"No records found. Please adjust start and end times." in capfd.readouterr().out
)
11 changes: 11 additions & 0 deletions pdr_backend/analytics/test/test_predictoor_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ def test_get_cli_statistics(capsys, _sample_first_predictions):
assert "Accuracy for Pair" in output
assert "Accuracy for Predictoor Address" in output

get_cli_statistics([])
assert "No predictions found" in capsys.readouterr().out

with patch(
"pdr_backend.analytics.predictoor_stats.aggregate_prediction_statistics"
) as mock:
mock.return_value = ({}, 0)
get_cli_statistics(_sample_first_predictions)

assert "No correct predictions found" in capsys.readouterr().out


@enforce_types
@patch("matplotlib.pyplot.savefig")
Expand Down
3 changes: 0 additions & 3 deletions pdr_backend/cli/arg_exchange.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,4 @@ def __init__(self, exchanges: Union[List[str], List[ArgExchange]]):
super().__init__(converted)

def __str__(self):
if not self:
return ""

return ",".join([str(exchange) for exchange in self])
3 changes: 0 additions & 3 deletions pdr_backend/cli/arg_feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,6 @@ def __str__(self):

return feed_str

def __repr__(self):
return self.__str__()

def __eq__(self, other):
return (
self.exchange == other.exchange
Expand Down
11 changes: 3 additions & 8 deletions pdr_backend/cli/arg_pair.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def __init__(
base_str: Optional[str] = None,
quote_str: Optional[str] = None,
):
if not pair_str and [None in [base_str, quote_str]]:
if not pair_str and None in [base_str, quote_str]:
raise ValueError(
"Must provide either pair_str, or both base_str and quote_str"
)
Expand Down Expand Up @@ -55,12 +55,7 @@ def __hash__(self):
class ArgPairs(List[ArgPair]):
@staticmethod
def from_str(pairs_str: str) -> "ArgPairs":
pairs = ArgPairs(_unpack_pairs_str(pairs_str))

if not pairs:
raise ValueError(pairs_str)

return pairs
return ArgPairs(_unpack_pairs_str(pairs_str))

def __eq__(self, other):
return set(self) == set(other)
Expand Down Expand Up @@ -106,7 +101,7 @@ def _unpack_pairs_str(pairs_str: str) -> List[str]:
pairs_str = pairs_str.replace("-", "/") # ETH/USDT -> ETH-USDT. Safer files.
pair_str_list = pairs_str.split(",")

if not pair_str_list:
if not any(pair_str_list):
raise ValueError(pairs_str)

return pair_str_list
Expand Down
62 changes: 31 additions & 31 deletions pdr_backend/cli/cli_arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,9 @@ class _ArgParser_ST_END_PQDIR_NETWORK_PPSS_PDRS(
@enforce_types
def __init__(self, description: str, command_name: str):
super().__init__(description=description)
self.add_arguments_bulk(command_name, ["ST", "END", "PQDIR", "PPSS", "NETWORK"])
self.add_arguments_bulk(
command_name, ["ST", "END", "PQDIR", "PPSS", "NETWORK", "PDRS"]
)


@enforce_types
Expand Down Expand Up @@ -249,37 +251,35 @@ def print_args(arguments: Namespace):

TopupArgParser = _ArgParser_PPSS_NETWORK

defined_parsers = {
"do_sim": SimArgParser("Run simulation", "sim"),
"do_predictoor": PredictoorArgParser("Run a predictoor bot", "predictoor"),
"do_trader": TraderArgParser("Run a trader bot", "trader"),
"do_lake": LakeArgParser("Run the lake tool", "lake"),
"do_claim_OCEAN": ClaimOceanArgParser("Claim OCEAN", "claim_OCEAN"),
"do_claim_ROSE": ClaimRoseArgParser("Claim ROSE", "claim_ROSE"),
"do_get_predictoors_info": GetPredictoorsInfoArgParser(
"For specified predictoors, report {accuracy, ..} of each predictoor",
"get_predictoors_info",
),
"do_get_predictions_info": GetPredictionsInfoArgParser(
"For specified feeds, report {accuracy, ..} of each predictoor",
"get_predictions_info",
),
"do_get_traction_info": GetTractionInfoArgParser(
"Get traction info: # predictoors vs time, etc",
"get_traction_info",
),
"do_check_network": CheckNetworkArgParser("Check network", "check_network"),
"do_trueval": TruevalArgParser("Run trueval bot", "trueval"),
"do_dfbuyer": DfbuyerArgParser("Run dfbuyer bot", "dfbuyer"),
"do_publisher": PublisherArgParser("Publish feeds", "publisher"),
"do_topup": TopupArgParser("Topup OCEAN and ROSE in dfbuyer, trueval, ..", "topup"),
}


def get_arg_parser(func_name):
parsers = {
"do_sim": SimArgParser("Run simulation", "sim"),
"do_predictoor": PredictoorArgParser("Run a predictoor bot", "predictoor"),
"do_trader": TraderArgParser("Run a trader bot", "trader"),
"do_lake": LakeArgParser("Run the lake tool", "lake"),
"do_claim_OCEAN": ClaimOceanArgParser("Claim OCEAN", "claim_OCEAN"),
"do_claim_ROSE": ClaimRoseArgParser("Claim ROSE", "claim_ROSE"),
"do_get_predictoors_info": GetPredictoorsInfoArgParser(
"For specified predictoors, report {accuracy, ..} of each predictoor",
"get_predictoors_info",
),
"do_get_predictions_info": GetPredictionsInfoArgParser(
"For specified feeds, report {accuracy, ..} of each predictoor",
"get_predictions_info",
),
"do_get_traction_info": GetTractionInfoArgParser(
"Get traction info: # predictoors vs time, etc",
"get_traction_info",
),
"do_check_network": CheckNetworkArgParser("Check network", "check_network"),
"do_trueval": TruevalArgParser("Run trueval bot", "trueval"),
"do_dfbuyer": DfbuyerArgParser("Run dfbuyer bot", "dfbuyer"),
"do_publisher": PublisherArgParser("Publish feeds", "publisher"),
"do_topup": TopupArgParser(
"Topup OCEAN and ROSE in dfbuyer, trueval, ..", "topup"
),
}

if func_name not in parsers:
if func_name not in defined_parsers:
raise ValueError(f"Unknown function name: {func_name}")

return parsers[func_name]
return defined_parsers[func_name]
5 changes: 4 additions & 1 deletion pdr_backend/cli/test_noganache/test_arg_exchange.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pytest
from enforce_typing import enforce_types

from pdr_backend.cli.arg_exchange import ArgExchanges
from pdr_backend.cli.arg_exchange import ArgExchange, ArgExchanges


@enforce_types
Expand All @@ -15,6 +15,9 @@ def test_pack_exchange_str_list():
with pytest.raises(TypeError):
ArgExchanges(None)

with pytest.raises(ValueError):
ArgExchange(None)

with pytest.raises(TypeError):
ArgExchanges("")

Expand Down
12 changes: 8 additions & 4 deletions pdr_backend/cli/test_noganache/test_arg_feed.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@ def test_unpack_feeds_strs():
assert ArgFeeds.from_strs(["binance ADA-USDT o 1h"]) == target_feeds

# 1 str w 2 feeds, 2 feeds total
target_feeds = [
ArgFeed("binance", "open", "ADA/USDT"),
ArgFeed("binance", "high", "ADA/USDT"),
]
target_feeds = ArgFeeds(
[
ArgFeed("binance", "open", "ADA/USDT"),
ArgFeed("binance", "high", "ADA/USDT"),
]
)
assert ArgFeeds.from_strs(["binance ADA/USDT oh"]) == target_feeds
assert ArgFeeds.from_strs(["binance ADA-USDT oh"]) == target_feeds
assert target_feeds.signals == set(["open", "high"])
assert target_feeds.exchanges == set(["binance"])

# 2 strs each w 1 feed, 2 feeds total
target_feeds = [
Expand Down
7 changes: 7 additions & 0 deletions pdr_backend/cli/test_noganache/test_arg_pair.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pdr_backend.cli.arg_pair import (
ArgPair,
ArgPairs,
_unpack_pairs_str,
_verify_base_str,
_verify_quote_str,
)
Expand All @@ -19,6 +20,9 @@ def test_unpack_pair_str():

@enforce_types
def test_unpack_pairs_str():
with pytest.raises(ValueError):
_unpack_pairs_str("")

assert ArgPairs.from_str("ADA-USDT BTC/USDT") == ["ADA/USDT", "BTC/USDT"]
assert ArgPairs.from_str("ADA/USDT,BTC/USDT") == ["ADA/USDT", "BTC/USDT"]
assert ArgPairs.from_str("ADA/USDT, BTC/USDT") == ["ADA/USDT", "BTC/USDT"]
Expand Down Expand Up @@ -53,6 +57,9 @@ def test_pack_pair_str_list():
with pytest.raises(ValueError):
ArgPairs(["ADA-USDT fgds"])

pair_from_base_and_quote = ArgPair(base_str="BTC", quote_str="USDT")
assert str(ArgPair(pair_from_base_and_quote)) == "BTC/USDT"


@enforce_types
def test_verify_pairs_str__and__verify_pair_str():
Expand Down
41 changes: 41 additions & 0 deletions pdr_backend/cli/test_noganache/test_cli_arguments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import pytest

from pdr_backend.cli.cli_arguments import (
CustomArgParser,
defined_parsers,
do_help_long,
get_arg_parser,
print_args,
)


def test_arg_parser():
for arg in defined_parsers:
parser = get_arg_parser(arg)
assert isinstance(parser, CustomArgParser)

with pytest.raises(ValueError):
get_arg_parser("xyz")


def test_do_help_long(capfd):
with pytest.raises(SystemExit):
do_help_long()

out, _ = capfd.readouterr()
assert "Predictoor tool" in out
assert "Main tools:" in out


def test_print_args(capfd):
SimArgParser = defined_parsers["do_sim"]
parser = SimArgParser
args = ["sim", "ppss.yaml"]
parsed_args = parser.parse_args(args)

print_args(parsed_args)

out, _ = capfd.readouterr()
assert "dftool sim: Begin" in out
assert "Arguments:" in out
assert "PPSS_FILE=ppss.yaml" in out
Loading

0 comments on commit 56392e4

Please sign in to comment.