예제 #1
0
    def testLoadErrors(self):
        f = factory.Factory(plugin_dirs=('./plugins', ))
        self.assertEqual(f.status(), 0)

        with mock.patch('importlib.import_module') as loader:
            loader.side_effect = Exception()
            with self.assertLogs(level='CRITICAL') as log:
                f.load()
            self.assertEqual(f.status(), 1)
            for out in log.output:
                self.assertIn("Failed to load module", out)

        with mock.patch('os.path.isdir', return_value=False):
            with self.assertLogs(level='ERROR') as log:
                f.load()
            self.assertEqual(f.status(), 1)
            self.assertEqual(len(log.output), 1)
            self.assertIn("'plugin_dirs' parameter is not a directory",
                          log.output[0])

        with mock.patch('os.path.isfile', return_value=False):
            with self.assertLogs(level='ERROR') as log:
                f.load()
            self.assertEqual(f.status(), 1)
            self.assertEqual(len(log.output), 1)
            self.assertIn("'plugin_dirs' parameter is not a python package",
                          log.output[0])
예제 #2
0
    def testCreate(self):
        f = factory.Factory(plugin_dirs=('./plugins', ))
        f.load()
        self.assertEqual(f.status(), 0)

        obj = f.create('CustomObject', name='Andrew')
        self.assertEqual(obj.name(), 'Andrew')
        self.assertEqual(f.status(), 0)

        obj = f.create('CustomCustomObject', name='Andrew')
        self.assertEqual(obj.name(), 'Andrew')
        self.assertEqual(f.status(), 0)

        with self.assertLogs(level='CRITICAL') as log:
            f.create('TestObjectBadInit', name='Andrew')
        self.assertEqual(f.status(), 1)
        self.assertEqual(len(log.output), 1)
        self.assertIn("Failed to create 'TestObjectBadInit'", log.output[0])

        with self.assertLogs(level='ERROR') as log:
            f.create('Unknown')
        self.assertEqual(f.status(), 1)
        self.assertEqual(len(log.output), 1)
        self.assertIn("The supplied name 'Unknown' is not associated",
                      log.output[0])
예제 #3
0
    def testRegister(self):
        f = factory.Factory()
        f.load()
        self.assertEqual(f.status(), 0)

        plugins2 = os.path.join('plugins2', 'CustomObject2.py')
        spec = importlib.util.spec_from_file_location('CustomObject2',
                                                      plugins2)
        module = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(module)
        otype = module.CustomObject2

        f.register('CO2', otype)
        self.assertEqual(f.status(), 0)

        obj = f.create('CO2', name='Andrew')
        self.assertEqual(f.status(), 0)
        self.assertIsInstance(obj, otype)
        self.assertEqual(obj.name(), 'Andrew')

        with self.assertLogs(level='ERROR') as log:
            f.register('CO2', otype)
        self.assertEqual(f.status(), 1)
        self.assertEqual(len(log.output), 1)
        self.assertIn("The 'CO2' name is already", log.output[0])
예제 #4
0
 def testPrint(self):
     f = factory.Factory(plugin_dirs=('./plugins', ))
     f.load()
     f._registered_types.pop('TestObjectBadParams')  # avoid error
     out = str(f)
     self.assertIn('CustomObject', out)
     self.assertIn('CustomCustomObject', out)
예제 #5
0
def make_formatter(filename, root, plugin_dirs):
    """
    Create the `Formatter` object from the [Formatter] block of the `pyhit.Node` of *root*.

    By default, a `BasicFormatter` is created. Refer to `make_controllers` function for information
    on the supplied input arguments.
    """

    # Locate/create the [Formatter] node
    f_node = moosetree.find(root, func=lambda n: n.fullpath == '/Formatter')
    if f_node is None:
        f_node = root.append('Formatter', type='BasicFormatter')

    # Factory for building Formatter objects
    f_factory = factory.Factory(plugin_dirs=plugin_dirs,
                                plugin_types=(Formatter, ))
    f_factory.load()
    if f_factory.status() > 0:
        msg = "An error occurred registering the Formatter type, see console message(s) for details."
        raise RuntimeError(msg)

    # Create the Formatter object by parsing the input file
    formatters = list()
    f_parser = factory.Parser(f_factory, formatters)
    with mooseutils.CurrentWorkingDirectory(os.path.dirname(filename)):
        f_parser._parseNode(filename, f_node)
    if f_parser.status() > 0:
        msg = "An error occurred during parsing of the root level parameters for creation of the Formatter object, see console message(s) for details."
        raise RuntimeError(msg)

    return formatters[0]
예제 #6
0
    def testTypes(self):

        f = factory.Factory()
        f.load()
        w = factory.Warehouse()
        p = factory.Parser(f, w)
        p.parse('test1.hit')

        self.assertEqual(len(w.objects), 4)
        self.assertEqual(w.objects[0].name(), 'scalar')
        self.assertEqual(w.objects[0].getParam('par_int'), 1980)
        self.assertEqual(w.objects[0].getParam('par_float'), 1.2345)
        self.assertEqual(w.objects[0].getParam('par_str'), "string with space")
        self.assertEqual(w.objects[0].getParam('par_bool'), True)

        self.assertEqual(w.objects[1].name(), 'vector')
        self.assertEqual(w.objects[1].getParam('vec_int'), (1949, 1954, 1977, 1980))
        self.assertEqual(w.objects[1].getParam('vec_float'), (1.1, 1.2, 1.3))
        self.assertEqual(w.objects[1].getParam('vec_str'), ("s0", "s1", "s2"))
        self.assertEqual(w.objects[1].getParam('vec_bool'), (True, False, True, False, True, False))

        self.assertEqual(w.objects[2].name(), 'any')
        self.assertEqual(w.objects[2].getParam('par'), "this is something")

        self.assertEqual(w.objects[3].name(), 'scalar_with_quote')
        self.assertEqual(w.objects[3].getParam('par_int'), 1980)
        self.assertEqual(w.objects[3].getParam('par_float'), 1.2345)
        self.assertEqual(w.objects[3].getParam('par_str'), "string with 'quote'")
        self.assertEqual(w.objects[3].getParam('par_bool'), True)
예제 #7
0
 def testPackageError(self):
     f = factory.Factory(plugin_dirs=(self._tmpdir, ))
     with self.assertLogs(level='ERROR') as log:
         f.load()
     self.assertEqual(f.status(), 1)
     self.assertEqual(len(log.output), 1)
     self.assertIn("the 'plugin_dirs' parameter is not a python package",
                   log.output[0])
예제 #8
0
    def testSimple(self):
        f = factory.Factory()
        f.load()
        w = factory.Warehouse()
        p = factory.Parser(f, w)
        p.parse('test0.hit')

        self.assertEqual(len(w.objects), 2)
        self.assertEqual(w.objects[0].name(), 'object0')
        self.assertEqual(w.objects[1].name(), 'object1')
예제 #9
0
def make_controllers(filename, root, plugin_dirs):
    """
    Create the `Controller` object from the [Controllers] block of the `pyhit.Node` of *root*.

    The *filename* is provided for error reporting and setting the current working directory for
    creating object defined in the configuration file. It should be the file used for generating
    the tree structure in *root*.

    The *plugin_dirs* should contain a list of absolute paths to include when registering Controller
    objects with the factory. By default, regardless of the contents of *root*, all registered
    Controller objects are created.
    """

    # Locate/create the [Controllers] node
    c_node = moosetree.find(root, func=lambda n: n.fullpath == '/Controllers')
    if c_node is None:
        c_node = root.append('Controllers')

    # Factory for building Controller objects
    c_factory = factory.Factory(plugin_dirs=plugin_dirs,
                                plugin_types=(Controller, ))
    c_factory.load()
    if c_factory.status() > 0:
        msg = "An error occurred registering the Controller type, see console message(s) for details."
        raise RuntimeError(msg)

    # All Controller object type found by the Factory are automatically included with the default
    # configuration. This adds them to the configuration tree so they will be built by the factory
    c_types = set(child['type'] for child in c_node)
    for name in [
            key for key, value in c_factory._registered_types.items()
            if value.AUTO_BUILD
    ]:
        if name not in c_types:
            c_node.append(f"_moosetools_{name}", type=name)

    # Use the Parser to create the Controller objects
    controllers = list()
    c_parser = factory.Parser(c_factory, controllers)
    with mooseutils.CurrentWorkingDirectory(os.path.dirname(filename)):
        c_parser.parse(filename, c_node)
    if c_parser.status() > 0:
        msg = "An error occurred during parsing of the Controller block, see console message(s) for details."
        raise RuntimeError(msg)

    return tuple(controllers)
예제 #10
0
def make_harness(filename, root, cli_args):
    """
    Create the `TestHarness` object from top-level parameters in the `pyhit.Node` of *root*.

    The *filename* is provided for error reporting and should be the file used for generating
    the tree structure in *root*. The *cli_args* input is passed to the created `TestHarness` object
    via the `applyCommandLineArguments` method.

    It is expected that the file that produced *root* has top-level parameters, which are used to
    create a `TestHarness` object.
    """
    # Top-level parameters are used to build the TestHarness object. Creating custom `TestHarness`
    # objects is not-supported, so don't allow "type" to be set.
    if 'type' in root:
        msg = "The 'type' parameter must NOT be defined in the top-level of the configuration."
        raise RuntimeError(msg)
    root['type'] = 'TestHarness'

    # Build a factory capable of creating the TestHarness object
    f = factory.Factory()
    f.register('TestHarness', TestHarness)
    if f.status() > 0:
        msg = "An error occurred during registration of the TestHarness type, see console message(s) for details."
        raise RuntimeError(msg)

    # Setup the environment variables
    setup_environment(filename, root)

    # Use the Parser is used to correctly convert HIT to InputParameters
    w = list()
    p = factory.Parser(f, w)
    with mooseutils.CurrentWorkingDirectory(os.path.dirname(filename)):
        p._parseNode(filename, root)
    if p.status() > 0:
        msg = "An error occurred during parsing of the root level parameters for creation of the TestHarness object, see console message(s) for details."
        raise RuntimeError(msg)

    # Apply the command line arguments to update TestHarness object parameters
    harness = w[0]
    harness.applyCommandLineArguments(cli_args)
    if harness.status() > 0:
        msg = "An error occurred applying the command line arguments to the TestHarness object, see console message(s) for details."
        raise RuntimeError(msg)

    return harness
예제 #11
0
    def testParams(self):
        f = factory.Factory(plugin_dirs=('./plugins', ))
        f.load()
        self.assertEqual(f.status(), 0)

        params = f.params('TestObject')
        self.assertEqual(f.status(), 0)
        self.assertIn('par', params)

        with self.assertLogs(level='CRITICAL') as log:
            f.params('TestObjectBadParams')
        self.assertEqual(f.status(), 1)
        self.assertEqual(len(log.output), 1)
        self.assertIn('Failed to evaluate validParams', log.output[0])

        with self.assertLogs(level='ERROR') as log:
            f.params('Unknown')
        self.assertEqual(f.status(), 1)
        self.assertEqual(len(log.output), 1)
        self.assertIn("The supplied name 'Unknown' is not associated",
                      log.output[0])
예제 #12
0
    def testSubBlocks(self):
        root = pyhit.Node(None, 'Tests')
        root.append('obj0', type='TestObject')
        root.append('obj1', type='TestObject')
        sub = root.append('sub')
        sub.append('obj2', type='TestObject')
        sub.append('obj3', type='TestObject')

        f = factory.Factory()
        f.load()
        w = factory.Warehouse()
        p = factory.Parser(f, w)

        with mock.patch('moosetools.pyhit.load') as load:
            load.return_value = root
            p.parse('test0.hit')

        self.assertEqual(len(w.objects), 4)
        self.assertEqual(w.objects[0].name(), 'obj0')
        self.assertEqual(w.objects[1].name(), 'obj1')
        self.assertEqual(w.objects[2].name(), 'obj2')
        self.assertEqual(w.objects[3].name(), 'obj3')
예제 #13
0
 def testLoad(self):
     f = factory.Factory(plugin_dirs=('./plugins', ))
     f.load()
     self.assertIn('CustomObject', f._registered_types)
예제 #14
0
 def testInit(self):
     f = factory.Factory()
     self.assertEqual(f.status(), 0)
     f.load()
     self.assertEqual(f.status(), 0)
예제 #15
0
    def testErrors(self):

        f = factory.Factory()
        f.load()
        w = factory.Warehouse()
        p = factory.Parser(f, w)

        # INVALID FILENAME
        with self.assertLogs(level='ERROR') as log:
            p.parse('wrong')
        self.assertEqual(len(log.output), 1)
        self.assertIn("The filename 'wrong' does not exist.", log.output[0])

        # MISSING TYPE
        root = pyhit.Node(None, 'Tests')
        root.append('obj0')
        with self.assertLogs(level='ERROR') as log:
            p._parseNode('test0.hit', root)
        self.assertEqual(p.status(), 1)
        self.assertEqual(len(log.output), 1)
        self.assertIn("Missing 'type' in block", log.output[0])

        # FAIL PYHIT.LOAD
        with mock.patch('moosetools.pyhit.load') as load:
            load.side_effect = Exception()
            with self.assertLogs(level='ERROR') as log:
                p.parse('test0.hit')
            self.assertEqual(p.status(), 1)
            self.assertEqual(len(log.output), 1)
            self.assertIn("Failed to load filename with pyhit: test0.hit", log.output[0])

        # OBJECT FAILS VALIDPARAMS
        root = pyhit.Node(None, 'Tests')
        root.append('obj0', type='TestObjectBadParams')
        with mock.patch('moosetools.pyhit.load') as load:
            load.return_value = root
            with self.assertLogs(level='ERROR') as log:
                p.parse('test0.hit')
            self.assertEqual(p.status(), 1)
            self.assertEqual(len(log.output), 2)
            self.assertIn("Failed to evaluate validParams function of 'TestObjectBadParams'",
                          log.output[0])
            self.assertIn("Failed to extract parameters from 'TestObjectBadParams'", log.output[1])

        # PARAM NO EXISTY
        root = pyhit.Node(None, 'Tests')
        root.append('obj0', type='TestObject', nope='1')
        with mock.patch('moosetools.pyhit.load') as load:
            load.return_value = root
            with self.assertLogs(level='ERROR') as log:
                p.parse('test0.hit')
            self.assertEqual(p.status(), 1)
            self.assertEqual(len(log.output), 1)
            self.assertIn("he parameter 'nope' does not exist", log.output[0])

        # PARAM WRONG TYPE
        root = pyhit.Node(None, 'Tests')
        root.append('obj0', type='TestObject', par_int='abc')
        with mock.patch('moosetools.pyhit.load') as load:
            load.return_value = root
            with self.assertLogs(level='ERROR') as log:
                p.parse('test0.hit')
            self.assertEqual(p.status(), 1)
            self.assertEqual(len(log.output), 1)
            self.assertIn(
                "Failed to convert 'None' to the correct type(s) of '(<class 'int'>,)' for 'par_int' parameter",
                log.output[0])

        # OBJECT FAILS __INIT__
        root = pyhit.Node(None, 'Tests')
        root.append('obj0', type='TestObjectBadInit')
        with mock.patch('moosetools.pyhit.load') as load:
            load.return_value = root
            with self.assertLogs(level='ERROR') as log:
                p.parse('test0.hit')
            self.assertEqual(p.status(), 1)
            self.assertEqual(len(log.output), 2)
            self.assertIn("Failed to create 'TestObjectBadInit' object.", log.output[0])
            self.assertIn(
                "Failed to create object of type 'TestObjectBadInit' in block 'Tests/obj0'",
                log.output[1])

        # DUPLICATE BLOCKS/PARAMS
        root = pyhit.Node(None, 'Tests')
        root.append('obj0', type='TestObject')
        root.append('obj0', type='TestObject')
        with mock.patch('moosetools.pyhit.load') as load:
            load.return_value = root
            with self.assertLogs(level='ERROR') as log:
                p.parse('test0.hit')
            self.assertEqual(p.status(), 1)
            self.assertEqual(len(log.output), 2)
            self.assertIn("Duplicate section 'Tests/obj0'", log.output[0])
            self.assertIn("Duplicate parameter 'Tests/obj0/type'", log.output[1])