mirror of
https://pagure.io/fedora-qa/os-autoinst-distri-fedora.git
synced 2024-11-18 12:33:09 +00:00
kickstart-tests: handle non-US keyboard layouts
wow, this was a deep dive. A few of the kickstart-tests set the OS keymap to cz. Long story short, the way openQA does keyboard input is via VNC; VNC keyboard events are for keysyms, which are layout-dependent (so when we say `send_key "a"`, openQA sends qemu the keysym for 'a', regardless of layout issues). qemu turns the keysym into a keycode and sends *that* to the guest OS, which turns it back into a keysym according to its keymap config. qemu uses a US map by default to turn the keysym it receives via VNC into a keycode. So if you send qemu a '-', it sends the guest OS the keycode that would be converted to the keysym for '-' *in the US layout*. But if the guest OS has its layout set to cz, the same keycode is converted to '=', since that's what the key with that keycode is labelled as on a Czech keyboard. That's why if you set the guest OS keymap to cz and tell openQA to type '-', you get '='. However! You can tell qemu to use a different keymap for its keysym -> keycode conversion. If you keep the qemu keymap and the guest OS keymap lined up, when you say `send_key "-"`, you should actually *get* a "-". Which is what we want, for these tests. So we tell openQA to tell qemu to do that, using the VNCKB var, which is for precisely this: it tells os-autoinst to run qemu with `-k (layout)`.
This commit is contained in:
parent
dd247c7737
commit
d33f624c20
@ -47,11 +47,13 @@ def prep_kickstarts(indir, outdir):
|
||||
if not tests:
|
||||
raise ValueError("No tests found!")
|
||||
for test in tests:
|
||||
# read in the .ks.in file
|
||||
with open('{0}/{1}.ks.in'.format(indir, test), 'r') as ksinfh:
|
||||
kstext = ksinfh.read()
|
||||
ksout = "{0}.ks".format(test)
|
||||
for (orig, repl) in SUBSTS:
|
||||
kstext = kstext.replace(orig, repl)
|
||||
# write out the processed .ks
|
||||
ksout = "{0}.ks".format(test)
|
||||
with open('{0}/{1}'.format(outdir, ksout), 'w') as ksoutfh:
|
||||
ksoutfh.write(kstext)
|
||||
|
||||
@ -73,8 +75,8 @@ def merge_templates(indir, baseurl, tempfile, outfile):
|
||||
outfh.write(json.dumps(templates, sort_keys=True, indent=4,
|
||||
separators=(',', ': ')))
|
||||
|
||||
def _get_disk_settings(test):
|
||||
"""Given text of a kickstart_tests test (.sh file) as test, return
|
||||
def _get_settings_disk(sh):
|
||||
"""Given text of a kickstart_tests test (.sh file) as sh, return
|
||||
a list of appropriate openQA settings dicts for hard disks.
|
||||
"""
|
||||
# most prepare_disks just create empty disks of a given size in
|
||||
@ -85,11 +87,11 @@ def _get_disk_settings(test):
|
||||
# create multiple clean disk images with different sizes.
|
||||
settings = []
|
||||
simpre = re.compile(r'qemu-img create -q -f qcow2 \$\{(tmp|disk)dir\}/disk-.\.img \d+G')
|
||||
numdisks = len(simpre.findall(test))
|
||||
numdisks = len(simpre.findall(sh))
|
||||
|
||||
# the one tricky case that exists so far is the driverdisk case.
|
||||
# it gets created elsewhere. here we just point to it.
|
||||
if 'mkdud.py' in test:
|
||||
if 'mkdud.py' in sh:
|
||||
numdisks += 1
|
||||
settings.append({'key': 'HDD_{0}'.format(str(numdisks)), 'value': "driverdisk.img"})
|
||||
|
||||
@ -98,26 +100,65 @@ def _get_disk_settings(test):
|
||||
|
||||
return settings
|
||||
|
||||
def _get_settings_postinstall(sh):
|
||||
"""Given text of a kickstart_tests test (.sh file) as sh, return
|
||||
a list of appropriate openQA settings dict for post-install test
|
||||
settings (currently a single-item list, but we're future-proofing
|
||||
here).
|
||||
"""
|
||||
# just one test checks for RESULT in /home instead of /root
|
||||
if '/home/RESULT' in sh:
|
||||
return [{'key': 'POSTINSTALL', 'value': 'kstest_home'}]
|
||||
else:
|
||||
return [{'key': 'POSTINSTALL', 'value': 'kstest_root'}]
|
||||
|
||||
def _get_settings_keyboard(ksin):
|
||||
"""Given text of a kickstart_tests .ks.in file as ksin, return
|
||||
a list of appropriate openQA settings dict for keyboard test
|
||||
settings (currently a single-item list, but we're future-proofing
|
||||
here).
|
||||
"""
|
||||
# if the kickstart sets a keyboard layout, we set VNCKB to the
|
||||
# same layout. This tells openQA to run qemu with '-k (layout)',
|
||||
# which makes it use that layout for converting keysyms received
|
||||
# via VNC to keycodes which are passed on to the guest OS, which
|
||||
# converts them back into keysyms. Basically if we want to set a
|
||||
# non-US layout in the guest and have 'type_string qwerty' still
|
||||
# type 'qwerty' and not 'qwertz' or 'azert' or something, this is
|
||||
# how we do that.
|
||||
match = re.search(r'--vckeymap (\S+)', ksin)
|
||||
if match:
|
||||
return [{'key': 'VNCKB', 'value': match.group(1)}]
|
||||
else:
|
||||
return []
|
||||
|
||||
def create_testsuite(test, path, baseurl):
|
||||
"""Create an openQA 'test suite' for a given kickstart_test. test
|
||||
is the test name, path is the directory the test files are in.
|
||||
"""
|
||||
with open('{0}/{1}.sh'.format(path, test), 'r') as testfh:
|
||||
sh = testfh.read()
|
||||
with open('{0}/{1}.ks.in'.format(path, test), 'r') as ksfh:
|
||||
ks = ksfh.read()
|
||||
settings = _get_disk_settings(sh)
|
||||
settings.append({'key': 'KICKSTART', 'value': '1'})
|
||||
# just one test checks for RESULT in /home instead of /root
|
||||
if '/home/RESULT' in sh:
|
||||
settings.append({'key': 'POSTINSTALL', 'value': 'kstest_home'})
|
||||
else:
|
||||
settings.append({'key': 'POSTINSTALL', 'value': 'kstest_root'})
|
||||
# for some goddamn reason there are two different root passwords.
|
||||
rootpatt = re.compile(r'rootpw (.+)')
|
||||
settings.append({'key': 'ROOT_PASSWORD', 'value': rootpatt.search(ks).group(1)})
|
||||
# duh. these are all kickstart tests.
|
||||
settings = [{'key': 'KICKSTART', 'value': '1'}]
|
||||
|
||||
# get text of .sh and .ks.in files
|
||||
with open('{0}/{1}.sh'.format(path, test), 'r') as shfh:
|
||||
sh = shfh.read()
|
||||
with open('{0}/{1}.ks.in'.format(path, test), 'r') as ksinfh:
|
||||
ksin = ksinfh.read()
|
||||
|
||||
# call all the functions for getting different settings.
|
||||
settings.extend(_get_settings_disk(sh))
|
||||
settings.extend(_get_settings_postinstall(sh))
|
||||
settings.extend(_get_settings_keyboard(ksin))
|
||||
|
||||
# do some very simple ones ourselves (to avoid this function
|
||||
# growing too much, the rule is that if it needs more than one
|
||||
# line, split it out).
|
||||
|
||||
# root password. for now we assume there is one.
|
||||
settings.append({'key': 'ROOT_PASSWORD', 'value': re.search(r'rootpw (.+)', ksin).group(1)})
|
||||
# kickstart URL
|
||||
settings.append({'key': 'GRUB', 'value': "inst.ks={0}/{1}.ks".format(baseurl.strip('/'), test)})
|
||||
# we never want to do a user login for these.
|
||||
# we never want to do a user login for these
|
||||
settings.append({'key': 'USER_LOGIN', 'value': "false"})
|
||||
return {'name': "kstest_{0}".format(test), 'settings': settings}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user