Merge branch 'dev', v0.6.40

94b79ca - forgot to remove test for linux keep alive
0267bb6 - update travis config for container upgrade
9f3a213 - bump to v0.6.40
8605f74 - removed linux specific socket keepalive settings
18be87d - IS: added connection related logger lines
This commit is contained in:
Rossen Georgiev 2015-08-10 15:32:27 +01:00
commit 7b67a259a1
5 changed files with 18 additions and 26 deletions

View File

@ -1,4 +1,5 @@
language: python language: python
sudo: false
python: python:
- "2.6" - "2.6"
- "2.7" - "2.7"

View File

@ -22,7 +22,6 @@ import socket
import select import select
import time import time
import logging import logging
import sys
from . import __version__, string_type, is_py3 from . import __version__, string_type, is_py3
from .parsing import parse from .parsing import parse
@ -114,10 +113,11 @@ class IS(object):
self._connect() self._connect()
self._send_login() self._send_login()
break break
except: except (LoginError, ConnectionError):
if not blocking: if not blocking:
raise raise
self.logger.info("Retrying connection is %d seconds." % retry)
time.sleep(retry) time.sleep(retry)
def close(self): def close(self):
@ -235,14 +235,6 @@ class IS(object):
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1) self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
if sys.platform not in ['cygwin', 'win32']:
# these things don't exist in socket under Windows
# pylint: disable=E1103
self.sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPIDLE, 15)
self.sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPCNT, 3)
self.sock.setsockopt(socket.SOL_TCP, socket.TCP_KEEPINTVL, 5)
# pylint: enable=E1103
banner = self.sock.recv(512) banner = self.sock.recv(512)
if is_py3: if is_py3:
banner = banner.decode('latin-1') banner = banner.decode('latin-1')
@ -252,12 +244,14 @@ class IS(object):
else: else:
raise ConnectionError("invalid banner from server") raise ConnectionError("invalid banner from server")
except ConnectionError: except ConnectionError as e:
self.logger.error(str(e))
self.close() self.close()
raise raise
except (socket.error, socket.timeout) as e: except (socket.error, socket.timeout) as e:
self.close() self.close()
self.logger.error("Socket error: %s" % str(e))
if str(e) == "timed out": if str(e) == "timed out":
raise ConnectionError("no banner from server") raise ConnectionError("no banner from server")
else: else:
@ -303,12 +297,14 @@ class IS(object):
else: else:
self.logger.info("Login successful") self.logger.info("Login successful")
except LoginError: except LoginError as e:
self.logger.error(str(e))
self.close() self.close()
raise raise
except: except:
self.close() self.close()
raise LoginError("failed to login") self.logger.error("Failed to login")
raise LoginError("Failed to login")
def _socket_readlines(self, blocking=False): def _socket_readlines(self, blocking=False):
""" """
@ -317,6 +313,7 @@ class IS(object):
try: try:
self.sock.setblocking(0) self.sock.setblocking(0)
except socket.error as e: except socket.error as e:
self.logger.error("socket error when setblocking(0): %s" % str(e))
raise ConnectionDrop("connection dropped") raise ConnectionDrop("connection dropped")
while True: while True:
@ -330,8 +327,10 @@ class IS(object):
# sock.recv returns empty if the connection drops # sock.recv returns empty if the connection drops
if not short_buf: if not short_buf:
self.logger.error("socket.recv(): returned empty")
raise ConnectionDrop("connection dropped") raise ConnectionDrop("connection dropped")
except socket.error as e: except socket.error as e:
self.logger.error("socket error on recv(): %s" % str(e))
if "Resource temporarily unavailable" in str(e): if "Resource temporarily unavailable" in str(e):
if not blocking: if not blocking:
if len(self.buf) == 0: if len(self.buf) == 0:

View File

@ -50,7 +50,7 @@ from datetime import date as _date
__date__ = str(_date.today()) __date__ = str(_date.today())
del _date del _date
__version__ = "0.6.39" __version__ = "0.6.40"
__author__ = "Rossen Georgiev" __author__ = "Rossen Georgiev"
__all__ = ['IS', 'parse', 'passcode'] __all__ = ['IS', 'parse', 'passcode']

View File

@ -35,7 +35,7 @@ except ImportError:
return {'confidence': 0.0, 'encoding': 'windows-1252'} return {'confidence': 0.0, 'encoding': 'windows-1252'}
from .exceptions import (UnknownFormat, ParseError) from .exceptions import (UnknownFormat, ParseError)
from . import base91, string_type_parse, is_py3 from . import base91, string_type_parse
__all__ = ['parse'] __all__ = ['parse']
@ -98,7 +98,7 @@ def parse(packet):
""" """
if not isinstance(packet, string_type_parse): if not isinstance(packet, string_type_parse):
raise TypeError("Epected packet to be str/unicode/bytes, got %s", type(packet)) raise TypeError("Expected packet to be str/unicode/bytes, got %s", type(packet))
# attempt to detect encoding # attempt to detect encoding
if isinstance(packet, bytes): if isinstance(packet, bytes):

View File

@ -169,10 +169,6 @@ class TC_IS(unittest.TestCase):
self.ais.sock.setblocking(mox.IgnoreArg()) self.ais.sock.setblocking(mox.IgnoreArg())
self.ais.sock.settimeout(mox.IgnoreArg()) self.ais.sock.settimeout(mox.IgnoreArg())
self.ais.sock.setsockopt(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()) self.ais.sock.setsockopt(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
if sys.platform not in ['cygwin', 'win32']:
self.ais.sock.setsockopt(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
self.ais.sock.setsockopt(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
self.ais.sock.setsockopt(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
self.ais.sock.recv(mox.IgnoreArg()).AndReturn(b"junk") self.ais.sock.recv(mox.IgnoreArg()).AndReturn(b"junk")
self.ais.close() self.ais.close()
# part 3 - everything going well # part 3 - everything going well
@ -181,10 +177,6 @@ class TC_IS(unittest.TestCase):
self.ais.sock.setblocking(mox.IgnoreArg()) self.ais.sock.setblocking(mox.IgnoreArg())
self.ais.sock.settimeout(mox.IgnoreArg()) self.ais.sock.settimeout(mox.IgnoreArg())
self.ais.sock.setsockopt(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()) self.ais.sock.setsockopt(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
if sys.platform not in ['cygwin', 'win32']:
self.ais.sock.setsockopt(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
self.ais.sock.setsockopt(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
self.ais.sock.setsockopt(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
self.ais.sock.recv(mox.IgnoreArg()).AndReturn(b"# server banner") self.ais.sock.recv(mox.IgnoreArg()).AndReturn(b"# server banner")
mox.Replay(self.ais.sock) mox.Replay(self.ais.sock)
self.m.ReplayAll() self.m.ReplayAll()
@ -252,9 +244,9 @@ class TC_IS(unittest.TestCase):
def test_connect_raising_exceptions(self): def test_connect_raising_exceptions(self):
self.m.StubOutWithMock(self.ais, "_connect") self.m.StubOutWithMock(self.ais, "_connect")
self.m.StubOutWithMock(self.ais, "_send_login") self.m.StubOutWithMock(self.ais, "_send_login")
self.ais._connect().AndRaise(Exception("first")) self.ais._connect().AndRaise(aprslib.exceptions.ConnectionError("first"))
self.ais._connect() self.ais._connect()
self.ais._send_login().AndRaise(Exception("second")) self.ais._send_login().AndRaise(aprslib.exceptions.LoginError("second"))
self.ais._connect() self.ais._connect()
self.ais._send_login() self.ais._send_login()
self.m.ReplayAll() self.m.ReplayAll()