-
Notifications
You must be signed in to change notification settings - Fork 45
feat: add --sysctl-init-file as cli command option #714
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
0aa5573
refactor: extract SysctlRunner from SysctlProtocol
alexruzenhack 0685c2b
chore: remove path word lsfrom error messages
alexruzenhack 9250fc5
chore: treats the exceptions in the sysctl protocol
alexruzenhack 839a599
refactor: extract get_line_parts function
alexruzenhack d7c4706
feat: add --sysctl-config-file as cli command option
alexruzenhack 9991be7
chore: remove unused settings
alexruzenhack 1c740e7
fix: test and lint
alexruzenhack 3918162
test: serialize path with json.dumps
alexruzenhack 45ddf4b
chore: remove unused class attribute
alexruzenhack beb0b56
style: join lines
alexruzenhack c3ba641
feat: make init_file mandatory with assert
alexruzenhack e880135
chore: add docstring to load method
alexruzenhack 08a07a7
feat: load init file only if arg value is not None
alexruzenhack f6edfcf
chore: remove bugfix
alexruzenhack File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| from hathor.sysctl.runner import SysctlRunner | ||
|
|
||
|
|
||
| class SysctlInitFileLoader: | ||
| def __init__(self, runner: SysctlRunner, init_file: str) -> None: | ||
| assert runner | ||
| assert init_file | ||
|
|
||
| self.runner = runner | ||
| self.init_file = init_file | ||
|
|
||
| def load(self) -> None: | ||
msbrogli marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """Read the init_file and execute each line as a syctl command in the runner.""" | ||
| with open(self.init_file, 'r', encoding='utf-8') as file: | ||
| lines = file.readlines() | ||
|
|
||
| for line in lines: | ||
| self.runner.run(line.strip()) | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,200 @@ | ||
| import json | ||
| import shutil | ||
| import tempfile | ||
| from pathlib import Path | ||
| from unittest.mock import Mock, patch | ||
|
|
||
| from hathor.builder.sysctl_builder import SysctlBuilder | ||
| from hathor.cli.run_node import RunNode | ||
| from hathor.sysctl.exception import SysctlEntryNotFound, SysctlRunnerException | ||
| from hathor.sysctl.init_file_loader import SysctlInitFileLoader | ||
| from hathor.sysctl.runner import SysctlRunner | ||
| from tests import unittest | ||
|
|
||
|
|
||
| class SysctlInitTest(unittest.TestCase): | ||
|
|
||
| def setUp(self): | ||
| super().setUp() | ||
| self.tmp_dir = tempfile.mkdtemp() | ||
|
|
||
| def tearDown(self): | ||
| super().tearDown() | ||
| # Removing tmpdir | ||
| shutil.rmtree(self.tmp_dir) | ||
|
|
||
| def test_sysctl_builder_fail_with_invalid_property(self): | ||
| file_content = [ | ||
| 'invalid.property=10', | ||
| ] | ||
|
|
||
| with tempfile.NamedTemporaryFile( | ||
| dir=self.tmp_dir, | ||
| suffix='.txt', | ||
| prefix='sysctl_', | ||
| delete=False) as sysctl_init_file: | ||
| sysctl_init_file.write('\n'.join(file_content).encode()) | ||
| sysctl_init_file_path = str(Path(sysctl_init_file.name)) | ||
|
|
||
| # prepare to register only p2p commands | ||
| artifacts = Mock(**{ | ||
| 'p2p_manager': Mock(), | ||
| 'manager.metrics.websocket_factory.return_value': None | ||
| }) | ||
|
|
||
| with self.assertRaises(SysctlEntryNotFound) as context: | ||
| root = SysctlBuilder(artifacts).build() | ||
| runner = SysctlRunner(root) | ||
| loader = SysctlInitFileLoader(runner, sysctl_init_file_path) | ||
| loader.load() | ||
|
|
||
| # assert message in the caught exception | ||
| expected_msg = 'invalid.property' | ||
| self.assertEqual(str(context.exception), expected_msg) | ||
|
|
||
| def test_sysctl_builder_fail_with_invalid_value(self): | ||
| file_content = [ | ||
| 'p2p.rate_limit.global.send_tips=!!tuple [1,2]' | ||
| ] | ||
|
|
||
| with tempfile.NamedTemporaryFile( | ||
| dir=self.tmp_dir, | ||
| suffix='.txt', | ||
| prefix='sysctl_', | ||
| delete=False) as sysctl_init_file: | ||
| sysctl_init_file.write('\n'.join(file_content).encode()) | ||
| sysctl_init_file_path = str(Path(sysctl_init_file.name)) | ||
|
|
||
| # prepare to register only p2p commands | ||
| artifacts = Mock(**{ | ||
| 'p2p_manager': Mock(), | ||
| 'manager.metrics.websocket_factory.return_value': None | ||
| }) | ||
|
|
||
| with self.assertRaises(SysctlRunnerException) as context: | ||
| root = SysctlBuilder(artifacts).build() | ||
| runner = SysctlRunner(root) | ||
| loader = SysctlInitFileLoader(runner, sysctl_init_file_path) | ||
| loader.load() | ||
|
|
||
| # assert message in the caught exception | ||
| expected_msg = 'value: wrong format' | ||
| self.assertEqual(str(context.exception), expected_msg) | ||
|
|
||
| def test_syctl_init_file_fail_with_empty_or_invalid_file(self): | ||
| # prepare to register only p2p commands | ||
| artifacts = Mock(**{ | ||
| 'p2p_manager': Mock(), | ||
| 'manager.metrics.websocket_factory.return_value': None | ||
| }) | ||
|
|
||
| with self.assertRaises(AssertionError): | ||
| root = SysctlBuilder(artifacts).build() | ||
| runner = SysctlRunner(root) | ||
| loader = SysctlInitFileLoader(runner, None) | ||
| loader.load() | ||
|
|
||
| with self.assertRaises(AssertionError): | ||
| root = SysctlBuilder(artifacts).build() | ||
| runner = SysctlRunner(root) | ||
| loader = SysctlInitFileLoader(runner, "") | ||
| loader.load() | ||
|
|
||
| @patch('twisted.internet.endpoints.serverFromString') # avoid open sock | ||
| def test_command_option_sysctl_init_file(self, mock_endpoint): | ||
| class CustomRunNode(RunNode): | ||
| def start_manager(self) -> None: | ||
| pass | ||
|
|
||
| def register_signal_handlers(self) -> None: | ||
| pass | ||
|
|
||
| expected_sysctl_dict = { | ||
| 'p2p.max_enabled_sync': 7, | ||
| 'p2p.rate_limit.global.send_tips': (5, 3), | ||
| 'p2p.sync_update_interval': 17, | ||
| } | ||
|
|
||
| file_content = [ | ||
| 'p2p.max_enabled_sync=7', | ||
| 'p2p.rate_limit.global.send_tips=5,3', | ||
| 'p2p.sync_update_interval=17', | ||
| ] | ||
|
|
||
| with tempfile.NamedTemporaryFile( | ||
| dir=self.tmp_dir, | ||
| suffix='.txt', | ||
| prefix='sysctl_', | ||
| delete=False) as sysctl_init_file: | ||
| sysctl_init_file.write('\n'.join(file_content).encode()) | ||
| sysctl_init_file_path = str(Path(sysctl_init_file.name)) | ||
|
|
||
| run_node = CustomRunNode(argv=[ | ||
| '--sysctl', 'tcp:8181', | ||
| '--sysctl-init-file', sysctl_init_file_path, # relative to src/hathor | ||
| '--memory-storage', | ||
| ]) | ||
| self.assertTrue(run_node is not None) | ||
| conn = run_node.manager.connections | ||
|
|
||
| curr_max_enabled_sync = conn.MAX_ENABLED_SYNC | ||
| self.assertEqual( | ||
| curr_max_enabled_sync, | ||
| expected_sysctl_dict['p2p.max_enabled_sync']) | ||
|
|
||
| curr_rate_limit_global_send_tips = conn.rate_limiter.get_limit(conn.GlobalRateLimiter.SEND_TIPS) | ||
| self.assertEqual( | ||
| curr_rate_limit_global_send_tips.max_hits, | ||
| expected_sysctl_dict['p2p.rate_limit.global.send_tips'][0]) | ||
| self.assertEqual( | ||
| curr_rate_limit_global_send_tips.window_seconds, | ||
| expected_sysctl_dict['p2p.rate_limit.global.send_tips'][1]) | ||
|
|
||
| curr_sync_update_interval = conn.lc_sync_update_interval | ||
| self.assertEqual( | ||
| curr_sync_update_interval, | ||
| expected_sysctl_dict['p2p.sync_update_interval']) | ||
|
|
||
| # assert always_enabled_sync when it is set with a file | ||
| expected_sysctl_dict = { | ||
| 'p2p.always_enable_sync': ['peer-3', 'peer-4'], | ||
| } | ||
|
|
||
| file_content = [ | ||
| 'peer-3', | ||
| 'peer-4', | ||
| ] | ||
|
|
||
| # set the always_enabled_sync peers file | ||
| with tempfile.NamedTemporaryFile( | ||
| dir=self.tmp_dir, | ||
| suffix='.txt', | ||
| prefix='always_enable_sync_', | ||
| delete=False) as always_enabled_peers_file: | ||
| always_enabled_peers_file.write('\n'.join(file_content).encode()) | ||
| always_enabled_peers_file_path = str(Path(always_enabled_peers_file.name)) | ||
|
|
||
| file_content = [ | ||
| f'p2p.always_enable_sync.readtxt={json.dumps(always_enabled_peers_file_path)}' | ||
| ] | ||
|
|
||
| # set the sysctl.txt file | ||
| with tempfile.NamedTemporaryFile( | ||
| dir=self.tmp_dir, | ||
| suffix='.txt', | ||
| prefix='sysctl_', | ||
| delete=False) as sysctl_init_file: | ||
| sysctl_init_file.write('\n'.join(file_content).encode()) | ||
| sysctl_init_file_path = str(Path(sysctl_init_file.name)) | ||
|
|
||
| run_node = CustomRunNode(argv=[ | ||
| '--sysctl', 'tcp:8181', | ||
| '--sysctl-init-file', sysctl_init_file_path, # relative to src/hathor | ||
| '--memory-storage', | ||
| ]) | ||
| self.assertTrue(run_node is not None) | ||
| conn = run_node.manager.connections | ||
|
|
||
| curr_always_enabled_sync = list(conn.always_enable_sync) | ||
| self.assertTrue( | ||
| set(curr_always_enabled_sync).issuperset(set(expected_sysctl_dict['p2p.always_enable_sync']))) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.