105 lines
5.1 KiB
Plaintext
105 lines
5.1 KiB
Plaintext
|
#!/bin/python3
|
||
|
|
||
|
"""
|
||
|
This script takes JSON-formatted openQA template data (in the older format with a JobTemplates
|
||
|
dict, not the newer YAML-ish format organized by job group) and converts to an intermediate format
|
||
|
(Fedora Intermediate Format - 'fif') intended to be easier for human editing. It extracts all the
|
||
|
unique 'environment profiles' - a combination of machine and product - from the JobTemplates and
|
||
|
stores them in a 'Profiles' dict; it then adds a 'profiles' key to each test suite, indicating
|
||
|
which profiles that suite is run on. It is fairly easy to reverse this process to reproduce the
|
||
|
openQA loader-compatible data, but the intermediate format is more friendly to a human editor.
|
||
|
Adding a new test suite to run on existing 'profiles' only requires adding the suite and an
|
||
|
appropriate 'profiles' dict. Adding a new profile involves adding the machine and/or product,
|
||
|
manually adding the profile to the Profiles dict, and then adding the profile to all the test
|
||
|
suites which should be run on it. See also fifloader.py, which handles converting FIF input to
|
||
|
upstream format, and optionally can pass it through to the upstream loader.
|
||
|
"""
|
||
|
|
||
|
import json
|
||
|
|
||
|
with open('templates.old.json', 'r') as tempfh:
|
||
|
tempdata = json.load(tempfh)
|
||
|
with open('templates-updates.old.json', 'r') as updfh:
|
||
|
updata = json.load(updfh)
|
||
|
|
||
|
def _synthesize_product_name(product):
|
||
|
"""Synthesize a product name from a product dict. We do this when
|
||
|
reading the templates file and also when constructing the profiles
|
||
|
so use a function to make sure they both do it the same way.
|
||
|
"""
|
||
|
return "-".join((product['distri'], product['flavor'], product['arch'], product['version']))
|
||
|
|
||
|
def read_templates(templates):
|
||
|
newtemps = {}
|
||
|
if 'Machines' in templates:
|
||
|
newtemps['Machines'] = {}
|
||
|
for machine in templates['Machines']:
|
||
|
# condense the stupid settings format
|
||
|
machine['settings'] = {settdict['key']: settdict['value'] for settdict in machine['settings']}
|
||
|
# just use a dict, not a list of dicts with 'name' keys...
|
||
|
name = machine.pop('name')
|
||
|
newtemps['Machines'][name] = machine
|
||
|
if 'Products' in templates:
|
||
|
newtemps['Products'] = {}
|
||
|
for product in templates['Products']:
|
||
|
# condense the stupid settings format
|
||
|
product['settings'] = {settdict['key']: settdict['value'] for settdict in product['settings']}
|
||
|
# synthesize a name, as we don't have any in our templates
|
||
|
# and we can use them in the scenarios. however, note that
|
||
|
# openQA itself doesn't let you use the product name as a
|
||
|
# key when loading templates, unlike the machine name, our
|
||
|
# loader has to reverse this and provide the full product
|
||
|
# dict to the upstream loader
|
||
|
name = _synthesize_product_name(product)
|
||
|
# this is always an empty string in our templates
|
||
|
del product['name']
|
||
|
newtemps['Products'][name] = product
|
||
|
if 'TestSuites' in templates:
|
||
|
newtemps['TestSuites'] = {}
|
||
|
for testsuite in templates['TestSuites']:
|
||
|
# condense the stupid settings format
|
||
|
testsuite['settings'] = {settdict['key']: settdict['value'] for settdict in testsuite['settings']}
|
||
|
# just use a dict, not a list of dicts with 'name' keys...
|
||
|
name = testsuite.pop('name')
|
||
|
newtemps['TestSuites'][name] = testsuite
|
||
|
profiles = {}
|
||
|
for jobtemp in templates['JobTemplates']:
|
||
|
# figure out the profile for each job template and add it to
|
||
|
# the dict. For Fedora, the group name is predictable based on
|
||
|
# the arch and whether it's an update test; the intermediate
|
||
|
# loader figures that out
|
||
|
profile = {
|
||
|
'machine': jobtemp['machine']['name'],
|
||
|
'product': _synthesize_product_name(jobtemp['product']),
|
||
|
}
|
||
|
profname = '-'.join([profile['product'], profile['machine']])
|
||
|
# keep track of all the profiles we've hit
|
||
|
profiles[profname] = profile
|
||
|
|
||
|
test = jobtemp['test_suite']['name']
|
||
|
prio = jobtemp['prio']
|
||
|
try:
|
||
|
suite = newtemps['TestSuites'][test]
|
||
|
except KeyError:
|
||
|
# this is a templates-updates JobTemplate which refers to a
|
||
|
# TestSuite defined in templates. What we do here is define
|
||
|
# a partial TestSuite which contains only the name and the
|
||
|
# profiles; the loader for this format knows how to combine
|
||
|
# dicts (including incomplete ones) from multiple source
|
||
|
# files into one big final-format lump
|
||
|
suite = {}
|
||
|
newtemps['TestSuites'][test] = suite
|
||
|
if 'profiles' in suite:
|
||
|
suite['profiles'][profname] = prio
|
||
|
else:
|
||
|
suite['profiles'] = {profname: prio}
|
||
|
|
||
|
newtemps['Profiles'] = profiles
|
||
|
return newtemps
|
||
|
|
||
|
with open('templates.fif.json', 'w') as newtempfh:
|
||
|
json.dump(read_templates(tempdata), newtempfh, sort_keys=True, indent=4)
|
||
|
|
||
|
with open('templates-updates.fif.json', 'w') as newtempfh:
|
||
|
json.dump(read_templates(updata), newtempfh, sort_keys=True, indent=4)
|