timid/steps.py
def parse_step(cls, ctxt, step_addr, step_conf):
        """
        Parse a step dictionary.

        :param ctxt: The context object.
        :param step_addr: The address of the step in the test
                          configuration.
        :param step_conf: The description of the step.  This may be a
                          scalar string or a dictionary.

        :returns: A list of steps.
        """

        # Make sure the step makes sense
        if isinstance(step_conf, six.string_types):
            # Convert string to a dict for uniformity of processing
            step_conf = {step_conf: None}
        elif not isinstance(step_conf, collections.Mapping):
            raise ConfigError(
                'Unable to parse step configuration: expecting string or '
                'dictionary, not "%s"' % step_conf.__class__.__name__,
                step_addr,
            )

        # Parse the configuration into the action and modifier classes
        # and the configuration to apply to each
        action_item = None
        mod_items = {}
        kwargs = {}  # extra args for Step.__init__()
        for key, key_conf in step_conf.items():
            # Handle special keys first
            if key in cls.schemas:
                # Validate the key
                utils.schema_validate(key_conf, cls.schemas[key], ConfigError,
                                      key, step_addr=step_addr)

                # Save the value
                kwargs[key] = key_conf

            # Is it an action?
            elif key in entry.points[NAMESPACE_ACTION]:
                if action_item is not None:
                    raise ConfigError(
                        'Bad step configuration: action "%s" specified, '
                        'but action "%s" already processed' %
                        (key, action_item.name),
                        step_addr,
                    )

                action_item = StepItem(
                    entry.points[NAMESPACE_ACTION][key], key, key_conf)

            # OK, is it a modifier?
            elif key in entry.points[NAMESPACE_MODIFIER]:
                mod_class = entry.points[NAMESPACE_MODIFIER][key]

                # Store it in priority order
                mod_items.setdefault(mod_class.priority, [])
                mod_items[mod_class.priority].append(StepItem(
                    mod_class, key, key_conf))

            # Couldn't resolve it
            else:
                raise ConfigError(
                    'Bad step configuration: unable to resolve action '
                    '"%s"' % key,
                    step_addr,
                )

        # Make sure we have an action
        if action_item is None:
            raise ConfigError(
                'Bad step configuration: no action specified',
                step_addr,
            )

        # What is the action type?
        action_type = (Modifier.STEP if action_item.cls.step_action
                       else Modifier.NORMAL)

        # OK, build our modifiers list and preprocess the action
        # configuration
        modifiers = []
        for mod_item in utils.iter_prio_dict(mod_items):
            # Verify that the modifier is compatible with the
            # action
            if mod_item.cls.restriction & action_type == 0:
                raise ConfigError(
                    'Bad step configuration: modifier "%s" is '
                    'incompatible with the action "%s"' %
                    (mod_item.name, action_item.name),
                    step_addr,
                )

            # Initialize the modifier
            modifier = mod_item.init(ctxt, step_addr)

            # Add it to the list of modifiers
            modifiers.append(modifier)

            # Apply the modifier's configuration processing
            action_item.conf = modifier.action_conf(
                ctxt, action_item.cls, action_item.name, action_item.conf,
                step_addr)

        # Now we can initialize the action
        action = action_item.init(ctxt, step_addr)

        # Create the step
        step = cls(step_addr, action, modifiers, **kwargs)

        # If the final_action is a StepAction, invoke it now and
        # return the list of steps.  We do this after creating the
        # Step object so that we can take advantage of its handling of
        # modifiers.
        if action_item.cls.step_action:
            return step(ctxt)

        # Not a step action, return the step as a list of one element
        return [step]
def parse_step(cls, ctxt, step_addr, step_conf):
        # Make sure the step makes sense
        if isinstance(step_conf, six.string_types):
            # Convert string to a dict for uniformity of processing
            step_conf = {step_conf: None}
        elif not isinstance(step_conf, collections.Mapping):
            raise ConfigError(
                'Unable to parse step configuration: expecting string or '
                'dictionary, not "%s"' % step_conf.__class__.__name__,
                step_addr,
            )

        # Parse the configuration into the action and modifier classes
        # and the configuration to apply to each
        action_item = None
        mod_items = {}
        kwargs = {}  # extra args for Step.__init__()
        for key, key_conf in step_conf.items():
            # Handle special keys first
            if key in cls.schemas:
                # Validate the key
                utils.schema_validate(key_conf, cls.schemas[key], ConfigError,
                                      key, step_addr=step_addr)

                # Save the value
                kwargs[key] = key_conf

            # Is it an action?
            elif key in entry.points[NAMESPACE_ACTION]:
                if action_item is not None:
                    raise ConfigError(
                        'Bad step configuration: action "%s" specified, '
                        'but action "%s" already processed' %
                        (key, action_item.name),
                        step_addr,
                    )

                action_item = StepItem(
                    entry.points[NAMESPACE_ACTION][key], key, key_conf)

            # OK, is it a modifier?
            elif key in entry.points[NAMESPACE_MODIFIER]:
                mod_class = entry.points[NAMESPACE_MODIFIER][key]

                # Store it in priority order
                mod_items.setdefault(mod_class.priority, [])
                mod_items[mod_class.priority].append(StepItem(
                    mod_class, key, key_conf))

            # Couldn't resolve it
            else:
                raise ConfigError(
                    'Bad step configuration: unable to resolve action '
                    '"%s"' % key,
                    step_addr,
                )

        # Make sure we have an action
        if action_item is None:
            raise ConfigError(
                'Bad step configuration: no action specified',
                step_addr,
            )

        # What is the action type?
        action_type = (Modifier.STEP if action_item.cls.step_action
                       else Modifier.NORMAL)

        # OK, build our modifiers list and preprocess the action
        # configuration
        modifiers = []
        for mod_item in utils.iter_prio_dict(mod_items):
            # Verify that the modifier is compatible with the
            # action
            if mod_item.cls.restriction & action_type == 0:
                raise ConfigError(
                    'Bad step configuration: modifier "%s" is '
                    'incompatible with the action "%s"' %
                    (mod_item.name, action_item.name),
                    step_addr,
                )

            # Initialize the modifier
            modifier = mod_item.init(ctxt, step_addr)

            # Add it to the list of modifiers
            modifiers.append(modifier)

            # Apply the modifier's configuration processing
            action_item.conf = modifier.action_conf(
                ctxt, action_item.cls, action_item.name, action_item.conf,
                step_addr)

        # Now we can initialize the action
        action = action_item.init(ctxt, step_addr)

        # Create the step
        step = cls(step_addr, action, modifiers, **kwargs)

        # If the final_action is a StepAction, invoke it now and
        # return the list of steps.  We do this after creating the
        # Step object so that we can take advantage of its handling of
        # modifiers.
        if action_item.cls.step_action:
            return step(ctxt)

        # Not a step action, return the step as a list of one element
        return [step]
def parse_step ( cls , ctxt , step_addr , step_conf ) : # Make sure the step makes sense if isinstance ( step_conf , six . string_types ) : # Convert string to a dict for uniformity of processing step_conf = { step_conf : None } elif not isinstance ( step_conf , collections . Mapping ) : raise ConfigError ( 'Unable to parse step configuration: expecting string or ' 'dictionary, not "%s"' % step_conf . __class__ . __name__ , step_addr , ) # Parse the configuration into the action and modifier classes # and the configuration to apply to each action_item = None mod_items = { } kwargs = { } # extra args for Step.__init__() for key , key_conf in step_conf . items ( ) : # Handle special keys first if key in cls . schemas : # Validate the key utils . schema_validate ( key_conf , cls . schemas [ key ] , ConfigError , key , step_addr = step_addr ) # Save the value kwargs [ key ] = key_conf # Is it an action? elif key in entry . points [ NAMESPACE_ACTION ] : if action_item is not None : raise ConfigError ( 'Bad step configuration: action "%s" specified, ' 'but action "%s" already processed' % ( key , action_item . name ) , step_addr , ) action_item = StepItem ( entry . points [ NAMESPACE_ACTION ] [ key ] , key , key_conf ) # OK, is it a modifier? elif key in entry . points [ NAMESPACE_MODIFIER ] : mod_class = entry . points [ NAMESPACE_MODIFIER ] [ key ] # Store it in priority order mod_items . setdefault ( mod_class . priority , [ ] ) mod_items [ mod_class . priority ] . append ( StepItem ( mod_class , key , key_conf ) ) # Couldn't resolve it else : raise ConfigError ( 'Bad step configuration: unable to resolve action ' '"%s"' % key , step_addr , ) # Make sure we have an action if action_item is None : raise ConfigError ( 'Bad step configuration: no action specified' , step_addr , ) # What is the action type? action_type = ( Modifier . STEP if action_item . cls . step_action else Modifier . NORMAL ) # OK, build our modifiers list and preprocess the action # configuration modifiers = [ ] for mod_item in utils . iter_prio_dict ( mod_items ) : # Verify that the modifier is compatible with the # action if mod_item . cls . restriction & action_type == 0 : raise ConfigError ( 'Bad step configuration: modifier "%s" is ' 'incompatible with the action "%s"' % ( mod_item . name , action_item . name ) , step_addr , ) # Initialize the modifier modifier = mod_item . init ( ctxt , step_addr ) # Add it to the list of modifiers modifiers . append ( modifier ) # Apply the modifier's configuration processing action_item . conf = modifier . action_conf ( ctxt , action_item . cls , action_item . name , action_item . conf , step_addr ) # Now we can initialize the action action = action_item . init ( ctxt , step_addr ) # Create the step step = cls ( step_addr , action , modifiers , * * kwargs ) # If the final_action is a StepAction, invoke it now and # return the list of steps.  We do this after creating the # Step object so that we can take advantage of its handling of # modifiers. if action_item . cls . step_action : return step ( ctxt ) # Not a step action, return the step as a list of one element return [ step ]
Parse a step dictionary.

        :param ctxt: The context object.
        :param step_addr: The address of the step in the test
                          configuration.
        :param step_conf: The description of the step.  This may be a
                          scalar string or a dictionary.

        :returns: A list of steps.
Parse a step dictionary .