예제 #1
0
 def test_serialization(self):
     """Test serialization of workflow templates."""
     template = TemplateHandle(
         identifier='ABC',
         base_dir='XYZ',
         workflow_spec=dict(),
         parameters=[
             TemplateParameter(pd.parameter_declaration('A')),
             TemplateParameter(
                 pd.parameter_declaration('B', data_type=pd.DT_LIST)),
             TemplateParameter(pd.parameter_declaration('C', parent='B'))
         ])
     doc = DefaultTemplateLoader().to_dict(template)
     parameters = DefaultTemplateLoader().from_dict(doc).parameters
     assert len(parameters) == 3
     assert 'A' in parameters
     assert 'B' in parameters
     assert len(parameters['B'].children) == 1
     template = DefaultTemplateLoader().from_dict(doc)
     assert template.identifier == 'ABC'
     # The base directory is not materialized
     assert template.base_dir is None
     # Invalid resource descriptor serializations
     with pytest.raises(err.InvalidTemplateError):
         ResourceDescriptor.from_dict(dict())
     with pytest.raises(err.InvalidTemplateError):
         ResourceDescriptor.from_dict({LABEL_ID: 'A', 'noname': 'B'})
예제 #2
0
 def test_validate(self):
     """Test error cases for argument validation."""
     para_list = TemplateParameter(
         pd.parameter_declaration('E', data_type=pd.DT_LIST))
     with pytest.raises(ValueError):
         values.TemplateArgument(parameter=para_list, value=1)
     para_record = TemplateParameter(
         pd.parameter_declaration('E', data_type=pd.DT_RECORD))
     with pytest.raises(ValueError):
         values.TemplateArgument(parameter=para_record, value=list())
     arg = values.TemplateArgument(parameter=TemplateParameter(
         pd.parameter_declaration('E', data_type=pd.DT_INTEGER)),
                                   value=1,
                                   validate=True)
     arg.data_type = 'unknown'
     with pytest.raises(ValueError):
         arg.validate()
예제 #3
0
 def test_init(self):
     """Test initialization of attribuets and error cases when creating
     template instances.
     """
     th = TemplateHandle(
         workflow_spec=dict(),
         parameters=[
             TemplateParameter(pd.parameter_declaration('A')),
             TemplateParameter(pd.parameter_declaration('B'))
         ])
     assert not th.identifier is None
     assert th.base_dir is None
     th = TemplateHandle(
         identifier='ABC',
         base_dir='XYZ',
         workflow_spec=dict(),
         parameters=[
             TemplateParameter(pd.parameter_declaration('A')),
             TemplateParameter(pd.parameter_declaration('B'))
         ])
     assert th.identifier == 'ABC'
     assert th.base_dir == 'XYZ'
     with pytest.raises(err.InvalidTemplateError):
         TemplateHandle(
             workflow_spec=dict(),
             parameters=[
                 TemplateParameter(pd.parameter_declaration('A')),
                 TemplateParameter(pd.parameter_declaration('B')),
                 TemplateParameter(pd.parameter_declaration('A'))
             ])
예제 #4
0
 def test_read_with_record(self):
     """Read argument for a template that contains a parameter of data type
     DT_RECORD.
     """
     template = TemplateHandle(
         workflow_spec=dict(),
         parameters=[
             TemplateParameter(
                 pd.parameter_declaration(identifier='codeFile',
                                          data_type=pd.DT_FILE,
                                          index=0,
                                          default_value=None,
                                          as_const=AS_INPUT)),
             TemplateParameter(
                 pd.parameter_declaration(identifier='dataFile',
                                          data_type=pd.DT_FILE,
                                          index=1,
                                          default_value='data/names.txt')),
             TemplateParameter(
                 pd.parameter_declaration(identifier='resultFile',
                                          data_type=pd.DT_FILE,
                                          index=2,
                                          default_value=None)),
             TemplateParameter(
                 pd.parameter_declaration(identifier='sleeptime',
                                          data_type=pd.DT_INTEGER,
                                          index=3,
                                          default_value=10)),
             TemplateParameter(
                 pd.parameter_declaration(identifier='verbose',
                                          data_type=pd.DT_BOOL,
                                          index=4,
                                          default_value=False)),
             TemplateParameter(
                 pd.parameter_declaration(identifier='frac',
                                          data_type=pd.DT_DECIMAL,
                                          index=6)),
             TemplateParameter(
                 pd.parameter_declaration(identifier='outputType',
                                          index=5)),
         ])
     sc = Scanner(reader=ListReader([
         'ABC.txt', 'code/abc.py', '', 'result/output.txt', 3, True, 'XYZ',
         0.123
     ]))
     arguments = tmpl.read(template.list_parameters(), scanner=sc)
     assert arguments['codeFile'].name == 'ABC.txt'
     assert arguments['codeFile'].target_path == 'code/abc.py'
     assert arguments['dataFile'].name == 'names.txt'
     assert arguments['dataFile'].target_path is None
     assert arguments['resultFile'].name == 'output.txt'
     assert arguments['resultFile'].target_path is None
     assert arguments['sleeptime'] == 3
     assert arguments['verbose']
     assert arguments['outputType'] == 'XYZ'
     assert arguments['frac'] == 0.123
예제 #5
0
def create_parameter_index(parameters, validate=True):
    """Create instances of template parameters from a list of dictionaries
    containing parameter declarations. The result is a dictionary containing the
    top-level parameters, indexed by their unique identifier.

    Parameters
    ----------
    parameters: list(dict)
        List of dictionaries containing template parameter declarations
    validate: bool, optional
        Flag indicating if given template parameter declarations are to be
        validated against the parameter schema or not.

    Returns
    -------
    dict(benchtmpl.workflow.parameter.base.TemplateParameter)

    Raises
    ------
    benchtmpl.error.InvalidTemplateError
    benchtmpl.error.UnknownParameterError
    """
    result = dict()
    for para in parameters:
        # Validate the template parameters if the validate flag is True
        if validate:
            pd.validate_parameter(para)
        # Create a TemplateParameter instance for the parameter. Keep
        # track of children for parameter that are of type DT_LIST or
        # DT_RECORD. Children are added after all parameters have been
        # instantiated.
        p_id = para[pd.LABEL_ID]
        # Ensure that the identifier of all parameters are unique
        if p_id in result:
            raise err.InvalidTemplateError('parameter \'{}\' not unique'.format(p_id))
        c = None
        if para[pd.LABEL_DATATYPE] in [pd.DT_LIST, pd.DT_RECORD]:
            c = list()
        tp = TemplateParameter(pd.set_defaults(para), children=c)
        result[p_id] = tp
    # Add parameter templates to the list of children for their
    # respective parent (if given). We currently only support one level
    # of nesting.
    for para in parameters:
        if pd.LABEL_PARENT in para:
            p_id = para[pd.LABEL_ID]
            parent = para[pd.LABEL_PARENT]
            if not parent is None:
                result[parent].add_child(result[p_id])
    return result
예제 #6
0
 def test_propmpt(self):
     """Test generated prompts when reading parameter values from standard
     input.
     """
     # BOOL
     p = TemplateParameter(
         pd.set_defaults(
             pd.parameter_declaration(identifier='ABC',
                                      data_type=pd.DT_BOOL))).prompt()
     assert p == 'ABC (bool): '
     # FILE
     p = TemplateParameter(
         pd.set_defaults(
             pd.parameter_declaration(identifier='ABC',
                                      data_type=pd.DT_FILE))).prompt()
     assert p == 'ABC (file): '
     # FLOAT
     p = TemplateParameter(
         pd.set_defaults(
             pd.parameter_declaration(identifier='ABC',
                                      data_type=pd.DT_DECIMAL))).prompt()
     assert p == 'ABC (decimal): '
     # INTEGER
     p = TemplateParameter(
         pd.set_defaults(
             pd.parameter_declaration(identifier='ABC',
                                      data_type=pd.DT_INTEGER))).prompt()
     assert p == 'ABC (integer): '
     # STRING
     p = TemplateParameter(
         pd.set_defaults(
             pd.parameter_declaration(identifier='ABC',
                                      data_type=pd.DT_STRING))).prompt()
     assert p == 'ABC (string): '
     # Default values in prompts
     p = TemplateParameter(
         pd.set_defaults(
             pd.parameter_declaration(identifier='ABC',
                                      data_type=pd.DT_INTEGER,
                                      default_value=100))).prompt()
     assert p == 'ABC (integer) [default 100]: '
     p = TemplateParameter(
         pd.set_defaults(
             pd.parameter_declaration(identifier='ABC',
                                      data_type=pd.DT_STRING,
                                      default_value=100))).prompt()
     assert p == 'ABC (string) [default \'100\']: '
예제 #7
0
 def test_flat_parse(self):
     """Test parsing arguments for a flat (un-nested) parameter declaration.
     """
     template = TemplateHandle(
         workflow_spec=dict(),
         parameters=[
             TemplateParameter(
                 pd.parameter_declaration('A', data_type=pd.DT_INTEGER)),
             TemplateParameter(
                 pd.parameter_declaration('B', data_type=pd.DT_BOOL)),
             TemplateParameter(
                 pd.parameter_declaration('C', data_type=pd.DT_DECIMAL)),
             TemplateParameter(
                 pd.parameter_declaration('D',
                                          data_type=pd.DT_FILE,
                                          required=False)),
             TemplateParameter(
                 pd.parameter_declaration('E',
                                          data_type=pd.DT_STRING,
                                          required=False))
         ])
     params = template.parameters
     fh = InputFile(f_handle=FileHandle(filepath=LOCAL_FILE))
     # Valid argument set
     args = values.parse_arguments(arguments={
         'A': 10,
         'B': True,
         'C': 12.5,
         'D': fh,
         'E': 'ABC'
     },
                                   parameters=params,
                                   validate=True)
     assert len(args) == 5
     for key in params.keys():
         assert key in args
     values.parse_arguments(arguments=args,
                            parameters=params,
                            validate=False)
     # Error cases
     with pytest.raises(ValueError):
         values.parse_arguments(arguments={
             'A': 10,
             'Z': 0
         },
                                parameters=params)
     with pytest.raises(ValueError):
         values.parse_arguments(arguments={
             'A': 10,
             'B': True
         },
                                parameters=params)
     # Validate data type
     with pytest.raises(ValueError):
         values.parse_arguments(arguments={
             'A': '10',
             'B': True,
             'C': 12.3,
             'D': fh,
             'E': 'ABC'
         },
                                parameters=params,
                                validate=True)
     with pytest.raises(ValueError):
         values.parse_arguments(arguments={
             'A': 10,
             'B': 23,
             'C': 12.3,
             'D': fh,
             'E': 'ABC'
         },
                                parameters=params,
                                validate=True)
     with pytest.raises(ValueError):
         values.parse_arguments(arguments={
             'A': 10,
             'B': True,
             'C': '12.3',
             'D': fh,
             'E': 'ABC'
         },
                                parameters=params,
                                validate=True)
     with pytest.raises(ValueError):
         values.parse_arguments(arguments={
             'A': 10,
             'B': True,
             'C': 12.3,
             'D': 'fh',
             'E': 'ABC'
         },
                                parameters=params,
                                validate=True)
     with pytest.raises(ValueError):
         values.parse_arguments(arguments={
             'A': 10,
             'B': True,
             'C': 12.3,
             'D': fh,
             'E': 12
         },
                                parameters=params,
                                validate=True)
 def test_parameter_declaration(self):
     """Test methods of the parameter declaration object."""
     obj = pd.set_defaults(pd.parameter_declaration(identifier='ABC'))
     obj[pd.LABEL_AS] = 'XYZ'
     p = TemplateParameter(obj)
     # Type flags
     assert not p.is_bool()
     assert not p.is_file()
     assert not p.is_float()
     assert not p.is_int()
     assert not p.is_list()
     assert not p.is_record()
     assert p.is_string()
     # Constant values
     assert p.has_constant()
     assert p.get_constant() == 'XYZ'
     # Error for invalid data type
     with pytest.raises(err.InvalidParameterError):
         TemplateParameter({pd.LABEL_ID: 'A', pd.LABEL_DATATYPE: 'XYZ'})