2018-01-07 21:51:43 +01:00
|
|
|
#!/usr/bin/python
|
|
|
|
|
# -*- coding: utf-8 -*-
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!
|
2018-01-07 21:51:43 +01:00
|
|
|
____ ____ ______ __ __ __ _____
|
|
|
|
|
/ __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ /
|
|
|
|
|
/ __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ <
|
|
|
|
|
/ /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ /
|
|
|
|
|
/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/
|
|
|
|
|
German BOS Information Script
|
|
|
|
|
by Bastian Schroll
|
|
|
|
|
|
|
|
|
|
@file: test_ServerClient.py
|
|
|
|
|
@date: 10.12.2017
|
|
|
|
|
@author: Bastian Schroll
|
2019-03-03 11:13:27 +01:00
|
|
|
@description: Unittests for BOSWatch. File have to run as "pytest" unittest
|
2018-01-07 21:51:43 +01:00
|
|
|
"""
|
2019-03-03 19:18:19 +01:00
|
|
|
# problem of the pytest fixtures
|
|
|
|
|
# pylint: disable=redefined-outer-name
|
2018-01-12 07:48:27 +01:00
|
|
|
import logging
|
2018-01-07 21:51:43 +01:00
|
|
|
import time
|
2018-09-20 23:35:56 +02:00
|
|
|
import queue
|
2018-09-20 07:37:10 +02:00
|
|
|
import pytest
|
2018-01-07 21:51:43 +01:00
|
|
|
|
2018-01-11 12:59:53 +01:00
|
|
|
from boswatch.network.server import TCPServer
|
|
|
|
|
from boswatch.network.client import TCPClient
|
2019-10-23 09:01:11 +02:00
|
|
|
import threading
|
2018-01-07 21:51:43 +01:00
|
|
|
|
|
|
|
|
|
2019-10-24 23:11:57 +02:00
|
|
|
def setup_function(function):
|
|
|
|
|
logging.debug("[TEST] %s.%s", function.__module__, function.__name__)
|
2019-03-03 11:13:27 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def getClient():
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Build and serve a TCPCLient"""
|
2019-03-03 11:13:27 +01:00
|
|
|
return TCPClient()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def getServer():
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Build and serve a TCPServer"""
|
2019-03-03 11:13:27 +01:00
|
|
|
dataQueue = queue.Queue()
|
|
|
|
|
testServer = TCPServer(dataQueue)
|
|
|
|
|
return testServer
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
|
def getRunningServer(getServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Build and serve a still running TCPServer"""
|
2019-03-03 11:13:27 +01:00
|
|
|
logging.debug("start server")
|
|
|
|
|
assert getServer.start()
|
2019-03-03 20:08:31 +01:00
|
|
|
while not getServer.isRunning:
|
|
|
|
|
pass
|
2019-03-03 11:13:27 +01:00
|
|
|
yield getServer
|
|
|
|
|
logging.debug("stop server")
|
|
|
|
|
assert getServer.stop()
|
2019-03-03 20:08:31 +01:00
|
|
|
time.sleep(0.1) # wait for safe stopped
|
2019-03-03 11:13:27 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_clientConnectFailed(getClient):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Connect to a non available server"""
|
2019-03-03 11:13:27 +01:00
|
|
|
assert not getClient.connect()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_clientDisconnectFailed(getClient):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Disconnect while no connection is established"""
|
2019-03-03 11:13:27 +01:00
|
|
|
assert getClient.disconnect()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_clientTransmitFailed(getClient):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Transmit while no connection is established"""
|
2019-03-03 11:13:27 +01:00
|
|
|
assert not getClient.transmit("test")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_clientReceiveFailed(getClient):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Receive while no connection is established"""
|
2019-03-03 11:13:27 +01:00
|
|
|
assert not getClient.receive()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_clientConnect(getClient, getRunningServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Connect to a server"""
|
2019-03-03 11:13:27 +01:00
|
|
|
assert getClient.connect()
|
|
|
|
|
assert getClient.disconnect()
|
|
|
|
|
|
|
|
|
|
|
2019-10-20 17:56:40 +02:00
|
|
|
def test_doubleConnect(getClient, getRunningServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Connect to a server twice"""
|
2019-10-20 17:56:40 +02:00
|
|
|
assert getClient.connect()
|
|
|
|
|
assert getClient.connect()
|
|
|
|
|
assert getClient.disconnect()
|
|
|
|
|
|
|
|
|
|
|
2019-03-03 11:13:27 +01:00
|
|
|
def test_clientReconnect(getClient, getRunningServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Try a reconnect after a established connection"""
|
2019-03-03 11:13:27 +01:00
|
|
|
assert getClient.connect()
|
|
|
|
|
assert getClient.disconnect()
|
|
|
|
|
assert getClient.connect()
|
|
|
|
|
assert getClient.disconnect()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_clientMultiConnect(getClient, getRunningServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Connect with 2 clients to the server"""
|
2019-03-03 11:13:27 +01:00
|
|
|
assert getClient.connect()
|
|
|
|
|
testClient2 = TCPClient()
|
|
|
|
|
assert testClient2.connect()
|
|
|
|
|
time.sleep(0.1) # wait for all clients connected
|
|
|
|
|
# check connected clients
|
|
|
|
|
assert getRunningServer.countClientsConnected() == 2
|
|
|
|
|
# disconnect all
|
|
|
|
|
assert getClient.disconnect()
|
|
|
|
|
assert testClient2.disconnect()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_clientCommunicate(getClient, getRunningServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Try to send data to the server and check on '[ack]'"""
|
2019-03-03 11:13:27 +01:00
|
|
|
assert getClient.connect()
|
|
|
|
|
assert getClient.transmit("test")
|
|
|
|
|
assert getClient.receive() == "[ack]"
|
|
|
|
|
assert getClient.disconnect()
|
|
|
|
|
|
|
|
|
|
|
2019-03-03 20:00:04 +01:00
|
|
|
@pytest.mark.skip("needs fixture for more than one client")
|
2019-03-03 11:13:27 +01:00
|
|
|
def test_clientMultiCommunicate(getServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Try to send data to the server with 3 clients and check on '[ack]'"""
|
2019-03-03 11:13:27 +01:00
|
|
|
# connect all
|
|
|
|
|
testClient1 = TCPClient()
|
|
|
|
|
assert testClient1.connect()
|
|
|
|
|
testClient2 = TCPClient()
|
|
|
|
|
assert testClient2.connect()
|
|
|
|
|
testClient3 = TCPClient()
|
|
|
|
|
assert testClient3.connect()
|
|
|
|
|
# send all
|
|
|
|
|
assert testClient1.transmit("test")
|
|
|
|
|
assert testClient2.transmit("test")
|
|
|
|
|
assert testClient3.transmit("test")
|
|
|
|
|
# recv all
|
|
|
|
|
assert testClient3.receive() == "[ack]"
|
|
|
|
|
assert testClient2.receive() == "[ack]"
|
|
|
|
|
assert testClient1.receive() == "[ack]"
|
|
|
|
|
# check server msg queue
|
2019-10-23 09:01:11 +02:00
|
|
|
assert getRunningServer._alarmQueue.qsize() == 3
|
2019-03-03 11:13:27 +01:00
|
|
|
# disconnect all
|
|
|
|
|
assert testClient1.disconnect()
|
|
|
|
|
assert testClient2.disconnect()
|
|
|
|
|
assert testClient3.disconnect()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_serverRestart(getRunningServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Test a stop and restart of the server"""
|
2019-03-03 11:13:27 +01:00
|
|
|
assert getRunningServer.stop()
|
|
|
|
|
assert getRunningServer.start()
|
|
|
|
|
assert getRunningServer.stop()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_serverStopFailed(getServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Test to stop a stopped server"""
|
2019-03-03 11:13:27 +01:00
|
|
|
assert getServer.stop()
|
|
|
|
|
|
|
|
|
|
|
2019-10-21 11:22:53 +02:00
|
|
|
def test_serverDoubleStart(getServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Test to start the server twice"""
|
2019-10-21 11:22:53 +02:00
|
|
|
assert getServer.start()
|
|
|
|
|
assert getServer.start()
|
|
|
|
|
assert getServer.stop()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_serverStartTwoInstances():
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Test to start two server different server instances"""
|
2019-03-03 11:13:27 +01:00
|
|
|
dataQueue = queue.Queue()
|
|
|
|
|
testServer1 = TCPServer(dataQueue)
|
|
|
|
|
testServer2 = TCPServer(dataQueue)
|
|
|
|
|
assert testServer1.start()
|
2019-10-21 10:11:54 +02:00
|
|
|
assert testServer1.isRunning
|
2019-10-21 11:53:12 +02:00
|
|
|
assert not testServer2.start()
|
2019-10-21 10:11:54 +02:00
|
|
|
assert testServer1.isRunning
|
2019-10-21 12:24:25 +02:00
|
|
|
assert not testServer2.isRunning
|
2019-03-03 11:13:27 +01:00
|
|
|
assert testServer1.stop()
|
|
|
|
|
assert testServer2.stop()
|
|
|
|
|
|
|
|
|
|
|
2019-10-20 17:11:20 +02:00
|
|
|
def test_serverStopsWhileConnected(getRunningServer, getClient):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Shutdown server while client is connected"""
|
2019-10-20 17:11:20 +02:00
|
|
|
getClient.connect()
|
|
|
|
|
getRunningServer.stop()
|
2019-10-23 09:19:32 +02:00
|
|
|
timeout = 5
|
2019-10-20 17:37:37 +02:00
|
|
|
while getClient.isConnected:
|
2019-10-20 19:07:16 +02:00
|
|
|
time.sleep(0.1)
|
2019-10-20 17:37:37 +02:00
|
|
|
timeout = timeout - 1
|
2019-10-23 22:11:57 +02:00
|
|
|
if timeout == 0:
|
2019-10-21 11:22:53 +02:00
|
|
|
break
|
|
|
|
|
assert timeout
|
2019-10-20 17:11:20 +02:00
|
|
|
|
|
|
|
|
|
2019-03-03 20:00:04 +01:00
|
|
|
@pytest.mark.skip("needs fixture for more than one client")
|
2019-03-03 11:13:27 +01:00
|
|
|
def test_serverGetOutput(getRunningServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!Send data to server with 2 clients, check '[ack]' and data on server queue"""
|
2019-03-03 11:13:27 +01:00
|
|
|
# connect all
|
|
|
|
|
testClient1 = TCPClient()
|
|
|
|
|
assert testClient1.connect()
|
|
|
|
|
testClient2 = TCPClient()
|
|
|
|
|
assert testClient2.connect()
|
|
|
|
|
# send all
|
|
|
|
|
assert testClient1.transmit("test1")
|
|
|
|
|
time.sleep(0.1) # wait for recv to prevent fail of false order
|
|
|
|
|
assert testClient2.transmit("test2")
|
|
|
|
|
# recv all
|
|
|
|
|
assert testClient1.receive() == "[ack]"
|
|
|
|
|
assert testClient2.receive() == "[ack]"
|
|
|
|
|
# _check server output data
|
2019-10-23 09:01:11 +02:00
|
|
|
assert getRunningServer._alarmQueue.qsize() == 2
|
|
|
|
|
assert getRunningServer._alarmQueue.get(True, 1)[1] == "test1"
|
|
|
|
|
assert getRunningServer._alarmQueue.get(True, 1)[1] == "test2"
|
2019-10-23 22:11:57 +02:00
|
|
|
assert getRunningServer._alarmQueue.qsize() == 0 # Last _check must be None
|
2019-03-03 11:13:27 +01:00
|
|
|
# disconnect all
|
|
|
|
|
assert testClient1.disconnect()
|
|
|
|
|
assert testClient2.disconnect()
|
2019-10-23 09:01:11 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_serverHighLoad(getRunningServer):
|
2023-09-19 16:13:23 +02:00
|
|
|
r"""!High load server test with 10 send threads each will send 100 msg with 324 bytes size"""
|
2019-10-23 09:01:11 +02:00
|
|
|
logging.debug("start sendThreads")
|
|
|
|
|
threads = []
|
|
|
|
|
for thr_id in range(10):
|
2019-10-23 09:19:32 +02:00
|
|
|
thr = threading.Thread(target=sendThread, name="sendThread-" + str(thr_id))
|
2019-10-23 09:01:11 +02:00
|
|
|
thr.daemon = True
|
|
|
|
|
thr.start()
|
|
|
|
|
threads.append(thr)
|
|
|
|
|
for thread in threads:
|
|
|
|
|
thread.join()
|
|
|
|
|
logging.debug("finished sendThreads")
|
|
|
|
|
assert getRunningServer._alarmQueue.qsize() == 1000
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def sendThread():
|
|
|
|
|
client = TCPClient()
|
|
|
|
|
client.connect()
|
|
|
|
|
time.sleep(0.1)
|
|
|
|
|
for i in range(100):
|
|
|
|
|
# actually this string is 324 bytes long
|
|
|
|
|
client.transmit("HigLoadTestString-HigLoadTestString-HigLoadTestString-HigLoadTestString-HigLoadTestString-HigLoadTestString-"
|
|
|
|
|
"HigLoadTestString-HigLoadTestString-HigLoadTestString-HigLoadTestString-HigLoadTestString-HigLoadTestString-"
|
|
|
|
|
"HigLoadTestString-HigLoadTestString-HigLoadTestString-HigLoadTestString-HigLoadTestString-HigLoadTestString-")
|
|
|
|
|
if not client.receive() == "[ack]":
|
|
|
|
|
logging.error("missing [ACK]")
|
|
|
|
|
|
|
|
|
|
time.sleep(0.1)
|
|
|
|
|
client.disconnect()
|