From a5ef0ac229869009d93df784f547ac948f862736 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 21 Sep 2018 10:56:20 +0200 Subject: [PATCH 01/16] edit logger configs --- config/logger_client.ini | 2 +- config/logger_server.ini | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/logger_client.ini b/config/logger_client.ini index 10411db..fc97d55 100644 --- a/config/logger_client.ini +++ b/config/logger_client.ini @@ -22,7 +22,7 @@ format=%(asctime)s,%(msecs)03d - %(module)-15s [%(levelname)-8s] %(message)s datefmt=%d.%m.%Y %H:%M:%S [formatter_complex] -format=%(asctime)s,%(msecs)03d - %(module)-15s %(funcName)-18s [%(levelname)-8s] %(message)s +format=%(asctime)s,%(msecs)03d - %(threadName)-15s %(module)-15s %(funcName)-18s [%(levelname)-8s] %(message)s datefmt=%d.%m.%Y %H:%M:%S [handlers] diff --git a/config/logger_server.ini b/config/logger_server.ini index f6d17ed..faf2f45 100644 --- a/config/logger_server.ini +++ b/config/logger_server.ini @@ -22,7 +22,7 @@ format=%(asctime)s,%(msecs)03d - %(module)-15s [%(levelname)-8s] %(message)s datefmt=%d.%m.%Y %H:%M:%S [formatter_complex] -format=%(asctime)s,%(msecs)03d - %(module)-15s %(funcName)-18s [%(levelname)-8s] %(message)s +format=%(asctime)s,%(msecs)03d - %(threadName)-15s %(module)-15s %(funcName)-18s [%(levelname)-8s] %(message)s datefmt=%d.%m.%Y %H:%M:%S [handlers] From c7e301317fe11f2f8e8c086033ff718692d97796 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 21 Sep 2018 12:35:23 +0200 Subject: [PATCH 02/16] add timer and netCheck --- boswatch/network/netCheck.py | 35 +++++++++++++++++ boswatch/utils/timer.py | 74 ++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 boswatch/network/netCheck.py create mode 100644 boswatch/utils/timer.py diff --git a/boswatch/network/netCheck.py b/boswatch/network/netCheck.py new file mode 100644 index 0000000..4cccd1b --- /dev/null +++ b/boswatch/network/netCheck.py @@ -0,0 +1,35 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +"""! + ____ ____ ______ __ __ __ _____ + / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ / + / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ < + / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ / +/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/ + German BOS Information Script + by Bastian Schroll + +@file: netCheck.py +@date: 21.09.2018 +@author: Bastian Schroll +@description: Worker to check internet connection +""" +import logging +from urllib.request import urlopen + +logging.debug("- %s loaded", __name__) + + +class NetCheck: + """!Worker class to check internet connection""" + + def __init__(self, hostname="https://www.google.com/", timeout=1): + self._hostname = hostname + self._timeout = timeout + + def checkConn(self): + try: + urlopen(self._hostname, timeout=self._timeout) + return True + except: + return False diff --git a/boswatch/utils/timer.py b/boswatch/utils/timer.py new file mode 100644 index 0000000..49fb809 --- /dev/null +++ b/boswatch/utils/timer.py @@ -0,0 +1,74 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +"""! + ____ ____ ______ __ __ __ _____ + / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ / + / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ < + / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ / +/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/ + German BOS Information Script + by Bastian Schroll + +@file: timer.py +@date: 21.09.2018 +@author: Bastian Schroll +@description: Timer class for interval timed events +""" +import logging +import time +from threading import Thread, Event + +logging.debug("- %s loaded", __name__) + + +class RepeatedTimer: + + def __init__(self, interval, targetFunction, *args, **kwargs): + """!Create a new instance of the RepeatedTimer + + @param interval: interval in sec. to recall target function + @param targetFunction: function to call on timer event + @param *args: arguments for the called function + @param *kwargs: keyword arguments for the called function + """ + self._interval = interval + self._function = targetFunction + self._args = args + self._kwargs = kwargs + self._start = 0 + self._event = Event() + self._thread = None + + def start(self): + """!Start a new timer worker thread""" + self._event.clear() + self._thread = Thread(target=self._target) + self._thread.name = "RepTim(" + str(self._interval) + ")" + self._start = time.time() + self._thread.start() + logging.debug("start repeatedTimer: %s", self._thread.name) + + def stop(self): + """!Stop the timer worker thread""" + self._event.set() + self._thread.join() + logging.debug("stop repeatedTimer: %s", self._thread.name) + + def _target(self): + """!Runs the target function with his arguments""" + while not self._event.wait(self.restTime): + logging.debug("work") + startTime = time.time() + self._function(*self._args, **self._kwargs) + time.sleep(1.5) + runTime = time.time() - startTime + + if runTime < self._interval: + logging.debug("ready after: %0.3f sec. - next call in: %0.3f sec.", runTime, self.restTime) + else: + logging.warning("timer overdue! interval: %0.3f sec. - runtime: %0.3f sec.", self._interval, runTime) + + @property + def restTime(self): + """!Property to get remaining time till next call""" + return self._interval - ((time.time() - self._start) % self._interval) From b300d0c578e49f0c9d0bdd5c142d8e61d7b2f3a5 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 21 Sep 2018 12:39:36 +0200 Subject: [PATCH 03/16] add docu to NetCheck class --- boswatch/network/netCheck.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/boswatch/network/netCheck.py b/boswatch/network/netCheck.py index 4cccd1b..8b69703 100644 --- a/boswatch/network/netCheck.py +++ b/boswatch/network/netCheck.py @@ -24,10 +24,17 @@ class NetCheck: """!Worker class to check internet connection""" def __init__(self, hostname="https://www.google.com/", timeout=1): + """!Create a new NetCheck instance + + @param hostname: host against connection check is running ("https://www.google.com/") + @param timout: timout for connection check in sec.""" self._hostname = hostname self._timeout = timeout def checkConn(self): + """!Check the connection + + @return True or False""" try: urlopen(self._hostname, timeout=self._timeout) return True From 91389a9c5b5e35faf9ac9aa1c362a750393d834e Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 21 Sep 2018 13:30:41 +0200 Subject: [PATCH 04/16] add timer unittest --- boswatch/utils/timer.py | 25 ++++++++++++++------ test/test_timer.py | 51 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 7 deletions(-) create mode 100644 test/test_timer.py diff --git a/boswatch/utils/timer.py b/boswatch/utils/timer.py index 49fb809..64cf379 100644 --- a/boswatch/utils/timer.py +++ b/boswatch/utils/timer.py @@ -44,25 +44,36 @@ class RepeatedTimer: self._event.clear() self._thread = Thread(target=self._target) self._thread.name = "RepTim(" + str(self._interval) + ")" - self._start = time.time() self._thread.start() logging.debug("start repeatedTimer: %s", self._thread.name) + return True def stop(self): - """!Stop the timer worker thread""" + """!Stop the timer worker thread + + @return True or False""" self._event.set() - self._thread.join() - logging.debug("stop repeatedTimer: %s", self._thread.name) + if self._thread is not None: + logging.debug("stop repeatedTimer: %s", self._thread.name) + self._thread.join() + return True + else: + logging.warning("repeatedTimer always stopped") + return False def _target(self): """!Runs the target function with his arguments""" + self._start = time.time() while not self._event.wait(self.restTime): logging.debug("work") startTime = time.time() - self._function(*self._args, **self._kwargs) - time.sleep(1.5) - runTime = time.time() - startTime + try: + self._function(*self._args, **self._kwargs) + except: + logging.exception("target throws an exception") + + runTime = time.time() - startTime if runTime < self._interval: logging.debug("ready after: %0.3f sec. - next call in: %0.3f sec.", runTime, self.restTime) else: diff --git a/test/test_timer.py b/test/test_timer.py new file mode 100644 index 0000000..29161ed --- /dev/null +++ b/test/test_timer.py @@ -0,0 +1,51 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +"""! + ____ ____ ______ __ __ __ _____ + / __ )/ __ \/ ___/ | / /___ _/ /______/ /_ |__ / + / __ / / / /\__ \| | /| / / __ `/ __/ ___/ __ \ /_ < + / /_/ / /_/ /___/ /| |/ |/ / /_/ / /_/ /__/ / / / ___/ / +/_____/\____//____/ |__/|__/\__,_/\__/\___/_/ /_/ /____/ + German BOS Information Script + by Bastian Schroll + +@file: test_timer.py +@date: 21.09.2019 +@author: Bastian Schroll +@description: Unittests for BOSWatch. File must be _run as "pytest" unittest +""" +import logging +import time +import pytest + +from boswatch.utils.timer import RepeatedTimer + + +class Test_Timer: + """!Unittest for the timer class""" + + def setup_method(self, method): + logging.debug("[TEST] %s.%s", type(self).__name__, method.__name__) + + @staticmethod + def testTarget(): + logging.debug("run testTarget") + + @pytest.fixture(scope="function") + def useTimer(self): + """!Server a RepeatedTimer instance""" + self.testTimer = RepeatedTimer(0.5, Test_Timer.testTarget) + time.sleep(0.1) + yield 1 + + def test_timerStartStop(self, useTimer): + assert self.testTimer.start() + assert self.testTimer.stop() + + def test_timerStopNotStarted(self, useTimer): + assert not self.testTimer.stop() + + def test_timerRun(self, useTimer): + assert self.testTimer.start() + time.sleep(0.6) + assert self.testTimer.stop() From 11eab418ed931f19c366f6b6b03f453603805136 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 21 Sep 2018 14:21:33 +0200 Subject: [PATCH 05/16] improve exc handling and tests --- boswatch/network/client.py | 3 +-- boswatch/network/server.py | 4 +++- boswatch/utils/timer.py | 28 ++++++++++++++++++++-------- test/test_timer.py | 15 +++++++++++---- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/boswatch/network/client.py b/boswatch/network/client.py index c0eac72..a8604da 100644 --- a/boswatch/network/client.py +++ b/boswatch/network/client.py @@ -26,8 +26,7 @@ class TCPClient: def __init__(self, timeout=3): """!Create a new instance - Create a new instance of an TCP Client. - And set the timeout""" + @param timeout: timout for the client in sec. (3)""" try: self._sock = None self._timeout = timeout diff --git a/boswatch/network/server.py b/boswatch/network/server.py index f3a4be0..27df38c 100644 --- a/boswatch/network/server.py +++ b/boswatch/network/server.py @@ -75,7 +75,9 @@ class TCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer): """!TCP server class""" def __init__(self, timeout=3): - """!Create a new instance""" + """!Create a new instance + + @param timeout: timeout for the server in sec. (3)""" self._server = None self._server_thread = None self._timeout = timeout diff --git a/boswatch/utils/timer.py b/boswatch/utils/timer.py index 64cf379..0416035 100644 --- a/boswatch/utils/timer.py +++ b/boswatch/utils/timer.py @@ -36,17 +36,24 @@ class RepeatedTimer: self._args = args self._kwargs = kwargs self._start = 0 + self._overdueCount = 0 self._event = Event() self._thread = None def start(self): - """!Start a new timer worker thread""" - self._event.clear() - self._thread = Thread(target=self._target) - self._thread.name = "RepTim(" + str(self._interval) + ")" - self._thread.start() - logging.debug("start repeatedTimer: %s", self._thread.name) - return True + """!Start a new timer worker thread + + @return True or False""" + try: + self._event.clear() + self._thread = Thread(target=self._target) + self._thread.name = "RepTim(" + str(self._interval) + ")" + self._thread.start() + logging.debug("start repeatedTimer: %s", self._thread.name) + return True + except: + logging.exception("cannot start timer worker thread") + return False def stop(self): """!Stop the timer worker thread @@ -78,8 +85,13 @@ class RepeatedTimer: logging.debug("ready after: %0.3f sec. - next call in: %0.3f sec.", runTime, self.restTime) else: logging.warning("timer overdue! interval: %0.3f sec. - runtime: %0.3f sec.", self._interval, runTime) - + self._overdueCount += 1 @property def restTime(self): """!Property to get remaining time till next call""" return self._interval - ((time.time() - self._start) % self._interval) + + @property + def overdueCount(self): + """!Property to get a count over all iverdues""" + return self._overdueCount diff --git a/test/test_timer.py b/test/test_timer.py index 29161ed..4c8b3c6 100644 --- a/test/test_timer.py +++ b/test/test_timer.py @@ -20,6 +20,7 @@ import pytest from boswatch.utils.timer import RepeatedTimer +# todo add more tests to overlap all testcases class Test_Timer: """!Unittest for the timer class""" @@ -28,15 +29,21 @@ class Test_Timer: logging.debug("[TEST] %s.%s", type(self).__name__, method.__name__) @staticmethod - def testTarget(): - logging.debug("run testTarget") + def testTargetFast(): + logging.debug("run testTargetFast") + + @staticmethod + def testTargetSlow(): + logging.debug("run testTargetSlow start") + time.sleep(1) + logging.debug("run testTargetSlow end") @pytest.fixture(scope="function") def useTimer(self): """!Server a RepeatedTimer instance""" - self.testTimer = RepeatedTimer(0.5, Test_Timer.testTarget) + self.testTimer = RepeatedTimer(0.5, Test_Timer.testTargetFast) time.sleep(0.1) - yield 1 + yield 1 # server the timer instance def test_timerStartStop(self, useTimer): assert self.testTimer.start() From 3cf0b49c0e83c12760ace632d28e49f17202d5e7 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 21 Sep 2018 14:30:20 +0200 Subject: [PATCH 06/16] start timer as daemon --- boswatch/utils/timer.py | 1 + test/test_timer.py | 1 + 2 files changed, 2 insertions(+) diff --git a/boswatch/utils/timer.py b/boswatch/utils/timer.py index 0416035..be69ec4 100644 --- a/boswatch/utils/timer.py +++ b/boswatch/utils/timer.py @@ -48,6 +48,7 @@ class RepeatedTimer: self._event.clear() self._thread = Thread(target=self._target) self._thread.name = "RepTim(" + str(self._interval) + ")" + self._thread.daemon = True # start as daemon (thread dies if main program ends) self._thread.start() logging.debug("start repeatedTimer: %s", self._thread.name) return True diff --git a/test/test_timer.py b/test/test_timer.py index 4c8b3c6..e567ac5 100644 --- a/test/test_timer.py +++ b/test/test_timer.py @@ -22,6 +22,7 @@ from boswatch.utils.timer import RepeatedTimer # todo add more tests to overlap all testcases + class Test_Timer: """!Unittest for the timer class""" From cecde860057927ca85eb2ef5ef8a6f4c1c07c556 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 21 Sep 2018 15:27:02 +0200 Subject: [PATCH 07/16] insert logging --- boswatch/network/netCheck.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/boswatch/network/netCheck.py b/boswatch/network/netCheck.py index 8b69703..2c2e991 100644 --- a/boswatch/network/netCheck.py +++ b/boswatch/network/netCheck.py @@ -27,7 +27,7 @@ class NetCheck: """!Create a new NetCheck instance @param hostname: host against connection check is running ("https://www.google.com/") - @param timout: timout for connection check in sec.""" + @param timout: timout for connection check in sec. (1)""" self._hostname = hostname self._timeout = timeout @@ -37,6 +37,8 @@ class NetCheck: @return True or False""" try: urlopen(self._hostname, timeout=self._timeout) + logging.debug("%s is reachable", self._hostname) return True except: + logging.warning("%s is not reachable", self._hostname) return False From 2b572a659cd832c711a47b9efb30759fe09ec0ba Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 21 Sep 2018 15:27:53 +0200 Subject: [PATCH 08/16] add repTimer in testserver --- bw_server.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/bw_server.py b/bw_server.py index f9853dd..8ab6b48 100644 --- a/bw_server.py +++ b/bw_server.py @@ -57,6 +57,13 @@ except Exception as e: # pragma: no cover print(e) exit(1) + +from boswatch.utils.timer import RepeatedTimer +from boswatch.network.netCheck import NetCheck +net = NetCheck() +test = RepeatedTimer(10, net.checkConn) +test.start() + try: header.logoToLog() header.infoToLog() @@ -111,10 +118,10 @@ try: # # t1 = threading.Timer(1, eins) # t2 = threading.Timer(5, zwei) - t3 = threading.Timer(15, drei) + # t3 = threading.Timer(600, drei) # t1.start() # t2.start() - t3.start() + # t3.start() bwServer = TCPServer(bwConfig.getInt("Server", "PORT")) if bwServer.start(): From 407de76ccf53a25288dedfb4cb372d63397bb8b5 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Fri, 21 Sep 2018 20:14:56 +0200 Subject: [PATCH 09/16] edit comments --- boswatch/utils/timer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/boswatch/utils/timer.py b/boswatch/utils/timer.py index be69ec4..cb89dda 100644 --- a/boswatch/utils/timer.py +++ b/boswatch/utils/timer.py @@ -70,7 +70,7 @@ class RepeatedTimer: return False def _target(self): - """!Runs the target function with his arguments""" + """!Runs the target function with his arguments in own thread""" self._start = time.time() while not self._event.wait(self.restTime): logging.debug("work") @@ -94,5 +94,5 @@ class RepeatedTimer: @property def overdueCount(self): - """!Property to get a count over all iverdues""" + """!Property to get a count over all overdues""" return self._overdueCount From 71065672a7ab2c11068623733db075fc00efbc5a Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sun, 23 Sep 2018 18:44:58 +0200 Subject: [PATCH 10/16] some improvements --- boswatch/network/netCheck.py | 9 +++++++++ boswatch/utils/timer.py | 2 ++ bw_server.py | 5 ++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/boswatch/network/netCheck.py b/boswatch/network/netCheck.py index 2c2e991..c71d0ba 100644 --- a/boswatch/network/netCheck.py +++ b/boswatch/network/netCheck.py @@ -30,6 +30,8 @@ class NetCheck: @param timout: timout for connection check in sec. (1)""" self._hostname = hostname self._timeout = timeout + self._connectionState = False + self.checkConn() # initiate a first check def checkConn(self): """!Check the connection @@ -38,7 +40,14 @@ class NetCheck: try: urlopen(self._hostname, timeout=self._timeout) logging.debug("%s is reachable", self._hostname) + self._connectionState = True return True except: logging.warning("%s is not reachable", self._hostname) + self._connectionState = False return False + + @property + def connectionState(self): + """!Property for the last connection state from checkConn()""" + return self._connectionState diff --git a/boswatch/utils/timer.py b/boswatch/utils/timer.py index cb89dda..c9521f3 100644 --- a/boswatch/utils/timer.py +++ b/boswatch/utils/timer.py @@ -87,6 +87,8 @@ class RepeatedTimer: else: logging.warning("timer overdue! interval: %0.3f sec. - runtime: %0.3f sec.", self._interval, runTime) self._overdueCount += 1 + logging.debug("repeatedTimer thread stopped: %s", self._thread.name) + @property def restTime(self): """!Property to get remaining time till next call""" diff --git a/bw_server.py b/bw_server.py index 4814dcf..414d78b 100644 --- a/bw_server.py +++ b/bw_server.py @@ -61,8 +61,11 @@ except Exception as e: # pragma: no cover from boswatch.utils.timer import RepeatedTimer from boswatch.network.netCheck import NetCheck net = NetCheck() -test = RepeatedTimer(10, net.checkConn) +test = RepeatedTimer(3, net.checkConn) test.start() +time.sleep(10) +print(net.connectionState) +test.stop() try: header.logoToLog() From cb08ad4e88dc2361c551c00cccac18d798e88d55 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sun, 23 Sep 2018 21:08:44 +0200 Subject: [PATCH 11/16] improve timer tests and add some fixes --- boswatch/utils/timer.py | 35 ++++++++++++++++++++--------- test/test_timer.py | 50 ++++++++++++++++++++++++++++++++--------- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/boswatch/utils/timer.py b/boswatch/utils/timer.py index c9521f3..6bb32a8 100644 --- a/boswatch/utils/timer.py +++ b/boswatch/utils/timer.py @@ -37,6 +37,8 @@ class RepeatedTimer: self._kwargs = kwargs self._start = 0 self._overdueCount = 0 + self._lostEvents = 0 + self._isRunning = False self._event = Event() self._thread = None @@ -45,14 +47,18 @@ class RepeatedTimer: @return True or False""" try: - self._event.clear() - self._thread = Thread(target=self._target) - self._thread.name = "RepTim(" + str(self._interval) + ")" - self._thread.daemon = True # start as daemon (thread dies if main program ends) - self._thread.start() - logging.debug("start repeatedTimer: %s", self._thread.name) - return True - except: + if self._thread is None: + self._event.clear() + self._thread = Thread(target=self._target) + self._thread.name = "RepTim(" + str(self._interval) + ")" + self._thread.daemon = True # start as daemon (thread dies if main program ends) + self._thread.start() + logging.debug("start repeatedTimer: %s", self._thread.name) + return True + else: + logging.debug("repeatedTimer always started") + return True + except: # pragma: no cover logging.exception("cannot start timer worker thread") return False @@ -64,6 +70,7 @@ class RepeatedTimer: if self._thread is not None: logging.debug("stop repeatedTimer: %s", self._thread.name) self._thread.join() + self._thread = None return True else: logging.warning("repeatedTimer always stopped") @@ -78,14 +85,17 @@ class RepeatedTimer: try: self._function(*self._args, **self._kwargs) - except: + except: # pragma: no cover logging.exception("target throws an exception") runTime = time.time() - startTime if runTime < self._interval: logging.debug("ready after: %0.3f sec. - next call in: %0.3f sec.", runTime, self.restTime) else: - logging.warning("timer overdue! interval: %0.3f sec. - runtime: %0.3f sec.", self._interval, runTime) + lostEvents = int(runTime / self._interval) + logging.warning("timer overdue! interval: %0.3f sec. - runtime: %0.3f sec. - " + "%d events lost - next call in: %0.3f sec.", self._interval, runTime, lostEvents, self.restTime) + self._lostEvents += lostEvents self._overdueCount += 1 logging.debug("repeatedTimer thread stopped: %s", self._thread.name) @@ -98,3 +108,8 @@ class RepeatedTimer: def overdueCount(self): """!Property to get a count over all overdues""" return self._overdueCount + + @property + def lostEvents(self): + """!Property to get a count over all los events""" + return self._lostEvents diff --git a/test/test_timer.py b/test/test_timer.py index e567ac5..76630c1 100644 --- a/test/test_timer.py +++ b/test/test_timer.py @@ -20,8 +20,6 @@ import pytest from boswatch.utils.timer import RepeatedTimer -# todo add more tests to overlap all testcases - class Test_Timer: """!Unittest for the timer class""" @@ -31,29 +29,59 @@ class Test_Timer: @staticmethod def testTargetFast(): + """!Fast worker thread""" logging.debug("run testTargetFast") @staticmethod def testTargetSlow(): + """!Slow worker thread""" logging.debug("run testTargetSlow start") - time.sleep(1) + time.sleep(0.51) logging.debug("run testTargetSlow end") @pytest.fixture(scope="function") - def useTimer(self): - """!Server a RepeatedTimer instance""" - self.testTimer = RepeatedTimer(0.5, Test_Timer.testTargetFast) - time.sleep(0.1) + def useTimerFast(self): + """!Server a RepeatedTimer instance with fast worker""" + self.testTimer = RepeatedTimer(0.1, Test_Timer.testTargetFast) yield 1 # server the timer instance - def test_timerStartStop(self, useTimer): + @pytest.fixture(scope="function") + def useTimerSlow(self): + """!Server a RepeatedTimer instance slow worker""" + self.testTimer = RepeatedTimer(0.1, Test_Timer.testTargetSlow) + yield 1 # server the timer instance + + # test cases starts here + + def test_timerStartStop(self, useTimerFast): assert self.testTimer.start() assert self.testTimer.stop() - def test_timerStopNotStarted(self, useTimer): + def test_timerDoubleSTart(self, useTimerFast): + assert self.testTimer.start() + assert self.testTimer.start() + assert self.testTimer.stop() + + def test_timerStopNotStarted(self, useTimerFast): assert not self.testTimer.stop() - def test_timerRun(self, useTimer): + def test_timerRun(self, useTimerFast): assert self.testTimer.start() - time.sleep(0.6) + time.sleep(0.2) assert self.testTimer.stop() + assert self.testTimer.overdueCount == 0 + assert self.testTimer.lostEvents == 0 + + def test_timerOverdue(self, useTimerSlow): + assert self.testTimer.start() + time.sleep(0.2) + assert self.testTimer.stop() + assert self.testTimer.overdueCount == 1 + assert self.testTimer.lostEvents == 5 + + def test_timerOverdueLong(self, useTimerSlow): + assert self.testTimer.start() + time.sleep(1) + assert self.testTimer.stop() + assert self.testTimer.overdueCount == 2 + assert self.testTimer.lostEvents == 10 From 3435022483a3470b504b8c38fe2b4d7ce4045265 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sun, 23 Sep 2018 21:15:37 +0200 Subject: [PATCH 12/16] improve tests, add is Running prop --- boswatch/utils/timer.py | 8 +++++++- test/test_timer.py | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/boswatch/utils/timer.py b/boswatch/utils/timer.py index 6bb32a8..f69c76d 100644 --- a/boswatch/utils/timer.py +++ b/boswatch/utils/timer.py @@ -70,7 +70,6 @@ class RepeatedTimer: if self._thread is not None: logging.debug("stop repeatedTimer: %s", self._thread.name) self._thread.join() - self._thread = None return True else: logging.warning("repeatedTimer always stopped") @@ -98,6 +97,13 @@ class RepeatedTimer: self._lostEvents += lostEvents self._overdueCount += 1 logging.debug("repeatedTimer thread stopped: %s", self._thread.name) + self._Thread = None # set to none after leave teh thread (running recognize) + + @property + def isRunning(self): + if self._thread: + return True + return False @property def restTime(self): diff --git a/test/test_timer.py b/test/test_timer.py index 76630c1..28462f1 100644 --- a/test/test_timer.py +++ b/test/test_timer.py @@ -44,12 +44,16 @@ class Test_Timer: """!Server a RepeatedTimer instance with fast worker""" self.testTimer = RepeatedTimer(0.1, Test_Timer.testTargetFast) yield 1 # server the timer instance + if self.testTimer.isRunning: + self.testTimer.stop() @pytest.fixture(scope="function") def useTimerSlow(self): """!Server a RepeatedTimer instance slow worker""" self.testTimer = RepeatedTimer(0.1, Test_Timer.testTargetSlow) yield 1 # server the timer instance + if self.testTimer.isRunning: + self.testTimer.stop() # test cases starts here @@ -65,6 +69,11 @@ class Test_Timer: def test_timerStopNotStarted(self, useTimerFast): assert not self.testTimer.stop() + def test_timerIsRunning(self, useTimerFast): + assert self.testTimer.start() + assert self.testTimer.isRunning + assert self.testTimer.stop() + def test_timerRun(self, useTimerFast): assert self.testTimer.start() time.sleep(0.2) From 362e1001b32b0b805ee258bb0c39357332733fe0 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sun, 23 Sep 2018 21:15:37 +0200 Subject: [PATCH 13/16] improve tests, add is Running prop --- boswatch/utils/timer.py | 8 +++++++- test/test_timer.py | 9 +++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/boswatch/utils/timer.py b/boswatch/utils/timer.py index 6bb32a8..f69c76d 100644 --- a/boswatch/utils/timer.py +++ b/boswatch/utils/timer.py @@ -70,7 +70,6 @@ class RepeatedTimer: if self._thread is not None: logging.debug("stop repeatedTimer: %s", self._thread.name) self._thread.join() - self._thread = None return True else: logging.warning("repeatedTimer always stopped") @@ -98,6 +97,13 @@ class RepeatedTimer: self._lostEvents += lostEvents self._overdueCount += 1 logging.debug("repeatedTimer thread stopped: %s", self._thread.name) + self._Thread = None # set to none after leave teh thread (running recognize) + + @property + def isRunning(self): + if self._thread: + return True + return False @property def restTime(self): diff --git a/test/test_timer.py b/test/test_timer.py index 76630c1..28462f1 100644 --- a/test/test_timer.py +++ b/test/test_timer.py @@ -44,12 +44,16 @@ class Test_Timer: """!Server a RepeatedTimer instance with fast worker""" self.testTimer = RepeatedTimer(0.1, Test_Timer.testTargetFast) yield 1 # server the timer instance + if self.testTimer.isRunning: + self.testTimer.stop() @pytest.fixture(scope="function") def useTimerSlow(self): """!Server a RepeatedTimer instance slow worker""" self.testTimer = RepeatedTimer(0.1, Test_Timer.testTargetSlow) yield 1 # server the timer instance + if self.testTimer.isRunning: + self.testTimer.stop() # test cases starts here @@ -65,6 +69,11 @@ class Test_Timer: def test_timerStopNotStarted(self, useTimerFast): assert not self.testTimer.stop() + def test_timerIsRunning(self, useTimerFast): + assert self.testTimer.start() + assert self.testTimer.isRunning + assert self.testTimer.stop() + def test_timerRun(self, useTimerFast): assert self.testTimer.start() time.sleep(0.2) From 575cc1f19acf5a996254a691e63bd417eeeac5e4 Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Sun, 23 Sep 2018 21:39:50 +0200 Subject: [PATCH 14/16] fixes --- boswatch/utils/timer.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/boswatch/utils/timer.py b/boswatch/utils/timer.py index f69c76d..8e373e2 100644 --- a/boswatch/utils/timer.py +++ b/boswatch/utils/timer.py @@ -71,9 +71,8 @@ class RepeatedTimer: logging.debug("stop repeatedTimer: %s", self._thread.name) self._thread.join() return True - else: - logging.warning("repeatedTimer always stopped") - return False + logging.warning("repeatedTimer always stopped") + return False def _target(self): """!Runs the target function with his arguments in own thread""" @@ -97,10 +96,11 @@ class RepeatedTimer: self._lostEvents += lostEvents self._overdueCount += 1 logging.debug("repeatedTimer thread stopped: %s", self._thread.name) - self._Thread = None # set to none after leave teh thread (running recognize) + self._thread = None # set to none after leave teh thread (running recognize) @property def isRunning(self): + """!Property for repeatedTimer running state""" if self._thread: return True return False From 7d2935ea0d1573de0142640f2c76b008d35c1f2d Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Mon, 24 Sep 2018 20:39:25 +0200 Subject: [PATCH 15/16] fixe false date --- test/test_timer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_timer.py b/test/test_timer.py index 28462f1..2fff21f 100644 --- a/test/test_timer.py +++ b/test/test_timer.py @@ -10,7 +10,7 @@ by Bastian Schroll @file: test_timer.py -@date: 21.09.2019 +@date: 21.09.2018 @author: Bastian Schroll @description: Unittests for BOSWatch. File must be _run as "pytest" unittest """ From 3eac36d12301eab5e95db788b0d81bc56a25dc2a Mon Sep 17 00:00:00 2001 From: Bastian Schroll Date: Tue, 25 Sep 2018 10:08:00 +0200 Subject: [PATCH 16/16] some little fixes --- boswatch/utils/timer.py | 16 ++++++++++------ test/test_timer.py | 8 ++++---- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/boswatch/utils/timer.py b/boswatch/utils/timer.py index 8e373e2..449864d 100644 --- a/boswatch/utils/timer.py +++ b/boswatch/utils/timer.py @@ -66,13 +66,17 @@ class RepeatedTimer: """!Stop the timer worker thread @return True or False""" - self._event.set() - if self._thread is not None: - logging.debug("stop repeatedTimer: %s", self._thread.name) - self._thread.join() + try: + self._event.set() + if self._thread is not None: + logging.debug("stop repeatedTimer: %s", self._thread.name) + self._thread.join() + return True + logging.warning("repeatedTimer always stopped") return True - logging.warning("repeatedTimer always stopped") - return False + except: # pragma: no cover + logging.exception("cannot stop repeatedTimer") + return False def _target(self): """!Runs the target function with his arguments in own thread""" diff --git a/test/test_timer.py b/test/test_timer.py index 2fff21f..49ff4a6 100644 --- a/test/test_timer.py +++ b/test/test_timer.py @@ -45,7 +45,7 @@ class Test_Timer: self.testTimer = RepeatedTimer(0.1, Test_Timer.testTargetFast) yield 1 # server the timer instance if self.testTimer.isRunning: - self.testTimer.stop() + assert self.testTimer.stop() @pytest.fixture(scope="function") def useTimerSlow(self): @@ -53,7 +53,7 @@ class Test_Timer: self.testTimer = RepeatedTimer(0.1, Test_Timer.testTargetSlow) yield 1 # server the timer instance if self.testTimer.isRunning: - self.testTimer.stop() + assert self.testTimer.stop() # test cases starts here @@ -61,13 +61,13 @@ class Test_Timer: assert self.testTimer.start() assert self.testTimer.stop() - def test_timerDoubleSTart(self, useTimerFast): + def test_timerDoubleStart(self, useTimerFast): assert self.testTimer.start() assert self.testTimer.start() assert self.testTimer.stop() def test_timerStopNotStarted(self, useTimerFast): - assert not self.testTimer.stop() + assert self.testTimer.stop() def test_timerIsRunning(self, useTimerFast): assert self.testTimer.start()