Merge #12856: Tests: Add Metaclass for BitcoinTestFramework

c9cce0a Tests: Add Metaclass for BitcoinTestFramework (Will Ayd)

Pull request description:

  BitcoinTestFramework instructs developers in its docstring to override
  `set_test_params` and `run_test` in subclasses while being sure NOT to
  override `__init__` and `main` . This change adds a metaclass to ensure
  that developers adhere to that protocol, raising a ``TypeError`` in
  instances where they have not.

  closes #12835

Tree-SHA512: 5a47a7ead1f18361138cad4374747c4a8f29d25506f7b2c2a8c1c966a0b65e5ccf7317f9a078df8680fdab5d3fb71fee46a159c9f381878a3683c1e9f874abbe
This commit is contained in:
Wladimir J. van der Laan 2018-04-08 19:47:00 +02:00
commit 27278dffe8
No known key found for this signature in database
GPG Key ID: 1E4AED62986CD25D
1 changed files with 23 additions and 1 deletions

View File

@ -41,7 +41,28 @@ TEST_EXIT_PASSED = 0
TEST_EXIT_FAILED = 1
TEST_EXIT_SKIPPED = 77
class BitcoinTestFramework():
class BitcoinTestMetaClass(type):
"""Metaclass for BitcoinTestFramework.
Ensures that any attempt to register a subclass of `BitcoinTestFramework`
adheres to a standard whereby the subclass overrides `set_test_params` and
`run_test` but DOES NOT override either `__init__` or `main`. If any of
those standards are violated, a ``TypeError`` is raised."""
def __new__(cls, clsname, bases, dct):
if not clsname == 'BitcoinTestFramework':
if not ('run_test' in dct and 'set_test_params' in dct):
raise TypeError("BitcoinTestFramework subclasses must override "
"'run_test' and 'set_test_params'")
if '__init__' in dct or 'main' in dct:
raise TypeError("BitcoinTestFramework subclasses may not override "
"'__init__' or 'main'")
return super().__new__(cls, clsname, bases, dct)
class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
"""Base class for a bitcoin test script.
Individual bitcoin test scripts should subclass this class and override the set_test_params() and run_test() methods.
@ -434,6 +455,7 @@ class BitcoinTestFramework():
for i in range(self.num_nodes):
initialize_datadir(self.options.tmpdir, i)
class SkipTest(Exception):
"""This exception is raised to skip a test"""
def __init__(self, message):