From 6ece74cb00bf8b842528ae318c7a1a3e5f765c28 Mon Sep 17 00:00:00 2001 From: derekpierre Date: Thu, 22 Aug 2019 16:40:45 +0200 Subject: [PATCH] Auto-detect 'file' uri scheme when an ipc file path is provided without a scheme and exists. This allows for auto-completion for file paths passed as --provider. --- nucypher/blockchain/eth/interfaces.py | 12 +++- .../eth/clients/test_mocked_clients.py | 71 +++++++++++++++++++ 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/nucypher/blockchain/eth/interfaces.py b/nucypher/blockchain/eth/interfaces.py index 0a2d3e2d8..dc0f6e7ca 100644 --- a/nucypher/blockchain/eth/interfaces.py +++ b/nucypher/blockchain/eth/interfaces.py @@ -14,7 +14,7 @@ GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with nucypher. If not, see . """ - +import os import pprint import time from typing import List @@ -55,8 +55,8 @@ from nucypher.blockchain.eth.providers import ( ) from nucypher.blockchain.eth.registry import EthereumContractRegistry from nucypher.blockchain.eth.sol.compile import SolidityCompiler -from nucypher.crypto.powers import TransactingPower from nucypher.characters.control.emitters import StdoutEmitter +from nucypher.crypto.powers import TransactingPower Web3Providers = Union[IPCProvider, WebsocketProvider, HTTPProvider, EthereumTester] @@ -334,6 +334,14 @@ class BlockchainInterface: 'https': _get_HTTP_provider, } provider_scheme = uri_breakdown.scheme + + # auto-detect for file based ipc + if not provider_scheme: + if os.path.exists(provider_uri): + # file is available - assume ipc/file scheme + self.log.info(f"Auto-detecting provider scheme as 'file://' for provider {provider_uri}") + provider_scheme = 'file' + try: self._provider = providers[provider_scheme](provider_uri) except KeyError: diff --git a/tests/blockchain/eth/clients/test_mocked_clients.py b/tests/blockchain/eth/clients/test_mocked_clients.py index eedf595c9..a4bbd88be 100644 --- a/tests/blockchain/eth/clients/test_mocked_clients.py +++ b/tests/blockchain/eth/clients/test_mocked_clients.py @@ -1,5 +1,7 @@ import datetime + import pytest +from web3 import HTTPProvider, IPCProvider from nucypher.blockchain.eth.clients import ( Web3Client, @@ -154,6 +156,26 @@ class BlockchainInterfaceTestBase(BlockchainInterface): pass +class ProviderTypeTestClient(BlockchainInterfaceTestBase): + def __init__(self, + expected_provider_class, + actual_provider_to_attach, + *args, + **kwargs): + BlockchainInterfaceTestBase.__init__(self, *args, **kwargs) + self.expected_provider_class = expected_provider_class + self.test_provider_to_attach = actual_provider_to_attach + + def _attach_provider(self, *args, **kwargs) -> None: + super()._attach_provider(*args, **kwargs) + + if self.expected_provider_class is not None: + # check type + assert self.expected_provider_class == self.provider.__class__ + + super()._attach_provider(provider=self.test_provider_to_attach) + + class InfuraTestClient(BlockchainInterfaceTestBase): def _attach_provider(self, *args, **kwargs) -> None: @@ -199,6 +221,55 @@ def test_geth_web3_client(): assert interface.client.chain_id == 5 # Hardcoded above +def test_autodetect_provider_type_file(tempfile_path): + + interface = ProviderTypeTestClient(provider_uri=tempfile_path, # existing file for test + expected_provider_class=IPCProvider, + actual_provider_to_attach=MockGethProvider()) + interface.connect(fetch_registry=False, sync_now=False) + assert isinstance(interface.client, GethClient) + + +def test_autodetect_provider_type_file_none_existent(): + with pytest.raises(ValueError) as e: + interface = BlockchainInterfaceTestBase(provider_uri='/none_existent.ipc.geth') + interface.connect(fetch_registry=False, sync_now=False) + + assert "invalid or unsupported blockchain provider URI" in str(e) + + +def test_detect_provider_type_file(): + interface = ProviderTypeTestClient(provider_uri='file:///ipc.geth', + expected_provider_class=IPCProvider, + actual_provider_to_attach=MockGethProvider()) + interface.connect(fetch_registry=False, sync_now=False) + assert isinstance(interface.client, GethClient) + + +def test_detect_provider_type_ipc(): + interface = ProviderTypeTestClient(provider_uri='ipc:///ipc.geth', + expected_provider_class=IPCProvider, + actual_provider_to_attach=MockGethProvider()) + interface.connect(fetch_registry=False, sync_now=False) + assert isinstance(interface.client, GethClient) + + +def test_detect_provider_type_http(): + interface = ProviderTypeTestClient(provider_uri='http://ganache:8445', + expected_provider_class=HTTPProvider, + actual_provider_to_attach=MockGanacheProvider()) + interface.connect(fetch_registry=False, sync_now=False) + assert isinstance(interface.client, GanacheClient) + + +def test_detect_provider_type_https(): + interface = ProviderTypeTestClient(provider_uri='https://ganache:8445', + expected_provider_class=HTTPProvider, + actual_provider_to_attach=MockGanacheProvider()) + interface.connect(fetch_registry=False, sync_now=False) + assert isinstance(interface.client, GanacheClient) + + def test_infura_web3_client(): interface = InfuraTestClient(provider_uri='infura://1234567890987654321abcdef') interface.connect(fetch_registry=False, sync_now=False)