From 4f6f226b18e8442002ecb1d3a3ea4db63bc53241 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 9 Oct 2017 20:20:58 +0100 Subject: [PATCH 1/6] refactor asserts due to PYTHONOPTIMIZE flag --- CHANGELOG.md | 1 + lbrynet/conf.py | 8 ++++---- lbrynet/daemon/ExchangeRateManager.py | 6 ++++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d0a0de31..293096e51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ at anytime. * Announcing by head blob is turned on by default * Updated reflector server dns * Moved tests into the lbrynet package. + * Refactor some assert statements to accommodate the PYTHONOPTIMIZE flag set for Android. ### Added * Added WAL pragma to sqlite3 diff --git a/lbrynet/conf.py b/lbrynet/conf.py index 29f730f9b..35fb1fbf6 100644 --- a/lbrynet/conf.py +++ b/lbrynet/conf.py @@ -361,8 +361,8 @@ class Config(object): return name in self.get_valid_setting_names() def _assert_valid_setting(self, name): - assert self._is_valid_setting(name), \ - KeyError('{} is not a valid setting'.format(name)) + if not self._is_valid_setting(name): + raise AssertionError(KeyError('{} is not a valid setting'.format(name))) def _validate_settings(self, data): invalid_settings = set(data.keys()) - set(self.get_valid_setting_names()) @@ -371,8 +371,8 @@ class Config(object): def _assert_editable_setting(self, name): self._assert_valid_setting(name) - assert name not in self._fixed_defaults, \ - ValueError('{} is not an editable setting'.format(name)) + if name in self._fixed_defaults: + raise AssertionError(ValueError('{} is not an editable setting'.format(name))) def _validate_currency(self, currency): if currency not in self._fixed_defaults['CURRENCIES'].keys(): diff --git a/lbrynet/daemon/ExchangeRateManager.py b/lbrynet/daemon/ExchangeRateManager.py index 805df2db1..52fb1ab73 100644 --- a/lbrynet/daemon/ExchangeRateManager.py +++ b/lbrynet/daemon/ExchangeRateManager.py @@ -17,8 +17,10 @@ COINBASE_FEE = 0.0 #add fee class ExchangeRate(object): def __init__(self, market, spot, ts): - assert int(time.time()) - ts < 600 - assert spot > 0 + if not int(time.time()) - ts < 600: + raise AssertionError() + if not spot > 0: + raise AssertionError() self.currency_pair = (market[0:3], market[3:6]) self.spot = spot self.ts = ts From fb6545481b86aad81b90c94e4a78a547125e6dc3 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 9 Oct 2017 20:41:08 +0100 Subject: [PATCH 2/6] refactored one more assert --- lbrynet/conf.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lbrynet/conf.py b/lbrynet/conf.py index 35fb1fbf6..3a9bfe23b 100644 --- a/lbrynet/conf.py +++ b/lbrynet/conf.py @@ -352,7 +352,8 @@ class Config(object): return env_settings def _assert_valid_data_type(self, data_type): - assert data_type in self._data, KeyError('{} in is not a valid data type'.format(data_type)) + if not data_type in self._data: + raise AssertionError(KeyError('{} in is not a valid data type'.format(data_type))) def get_valid_setting_names(self): return self._data[TYPE_DEFAULT].keys() From 6ed56804b96ef3454225dfaa0b440e8b19f5ddd8 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 9 Oct 2017 21:14:16 +0100 Subject: [PATCH 3/6] return empty string as default value when docstring is missing --- lbrynet/daemon/Daemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lbrynet/daemon/Daemon.py b/lbrynet/daemon/Daemon.py index 59e344b25..3aaa2722f 100644 --- a/lbrynet/daemon/Daemon.py +++ b/lbrynet/daemon/Daemon.py @@ -1230,7 +1230,7 @@ class Daemon(AuthJSONRPCServer): ) return self._render_response({ - 'help': textwrap.dedent(fn.__doc__) + 'help': textwrap.dedent(fn.__doc__ or '') }) def jsonrpc_commands(self): From 0291482abbbf4872aa2fc73315f85abeee59b793 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 11 Oct 2017 07:59:30 +0100 Subject: [PATCH 4/6] raised errors directly instead of wrapping with AssertionError --- lbrynet/conf.py | 6 +++--- lbrynet/tests/unit/test_conf.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lbrynet/conf.py b/lbrynet/conf.py index 3a9bfe23b..4b156ad89 100644 --- a/lbrynet/conf.py +++ b/lbrynet/conf.py @@ -353,7 +353,7 @@ class Config(object): def _assert_valid_data_type(self, data_type): if not data_type in self._data: - raise AssertionError(KeyError('{} in is not a valid data type'.format(data_type))) + raise KeyError('{} in is not a valid data type'.format(data_type)) def get_valid_setting_names(self): return self._data[TYPE_DEFAULT].keys() @@ -363,7 +363,7 @@ class Config(object): def _assert_valid_setting(self, name): if not self._is_valid_setting(name): - raise AssertionError(KeyError('{} is not a valid setting'.format(name))) + raise KeyError('{} is not a valid setting'.format(name)) def _validate_settings(self, data): invalid_settings = set(data.keys()) - set(self.get_valid_setting_names()) @@ -373,7 +373,7 @@ class Config(object): def _assert_editable_setting(self, name): self._assert_valid_setting(name) if name in self._fixed_defaults: - raise AssertionError(ValueError('{} is not an editable setting'.format(name))) + raise ValueError('{} is not an editable setting'.format(name)) def _validate_currency(self, currency): if currency not in self._fixed_defaults['CURRENCIES'].keys(): diff --git a/lbrynet/tests/unit/test_conf.py b/lbrynet/tests/unit/test_conf.py index 9d7abca6c..c18ed1f83 100644 --- a/lbrynet/tests/unit/test_conf.py +++ b/lbrynet/tests/unit/test_conf.py @@ -39,12 +39,12 @@ class SettingsTest(unittest.TestCase): def test_invalid_setting_raises_exception(self): settings = self.get_mock_config_instance() - self.assertRaises(AssertionError, settings.set, 'invalid_name', 123) + self.assertRaises(KeyError, settings.set, 'invalid_name', 123) def test_invalid_data_type_raises_exception(self): settings = self.get_mock_config_instance() self.assertIsNone(settings.set('test', 123)) - self.assertRaises(AssertionError, settings.set, 'test', 123, ('fake_data_type',)) + self.assertRaises(KeyError, settings.set, 'test', 123, ('fake_data_type',)) def test_setting_precedence(self): settings = self.get_mock_config_instance() From e522e7e7f7156169e7e052b42e35594459051771 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 17 Oct 2017 03:11:20 +0100 Subject: [PATCH 5/6] Changed AssertionError to ValueError. Skip tests that cannot pass on Android. --- lbrynet/daemon/ExchangeRateManager.py | 4 ++-- lbrynet/tests/functional/test_misc.py | 11 ++++++++++- lbrynet/tests/unit/core/test_log_support.py | 11 ++++++++--- lbrynet/tests/unit/lbrynet_daemon/test_Daemon.py | 11 ++++++++--- .../unit/lbrynet_daemon/test_ExchangeRateManager.py | 4 ++-- lbrynet/tests/util.py | 3 +++ 6 files changed, 33 insertions(+), 11 deletions(-) diff --git a/lbrynet/daemon/ExchangeRateManager.py b/lbrynet/daemon/ExchangeRateManager.py index 52fb1ab73..63298ed88 100644 --- a/lbrynet/daemon/ExchangeRateManager.py +++ b/lbrynet/daemon/ExchangeRateManager.py @@ -18,9 +18,9 @@ COINBASE_FEE = 0.0 #add fee class ExchangeRate(object): def __init__(self, market, spot, ts): if not int(time.time()) - ts < 600: - raise AssertionError() + raise ValueError('The timestamp is too dated.') if not spot > 0: - raise AssertionError() + raise ValueError('Spot must be greater than 0.') self.currency_pair = (market[0:3], market[3:6]) self.spot = spot self.ts = ts diff --git a/lbrynet/tests/functional/test_misc.py b/lbrynet/tests/functional/test_misc.py index 1fa2b2c26..d84d693cb 100644 --- a/lbrynet/tests/functional/test_misc.py +++ b/lbrynet/tests/functional/test_misc.py @@ -33,7 +33,7 @@ from lbrynet.core.server.BlobRequestHandler import BlobRequestHandlerFactory from lbrynet.core.server.ServerProtocol import ServerProtocolFactory from lbrynet.tests import mocks -from lbrynet.tests.util import mk_db_and_blob_dir, rm_db_and_blob_dir +from lbrynet.tests.util import mk_db_and_blob_dir, rm_db_and_blob_dir, is_android FakeNode = mocks.Node FakeWallet = mocks.Wallet @@ -487,6 +487,9 @@ class TestTransfer(TestCase): return d + @unittest.skipIf(is_android(), + 'Test cannot pass on Android because multiprocessing ' + 'is not supported at the OS level.') def test_lbry_transfer(self): sd_hash_queue = Queue() kill_event = Event() @@ -574,6 +577,9 @@ class TestTransfer(TestCase): return d + @unittest.skipIf(is_android(), + 'Test cannot pass on Android because multiprocessing ' + 'is not supported at the OS level.') def test_last_blob_retrieval(self): kill_event = Event() dead_event_1 = Event() @@ -656,6 +662,9 @@ class TestTransfer(TestCase): d.addBoth(stop) return d + @unittest.skipIf(is_android(), + 'Test cannot pass on Android because multiprocessing ' + 'is not supported at the OS level.') def test_double_download(self): sd_hash_queue = Queue() kill_event = Event() diff --git a/lbrynet/tests/unit/core/test_log_support.py b/lbrynet/tests/unit/core/test_log_support.py index cf7bdfc27..5f68c6272 100644 --- a/lbrynet/tests/unit/core/test_log_support.py +++ b/lbrynet/tests/unit/core/test_log_support.py @@ -2,13 +2,15 @@ import StringIO import logging import mock +import unittest from twisted.internet import defer -from twisted.trial import unittest +from twisted import trial from lbrynet.core import log_support +from lbrynet.tests.util import is_android -class TestLogger(unittest.TestCase): +class TestLogger(trial.unittest.TestCase): def raiseError(self): raise Exception('terrible things happened') @@ -26,12 +28,15 @@ class TestLogger(unittest.TestCase): handler.setFormatter(logging.Formatter("%(filename)s:%(lineno)d - %(message)s")) self.log.addHandler(handler) + @unittest.skipIf(is_android(), + 'Test cannot pass on Android because the tests package is compiled ' + 'which results in a different method call stack') def test_can_log_failure(self): def output_lines(): return self.stream.getvalue().split('\n') # the line number could change if this file gets refactored - expected_first_line = 'test_log_support.py:18 - My message: terrible things happened' + expected_first_line = 'test_log_support.py:20 - My message: terrible things happened' # testing the entirety of the message is futile as the # traceback will depend on the system the test is being run on diff --git a/lbrynet/tests/unit/lbrynet_daemon/test_Daemon.py b/lbrynet/tests/unit/lbrynet_daemon/test_Daemon.py index 0fffb7b4a..3a91c54b0 100644 --- a/lbrynet/tests/unit/lbrynet_daemon/test_Daemon.py +++ b/lbrynet/tests/unit/lbrynet_daemon/test_Daemon.py @@ -1,8 +1,9 @@ import mock import json +import unittest from twisted.internet import defer -from twisted.trial import unittest +from twisted import trial from lbryschema.decode import smart_decode from lbrynet import conf @@ -14,6 +15,8 @@ from lbrynet.tests.mocks import mock_conf_settings, FakeNetwork from lbrynet.tests.mocks import BlobAvailabilityTracker as DummyBlobAvailabilityTracker from lbrynet.tests.mocks import ExchangeRateManager as DummyExchangeRateManager from lbrynet.tests.mocks import BTCLBCFeed, USDBTCFeed +from lbrynet.tests.util import is_android + def get_test_daemon(data_rate=None, generous=True, with_fee=False): if data_rate is None: @@ -59,7 +62,7 @@ def get_test_daemon(data_rate=None, generous=True, with_fee=False): return daemon -class TestCostEst(unittest.TestCase): +class TestCostEst(trial.unittest.TestCase): def setUp(self): mock_conf_settings(self) util.resetTime(self) @@ -93,7 +96,7 @@ class TestCostEst(unittest.TestCase): self.assertEquals(daemon.get_est_cost("test", size).result, correct_result) -class TestJsonRpc(unittest.TestCase): +class TestJsonRpc(trial.unittest.TestCase): def setUp(self): def noop(): return None @@ -109,6 +112,8 @@ class TestJsonRpc(unittest.TestCase): d = defer.maybeDeferred(self.test_daemon.jsonrpc_status) d.addCallback(lambda status: self.assertDictContainsSubset({'is_running': False}, status)) + @unittest.skipIf(is_android(), + 'Test cannot pass on Android because PYTHONOPTIMIZE removes the docstrings.') def test_help(self): d = defer.maybeDeferred(self.test_daemon.jsonrpc_help, command='status') d.addCallback(lambda result: self.assertSubstring('daemon status', result['help'])) diff --git a/lbrynet/tests/unit/lbrynet_daemon/test_ExchangeRateManager.py b/lbrynet/tests/unit/lbrynet_daemon/test_ExchangeRateManager.py index c8695144c..9c82b449b 100644 --- a/lbrynet/tests/unit/lbrynet_daemon/test_ExchangeRateManager.py +++ b/lbrynet/tests/unit/lbrynet_daemon/test_ExchangeRateManager.py @@ -35,9 +35,9 @@ class ExchangeRateTest(unittest.TestCase): util.resetTime(self) def test_invalid_rates(self): - with self.assertRaises(AssertionError): + with self.assertRaises(ValueError): ExchangeRateManager.ExchangeRate('USDBTC', 0, util.DEFAULT_ISO_TIME) - with self.assertRaises(AssertionError): + with self.assertRaises(ValueError): ExchangeRateManager.ExchangeRate('USDBTC', -1, util.DEFAULT_ISO_TIME) diff --git a/lbrynet/tests/util.py b/lbrynet/tests/util.py index ba3fc05c9..43cb007ea 100644 --- a/lbrynet/tests/util.py +++ b/lbrynet/tests/util.py @@ -36,3 +36,6 @@ def resetTime(test_case, timestamp=DEFAULT_TIMESTAMP): patcher = mock.patch('lbrynet.core.utils.utcnow') patcher.start().return_value = timestamp test_case.addCleanup(patcher.stop) + +def is_android(): + return 'ANDROID_ARGUMENT' in os.environ # detect Android using the Kivy way From f3d45061e8b511b4a80f0a439cb144ad208d6bd4 Mon Sep 17 00:00:00 2001 From: Jack Robison Date: Wed, 25 Oct 2017 12:05:46 -0400 Subject: [PATCH 6/6] fix changelog merge conflict --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d1086763..7a2adfda1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,7 +29,6 @@ at anytime. * Use the first port available for the peer and dht ports, starting with the provided values (defaults of 3333 and 4444). This allows multiple lbrynet instances in a LAN with UPnP. * Detect a UPnP redirect that didn't get cleaned up on a previous run and use it * Bumped jsonschema requirement to 2.6.0 - * Moved tests into the lbrynet package. * Refactor some assert statements to accommodate the PYTHONOPTIMIZE flag set for Android. ### Added