From c06be8df48e6e5c88f95a8aafabcab53e6142963 Mon Sep 17 00:00:00 2001 From: henddher Date: Sat, 1 Oct 2022 17:34:41 -0500 Subject: [PATCH 1/6] Force failure. --- evennia/scripts/tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/evennia/scripts/tests.py b/evennia/scripts/tests.py index 3d0e7d1308..aa30cad4f7 100644 --- a/evennia/scripts/tests.py +++ b/evennia/scripts/tests.py @@ -16,6 +16,7 @@ class TestScript(BaseEvenniaTest): self.assertTrue(obj, errors) self.assertFalse(errors, errors) mockinit.assert_called() + self.assertTrue(False) class TestScriptDB(TestCase): From 796f3910c6ba3bf272ca8a6c9c5d126493a6ef63 Mon Sep 17 00:00:00 2001 From: henddher Date: Sat, 1 Oct 2022 20:46:15 -0500 Subject: [PATCH 2/6] Skip global scripts that cannot be 'imported' successfully, and log_err about it. --- evennia/utils/containers.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/evennia/utils/containers.py b/evennia/utils/containers.py index ae3236a2b3..eb319f8160 100644 --- a/evennia/utils/containers.py +++ b/evennia/utils/containers.py @@ -202,14 +202,17 @@ class GlobalScriptContainer(Container): """ if self.typeclass_storage is None: self.typeclass_storage = {} - for key, data in self.loaded_data.items(): + for key, data in list(self.loaded_data.items()): try: typeclass = data.get("typeclass", settings.BASE_SCRIPT_TYPECLASS) self.typeclass_storage[key] = class_from_module(typeclass) except Exception: - logger.log_trace( - f"GlobalScriptContainer could not start import global script {key}." + logger.log_err( + f"GlobalScriptContainer could not start import global script {key}. " + "It will be removed (skipped)." ) + # Let's remove this key/value. We want to let other scripts load. + self.loaded_data.pop(key) def get(self, key, default=None): """ From d129c16c1b9c7d0da26e5847e104eda1f0ea1576 Mon Sep 17 00:00:00 2001 From: henddher Date: Sat, 1 Oct 2022 20:47:51 -0500 Subject: [PATCH 3/6] Remove force failure --- evennia/scripts/tests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/evennia/scripts/tests.py b/evennia/scripts/tests.py index aa30cad4f7..3d0e7d1308 100644 --- a/evennia/scripts/tests.py +++ b/evennia/scripts/tests.py @@ -16,7 +16,6 @@ class TestScript(BaseEvenniaTest): self.assertTrue(obj, errors) self.assertFalse(errors, errors) mockinit.assert_called() - self.assertTrue(False) class TestScriptDB(TestCase): From 6f4b832263c93776bafa1ac016b70e42ac98fc9f Mon Sep 17 00:00:00 2001 From: henddher Date: Sun, 2 Oct 2022 11:28:52 -0500 Subject: [PATCH 4/6] Revert back to log_trace. --- evennia/utils/containers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/evennia/utils/containers.py b/evennia/utils/containers.py index eb319f8160..d3392b1a14 100644 --- a/evennia/utils/containers.py +++ b/evennia/utils/containers.py @@ -207,7 +207,7 @@ class GlobalScriptContainer(Container): typeclass = data.get("typeclass", settings.BASE_SCRIPT_TYPECLASS) self.typeclass_storage[key] = class_from_module(typeclass) except Exception: - logger.log_err( + logger.log_trace( f"GlobalScriptContainer could not start import global script {key}. " "It will be removed (skipped)." ) From d2cb75b058931e7c9e579997570e045bd4421cc0 Mon Sep 17 00:00:00 2001 From: henddher Date: Sun, 2 Oct 2022 15:41:20 -0500 Subject: [PATCH 5/6] Addition of unit-tests for GlobalScriptContainer. --- evennia/utils/containers.py | 5 +- evennia/utils/tests/test_containers.py | 86 ++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 evennia/utils/tests/test_containers.py diff --git a/evennia/utils/containers.py b/evennia/utils/containers.py index d3392b1a14..a94a92454b 100644 --- a/evennia/utils/containers.py +++ b/evennia/utils/containers.py @@ -106,6 +106,7 @@ class GlobalScriptContainer(Container): callables from settings but a custom dict of tuples. """ + __BASE_SCRIPT_TYPECLASS = class_from_module(settings.BASE_SCRIPT_TYPECLASS) def __init__(self): """ @@ -205,7 +206,9 @@ class GlobalScriptContainer(Container): for key, data in list(self.loaded_data.items()): try: typeclass = data.get("typeclass", settings.BASE_SCRIPT_TYPECLASS) - self.typeclass_storage[key] = class_from_module(typeclass) + script_typeclass = class_from_module(typeclass) + assert issubclass(script_typeclass, self.__BASE_SCRIPT_TYPECLASS) + self.typeclass_storage[key] = script_typeclass except Exception: logger.log_trace( f"GlobalScriptContainer could not start import global script {key}. " diff --git a/evennia/utils/tests/test_containers.py b/evennia/utils/tests/test_containers.py new file mode 100644 index 0000000000..6967cd725e --- /dev/null +++ b/evennia/utils/tests/test_containers.py @@ -0,0 +1,86 @@ +import unittest + +from evennia.utils import containers +from django.conf import settings +from evennia.utils.utils import class_from_module + +_BASE_SCRIPT_TYPECLASS = class_from_module(settings.BASE_SCRIPT_TYPECLASS) + +class GoodScript(_BASE_SCRIPT_TYPECLASS): + pass + +class BadScript: + """Not subclass of _BASE_SCRIPT_TYPECLASS,""" + pass + +class WorseScript(_BASE_SCRIPT_TYPECLASS): + """objects will fail upon call""" + @property + def objects(self): + from evennia import module_that_doesnt_exist + +class TestGlobalScriptContainer(unittest.TestCase): + + def setUp(self): + settings.GLOBAL_SCRIPTS = {} + + def patch_global_scripts(self, adict): + settings.GLOBAL_SCRIPTS.update(adict) + + def test_init_with_no_scripts(self): + gsc = containers.GlobalScriptContainer() + + self.assertEqual(len(gsc.loaded_data), 0) + + def test_init_with_typeclassless_script(self): + self.patch_global_scripts({'script_name': {}}) + + gsc = containers.GlobalScriptContainer() + + self.assertEqual(len(gsc.loaded_data), 1) + self.assertIn('script_name', gsc.loaded_data) + + def test_start_with_no_scripts(self): + gsc = containers.GlobalScriptContainer() + + gsc.start() + + self.assertEqual(len(gsc.typeclass_storage), 0) + + def test_start_with_typeclassless_script_defaults_to_base(self): + self.patch_global_scripts({'script_name': {}}) + gsc = containers.GlobalScriptContainer() + + gsc.start() + + self.assertEqual(len(gsc.typeclass_storage), 1) + self.assertIn('script_name', gsc.typeclass_storage) + self.assertEqual(gsc.typeclass_storage['script_name'], _BASE_SCRIPT_TYPECLASS) + + def test_start_with_typeclassed_script_loads_it(self): + self.patch_global_scripts({'script_name': {'typeclass': 'evennia.utils.tests.test_containers.GoodScript'}}) + gsc = containers.GlobalScriptContainer() + + gsc.start() + + self.assertEqual(len(gsc.typeclass_storage), 1) + self.assertIn('script_name', gsc.typeclass_storage) + self.assertEqual(gsc.typeclass_storage['script_name'], GoodScript) + + def test_start_with_bad_typeclassed_script_skips_it(self): + self.patch_global_scripts({'script_name': {'typeclass': 'evennia.utils.tests.test_containers.BadScript'}}) + gsc = containers.GlobalScriptContainer() + + gsc.start() + + self.assertEqual(len(gsc.typeclass_storage), 0) + self.assertNotIn('script_name', gsc.typeclass_storage) + + def test_start_with_worst_typeclassed_script_skips_it(self): + self.patch_global_scripts({'script_name': {'typeclass': 'evennia.utils.tests.test_containers.WorstScript'}}) + gsc = containers.GlobalScriptContainer() + + gsc.start() + + self.assertEqual(len(gsc.typeclass_storage), 0) + self.assertNotIn('script_name', gsc.typeclass_storage) From 8b590a5cf65a2c772fae939ac603970b062f926b Mon Sep 17 00:00:00 2001 From: henddher Date: Mon, 3 Oct 2022 19:53:43 -0500 Subject: [PATCH 6/6] Use override_settings to patch settings.GLOBAL_SCRIPTS. --- evennia/utils/tests/test_containers.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/evennia/utils/tests/test_containers.py b/evennia/utils/tests/test_containers.py index 6967cd725e..0f46ec1bca 100644 --- a/evennia/utils/tests/test_containers.py +++ b/evennia/utils/tests/test_containers.py @@ -2,6 +2,7 @@ import unittest from evennia.utils import containers from django.conf import settings +from django.test import override_settings from evennia.utils.utils import class_from_module _BASE_SCRIPT_TYPECLASS = class_from_module(settings.BASE_SCRIPT_TYPECLASS) @@ -21,19 +22,13 @@ class WorseScript(_BASE_SCRIPT_TYPECLASS): class TestGlobalScriptContainer(unittest.TestCase): - def setUp(self): - settings.GLOBAL_SCRIPTS = {} - - def patch_global_scripts(self, adict): - settings.GLOBAL_SCRIPTS.update(adict) - def test_init_with_no_scripts(self): gsc = containers.GlobalScriptContainer() self.assertEqual(len(gsc.loaded_data), 0) + @override_settings(GLOBAL_SCRIPTS={'script_name': {}}) def test_init_with_typeclassless_script(self): - self.patch_global_scripts({'script_name': {}}) gsc = containers.GlobalScriptContainer() @@ -47,8 +42,8 @@ class TestGlobalScriptContainer(unittest.TestCase): self.assertEqual(len(gsc.typeclass_storage), 0) + @override_settings(GLOBAL_SCRIPTS={'script_name': {}}) def test_start_with_typeclassless_script_defaults_to_base(self): - self.patch_global_scripts({'script_name': {}}) gsc = containers.GlobalScriptContainer() gsc.start() @@ -57,8 +52,8 @@ class TestGlobalScriptContainer(unittest.TestCase): self.assertIn('script_name', gsc.typeclass_storage) self.assertEqual(gsc.typeclass_storage['script_name'], _BASE_SCRIPT_TYPECLASS) + @override_settings(GLOBAL_SCRIPTS={'script_name': {'typeclass': 'evennia.utils.tests.test_containers.GoodScript'}}) def test_start_with_typeclassed_script_loads_it(self): - self.patch_global_scripts({'script_name': {'typeclass': 'evennia.utils.tests.test_containers.GoodScript'}}) gsc = containers.GlobalScriptContainer() gsc.start() @@ -67,8 +62,8 @@ class TestGlobalScriptContainer(unittest.TestCase): self.assertIn('script_name', gsc.typeclass_storage) self.assertEqual(gsc.typeclass_storage['script_name'], GoodScript) + @override_settings(GLOBAL_SCRIPTS={'script_name': {'typeclass': 'evennia.utils.tests.test_containers.BadScript'}}) def test_start_with_bad_typeclassed_script_skips_it(self): - self.patch_global_scripts({'script_name': {'typeclass': 'evennia.utils.tests.test_containers.BadScript'}}) gsc = containers.GlobalScriptContainer() gsc.start() @@ -76,8 +71,8 @@ class TestGlobalScriptContainer(unittest.TestCase): self.assertEqual(len(gsc.typeclass_storage), 0) self.assertNotIn('script_name', gsc.typeclass_storage) + @override_settings(GLOBAL_SCRIPTS={'script_name': {'typeclass': 'evennia.utils.tests.test_containers.WorstScript'}}) def test_start_with_worst_typeclassed_script_skips_it(self): - self.patch_global_scripts({'script_name': {'typeclass': 'evennia.utils.tests.test_containers.WorstScript'}}) gsc = containers.GlobalScriptContainer() gsc.start()