Beispiel #1
0
    def run(self):
        cov_files = glob.glob('.coverage*')

        try:
            import coverage
            omitted_files = ['*site-packages*']
            cov = coverage.Coverage(data_file='.coverage.%s' %
                                    (len(cov_files) + 1),
                                    omit=omitted_files)
            cov.start()
        except ImportError:
            cov = None

        suite = unittest.TestSuite()
        import stomp.test
        if self.test == '*':
            logging.info('Running all tests')
            tests = stomp.test.__all__
        else:
            tests = self.test.split(',')
        for tst in tests:
            suite.addTests(unittest.TestLoader().loadTestsFromName(
                'stomp.test.%s' % tst))

        runner = unittest.TextTestRunner(verbosity=2)
        res = runner.run(suite)

        if cov:
            cov.stop()
            cov.save()
Beispiel #2
0
    def transmit(self, frame):
        """
        Convert a frame object to a frame string and transmit to the server.

        :param Frame frame: the Frame object to transmit
        """
        with self.__listeners_change_condition:
            listeners = sorted(self.listeners.items())

        for (_, listener) in listeners:
            if not listener:
                continue
            try:
                listener.on_send(frame)
            except AttributeError:
                continue

        if frame.cmd == CMD_DISCONNECT and HDR_RECEIPT in frame.headers:
            self.__disconnect_receipt = frame.headers[HDR_RECEIPT]

        lines = convert_frame(frame)
        packed_frame = pack(lines)

        if logging.isEnabledFor(logging.DEBUG):
            logging.debug("Sending frame: %s", clean_lines(lines))
        else:
            logging.info("Sending frame: %r", frame.cmd or "heartbeat")
        self.send(packed_frame)
Beispiel #3
0
    def __heartbeat_loop(self):
        """
        Main loop for sending (and monitoring received) heartbeats.
        """
        logging.info('Starting heartbeat loop')
        now = monotonic()

        # Setup the initial due time for the outbound heartbeat
        if self.send_sleep != 0:
            self.next_outbound_heartbeat = now + self.send_sleep

        while self.running:
            now = monotonic()

            next_events = []
            if self.next_outbound_heartbeat is not None:
                next_events.append(self.next_outbound_heartbeat - now)
            if self.receive_sleep != 0:
                t = self.received_heartbeat + self.receive_sleep - now
                if t > 0:
                    next_events.append(t)
            sleep_time = min(next_events)
            if sleep_time > 0:
                terminate = self.heartbeat_terminate_event.wait(sleep_time)
                if terminate:
                    break

            now = monotonic()

            if not self.transport.is_connected():
                time.sleep(self.send_sleep)
                continue

            if self.send_sleep != 0 and now > self.next_outbound_heartbeat:
                logging.debug("Sending a heartbeat message at %s", now)
                try:
                    self.transport.transmit(utils.Frame(None, {}, None))
                except exception.NotConnectedException:
                    logging.debug("Lost connection, unable to send heartbeat")
                except Exception:
                    _, e, _ = sys.exc_info()
                    logging.debug("Unable to send heartbeat, due to: %s", e)

            if self.receive_sleep != 0:
                diff_receive = now - self.received_heartbeat

                if diff_receive > self.receive_sleep:
                    # heartbeat timeout
                    logging.warning(
                        "Heartbeat timeout: diff_receive=%s, time=%s, lastrec=%s",
                        diff_receive, now, self.received_heartbeat)
                    self.transport.set_connected(False)
                    self.transport.disconnect_socket()
                    self.transport.stop()
                    for listener in self.transport.listeners.values():
                        listener.on_heartbeat_timeout()
        self.heartbeat_thread = None
        self.heartbeat_terminate_event.clear()
        logging.info('Heartbeat loop ended')
Beispiel #4
0
    def on_connecting(self, host_and_port):
        """
        Increment the connection count. See :py:meth:`ConnectionListener.on_connecting`

        :param (str,int) host_and_port: the host and port as a tuple
        """
        logging.info("connecting %s %s (x %s)", host_and_port[0], host_and_port[1], self.connections)
        self.connections += 1
Beispiel #5
0
 def try_setsockopt(sock, name, fam, opt, val):
     if val is None:
         return True  # no value to set always works
     try:
         sock.setsockopt(fam, opt, val)
         logging.info("keepalive: set %r option to %r on socket", name, val)
     except:
         logging.error("keepalive: unable to set %r option to %r on socket", name, val)
         return False
     return True
Beispiel #6
0
    def on_error(self, headers, body):
        """
        Increment the error count. See :py:meth:`ConnectionListener.on_error`

        :param dict headers: headers in the message
        :param body: the message content
        """
        if logging.isEnabledFor(logging.DEBUG):
            logging.debug("received an error %s [%s]", body, headers)
        else:
            logging.info("received an error %s", body)
        self.errors += 1
Beispiel #7
0
 def start(self):
     """
     Start the connection. This should be called after all
     listeners have been registered. If this method is not called,
     no frames will be received by the connection and no SSL/TLS
     handshake will occur.
     """
     self.running = True
     self.attempt_connection()
     receiver_thread = self.create_thread_fc(self.__receiver_loop)
     logging.info("Created thread %s using func %s", receiver_thread, self.create_thread_fc)
     self.notify("connecting")
Beispiel #8
0
 def start(self):
     logging.info("Starting stomp server")
     self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     self.s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
     self.s.bind((self.host, self.port))
     self.s.listen(1)
     self.running = True
     thread = threading.Thread(None, self.run)
     thread.daemon = True
     thread.start()
     self.stopped = False
     logging.info("Stomp server started")
Beispiel #9
0
 def stop(self):
     logging.info("Stopping test server")
     if self.conn:
         try:
             self.conn.shutdown(socket.SHUT_WR)
         except Exception:
             pass
         self.conn.close()
     if self.s:
         self.s.close()
     self.running = False
     self.conn = None
     self.s = None
     self.stopped = True
     logging.info("Connection stopped")
Beispiel #10
0
 def process_frame(self, f, frame_str):
     """
     :param Frame f: Frame object
     :param bytes frame_str: raw frame content
     """
     frame_type = f.cmd.lower()
     if frame_type in ["connected", "message", "receipt", "error", "heartbeat"]:
         if frame_type == "message":
             self.notify("before_message", f)
         if logging.isEnabledFor(logging.DEBUG):
             logging.debug("Received frame: %r, headers=%r, body=%r", f.cmd, f.headers, f.body)
         else:
             logging.info("Received frame: %r, len(body)=%r", f.cmd, length(f.body))
         self.notify(frame_type, f)
     else:
         logging.warning("Unknown response frame type: '%s' (frame length was %d)", frame_type, length(frame_str))
Beispiel #11
0
    def __receiver_loop(self):
        """
        Main loop listening for incoming data.
        """
        logging.info("Starting receiver loop (%s)", threading.current_thread())
        notify_disconnected = True
        try:
            while self.running:
                try:
                    while self.running:
                        frames = self.__read()

                        for frame in frames:
                            if self.__is_eol(frame):
                                f = HEARTBEAT_FRAME
                            else:
                                f = parse_frame(frame)
                            if f is None:
                                continue
                            if self.__auto_decode:
                                f.body = decode(f.body)
                            self.process_frame(f, frame)
                except exception.ConnectionClosedException:
                    if self.running:
                        #
                        # Clear out any half-received messages after losing connection
                        #
                        self.__recvbuf = b''
                        self.running = False
                        notify_disconnected = True
                    break
                finally:
                    self.cleanup()
        finally:
            with self.__receiver_thread_exit_condition:
                self.__receiver_thread_exited = True
                self.__receiver_thread_exit_condition.notifyAll()
            logging.info("Receiver loop ended")
            self.notify("receiver_loop_completed")
            if notify_disconnected and not self.__notified_on_disconnect:
                self.notify("disconnected")
            with self.__connect_wait_condition:
                self.__connect_wait_condition.notifyAll()
Beispiel #12
0
    def __enable_keepalive(self):
        def try_setsockopt(sock, name, fam, opt, val):
            if val is None:
                return True  # no value to set always works
            try:
                sock.setsockopt(fam, opt, val)
                logging.info("keepalive: set %r option to %r on socket", name,
                             val)
            except:
                logging.error(
                    "keepalive: unable to set %r option to %r on socket", name,
                    val)
                return False
            return True

        ka = self.__keepalive

        if not ka:
            return

        if ka is True:
            ka_sig = 'auto'
            ka_args = ()
        else:
            try:
                ka_sig = ka[0]
                ka_args = ka[1:]
            except Exception:
                logging.error("keepalive: bad specification %r", ka)
                return

        if ka_sig == 'auto':
            if LINUX_KEEPALIVE_AVAIL:
                ka_sig = 'linux'
                ka_args = None
                logging.info("keepalive: autodetected linux-style support")
            else:
                logging.error(
                    "keepalive: unable to detect any implementation, DISABLED!"
                )
                return

        if ka_sig == 'linux':
            logging.info("keepalive: activating linux-style support")
            if ka_args is None:
                logging.info("keepalive: using system defaults")
                ka_args = (None, None, None)
            lka_idle, lka_intvl, lka_cnt = ka_args
            if try_setsockopt(self.socket, 'enable', SOL_SOCKET, SO_KEEPALIVE,
                              1):
                try_setsockopt(self.socket, 'idle time', SOL_TCP, TCP_KEEPIDLE,
                               lka_idle)
                try_setsockopt(self.socket, 'interval', SOL_TCP, TCP_KEEPINTVL,
                               lka_intvl)
                try_setsockopt(self.socket, 'count', SOL_TCP, TCP_KEEPCNT,
                               lka_cnt)
        else:
            logging.error(
                "keepalive: implementation %r not recognized or not supported",
                ka_sig)
Beispiel #13
0
 def run(self):
     self.conn, _ = self.s.accept()
     while self.running:
         try:
             _ = self.conn.recv(1024)
             frame = self.get_next_frame()
             if self.conn is None:
                 break
             if frame is not None:
                 logging.info("Stompserver sending frame %s", frame)
                 self.conn.send(encode(frame))
         except Exception:
             _, e, _ = sys.exc_info()
             logging.debug(e)
             break
         time.sleep(0.1)
     try:
         self.conn.close()
     except:
         pass
     self.stopped = True
     logging.info("Run loop completed")
Beispiel #14
0
 def __print(self, msg, *args):
     if self.print_to_log:
         logging.info(msg, *args)
     else:
         print(msg % args)
Beispiel #15
0
    def attempt_connection(self):
        """
        Try connecting to the (host, port) tuples specified at construction time.
        """
        self.connection_error = False
        sleep_exp = 1
        connect_count = 0

        while self.running and self.socket is None and (
                connect_count < self.__reconnect_attempts_max
                or self.__reconnect_attempts_max == -1):
            for host_and_port in self.__host_and_ports:
                try:
                    logging.info("Attempting connection to host %s, port %s",
                                 host_and_port[0], host_and_port[1])
                    self.socket = socket.create_connection(
                        host_and_port, self.__timeout)
                    self.__enable_keepalive()
                    need_ssl = self.__need_ssl(host_and_port)

                    if need_ssl:  # wrap socket
                        ssl_params = self.get_ssl(host_and_port)
                        if ssl_params['ca_certs']:
                            cert_validation = ssl.CERT_REQUIRED
                        else:
                            cert_validation = ssl.CERT_NONE
                        try:
                            tls_context = ssl.create_default_context(
                                cafile=ssl_params['ca_certs'])
                        except AttributeError:
                            tls_context = None
                        if tls_context:
                            # Wrap the socket for TLS
                            certfile = ssl_params['cert_file']
                            keyfile = ssl_params['key_file']
                            password = ssl_params.get('password')
                            if certfile and not keyfile:
                                keyfile = certfile
                            if certfile:
                                tls_context.load_cert_chain(
                                    certfile, keyfile, password)
                            if cert_validation is None or cert_validation == ssl.CERT_NONE:
                                tls_context.check_hostname = False
                            tls_context.verify_mode = cert_validation
                            self.socket = tls_context.wrap_socket(
                                self.socket, server_hostname=host_and_port[0])
                        else:
                            # Old-style wrap_socket where we don't have a modern SSLContext (so no SNI)
                            self.socket = ssl.wrap_socket(
                                self.socket,
                                keyfile=ssl_params['key_file'],
                                certfile=ssl_params['cert_file'],
                                cert_reqs=cert_validation,
                                ca_certs=ssl_params['ca_certs'],
                                ssl_version=ssl_params['ssl_version'])

                    self.socket.settimeout(self.__timeout)

                    if self.blocking is not None:
                        self.socket.setblocking(self.blocking)

                    #
                    # Validate server cert
                    #
                    if need_ssl and ssl_params['cert_validator']:
                        cert = self.socket.getpeercert()
                        (ok, errmsg) = ssl_params['cert_validator'](
                            cert, host_and_port[0])
                        if not ok:
                            raise SSLError(
                                "Server certificate validation failed: %s",
                                errmsg)

                    self.current_host_and_port = host_and_port
                    logging.info("Established connection to host %s, port %s",
                                 host_and_port[0], host_and_port[1])
                    break
                except socket.error:
                    self.socket = None
                    connect_count += 1
                    logging.warning("Could not connect to host %s, port %s",
                                    host_and_port[0],
                                    host_and_port[1],
                                    exc_info=1)

            if self.socket is None:
                sleep_duration = (min(self.__reconnect_sleep_max, (
                    (self.__reconnect_sleep_initial /
                     (1.0 + self.__reconnect_sleep_increase)) *
                    math.pow(1.0 + self.__reconnect_sleep_increase, sleep_exp)
                )) * (1.0 + random.random() * self.__reconnect_sleep_jitter))
                sleep_end = monotonic() + sleep_duration
                logging.debug(
                    "Sleeping for %.1f seconds before attempting reconnect",
                    sleep_duration)
                while self.running and monotonic() < sleep_end:
                    time.sleep(0.2)

                if sleep_duration < self.__reconnect_sleep_max:
                    sleep_exp += 1

        if not self.socket:
            raise exception.ConnectFailedException()
Beispiel #16
0
 def on_disconnected(self):
     """
     Increment the disconnect count. See :py:meth:`ConnectionListener.on_disconnected`
     """
     self.disconnects += 1
     logging.info("disconnected (x %s)", self.disconnects)
Beispiel #17
0
def is_inside_travis():
    if os.environ.get("TRAVIS", "false") == "true":
        logging.info("Not running test inside travis")
        return True
    return False