Test Configuration: Difference between revisions
From KVM
mNo edit summary |
mNo edit summary |
||
(One intermediate revision by the same user not shown) | |||
Line 21: | Line 21: | ||
** 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 '<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 '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': | * 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 'variants' block is opened by a 'variants:' statement. The contents of the block should follow the 'variants:' line and should be indented. | ||
Line 35: | Line 35: | ||
The following file: | The following file: | ||
key1 = value1 | |||
key1 = value1 | key2 = value2 | ||
key2 = value2 | key3 = value3 | ||
key3 = value3 | |||
results in the following list of dictionaries (a single dictionary): | results in the following list of dictionaries (a single dictionary): | ||
Dictionary #0: | |||
Dictionary #0: | |||
depend = [] | depend = [] | ||
key1 = value1 | key1 = value1 | ||
Line 52: | Line 49: | ||
name = | name = | ||
shortname = | shortname = | ||
=== Adding a 'variants' block === | === Adding a 'variants' block === | ||
Line 58: | Line 55: | ||
The following file: | The following file: | ||
key1 = value1 | |||
key1 = value1 | key2 = value2 | ||
key2 = value2 | key3 = value3 | ||
key3 = value3 | variants: | ||
variants: | |||
- one: | - one: | ||
- two: | - two: | ||
- three: | - three: | ||
results in the following list: | results in the following list: | ||
Dictionary #0: | Dictionary #0: | ||
depend = [] | depend = [] | ||
key1 = value1 | key1 = value1 | ||
Line 79: | Line 73: | ||
name = one | name = one | ||
shortname = one | shortname = one | ||
Dictionary #1: | Dictionary #1: | ||
depend = [] | depend = [] | ||
key1 = value1 | key1 = value1 | ||
Line 86: | Line 80: | ||
name = two | name = two | ||
shortname = two | shortname = two | ||
Dictionary #2: | Dictionary #2: | ||
depend = [] | depend = [] | ||
key1 = value1 | key1 = value1 | ||
Line 93: | Line 87: | ||
name = three | name = three | ||
shortname = three | shortname = three | ||
=== Modifying dictionaries inside a variant === | === Modifying dictionaries inside a variant === | ||
Line 99: | Line 92: | ||
The following file: | The following file: | ||
variants: | key1 = value1 | ||
key2 = value2 | |||
key3 = value3 | |||
variants: | |||
- one: | - one: | ||
key1 = Hello World | key1 = Hello World | ||
Line 111: | Line 103: | ||
key2 <= another_prefix_ | key2 <= another_prefix_ | ||
- three: | - three: | ||
results in the following list: | results in the following list: | ||
Dictionary #0: | Dictionary #0: | ||
depend = [] | depend = [] | ||
key1 = Hello World | key1 = Hello World | ||
Line 123: | Line 114: | ||
name = one | name = one | ||
shortname = one | shortname = one | ||
Dictionary #1: | Dictionary #1: | ||
depend = [] | depend = [] | ||
key1 = value1 | key1 = value1 | ||
Line 130: | Line 121: | ||
name = two | name = two | ||
shortname = two | shortname = two | ||
Dictionary #2: | Dictionary #2: | ||
depend = [] | depend = [] | ||
key1 = value1 | key1 = value1 | ||
Line 137: | Line 128: | ||
name = three | name = three | ||
shortname = three | shortname = three | ||
=== Adding dependencies === | === Adding dependencies === | ||
Line 143: | Line 133: | ||
The following file: | The following file: | ||
variants: | key1 = value1 | ||
key2 = value2 | |||
key3 = value3 | |||
variants: | |||
- one: | - one: | ||
key1 = Hello World | key1 = Hello World | ||
Line 155: | Line 144: | ||
key2 <= another_prefix_ | key2 <= another_prefix_ | ||
- three: one two | - three: one two | ||
results in the following list: | results in the following list: | ||
Dictionary #0: | |||
Dictionary #0: | |||
depend = [] | depend = [] | ||
key1 = Hello World | key1 = Hello World | ||
Line 167: | Line 154: | ||
name = one | name = one | ||
shortname = one | shortname = one | ||
Dictionary #1: | Dictionary #1: | ||
depend = ['one'] | depend = ['one'] | ||
key1 = value1 | key1 = value1 | ||
Line 174: | Line 161: | ||
name = two | name = two | ||
shortname = two | shortname = two | ||
Dictionary #2: | Dictionary #2: | ||
depend = ['one', 'two'] | depend = ['one', 'two'] | ||
key1 = value1 | key1 = value1 | ||
Line 181: | Line 168: | ||
name = three | name = three | ||
shortname = three | shortname = three | ||
=== Multiple 'variants' blocks === | === Multiple 'variants' blocks === | ||
Line 187: | Line 173: | ||
The following file: | The following file: | ||
variants: | key1 = value1 | ||
key2 = value2 | |||
key3 = value3 | |||
variants: | |||
- one: | - one: | ||
key1 = Hello World | key1 = Hello World | ||
Line 199: | Line 184: | ||
key2 <= another_prefix_ | key2 <= another_prefix_ | ||
- three: one two | - three: one two | ||
variants: | |||
variants: | |||
- A: | - A: | ||
- B: | - B: | ||
results in the following list: | results in the following list: | ||
Dictionary #0: | |||
Dictionary #0: | |||
depend = [] | depend = [] | ||
key1 = Hello World | key1 = Hello World | ||
Line 215: | Line 197: | ||
name = A.one | name = A.one | ||
shortname = A.one | shortname = A.one | ||
Dictionary #1: | Dictionary #1: | ||
depend = ['A.one'] | depend = ['A.one'] | ||
key1 = value1 | key1 = value1 | ||
Line 222: | Line 204: | ||
name = A.two | name = A.two | ||
shortname = A.two | shortname = A.two | ||
Dictionary #2: | Dictionary #2: | ||
depend = ['A.one', 'A.two'] | depend = ['A.one', 'A.two'] | ||
key1 = value1 | key1 = value1 | ||
Line 229: | Line 211: | ||
name = A.three | name = A.three | ||
shortname = A.three | shortname = A.three | ||
Dictionary #3: | Dictionary #3: | ||
depend = [] | depend = [] | ||
key1 = Hello World | key1 = Hello World | ||
Line 236: | Line 218: | ||
name = B.one | name = B.one | ||
shortname = B.one | shortname = B.one | ||
Dictionary #4: | Dictionary #4: | ||
depend = ['B.one'] | depend = ['B.one'] | ||
key1 = value1 | key1 = value1 | ||
Line 243: | Line 225: | ||
name = B.two | name = B.two | ||
shortname = B.two | shortname = B.two | ||
Dictionary #5: | Dictionary #5: | ||
depend = ['B.one', 'B.two'] | depend = ['B.one', 'B.two'] | ||
key1 = value1 | key1 = value1 | ||
Line 250: | Line 232: | ||
name = B.three | name = B.three | ||
shortname = B.three | shortname = B.three | ||
=== Using 'no' and 'only' === | === Using 'no' and 'only' === | ||
Line 256: | Line 237: | ||
The following file: | The following file: | ||
key1 = value1 | |||
key1 = value1 | key2 = value2 | ||
key2 = value2 | key3 = value3 | ||
key3 = value3 | variants: | ||
variants: | |||
- one: | - one: | ||
key1 = Hello World | key1 = Hello World | ||
Line 268: | Line 247: | ||
key2 <= another_prefix_ | key2 <= another_prefix_ | ||
- three: one two | - three: one two | ||
variants: | |||
variants: | |||
- A: | - A: | ||
no one | no one | ||
- B: | - B: | ||
only one|three | only one|three | ||
results in the following list: | results in the following list: | ||
Dictionary #0: | |||
Dictionary #0: | |||
depend = ['A.one'] | depend = ['A.one'] | ||
key1 = value1 | key1 = value1 | ||
Line 286: | Line 262: | ||
name = A.two | name = A.two | ||
shortname = A.two | shortname = A.two | ||
Dictionary #1: | Dictionary #1: | ||
depend = ['A.one', 'A.two'] | depend = ['A.one', 'A.two'] | ||
key1 = value1 | key1 = value1 | ||
Line 293: | Line 269: | ||
name = A.three | name = A.three | ||
shortname = A.three | shortname = A.three | ||
Dictionary #2: | Dictionary #2: | ||
depend = [] | depend = [] | ||
key1 = Hello World | key1 = Hello World | ||
Line 300: | Line 276: | ||
name = B.one | name = B.one | ||
shortname = B.one | shortname = B.one | ||
Dictionary #3: | Dictionary #3: | ||
depend = ['B.one', 'B.two'] | depend = ['B.one', 'B.two'] | ||
key1 = value1 | key1 = value1 | ||
Line 307: | Line 283: | ||
name = B.three | name = B.three | ||
shortname = B.three | shortname = B.three | ||
=== Using '@' === | === Using '@' === | ||
Line 313: | Line 288: | ||
The following file: | The following file: | ||
key1 = value1 | |||
key1 = value1 | key2 = value2 | ||
key2 = value2 | key3 = value3 | ||
key3 = value3 | variants: | ||
variants: | |||
- one: | - one: | ||
key1 = Hello World | key1 = Hello World | ||
Line 325: | Line 298: | ||
key2 <= another_prefix_ | key2 <= another_prefix_ | ||
- three: one two | - three: one two | ||
variants: | |||
variants: | |||
- @A: | - @A: | ||
no one | no one | ||
- B: | - B: | ||
only one|three | only one|three | ||
results in the following list (note the difference between the 'name' and 'shortname' fields): | results in the following list (note the difference between the 'name' and 'shortname' fields): | ||
Dictionary #0: | |||
Dictionary #0: | |||
depend = ['A.one'] | depend = ['A.one'] | ||
key1 = value1 | key1 = value1 | ||
Line 343: | Line 313: | ||
name = A.two | name = A.two | ||
shortname = two | shortname = two | ||
Dictionary #1: | Dictionary #1: | ||
depend = ['A.one', 'A.two'] | depend = ['A.one', 'A.two'] | ||
key1 = value1 | key1 = value1 | ||
Line 350: | Line 320: | ||
name = A.three | name = A.three | ||
shortname = three | shortname = three | ||
Dictionary #2: | Dictionary #2: | ||
depend = [] | depend = [] | ||
key1 = Hello World | key1 = Hello World | ||
Line 357: | Line 327: | ||
name = B.one | name = B.one | ||
shortname = B.one | shortname = B.one | ||
Dictionary #3: | Dictionary #3: | ||
depend = ['B.one', 'B.two'] | depend = ['B.one', 'B.two'] | ||
key1 = value1 | key1 = value1 | ||
Line 364: | Line 334: | ||
name = B.three | name = B.three | ||
shortname = B.three | shortname = B.three | ||
Latest revision as of 11:12, 9 March 2009
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