Skip to content

Commit 65459e6

Browse files
committed
1.4.1 - Catch NXDOMAIN, plus travis install iputils-ping
Plus check for 'network is unreachable' when pinging, because travis-ci doesn't like IPv6... Raise a warning if test_ping / test_ping_v6 fails due to NetworkUnreachable, to avoid full test suite failure due to lack of IPv4 / IPv6
1 parent e678cac commit 65459e6

5 files changed

Lines changed: 29 additions & 7 deletions

File tree

.travis.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ python:
1010
- "3.7-dev"
1111
- "3.8-dev"
1212
- "nightly"
13+
before_install:
14+
- sudo apt-get update -qy
15+
- sudo apt-get install -qy iputils-ping
1316
install:
1417
- pip install -r docs/requirements.txt
1518
- pip install .

privex/helpers/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ def _setup_logging(level=logging.WARNING):
8383
log = _setup_logging()
8484
name = 'helpers'
8585

86-
VERSION = '1.4.0'
86+
VERSION = '1.4.1'
8787

8888

8989

privex/helpers/exceptions.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,11 @@ class NotConfigured(PrivexException):
9898
9999
Example: Attempting to use a database dependant function/method without having configured any database details.
100100
"""
101+
102+
103+
class NetworkUnreachable(PrivexException):
104+
"""
105+
Thrown when a network interface or IP version (e.g. IPv4/v6) is unavailable.
106+
107+
Example: when running ``ping`` with an IPv6 address on a system which has no IPv6.
108+
"""

privex/helpers/net.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@
4040
import logging
4141
import platform
4242
import subprocess
43-
from privex.helpers.exceptions import BoundaryException
43+
from privex.helpers.exceptions import BoundaryException, NetworkUnreachable
4444
from privex.helpers import plugin
4545
from ipaddress import ip_address, IPv4Address, IPv6Address
4646
from typing import Union
4747

4848
log = logging.getLogger(__name__)
4949

5050
try:
51-
from dns.resolver import Resolver, NoAnswer
51+
from dns.resolver import Resolver, NoAnswer, NXDOMAIN
5252

5353
def asn_to_name(as_number: Union[int, str], quiet: bool = True) -> str:
5454
"""
@@ -83,7 +83,7 @@ def asn_to_name(as_number: Union[int, str], quiet: bool = True) -> str:
8383
asname = str(res[0]).strip('"').split('|')[-1:][0].strip()
8484
return str(asname)
8585
raise NoAnswer('privex.helpers.net.asn_to_name returned no results.')
86-
except NoAnswer:
86+
except (NoAnswer, NXDOMAIN):
8787
if quiet:
8888
return 'Unknown ASN'
8989
raise KeyError('ASN {} was not found, or server did not respond.'.format(as_number))
@@ -262,5 +262,10 @@ def ping(ip: str, timeout: int = 30) -> bool:
262262
if platform.system() not in opts:
263263
raise NotImplementedError(f"{__name__}.ping is not fully supported on platform '{platform.system()}'...")
264264

265-
with subprocess.Popen(opts[platform.system()] + [ip], stdout=subprocess.PIPE) as proc:
266-
return 'bytes from {}'.format(ip) in proc.stdout.read().decode('utf-8')
265+
with subprocess.Popen(opts[platform.system()] + [ip], stdout=subprocess.PIPE, stderr=subprocess.PIPE) as proc:
266+
out, err = proc.communicate()
267+
err = err.decode('utf-8')
268+
if 'network is unreachable' in err.lower():
269+
raise NetworkUnreachable(f'Got error from ping: "{err}"')
270+
271+
return 'bytes from {}'.format(ip) in out.decode('utf-8')

tests/test_general.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
import warnings
4343

4444
from privex import helpers
45-
from privex.helpers import ping
45+
from privex.helpers import ping, NetworkUnreachable
4646
from tests.base import PrivexBaseCase
4747

4848

@@ -66,6 +66,9 @@ def test_ping(self):
6666
except NotImplementedError as e:
6767
warnings.warn(f"Skipping test TestGeneral.test_ping as platform is not supported: {str(e)}")
6868
return
69+
except NetworkUnreachable as e:
70+
warnings.warn(f"Skipping test TestGeneral.test_ping as network is unavailable: \"{str(e)}\"")
71+
return
6972

7073
def test_ping_v6(self):
7174
"""Test success & failure cases for ping function with IPv6, as well as input validation"""
@@ -81,6 +84,9 @@ def test_ping_v6(self):
8184
except NotImplementedError as e:
8285
warnings.warn(f"Skipping test TestGeneral.test_ping_v6 as platform is not supported: \"{str(e)}\"")
8386
return
87+
except NetworkUnreachable as e:
88+
warnings.warn(f"Skipping test TestGeneral.test_ping_v6 as network is unavailable: \"{str(e)}\"")
89+
return
8490

8591
def _check_asn(self, asn, expected_name):
8692
if not helpers.plugin.HAS_DNSPYTHON:

0 commit comments

Comments
 (0)