def test_date(self): """ Test """ dt = SolBase.datecurrent() SolBase.sleep(100) # Gevent 1.3 : this is buggy (may be related to https://github.com/gevent/gevent/issues/1227) self.assertGreaterEqual(SolBase.datediff(dt), 100) self.assertLessEqual(SolBase.datediff(dt), 200)
def _protocol_client_hello_received(self): """ Must send a hello """ with self._protocolLock: # Un-schedule hello timeout self._unschedule_client_hello_timeout() # Stats Meters.aii("ping.server.clientHelloReceived") # Delay Meters.aii("ping.server.delayClientConnectToClientHello", SolBase.datediff(self.dtClientConnect)) # Send a reply b = self.send_unicode_to_socket("C.HI.REPLY PID={0}".format( os.getpid())) if not b: # Stat logger.error("send failed, fatal, disconnecting") Meters.aii("ping.server.serverSendError") # Disconnect self.stop_asynch() else: # Now connected, schedule a ping self._schedule_server_ping() # Stats Meters.aii("ping.server.client_hello_server_reply")
def connect(self): """ Connect to server. :return Return true upon success. """ # Stats Meters.aii("ping.client.client_connect_count") # Call base dt_start = SolBase.datecurrent() b = TcpSimpleClient.connect(self) if not b: # Stat logger.error("PingSimpleClient : connect failed, fatal, exiting") Meters.aii("ping.client.client_connect_error") # Exit return False # Stat Meters.dtci("ping.client.delay_client_connect", SolBase.datediff(dt_start)) # SSL stats ms = self._get_ssl_handshake_ms() if ms: Meters.dtci("ping.client.delay_client_sslhandshake", ms) # Send hello self._protocol_client_hello_send() return True
def _protocol_client_ping_server_reply(self): """ A client ping has been replied """ with self._protocol_lock: # Must have a timeout ongoing if self._ping_timeout_greenlet is None: # Ping reply received without ongoing ping Meters.aii( "ping.client.client_ping_server_reply_noping_ongoing") else: # Unschedule the timeout self._unschedule_client_pingservertimeout() # Reschedule a ping self._schedule_clientping() # Stats Meters.aii("ping.client.client_ping_server_reply") # Delay and stats Meters.dtci("ping.client.delay_client_ping_toserver_reply", SolBase.datediff(self.dt_last_ping_send))
def _protocol_client_hello_server_reply(self, item): """ Received a hello reply :param item: Received server reply ("C.HI.REPLY PID=...") """ with self._protocol_lock: # Parse it self._server_pid = item.replace("C.HI.REPLY PID=", "") # Unschedule timeout self._unschedule_client_helloservertimeout() # Stats Meters.aii("ping.client.client_hello_server_reply") # Delay ms = SolBase.datediff(self.dt_hello_send) # Stats Meters.dtci("ping.client.delay_client_hello_toserver_reply", ms) # Initiate the ping loop, with random start self._schedule_clientping(True)
def _protocol_server_ping_client_reply(self): """ A client ping has been replied """ with self._protocolLock: # Must have a timeout ongoing if self._pingTimeOutGreenlet is None: # Ping reply received without ongoing ping Meters.aii( "ping.server.serverPingServerClientReplyNoPingOngoing") else: # Unschedule the timeout self._unschedule_server_ping_client_timeout() # Reschedule a ping self._schedule_server_ping() # Stats Meters.aii("ping.server.serverPingClientReply") # Delay Meters.dtci("ping.server.client_ping_server_reply", SolBase.datediff(self.dtLastPingSend))
def _start_all(self, server_config): """ Start server and client. :param server_config: Server config. :return: tuple pysoltcp.tcpserver.TcpServer.TcpServer,pysoltcp.tcp_client.TcpSimpleClient.TcpSimpleClient :rtype tuple """ # Allocate self.tcp_server = TcpServer(server_config) # Check self.assertIsNotNone(self.tcp_server) self.assertFalse(self.tcp_server._is_started) self.assertTrue(self.tcp_server._server is None) # Start self.assertTrue(self.tcp_server.start_server()) self.assertTrue(self.tcp_server._is_started) self.assertFalse(self.tcp_server._server is None) # Client config client_config = TcpClientConfig() client_config.target_addr = "127.0.0.1" client_config.target_port = 3201 client_config.debug_log = True # Client self.tcp_client = TcpSimpleClient(client_config) # Check self.assertTrue(self.tcp_client.current_socket is None) self.assertTrue(not self.tcp_client.is_connected) # Connect logger.info("Starting connect()") self.assertTrue(self.tcp_client.connect()) logger.info("Starting connect() : done") # Check client self.assertIsNotNone(self.tcp_client.current_socket) self.assertTrue(self.tcp_client.is_connected) # Wait for server logger.info("TestLog : server : wait connection") dt_start = SolBase.datecurrent() while SolBase.datediff(dt_start) < self.checkTimeOut: if len(self.tcp_server._client_connected_hash) > 0: break SolBase.sleep(int(self.checkTimeOut / 100)) logger.info("TestLog : server : wait connection : done") # Check self.assertEqual(len(self.tcp_server._client_connected_hash), 1) # Ok logger.info("Started and connected, effectiveMs=%s", self.tcp_server.get_effective_controlinterval_ms()) return self.tcp_server, self.tcp_client
def _waitforserver_disconnection(self, timeout_ms): """ Wait for client disconnection at server level :return: Nothing """ logger.info("server : wait for disconnection") dt_start = SolBase.datecurrent() while SolBase.datediff(dt_start) < timeout_ms: if len(self.tcp_server._client_connected_hash ) == 0 and self.tcp_client.current_socket is None: break SolBase.sleep(timeout_ms / 1000) logger.info("server : wait for disconnection : done, ms=%s", SolBase.datediff(dt_start)) # Check self.assertEqual(len(self.tcp_server._client_connected_hash), 0) self.assertIsNone(self.tcp_client.current_socket)
def _stop_one_client(self): """ Test """ # Check logger.info("TestLog : server : get server context") self.assertTrue(len(self.tcp_server._client_connected_hash) == 1) ctx = None for cur in self.tcp_server._client_connected_hash.values(): ctx = cur break self.assertIsNotNone(ctx) self.assertEqual(ctx.stop_synchCalled, False) self.assertEqual(ctx.stop_synch_internalCalled, False) # Kill client self.tcpClient.disconnect() # Check client self.assertTrue(self.tcpClient.current_socket is None) self.assertFalse(self.tcpClient.is_connected) # Reset client self.tcpClient = None # Server should be disconnected from client # Wait for server logger.info("TestLog : server : wait for disconnection") dt_start = SolBase.datecurrent() while SolBase.datediff(dt_start) < self.checkTimeOutMs: ok = True if len(self.tcp_server._client_connected_hash) != 0: ok = False elif not ctx.stop_synchCalled: ok = False elif not ctx.stop_synch_internalCalled: ok = False if ok: logger.info("TestLog : server : wait for disconnection : done") break else: SolBase.sleep(int(self.checkTimeOutMs / 100)) # Check logger.info("TestLog : server : check for disconnection") self.assertTrue(len(self.tcp_server._client_connected_hash) == 0) # Check self.assertEqual(ctx.stop_synchCalled, True) self.assertEqual(ctx.stop_synch_internalCalled, True)
def __str__(self): """ To string override :return: A string :rtype str """ to = None if self.current_socket: to = self.current_socket.timeout return "s.to={0}*dt.creat={1}*dt.recv={2}*dt.send={3}*q.send.size={4}*is.co={5}/{6}*cl={7}*id={8}".format( to, int(SolBase.datediff(self._dt_created) * 0.001), int(SolBase.datediff(self._dt_last_recv) * 0.001), int(SolBase.datediff(self._dt_last_send) * 0.001), self.__send_queue.qsize(), self.is_connected, self.__is_running(), self.__class__.__name__, id(self) )
def _start_one_client_checkallping_stop(self): """ Test """ # Start self._start_one_client() # Here we must wait # 1) Client : already connected, must # - send hello, have a reply # - send a ping, have a reply # - reply to one server ping # 2) Server # - receive a hello and reply # - send a ping, have a reply # - reply to one client ping # => We check using the static PingStatXXX dt = SolBase.datecurrent() while SolBase.datediff(dt) < self.checkPingTimeOutMs: # Client client_ko = PingTestTools.get_client_ko_count() # Server server_ko = PingTestTools.get_server_ko_count() # Check full ok if client_ko == 0 and server_ko == 0: break # Wait logger.info("Test : client_ko=%s, server_ko=%s", client_ko, server_ko) SolBase.sleep(1000) # Final check client_ko = PingTestTools.get_client_ko_count(True) server_ko = PingTestTools.get_server_ko_count(True) self.assertEqual(client_ko, 0) self.assertEqual(server_ko, 0) # Stop self._stop_one_client()
def _start_one_client(self): """ Test """ # Client config client_config = TcpClientConfig() client_config.target_addr = "127.0.0.1" client_config.target_port = 3201 client_config.debug_log = True # ssl if self.testSsl: client_config.ssl_enable = True # Client self.tcpClient = PingSimpleClient(client_config, self.clientHelloTimeOutMs, self.clientPingIntervalMs, self.clientPingTimeOutMs) # Check self.assertTrue(self.tcpClient.current_socket is None) self.assertFalse(self.tcpClient.is_connected) # Connect self.assertTrue(self.tcpClient.connect()) # Check client self.assertIsNotNone(self.tcpClient.current_socket) self.assertTrue(self.tcpClient.is_connected) # Wait for server logger.info("TestLog : server : wait connection") dt_start = SolBase.datecurrent() while SolBase.datediff(dt_start) < self.checkTimeOutMs: if len(self.tcp_server._client_connected_hash) > 0: break SolBase.sleep(int(self.checkTimeOutMs / 100)) logger.info("TestLog : server : wait connection : done") # Check self.assertEqual(len(self.tcp_server._client_connected_hash), 1)
def _protocol_client_pingserver_timeout(self): """ Called when a ping has time-out (ie no reply from server) """ with self._protocol_lock: logger.warning("ping timeout, rescheduling ping, ms=%s", SolBase.datediff(self.dt_last_ping_send)) # Reset (we are called by it) if self._ping_timeout_greenlet is None: # Greenlet none, not normal, we are called by it logger.warning("_ping_timeout_greenlet None") self._ping_timeout_greenlet = None # Reschedule a ping self._schedule_clientping() # Stat Meters.aii("ping.client.client_pingserver_timeout")
def _control_us(self): """ Control us. May force ourself to exit upon inactivity. Note: We do not use lock to minimize per socket memory usage... """ logger.info("Entering") # Check if not self.is_connected: return # Get settings c = self._tcp_server.get_tcpserver_config() # Check absolute absolute_ms = c.socket_absolute_timeout_ms if absolute_ms > 0: running_ms = SolBase.datediff(self._dt_created) if running_ms > absolute_ms: logger.debug( "Absolute reached, running_ms=%s, absolute_ms=%s, self=%s", running_ms, absolute_ms, self) # Kill ourself if we are running if self.is_connected: self.stop_asynch() return else: logger.debug( "Absolute not reached, running_ms=%s, absolute_ms=%s, self=%s", running_ms, absolute_ms, self) pass # Check relative relative_ms = c.socket_relative_timeout_ms if relative_ms > 0: # Get last receive ms last_recv_ms = SolBase.datediff(self._dt_last_recv) # Get last send ms last_send_ms = SolBase.datediff(self._dt_last_send) # We keep the minimum of both last_ms = min(last_recv_ms, last_send_ms) # Check if last_ms > relative_ms: # Kill ourself logger.debug( "Relative reached, last_recv_ms=%s, last_send_ms=%s, last_ms=%s, relative_ms=%s, self=%s", last_recv_ms, last_send_ms, last_ms, relative_ms, self) if self.is_connected: self.stop_asynch() return else: logger.debug( "Relative not reached, last_recv_ms=%s, last_send_ms=%s, last_ms=%s, relative_ms=%s, self=%s", last_recv_ms, last_send_ms, last_ms, relative_ms, self) # Schedule next check self._schedule_control_greenlet()
def stop_synch_internal(self): """ Stop processing our socket read/write. Reserved for PURE in-memory stop operations (greenlet stop, counter put mainly) NEVER, NEVER perform any kind of non-memory operations here. For instance, are FORDIDEN in higher level implementation of stop_synch_internal : - Any socket send/recv - Any external queries (redis/mongo, whatever) JUST HANDLE IN MEMORY STUFF. :return True if success, false otherwise. :rtype bool """ try: logger.debug( "TcpServerClientContext : disconnect : entering, self=%s", self) # Check if not self.is_connected: logger.debug( "TcpServerClientContext : disconnect : not connected, doing nothing, self=%s", self) return False # Signal (move on top, try to avoid some TcpManager warn logs while stopping) self.is_connected = False # Timeout unschedule self._unschedule_ssl_handshake_timeout() # Control unschedule self._unschedule_control_greenlet() # Disconnect # Close the socket in this case (should not cover mantis 1173) SolBase.safe_close_socket(self.current_socket) self.current_socket = None # Greenlet reset after is_connected=False (will help to exit itself) if self._read_greenlet: self._read_greenlet.kill() self._read_greenlet = None if self._write_greenlet: self._write_greenlet.kill() self._write_greenlet = None # Flush out the send queue now, and decrement pending bytes to send total_len = 0 while True: try: item = self.send_queue.get(False) if isinstance(item, bytes): total_len += len(item) elif isinstance(item, SignaledBuffer): total_len += len(item.binary_buffer) except Empty: break # Decrement logger.debug( "TcpServerClientContext : disconnect : decrementing, total_len=%s", total_len) Meters.aii("tcp.server.server_bytes_send_pending", -total_len) # Over logger.debug("TcpServerClientContext : disconnect : done, self=%s", self) return True except Exception as e: logger.error( "TcpServerClientContext : disconnect : Exception, ex=%s, self=%s", SolBase.extostr(e), self) return False finally: # Session duration stats sec = SolBase.datediff(self._dt_created) / 1000 Meters.dtci("tcp.server.session_duration_second", sec)
def _start_multi_client_checkallping_stop(self): """ Test """ # Start self._start_multi_client(self.clientMaxCount) # Here we must wait # 1) Client : already connected, must # - send hello, have a reply # - send a ping, have a reply # - reply to one server ping # 2) Server # - receive a hello and reply # - send a ping, have a reply # - reply to one client ping # => We check using the static PingStatXXX flush_stat_inloop = False dt = SolBase.datecurrent() dt_stat = SolBase.datecurrent() dt_loop = SolBase.datecurrent() client_prev_completed_ping = 0 server_prev_completed_ping = 0 while SolBase.datediff(dt) < self.runTimeMs: # Wait SolBase.sleep(1000) # Client client_ko = PingTestTools.get_client_ko_count( False, self.clientMaxCount) # Server server_ko = PingTestTools.get_server_ko_count( False, self.clientMaxCount) # Total ping client_total_completed_ping = Meters.aig( "ping.client.client_ping_server_reply") server_total_completed_ping = Meters.aig( "ping.server.serverPingClientReply") # Current ping client_local_completed_ping = client_total_completed_ping - client_prev_completed_ping server_local_completed_ping = server_total_completed_ping - server_prev_completed_ping # Store prev client_prev_completed_ping = client_total_completed_ping server_prev_completed_ping = server_total_completed_ping # Elapsed ms elapsed_ms = SolBase.datediff(dt_loop) elapsed_total_ms = SolBase.datediff(dt) # Ping per sec. client_local_pps = (client_local_completed_ping / (elapsed_ms / 1000.0)) server_local_pps = (server_local_completed_ping / (elapsed_ms / 1000.0)) client_avg_pps = (client_total_completed_ping / (elapsed_total_ms / 1000.0)) server_avg_pps = (server_total_completed_ping / (elapsed_total_ms / 1000.0)) # Reset date dt_loop = SolBase.datecurrent() # Wait logger.info( "Running : ko=%s:%s, sec=%s/%s, cli.ping=%s, svr.ping=%s, exp.pps=%.2f, " "cli.pps=%.2f, svr.pps=%.2f, cli.aps=%.2f, svr.aps=%.2f", client_ko, server_ko, int(SolBase.datediff(dt) / 1000), int(self.runTimeMs / 1000), client_local_completed_ping, server_local_completed_ping, self.expectedPps, client_local_pps, server_local_pps, client_avg_pps, server_avg_pps) # Stat if flush_stat_inloop and SolBase.datediff( dt_stat) > self.statEveryMs: Meters.write_to_logger() dt_stat = SolBase.datecurrent() # Final check client_ko = PingTestTools.get_client_ko_count(True, self.clientMaxCount) server_ko = PingTestTools.get_server_ko_count(True, self.clientMaxCount) self.assertEqual(client_ko, 0) self.assertEqual(server_ko, 0) # Stop self._stop_multi_client()
def test_tcp_svr_start_cli_connect_clidisco_clicanreco_deadlock(self): """ Test """ # Instance self.tcp_server = None try: # Start server self._start_server_and_check(deadlock=True) # Start client, check and stop client self._start_one_client_checkstop() # Check stats logger.info("TestLog : server : wait for timeout on stop calls") dt_start = SolBase.datecurrent() while SolBase.datediff(dt_start) < self.checkTimeOutMs: ok = True if Meters.aig( "tcp.server.client_remove_timeout_internal") != 1: ok = False elif Meters.aig( "tcp.server.client_remove_timeout_business") != 1: ok = False if ok: logger.info( "TestLog : server : wait for timeout on stop calls : done" ) break else: SolBase.sleep(int(self.checkTimeOutMs / 100)) # Check self.assertEqual( Meters.aig("tcp.server.client_remove_timeout_internal"), 1) self.assertEqual( Meters.aig("tcp.server.client_remove_timeout_business"), 1) # Start client, check and stop client self._start_one_client_checkstop() # Check stats logger.info("TestLog : server : wait for timeout on stop calls") dt_start = SolBase.datecurrent() while SolBase.datediff(dt_start) < self.checkTimeOutMs: ok = True if Meters.aig( "tcp.server.client_remove_timeout_internal") != 2: ok = False elif Meters.aig( "tcp.server.client_remove_timeout_business") != 2: ok = False if ok: logger.info( "TestLog : server : wait for timeout on stop calls : done" ) break else: SolBase.sleep(int(self.checkTimeOutMs / 100)) # Check self.assertEqual( Meters.aig("tcp.server.client_remove_timeout_internal"), 2) self.assertEqual( Meters.aig("tcp.server.client_remove_timeout_business"), 2) except Exception as e: logger.error("Exception in test, ex=%s", SolBase.extostr(e)) raise finally: if self.tcp_server: self.tcp_server.stop_server() if self.tcpClient: self.tcpClient.disconnect()
def _start_multi_client(self, client_count): """ Test :param client_count: Client count. """ # Client config client_config = TcpClientConfig() client_config.target_addr = "127.0.0.1" client_config.target_port = 3201 client_config.debug_log = self.debug_log # ssl if self.testSsl: client_config.ssl_enable = True # Proxy ? if self.testProxy: client_config.proxy_enable = True client_config.proxy_addr = "127.0.0.1" client_config.proxy_port = 1080 # -------------------------------- # Client array : allocate # -------------------------------- logger.info("allocating, client_count=%s", client_count) self.arTcpClient = list() dt_cur = SolBase.datecurrent() for _ in range(client_count): # Alloc local_client = PingSimpleClient(client_config, self.clientHelloTimeOutMs, self.clientPingIntervalMs, self.clientPingTimeOutMs) # Register self.arTcpClient.append(local_client) # Check self.assertTrue(local_client.current_socket is None) self.assertFalse(local_client.is_connected) if SolBase.datediff(dt_cur) > 1000: dt_cur = SolBase.datecurrent() logger.info("allocating, client_count=%s, done=%s", client_count, len(self.arTcpClient)) logger.info("allocating, client_count=%s, done=%s", client_count, len(self.arTcpClient)) # -------------------------------- # Client array : start # -------------------------------- logger.info("connecting, client_count=%s", client_count) dt_start = SolBase.datecurrent() dt_cur = SolBase.datecurrent() connected_count = 0 for local_client in self.arTcpClient: # Connect self.assertTrue(local_client.connect()) # Check client self.assertIsNotNone(local_client.current_socket) self.assertTrue(local_client.is_connected) connected_count += 1 if SolBase.datediff(dt_cur) > 1000: dt_cur = SolBase.datecurrent() elapsed_ms = SolBase.datediff(dt_start) if elapsed_ms > 0: connect_per_sec = client_count / (elapsed_ms * 0.001) else: connect_per_sec = 0 logger.info( "connecting, client_count=%s, connected_count=%s, perSec=%.2f", client_count, connected_count, connect_per_sec) elapsed_ms = SolBase.datediff(dt_start) if elapsed_ms > 0: connect_per_sec = client_count / (elapsed_ms * 0.001) else: connect_per_sec = 0 logger.info( "connecting, client_count=%s, connected_count=%s, perSec=%.2f", client_count, connected_count, connect_per_sec) # -------------------------------- # Wait for server # -------------------------------- logger.info("waiting for server") dt_start = SolBase.datecurrent() while SolBase.datediff(dt_start) < self.checkTimeOutMs: if len(self.tcp_server._client_connected_hash) == client_count: break logger.info("waiting for server : connected=%s, target=%s", len(self.tcp_server._client_connected_hash), client_count) SolBase.sleep(int(self.checkTimeOutMs / 100)) logger.info("waiting for server : done : connected=%s, target=%s", len(self.tcp_server._client_connected_hash), client_count) # Check self.assertEqual(len(self.tcp_server._client_connected_hash), client_count) # -------------------------------- # Done # -------------------------------- logger.info("all client connected")
def _read_loop_internal(self): """ Low level read loop on socket """ logger.debug("entering now, self=%s", self) try: while self.__is_running(): try: if self.__ssl_handshake_pending: # Pending SSL handshake + received something # Handle SSL handshake now # Stats Meters.dtci("tcp.server.delay_server_accept_to_sslhandshakestart", SolBase.datediff(self._dt_created)) # Timestamps self._dt_last_recv = SolBase.datecurrent() # Debug ONLY if self.__ssl_wait_debug_ms: logger.warning("DEBUG : forcing a wait for SSL handshake timeout, ms=%s, self=%s", self.__ssl_wait_debug_ms, self) SolBase.sleep(self.__ssl_wait_debug_ms) logger.warning("DEBUG : forcing a wait for SSL handshake timeout, done, self=%s", self) # Do the handshake # TODO : gevent 1.3 : This is now broken due to underlying _sslobj None. To be checked. SSL support current disable. raise Exception("SSL Support currently disabled") # noinspection PyUnreachableCode self.current_socket.do_handshake() # Done, cancel timeout self._unschedule_ssl_handshake_timeout() # Ms ms = SolBase.datediff(self._dt_last_recv) # SSL Stats (for client) self._set_ssl_handshake_ms(ms) # Server stats Meters.dtci("tcp.server.delay_server_sslhandshake", ms) # Done self.__ssl_handshake_pending = False # Non blocking mode now self.current_socket.setblocking(0) self.current_socket.settimeout(None) # Reloop in normal mode continue # Wait for socket to be available for read ok = self._wait_for_socket_recv() if not ok: # This is not really normal logger.warning("_wait_for_socket_recv returned False, self=%s", self) elif not self.__is_running(): logger.debug("_wait_for_socket_recv returned True, __is_running()==False, exiting, self=%s", self) return else: # Something to read... local_buf = self._read_from_socket() if not self.__is_running(): logger.debug("_read_from_socket returned, __is_running()==False, exiting, self=%s", self) elif local_buf is None: # This is not really normal logger.debug("_read_from_socket returned None, self=%s", self) elif len(local_buf) == 0: # This is not really normal logger.debug("_read_from_socket returned empty string, self=%s", self) # Gevent 1.0.2 : call disconnect self._disconnect_helper("_read_from_socket returned empty string") else: # Timestamps self._dt_last_recv = SolBase.datecurrent() # Notify if self._callback_receive: self._callback_receive(local_buf) else: logger.error("_callback_receive is None, check you implementation, self=%s", self) # Next read SolBase.sleep(0) except Exception as e: logger.warning("IN_LOOP Exception raised, ex=%s, self=%s", SolBase.extostr(e), self) except Exception as e: logger.error("METHOD Exception raised, ex=%s, self=%s", SolBase.extostr(e), self) finally: logger.debug("exiting now, self=%s", self) SolBase.sleep(0)
def _stop_multi_client(self): """ Test """ if self.arTcpClient is None: return # -------------------------------- # Disconnect # -------------------------------- logger.info("disconnecting, clientCount=%s", len(self.arTcpClient)) ko_count_socket = 0 ko_count_is_connected = 0 for local_client in self.arTcpClient: # Kill client local_client.disconnect() # Check client if local_client.current_socket: ko_count_socket += 1 if local_client.is_connected: ko_count_is_connected += 1 if ko_count_socket == 0 and ko_count_is_connected == 0: logger.info( "disconnecting, ko_count_socket=%s, ko_count_is_connected=%s", ko_count_socket, ko_count_is_connected) else: logger.error( "disconnecting, ko_count_socket=%s, ko_count_is_connected=%s", ko_count_socket, ko_count_is_connected) # -------------------------------- # Clean up # -------------------------------- self.arTcpClient = None # -------------------------------- # Server should be disconnected from client # Wait for server # -------------------------------- logger.info("wait for server disconnection") dt_start = SolBase.datecurrent() while SolBase.datediff(dt_start) < self.checkTimeOutMs: # Check if len(self.tcp_server._client_connected_hash) == 0: break # Log logger.info("waiting for server : connected/target=%s/0", len(self.tcp_server._client_connected_hash)) # Wait SolBase.sleep(int(self.checkTimeOutMs / 100)) # Check logger.info("check for disconnection") self.assertTrue(len(self.tcp_server._client_connected_hash) == 0) self.assertTrue(ko_count_socket == 0) self.assertTrue(ko_count_is_connected == 0) # Done logger.info("all done")