Add a partial kickstart install test (#308)
All checks were successful
CI via Tox and perl / tox (pull_request) Successful in 1m26s
CI via Tox and perl / perl (pull_request) Successful in 3m34s
CI via Tox and perl / checkwiki (pull_request) Successful in 33s

We also split out the _do_root_and_user stuff from
_do_install_and_reboot into a separate test module. This makes
the logic for the partial kickstart install easier, but it's also
just the right thing to do anyway; those things used to be part
of _do_install_and_reboot because you did them while the install
was actually running, but we stopped that since Fedora 31, so it
didn't make any sense for them to be in that module any more.

We also tweak _software_selection a little bit - we move the
'oh dear, can't deal with these, bail out' clause from that test
into main.pm, because there's no point going into the test module
then immediately bailing out, it's clearer this way. We can also
skip it for PARTIAL_KICKSTART at the same time. This also means
we don't have to bother setting PACKAGE_SET to "default" on LIVE
and CANNED flavors, as that was only done to force us down the
bail-out path in _software_selection.

Signed-off-by: Adam Williamson <awilliam@redhat.com>
This commit is contained in:
Adam Williamson 2026-04-20 14:51:05 -07:00
commit 9d0a1092e6
9 changed files with 135 additions and 115 deletions

View file

@ -61,6 +61,7 @@ it also means that `B` conflicts `A` even if not shown in the table).
| `ENTRYPOINT` | filename | not set | N/A | set `ENTRYPOINT` to load specific test directly (bypass modular structure, mainly usable for testing). If you want to run more than one test, separate them with space. |
| `UPGRADE` | string (`minimal`, `desktop`, `encrypted`, ...) | not set | all except of `LIVE` and `USER_PASSWORD` | when set, do an upgrade test of specified type |
| `KICKSTART` | boolean | `false`/not set | all | when specified, do an kickstart installation (you should use `GRUB` variable to specify where kickstart file resides) |
| `PARTIAL_KICKSTART` | boolean | `false`/not set | all | when specified, do a partial kickstart installation - the kickstart is expected to omit package set configuration (you should use `GRUB` variable to specify where kickstart file resides) |
| `MIRRORLIST_GRAPHICAL` | boolean | `false`/not set | `REPOSITORY_GRAPHICAL` | sets installation source to mirrorlist |
| `REPOSITORY_GRAPHICAL` | url to repository (without arch and `/os`, for example `http://dl.fedoraproject.org/pub/fedora/linux/development`) | not set | `MIRRORLIST_GRAPHICAL` | sets installation source to repository url in Anaconda |
| `REPOSITORY_VARIATION` | url to repository (without arch and `/os`, for example `http://dl.fedoraproject.org/pub/fedora/linux/development`) | not set | nothing | sets installation source to repository url in GRUB |

View file

@ -281,7 +281,7 @@ sub console_login {
# otherwise, type the password
type_string "$args{password}";
if (get_var("SWITCHED_LAYOUT") and $args{user} ne "root") {
# see _do_install_and_reboot; when layout is switched
# see _do_root_and_user; when layout is switched
# user password is doubled to contain both US and native
# chars
console_switch_layout;
@ -2002,7 +2002,7 @@ sub dm_perform_login {
# away
wait_still_screen(stilltime => 5, similarity_level => 38);
if (get_var("SWITCHED_LAYOUT")) {
# see _do_install_and_reboot; when layout is switched
# see _do_root_and_user; when layout is switched
# user password is doubled to contain both US and native
# chars
desktop_switch_layout 'ascii';

13
main.pm
View file

@ -179,8 +179,10 @@ sub load_install_tests() {
autotest::loadtest "tests/_check_install_source.pm";
}
## Select package set. Minimal is the default, if 'default' is specified, skip selection.
autotest::loadtest "tests/_software_selection.pm";
unless (get_var('CANNED') || get_var('LIVE') || get_var('PARTIAL_KICKSTART')) {
## Select package set. Minimal is the default, if 'default' is specified, skip selection.
autotest::loadtest "tests/_software_selection.pm";
}
## Disk partitioning.
# If PARTITIONING is set, we pick the storage test
@ -202,9 +204,10 @@ sub load_install_tests() {
autotest::loadtest "tests/disk_guided_encrypted.pm";
}
# Start installation, set user & root passwords, reboot
# install and reboot phase is loaded automatically every time (except when KICKSTART is set)
autotest::loadtest "tests/_do_install_and_reboot.pm";
# Set user & root passwords, start installation, reboot
# these are loaded automatically every time (except when (PARTIAL_)KICKSTART is set)
autotest::loadtest 'tests/_do_root_and_user.pm' unless (get_var('PARTIAL_KICKSTART'));
autotest::loadtest 'tests/_do_install_and_reboot.pm';
}
sub _load_instance {

View file

@ -132,7 +132,6 @@
"CANNED": "1",
"DEPLOY_UPLOAD_TEST": "install_default_upload",
"INSTALL_RETRY": "",
"PACKAGE_SET": "default",
"TEST_TARGET": "ISO"
}
},
@ -144,7 +143,6 @@
"HDDSIZEGB": "15",
"INSTALL_RETRY": "1",
"LIVE": "1",
"PACKAGE_SET": "default",
"TEST_TARGET": "ISO"
}
},
@ -162,7 +160,6 @@
"DEPLOY_UPLOAD_TEST": "install_default_upload",
"INSTALL_RETRY": "1",
"LIVE": "1",
"PACKAGE_SET": "default",
"TEST_TARGET": "ISO",
"USER_LOGIN": "i3-user"
}
@ -199,7 +196,6 @@
"DESKTOP": "gnome",
"HDDSIZEGB": "20",
"INSTALL_RETRY": "",
"PACKAGE_SET": "default",
"RETRY": "2",
"TEST_TARGET": "ISO"
}
@ -212,7 +208,6 @@
"HDDSIZEGB": "20",
"INSTALL_RETRY": "1",
"LIVE": "1",
"PACKAGE_SET": "default",
"TEST_TARGET": "ISO"
}
},
@ -245,7 +240,6 @@
"DUG_RETRY": "3",
"HDDSIZEGB": "15",
"LIVE": "1",
"PACKAGE_SET": "default",
"+QEMURAM": "6144",
"TEST_TARGET": "ISO"
}
@ -258,7 +252,6 @@
"HDDSIZEGB": "20",
"INSTALL_RETRY": "1",
"LIVE": "1",
"PACKAGE_SET": "default",
"+QEMURAM": "6144",
"TEST_TARGET": "ISO"
}
@ -1839,6 +1832,17 @@
"WORKER_CLASS": "tap"
}
},
"install_kickstart_partial": {
"profile_groups": {
"server-dvd-3arch": 20
},
"settings": {
"GRUB": "inst.ks=https://fedorapeople.org/groups/qa/kickstarts/example-partial.ks",
"PARTIAL_KICKSTART": "1",
"ROOT_PASSWORD": "fedora",
"USER_LOGIN": "false"
}
},
"install_kickstart_user_creation": {
"profile_groups": {
"server-dvd-3arch": 20

View file

@ -193,13 +193,19 @@ sub run {
}
}
# wait for anaconda to appear
unless (check_screen ["anaconda_select_install_lang", "anaconda_webui_wrong_font"], 300) {
unless (check_screen ["anaconda_select_install_lang", "anaconda_webui_wrong_font", "anaconda_main_hub"], 300) {
# may be hitting https://bugzilla.redhat.com/show_bug.cgi?id=2325780,
# try pressing a key
send_key "spc";
assert_screen ["anaconda_select_install_lang", "anaconda_webui_wrong_font"], 300;
assert_screen ["anaconda_select_install_lang", "anaconda_webui_wrong_font", "anaconda_main_hub"], 300;
record_soft_failure "boot hung until key pressed - #2325780";
}
if (match_has_tag 'anaconda_main_hub') {
# this is fine - we should skip right to hub
return if get_var('PARTIAL_KICKSTART');
# this is not fine!
die 'Language and layout selection unexpectedly skipped!';
}
if (match_has_tag 'anaconda_webui_wrong_font') {
# https://bugzilla.redhat.com/show_bug.cgi?id=2402533
# see if a refresh gives us the right font

View file

@ -4,107 +4,11 @@ use testapi;
use anaconda;
use utils;
sub _set_root_password {
# can also hit a transition animation
wait_still_screen 2;
my $root_password = get_var("ROOT_PASSWORD", "weakpassword");
assert_and_click "anaconda_install_root_password";
# we have to click 'enable root account' before typing the
#password
assert_and_click "anaconda_install_root_password_screen";
# wait out animation
wait_still_screen 2;
desktop_switch_layout("ascii", "anaconda") if (get_var("SWITCHED_LAYOUT"));
# these screens seems insanely subject to typing errors, so
# type super safely. This doesn't really slow the test down
# as we still get done before the install process is complete.
type_very_safely $root_password;
wait_screen_change { send_key "tab"; };
type_very_safely $root_password;
# Another screen to test identification on
my $identification = get_var('IDENTIFICATION');
if ($identification eq 'true') {
check_top_bar();
# we don't check version or pre-release because here those
# texts appear on the banner which makes the needling
# complex and fragile (banner is different between variants,
# and has a gradient so for RTL languages the background color
# differs; pre-release text is also translated)
}
assert_and_click "anaconda_spoke_done";
# exiting this screen can take a while, so check for the hub
assert_screen "anaconda_main_hub", 60;
}
sub _set_root_password_webui {
my $root_password = get_var("ROOT_PASSWORD", "weakpassword");
# hit tab till we can see the button, it may be off screen
send_key_until_needlematch("anaconda_webui_allow_root", "tab", 3, 3);
# Click the radio button, then get focus and fill the fields.
assert_and_click("anaconda_webui_allow_root");
sleep(1);
type_very_safely($root_password);
for (1 .. 2) {
send_key("tab");
sleep(1);
}
type_very_safely($root_password);
}
sub _do_root_and_user {
# check whether user and root password creation are suppressed,
# as they may be. if the 'begin installation' button is present
# and active, they must be suppressed. we use assert_screen not
# check_screen just to make it faster
assert_screen [
'anaconda_install_user_creation',
'anaconda_webui_no_local_account',
'anaconda_webui_begin_installation',
'anaconda_main_hub_begin_installation'
];
if (match_has_tag('anaconda_webui_begin_installation') || match_has_tag('anaconda_main_hub_begin_installation')) {
set_var('INSTALLER_NO_ROOT', '1');
set_var('INSTALL_NO_USER', '1');
}
my $nouser = (get_var("USER_LOGIN", '') eq 'false' || get_var("INSTALL_NO_USER"));
my $noroot = get_var("INSTALLER_NO_ROOT");
return if ($nouser && $noroot);
if (get_var("_ANACONDA_WEBUI")) {
if ($nouser) {
assert_and_click 'anaconda_webui_no_local_account';
}
else {
webui_create_user();
}
_set_root_password_webui() unless ($noroot);
assert_and_click("anaconda_webui_next");
}
else {
_set_root_password() unless ($noroot);
# Set user details, unless the test is configured not to create one
unless ($nouser) {
# Wait out animation
wait_still_screen 8;
anaconda_create_user();
}
}
# Check username (and hence keyboard layout) if non-English
if (get_var('LANGUAGE')) {
assert_screen "anaconda_install_user_created";
}
}
sub run {
my $self = shift;
my $webui = get_var("_ANACONDA_WEBUI");
my $desktop = get_var("DESKTOP");
# From F31 onwards (after Fedora-Rawhide-20190722.n.1), user and
# root password spokes are moved to main hub, so we must do those
# before we run the install.
_do_root_and_user();
# Begin installation
# Sometimes, the 'slide in from the top' animation messes with
# this - by the time we click the button isn't where it was any

104
tests/_do_root_and_user.pm Normal file
View file

@ -0,0 +1,104 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
use utils;
sub _set_root_password {
# can also hit a transition animation
wait_still_screen 2;
my $root_password = get_var("ROOT_PASSWORD", "weakpassword");
assert_and_click "anaconda_install_root_password";
# we have to click 'enable root account' before typing the
#password
assert_and_click "anaconda_install_root_password_screen";
# wait out animation
wait_still_screen 2;
desktop_switch_layout("ascii", "anaconda") if (get_var("SWITCHED_LAYOUT"));
# these screens seems insanely subject to typing errors, so
# type super safely. This doesn't really slow the test down
# as we still get done before the install process is complete.
type_very_safely $root_password;
wait_screen_change { send_key "tab"; };
type_very_safely $root_password;
# Another screen to test identification on
my $identification = get_var('IDENTIFICATION');
if ($identification eq 'true') {
check_top_bar();
# we don't check version or pre-release because here those
# texts appear on the banner which makes the needling
# complex and fragile (banner is different between variants,
# and has a gradient so for RTL languages the background color
# differs; pre-release text is also translated)
}
assert_and_click "anaconda_spoke_done";
# exiting this screen can take a while, so check for the hub
assert_screen "anaconda_main_hub", 60;
}
sub _set_root_password_webui {
my $root_password = get_var("ROOT_PASSWORD", "weakpassword");
# hit tab till we can see the button, it may be off screen
send_key_until_needlematch("anaconda_webui_allow_root", "tab", 3, 3);
# Click the radio button, then get focus and fill the fields.
assert_and_click("anaconda_webui_allow_root");
sleep(1);
type_very_safely($root_password);
for (1 .. 2) {
send_key("tab");
sleep(1);
}
type_very_safely($root_password);
}
sub run {
my $self = shift;
# check whether user and root password creation are suppressed,
# as they may be. if the 'begin installation' button is present
# and active, they must be suppressed. we use assert_screen not
# check_screen just to make it faster
assert_screen [
'anaconda_install_user_creation',
'anaconda_webui_no_local_account',
'anaconda_webui_begin_installation',
'anaconda_main_hub_begin_installation'
];
if (match_has_tag('anaconda_webui_begin_installation') || match_has_tag('anaconda_main_hub_begin_installation')) {
set_var('INSTALLER_NO_ROOT', '1');
set_var('INSTALL_NO_USER', '1');
}
my $nouser = (get_var("USER_LOGIN", '') eq 'false' || get_var("INSTALL_NO_USER"));
my $noroot = get_var("INSTALLER_NO_ROOT");
return if ($nouser && $noroot);
if (get_var("_ANACONDA_WEBUI")) {
if ($nouser) {
assert_and_click 'anaconda_webui_no_local_account';
}
else {
webui_create_user();
}
_set_root_password_webui() unless ($noroot);
assert_and_click("anaconda_webui_next");
}
else {
_set_root_password() unless ($noroot);
# Set user details, unless the test is configured not to create one
unless ($nouser) {
# Wait out animation
wait_still_screen 8;
anaconda_create_user();
}
}
# Check username (and hence keyboard layout) if non-English
if (get_var('LANGUAGE')) {
assert_screen "anaconda_install_user_created";
}
}
sub test_flags {
return {fatal => 1};
}
1;
# vim: set sw=4 et:

View file

@ -7,7 +7,7 @@ use utils;
sub _enter_password {
my $password = shift;
if (get_var("SWITCHED_LAYOUT")) {
# see _do_install_and_reboot; when layout is switched
# see _do_root_and_user; when layout is switched
# user password is doubled to contain both US and native
# chars
desktop_switch_layout 'ascii';

View file

@ -9,8 +9,6 @@ sub run {
# but verify correct default in some cases
my $packageset = get_var('PACKAGE_SET', 'minimal');
if ($packageset eq 'default') {
# we can't or don't want to check the selected package set in this case
return if (get_var('CANNED') || get_var('LIVE') || get_var('MEMCHECK'));
$self->root_console;
my $env = 'custom-environment';
if (get_var('SUBVARIANT') eq 'Server') {