diff options
| -rw-r--r-- | src/leap/base/checks.py | 139 | ||||
| -rw-r--r-- | src/leap/base/constants.py | 2 | ||||
| -rw-r--r-- | src/leap/base/exceptions.py | 66 | ||||
| -rw-r--r-- | src/leap/base/network.py | 80 | ||||
| -rw-r--r-- | src/leap/base/tests/test_checks.py | 117 | ||||
| -rw-r--r-- | src/leap/baseapp/eip.py | 2 | ||||
| -rw-r--r-- | src/leap/baseapp/mainwindow.py | 27 | ||||
| -rw-r--r-- | src/leap/baseapp/network.py | 40 | ||||
| -rw-r--r-- | src/leap/baseapp/systray.py | 7 | ||||
| -rw-r--r-- | src/leap/eip/checks.py | 83 | ||||
| -rw-r--r-- | src/leap/eip/exceptions.py | 17 | ||||
| -rw-r--r-- | src/leap/eip/tests/test_checks.py | 61 | ||||
| -rw-r--r-- | src/leap/util/coroutines.py | 8 | 
13 files changed, 486 insertions, 163 deletions
| diff --git a/src/leap/base/checks.py b/src/leap/base/checks.py new file mode 100644 index 00000000..84f9dd46 --- /dev/null +++ b/src/leap/base/checks.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +import logging +import platform + +import netifaces +import ping +import requests + +from leap.base import constants +from leap.base import exceptions + +logger = logging.getLogger(name=__name__) + + +class LeapNetworkChecker(object): +    """ +    all network related checks +    """ +    # #718 +    # XXX get provider gateway as a parameter +    # for constructor. +    # def __init__(self, *args, **kwargs): +    # ... +    #   provider_gw = kwargs.pop('provider_gw', None) +    #   self.provider_gateway = provider_gw + +    def run_all(self, checker=None): +        if not checker: +            checker = self +        self.error = None  # ? + +        # for MVS +        checker.check_tunnel_default_interface() +        checker.check_internet_connection() +        checker.is_internet_up() + +        # XXX We are pinging the default gateway for our connection right? +        # kali: 2012-10-05 20:59 -- I think we should get +        # also the default gateway and ping it instead. +        checker.ping_gateway() + +        # something like: ? +        # see __init__ above +        # if self.provider_gateway: +        #     checker.ping_gateway(self.provider_gateway) + +    def check_internet_connection(self): +        try: +            # XXX remove this hardcoded random ip +            # ping leap.se or eip provider instead...? +            requests.get('http://216.172.161.165') + +        except (requests.HTTPError, requests.RequestException) as e: +            raise exceptions.NoInternetConnection(e.message) +        except requests.ConnectionError as e: +            error = "Unidentified Connection Error" +            if e.message == "[Errno 113] No route to host": +                if not self.is_internet_up(): +                    error = "No valid internet connection found." +                else: +                    error = "Provider server appears to be down." +            logger.error(error) +            raise exceptions.NoInternetConnection(error) +        logger.debug('Network appears to be up.') + +    def is_internet_up(self): +        iface, gateway = self.get_default_interface_gateway() +        self.ping_gateway(self) + +    def check_tunnel_default_interface(self): +        """ +        Raises an TunnelNotDefaultRouteError +        (including when no routes are present) +        """ +        if not platform.system() == "Linux": +            raise NotImplementedError + +        f = open("/proc/net/route") +        route_table = f.readlines() +        f.close() +        #toss out header +        route_table.pop(0) + +        if not route_table: +            raise exceptions.TunnelNotDefaultRouteError() + +        line = route_table.pop(0) +        iface, destination = line.split('\t')[0:2] +        if not destination == '00000000' or not iface == 'tun0': +            raise exceptions.TunnelNotDefaultRouteError() + +    def get_default_interface_gateway(self): +        """only impletemented for linux so far.""" +        if not platform.system() == "Linux": +            raise NotImplementedError + +        # XXX use psutil +        f = open("/proc/net/route") +        route_table = f.readlines() +        f.close() +        #toss out header +        route_table.pop(0) + +        default_iface = None +        gateway = None +        while route_table: +            line = route_table.pop(0) +            iface, destination, gateway = line.split('\t')[0:3] +            if destination == '00000000': +                default_iface = iface +                break + +        if not default_iface: +            raise exceptions.NoDefaultInterfaceFoundError + +        if default_iface not in netifaces.interfaces(): +            raise exceptions.InterfaceNotFoundError + +        return default_iface, gateway + +    def ping_gateway(self, gateway): +        # TODO: Discuss how much packet loss (%) is acceptable. + +        # XXX -- validate gateway +        # -- is it a valid ip? (there's something in util) +        # -- is it a domain? +        # -- can we resolve? -- raise NoDNSError if not. +        packet_loss = ping.quiet_ping(gateway)[0] +        if packet_loss > constants.MAX_ICMP_PACKET_LOSS: +            raise exceptions.NoConnectionToGateway + +     # XXX check for name resolution servers +     # dunno what's the best way to do this... +     # check for etc/resolv entries or similar? +     # just try to resolve? +     # is there something in psutil? + +     # def check_name_resolution(self): +     #     pass diff --git a/src/leap/base/constants.py b/src/leap/base/constants.py index 48a18dc3..f7be8d98 100644 --- a/src/leap/base/constants.py +++ b/src/leap/base/constants.py @@ -28,3 +28,5 @@ DEFAULT_PROVIDER_DEFINITION = {      u'version': u'0.1.0'}  MAX_ICMP_PACKET_LOSS = 10 + +ROUTE_CHECK_INTERVAL = 10 diff --git a/src/leap/base/exceptions.py b/src/leap/base/exceptions.py index 9c4aa77b..f12a49d5 100644 --- a/src/leap/base/exceptions.py +++ b/src/leap/base/exceptions.py @@ -1,6 +1,72 @@ +""" +Exception attributes and their meaning/uses +------------------------------------------- + +* critical:    if True, will abort execution prematurely, +               after attempting any cleaning +               action. + +* failfirst:   breaks any error_check loop that is examining +               the error queue. + +* message:     the message that will be used in the __repr__ of the exception. + +* usermessage: the message that will be passed to user in ErrorDialogs +               in Qt-land. +""" + + +class LeapException(Exception): +    """ +    base LeapClient exception +    sets some parameters that we will check +    during error checking routines +    """ +    critical = False +    failfirst = False +    warning = False + + +class CriticalError(LeapException): +    """ +    we cannot do anything about it +    """ +    critical = True +    failfirst = True + + +# In use ??? +# don't thing so. purge if not... +  class MissingConfigFileError(Exception):      pass  class ImproperlyConfigured(Exception):      pass + + +class NoDefaultInterfaceFoundError(LeapException): +    message = "no default interface found" +    usermessage = "Looks like your computer is not connected to the internet" + + +class InterfaceNotFoundError(LeapException): +    # XXX should take iface arg on init maybe? +    message = "interface not found" + + +class NoConnectionToGateway(CriticalError): +    message = "no connection to gateway" +    usermessage = "Looks like there are problems with your internet connection" + + +class NoInternetConnection(CriticalError): +    message = "No Internet connection found" +    usermessage = "It looks like there is no internet connection." +    # and now we try to connect to our web to troubleshoot LOL :P + + +class TunnelNotDefaultRouteError(CriticalError): +    message = "Tunnel connection dissapeared. VPN down?" +    usermessage = "The Encrypted Connection was lost. Shutting down..." diff --git a/src/leap/base/network.py b/src/leap/base/network.py new file mode 100644 index 00000000..e90139c4 --- /dev/null +++ b/src/leap/base/network.py @@ -0,0 +1,80 @@ +# -*- coding: utf-8 -*- +from __future__ import (print_function) +import logging +import threading + +from leap.base.checks import LeapNetworkChecker +from leap.base.constants import ROUTE_CHECK_INTERVAL +from leap.base.exceptions import TunnelNotDefaultRouteError +from leap.util.coroutines import (launch_thread, process_events) + +from time import sleep + +logger = logging.getLogger(name=__name__) + + +class NetworkCheckerThread(object): +    """ +    Manages network checking thread that makes sure we have a working network +    connection. +    """ +    def __init__(self, *args, **kwargs): +        self.status_signals = kwargs.pop('status_signals', None) +        #self.watcher_cb = kwargs.pop('status_signals', None) +        self.error_cb = kwargs.pop( +            'error_cb', +            lambda exc: logger.error("%s", exc.message)) +        self.shutdown = threading.Event() + +        # XXX get provider_gateway and pass it to checker +        # see in eip.config for function +        # #718 +        self.checker = LeapNetworkChecker() + +    def start(self): +        self.process_handle = self._launch_recurrent_network_checks( +            (self.error_cb,)) + +    def stop(self): +        self.shutdown.set() +        logger.debug("network checked stopped.") + +    def run_checks(self): +        pass + +    #private methods + +    #here all the observers in fail_callbacks expect one positional argument, +    #which is exception so we can try by passing a lambda with logger to +    #check it works. +    def _network_checks_thread(self, fail_callbacks): +        #TODO: replace this with waiting for a signal from openvpn +        while True: +            try: +                self.checker.check_tunnel_default_interface() +                break +            except TunnelNotDefaultRouteError: +                # XXX ??? why do we sleep here??? +                sleep(1) + +        fail_observer_dict = dict((( +            observer, +            process_events(observer)) for observer in fail_callbacks)) +        while not self.shutdown.is_set(): +            try: +                self.checker.check_tunnel_default_interface() +                self.checker.check_internet_connection() +                sleep(ROUTE_CHECK_INTERVAL) +            except Exception as exc: +                for obs in fail_observer_dict: +                    fail_observer_dict[obs].send(exc) +                sleep(ROUTE_CHECK_INTERVAL) +        #reset event +        self.shutdown.clear() + +    def _launch_recurrent_network_checks(self, fail_callbacks): +        #we need to wrap the fail callback in a tuple +        watcher = launch_thread( +            self._network_checks_thread, +            (fail_callbacks,)) +        return watcher diff --git a/src/leap/base/tests/test_checks.py b/src/leap/base/tests/test_checks.py new file mode 100644 index 00000000..bec09ce6 --- /dev/null +++ b/src/leap/base/tests/test_checks.py @@ -0,0 +1,117 @@ +try: +    import unittest2 as unittest +except ImportError: +    import unittest +import os + +from mock import (patch, Mock) +from StringIO import StringIO + +import ping +import requests + +from leap.base import checks +from leap.base import exceptions +from leap.testing.basetest import BaseLeapTest + +_uid = os.getuid() + + +class LeapNetworkCheckTest(BaseLeapTest): +    __name__ = "leap_network_check_tests" + +    def setUp(self): +        pass + +    def tearDown(self): +        pass + +    def test_checker_should_implement_check_methods(self): +        checker = checks.LeapNetworkChecker() + +        self.assertTrue(hasattr(checker, "check_internet_connection"), +                        "missing meth") +        self.assertTrue(hasattr(checker, "check_tunnel_default_interface"), +                        "missing meth") +        self.assertTrue(hasattr(checker, "is_internet_up"), +                        "missing meth") +        self.assertTrue(hasattr(checker, "ping_gateway"), +                        "missing meth") + +    def test_checker_should_actually_call_all_tests(self): +        checker = checks.LeapNetworkChecker() + +        mc = Mock() +        checker.run_all(checker=mc) +        self.assertTrue(mc.check_internet_connection.called, "not called") +        self.assertTrue(mc.check_tunnel_default_interface.called, "not called") +        self.assertTrue(mc.ping_gateway.called, "not called") +        self.assertTrue(mc.is_internet_up.called, "not called") + +    def test_get_default_interface_no_interface(self): +        checker = checks.LeapNetworkChecker() +        with patch('leap.base.checks.open', create=True) as mock_open: +            with self.assertRaises(exceptions.NoDefaultInterfaceFoundError): +                mock_open.return_value = StringIO( +                    "Iface\tDestination Gateway\t" +                    "Flags\tRefCntd\tUse\tMetric\t" +                    "Mask\tMTU\tWindow\tIRTT") +                checker.get_default_interface_gateway() + +    def test_check_tunnel_default_interface(self): +        checker = checks.LeapNetworkChecker() +        with patch('leap.base.checks.open', create=True) as mock_open: +            with self.assertRaises(exceptions.TunnelNotDefaultRouteError): +                mock_open.return_value = StringIO( +                    "Iface\tDestination Gateway\t" +                    "Flags\tRefCntd\tUse\tMetric\t" +                    "Mask\tMTU\tWindow\tIRTT") +                checker.check_tunnel_default_interface() + +        with patch('leap.base.checks.open', create=True) as mock_open: +            with self.assertRaises(exceptions.TunnelNotDefaultRouteError): +                mock_open.return_value = StringIO( +                    "Iface\tDestination Gateway\t" +                    "Flags\tRefCntd\tUse\tMetric\t" +                    "Mask\tMTU\tWindow\tIRTT\n" +                    "wlan0\t00000000\t0102A8C0\t" +                    "0003\t0\t0\t0\t00000000\t0\t0\t0") +                checker.check_tunnel_default_interface() + +        with patch('leap.base.checks.open', create=True) as mock_open: +            mock_open.return_value = StringIO( +                "Iface\tDestination Gateway\t" +                "Flags\tRefCntd\tUse\tMetric\t" +                "Mask\tMTU\tWindow\tIRTT\n" +                "tun0\t00000000\t01002A0A\t0003\t0\t0\t0\t00000080\t0\t0\t0") +            checker.check_tunnel_default_interface() + +    def test_ping_gateway_fail(self): +        checker = checks.LeapNetworkChecker() +        with patch.object(ping, "quiet_ping") as mocked_ping: +            with self.assertRaises(exceptions.NoConnectionToGateway): +                mocked_ping.return_value = [11, "", ""] +                checker.ping_gateway("4.2.2.2") + +    def test_check_internet_connection_failures(self): +        checker = checks.LeapNetworkChecker() +        with patch.object(requests, "get") as mocked_get: +            mocked_get.side_effect = requests.HTTPError +            with self.assertRaises(exceptions.NoInternetConnection): +                checker.check_internet_connection() + +        with patch.object(requests, "get") as mocked_get: +            mocked_get.side_effect = requests.RequestException +            with self.assertRaises(exceptions.NoInternetConnection): +                checker.check_internet_connection() + +        #TODO: Mock possible errors that can be raised by is_internet_up +        with patch.object(requests, "get") as mocked_get: +            mocked_get.side_effect = requests.ConnectionError +            with self.assertRaises(exceptions.NoInternetConnection): +                checker.check_internet_connection() + +    @unittest.skipUnless(_uid == 0, "root only") +    def test_ping_gateway(self): +        checker = checks.LeapNetworkChecker() +        checker.ping_gateway("4.2.2.2") diff --git a/src/leap/baseapp/eip.py b/src/leap/baseapp/eip.py index 8007d2b7..e291de34 100644 --- a/src/leap/baseapp/eip.py +++ b/src/leap/baseapp/eip.py @@ -230,9 +230,11 @@ class EIPConductorAppMixin(object):                  # we could bring Timer Init to this Mixin                  # or to its own Mixin.                  self.timer.start(constants.TIMER_MILLISECONDS) +                self.network_checker.start()              return          if self.eip_service_started is True: +            self.network_checker.stop()              self.conductor.disconnect()              if self.debugmode:                  self.startStopButton.setText('&Connect') diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py index 1accac30..09e0c0bb 100644 --- a/src/leap/baseapp/mainwindow.py +++ b/src/leap/baseapp/mainwindow.py @@ -8,7 +8,9 @@ from PyQt4 import QtGui  from leap.baseapp.eip import EIPConductorAppMixin  from leap.baseapp.log import LogPaneMixin  from leap.baseapp.systray import StatusAwareTrayIconMixin +from leap.baseapp.network import NetworkCheckerAppMixin  from leap.baseapp.leap_app import MainWindowMixin +from leap.baseapp import dialogs  logger = logging.getLogger(name=__name__) @@ -16,6 +18,7 @@ logger = logging.getLogger(name=__name__)  class LeapWindow(QtGui.QMainWindow,                   MainWindowMixin, EIPConductorAppMixin,                   StatusAwareTrayIconMixin, +                 NetworkCheckerAppMixin,                   LogPaneMixin):      """      main window for the leap app. @@ -28,6 +31,7 @@ class LeapWindow(QtGui.QMainWindow,      statusChange = QtCore.pyqtSignal([object])      mainappReady = QtCore.pyqtSignal([])      initReady = QtCore.pyqtSignal([]) +    networkError = QtCore.pyqtSignal([object])      def __init__(self, opts):          logger.debug('init leap window') @@ -38,6 +42,7 @@ class LeapWindow(QtGui.QMainWindow,          EIPConductorAppMixin.__init__(self, opts=opts)          StatusAwareTrayIconMixin.__init__(self) +        NetworkCheckerAppMixin.__init__(self)          MainWindowMixin.__init__(self)          settings = QtCore.QSettings() @@ -58,6 +63,8 @@ class LeapWindow(QtGui.QMainWindow,              lambda status: self.onStatusChange(status))          self.timer.timeout.connect(              lambda: self.onTimerTick()) +        self.networkError.connect( +            lambda exc: self.onNetworkError(exc))          # do frwizard and init signals          self.mainappReady.connect(self.do_first_run_wizard_check) @@ -93,5 +100,25 @@ class InitChecksThread(QtCore.QThread):      def run(self):          self.fun() +#<<<<<<< HEAD      def begin(self):          self.start() +#======= +        # could send "ready" signal instead +        # eipapp should catch that +        #if self.conductor.autostart: +            #self.start_or_stopVPN() +# +    #TODO: Put all Dialogs in one place +    #@QtCore.pyqtSlot() +    #def raise_Network_Error(self, exc): +        #message = exc.message +# +        # XXX +        # check headless = False before +        # launching dialog. +        # (so Qt tests can assert stuff) +# +        #dialog = dialogs.ErrorDialog() +        #dialog.warningMessage(message, 'error') +#>>>>>>> feature/network_check diff --git a/src/leap/baseapp/network.py b/src/leap/baseapp/network.py new file mode 100644 index 00000000..077d5164 --- /dev/null +++ b/src/leap/baseapp/network.py @@ -0,0 +1,40 @@ +from __future__ import print_function + +import logging + +logger = logging.getLogger(name=__name__) + +from PyQt4 import QtCore + +from leap.baseapp.dialogs import ErrorDialog +from leap.base.network import NetworkCheckerThread + + +class NetworkCheckerAppMixin(object): +    """ +    initialize an instance of the Network Checker, +    which gathers error and passes them on. +    """ + +    def __init__(self, *args, **kwargs): +        self.network_checker = NetworkCheckerThread( +            error_cb=self.networkError.emit, +            debug=self.debugmode) + +        # XXX move run_checks to slot +        self.network_checker.run_checks() + +    @QtCore.pyqtSlot(object) +    def onNetworkError(self, exc): +        """ +        slot that receives a network exceptions +        and raises a user error message +        """ +        logger.debug('handling network exception') +        logger.error(exc.message) +        dialog = ErrorDialog(parent=self) + +        if exc.critical: +            dialog.criticalMessage(exc.usermessage, "network error") +        else: +            dialog.warningMessage(exc.usermessage, "network error") diff --git a/src/leap/baseapp/systray.py b/src/leap/baseapp/systray.py index 0ab37f7f..1939bc09 100644 --- a/src/leap/baseapp/systray.py +++ b/src/leap/baseapp/systray.py @@ -163,9 +163,10 @@ class StatusAwareTrayIconMixin(object):          oldlayout.itemAt(new).widget().show()      def setIcon(self, name): -        icon = self.Icons.get(name)(self) -        self.trayIcon.setIcon(icon) -        #self.setWindowIcon(icon) +        icon_fun = self.Icons.get(name) +        if icon_fun and callable(icon_fun): +            icon = icon_fun(self) +            self.trayIcon.setIcon(icon)      def getIcon(self, icon_name):          return self.states.get(icon_name, None) diff --git a/src/leap/eip/checks.py b/src/leap/eip/checks.py index 413a3467..f739c3e8 100644 --- a/src/leap/eip/checks.py +++ b/src/leap/eip/checks.py @@ -1,12 +1,12 @@  import logging  import ssl -import platform +#import platform  import time  import os  from gnutls import crypto -import netifaces -import ping +#import netifaces +#import ping  import requests  from leap import __branding as BRANDING @@ -39,10 +39,6 @@ into base.tests to be invoked by the base leap init routines.  However, I'm testing them alltogether for the sake of having the whole unit  reachable and testable as a whole. -LeapNetworkChecker ------------------- -Network checks. To be moved to base. -docs TBD  """ @@ -52,79 +48,6 @@ def get_ca_cert():          return certs.where(ca_file) -class LeapNetworkChecker(object): -    """ -    all network related checks -    """ -    # XXX to be moved to leap.base.checks -    # TODO eventually, use a more portable solution -    # like psutil - -    def run_all(self, checker=None): -        if not checker: -            checker = self -        self.error = None  # ? - -        # for MVS -        checker.test_internet_connection() -        checker.is_internet_up() -        checker.ping_gateway() - -    def test_internet_connection(self): -        # XXX we're not passing the error anywhere. -        # XXX we probably should raise an exception here? -        # unless we use this as smoke test -        try: -            # XXX remove this hardcoded random ip -            requests.get('http://216.172.161.165') -        except (requests.HTTPError, requests.RequestException) as e: -            self.error = e.message -        except requests.ConenctionError as e: -            if e.message == "[Errno 113] No route to host": -                if not self.is_internet_up(): -                    self.error = "No valid internet connection found." -                else: -                    self.error = "Provider server appears to be down." - -    def is_internet_up(self): -        iface, gateway = self.get_default_interface_gateway() -        self.ping_gateway(self) - -    def get_default_interface_gateway(self): -        """only impletemented for linux so far.""" -        if not platform.system() == "Linux": -            raise NotImplementedError - -        f = open("/proc/net/route") -        route_table = f.readlines() -        f.close() -        #toss out header -        route_table.pop(0) - -        default_iface = None -        gateway = None -        while route_table: -            line = route_table.pop(0) -            iface, destination, gateway = line.split('\t')[0:3] -            if destination == '00000000': -                default_iface = iface -                break - -        if not default_iface: -            raise eipexceptions.NoDefaultInterfaceFoundError - -        if default_iface not in netifaces.interfaces(): -            raise eipexceptions.InterfaceNotFoundError - -        return default_iface, gateway - -    def ping_gateway(self, gateway): -        #TODO: Discuss how much packet loss (%) is acceptable. -        packet_loss = ping.quiet_ping(gateway)[0] -        if packet_loss > baseconstants.MAX_ICMP_PACKET_LOSS: -            raise eipexceptions.NoConnectionToGateway - -  class ProviderCertChecker(object):      """      Several checks needed for getting diff --git a/src/leap/eip/exceptions.py b/src/leap/eip/exceptions.py index a6216caa..11bfd620 100644 --- a/src/leap/eip/exceptions.py +++ b/src/leap/eip/exceptions.py @@ -28,7 +28,6 @@ TODO:  * EIPClientError:    Should inherit from LeapException -  and move basic attrs there  * gettext / i18n for user messages. @@ -128,22 +127,6 @@ class EIPInitBadProviderError(EIPClientError):  class EIPConfigurationError(EIPClientError):      pass - -class NoDefaultInterfaceFoundError(EIPClientError): -    message = "no default interface found" -    usermessage = "Looks like your computer is not connected to the internet" - - -class InterfaceNotFoundError(EIPClientError): -    # XXX should take iface arg on init maybe? -    message = "interface not found" - - -class NoConnectionToGateway(EIPClientError): -    message = "no connection to gateway" -    usermessage = "Looks like there are problems with your internet connection" - -  #  # Errors that probably we don't need anymore  # chase down for them and check. diff --git a/src/leap/eip/tests/test_checks.py b/src/leap/eip/tests/test_checks.py index 582dcb84..58ce473f 100644 --- a/src/leap/eip/tests/test_checks.py +++ b/src/leap/eip/tests/test_checks.py @@ -9,11 +9,10 @@ import os  import time  import urlparse -from StringIO import StringIO  from mock import (patch, Mock)  import jsonschema -import ping +#import ping  import requests  from leap.base import config as baseconfig @@ -27,8 +26,6 @@ from leap.testing.basetest import BaseLeapTest  from leap.testing.https_server import BaseHTTPSServerTestCase  from leap.testing.https_server import where as where_cert -_uid = os.getuid() -  class NoLogRequestHandler:      def log_message(self, *args): @@ -39,60 +36,6 @@ class NoLogRequestHandler:          return '' -class LeapNetworkCheckTest(BaseLeapTest): -    # XXX to be moved to base.checks - -    __name__ = "leap_network_check_tests" - -    def setUp(self): -        pass - -    def tearDown(self): -        pass - -    def test_checker_should_implement_check_methods(self): -        checker = eipchecks.LeapNetworkChecker() - -        self.assertTrue(hasattr(checker, "test_internet_connection"), -                        "missing meth") -        self.assertTrue(hasattr(checker, "is_internet_up"), -                        "missing meth") -        self.assertTrue(hasattr(checker, "ping_gateway"), -                        "missing meth") - -    def test_checker_should_actually_call_all_tests(self): -        checker = eipchecks.LeapNetworkChecker() - -        mc = Mock() -        checker.run_all(checker=mc) -        self.assertTrue(mc.test_internet_connection.called, "not called") -        self.assertTrue(mc.ping_gateway.called, "not called") -        self.assertTrue(mc.is_internet_up.called, -                        "not called") - -    def test_get_default_interface_no_interface(self): -        checker = eipchecks.LeapNetworkChecker() -        with patch('leap.eip.checks.open', create=True) as mock_open: -            with self.assertRaises(eipexceptions.NoDefaultInterfaceFoundError): -                mock_open.return_value = StringIO( -                    "Iface\tDestination Gateway\t" -                    "Flags\tRefCntd\tUse\tMetric\t" -                    "Mask\tMTU\tWindow\tIRTT") -                checker.get_default_interface_gateway() - -    def test_ping_gateway_fail(self): -        checker = eipchecks.LeapNetworkChecker() -        with patch.object(ping, "quiet_ping") as mocked_ping: -            with self.assertRaises(eipexceptions.NoConnectionToGateway): -                mocked_ping.return_value = [11, "", ""] -                checker.ping_gateway("4.2.2.2") - -    @unittest.skipUnless(_uid == 0, "root only") -    def test_ping_gateway(self): -        checker = eipchecks.LeapNetworkChecker() -        checker.ping_gateway("4.2.2.2") - -  class EIPCheckTest(BaseLeapTest):      __name__ = "eip_check_tests" @@ -132,8 +75,6 @@ class EIPCheckTest(BaseLeapTest):                          "not called")          self.assertTrue(mc.check_complete_eip_config.called,                          "not called") -        #self.assertTrue(mc.ping_gateway.called, -                        #"not called")      # test individual check methods diff --git a/src/leap/util/coroutines.py b/src/leap/util/coroutines.py index e7ccfacf..0657fc04 100644 --- a/src/leap/util/coroutines.py +++ b/src/leap/util/coroutines.py @@ -4,10 +4,13 @@  from __future__ import division, print_function +import logging  from subprocess import PIPE, Popen  import sys  from threading import Thread +logger = logging.getLogger(__name__) +  ON_POSIX = 'posix' in sys.builtin_module_names @@ -38,8 +41,7 @@ for each event              if callable(callback):                  callback(m)              else: -                #XXX log instead -                print('not a callable passed') +                logger.debug('not a callable passed')      except GeneratorExit:          return @@ -72,7 +74,7 @@ def watch_output(out, observers):      :type out: fd      :param observers: tuple of coroutines to send data\  for each event -    :type ovservers: tuple +    :type observers: tuple      """      observer_dict = dict(((observer, process_events(observer))                           for observer in observers)) | 
