mirror of https://github.com/nucypher/nucypher.git
Allow MockRegistrySource to take any domain value while allowing the accepted values to be specified.
Update various tests that used random domain values to either use the mock, or just use TEMPORARY_DOMAIN if applicable.pull/3262/head
parent
9708efb0ba
commit
568270d36c
|
@ -1,9 +1,11 @@
|
|||
import pytest
|
||||
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
|
||||
|
||||
def test_new_ursula_announces_herself(lonely_ursula_maker):
|
||||
ursula_in_a_house, ursula_with_a_mouse = lonely_ursula_maker(
|
||||
quantity=2, domain="useless_domain"
|
||||
quantity=2, domain=TEMPORARY_DOMAIN
|
||||
)
|
||||
|
||||
# Neither Ursula knows about the other.
|
||||
|
@ -36,7 +38,7 @@ def test_goerli_and_mumbai_as_conditions_providers(lonely_ursula_maker):
|
|||
with pytest.raises(NotImplementedError):
|
||||
_ursula_who_tries_to_connect_to_an_invalid_chain = lonely_ursula_maker(
|
||||
quantity=1,
|
||||
domain="useless_domain",
|
||||
domain=TEMPORARY_DOMAIN,
|
||||
condition_blockchain_endpoints={
|
||||
INVALID_CHAIN_ID: "this is a provider URI, but it doesn't matter what we pass here because the chain_id is invalid."
|
||||
},
|
||||
|
|
|
@ -2,22 +2,62 @@ from pathlib import Path
|
|||
|
||||
import pytest
|
||||
|
||||
import tests
|
||||
from nucypher.acumen.perception import FleetSensor
|
||||
from nucypher.blockchain.eth.registry import ContractRegistry
|
||||
from nucypher.characters.lawful import Ursula
|
||||
from nucypher.config.storages import LocalFileBasedNodeStorage
|
||||
from nucypher.network.nodes import TEACHER_NODES
|
||||
from tests.utils.registry import MockRegistrySource
|
||||
from tests.utils.ursula import make_ursulas
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("test_registry_source_manager")
|
||||
def test_learner_learns_about_domains_separately(lonely_ursula_maker, caplog):
|
||||
@pytest.fixture(scope="module")
|
||||
def domain_1():
|
||||
return "domain_uno"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def domain_2():
|
||||
return "domain_dos"
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def test_registry(module_mocker, domain_1, domain_2):
|
||||
with tests.utils.registry.mock_registry_sources(
|
||||
mocker=module_mocker, domain_names=[domain_1, domain_2]
|
||||
):
|
||||
# doesn't really matter what domain is used here
|
||||
registry = ContractRegistry(MockRegistrySource(domain=domain_1))
|
||||
yield registry
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def registry_1(domain_1, test_registry):
|
||||
return ContractRegistry(MockRegistrySource(domain=domain_1))
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def registry_2(domain_2, test_registry):
|
||||
return ContractRegistry(MockRegistrySource(domain=domain_2))
|
||||
|
||||
|
||||
def test_learner_learns_about_domains_separately(
|
||||
lonely_ursula_maker, domain_1, domain_2, registry_1, registry_2, caplog
|
||||
):
|
||||
hero_learner, other_first_domain_learner = lonely_ursula_maker(
|
||||
domain="nucypher1.test_suite", quantity=2
|
||||
domain=domain_1,
|
||||
registry=registry_1,
|
||||
quantity=2,
|
||||
)
|
||||
_nobody = lonely_ursula_maker(domain="nucypher1.test_suite", quantity=1).pop()
|
||||
_nobody = lonely_ursula_maker(
|
||||
domain=domain_1, registry=registry_1, quantity=1
|
||||
).pop()
|
||||
other_first_domain_learner.remember_node(_nobody)
|
||||
|
||||
second_domain_learners = lonely_ursula_maker(domain="nucypher2.test_suite", know_each_other=True, quantity=3)
|
||||
second_domain_learners = lonely_ursula_maker(
|
||||
domain=domain_2, registry=registry_2, know_each_other=True, quantity=3
|
||||
)
|
||||
|
||||
assert len(hero_learner.known_nodes) == 0
|
||||
|
||||
|
@ -36,8 +76,12 @@ def test_learner_learns_about_domains_separately(lonely_ursula_maker, caplog):
|
|||
# All domain 1 nodes
|
||||
assert len(hero_learner.known_nodes) == 2
|
||||
|
||||
new_first_domain_learner = lonely_ursula_maker(domain="nucypher1.test_suite", quantity=1).pop()
|
||||
_new_second_domain_learner = lonely_ursula_maker(domain="nucypher2.test_suite", quantity=1).pop()
|
||||
new_first_domain_learner = lonely_ursula_maker(
|
||||
domain=domain_1, registry=registry_1, quantity=1
|
||||
).pop()
|
||||
_new_second_domain_learner = lonely_ursula_maker(
|
||||
domain=domain_2, registry=registry_2, quantity=1
|
||||
).pop()
|
||||
|
||||
new_first_domain_learner.remember_node(hero_learner)
|
||||
|
||||
|
@ -52,7 +96,9 @@ def test_learner_learns_about_domains_separately(lonely_ursula_maker, caplog):
|
|||
assert _nobody in new_first_domain_learner.known_nodes
|
||||
|
||||
|
||||
def test_learner_restores_metadata_from_storage(lonely_ursula_maker, tmpdir):
|
||||
def test_learner_restores_metadata_from_storage(
|
||||
lonely_ursula_maker, tmpdir, domain_1, domain_2
|
||||
):
|
||||
# Create a local file-based node storage
|
||||
root = tmpdir.mkdir("known_nodes")
|
||||
metadata = root.mkdir("metadata")
|
||||
|
@ -62,20 +108,24 @@ def test_learner_restores_metadata_from_storage(lonely_ursula_maker, tmpdir):
|
|||
storage_root=Path(root))
|
||||
|
||||
# Use the ursula maker with this storage so it's populated with nodes from one domain
|
||||
_some_ursulas = lonely_ursula_maker(domain="fistro",
|
||||
node_storage=old_storage,
|
||||
know_each_other=True,
|
||||
quantity=3,
|
||||
save_metadata=True)
|
||||
_some_ursulas = lonely_ursula_maker(
|
||||
domain=domain_1,
|
||||
node_storage=old_storage,
|
||||
know_each_other=True,
|
||||
quantity=3,
|
||||
save_metadata=True,
|
||||
)
|
||||
|
||||
# Create a pair of new learners in a different domain, using the previous storage, and learn from it
|
||||
new_learners = lonely_ursula_maker(domain="duodenal",
|
||||
node_storage=old_storage,
|
||||
quantity=2,
|
||||
know_each_other=True,
|
||||
save_metadata=False)
|
||||
new_learners = lonely_ursula_maker(
|
||||
domain=domain_2,
|
||||
node_storage=old_storage,
|
||||
quantity=2,
|
||||
know_each_other=True,
|
||||
save_metadata=False,
|
||||
)
|
||||
learner, buddy = new_learners
|
||||
buddy._Learner__known_nodes = FleetSensor(domain="fistro")
|
||||
buddy._Learner__known_nodes = FleetSensor(domain=domain_1)
|
||||
|
||||
# The learner shouldn't learn about any node from the first domain, since it's different.
|
||||
learner.learn_from_teacher_node()
|
||||
|
@ -88,11 +138,19 @@ def test_learner_restores_metadata_from_storage(lonely_ursula_maker, tmpdir):
|
|||
|
||||
|
||||
def test_learner_ignores_stored_nodes_from_other_domains(
|
||||
lonely_ursula_maker, tmpdir, testerchain, ursula_test_config
|
||||
lonely_ursula_maker,
|
||||
domain_1,
|
||||
domain_2,
|
||||
registry_1,
|
||||
registry_2,
|
||||
tmpdir,
|
||||
testerchain,
|
||||
ursula_test_config,
|
||||
):
|
||||
learner, other_staker = make_ursulas(
|
||||
ursula_test_config,
|
||||
domain="call-it-mainnet",
|
||||
domain=domain_1,
|
||||
registry=registry_1,
|
||||
quantity=2,
|
||||
know_each_other=True,
|
||||
staking_provider_addresses=testerchain.stake_providers_accounts[:2],
|
||||
|
@ -101,7 +159,8 @@ def test_learner_ignores_stored_nodes_from_other_domains(
|
|||
|
||||
pest, *other_ursulas_from_the_wrong_side_of_the_tracks = make_ursulas(
|
||||
ursula_test_config,
|
||||
domain="i-dunno-testt-maybe",
|
||||
domain=domain_2,
|
||||
registry=registry_2,
|
||||
quantity=5,
|
||||
know_each_other=True,
|
||||
staking_provider_addresses=testerchain.stake_providers_accounts[2:],
|
||||
|
@ -129,13 +188,16 @@ def test_learner_ignores_stored_nodes_from_other_domains(
|
|||
assert pest not in other_staker.known_nodes # But not anymore.
|
||||
|
||||
|
||||
def test_learner_with_empty_storage_uses_fallback_nodes(lonely_ursula_maker, mocker):
|
||||
domain = "learner-domain"
|
||||
mocker.patch.dict(TEACHER_NODES, {domain: ("teacher-uri",)}, clear=True)
|
||||
def test_learner_with_empty_storage_uses_fallback_nodes(
|
||||
lonely_ursula_maker, domain_1, mocker
|
||||
):
|
||||
mocker.patch.dict(TEACHER_NODES, {domain_1: ("teacher-uri",)}, clear=True)
|
||||
|
||||
# Create a learner and a teacher
|
||||
learner, teacher = lonely_ursula_maker(domain=domain, quantity=2, save_metadata=False)
|
||||
mocker.patch.object(Ursula, 'from_teacher_uri', return_value=teacher)
|
||||
learner, teacher = lonely_ursula_maker(
|
||||
domain=domain_1, quantity=2, save_metadata=False
|
||||
)
|
||||
mocker.patch.object(Ursula, "from_teacher_uri", return_value=teacher)
|
||||
|
||||
# Since there are no nodes in local node storage, the learner should only learn about the teacher
|
||||
learner.learn_from_teacher_node()
|
||||
|
@ -143,10 +205,16 @@ def test_learner_with_empty_storage_uses_fallback_nodes(lonely_ursula_maker, moc
|
|||
|
||||
|
||||
def test_learner_uses_both_nodes_from_storage_and_fallback_nodes(
|
||||
lonely_ursula_maker, tmpdir, mocker, test_registry, ursula_test_config, testerchain
|
||||
lonely_ursula_maker,
|
||||
domain_1,
|
||||
registry_1,
|
||||
tmpdir,
|
||||
mocker,
|
||||
test_registry,
|
||||
ursula_test_config,
|
||||
testerchain,
|
||||
):
|
||||
domain = "learner-domain"
|
||||
mocker.patch.dict(TEACHER_NODES, {domain: ("teacher-uri",)}, clear=True)
|
||||
mocker.patch.dict(TEACHER_NODES, {domain_1: ("teacher-uri",)}, clear=True)
|
||||
|
||||
# Create a local file-based node storage
|
||||
root = tmpdir.mkdir("known_nodes")
|
||||
|
@ -159,7 +227,8 @@ def test_learner_uses_both_nodes_from_storage_and_fallback_nodes(
|
|||
# Create some nodes and persist them to local storage
|
||||
other_nodes = make_ursulas(
|
||||
ursula_test_config,
|
||||
domain=domain,
|
||||
domain=domain_1,
|
||||
registry=registry_1,
|
||||
node_storage=node_storage,
|
||||
know_each_other=True,
|
||||
quantity=3,
|
||||
|
@ -170,7 +239,8 @@ def test_learner_uses_both_nodes_from_storage_and_fallback_nodes(
|
|||
|
||||
# Create a teacher and a learner using existing node storage
|
||||
learner, teacher = lonely_ursula_maker(
|
||||
domain=domain,
|
||||
domain=domain_1,
|
||||
registry=registry_1,
|
||||
node_storage=node_storage,
|
||||
quantity=2,
|
||||
know_each_other=True,
|
||||
|
|
|
@ -3,15 +3,18 @@ from functools import partial
|
|||
import pytest_twisted as pt
|
||||
from twisted.internet.threads import deferToThread
|
||||
|
||||
from nucypher.config.constants import TEMPORARY_DOMAIN
|
||||
from nucypher.network.middleware import RestMiddleware
|
||||
from tests.constants import MOCK_ETH_PROVIDER_URI
|
||||
|
||||
|
||||
def test_proper_seed_node_instantiation(lonely_ursula_maker):
|
||||
_lonely_ursula_maker = partial(lonely_ursula_maker, quantity=1)
|
||||
firstula = _lonely_ursula_maker(domain="this-is-meaningful-now").pop()
|
||||
firstula = _lonely_ursula_maker(domain=TEMPORARY_DOMAIN).pop()
|
||||
firstula_as_seed_node = firstula.seed_node_metadata()
|
||||
any_other_ursula = _lonely_ursula_maker(seed_nodes=[firstula_as_seed_node], domain="this-is-meaningful-now").pop()
|
||||
any_other_ursula = _lonely_ursula_maker(
|
||||
seed_nodes=[firstula_as_seed_node], domain=TEMPORARY_DOMAIN
|
||||
).pop()
|
||||
|
||||
assert not any_other_ursula.known_nodes
|
||||
any_other_ursula.start_learning_loop(now=True)
|
||||
|
|
|
@ -20,13 +20,22 @@ from nucypher.config.constants import TEMPORARY_DOMAIN
|
|||
|
||||
|
||||
@contextmanager
|
||||
def mock_registry_sources(mocker):
|
||||
test_domain = TACoDomain(
|
||||
TEMPORARY_DOMAIN, EthChain.TESTERCHAIN, PolygonChain.TESTERCHAIN
|
||||
)
|
||||
def mock_registry_sources(mocker, domain_names: List[str] = None):
|
||||
if not domain_names:
|
||||
domain_names = [TEMPORARY_DOMAIN]
|
||||
|
||||
mocker.patch.object(domains, "SUPPORTED_DOMAINS", [test_domain])
|
||||
mocker.patch.object(domains, "SUPPORTED_DOMAIN_NAMES", [TEMPORARY_DOMAIN])
|
||||
supported_domains = []
|
||||
supported_domain_names = []
|
||||
for domain_name in domain_names:
|
||||
test_domain = TACoDomain(
|
||||
domain_name, EthChain.TESTERCHAIN, PolygonChain.TESTERCHAIN
|
||||
)
|
||||
supported_domains.append(test_domain)
|
||||
supported_domain_names.append(domain_name)
|
||||
|
||||
mocker.patch.object(domains, "SUPPORTED_DOMAINS", supported_domains)
|
||||
mocker.patch.object(domains, "SUPPORTED_DOMAIN_NAMES", supported_domain_names)
|
||||
mocker.patch.object(MockRegistrySource, "ALLOWED_DOMAINS", domain_names)
|
||||
|
||||
mocker.patch.object(RegistrySourceManager, "_FALLBACK_CHAIN", (MockRegistrySource,))
|
||||
|
||||
|
@ -34,15 +43,17 @@ def mock_registry_sources(mocker):
|
|||
|
||||
|
||||
class MockRegistrySource(RegistrySource):
|
||||
ALLOWED_DOMAINS = [TEMPORARY_DOMAIN]
|
||||
|
||||
name = "Mock Registry Source"
|
||||
is_primary = False
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
if self.domain != TEMPORARY_DOMAIN:
|
||||
if self.domain not in self.ALLOWED_DOMAINS:
|
||||
raise ValueError(
|
||||
f"Somehow, MockRegistrySource is trying to get a registry for '{self.domain}'. "
|
||||
f"Only '{TEMPORARY_DOMAIN}' is supported.'"
|
||||
f"Only '{','.join(self.ALLOWED_DOMAINS)}' are supported.'"
|
||||
)
|
||||
|
||||
@property
|
||||
|
|
Loading…
Reference in New Issue