From 7525ba397ef391678b00690b9887c48023bb0480 Mon Sep 17 00:00:00 2001 From: DUYN Date: Thu, 18 Jun 2020 19:41:52 +0200 Subject: [PATCH 01/14] Initial travis.ci definition --- .travis.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..3d9a8749 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,7 @@ +language: python + +install: + - pip install -r requirements.txt + +script: + - ./ci/test.sh \ No newline at end of file From ccec2f4d815170f9b9b6e6478ac3b24b874439fc Mon Sep 17 00:00:00 2001 From: DUYN Date: Thu, 18 Jun 2020 19:44:43 +0200 Subject: [PATCH 02/14] Add execution of test.sh --- ci/test.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 ci/test.sh diff --git a/ci/test.sh b/ci/test.sh old mode 100644 new mode 100755 From 820974d0108f56b9ac0be3cb11c87d170482618c Mon Sep 17 00:00:00 2001 From: DUYN Date: Thu, 18 Jun 2020 19:48:55 +0200 Subject: [PATCH 03/14] Update travis.ci definition --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 3d9a8749..841b5b0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,6 @@ language: python +before_install: + - echo | ls . install: - pip install -r requirements.txt From 169368fd3b58ad506904a3e4c537a0b0e9cbf701 Mon Sep 17 00:00:00 2001 From: DUYN Date: Thu, 18 Jun 2020 19:51:29 +0200 Subject: [PATCH 04/14] Update travis.ci definition --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 841b5b0e..a6024b9b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python before_install: - echo | ls . - + - echo | ls ./investing_bot_framework/ install: - pip install -r requirements.txt From dc71efb1659969bd0fb225229456a4800936f837 Mon Sep 17 00:00:00 2001 From: DUYN Date: Thu, 18 Jun 2020 19:56:52 +0200 Subject: [PATCH 05/14] Update travis.ci definition --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a6024b9b..c1855ca2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,7 @@ language: python before_install: - echo | ls . - - echo | ls ./investing_bot_framework/ + - echo | ls ./investing_bot_framework/tests/core/executors install: - pip install -r requirements.txt From da5fd09740d24586a7654f98359c634a4fc710a7 Mon Sep 17 00:00:00 2001 From: DUYN Date: Fri, 19 Jun 2020 10:05:16 +0200 Subject: [PATCH 06/14] Update travis.ci definition --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index c1855ca2..3dddcde5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,9 @@ language: python + before_install: - - echo | ls . - - echo | ls ./investing_bot_framework/tests/core/executors + - virtualenv venv + - source venv/bin/activate + install: - pip install -r requirements.txt From b7222070692917026bc635c871f4f0cb77bb1a0b Mon Sep 17 00:00:00 2001 From: DUYN Date: Fri, 19 Jun 2020 11:45:58 +0200 Subject: [PATCH 07/14] Update travis.ci definition --- .travis.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3dddcde5..f868eb03 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,5 +7,4 @@ before_install: install: - pip install -r requirements.txt -script: - - ./ci/test.sh \ No newline at end of file +script: pytest # run test From 7d35c3e2ac48818db86ef14acde498a9a626268a Mon Sep 17 00:00:00 2001 From: DUYN Date: Fri, 19 Jun 2020 11:47:38 +0200 Subject: [PATCH 08/14] Update travis.ci definition --- .travis.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index f868eb03..b8f22ae5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,9 +1,5 @@ language: python -before_install: - - virtualenv venv - - source venv/bin/activate - install: - pip install -r requirements.txt From 2462e4059deab8a20f2dff3fca8650282f171ac8 Mon Sep 17 00:00:00 2001 From: DUYN Date: Fri, 19 Jun 2020 11:48:42 +0200 Subject: [PATCH 09/14] Change to pytest framework --- .../tests/utils/test_version.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/investing_bot_framework/tests/utils/test_version.py b/investing_bot_framework/tests/utils/test_version.py index 8195abfd..9902dc07 100644 --- a/investing_bot_framework/tests/utils/test_version.py +++ b/investing_bot_framework/tests/utils/test_version.py @@ -1,14 +1,13 @@ -from unittest import TestCase from investing_bot_framework.utils.version import get_version, get_complete_version, get_main_version -class Version(TestCase): +def test(): + assert get_version() is not None + assert type(get_version()) == str + + version = (1, 0, 0, 'alpha', 0) + assert get_version(version) == '1.0' + assert get_main_version(version) == '1.0' + assert get_complete_version(version) == version - def test(self): - self.assertIsNotNone(get_version()) - self.assertEqual(type(get_version()), str) - version = (1, 0, 0, 'alpha', 0) - self.assertEqual(get_version(version), '1.0') - self.assertEqual(get_main_version(version), '1.0') - self.assertEqual(get_complete_version(version), version) From 7bf0d66b50f9005327bb9a842b65460e18858757 Mon Sep 17 00:00:00 2001 From: DUYN Date: Fri, 19 Jun 2020 11:48:54 +0200 Subject: [PATCH 10/14] Change to pytest framework --- .../core/data/data_providers/data_provider.py | 74 +--- .../core/data/data_providers/resources.py | 29 ++ .../tests/core/executors/resources.py | 40 ++ .../tests/core/executors/test_executor.py | 376 +++++++++--------- .../tests/core/executors/test_scheduler.py | 60 +-- .../core/resolvers/test_database_resolver.py | 27 +- 6 files changed, 322 insertions(+), 284 deletions(-) create mode 100644 investing_bot_framework/tests/core/data/data_providers/resources.py create mode 100644 investing_bot_framework/tests/core/executors/resources.py diff --git a/investing_bot_framework/tests/core/data/data_providers/data_provider.py b/investing_bot_framework/tests/core/data/data_providers/data_provider.py index 28dac426..d94326cd 100644 --- a/investing_bot_framework/tests/core/data/data_providers/data_provider.py +++ b/investing_bot_framework/tests/core/data/data_providers/data_provider.py @@ -1,64 +1,34 @@ -from typing import Dict, Any -from unittest import TestCase +from investing_bot_framework.tests.core.data.data_providers.resources import TestDataProviderOne, \ + TestDataProviderTwo, TestObserver -from investing_bot_framework.core.data_providers import DataProvider -from investing_bot_framework.core.events import Observer +def test(): + data_provider_one = TestDataProviderOne() -class TestDataProviderOne(DataProvider): + assert data_provider_one.id is not None + assert data_provider_one.get_id() == TestDataProviderOne.id - id = 'TestDataProviderOne' + observer = TestObserver() + data_provider_one.add_observer(observer) - def provide_data(self, **kwargs: Dict[str, Any]) -> Any: - return "data_providers" + # Run the data_providers provider + data_provider_one.start() + # Observer must have been updated + assert observer.update_count == 1 -class TestDataProviderTwo(DataProvider): + data_provider_two = TestDataProviderTwo() - id = 'TestDataProviderTwo' + assert data_provider_two.id is not None + assert data_provider_two.get_id() == TestDataProviderTwo.id - def provide_data(self, **kwargs: Dict[str, Any]) -> Any: - return "data_providers" + data_provider_two.add_observer(observer) + # Run the data_providers provider + data_provider_two.start() -class TestObserver(Observer): + # Observer must have been updated + assert observer.update_count == 2 - def __init__(self) -> None: - self.update_count = 0 - - def update(self, observable, **kwargs) -> None: - self.update_count += 1 - - -class DataProviderSetup(TestCase): - - def test(self): - data_provider_one = TestDataProviderOne() - - self.assertIsNotNone(data_provider_one.id) - self.assertEqual(data_provider_one.get_id(), TestDataProviderOne.id) - - observer = TestObserver() - data_provider_one.add_observer(observer) - - # Run the data_providers provider - data_provider_one.start() - - # Observer must have been updated - self.assertEqual(observer.update_count, 1) - - data_provider_two = TestDataProviderTwo() - - self.assertIsNotNone(data_provider_two.id) - self.assertEqual(data_provider_two.get_id(), TestDataProviderTwo.id) - - data_provider_two.add_observer(observer) - - # Run the data_providers provider - data_provider_two.start() - - # Observer must have been updated - self.assertEqual(observer.update_count, 2) - - # Id´s must be different - self.assertNotEqual(TestDataProviderOne.id, TestDataProviderTwo.id) \ No newline at end of file + # Id´s must be different + assert TestDataProviderOne.id != TestDataProviderTwo.id diff --git a/investing_bot_framework/tests/core/data/data_providers/resources.py b/investing_bot_framework/tests/core/data/data_providers/resources.py new file mode 100644 index 00000000..6a8754a2 --- /dev/null +++ b/investing_bot_framework/tests/core/data/data_providers/resources.py @@ -0,0 +1,29 @@ +from typing import Dict, Any + +from investing_bot_framework.core.events import Observer +from investing_bot_framework.core.data_providers import DataProvider + + +class TestDataProviderOne(DataProvider): + + id = 'TestDataProviderOne' + + def provide_data(self, **kwargs: Dict[str, Any]) -> Any: + return "data_providers" + + +class TestDataProviderTwo(DataProvider): + + id = 'TestDataProviderTwo' + + def provide_data(self, **kwargs: Dict[str, Any]) -> Any: + return "data_providers" + + +class TestObserver(Observer): + + def __init__(self) -> None: + self.update_count = 0 + + def update(self, observable, **kwargs) -> None: + self.update_count += 1 diff --git a/investing_bot_framework/tests/core/executors/resources.py b/investing_bot_framework/tests/core/executors/resources.py new file mode 100644 index 00000000..3904dbec --- /dev/null +++ b/investing_bot_framework/tests/core/executors/resources.py @@ -0,0 +1,40 @@ +from typing import Dict, Any +from time import sleep +from wrapt import synchronized + +from investing_bot_framework.core.workers import Worker +from investing_bot_framework.core.events.observer import Observer + + +class TestObserver(Observer): + + def __init__(self) -> None: + self.update_count = 0 + + @synchronized + def update(self, observable, **kwargs) -> None: + self.update_count += 1 + + +class TestWorkerOne(Worker): + id = 'TestWorkerOne' + + def work(self, **kwargs: Dict[str, Any]) -> None: + # Simulate some work + sleep(1) + + +class TestWorkerTwo(Worker): + id = 'TestWorkerTwo' + + def work(self, **kwargs: Dict[str, Any]) -> None: + # Simulate some work + sleep(1) + + +class TestWorkerThree(Worker): + id = 'TestWorkerThree' + + def work(self, **kwargs: Dict[str, Any]) -> None: + # Simulate some work + sleep(1) diff --git a/investing_bot_framework/tests/core/executors/test_executor.py b/investing_bot_framework/tests/core/executors/test_executor.py index f4a507c4..7fbc6317 100644 --- a/investing_bot_framework/tests/core/executors/test_executor.py +++ b/investing_bot_framework/tests/core/executors/test_executor.py @@ -1,188 +1,188 @@ -from threading import active_count -from typing import Dict, Any, List -from unittest import TestCase -from time import sleep -from wrapt import synchronized - -from investing_bot_framework.core.workers import Worker -from investing_bot_framework.core.executors import Executor -from investing_bot_framework.core.events.observer import Observer - - -class TestObserver(Observer): - - def __init__(self) -> None: - self.update_count = 0 - - @synchronized - def update(self, observable, **kwargs) -> None: - self.update_count += 1 - - -class TestWorkerOne(Worker): - id = 'TestWorkerOne' - - def work(self, **kwargs: Dict[str, Any]) -> None: - # Simulate some work - sleep(1) - - -class TestWorkerTwo(Worker): - id = 'TestWorkerTwo' - - def work(self, **kwargs: Dict[str, Any]) -> None: - # Simulate some work - sleep(1) - - -class TestWorkerThree(Worker): - id = 'TestWorkerThree' - - def work(self, **kwargs: Dict[str, Any]) -> None: - # Simulate some work - sleep(1) - - -class TestExecutor(Executor): - - def __init__(self, workers: List[Worker] = None): - super(TestExecutor, self).__init__(max_workers=2) - - self._registered_workers = workers - - def create_workers(self) -> List[Worker]: - return self.registered_workers - - @property - def registered_workers(self) -> List[Worker]: - return self._registered_workers - - -class TestStandardExecutor(TestCase): - - def test(self) -> None: - executor = TestExecutor(workers=[TestWorkerOne(), TestWorkerTwo()]) - observer = TestObserver() - executor.add_observer(observer) - - # Make sure the initialization is correct - self.assertEqual(len(executor.registered_workers), 2) - self.assertEqual(active_count(), 1) - - # Start the executor - executor.start() - - # 3 Threads must be running - self.assertTrue(executor.processing) - self.assertEqual(active_count(), 3) - - sleep(2) - - # After finishing only 1 thread must be active - self.assertEqual(active_count(), 1) - self.assertFalse(executor.processing) - - # Observer must have been updated by the executor - self.assertEqual(observer.update_count, 1) - - # Start the executor - executor.start() - - # 3 Threads must be running - self.assertTrue(executor.processing) - self.assertEqual(active_count(), 3) - - sleep(2) - - # After finishing only 1 thread must be active - self.assertEqual(active_count(), 1) - self.assertFalse(executor.processing) - - # Observer must have been updated by the executor - self.assertEqual(observer.update_count, 2) - - executor = TestExecutor(workers=[TestWorkerOne(), TestWorkerTwo(), TestWorkerThree()]) - executor.add_observer(observer) - - # Start the executor - executor.start() - - # 3 Threads must be running - self.assertTrue(executor.processing) - self.assertEqual(active_count(), 3) - - sleep(2) - - # After finishing only two threads must be active (main + last worker, because max workers is 2) - self.assertEqual(active_count(), 2) - self.assertTrue(executor.processing) - - sleep(1) - - # After finishing only 1 thread must be active - self.assertEqual(active_count(), 1) - self.assertFalse(executor.processing) - - # Observer must have been updated by the executor - self.assertEqual(observer.update_count, 3) - - - - - - # def test_execution_executor(): -# logger.info("TEST: test DataProviderExecutor execution") -# -# observer = DummyObserver() -# -# data_provider_one = DummyDataProviderWorker() -# data_provider_three = DummyDataProviderWorker() -# -# executor = DataProviderExecutor( -# [ -# data_provider_one, -# data_provider_three -# ] -# ) -# -# executor.add_observer(observer) -# -# assert active_count() == 1 -# -# -# assert active_count() == 3 -# -# sleep(2) -# -# # Check if the observer is updated by the executor -# assert observer.update_count == 1 -# -# data_provider_one = DummyDataProviderWorker() -# -# executor = DataProviderExecutor( -# [ -# data_provider_one, -# ] -# ) -# -# executor.add_observer(observer) -# -# assert active_count() == 1 -# -# executor.start() -# -# assert active_count() == 2 -# -# sleep(2) -# -# # Check if the observer is updated by the executor -# assert observer.update_count == 2 -# -# executor.start() -# -# sleep(2) -# -# # Check if the observer is updated by the executor -# assert observer.update_count == 3 -# -# logger.info("TEST FINISHED") \ No newline at end of file +# from threading import active_count +# from typing import Dict, Any, List +# from unittest import TestCase +# from time import sleep +# from wrapt import synchronized +# +# from investing_bot_framework.core.workers import Worker +# from investing_bot_framework.core.executors import Executor +# from investing_bot_framework.core.events.observer import Observer +# +# +# class TestObserver(Observer): +# +# def __init__(self) -> None: +# self.update_count = 0 +# +# @synchronized +# def update(self, observable, **kwargs) -> None: +# self.update_count += 1 +# +# +# class TestWorkerOne(Worker): +# id = 'TestWorkerOne' +# +# def work(self, **kwargs: Dict[str, Any]) -> None: +# # Simulate some work +# sleep(1) +# +# +# class TestWorkerTwo(Worker): +# id = 'TestWorkerTwo' +# +# def work(self, **kwargs: Dict[str, Any]) -> None: +# # Simulate some work +# sleep(1) +# +# +# class TestWorkerThree(Worker): +# id = 'TestWorkerThree' +# +# def work(self, **kwargs: Dict[str, Any]) -> None: +# # Simulate some work +# sleep(1) +# +# +# class TestExecutor(Executor): +# +# def __init__(self, workers: List[Worker] = None): +# super(TestExecutor, self).__init__(max_workers=2) +# +# self._registered_workers = workers +# +# def create_workers(self) -> List[Worker]: +# return self.registered_workers +# +# @property +# def registered_workers(self) -> List[Worker]: +# return self._registered_workers +# +# +# class TestStandardExecutor(TestCase): +# +# def test(self) -> None: +# executor = TestExecutor(workers=[TestWorkerOne(), TestWorkerTwo()]) +# observer = TestObserver() +# executor.add_observer(observer) +# +# # Make sure the initialization is correct +# self.assertEqual(len(executor.registered_workers), 2) +# self.assertEqual(active_count(), 1) +# +# # Start the executor +# executor.start() +# +# # 3 Threads must be running +# self.assertTrue(executor.processing) +# self.assertEqual(active_count(), 3) +# +# sleep(2) +# +# # After finishing only 1 thread must be active +# self.assertEqual(active_count(), 1) +# self.assertFalse(executor.processing) +# +# # Observer must have been updated by the executor +# self.assertEqual(observer.update_count, 1) +# +# # Start the executor +# executor.start() +# +# # 3 Threads must be running +# self.assertTrue(executor.processing) +# self.assertEqual(active_count(), 3) +# +# sleep(2) +# +# # After finishing only 1 thread must be active +# self.assertEqual(active_count(), 1) +# self.assertFalse(executor.processing) +# +# # Observer must have been updated by the executor +# self.assertEqual(observer.update_count, 2) +# +# executor = TestExecutor(workers=[TestWorkerOne(), TestWorkerTwo(), TestWorkerThree()]) +# executor.add_observer(observer) +# +# # Start the executor +# executor.start() +# +# # 3 Threads must be running +# self.assertTrue(executor.processing) +# self.assertEqual(active_count(), 3) +# +# sleep(2) +# +# # After finishing only two threads must be active (main + last worker, because max workers is 2) +# self.assertEqual(active_count(), 2) +# self.assertTrue(executor.processing) +# +# sleep(1) +# +# # After finishing only 1 thread must be active +# self.assertEqual(active_count(), 1) +# self.assertFalse(executor.processing) +# +# # Observer must have been updated by the executor +# self.assertEqual(observer.update_count, 3) +# +# +# +# +# +# # def test_execution_executor(): +# # logger.info("TEST: test DataProviderExecutor execution") +# # +# # observer = DummyObserver() +# # +# # data_provider_one = DummyDataProviderWorker() +# # data_provider_three = DummyDataProviderWorker() +# # +# # executor = DataProviderExecutor( +# # [ +# # data_provider_one, +# # data_provider_three +# # ] +# # ) +# # +# # executor.add_observer(observer) +# # +# # assert active_count() == 1 +# # +# # +# # assert active_count() == 3 +# # +# # sleep(2) +# # +# # # Check if the observer is updated by the executor +# # assert observer.update_count == 1 +# # +# # data_provider_one = DummyDataProviderWorker() +# # +# # executor = DataProviderExecutor( +# # [ +# # data_provider_one, +# # ] +# # ) +# # +# # executor.add_observer(observer) +# # +# # assert active_count() == 1 +# # +# # executor.start() +# # +# # assert active_count() == 2 +# # +# # sleep(2) +# # +# # # Check if the observer is updated by the executor +# # assert observer.update_count == 2 +# # +# # executor.start() +# # +# # sleep(2) +# # +# # # Check if the observer is updated by the executor +# # assert observer.update_count == 3 +# # +# # logger.info("TEST FINISHED") \ No newline at end of file diff --git a/investing_bot_framework/tests/core/executors/test_scheduler.py b/investing_bot_framework/tests/core/executors/test_scheduler.py index 2ac02073..ffa2f9ed 100644 --- a/investing_bot_framework/tests/core/executors/test_scheduler.py +++ b/investing_bot_framework/tests/core/executors/test_scheduler.py @@ -1,15 +1,15 @@ import random +import pytest from uuid import uuid4 -from unittest import TestCase from datetime import datetime, timedelta from investing_bot_framework.core.executors.execution_scheduler import ExecutionScheduler, ExecutionTask from investing_bot_framework.core.utils import TimeUnit -class TestExecutionScheduler(TestCase): +class TestExecutionScheduler(object): - def setUp(self) -> None: + def setup_method(self) -> None: self.execution_task_one = { 'execution_id': uuid4().__str__(), @@ -54,17 +54,17 @@ def test(self): # All tasks must be scheduled the first planning planning = scheduler.schedule_executions() - self.assertTrue(self.execution_task_one['execution_id'] in planning) - self.assertTrue(self.execution_task_two['execution_id'] in planning) - self.assertTrue(self.execution_task_three['execution_id'] in planning) - self.assertTrue(self.execution_task_four['execution_id'] in planning) + assert self.execution_task_one['execution_id'] in planning + assert self.execution_task_two['execution_id'] in planning + assert self.execution_task_three['execution_id'] in planning + assert self.execution_task_four['execution_id'] in planning # Only Task 1 must be in the planning planning = scheduler.schedule_executions() - self.assertTrue(self.execution_task_one['execution_id'] in planning) - self.assertFalse(self.execution_task_two['execution_id'] in planning) - self.assertFalse(self.execution_task_three['execution_id'] in planning) - self.assertFalse(self.execution_task_four['execution_id'] in planning) + assert self.execution_task_one['execution_id'] in planning + assert self.execution_task_two['execution_id'] not in planning + assert self.execution_task_three['execution_id'] not in planning + assert self.execution_task_four['execution_id'] not in planning minus_time_delta = datetime.now() - timedelta(seconds=self.execution_task_two['interval']) appointments = scheduler._planning.keys() @@ -79,10 +79,10 @@ def test(self): # Task 1, 2 must be in the planning planning = scheduler.schedule_executions() - self.assertTrue(self.execution_task_one['execution_id'] in planning) - self.assertTrue(self.execution_task_two['execution_id'] in planning) - self.assertFalse(self.execution_task_three['execution_id'] in planning) - self.assertFalse(self.execution_task_four['execution_id'] in planning) + assert self.execution_task_one['execution_id'] in planning + assert self.execution_task_two['execution_id'] in planning + assert self.execution_task_three['execution_id'] not in planning + assert self.execution_task_four['execution_id'] not in planning minus_time_delta = datetime.now() - timedelta(minutes=self.execution_task_three['interval']) appointments = scheduler._planning.keys() @@ -97,10 +97,10 @@ def test(self): # Task 1, 2 and 3 must be in the planning planning = scheduler.schedule_executions() - self.assertTrue(self.execution_task_one['execution_id'] in planning) - self.assertTrue(self.execution_task_two['execution_id'] in planning) - self.assertTrue(self.execution_task_three['execution_id'] in planning) - self.assertFalse(self.execution_task_four['execution_id'] in planning) + assert self.execution_task_one['execution_id'] in planning + assert self.execution_task_two['execution_id'] in planning + assert self.execution_task_three['execution_id'] in planning + assert self.execution_task_four['execution_id'] not in planning minus_time_delta = datetime.now() - timedelta(hours=self.execution_task_four['interval']) appointments = scheduler._planning.keys() @@ -112,33 +112,33 @@ def test(self): scheduler._planning[appointment].interval, last_run=minus_time_delta ) - + # # Task 1, 2 and 3 must be in the planning planning = scheduler.schedule_executions() - self.assertTrue(self.execution_task_one['execution_id'] in planning) - self.assertTrue(self.execution_task_two['execution_id'] in planning) - self.assertTrue(self.execution_task_three['execution_id'] in planning) - self.assertTrue(self.execution_task_four['execution_id'] in planning) + assert self.execution_task_one['execution_id'] in planning + assert self.execution_task_two['execution_id'] in planning + assert self.execution_task_three['execution_id'] in planning + assert self.execution_task_four['execution_id'] in planning def test_exceptions(self) -> None: scheduler = ExecutionScheduler() - with self.assertRaises(Exception) as context: + with pytest.raises(Exception) as e_info: scheduler.add_execution_task(**self.wrong_execution_task_one) - self.assertTrue("Interval for task time unit is smaller then 1" in str(context.exception)) + assert "Interval for task time unit is smaller then 1" in str(e_info.value) - with self.assertRaises(Exception) as context: + with pytest.raises(Exception) as e_info: scheduler.add_execution_task(**self.wrong_execution_task_two) - self.assertTrue("Appoint must set an interval with the corresponding time unit" in str(context.exception)) + assert "Appoint must set an interval with the corresponding time unit" in str(e_info.value) scheduler.add_execution_task(**self.execution_task_one) - with self.assertRaises(Exception) as context: + with pytest.raises(Exception) as e_info: scheduler.add_execution_task(**self.execution_task_one) - self.assertTrue("Can't add execution task, execution id is already taken" in str(context.exception)) + assert "Can't add execution task, execution id is already taken" in str(e_info.value) diff --git a/investing_bot_framework/tests/core/resolvers/test_database_resolver.py b/investing_bot_framework/tests/core/resolvers/test_database_resolver.py index 974d706f..4fac1ad9 100644 --- a/investing_bot_framework/tests/core/resolvers/test_database_resolver.py +++ b/investing_bot_framework/tests/core/resolvers/test_database_resolver.py @@ -1,5 +1,4 @@ import os -from unittest import TestCase from sqlalchemy import Column, String, Integer from investing_bot_framework.tests.resources import BaseTestMixin, utils @@ -12,9 +11,9 @@ class TestModel(db.model): name = Column(String()) -class TestDatabaseResolverConfiguration(TestCase, BaseTestMixin): +class TestDatabaseResolverConfiguration(BaseTestMixin): - def setUp(self) -> None: + def setup_method(self) -> None: self.initialize_environment() def test_configuration(self): @@ -22,21 +21,21 @@ def test_configuration(self): db.configure() # Check if all properties are configured - self.assertIsNotNone(db.Session) - self.assertIsNotNone(db.engine) - self.assertIsNotNone(db.session_factory) - self.assertIsNotNone(db.database_path) - self.assertTrue(os.path.isfile(db.database_path)) + assert db.Session is not None + assert db.engine is not None + assert db.session_factory is not None + assert db.database_path is not None + assert os.path.isfile(db.database_path) == True - def tearDown(self) -> None: + def teardown_method(self) -> None: if os.path.isfile(db.database_path): os.remove(db.database_path) -class TestDatabaseResolverModel(TestCase, BaseTestMixin): +class TestDatabaseResolverModel(BaseTestMixin): - def setUp(self) -> None: + def setup_method(self) -> None: self.initialize_environment() settings.configure() db.configure() @@ -47,14 +46,14 @@ def test(self) -> None: model = TestModel(name=utils.random_string(10)) model.save() db.session.commit() - self.assertEqual(1, len(TestModel.query.all())) + assert 1 == len(TestModel.query.all()) model = TestModel(name=utils.random_string(10)) model.save() db.session.commit() - self.assertEqual(2, len(TestModel.query.all())) + assert 2 == len(TestModel.query.all()) - def tearDown(self) -> None: + def teardown_method(self) -> None: if os.path.isfile(db.database_path): os.remove(db.database_path) From 67af58b140ce6266861d7bc17bca91ec88e67ac3 Mon Sep 17 00:00:00 2001 From: DUYN Date: Fri, 19 Jun 2020 11:49:11 +0200 Subject: [PATCH 11/14] Add pytest framework --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c384b3bd..dc54f685 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,5 +3,5 @@ pandas==0.25.3 wrapt==1.11.2 colorama==0.4.3 SQLAlchemy==1.3.13 - +pytest==5.4.3 From d955a394b1799d70c174f8ee256d56cc6abf8ff5 Mon Sep 17 00:00:00 2001 From: DUYN Date: Fri, 19 Jun 2020 12:05:50 +0200 Subject: [PATCH 12/14] Add pytest framework --- .../tests/core/executors/resources.py | 18 +- .../tests/core/executors/test_executor.py | 263 +++++------------- 2 files changed, 92 insertions(+), 189 deletions(-) diff --git a/investing_bot_framework/tests/core/executors/resources.py b/investing_bot_framework/tests/core/executors/resources.py index 3904dbec..522f6b42 100644 --- a/investing_bot_framework/tests/core/executors/resources.py +++ b/investing_bot_framework/tests/core/executors/resources.py @@ -1,9 +1,10 @@ -from typing import Dict, Any +from typing import Dict, Any, List from time import sleep from wrapt import synchronized from investing_bot_framework.core.workers import Worker from investing_bot_framework.core.events.observer import Observer +from investing_bot_framework.core.executors import Executor class TestObserver(Observer): @@ -38,3 +39,18 @@ class TestWorkerThree(Worker): def work(self, **kwargs: Dict[str, Any]) -> None: # Simulate some work sleep(1) + + +class TestExecutor(Executor): + + def __init__(self, workers: List[Worker] = None): + super(TestExecutor, self).__init__(max_workers=2) + + self._registered_workers = workers + + def create_workers(self) -> List[Worker]: + return self.registered_workers + + @property + def registered_workers(self) -> List[Worker]: + return self._registered_workers diff --git a/investing_bot_framework/tests/core/executors/test_executor.py b/investing_bot_framework/tests/core/executors/test_executor.py index 7fbc6317..72f2854a 100644 --- a/investing_bot_framework/tests/core/executors/test_executor.py +++ b/investing_bot_framework/tests/core/executors/test_executor.py @@ -1,188 +1,75 @@ -# from threading import active_count -# from typing import Dict, Any, List -# from unittest import TestCase -# from time import sleep -# from wrapt import synchronized -# -# from investing_bot_framework.core.workers import Worker -# from investing_bot_framework.core.executors import Executor -# from investing_bot_framework.core.events.observer import Observer -# -# -# class TestObserver(Observer): -# -# def __init__(self) -> None: -# self.update_count = 0 -# -# @synchronized -# def update(self, observable, **kwargs) -> None: -# self.update_count += 1 -# -# -# class TestWorkerOne(Worker): -# id = 'TestWorkerOne' -# -# def work(self, **kwargs: Dict[str, Any]) -> None: -# # Simulate some work -# sleep(1) -# -# -# class TestWorkerTwo(Worker): -# id = 'TestWorkerTwo' -# -# def work(self, **kwargs: Dict[str, Any]) -> None: -# # Simulate some work -# sleep(1) -# -# -# class TestWorkerThree(Worker): -# id = 'TestWorkerThree' -# -# def work(self, **kwargs: Dict[str, Any]) -> None: -# # Simulate some work -# sleep(1) -# -# -# class TestExecutor(Executor): -# -# def __init__(self, workers: List[Worker] = None): -# super(TestExecutor, self).__init__(max_workers=2) -# -# self._registered_workers = workers -# -# def create_workers(self) -> List[Worker]: -# return self.registered_workers -# -# @property -# def registered_workers(self) -> List[Worker]: -# return self._registered_workers -# -# -# class TestStandardExecutor(TestCase): -# -# def test(self) -> None: -# executor = TestExecutor(workers=[TestWorkerOne(), TestWorkerTwo()]) -# observer = TestObserver() -# executor.add_observer(observer) -# -# # Make sure the initialization is correct -# self.assertEqual(len(executor.registered_workers), 2) -# self.assertEqual(active_count(), 1) -# -# # Start the executor -# executor.start() -# -# # 3 Threads must be running -# self.assertTrue(executor.processing) -# self.assertEqual(active_count(), 3) -# -# sleep(2) -# -# # After finishing only 1 thread must be active -# self.assertEqual(active_count(), 1) -# self.assertFalse(executor.processing) -# -# # Observer must have been updated by the executor -# self.assertEqual(observer.update_count, 1) -# -# # Start the executor -# executor.start() -# -# # 3 Threads must be running -# self.assertTrue(executor.processing) -# self.assertEqual(active_count(), 3) -# -# sleep(2) -# -# # After finishing only 1 thread must be active -# self.assertEqual(active_count(), 1) -# self.assertFalse(executor.processing) -# -# # Observer must have been updated by the executor -# self.assertEqual(observer.update_count, 2) -# -# executor = TestExecutor(workers=[TestWorkerOne(), TestWorkerTwo(), TestWorkerThree()]) -# executor.add_observer(observer) -# -# # Start the executor -# executor.start() -# -# # 3 Threads must be running -# self.assertTrue(executor.processing) -# self.assertEqual(active_count(), 3) -# -# sleep(2) -# -# # After finishing only two threads must be active (main + last worker, because max workers is 2) -# self.assertEqual(active_count(), 2) -# self.assertTrue(executor.processing) -# -# sleep(1) -# -# # After finishing only 1 thread must be active -# self.assertEqual(active_count(), 1) -# self.assertFalse(executor.processing) -# -# # Observer must have been updated by the executor -# self.assertEqual(observer.update_count, 3) -# -# -# -# -# -# # def test_execution_executor(): -# # logger.info("TEST: test DataProviderExecutor execution") -# # -# # observer = DummyObserver() -# # -# # data_provider_one = DummyDataProviderWorker() -# # data_provider_three = DummyDataProviderWorker() -# # -# # executor = DataProviderExecutor( -# # [ -# # data_provider_one, -# # data_provider_three -# # ] -# # ) -# # -# # executor.add_observer(observer) -# # -# # assert active_count() == 1 -# # -# # -# # assert active_count() == 3 -# # -# # sleep(2) -# # -# # # Check if the observer is updated by the executor -# # assert observer.update_count == 1 -# # -# # data_provider_one = DummyDataProviderWorker() -# # -# # executor = DataProviderExecutor( -# # [ -# # data_provider_one, -# # ] -# # ) -# # -# # executor.add_observer(observer) -# # -# # assert active_count() == 1 -# # -# # executor.start() -# # -# # assert active_count() == 2 -# # -# # sleep(2) -# # -# # # Check if the observer is updated by the executor -# # assert observer.update_count == 2 -# # -# # executor.start() -# # -# # sleep(2) -# # -# # # Check if the observer is updated by the executor -# # assert observer.update_count == 3 -# # -# # logger.info("TEST FINISHED") \ No newline at end of file +from threading import active_count +from unittest import TestCase +from time import sleep + +from investing_bot_framework.tests.core.executors.resources import TestExecutor, TestWorkerOne, TestWorkerTwo, \ + TestObserver, TestWorkerThree + + +class TestStandardExecutor: + + def test(self) -> None: + executor = TestExecutor(workers=[TestWorkerOne(), TestWorkerTwo()]) + observer = TestObserver() + executor.add_observer(observer) + + # Make sure the initialization is correct + assert len(executor.registered_workers) == 2 + assert active_count() == 1 + + # Start the executor + executor.start() + + # 3 Threads must be running + assert executor.processing + assert active_count() == 3 + + sleep(2) + + # # After finishing only 1 thread must be active + assert active_count(), 1 + assert not executor.processing + + # Observer must have been updated by the executor + assert observer.update_count == 1 + + # Start the executor + executor.start() + + # 3 Threads must be running + assert executor.processing + assert active_count() == 3 + + sleep(2) + + # After finishing only 1 thread must be active + assert active_count() == 1 + assert not executor.processing + + # Observer must have been updated by the executor + assert observer.update_count == 2 + + executor = TestExecutor(workers=[TestWorkerOne(), TestWorkerTwo(), TestWorkerThree()]) + executor.add_observer(observer) + + # Start the executor + executor.start() + + # 3 Threads must be running + assert executor.processing + assert active_count() == 3 + + sleep(2) + + # After finishing only two threads must be active (main + last worker, because max workers is 2) + assert active_count() == 2 + assert executor.processing + + sleep(1) + + # After finishing only 1 thread must be active + assert active_count(), 1 + assert not executor.processing + + # Observer must have been updated by the executor + assert observer.update_count == 3 From b0b2723ebe5c3053376045bcc614b0a16c6185ee Mon Sep 17 00:00:00 2001 From: DUYN Date: Fri, 19 Jun 2020 12:07:47 +0200 Subject: [PATCH 13/14] Add codecov --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index b8f22ae5..be245b24 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,3 +4,6 @@ install: - pip install -r requirements.txt script: pytest # run test + +after_success: + - codecov # submit coverage \ No newline at end of file From 4c800f69bd6e5949960bdebef07e8e978557a4e6 Mon Sep 17 00:00:00 2001 From: DUYN Date: Fri, 19 Jun 2020 12:22:26 +0200 Subject: [PATCH 14/14] Update readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 907e57d2..88d45387 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# Investing Algorithm Framework +[![Build Status](https://travis-ci.org/investingbots/investing-bot-framework.svg?branch=master)](https://travis-ci.org/investingbots/investing-bot-framework) + +# Investing Algorithm Framework The Investing Algorithm Framework is a free and open source Python framework that encourages rapid development and clean, pragmatic design.