コード例 #1
0
 def setUp(self):
     """
     create the module manager and a temporary directory.
     Write a python file with several data members into
     the created temporary directory.
     """
     self.module_manager = ModuleManager()
     self.temp_dir = tempfile.TemporaryDirectory()
     self.code_filepath = os.path.join(self.temp_dir.name, "mod_test.py")
     code = 'PLUGINS = [5,4]\nfive = 5.0\ndef func():\n\tpass'
     with open(self.code_filepath, 'w+') as f:
         f.write(code)
コード例 #2
0
 def setUp(self):
     """
     create the module manager and a temporary directory.
     Write a python file with several data members into
     the created temporary directory.
     """
     self.module_manager = ModuleManager()
     self.temp_dir = tempfile.TemporaryDirectory()
     self.code_filepath = os.path.join(self.temp_dir.name, "mod_test.py")
     code = 'PLUGINS = [5,4]\nfive = 5.0\ndef func():\n\tpass'
     with open(self.code_filepath, 'w+') as f:
         f.write(code)
コード例 #3
0
class TestModuleManager(unittest.TestCase):
    def setUp(self):
        """
        create the module manager and a temporary directory.
        Write a python file with several data members into
        the created temporary directory.
        """
        self.module_manager = ModuleManager()
        self.temp_dir = tempfile.TemporaryDirectory()
        self.code_filepath = os.path.join(self.temp_dir.name, "mod_test.py")
        code = 'PLUGINS = [5,4]\nfive = 5.0\ndef func():\n\tpass'
        with open(self.code_filepath, 'w+') as f:
            f.write(code)

    def tearDown(self):
        """
        cleanup the temporary directory created in the setUp method.
        """
        self.temp_dir.cleanup()

    def test_load_modules(self):
        """
        Create some test code. write it into the test code filepath.
        Then load the test code. Assert that the test code has all
        the desired attributes. Assert that the filepath is in the processed
        filepaths and that the expected module name is in the processed
        filepaths and the loaded modules.
        """
        module = self.module_manager.load_modules(self.code_filepath).pop()
        self.assertTrue(hasattr(module, 'PLUGINS'))
        self.assertTrue(hasattr(module, 'func'))
        self.assertTrue(hasattr(module, 'five'))
        self.assertEqual(module.PLUGINS, [5, 4])
        self.assertEqual(module.five, 5.0)
        del sys.modules[module.__name__]
        del module
        expected_module_name = 'pluginmanager_plugin_mod_test_0'
        self.assertIn(expected_module_name, self.module_manager.loaded_modules)
        self.assertIn(self.code_filepath,
                      self.module_manager.processed_filepaths.values())

        self.assertIn(expected_module_name,
                      self.module_manager.processed_filepaths.keys())

    def test_load_modules_with_processed_filepath(self):
        """
        add a filepath to the processed filepaths and then assert that
        the loaded modules are empty.
        """
        self.module_manager.processed_filepaths['test'] = self.code_filepath
        modules = self.module_manager.load_modules(self.code_filepath)
        self.assertEqual(len(modules), 0)

    def test_collect_plugins(self):
        """
        Create a module with a data member `blue`
        collect the plugins from the module and assert that the data member
        is present in the collected plugins. Next, collect the plugins without
        passing in an argument and assert it's empty. Lastly, add the module to
        the loaded modules and collect plugins without passing in anything
        explicitly into the method call. Assert that blue is still present in
        the collected modules.
        """
        module_name = 'test_pluginmanager_module'
        module = types.ModuleType(module_name)
        blue = 'blue data member'
        module.blue = blue
        plugins = self.module_manager.collect_plugins(module)
        self.assertIn(blue, plugins)

        empty_plugins = self.module_manager.collect_plugins()
        self.assertEqual(len(empty_plugins), 0)

        self.module_manager.add_to_loaded_modules(module)
        sys.modules[module_name] = module
        loaded_module_plugins = self.module_manager.collect_plugins()
        self.assertIn(blue, loaded_module_plugins)
        del sys.modules[module_name]

    def test_set_module_plugin_filters(self):
        """
        create and add some state in the module filters. Then set the module
        filters with a test object. assert that the test object is in the
        module filters and that the previous state is not.
        """
        previous_module = object()
        self.module_manager.add_module_plugin_filters(previous_module)
        test_obj = object()
        self.module_manager.set_module_plugin_filters(test_obj)
        self.assertIn(test_obj, self.module_manager.module_plugin_filters)
        self.assertNotIn(previous_module,
                         self.module_manager.module_plugin_filters)

    def test_add_to_loaded_modules(self):
        """
        assert that the module `types` is not being tracked. Then add the
        actual module to the loaded modules and assert that the string name
        is there.
        Also want to test the string handeling, so pass in a test string and
        assert that it is in tracked.
        """
        types_module_str = 'types'
        self.assertNotIn(types_module_str, self.module_manager.loaded_modules)
        self.module_manager.add_to_loaded_modules(types)
        self.assertIn(types_module_str, self.module_manager.loaded_modules)

        test_module_name = 'bogus'
        self.assertNotIn(test_module_name, self.module_manager.loaded_modules)
        self.module_manager.add_to_loaded_modules(test_module_name)
        self.assertIn(test_module_name, self.module_manager.loaded_modules)

    def test_get_loaded_modules(self):
        """
        get out the loaded modules. Assert that it is a list and is
        empty. Assert that the module `types` is not present. Then add
        the module `types` to tracked internally. get the loaded modules
        again and assert that the module `types` is present.
        """
        default_modules = self.module_manager.get_loaded_modules()
        self.assertTrue(isinstance(default_modules, list))
        self.assertEqual(len(default_modules), 0)

        self.assertNotIn(types, default_modules)
        self.module_manager.add_to_loaded_modules(types)
        gotten_modules = self.module_manager.get_loaded_modules()
        self.assertIn(types, gotten_modules)

    def test_add_module_plugin_filter(self):
        """
        add a test object to the module filters and assert that it is in there.
        """
        test_obj = object()
        self.module_manager.add_module_plugin_filters(test_obj)
        self.assertIn(test_obj, self.module_manager.module_plugin_filters)

    def test_get_module_plugin_filters(self):
        """
        Assert that the module plugin filters are empty at first. Add an
        object. Use the method to get all of the plugin filters out. Assert
        that the object returned from the method is a set. That it only has
        one object, and that the one object was the object added.
        """
        self.assertEqual(len(self.module_manager.get_module_plugin_filters()),
                         0)

        test_obj = object()
        self.module_manager.add_module_plugin_filters(test_obj)
        gotten_filters = self.module_manager.get_module_plugin_filters()
        self.assertTrue(isinstance(gotten_filters, list))
        self.assertEqual(len(gotten_filters), 1)
        self.assertIn(test_obj, gotten_filters)

    def test_get_module_plugin_filters_with_filter(self):
        """
        want to test the ability to add filter functions to
        the ascribed method so create two objects and add them
        both to the module plugin filters. Create a function that
        returns only one of the objects and pass the funciton in
        to the method call. Assert that the expected object is
        in the list, while the other is not.
        """
        test_obj_1 = object()
        test_obj_2 = object()
        objects = [test_obj_1, test_obj_2]
        self.module_manager.add_module_plugin_filters(objects)

        def get_obj_1_filter(filters):
            for filter_ in filters:
                if filter_ == test_obj_1:
                    return [test_obj_1, ]

        get_filters = self.module_manager.get_module_plugin_filters
        filters = get_filters(get_obj_1_filter)
        self.assertIn(test_obj_1, filters)
        self.assertNotIn(test_obj_2, filters)
        self.assertIn(test_obj_2, self.module_manager.module_plugin_filters)

    def test_remove_module_plugin_filters(self):
        """
        create an object, add it to the module plugin filters. Assert that the
        object is there. call the method to remove the object. Assert that it
        is not there.
        """
        test_obj = object()
        self.module_manager.add_module_plugin_filters(test_obj)
        self.assertIn(test_obj, self.module_manager.module_plugin_filters)
        self.module_manager.remove_module_plugin_filters(test_obj)
        self.assertNotIn(test_obj, self.module_manager.module_plugin_filters)

    def test_load_failing_module(self):
        """
        This tests that a failing import does not stop the program
        Currently, logging is disabled to prevent noise in the logs.
        Should change it to expect the log. Should.
        """
        logging.disable(logging.CRITICAL)
        filepath = os.path.join(self.temp_dir.name, 'fail.py')
        with open(filepath, 'w+') as f:
            f.write('blue=5/nred=')
        self.module_manager.load_modules(filepath)
        logging.disable(logging.NOTSET)

    def test_filter_modules(self):
        """
        Create a filter that returns only instances of floats. Create a list
        of plugins that include both a float and a non-float member.
        pass the list through the filter function and assert that the float
        member made it, while the non float member did not.
        """
        def filter_(plugins, *args):
            result = []
            for plugin in plugins:
                if isinstance(plugin, float):
                    result.append(plugin)
            return result
        self.module_manager.add_module_plugin_filters(filter_)
        instance = object()
        plugins = [5.0, instance]
        filtered = self.module_manager._filter_modules(plugins, [])
        self.assertNotIn(instance, filtered)
        self.assertIn(5.0, filtered)

        def bad_filter(plugins, *args):
            for plugin in plugins:
                if not isinstance(plugin, float):
                    plugins.remove(plugin)
            return plugins

        self.module_manager.set_module_plugin_filters(bad_filter)
        self.module_manager._filter_modules(plugins, [])

    def test_processed_filepath(self):
        """
        Create two fake filepaths, a "processed" filepath and an
        unprocessed filepath. Set the processed filepath in the internal
        data memeber `processed_filepaths`. Then test the prescribed method,
        asserting that the processed filepath returns a True, while the
        unprocessed filepath correctly returns a False
        """
        processed_filepath = 'dir/processed'
        test_filepath = 'dir/test'
        self.module_manager.processed_filepaths['test'] = processed_filepath
        # test processed_filepath
        processed = self.module_manager._processed_filepath(processed_filepath)
        self.assertTrue(processed)
        # test regular dir
        unprocessed = self.module_manager._processed_filepath(test_filepath)
        self.assertFalse(unprocessed)

    def test_clean_filepath(self):
        """
        Create an `__init__.py` file in the temp dir. Pass the temp dir
        filepath into the prescribed method and assert that the returned
        filepath is the created `__init__.py` file in the temp dir.

        Next, pull off the extension information from the file and repass the
        filepath in, asserting that it correctly reappends the expected
        extension.
        """
        expected_filepath = os.path.join(self.temp_dir.name, '__init__.py')
        open(expected_filepath, 'a+').close()
        cleaned_file = self.module_manager._clean_filepath(self.temp_dir.name)
        self.assertEqual(cleaned_file, expected_filepath)
        no_ext = expected_filepath[:-3]
        processed_ext = self.module_manager._clean_filepath(no_ext)
        self.assertEqual(processed_ext, expected_filepath)

    def test_update_loaded_modules(self):
        """
        Add the filepath created in setup to the processed filepath with the
        name `module_name`. Also add the `module_name` to sys.modules
        """
        module_name = 'test_pluginmanager'
        self.module_manager.loaded_modules.add(module_name)
        processed_filepaths = self.module_manager.processed_filepaths
        processed_filepaths[module_name] = self.code_filepath
        sys.modules[module_name] = None
        self.module_manager._update_loaded_modules()
        self.assertIn(module_name, self.module_manager.loaded_modules)
        self.assertIn(module_name, processed_filepaths.keys())
        del sys.modules[module_name]
        self.module_manager._update_loaded_modules()
        self.assertNotIn(module_name, processed_filepaths.keys())
        self.assertNotIn(module_name, self.module_manager.loaded_modules)
コード例 #4
0
class TestModuleManager(unittest.TestCase):
    def setUp(self):
        """
        create the module manager and a temporary directory.
        Write a python file with several data members into
        the created temporary directory.
        """
        self.module_manager = ModuleManager()
        self.temp_dir = tempfile.TemporaryDirectory()
        self.code_filepath = os.path.join(self.temp_dir.name, "mod_test.py")
        code = 'PLUGINS = [5,4]\nfive = 5.0\ndef func():\n\tpass'
        with open(self.code_filepath, 'w+') as f:
            f.write(code)

    def tearDown(self):
        """
        cleanup the temporary directory created in the setUp method.
        """
        self.temp_dir.cleanup()

    def test_load_modules(self):
        """
        Create some test code. write it into the test code filepath.
        Then load the test code. Assert that the test code has all
        the desired attributes. Assert that the filepath is in the processed
        filepaths and that the expected module name is in the processed
        filepaths and the loaded modules.
        """
        module = self.module_manager.load_modules(self.code_filepath).pop()
        self.assertTrue(hasattr(module, 'PLUGINS'))
        self.assertTrue(hasattr(module, 'func'))
        self.assertTrue(hasattr(module, 'five'))
        self.assertEqual(module.PLUGINS, [5, 4])
        self.assertEqual(module.five, 5.0)
        del sys.modules[module.__name__]
        del module
        expected_module_name = 'pluginmanager_plugin_mod_test_0'
        self.assertIn(expected_module_name, self.module_manager.loaded_modules)
        self.assertIn(self.code_filepath,
                      self.module_manager.processed_filepaths.values())

        self.assertIn(expected_module_name,
                      self.module_manager.processed_filepaths.keys())

    def test_load_modules_with_processed_filepath(self):
        """
        add a filepath to the processed filepaths and then assert that
        the loaded modules are empty.
        """
        self.module_manager.processed_filepaths['test'] = self.code_filepath
        modules = self.module_manager.load_modules(self.code_filepath)
        self.assertEqual(len(modules), 0)

    def test_collect_plugins(self):
        """
        Create a module with a data member `blue`
        collect the plugins from the module and assert that the data member
        is present in the collected plugins. Next, collect the plugins without
        passing in an argument and assert it's empty. Lastly, add the module to
        the loaded modules and collect plugins without passing in anything
        explicitly into the method call. Assert that blue is still present in
        the collected modules.
        """
        module_name = 'test_pluginmanager_module'
        module = types.ModuleType(module_name)
        blue = 'blue data member'
        module.blue = blue
        plugins = self.module_manager.collect_plugins(module)
        self.assertIn(blue, plugins)

        empty_plugins = self.module_manager.collect_plugins()
        self.assertEqual(len(empty_plugins), 0)

        self.module_manager.add_to_loaded_modules(module)
        sys.modules[module_name] = module
        loaded_module_plugins = self.module_manager.collect_plugins()
        self.assertIn(blue, loaded_module_plugins)
        del sys.modules[module_name]

    def test_set_module_plugin_filters(self):
        """
        create and add some state in the module filters. Then set the module
        filters with a test object. assert that the test object is in the
        module filters and that the previous state is not.
        """
        previous_module = object()
        self.module_manager.add_module_plugin_filters(previous_module)
        test_obj = object()
        self.module_manager.set_module_plugin_filters(test_obj)
        self.assertIn(test_obj, self.module_manager.module_plugin_filters)
        self.assertNotIn(previous_module,
                         self.module_manager.module_plugin_filters)

    def test_add_to_loaded_modules(self):
        """
        assert that the module `types` is not being tracked. Then add the
        actual module to the loaded modules and assert that the string name
        is there.
        Also want to test the string handeling, so pass in a test string and
        assert that it is in tracked.
        """
        types_module_str = 'types'
        self.assertNotIn(types_module_str, self.module_manager.loaded_modules)
        self.module_manager.add_to_loaded_modules(types)
        self.assertIn(types_module_str, self.module_manager.loaded_modules)

        test_module_name = 'bogus'
        self.assertNotIn(test_module_name, self.module_manager.loaded_modules)
        self.module_manager.add_to_loaded_modules(test_module_name)
        self.assertIn(test_module_name, self.module_manager.loaded_modules)

    def test_get_loaded_modules(self):
        """
        get out the loaded modules. Assert that it is a list and is
        empty. Assert that the module `types` is not present. Then add
        the module `types` to tracked internally. get the loaded modules
        again and assert that the module `types` is present.
        """
        default_modules = self.module_manager.get_loaded_modules()
        self.assertTrue(isinstance(default_modules, list))
        self.assertEqual(len(default_modules), 0)

        self.assertNotIn(types, default_modules)
        self.module_manager.add_to_loaded_modules(types)
        gotten_modules = self.module_manager.get_loaded_modules()
        self.assertIn(types, gotten_modules)

    def test_add_module_plugin_filter(self):
        """
        add a test object to the module filters and assert that it is in there.
        """
        test_obj = object()
        self.module_manager.add_module_plugin_filters(test_obj)
        self.assertIn(test_obj, self.module_manager.module_plugin_filters)

    def test_get_module_plugin_filters(self):
        """
        Assert that the module plugin filters are empty at first. Add an
        object. Use the method to get all of the plugin filters out. Assert
        that the object returned from the method is a set. That it only has
        one object, and that the one object was the object added.
        """
        self.assertEqual(len(self.module_manager.get_module_plugin_filters()),
                         0)

        test_obj = object()
        self.module_manager.add_module_plugin_filters(test_obj)
        gotten_filters = self.module_manager.get_module_plugin_filters()
        self.assertTrue(isinstance(gotten_filters, list))
        self.assertEqual(len(gotten_filters), 1)
        self.assertIn(test_obj, gotten_filters)

    def test_get_module_plugin_filters_with_filter(self):
        """
        want to test the ability to add filter functions to
        the ascribed method so create two objects and add them
        both to the module plugin filters. Create a function that
        returns only one of the objects and pass the funciton in
        to the method call. Assert that the expected object is
        in the list, while the other is not.
        """
        test_obj_1 = object()
        test_obj_2 = object()
        objects = [test_obj_1, test_obj_2]
        self.module_manager.add_module_plugin_filters(objects)

        def get_obj_1_filter(filters):
            for filter_ in filters:
                if filter_ == test_obj_1:
                    return [
                        test_obj_1,
                    ]

        get_filters = self.module_manager.get_module_plugin_filters
        filters = get_filters(get_obj_1_filter)
        self.assertIn(test_obj_1, filters)
        self.assertNotIn(test_obj_2, filters)
        self.assertIn(test_obj_2, self.module_manager.module_plugin_filters)

    def test_remove_module_plugin_filters(self):
        """
        create an object, add it to the module plugin filters. Assert that the
        object is there. call the method to remove the object. Assert that it
        is not there.
        """
        test_obj = object()
        self.module_manager.add_module_plugin_filters(test_obj)
        self.assertIn(test_obj, self.module_manager.module_plugin_filters)
        self.module_manager.remove_module_plugin_filters(test_obj)
        self.assertNotIn(test_obj, self.module_manager.module_plugin_filters)

    def test_load_failing_module(self):
        """
        This tests that a failing import does not stop the program
        Currently, logging is disabled to prevent noise in the logs.
        Should change it to expect the log. Should.
        """
        logging.disable(logging.CRITICAL)
        filepath = os.path.join(self.temp_dir.name, 'fail.py')
        with open(filepath, 'w+') as f:
            f.write('blue=5/nred=')
        self.module_manager.load_modules(filepath)
        logging.disable(logging.NOTSET)

    def test_filter_modules(self):
        """
        Create a filter that returns only instances of floats. Create a list
        of plugins that include both a float and a non-float member.
        pass the list through the filter function and assert that the float
        member made it, while the non float member did not.
        """
        def filter_(plugins, *args):
            result = []
            for plugin in plugins:
                if isinstance(plugin, float):
                    result.append(plugin)
            return result

        self.module_manager.add_module_plugin_filters(filter_)
        instance = object()
        plugins = [5.0, instance]
        filtered = self.module_manager._filter_modules(plugins, [])
        self.assertNotIn(instance, filtered)
        self.assertIn(5.0, filtered)

        def bad_filter(plugins, *args):
            for plugin in plugins:
                if not isinstance(plugin, float):
                    plugins.remove(plugin)
            return plugins

        self.module_manager.set_module_plugin_filters(bad_filter)
        self.module_manager._filter_modules(plugins, [])

    def test_processed_filepath(self):
        """
        Create two fake filepaths, a "processed" filepath and an
        unprocessed filepath. Set the processed filepath in the internal
        data memeber `processed_filepaths`. Then test the prescribed method,
        asserting that the processed filepath returns a True, while the
        unprocessed filepath correctly returns a False
        """
        processed_filepath = 'dir/processed'
        test_filepath = 'dir/test'
        self.module_manager.processed_filepaths['test'] = processed_filepath
        # test processed_filepath
        processed = self.module_manager._processed_filepath(processed_filepath)
        self.assertTrue(processed)
        # test regular dir
        unprocessed = self.module_manager._processed_filepath(test_filepath)
        self.assertFalse(unprocessed)

    def test_clean_filepath(self):
        """
        Create an `__init__.py` file in the temp dir. Pass the temp dir
        filepath into the prescribed method and assert that the returned
        filepath is the created `__init__.py` file in the temp dir.

        Next, pull off the extension information from the file and repass the
        filepath in, asserting that it correctly reappends the expected
        extension.
        """
        expected_filepath = os.path.join(self.temp_dir.name, '__init__.py')
        open(expected_filepath, 'a+').close()
        cleaned_file = self.module_manager._clean_filepath(self.temp_dir.name)
        self.assertEqual(cleaned_file, expected_filepath)
        no_ext = expected_filepath[:-3]
        processed_ext = self.module_manager._clean_filepath(no_ext)
        self.assertEqual(processed_ext, expected_filepath)

    def test_update_loaded_modules(self):
        """
        Add the filepath created in setup to the processed filepath with the
        name `module_name`. Also add the `module_name` to sys.modules
        """
        module_name = 'test_pluginmanager'
        self.module_manager.loaded_modules.add(module_name)
        processed_filepaths = self.module_manager.processed_filepaths
        processed_filepaths[module_name] = self.code_filepath
        sys.modules[module_name] = None
        self.module_manager._update_loaded_modules()
        self.assertIn(module_name, self.module_manager.loaded_modules)
        self.assertIn(module_name, processed_filepaths.keys())
        del sys.modules[module_name]
        self.module_manager._update_loaded_modules()
        self.assertNotIn(module_name, processed_filepaths.keys())
        self.assertNotIn(module_name, self.module_manager.loaded_modules)