-
Notifications
You must be signed in to change notification settings - Fork 70
Structure improvement functional tests #309
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
3 commits
Select commit
Hold shift + click to select a range
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
Large diffs are not rendered by default.
Oops, something went wrong.
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,43 @@ | ||
| # With this the user can use a custom | ||
| # python environment, like those created | ||
| # with venv or pyenv. The default will be | ||
| # the system python. | ||
| [virtualenvs] | ||
| prefer-active-python = true | ||
|
|
||
| # This isn't really needed on pratical aspect | ||
| # since this is only for organize the functional tests | ||
| # but is necessary since its a requirement for poetry. | ||
| [tool.poetry] | ||
| name = "floresta-functional-tests" | ||
| version = "0.0.1" | ||
| description = "collection of tools to help with functional testing of Floresta" | ||
| authors = ["The Floresta Project Developers"] | ||
| license = "MIT" | ||
|
|
||
| # To add a new dependency, use `poetry add <package>`. | ||
| # To update, first find outdated packages with `poetry show --outdated`, | ||
| # then re-install with `poetry add <package>@<version>`. | ||
| [tool.poetry.dependencies] | ||
| python = ">=3.12" | ||
| jsonrpclib = "^0.2.1" | ||
| requests = "^2.32.3" | ||
| black = "^24.10.0" | ||
| pylint = "^3.3.2" | ||
| poethepoet = "^0.31.1" | ||
|
|
||
| # Here we can define some custom tasks | ||
| # (even bash or rust ones can be defined). | ||
| # All of them will run on virtualenv environment. | ||
| # For more information, see guidelines in https://poethepoet.natn.io | ||
| [tool.poe.tasks] | ||
| format = "black ./tests" | ||
| lint = "pylint ./tests" | ||
| example-test = "python tests/run_tests.py --test-name example_test" | ||
| restart-test = "python tests/run_tests.py --test-name restart" | ||
| tests = ["example-test", "restart-test"] | ||
| pre-commit = ["format", "lint", "tests"] | ||
|
|
||
| [build-system] | ||
| requires = ["poetry-core"] | ||
| build-backend = "poetry.core.masonry.api" |
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 |
|---|---|---|
| @@ -1,31 +1,116 @@ | ||
| """ | ||
| This is an example of how tests should look like, see the class bellow for more info | ||
| example_test.py | ||
|
|
||
| This is an example of how tests should look like, see the class bellow for more info. | ||
|
|
||
| Every test should define, at least, two special methods: | ||
|
|
||
| - `set_test_params`: change default values for number of node, topology, etc. | ||
| - `run_test`: the test itself | ||
|
|
||
| Any attempt to define a test without these methods will raise a TypeError. | ||
|
|
||
| Other methods are available to do more things. Some of them make sense only in `set_test_params` | ||
| and others make sense only in `run_tests`. | ||
|
|
||
| - `add_node_settings`: register a node settings to create a node after. A node will be a spawned | ||
| `cargo run --features json-rpc --bin florestad -- --network <chain>` process. | ||
| In summary, its a `FlorestaRPC` instance. | ||
|
|
||
| The chain can be one of ["regtest", "signet", "testnet"]. | ||
| You can pass some extra arguments with `extra_args` and it will be appended | ||
| to the process command. The `rpcserver` is a dictionary defining a "host", | ||
| "port", "username" and "password". The "data_dir" is optional and can be | ||
| used to create a temporary directory to store files. It will return an | ||
| integer pointing an index of a list of nodes. | ||
|
|
||
| - `get_node_settings`: get a registered node settings | ||
|
|
||
| - `run_node`: run a node for a registered node settings at some index, | ||
| configured with `add_node_settings`. | ||
|
|
||
| - `get_node`: get a resgistered running node. | ||
|
|
||
| - `wait_for_rpc_connection`: given a node index, wait for it to be available. | ||
|
|
||
| - `run_rpc`: our RPC is a MockUtreexod running on a thread. | ||
|
|
||
| - `stop_node`: given a running node at index, stop it. | ||
| If any directory was created, it will be removed. | ||
|
|
||
| - `stop`: stop all registered nodes. | ||
|
|
||
| After the definition of test within a class, you should call `MyTest().main()` at the end of file. | ||
| """ | ||
| import time | ||
| import os | ||
|
|
||
| from test_framework.test_framework import TestFramework | ||
| import json | ||
| from test_framework.test_framework import FlorestaTestFramework | ||
| from test_framework.electrum_client import ElectrumClient | ||
| from test_framework.mock_rpc import MockUtreexod | ||
| from test_framework.floresta_rpc import REGTEST_RPC_SERVER | ||
|
|
||
|
|
||
| class ExampleTest(FlorestaTestFramework): | ||
| """ | ||
| Tests should be a child class from FlorestaTestFramework | ||
|
|
||
| class ExampleTest(TestFramework): | ||
| """ Tests should be a child class from TestFramework """ | ||
| In each test class definition, `set_test_params` and `run_test`, say what | ||
| the test do and the expected result in the docstrings | ||
| """ | ||
|
|
||
| index = [-1] | ||
| expected_version = ["Floresta 0.3.0", "1.4"] | ||
| expected_height = 0 | ||
| expected_block = "0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206" | ||
| expected_difficulty = 1 | ||
| expected_leaf_count = 0 | ||
|
|
||
| def set_test_params(self): | ||
| """ | ||
| Here we define setup for test adding a node definition | ||
| """ | ||
| ExampleTest.index[0] = self.add_node_settings( | ||
| chain="regtest", extra_args=[], rpcserver=REGTEST_RPC_SERVER | ||
| ) | ||
|
|
||
| # All tests should override the run_test method | ||
| def run_test(self): | ||
| """ | ||
| Here we define the test itself: | ||
|
|
||
| - creates a dummy rpc listening on port 8080 | ||
| - wait until the rpc is ready and start a new node (this crate's binary) | ||
| - wait the node to start | ||
| - perform some requests to FlorestaRPC node | ||
| - Create an instance of the Electrum Client, a small implementation of the electrum | ||
| protocol, to test our own electrum implementation | ||
| """ | ||
| # This creates a dummy rpc listening on port 8080 | ||
| self.run_rpc() | ||
|
|
||
| # Wait until the rpc is ready | ||
| # Start a new node (this crate's binary) | ||
| node1 = self.run_node("./data/test1", "regtest") | ||
| self.run_node(ExampleTest.index[0]) | ||
|
|
||
| # Wait the node to start | ||
| self.wait_for_rpc_connection() | ||
| self.wait_for_rpc_connection(ExampleTest.index[0]) | ||
|
|
||
| # Perform for some defined requests to FlorestaRPC | ||
| node = self.get_node(ExampleTest.index[0]) | ||
| inf_response = node.get_blockchain_info() | ||
|
|
||
| # Create an instance of the Electrum Client, a small implementation of the electrum | ||
| # protocol, to test our own electrum implementation | ||
| electrum = ElectrumClient("localhost", 50001) | ||
| print(electrum.get_version()) | ||
| rpc_response = json.loads(electrum.get_version()) | ||
|
|
||
| # Make assertions | ||
| assert rpc_response["result"][0] == ExampleTest.expected_version[0] | ||
| assert rpc_response["result"][1] == ExampleTest.expected_version[1] | ||
| assert inf_response["height"] == ExampleTest.expected_height | ||
| assert inf_response["best_block"] == ExampleTest.expected_block | ||
| assert inf_response["difficulty"] == ExampleTest.expected_difficulty | ||
| assert inf_response["leaf_count"] == ExampleTest.expected_leaf_count | ||
|
|
||
|
|
||
| if __name__ == '__main__': | ||
| if __name__ == "__main__": | ||
| ExampleTest().main() |
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 |
|---|---|---|
| @@ -1,21 +1,65 @@ | ||
| import subprocess | ||
| """ | ||
| restart.py | ||
|
|
||
| A simple test that restart a Floresta node and a related data directory. | ||
|
|
||
| The directories used between each power-on/power-off must not be corrupted. | ||
| """ | ||
|
|
||
| import time | ||
| import os | ||
| import filecmp | ||
| from test_framework.test_framework import TestFramework | ||
| from test_framework.test_framework import FlorestaTestFramework | ||
| from test_framework.floresta_rpc import REGTEST_RPC_SERVER | ||
|
|
||
|
|
||
| class TestRestart(FlorestaTestFramework): | ||
| """ | ||
| Test the restart of a node, calling a first node (0) the recall it as (1); | ||
| We need to check if given data_dirs arent corrupted between restarts | ||
| """ | ||
|
|
||
| indexes = [-1, -1] | ||
|
|
||
| def set_test_params(self): | ||
| """ | ||
| Here we define setup for test | ||
| """ | ||
| dirname = os.path.dirname(__file__) | ||
| TestRestart.indexes[0] = self.add_node_settings( | ||
| chain="regtest", | ||
| extra_args=[], | ||
| rpcserver=REGTEST_RPC_SERVER, | ||
| data_dir=os.path.normpath(os.path.join(dirname, "data", "0")), | ||
| ) | ||
| TestRestart.indexes[1] = self.add_node_settings( | ||
| chain="regtest", | ||
| extra_args=[], | ||
| rpcserver=REGTEST_RPC_SERVER, | ||
| data_dir=os.path.normpath(os.path.join(dirname, "data", "1")), | ||
| ) | ||
|
|
||
| class TestRestart(TestFramework): | ||
| def run_test(self): | ||
| """ | ||
| Tests if we don't corrupt our data dir between restarts. This would have caught, | ||
| the error fixed in #9 | ||
| Tests if we don't corrupt our data dir between restarts. This would have caught, | ||
| the error fixed in #9 | ||
| """ | ||
| base_testdir = "data/TestRestart/" | ||
| self.run_node(base_testdir + "1/") | ||
| time.sleep(5) | ||
| self.stop_node(0) | ||
| self.run_node(base_testdir + "2/") | ||
| time.sleep(5) | ||
| self.stop_node(0) | ||
| assert (filecmp.dircmp(base_testdir + "2/", base_testdir + "1/")) | ||
| # start first node, wait and then kill | ||
| self.run_node(TestRestart.indexes[0]) | ||
| time.sleep(5.0) | ||
| self.stop_node(TestRestart.indexes[0]) | ||
|
|
||
| # start second node, wait and then kill | ||
| self.run_node(TestRestart.indexes[1]) | ||
| time.sleep(5.0) | ||
| self.stop_node(TestRestart.indexes[1]) | ||
|
|
||
| # check for any corruption | ||
| assert filecmp.dircmp( | ||
| self.get_node_settings(TestRestart.indexes[0])["data_dir"], | ||
| self.get_node_settings(TestRestart.indexes[1])["data_dir"], | ||
| ) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| TestRestart().main() |
Oops, something went wrong.
Oops, something went wrong.
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.