Hi Eduardo,

what do you say?

                                  default
variants guest_os:            expand all variants
   - linux1:
   - linux2:

variants host_os:             take linux1
   - @linux1:
   - linux2:


First part as we talk before. 


Double default variant:

variants system:               It should be impossible at all? There is some 
case which uses it.
   - @ asaa                    Or there should be other marker? I think and 
hope that new marker
   - @ aaaa                    will not be necessary but with new maker it 
could be cleaner.


1)   Exchange '>' to '='

only host_os=linux2            should work
host_os=linux:                 should be condition not assigning value to 
variable

then there will be impossible do assigning:
   var1=sddd:                  not work nobody know if this is condition or 
something else.
   var2="sddd:"                should work

2)   Exchange '>' to ':'

only host_os:linux2            should work
host_os:linux1: var = 2        could work but not good visible
host_os:linux1:                but not work      in my opinion looks strange
     var1 = 2

3)   Exchange '>' to '::'       
                               little more performance expensive
only host_os::linux2           should work
host_os::linux1: var = 2       could work but
host_os::linux1:               work but
     var1 = 2

4)   Exchange '>' to '-'

only host_os-linux2           should work
host_os-linux1: var = 2       could work but not good visible
host_os-linux1:               
     var1 = 2

Which of this version do you prefer most or do you prefer some different 
version?


I like your idea with expand_variants. Which with "run" it is not necessary 
implement it to
cart config directly for now. But for autoserv tests it could be better.

>    # will expand only the "subtest" and "guest_os" variants-block, and
>    # automatically choose defaults for every other variants-block:
>    c = Parser(..., expand_variants=['subtest', 'guest_os'])
>    # For somebody who wants to run the default tests with all Windows
>    # versions:
>    c = Parser(..., expand_variants=['subtest', 'windows_version'])
>    # For somebody who wants to run the default tests with all CPU models,
>    # and all guest OSes:
>    c = Parser(..., expand_variants=['subtest', 'guest_os', 'cpu_model'])
>    # (additional nice-to-have: to allow something like "guest_os.*" to
>    # expand a variants-block and all its "sub-variants" (guest OS
>    # version, guest OS architecture, etc)


It is necessary to solve one case where there is unnamed variant with default.
Then it impossible to expand unnamed variant with expand_variants=[]. 
By this reason the selection of default variant shouldn't work in this
case even if variant name contain @.

example:
  variants:                        expand all variant again.
    - @first:
        var1= xxxxx
    - second

Thanks for review and your time:-)
Jiří

----- Original Message -----
> On Fri, Mar 29, 2013 at 06:14:09PM +0100, Jiří Župka wrote:
> > If default variant is not filtered by only or no filters then
> > only default variant is chosen. This behavior was used for optimizing
> > of speed of Cartesian config.
> > If variants don't have default variant then everything works as usual.
> > Default variant must be in variants with with_default exactly one times.
> > The default variant could be filtered by only, no filter. If default
> > variant is filtered from variants then variants works same as usual
> > variants with
> > default variant.
> > 
> > For calling Cartesian config from command line is used option
> > -d/--defaults:
> >    ../virttest/cartesian_config.py -d cfg/cc.cfg
> > 
> > For calling Cartesian config from python:
> >    c = Parser(args[0], defaults=options.defaults, debug=options.debug)
> 
> I believe we have allow that to be per-variants-block, not
> all-or-nothing.
> 
> For example: the default ./run behavior could be to automatically choose
> defaults for every variants-block (guest OS, block format, etc), except
> for the "subtests" variants-block.
> 
> I would like the API to look like this:
> 
>    # this would be the current behavior:
>    c = Parser(..., expand_all_variants=True)
>    # will expand only the "subtest" and "guest_os" variants-block, and
>    # automatically choose defaults for every other variants-block:
>    c = Parser(..., expand_variants=['subtest', 'guest_os'])
>    # For somebody who wants to run the default tests with all Windows
>    # versions:
>    c = Parser(..., expand_variants=['subtest', 'windows_version'])
>    # For somebody who wants to run the default tests with all CPU models,
>    # and all guest OSes:
>    c = Parser(..., expand_variants=['subtest', 'guest_os', 'cpu_model'])
>    # (additional nice-to-have: to allow something like "guest_os.*" to
>    # expand a variants-block and all its "sub-variants" (guest OS
>    # version, guest OS architecture, etc)
> 
> We could also find a way to encode the "expand_variants" instruction
> inside the config file syntax, so people could put that information in
> their config file. But that can be done later, after we test if the
> concept is really working in the Python API and command-line.
> 
> > 
> > *********  example:
> > variants name=tests:
> >   - wait:
> >        run = "wait"
> >        variants:
> >          - long:
> >             time = short_time
> >          - short: long
> >             time = logn_time
> >   - test2:
> >        run = "test1"
> > 
> > variants name=virt_system, with_default:
> >   - @linux:
> >   - windows:
> > 
> > variants name=host_os, with_default:
> >   - linux:
> >        image = linux
> >        variants with_default:
> >             - ubuntu:
> >             - @fedora:
> >   - windows:
> >        image = windows
> >        variants:
> >             - @XP:
> >             - WIN7:
> > 
> > only host_os>windows
> > 
> > In this case is chosen from host_os variants windows variant.
> > host_os>windows was choosen because default variant linux was filtered.
> > Next step is select one variant from guest_os. There will be chosen only
> > default variant linux because not filtered and virt_system variant is
> > with with_default. There is no default variant in tests variants because
> > that all of tests will be chosen.
> > 
> > ********  output:
> > dict    1:  host_os>windows.tests>wait.long
> >     dep = []
> >     host_os = windows
> >     image = windows
> >     name = host_os>windows.XP.virt_system>linux.tests>wait.long
> >     run = wait
> >     shortname = host_os>windows.tests>wait.long
> >     tests = wait
> >     time = short_time
> >     virt_system = linux
> > dict    2:  host_os>windows.tests>wait.short
> >     dep = ['host_os>windows.XP.virt_system>linux.tests>wait.long']
> >     host_os = windows
> >     image = windows
> >     name = host_os>windows.XP.virt_system>linux.tests>wait.short
> >     run = wait
> >     shortname = host_os>windows.tests>wait.short
> >     tests = wait
> >     time = logn_time
> >     virt_system = linux
> > dict    3:  host_os>windows.tests>test2
> >     dep = []
> >     host_os = windows
> >     image = windows
> >     name = host_os>windows.XP.virt_system>linux.tests>test2
> >     run = test1
> >     shortname = host_os>windows.tests>test2
> >     tests = test2
> >     virt_system = linux
> > dict    4:  host_os>windows.WIN7.tests>wait.long
> >     dep = []
> >     host_os = windows
> >     image = windows
> >     name = host_os>windows.WIN7.virt_system>linux.tests>wait.long
> >     run = wait
> >     shortname = host_os>windows.WIN7.tests>wait.long
> >     tests = wait
> >     time = short_time
> >     virt_system = linux
> > dict    5:  host_os>windows.WIN7.tests>wait.short
> >     dep = ['host_os>windows.WIN7.virt_system>linux.tests>wait.long']
> >     host_os = windows
> >     image = windows
> >     name = host_os>windows.WIN7.virt_system>linux.tests>wait.short
> >     run = wait
> >     shortname = host_os>windows.WIN7.tests>wait.short
> >     tests = wait
> >     time = logn_time
> >     virt_system = linux
> > dict    6:  host_os>windows.WIN7.tests>test2
> >     dep = []
> >     host_os = windows
> >     image = windows
> >     name = host_os>windows.WIN7.virt_system>linux.tests>test2
> >     run = test1
> >     shortname = host_os>windows.WIN7.tests>test2
> >     tests = test2
> >     virt_system = linux
> > 
> > Signed-off-by: Jiří Župka <[email protected]>
> > ---
> >  virttest/cartesian_config.py | 82
> >  ++++++++++++++++++++++++++++++++++++--------
> >  1 file changed, 68 insertions(+), 14 deletions(-)
> > 
> > diff --git a/virttest/cartesian_config.py b/virttest/cartesian_config.py
> > index 04ed2b5..6cd0e88 100755
> > --- a/virttest/cartesian_config.py
> > +++ b/virttest/cartesian_config.py
> > @@ -131,6 +131,10 @@ class ParserError:
> >              return "%s (%s:%s)" % (self.msg, self.filename, self.linenum)
> >  
> >  
> > +class MissingDefault:
> > +    pass
> > +
> > +
> >  class MissingIncludeError:
> >      def __init__(self, line, filename, linenum):
> >          self.line = line
> > @@ -225,6 +229,7 @@ class Node(object):
> >          self.labels = set()
> >          self.append_to_shortname = False
> >          self.failed_cases = collections.deque()
> > +        self.default = False
> >  
> >  
> >      def dump(self, indent, recurse=False):
> > @@ -407,14 +412,17 @@ class Parser(object):
> >  
> >      @see:
> >      
> > https://github.com/autotest/autotest/wiki/KVMAutotest-CartesianConfigParametersIntro
> >      """
> > -    def __init__(self, filename=None, debug=False):
> > +    def __init__(self, filename=None, defaults=False, debug=False):
> >          """
> >          Initialize the parser and optionally parse a file.
> >  
> >          @param filename: Path of the file to parse.
> > +        @param defaults: If True adds only defaults variant from variants
> > +                         if there is some.
> >          @param debug: Whether to turn on debugging output.
> >          """
> >          self.node = Node()
> > +        self.defaults = defaults
> >          self.debug = debug
> >          if filename:
> >              self.parse_file(filename)
> > @@ -611,10 +619,18 @@ class Parser(object):
> >  
> >          # Recurse into children
> >          count = 0
> > -        for n in node.children:
> > -            for d in self.get_dicts(n, ctx, new_content, shortname, dep):
> > -                count += 1
> > -                yield d
> > +        if self.defaults:
> > +            for n in node.children:
> > +                for d in self.get_dicts(n, ctx, new_content, shortname,
> > dep):
> > +                    count += 1
> > +                    yield d
> > +                if n.default and count:
> > +                    break
> > +        else:
> > +            for n in node.children:
> > +                for d in self.get_dicts(n, ctx, new_content, shortname,
> > dep):
> > +                    count += 1
> > +                    yield d
> >          # Reached leaf?
> >          if not node.children:
> >              self._debug("    reached leaf, returning it")
> > @@ -656,7 +672,8 @@ class Parser(object):
> >          print s % args
> >  
> >  
> > -    def _parse_variants(self, cr, node, prev_indent=-1, var_name=None):
> > +    def _parse_variants(self, cr, node, prev_indent=-1, var_name=None,
> > +                        with_default=False):
> >          """
> >          Read and parse lines from a FileReader object until a line with an
> >          indent level lower than or equal to prev_indent is encountered.
> > @@ -665,8 +682,10 @@ class Parser(object):
> >          @param node: A node to operate on.
> >          @param prev_indent: The indent level of the "parent" block.
> >          @param var_name: Variants name
> > +        @param with_default: Variants take only default variant.
> >          @return: A node object.
> >          """
> > +        already_default = False
> >          node4 = Node()
> >  
> >          while True:
> > @@ -694,7 +713,9 @@ class Parser(object):
> >              node2.labels = node.labels
> >  
> >              node3 = self._parse(cr, node2, prev_indent=indent)
> > -            node3.name = [Label(var_name, n) for n in
> > name.lstrip("@").split(".")]
> > +            is_default = name.startswith("@")
> > +            name = name.lstrip("@")
> > +            node3.name = [Label(var_name, n) for n in name.split(".")]
> >              node3.dep = [Label(var_name, d) for d in dep.replace(",", "
> >              ").split()]
> >  
> >              if var_name:
> > @@ -702,12 +723,33 @@ class Parser(object):
> >                  op_match = _ops_exp.search(l)
> >                  node3.content += [(cr.filename, linenum, Op(l, op_match))]
> >  
> > -            is_default = name.startswith("@")
> > -
> > -            node4.children += [node3]
> > +            node3.append_to_shortname = not is_default
> > +
> > +            if with_default and self.defaults:
> > +                """
> > +                Relevant only if defaults is True and
> > +                variants is with default.
> > +                """
> > +                if is_default:
> > +                    if not already_default:
> > +                        node3.default = True
> > +                        already_default = True
> > +                    else:
> > +                        raise MissingDefault
> > +                if node3.default:
> > +                    # Move default variant in front of rest of all
> > variants.
> > +                    # Speed optimization.
> > +                    node4.children.insert(0, node3)
> > +                else:
> > +                    node4.children += [node3]
> > +            else:
> > +                node4.children += [node3]
> >              node4.labels.update(node3.labels)
> >              node4.labels.update(node3.name)
> >  
> > +        if with_default and not already_default:
> > +            raise MissingDefault
> > +
> >          return node4
> >  
> >  
> > @@ -751,6 +793,7 @@ class Parser(object):
> >                                  char in "._-=,"):
> >                              raise ParserError("Illegal characters in
> >                              variants",
> >                                                line, cr.filename, linenum)
> > +                with_default = False
> >                  var_name = None
> >                  if name:
> >                      block = name.split(",")
> > @@ -761,12 +804,20 @@ class Parser(object):
> >                                  raise ParserError("Missing name of
> >                                  variants",
> >                                                    line, cr.filename,
> >                                                    linenum)
> >                              var_name = oper[1].strip()
> > +                        elif "with_default" in oper[0]:
> > +                            with_default = True
> >                          else:
> >                              raise ParserError("Ilegal variants param",
> >                                                 line, cr.filename, linenum)
> > -                node = self._parse_variants(cr, node, prev_indent=indent,
> > -                                            var_name=var_name)
> > -                                            var_name=name)
> > +                try:
> > +                    node = self._parse_variants(cr, node,
> > prev_indent=indent,
> > +                                                var_name=var_name,
> > +                                                with_default=with_default)
> > +                except MissingDefault:
> > +                    raise ParserError("There must be exactly one default "
> > +                                      "variant in variants with param "
> > +                                      "with_default.",
> > +                                      line, cr.filename, linenum)
> >                  continue
> >  
> >              # Parse 'include' statements
> > @@ -1040,12 +1091,15 @@ if __name__ == "__main__":
> >                        help="show dict contents")
> >      parser.add_option("-r", "--repr", dest="repr_mode",
> >      action="store_true",
> >                        help="Output parsing results Python format")
> > +    parser.add_option("-d", "--defaults", dest="defaults",
> > action="store_true",
> > +                      help="use only default variant of variants if there"
> > +                           " is some")
> >  
> >      options, args = parser.parse_args()
> >      if not args:
> >          parser.error("filename required")
> >  
> > -    c = Parser(args[0], debug=options.debug)
> > +    c = Parser(args[0], defaults=options.defaults, debug=options.debug)
> >      for s in args[1:]:
> >          c.parse_string(s)
> >  
> > --
> > 1.8.1.4
> > 
> 
> --
> Eduardo
> 

_______________________________________________
Virt-test-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/virt-test-devel

Reply via email to