Test Configuration

From KVM
Revision as of 12:12, 9 March 2009 by Drorr (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

The Weird Cartesian Product KVM Test Config File Format (TWCPKVMTCFF)

This is the format used by test configuration files in kvm_runtest_2. It was designed to meet several requirements:

  • Support for quick definition of multiple test scenarios (drive format, ACPI support, SMP configuration and other QEMU params) for all guests and tests
  • Support for exceptions applying to specific guests/tests/scenarios
  • Support for dependencies between tests
  • Unification of the various config files currently used into a single (hopefully simple) framework

General Description

  • The parser relies on indentation.
  • The parser produces a list of dictionaries (dicts). Each dictionary contains a set of key-value pairs.
  • Each dict contains at least three keys: 'name', 'shortname' and 'depend'. The values of 'name' and 'shortname' are strings, and the value of 'depend' is a list of strings.
  • A list of dictionaries will henceforth be referred to as a frame.
  • The initial frame contains a single dict, whose 'name' and 'shortname' are empty strings, and whose 'depend' is an empty list.
  • Parsing dict contents:
    • The dict parser operates on a frame, which will henceforth be referred to as the current frame.
    • A statement of the form '<key> = <value>' sets the value of <key> to <value> in all dicts of the current frame. If a dict lacks <key>, it will be created.
    • A statement of the form '<key> += <value>' appends <value> to the value of <key> in all dicts of the current frame. If a dict lacks <key>, it will be created.
    • A statement of the form '<key> <= <value>' pre-pends <value> to the value of <key> in all dicts of the current frame. If a dict lacks <key>, it will be created.
    • A statement of the form '<key> ?= <value>' sets the value of <key> to <value>, in all dicts of the current frame, but only if <key> exists in the dict. The operators ?+= and ?<= are also supported.
    • A statement of the form 'no <regex>' removes from the current frame all dicts whose 'name' field matches <regex>.
  • A statement of the form 'only <regex>' removes from the current frame all dicts whose 'name' field does not match <regex>.
  • Parsing 'variants':
    • A 'variants' block is opened by a 'variants:' statement. The contents of the block should follow the 'variants:' line and should be indented.
    • A line in a 'variants' block should be of the format '- <variant_name>:'. The contents of this variant should be specified following that line, and should be indented. The contents are parsed by the dict parser described above; they may be of the format '<key> <op> <value>'. They may also contain 'variants:' statements, or whatever the dict parser recognizes.
    • Each variant in a 'variants' block inherits a copy of the frame in which the 'variants:' statement appears. The 'current frame', which may be modified by the dict parser, becomes this copy.
    • The name of the variant (specified in the line '- <variant_name>:') is pre-pended to the 'name' field of each dict of the variant's frame, along with a separator dot ('.').
    • If the name of the variant is not preceeded by a '@' (i.e. '- @<variant_name>:'), it is pre-pended to the 'shortname' field of each dict of the variant's frame. In other words, if a variant's name is preceeded by a '@', it is omitted from the 'shortname' field.
    • The frames of the variants defined in the 'variants' block are joined into a single frame which replaces the frame in which the 'variants:' statement appears.

Example

A single dictionary

The following file:

key1 = value1
key2 = value2
key3 = value3

results in the following list of dictionaries (a single dictionary):

Dictionary #0:
   depend = []
   key1 = value1
   key2 = value2
   key3 = value3
   name = 
   shortname =


Adding a 'variants' block

The following file:

key1 = value1
key2 = value2
key3 = value3 
variants:
   - one:
   - two:
   - three:

results in the following list:


Dictionary #0:
   depend = []
   key1 = value1
   key2 = value2
   key3 = value3
   name = one
   shortname = one
Dictionary #1:
   depend = []
   key1 = value1
   key2 = value2
   key3 = value3
   name = two
   shortname = two
Dictionary #2:
   depend = []
   key1 = value1
   key2 = value2
   key3 = value3
   name = three
   shortname = three

Modifying dictionaries inside a variant

The following file:


key1 = value1
key2 = value2
key3 = value3
variants:
   - one:
       key1 = Hello World
       key2 <= some_prefix_
   - two:
       key2 <= another_prefix_
   - three:

results in the following list:


Dictionary #0:
   depend = []
   key1 = Hello World
   key2 = some_prefix_value2
   key3 = value3
   name = one
   shortname = one
Dictionary #1:
   depend = []
   key1 = value1
   key2 = another_prefix_value2
   key3 = value3
   name = two
   shortname = two
Dictionary #2:
   depend = []
   key1 = value1
   key2 = value2
   key3 = value3
   name = three
   shortname = three

Adding dependencies

The following file:


key1 = value1
key2 = value2
key3 = value3
variants:
   - one:
       key1 = Hello World
       key2 <= some_prefix_
   - two: one
       key2 <= another_prefix_
   - three: one two

results in the following list:

Dictionary #0:
   depend = []
   key1 = Hello World
   key2 = some_prefix_value2
   key3 = value3
   name = one
   shortname = one
Dictionary #1:
   depend = ['one']
   key1 = value1
   key2 = another_prefix_value2
   key3 = value3
   name = two
   shortname = two
Dictionary #2:
   depend = ['one', 'two']
   key1 = value1
   key2 = value2
   key3 = value3
   name = three
   shortname = three

Multiple 'variants' blocks

The following file:


key1 = value1
key2 = value2
key3 = value3
variants:
   - one:
       key1 = Hello World
       key2 <= some_prefix_
   - two: one
       key2 <= another_prefix_
   - three: one two
variants:
   - A:
   - B:

results in the following list:

Dictionary #0:
   depend = []
   key1 = Hello World
   key2 = some_prefix_value2
   key3 = value3
   name = A.one
   shortname = A.one
Dictionary #1:
   depend = ['A.one']
   key1 = value1
   key2 = another_prefix_value2
   key3 = value3
   name = A.two
   shortname = A.two
Dictionary #2:
   depend = ['A.one', 'A.two']
   key1 = value1
   key2 = value2
   key3 = value3
   name = A.three
   shortname = A.three
Dictionary #3:
   depend = []
   key1 = Hello World
   key2 = some_prefix_value2
   key3 = value3
   name = B.one
   shortname = B.one
Dictionary #4:
   depend = ['B.one']
   key1 = value1
   key2 = another_prefix_value2
   key3 = value3
   name = B.two
   shortname = B.two
Dictionary #5:
   depend = ['B.one', 'B.two']
   key1 = value1
   key2 = value2
   key3 = value3
   name = B.three
   shortname = B.three

Using 'no' and 'only'

The following file:

key1 = value1
key2 = value2
key3 = value3
variants:
   - one:
       key1 = Hello World
       key2 <= some_prefix_
   - two: one
       key2 <= another_prefix_
   - three: one two
variants:
   - A:
       no one
   - B:
       only one|three

results in the following list:

Dictionary #0:
   depend = ['A.one']
   key1 = value1
   key2 = another_prefix_value2
   key3 = value3
   name = A.two
   shortname = A.two
Dictionary #1:
   depend = ['A.one', 'A.two']
   key1 = value1
   key2 = value2
   key3 = value3
   name = A.three
   shortname = A.three
Dictionary #2:
   depend = []
   key1 = Hello World
   key2 = some_prefix_value2
   key3 = value3
   name = B.one
   shortname = B.one
Dictionary #3:
   depend = ['B.one', 'B.two']
   key1 = value1
   key2 = value2
   key3 = value3
   name = B.three
   shortname = B.three

Using '@'

The following file:

key1 = value1
key2 = value2
key3 = value3
variants:
   - one:
       key1 = Hello World
       key2 <= some_prefix_
   - two: one
       key2 <= another_prefix_
   - three: one two
variants:
   - @A:
       no one
   - B:
       only one|three

results in the following list (note the difference between the 'name' and 'shortname' fields):

Dictionary #0:
   depend = ['A.one']
   key1 = value1
   key2 = another_prefix_value2
   key3 = value3
   name = A.two
   shortname = two
Dictionary #1:
   depend = ['A.one', 'A.two']
   key1 = value1
   key2 = value2
   key3 = value3
   name = A.three
   shortname = three
Dictionary #2:
   depend = []
   key1 = Hello World
   key2 = some_prefix_value2
   key3 = value3
   name = B.one
   shortname = B.one
Dictionary #3:
   depend = ['B.one', 'B.two']
   key1 = value1
   key2 = value2
   key3 = value3
   name = B.three
   shortname = B.three