Skip to content

Commit

Permalink
Bug Fix: verbose_ping prints proper message on error.
Browse files Browse the repository at this point in the history
  • Loading branch information
kyan001 committed Aug 9, 2021
1 parent c2e4a0e commit c9cd2ce
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 35 deletions.
2 changes: 2 additions & 0 deletions UPDATES.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# UPDATES
* 3.0.1:
* Bug Fix: `verbose_ping` prints proper message on error.
* 3.0.0:
* Backward Compatibility: Only Command-line options changed, now the options is more like `ping` on macOS and Linux.
* `-w`/`--wait` -> `-t`/`--timeout`.
Expand Down
12 changes: 7 additions & 5 deletions ping3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from . import errors
from .enums import ICMP_DEFAULT_CODE, IcmpType, IcmpTimeExceededCode, IcmpDestinationUnreachableCode

__version__ = "3.0.0"
__version__ = "3.0.1"
DEBUG = False # DEBUG: Show debug info for developers. (default False)
EXCEPTIONS = False # EXCEPTIONS: Raise exception when delay is not available.
LOGGER = None # LOGGER: Record logs into console or file.
Expand Down Expand Up @@ -265,7 +265,7 @@ def ping(dest_addr: str, timeout: int = 4, unit: str = "s", src_addr: str = None
size: The ICMP packet payload size in bytes. If the input of this is less than the bytes of a double format (usually 8), the size of ICMP packet payload is 8 bytes to hold a time. The max should be the router_MTU(Usually 1480) - IP_Header(20) - ICMP_Header(8). Default is 56, same as in macOS. (default 56)
Returns:
The delay in seconds/milliseconds or None on timeout.
The delay in seconds/milliseconds, False on error and None on timeout.
Raises:
PingError: Any PingError will raise again if `ping3.EXCEPTIONS` is True.
Expand Down Expand Up @@ -302,14 +302,14 @@ def ping(dest_addr: str, timeout: int = 4, unit: str = "s", src_addr: str = None
try:
send_one_ping(sock=sock, dest_addr=dest_addr, icmp_id=icmp_id, seq=seq, size=size)
delay = receive_one_ping(sock=sock, icmp_id=icmp_id, seq=seq, timeout=timeout) # in seconds
except errors.HostUnknown as err: # Unsolved
except errors.Timeout as err:
_debug(err)
_raise(err)
return False
return None
except errors.PingError as err:
_debug(err)
_raise(err)
return None
return False
if delay is None:
return None
if unit == "ms":
Expand Down Expand Up @@ -345,6 +345,8 @@ def verbose_ping(dest_addr: str, count: int = 4, interval: float = 0, *args, **k
print(output_text, end="")
if delay is None:
print("Timeout > {}s".format(timeout) if timeout else "Timeout")
elif delay is False:
print("Error")
else:
print("{value}{unit}".format(value=int(delay), unit=unit))
i += 1
66 changes: 36 additions & 30 deletions tests/test_ping3.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def tearDown(self):
pass

def test_version(self):
self.assertTrue(isinstance(ping3.__version__, str))
self.assertIsInstance(ping3.__version__, str)

def test_ping_normal(self):
delay = ping3.ping("example.com")
Expand All @@ -47,10 +47,18 @@ def test_verbose_ping_timeout(self):
self.assertRegex(fake_out.getvalue(), r".*Timeout \> [0-9\.]+s.*")

def test_verbose_ping_timeout_exception(self):
with patch("sys.stdout", new=io.StringIO()):
with patch("ping3.EXCEPTIONS", True):
with self.assertRaises(errors.Timeout):
ping3.verbose_ping("example.com", timeout=0.0001)
with patch("ping3.EXCEPTIONS", True):
with self.assertRaises(errors.Timeout):
ping3.verbose_ping("example.com", timeout=0.0001)

def test_ping_error(self):
delay = ping3.ping("not.exist.com")
self.assertFalse(delay)

def test_ping_error_exception(self):
with patch("ping3.EXCEPTIONS", True):
with self.assertRaises(errors.HostUnknown):
ping3.ping("not.exist.com")

def test_ping_seq(self):
delay = ping3.ping("example.com", seq=199)
Expand All @@ -59,15 +67,19 @@ def test_ping_seq(self):
def test_ping_size(self):
delay = ping3.ping("example.com", size=100)
self.assertIsInstance(delay, float)

def test_ping_size_exception(self):
with self.assertRaises(OSError):
ping3.ping("example.com", size=99999) # most router has 1480 MTU, which is IP_Header(20) + ICMP_Header(8) + ICMP_Payload(1452)

def test_verbose_ping_size(self):
with patch("sys.stdout", new=io.StringIO()) as fake_out:
ping3.verbose_ping("example.com", size=100)
self.assertRegex(fake_out.getvalue(), r".*[0-9]+ms.*")
with self.assertRaises(OSError):
ping3.ping("example.com", size=99999)

def test_verbose_ping_size_exception(self):
with self.assertRaises(OSError):
ping3.verbose_ping("example.com", size=99999)

def test_ping_unit(self):
delay = ping3.ping("example.com", unit="ms")
Expand Down Expand Up @@ -114,24 +126,26 @@ def test_verbose_ping_interface(self):

def test_ping_src_addr(self):
my_ip = socket.gethostbyname(socket.gethostname())
dest_addr = "example.com"
if my_ip == "127.0.0.1" or my_ip == "127.0.1.1": # This may caused by /etc/hosts settings.
if my_ip in ("127.0.0.1", "127.0.1.1"): # This may caused by /etc/hosts settings.
dest_addr = my_ip # only localhost can send and receive from 127.0.0.1 (or 127.0.1.1 on Ubuntu).
else:
dest_addr = "example.com"
delay = ping3.ping(dest_addr, src_addr=my_ip)
self.assertIsInstance(delay, float)

def test_verbose_ping_src_addr(self):
with patch("sys.stdout", new=io.StringIO()) as fake_out:
my_ip = socket.gethostbyname(socket.gethostname())
dest_addr = "example.com"
if my_ip == "127.0.0.1" or my_ip == "127.0.1.1": # This may caused by /etc/hosts settings.
if my_ip in ("127.0.0.1", "127.0.1.1"): # This may caused by /etc/hosts settings.
dest_addr = my_ip # only localhost can send and receive from 127.0.0.1 (or 127.0.1.1 on Ubuntu).
else:
dest_addr = "example.com"
ping3.verbose_ping(dest_addr, src_addr=my_ip)
self.assertRegex(fake_out.getvalue(), r".*[0-9]+ms.*")

def test_ping_ttl(self):
delay = ping3.ping("example.com", ttl=1)
self.assertIsNone(delay)
self.assertIn(delay, (None, False)) # When TTL expired, some routers report nothing.

def test_ping_ttl_exception(self):
with patch("ping3.EXCEPTIONS", True):
Expand All @@ -141,12 +155,12 @@ def test_ping_ttl_exception(self):
def test_verbose_ping_ttl(self):
with patch("sys.stdout", new=io.StringIO()) as fake_out:
ping3.verbose_ping("example.com", ttl=1)
self.assertRegex(fake_out.getvalue(), r".*Timeout.*")
self.assertNotRegex(fake_out.getvalue(), r".*[0-9]+ms.*")

def test_verbose_ping_ttl_exception(self):
with patch("sys.stdout", new=io.StringIO()) as fake_out:
ping3.verbose_ping("example.com", ttl=1)
self.assertRegex(fake_out.getvalue(), r".*Timeout.*")
with patch("ping3.EXCEPTIONS", True):
with self.assertRaises((errors.TimeToLiveExpired, errors.Timeout)): # When TTL expired, some routers report nothing.
ping3.verbose_ping("example.com", ttl=1)

def test_verbose_ping_count(self):
with patch("sys.stdout", new=io.StringIO()) as fake_out:
Expand All @@ -155,22 +169,14 @@ def test_verbose_ping_count(self):

def test_verbose_ping_interval(self):
with patch("sys.stdout", new=io.StringIO()) as fake_out:
delay = ping3.ping("example.com")
self.assertIsInstance(delay, float)
self.assertTrue(0 < delay < 0.75) # If interval does not work, the total delay should be < 3s (4 * 0.75s)
start_time = time.time()
ping3.verbose_ping("example.com", interval=1.7)
ping3.verbose_ping("example.com", interval=1) # If interval does work, the total delay should be > 3s (3 * 1s)
end_time = time.time()
self.assertTrue((end_time - start_time) >= 5.1) # time_expect = (count - 1) * interval
self.assertFalse('Timeout' in fake_out.getvalue())

def test_ping_hostunknown(self):
not_exist_url = "not-exist.com"
with patch("sys.stdout", new=io.StringIO()) as fake_out:
self.assertFalse(ping3.ping(not_exist_url))

def test_ping_hostunknown_exception(self):
with patch("sys.stdout", new=io.StringIO()):
with patch("ping3.EXCEPTIONS", True):
with self.assertRaises(errors.HostUnknown):
ping3.ping("not-exist.com")
self.assertTrue((end_time - start_time) >= 3) # time_expect = (count - 1) * interval
self.assertRegex(fake_out.getvalue(), r".*[0-9]+.*")

def test_DEBUG(self):
with patch("ping3.DEBUG", True), patch("sys.stderr", new=io.StringIO()):
Expand Down

0 comments on commit c9cd2ce

Please sign in to comment.