Test Configuration

From KVM
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

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