Checking for zombified Characters and failing modules that leave them in state.

pull/2177/head
jMyles 2020-08-07 13:47:30 -07:00
parent 6dd188a6d8
commit 4057608e68
3 changed files with 50 additions and 17 deletions

View File

@ -265,23 +265,28 @@ class Learner:
self._init_frames = frames
from tests.conftest import global_mutable_where_everybody
for frame in frames:
try:
test_name = frame.frame.f_locals['request'].module.__name__
break
except KeyError:
try:
if frame.function.startswith("test"):
test_name = frame.function
break
else:
continue
except AttributeError:
continue
else:
# Didn't find which test from which this object came. Hmph.
# It's possible that this is wrong, but it's better than nothing:
test_name = os.environ["PYTEST_CURRENT_TEST"].split("::")[1]
# Below is the variant where we iterate through frames. If there's a race condition within a test itself, this will be more reliable.
# for frame in frames:
# try:
# test_name = frame.frame.f_locals['request'].module
# break
# except KeyError:
# try:
# if frame.function.startswith("test"):
# where = frame[0]
# test_name = where
# break
# else:
# continue
# except AttributeError:
# continue
# else:
# # Didn't find which test from which this object came. Hmph.
# # It's possible that this is wrong, but it's better than nothing:
# test_name = os.environ["PYTEST_CURRENT_TEST"].split("::")[1]
test_name = os.environ["PYTEST_CURRENT_TEST"]
if test_name == 'test_ursula_and_local_keystore_signer_integration':
assert True
global_mutable_where_everybody[test_name].append(self)
self._FOR_TEST = test_name
########################
@ -550,6 +555,7 @@ class Learner:
self.log.warn(
"Learning loop isn't started; can't learn about nodes now. You can override this with force=True.")
elif force:
# TODO: What if this has been stopped?
self.log.info("Learning loop wasn't started; forcing start now.")
self._learning_task.start(self._SHORT_LEARNING_DELAY, now=True)

View File

@ -314,6 +314,7 @@ def run_entire_cli_lifecycle(click_runner,
grant_args += ('--provider', TEST_PROVIDER_URI,
'--rate', Web3.toWei(9, 'gwei'))
# TODO: Stop.
grant_result = click_runner.invoke(nucypher_cli, grant_args, catch_exceptions=False, env=envvars)
assert grant_result.exit_code == 0

View File

@ -138,3 +138,29 @@ def pytest_collection_modifyitems(config, items):
GlobalLoggerSettings.set_log_level(log_level_name)
GlobalLoggerSettings.start_text_file_logging()
GlobalLoggerSettings.start_json_file_logging()
global_mutable_where_everybody = defaultdict(list)
@pytest.fixture(scope='module', autouse=True)
def check_character_state_after_test(request):
# TODO: Maybe patch here instead of the debug nonsense?
yield
gmwe = global_mutable_where_everybody
module_name = request.module.__name__
test_learners = global_mutable_where_everybody.get(module_name, [])
# Those match the module name exactly; maybe there are some that we got by frame.
for maybe_frame, learners in global_mutable_where_everybody.items():
if f"{module_name}.py" in maybe_frame:
test_learners.extend(learners)
still_running = [learner if learner._learning_task.running else None for learner in test_learners]
if any(still_running):
for learner in still_running:
try: # TODO: Deal with stop vs disenchant. Currently stop is only for Ursula.
learner.stop()
except AttributeError:
learner.disenchant()
pytest.fail(f"Learners remaining: {still_running} ")