From 809857ab98c6a16a2ee2e307d52e3e0f13c25473 Mon Sep 17 00:00:00 2001 From: Nick Date: Tue, 15 May 2018 11:33:51 +0200 Subject: [PATCH 01/12] gitlab-ci: added make as dependency --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 70c6f30..7886a87 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,7 +22,7 @@ build:fedora_x86: image: fedora:latest stage: build before_script: - - yum -y install cmake pkgconfig gcc-c++ rpmdevtools + - yum -y install make cmake pkgconfig gcc-c++ rpmdevtools script: - mkdir output.dir/ - cd output.dir From fa0b7a295e005ad8b61753f3d3aa96785dab9beb Mon Sep 17 00:00:00 2001 From: Nick Date: Wed, 16 May 2018 22:01:11 +0200 Subject: [PATCH 02/12] gitlab-ci tests: switched to 'cmake test' target --- .gitlab-ci.yml | 6 +++--- tests/run_itests.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7886a87..0f456ee 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -69,8 +69,8 @@ test_x86: script: - mkdir -p output.dir/ - cd output.dir - - cmake -DTESTS=True ../ - - make VERBOSE=1 + - cmake ../ + - make # execute all tests - - ./test_* + - make VERBOSE=1 CTEST_OUTPUT_ON_FAILURE=1 test diff --git a/tests/run_itests.sh b/tests/run_itests.sh index c1018ad..07038d3 100755 --- a/tests/run_itests.sh +++ b/tests/run_itests.sh @@ -24,7 +24,7 @@ function teardown() { } trap teardown EXIT -setup || exit 1 +setup || (echo "failed to setup" && exit 1) $CWD/run_itests.py || exit 1 From ccf0beb800dc2532b27a6b217ab88a92a636c790 Mon Sep 17 00:00:00 2001 From: Nick Date: Wed, 16 May 2018 22:13:01 +0200 Subject: [PATCH 03/12] gitlab-ci ctest: added twisted as dependency --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0f456ee..5a7f0c2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -62,7 +62,7 @@ test_x86: - apt update -qq - apt install -y -qq build-essential pkg-config cmake - apt install -y -qq python-dev python-pip python-setuptools socat - - python -m pip install pymodbus service_identity + - python -m pip install pymodbus service_identity twisted dependencies: - build:deb_x86 From ecf63b992b69e8519900d833e3a8305514248a1b Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 18 Jun 2018 14:13:51 +0200 Subject: [PATCH 04/12] tests: moved rtu_slave handling inside pythons realm --- ...runner.sh => notneeded_rtu_slave_runner.sh} | 0 tests/run_itests.py | 18 +++++++++++++++++- tests/run_itests.sh | 4 ++-- 3 files changed, 19 insertions(+), 3 deletions(-) rename tests/environment/{rtu_slave_runner.sh => notneeded_rtu_slave_runner.sh} (100%) diff --git a/tests/environment/rtu_slave_runner.sh b/tests/environment/notneeded_rtu_slave_runner.sh similarity index 100% rename from tests/environment/rtu_slave_runner.sh rename to tests/environment/notneeded_rtu_slave_runner.sh diff --git a/tests/run_itests.py b/tests/run_itests.py index 8f25527..71d5b8b 100755 --- a/tests/run_itests.py +++ b/tests/run_itests.py @@ -2,25 +2,41 @@ import random import unittest +import sys from pymodbus.client.sync import ModbusTcpClient -from pymodbus.pdu import ExceptionResponse, ModbusExceptions +from pymodbus.pdu import ExceptionResponse from pymodbus.bit_read_message import ReadDiscreteInputsResponse, ReadCoilsResponse from pymodbus.bit_write_message import WriteMultipleCoilsResponse, WriteSingleCoilResponse from pymodbus.register_read_message import ReadInputRegistersResponse, ReadHoldingRegistersResponse from pymodbus.register_write_message import WriteMultipleRegistersResponse, WriteSingleRegisterResponse +from environment.rtu_slave import ModbusSerialServer + MBUSD_PORT = 1025 + class TestModbusRequests(unittest.TestCase): + @classmethod def setUpClass(cls): + cls.log = logging.getLogger("TestModbusRequests") + + cls.mbs = ModbusSerialServer() + cls.mbs.start() + cls.client = ModbusTcpClient('127.0.0.1', port=MBUSD_PORT) cls.client.connect() @classmethod def tearDownClass(cls): + cls.log.info("test teardown") cls.client.close() + try: + cls.mbs.kill() + except e: + cls.log.info("Fetched exception during mbs.kill") + def test_coils(self): bits = [random.randrange(2)>0 for i in range(8)] diff --git a/tests/run_itests.sh b/tests/run_itests.sh index 07038d3..ad77920 100755 --- a/tests/run_itests.sh +++ b/tests/run_itests.sh @@ -12,14 +12,14 @@ export MBUSD_BIN=$1 function setup() { echo "[I] do test environment setup" $CWD/environment/socat_runner.sh start || return 1 - $CWD/environment/rtu_slave_runner.sh start || return 1 + # $CWD/environment/rtu_slave_runner.sh start || return 1 $CWD/environment/mbusd_runner.sh start || return 1 } function teardown() { echo "[I] do test environment teardown" $CWD/environment/mbusd_runner.sh stop - $CWD/environment/rtu_slave_runner.sh stop + # $CWD/environment/rtu_slave_runner.sh stop $CWD/environment/socat_runner.sh stop } trap teardown EXIT From ae360073bfddfed066bebcbafc74e74df292ce52 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 18 Jun 2018 14:15:01 +0200 Subject: [PATCH 05/12] tests: better logging for all testcases --- tests/environment/rtu_slave.py | 9 +++------ tests/run_itests.py | 8 +++++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/tests/environment/rtu_slave.py b/tests/environment/rtu_slave.py index 0ecf462..f882077 100644 --- a/tests/environment/rtu_slave.py +++ b/tests/environment/rtu_slave.py @@ -8,6 +8,7 @@ The asynchronous server is a high performance implementation using the twisted library as its backend. This allows it to scale to many thousands of nodes which can be helpful for testing monitoring software. ''' +import logging #---------------------------------------------------------------------------# # import the various server implementations #---------------------------------------------------------------------------# @@ -26,10 +27,7 @@ class ModbusSerialServer: #---------------------------------------------------------------------------# # configure the service logging #---------------------------------------------------------------------------# - import logging - logging.basicConfig() - log = logging.getLogger() - log.setLevel(logging.DEBUG) + log = logging.getLogger("ModbusServer") serialPort = readlink('/tmp/pts1') @@ -126,9 +124,8 @@ class ModbusSerialServer: self.p.start() print("p.start done") - def kill(self): - print("Going to terminate the process, this could throw exceptions") + self.log.info("Going to terminate the process, this could throw exceptions") if self.p is not None: self.p.terminate() diff --git a/tests/run_itests.py b/tests/run_itests.py index 71d5b8b..fa2f5c8 100755 --- a/tests/run_itests.py +++ b/tests/run_itests.py @@ -106,4 +106,10 @@ class TestModbusRequests(unittest.TestCase): if __name__ == '__main__': - unittest.main() \ No newline at end of file + import logging + stdout_handler = logging.StreamHandler(sys.stdout) + logging.basicConfig(level=logging.DEBUG, + format=u'[%(asctime)s] %(name)-26s-%(levelname)-5s %(funcName)-20s:%(lineno)-4d \033[35m%(message)s\033[0m', + datefmt='%d.%m. %H:%M:%S', + handlers=[stdout_handler]) + unittest.main(verbosity=2) \ No newline at end of file From 74189d6caf345b2cf800f356001d620a6d80cefd Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 18 Jun 2018 16:06:16 +0200 Subject: [PATCH 06/12] test: moved all setup/teardown into the python realm --- .../environment/notneeded_rtu_slave_runner.sh | 28 ------------- tests/run_itests.py | 40 +++++++++++++------ tests/run_itests.sh | 20 +--------- 3 files changed, 29 insertions(+), 59 deletions(-) delete mode 100755 tests/environment/notneeded_rtu_slave_runner.sh diff --git a/tests/environment/notneeded_rtu_slave_runner.sh b/tests/environment/notneeded_rtu_slave_runner.sh deleted file mode 100755 index b14db06..0000000 --- a/tests/environment/notneeded_rtu_slave_runner.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -RTU_SLAVE_PID=/tmp/rtu_slave.pid - -CURRENT_DIR="$(dirname "$(realpath "$0")")" -. $CURRENT_DIR/subprocess_helper.sh - -check_preconditions() { - python -c "import pymodbus" || exit 1 -} - -# check argument count -## https://stackoverflow.com/questions/4341630/checking-for-the-correct-number-of-arguments -if [ "$#" -ne 1 ]; then - echo "[E] usage: $0 " >&2 - exit 1 -fi - -check_preconditions -case "$1" in - up|start) - CMD="python ${CURRENT_DIR}/rtu_slave.py &" - run_cmd_save_pid "$CMD" $RTU_SLAVE_PID - ;; - down|stop) - kill_pid $RTU_SLAVE_PID - ;; -esac diff --git a/tests/run_itests.py b/tests/run_itests.py index fa2f5c8..3625cbb 100755 --- a/tests/run_itests.py +++ b/tests/run_itests.py @@ -3,6 +3,9 @@ import random import unittest import sys +import logging +from subprocess import Popen +from os.path import isfile from pymodbus.client.sync import ModbusTcpClient from pymodbus.pdu import ExceptionResponse @@ -11,31 +14,41 @@ from pymodbus.bit_write_message import WriteMultipleCoilsResponse, WriteSingleCo from pymodbus.register_read_message import ReadInputRegistersResponse, ReadHoldingRegistersResponse from pymodbus.register_write_message import WriteMultipleRegistersResponse, WriteSingleRegisterResponse -from environment.rtu_slave import ModbusSerialServer - -MBUSD_PORT = 1025 - +MBUSD_PORT = 1025 +MBUSD_BINARY = "../output.dir/mbusd" class TestModbusRequests(unittest.TestCase): + log = logging.getLogger("TestModbusRequests") @classmethod def setUpClass(cls): - cls.log = logging.getLogger("TestModbusRequests") + cls.log.debug("1. run socat") + cls.socat = Popen(["socat", "-d", "-d", "pty,raw,echo=0,link=/tmp/pts0", "pty,raw,echo=0,link=/tmp/pts1"]) + cls.log.debug("2. run rtu_slave") + from environment.rtu_slave import ModbusSerialServer cls.mbs = ModbusSerialServer() cls.mbs.start() + cls.log.debug("3. run mbusd to be tested with the binary:%s" % MBUSD_BINARY) + cls.mbusd_main = Popen([MBUSD_BINARY, "-d", "-L", "-v9", "-p/tmp/pts0", "-s19200", "-P" + str(MBUSD_PORT)]) + + cls.log.debug("4. connect the modbus TCP client to mbusd") cls.client = ModbusTcpClient('127.0.0.1', port=MBUSD_PORT) cls.client.connect() @classmethod def tearDownClass(cls): cls.log.info("test teardown") + + cls.log.debug("4. kill tcp_client") cls.client.close() - try: - cls.mbs.kill() - except e: - cls.log.info("Fetched exception during mbs.kill") + cls.log.debug("3. kill mbusd") + cls.mbusd_main.kill() + cls.log.debug("2. kill rtu_slave") + cls.mbs.kill() + cls.log.debug("1. kill socat") + cls.socat.kill() def test_coils(self): @@ -104,12 +117,15 @@ class TestModbusRequests(unittest.TestCase): self.assertEqual(result.original_code, 5, result) # fc05 Write Single Coil self.assertEqual(result.exception_code, 2, result) # Illegal Data Address - if __name__ == '__main__': - import logging stdout_handler = logging.StreamHandler(sys.stdout) logging.basicConfig(level=logging.DEBUG, format=u'[%(asctime)s] %(name)-26s-%(levelname)-5s %(funcName)-20s:%(lineno)-4d \033[35m%(message)s\033[0m', datefmt='%d.%m. %H:%M:%S', handlers=[stdout_handler]) - unittest.main(verbosity=2) \ No newline at end of file + if len(sys.argv) != 2 or not isfile(sys.argv[1]): + logging.error("usage: ./run_itests.py ") + sys.exit(1) + MBUSD_BINARY = sys.argv[1] + + unittest.main(verbosity=2, argv=[sys.argv[0]]) diff --git a/tests/run_itests.sh b/tests/run_itests.sh index ad77920..bf7dc36 100755 --- a/tests/run_itests.sh +++ b/tests/run_itests.sh @@ -8,24 +8,6 @@ if ! [ -x "$1" ]; then fi export MBUSD_BIN=$1 - -function setup() { - echo "[I] do test environment setup" - $CWD/environment/socat_runner.sh start || return 1 - # $CWD/environment/rtu_slave_runner.sh start || return 1 - $CWD/environment/mbusd_runner.sh start || return 1 -} - -function teardown() { - echo "[I] do test environment teardown" - $CWD/environment/mbusd_runner.sh stop - # $CWD/environment/rtu_slave_runner.sh stop - $CWD/environment/socat_runner.sh stop -} -trap teardown EXIT - -setup || (echo "failed to setup" && exit 1) - -$CWD/run_itests.py || exit 1 +$CWD/run_itests.py "$MBUSD_BIN" || exit 1 exit 0 From b28678831dd22231fa3de46221e7793c31fe23d1 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 18 Jun 2018 16:46:17 +0200 Subject: [PATCH 07/12] gitlab-ci: changed test execution, reduced apt deps --- .gitlab-ci.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5a7f0c2..ff5e932 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,7 +34,7 @@ build:deb_armhf: stage: build before_script: - apt update -qq - - apt install -y -qq build-essential pkg-config cmake gcc-arm-linux-gnueabihf + - apt install -y -qq --no-install-recommends build-essential pkg-config cmake gcc-arm-linux-gnueabihf script: - mkdir output.dir/ - cd output.dir @@ -46,7 +46,7 @@ build:deb_x86: stage: build before_script: - apt update -qq - - apt install -y -qq build-essential pkg-config cmake + - apt install -y -qq --no-install-recommends build-essential pkg-config cmake script: - mkdir output.dir/ - cd output.dir @@ -60,17 +60,17 @@ test_x86: #https://forum.gitlab.com/t/testing-copy-yaml-file-to-build-folder/8309 before_script: - apt update -qq - - apt install -y -qq build-essential pkg-config cmake - - apt install -y -qq python-dev python-pip python-setuptools socat + - apt install -y -qq --no-install-recommends build-essential pkg-config cmake + - apt install -y -qq --no-install-recommends python-dev python-pip python-setuptools socat - python -m pip install pymodbus service_identity twisted dependencies: - build:deb_x86 script: - - mkdir -p output.dir/ - - cd output.dir + - mkdir -p output.dir/ && cd $_ - cmake ../ - make # execute all tests - - make VERBOSE=1 CTEST_OUTPUT_ON_FAILURE=1 test + - (cd ../ && python tests/run_itests.py output.dir/mbusd) + #- make VERBOSE=1 CTEST_OUTPUT_ON_FAILURE=1 test From e092b4e9354ee92e827b6da4d8893a7c7504cfe7 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 18 Jun 2018 16:51:46 +0200 Subject: [PATCH 08/12] gitlab-ci: fixing the arm build --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ff5e932..881258c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -34,7 +34,7 @@ build:deb_armhf: stage: build before_script: - apt update -qq - - apt install -y -qq --no-install-recommends build-essential pkg-config cmake gcc-arm-linux-gnueabihf + - apt install -y -qq build-essential pkg-config cmake gcc-arm-linux-gnueabihf script: - mkdir output.dir/ - cd output.dir From fabae052383f527ec87993c745bb238731af93cc Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 18 Jun 2018 17:02:56 +0200 Subject: [PATCH 09/12] added __init__ to test/environment --- tests/environment/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tests/environment/__init__.py diff --git a/tests/environment/__init__.py b/tests/environment/__init__.py new file mode 100644 index 0000000..e69de29 From 0a35ef68b61136e88aaad126be053e05a1eecce8 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 18 Jun 2018 21:15:34 +0200 Subject: [PATCH 10/12] tests: running into race conditions --- tests/run_itests.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/run_itests.py b/tests/run_itests.py index 3625cbb..8fcb3a9 100755 --- a/tests/run_itests.py +++ b/tests/run_itests.py @@ -6,6 +6,7 @@ import sys import logging from subprocess import Popen from os.path import isfile +from time import sleep from pymodbus.client.sync import ModbusTcpClient from pymodbus.pdu import ExceptionResponse @@ -32,6 +33,8 @@ class TestModbusRequests(unittest.TestCase): cls.log.debug("3. run mbusd to be tested with the binary:%s" % MBUSD_BINARY) cls.mbusd_main = Popen([MBUSD_BINARY, "-d", "-L", "-v9", "-p/tmp/pts0", "-s19200", "-P" + str(MBUSD_PORT)]) + # wait a little bit for mbusd to come up + sleep(5) cls.log.debug("4. connect the modbus TCP client to mbusd") cls.client = ModbusTcpClient('127.0.0.1', port=MBUSD_PORT) From 1c94fda030525a1f39176bf1ed2945e4e4daae67 Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 18 Jun 2018 21:33:01 +0200 Subject: [PATCH 11/12] ci: moved test stage before the build stage --- .gitlab-ci.yml | 2 +- tests/run_itests.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 881258c..8f08c79 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,7 @@ --- stages: - - build - test + - build .mbusd_job_template: &mbusd_job_template # Hidden key that defines an anchor image: debian:stable diff --git a/tests/run_itests.py b/tests/run_itests.py index 8fcb3a9..adc52e2 100755 --- a/tests/run_itests.py +++ b/tests/run_itests.py @@ -34,6 +34,8 @@ class TestModbusRequests(unittest.TestCase): cls.log.debug("3. run mbusd to be tested with the binary:%s" % MBUSD_BINARY) cls.mbusd_main = Popen([MBUSD_BINARY, "-d", "-L", "-v9", "-p/tmp/pts0", "-s19200", "-P" + str(MBUSD_PORT)]) # wait a little bit for mbusd to come up + # alternatively do a poll for the socket + # https://stackoverflow.com/questions/667640/how-to-tell-if-a-connection-is-dead-in-python/667702#667702 sleep(5) cls.log.debug("4. connect the modbus TCP client to mbusd") From ab99734d87cd27fb44ea92dbe6e4052dc0e900bb Mon Sep 17 00:00:00 2001 From: Nick Date: Mon, 18 Jun 2018 21:34:33 +0200 Subject: [PATCH 12/12] ci: fixing dependency issues --- .gitlab-ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8f08c79..abc9c2f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -64,8 +64,6 @@ test_x86: - apt install -y -qq --no-install-recommends python-dev python-pip python-setuptools socat - python -m pip install pymodbus service_identity twisted - dependencies: - - build:deb_x86 script: - mkdir -p output.dir/ && cd $_ - cmake ../