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
derekpierre 2023-10-04 13:12:30 -04:00
parent 9708efb0ba
commit 568270d36c
4 changed files with 130 additions and 44 deletions

View File

@ -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."
},

View File

@ -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,

View File

@ -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)

View File

@ -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