From 4f5d51c1446fe7753bd4d782f510aaf8e643f4df Mon Sep 17 00:00:00 2001 From: Greg Date: Tue, 6 Aug 2019 17:45:16 +0300 Subject: [PATCH 01/14] added the feature, bad ut --- src/rotest/management/client/websocket_client.py | 8 +++++++- tests/api/channel_tests.py | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/rotest/management/client/websocket_client.py b/src/rotest/management/client/websocket_client.py index 204c316f..a30d1465 100644 --- a/src/rotest/management/client/websocket_client.py +++ b/src/rotest/management/client/websocket_client.py @@ -1,5 +1,5 @@ """Websocket client that sends pings periodically.""" -# pylint: disable=broad-except,bare-except +# pylint: disable=broad-except,bare-except,no-self-use import threading import websocket @@ -32,6 +32,11 @@ def close(self, *args, **kwargs): self.pinging_event.set() self.pinging_thread.join() + def handle_disconnection(self): + """Called on server disconnection.""" + from rotest.common import core_log + core_log.warn("Server disconnetion detected!") + def ping_loop(self): """Ping periodically until the finish event.""" while not self.pinging_event.wait(self.ping_interval): @@ -39,4 +44,5 @@ def ping_loop(self): self.send("ping") except: # noqa + self.handle_disconnection() break diff --git a/tests/api/channel_tests.py b/tests/api/channel_tests.py index b37d3c5c..c3dc22c0 100644 --- a/tests/api/channel_tests.py +++ b/tests/api/channel_tests.py @@ -4,6 +4,10 @@ import mock from channels.test import ChannelTestCase, Client +from rotest.common.config import DJANGO_MANAGER_PORT +from rotest.management.client.client import AbstractClient +from rotest.management.client.websocket_client import PingingWebsocket + class ChannelTests(ChannelTestCase): """Tests for consumer behavior.""" @@ -19,3 +23,14 @@ def test_close_session(self, mock_callback): client.send_and_consume('websocket.receive', message_content) client.send_and_consume('websocket.disconnect', {}) mock_callback.assert_called_with(self.TEST_TOKEN) + + @mock.patch('rotest.management.client.websocket_client.' + 'PingingWebsocket.handle_disconnection') + def test_server_disconnection(self, mock_callback): + """Check that 'close_session' is called at disconnect.""" + client = PingingWebsocket(ping_interval=1) + server_address = AbstractClient.WEBSOCKET_TARGET.format( + host="localhost", + port=DJANGO_MANAGER_PORT) + client.connect(server_address) + mock_callback.assert_called_with(self.TEST_TOKEN) From 274e13bbe2003d76275435e48f29d66fea61f7e0 Mon Sep 17 00:00:00 2001 From: UnDarkle Date: Thu, 8 Aug 2019 10:22:34 +0300 Subject: [PATCH 02/14] fixed the ws client ut --- tests/api/channel_tests.py | 15 -------------- tests/management/test_resource_manager.py | 25 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/tests/api/channel_tests.py b/tests/api/channel_tests.py index c3dc22c0..b37d3c5c 100644 --- a/tests/api/channel_tests.py +++ b/tests/api/channel_tests.py @@ -4,10 +4,6 @@ import mock from channels.test import ChannelTestCase, Client -from rotest.common.config import DJANGO_MANAGER_PORT -from rotest.management.client.client import AbstractClient -from rotest.management.client.websocket_client import PingingWebsocket - class ChannelTests(ChannelTestCase): """Tests for consumer behavior.""" @@ -23,14 +19,3 @@ def test_close_session(self, mock_callback): client.send_and_consume('websocket.receive', message_content) client.send_and_consume('websocket.disconnect', {}) mock_callback.assert_called_with(self.TEST_TOKEN) - - @mock.patch('rotest.management.client.websocket_client.' - 'PingingWebsocket.handle_disconnection') - def test_server_disconnection(self, mock_callback): - """Check that 'close_session' is called at disconnect.""" - client = PingingWebsocket(ping_interval=1) - server_address = AbstractClient.WEBSOCKET_TARGET.format( - host="localhost", - port=DJANGO_MANAGER_PORT) - client.connect(server_address) - mock_callback.assert_called_with(self.TEST_TOKEN) diff --git a/tests/management/test_resource_manager.py b/tests/management/test_resource_manager.py index 90f6ffad..201bd449 100644 --- a/tests/management/test_resource_manager.py +++ b/tests/management/test_resource_manager.py @@ -9,6 +9,7 @@ import time from threading import Thread +from unittest import TestCase import mock from future.builtins import zip, range @@ -20,10 +21,12 @@ from rotest.management import BaseResource, ResourceRequest from rotest.management.models.resource_data import DataPointer from rotest.management.client.manager import ClientResourceManager +from rotest.management.client.websocket_client import PingingWebsocket from rotest.management.common.resource_descriptor import \ ResourceDescriptor as Descriptor from rotest.management.models.ut_models import (DemoResourceData, DemoComplexResourceData) + from rotest.management.models.ut_resources import (DemoService, DemoResource, DemoComplexResource) @@ -2036,3 +2039,25 @@ def test_locking_resource_with_group_none(self): % (self.NO_GROUP_RESOURCE, resource.name)) self.get_resource(self.NO_GROUP_RESOURCE, owner="") + + +class ClientWebsocketTests(TestCase): + """Tests for client behavior.""" + + TEST_ADDRESS = 'localhost' + + @mock.patch('websocket._core.handshake') + @mock.patch('websocket._core.connect') + @mock.patch('rotest.management.client.websocket_client.' + 'PingingWebsocket.handle_disconnection') + def test_server_disconnection(self, mock_callback, mock_connect, _): + """Check that 'close_session' is called at disconnect.""" + client = PingingWebsocket(ping_interval=0.2) + mock_socket = mock.MagicMock() + mock_connect.return_value = mock_socket, self.TEST_ADDRESS + client.connect(self.TEST_ADDRESS) + time.sleep(0.6) + mock_callback.assert_not_called() + mock_socket.send.side_effect = RuntimeError + time.sleep(0.6) + mock_callback.assert_called_once() From bb96e09402632c89bd4f2ce5b90d147e555776d9 Mon Sep 17 00:00:00 2001 From: UnDarkle Date: Thu, 8 Aug 2019 10:25:00 +0300 Subject: [PATCH 03/14] bumped version and increase ping rate --- setup.py | 2 +- src/rotest/management/client/websocket_client.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 9bf059b4..e8da112b 100644 --- a/setup.py +++ b/setup.py @@ -3,7 +3,7 @@ from setuptools import setup, find_packages -__version__ = "7.9.1" +__version__ = "7.9.2" result_handlers = [ "db = rotest.core.result.handlers.db_handler:DBHandler", diff --git a/src/rotest/management/client/websocket_client.py b/src/rotest/management/client/websocket_client.py index a30d1465..d35e9005 100644 --- a/src/rotest/management/client/websocket_client.py +++ b/src/rotest/management/client/websocket_client.py @@ -11,7 +11,7 @@ class PingingWebsocket(websocket.WebSocket): Attributes: ping_interval (number): interval between pings in seconds, default 15. """ - def __init__(self, ping_interval=15, *args, **kwargs): + def __init__(self, ping_interval=10, *args, **kwargs): super(PingingWebsocket, self).__init__(*args, **kwargs) self.ping_interval = ping_interval self.pinging_thread = None From af37e5596dec7289e0e544eb0f5d2f10eb2170a5 Mon Sep 17 00:00:00 2001 From: UnDarkle Date: Thu, 8 Aug 2019 11:03:34 +0300 Subject: [PATCH 04/14] fixed by tox --- src/rotest/management/client/websocket_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rotest/management/client/websocket_client.py b/src/rotest/management/client/websocket_client.py index d35e9005..415f02d8 100644 --- a/src/rotest/management/client/websocket_client.py +++ b/src/rotest/management/client/websocket_client.py @@ -35,7 +35,7 @@ def close(self, *args, **kwargs): def handle_disconnection(self): """Called on server disconnection.""" from rotest.common import core_log - core_log.warn("Server disconnetion detected!") + core_log.warning("Server disconnetion detected!") def ping_loop(self): """Ping periodically until the finish event.""" From 022701d006332e774d9dab806f0f6202548cd6e7 Mon Sep 17 00:00:00 2001 From: Greg Date: Thu, 8 Aug 2019 14:00:01 +0300 Subject: [PATCH 05/14] fixed by review --- setup.py | 1 + src/rotest/management/client/websocket_client.py | 3 ++- tests/management/test_resource_manager.py | 11 ++++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index e8da112b..81abf45d 100644 --- a/setup.py +++ b/setup.py @@ -64,6 +64,7 @@ "pathlib2", "flake8", "pylint", + "waiting", ] }, python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*", diff --git a/src/rotest/management/client/websocket_client.py b/src/rotest/management/client/websocket_client.py index 415f02d8..f35f0a49 100644 --- a/src/rotest/management/client/websocket_client.py +++ b/src/rotest/management/client/websocket_client.py @@ -4,6 +4,8 @@ import websocket +from rotest.common import core_log + class PingingWebsocket(websocket.WebSocket): """Websocket client that sends pings periodically. @@ -34,7 +36,6 @@ def close(self, *args, **kwargs): def handle_disconnection(self): """Called on server disconnection.""" - from rotest.common import core_log core_log.warning("Server disconnetion detected!") def ping_loop(self): diff --git a/tests/management/test_resource_manager.py b/tests/management/test_resource_manager.py index 201bd449..167f6d85 100644 --- a/tests/management/test_resource_manager.py +++ b/tests/management/test_resource_manager.py @@ -12,6 +12,7 @@ from unittest import TestCase import mock +from waiting import wait from future.builtins import zip, range from django.db.models.query_utils import Q from django.contrib.auth.models import User @@ -2056,8 +2057,12 @@ def test_server_disconnection(self, mock_callback, mock_connect, _): mock_socket = mock.MagicMock() mock_connect.return_value = mock_socket, self.TEST_ADDRESS client.connect(self.TEST_ADDRESS) - time.sleep(0.6) + wait(lambda: mock_socket.send.call_count > 1, + timeout_seconds=2, sleep_seconds=0.1, + waiting_for='Waiting for 2 pings') + mock_callback.assert_not_called() mock_socket.send.side_effect = RuntimeError - time.sleep(0.6) - mock_callback.assert_called_once() + wait(lambda: mock_callback.call_count > 0, + timeout_seconds=2, sleep_seconds=0.1, + waiting_for='Waiting for disconnection') From 33b70f60522c5af548ccb1324050a6665b8981d3 Mon Sep 17 00:00:00 2001 From: Greg Date: Thu, 8 Aug 2019 14:50:58 +0300 Subject: [PATCH 06/14] pinned django from above --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 81abf45d..2b87ba63 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ url="https://github.com/gregoil/rotest", keywords="testing system django unittest", install_requires=[ - 'django>=1.8,<2.0', + 'django>=1.8,<1.11.23', 'py', 'ipdbugger>=2.5', 'xlwt', From 31aef01ea1ff9693dd218e1ea652c400cb0511f1 Mon Sep 17 00:00:00 2001 From: Greg Date: Thu, 8 Aug 2019 15:26:57 +0300 Subject: [PATCH 07/14] pinned autobahn --- setup.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 2b87ba63..d314c1c6 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ url="https://github.com/gregoil/rotest", keywords="testing system django unittest", install_requires=[ - 'django>=1.8,<1.11.23', + 'django>=1.8,<2.0', 'py', 'ipdbugger>=2.5', 'xlwt', @@ -50,7 +50,8 @@ 'cached_property', 'channels>=1,<2', 'websocket-client>=0.56', - 'pywin32<224; sys.platform == "win32"' + 'autobahn<19.8.0', + 'pywin32<224; sys.platform == "win32"', ], extras_require={ ':python_version=="2.7"': ['statistics'], From 57c6d98f8b8ff3b4802e431d60c37ccc2ba32780 Mon Sep 17 00:00:00 2001 From: Greg Date: Thu, 8 Aug 2019 15:59:57 +0300 Subject: [PATCH 08/14] either twisted or json --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d314c1c6..38203cf1 100644 --- a/setup.py +++ b/setup.py @@ -50,7 +50,8 @@ 'cached_property', 'channels>=1,<2', 'websocket-client>=0.56', - 'autobahn<19.8.0', + 'twisted<19.3.0', + 'jsonschema<3.0.2', 'pywin32<224; sys.platform == "win32"', ], extras_require={ From c8449e46ddf429b9d67d678a3427453a0f288e70 Mon Sep 17 00:00:00 2001 From: Greg Date: Thu, 8 Aug 2019 16:11:08 +0300 Subject: [PATCH 09/14] about to give up --- setup.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index 38203cf1..29dc4f25 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ url="https://github.com/gregoil/rotest", keywords="testing system django unittest", install_requires=[ - 'django>=1.8,<2.0', + 'django>=1.8,<1.11.23', 'py', 'ipdbugger>=2.5', 'xlwt', @@ -50,9 +50,8 @@ 'cached_property', 'channels>=1,<2', 'websocket-client>=0.56', - 'twisted<19.3.0', 'jsonschema<3.0.2', - 'pywin32<224; sys.platform == "win32"', + 'pywin32<224; sys.platform == "win32"' ], extras_require={ ':python_version=="2.7"': ['statistics'], From aece724dfd44a615789c7b3cc336d4243663d8ac Mon Sep 17 00:00:00 2001 From: Greg Date: Thu, 8 Aug 2019 16:26:26 +0300 Subject: [PATCH 10/14] here, i gave up --- setup.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 29dc4f25..9acaed9c 100644 --- a/setup.py +++ b/setup.py @@ -51,7 +51,10 @@ 'channels>=1,<2', 'websocket-client>=0.56', 'jsonschema<3.0.2', - 'pywin32<224; sys.platform == "win32"' + 'autobahn<=19.7.2', + 'pytz<=2019.1', + 'twisted<=19.2.1', + 'pywin32<224; sys.platform == "win32"', ], extras_require={ ':python_version=="2.7"': ['statistics'], From 4b55ba3b5a755b6e8717c9b5e1b473d60b514f22 Mon Sep 17 00:00:00 2001 From: Greg Date: Thu, 8 Aug 2019 16:30:37 +0300 Subject: [PATCH 11/14] damn you jsonschema --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9acaed9c..870921c6 100644 --- a/setup.py +++ b/setup.py @@ -50,7 +50,6 @@ 'cached_property', 'channels>=1,<2', 'websocket-client>=0.56', - 'jsonschema<3.0.2', 'autobahn<=19.7.2', 'pytz<=2019.1', 'twisted<=19.2.1', @@ -69,6 +68,7 @@ "flake8", "pylint", "waiting", + "jsonschema<=3.0.1", ] }, python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*", From 458d82fbf801fe95cfbdf6a6c5859195f860bd6b Mon Sep 17 00:00:00 2001 From: Greg Date: Thu, 8 Aug 2019 17:10:31 +0300 Subject: [PATCH 12/14] post giving up actions --- tox.ini | 1 + 1 file changed, 1 insertion(+) diff --git a/tox.ini b/tox.ini index 1e0c9773..cc303b95 100644 --- a/tox.ini +++ b/tox.ini @@ -22,6 +22,7 @@ deps = commands = flake8 setup.py src/rotest/ tests/ pylint setup.py src/rotest/ tests/ + pip install jsonschema==3.0.1 pytest {posargs:tests} [testenv:docs] From 41d6d2b384a890c5f9a9a71f31be1cc3ad523f50 Mon Sep 17 00:00:00 2001 From: Greg Date: Sun, 11 Aug 2019 11:01:40 +0300 Subject: [PATCH 13/14] its sqlite, tried pip install --- setup.py | 7 ++----- tox.ini | 1 - 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index 870921c6..ae5ad7a9 100644 --- a/setup.py +++ b/setup.py @@ -34,7 +34,7 @@ url="https://github.com/gregoil/rotest", keywords="testing system django unittest", install_requires=[ - 'django>=1.8,<1.11.23', + 'django>=1.8,<2', 'py', 'ipdbugger>=2.5', 'xlwt', @@ -50,9 +50,7 @@ 'cached_property', 'channels>=1,<2', 'websocket-client>=0.56', - 'autobahn<=19.7.2', - 'pytz<=2019.1', - 'twisted<=19.2.1', + 'pysqlite3<0.2.2', 'pywin32<224; sys.platform == "win32"', ], extras_require={ @@ -68,7 +66,6 @@ "flake8", "pylint", "waiting", - "jsonschema<=3.0.1", ] }, python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*", diff --git a/tox.ini b/tox.ini index cc303b95..1e0c9773 100644 --- a/tox.ini +++ b/tox.ini @@ -22,7 +22,6 @@ deps = commands = flake8 setup.py src/rotest/ tests/ pylint setup.py src/rotest/ tests/ - pip install jsonschema==3.0.1 pytest {posargs:tests} [testenv:docs] From 01c5bd9e4dd26e8d2542904580093041579502da Mon Sep 17 00:00:00 2001 From: Greg Date: Sun, 11 Aug 2019 11:45:27 +0300 Subject: [PATCH 14/14] reverted sqlite --- setup.py | 1 - 1 file changed, 1 deletion(-) diff --git a/setup.py b/setup.py index ae5ad7a9..2f458abe 100644 --- a/setup.py +++ b/setup.py @@ -50,7 +50,6 @@ 'cached_property', 'channels>=1,<2', 'websocket-client>=0.56', - 'pysqlite3<0.2.2', 'pywin32<224; sys.platform == "win32"', ], extras_require={