mirror of
https://pagure.io/fedora-qa/os-autoinst-distri-fedora.git
synced 2024-12-28 21:23:09 +00:00
c95bb4306d
We check the same screen twice with two different needles. Signed-off-by: Adam Williamson <awilliam@redhat.com>
472 lines
19 KiB
Perl
472 lines
19 KiB
Perl
package anaconda;
|
|
|
|
use strict;
|
|
|
|
use base 'Exporter';
|
|
use Exporter;
|
|
|
|
use testapi;
|
|
use utils;
|
|
use bugzilla;
|
|
|
|
our @EXPORT = qw/select_disks custom_scheme_select custom_blivet_add_partition custom_blivet_format_partition custom_blivet_resize_partition custom_change_type custom_change_fs custom_change_device custom_delete_part get_full_repo check_help_on_pane get_mirrorlist_url crash_anaconda_text report_bug_text/;
|
|
|
|
sub select_disks {
|
|
# Handles disk selection. Has one optional argument - number of
|
|
# disks to select. Should be run when main Anaconda hub is
|
|
# displayed. Enters disk selection spoke and then ensures that
|
|
# required number of disks are selected. Additionally, if
|
|
# PARTITIONING variable starts with custom_, selects "custom
|
|
# partitioning" checkbox. Example usage:
|
|
# after calling `select_disks(2);` from Anaconda main hub,
|
|
# installation destination spoke will be displayed and two
|
|
# attached disks will be selected for installation.
|
|
my %args = (
|
|
disks => 1,
|
|
iscsi => {},
|
|
@_
|
|
);
|
|
my %iscsi = %{$args{iscsi}};
|
|
# Anaconda hub
|
|
assert_screen "anaconda_main_hub", 300; #
|
|
# Damn animation delay can cause bad clicks here too - wait for it
|
|
sleep 1;
|
|
assert_and_click "anaconda_main_hub_install_destination";
|
|
|
|
if (get_var('NUMDISKS') > 1) {
|
|
# Multi-disk case. Select however many disks the test needs. If
|
|
# $disks is 0, this will do nothing, and 0 disks will be selected.
|
|
for my $n (1 .. $args{disks}) {
|
|
assert_and_click "anaconda_install_destination_select_disk_$n";
|
|
}
|
|
}
|
|
else {
|
|
# Single disk case.
|
|
if ($args{disks} == 0) {
|
|
# Clicking will *de*-select.
|
|
assert_and_click "anaconda_install_destination_select_disk_1";
|
|
}
|
|
elsif ($args{disks} > 1) {
|
|
die "Only one disk is connected! Cannot select $args{disks} disks.";
|
|
}
|
|
# For exactly 1 disk, we don't need to do anything.
|
|
}
|
|
|
|
# Handle network disks.
|
|
if (%iscsi) {
|
|
assert_and_click "anaconda_install_destination_add_network_disk";
|
|
foreach my $target (keys %iscsi) {
|
|
my $ip = $iscsi{$target}->[0];
|
|
my $user = $iscsi{$target}->[1];
|
|
my $password = $iscsi{$target}->[2];
|
|
assert_and_click "anaconda_install_destination_add_iscsi_target";
|
|
wait_still_screen 2;
|
|
type_safely $ip;
|
|
wait_screen_change { send_key "tab"; };
|
|
type_safely $target;
|
|
# start discovery - three tabs, enter
|
|
type_safely "\t\t\t\n";
|
|
if ($user && $password) {
|
|
assert_and_click "anaconda_install_destination_target_auth_type";
|
|
assert_and_click "anaconda_install_destination_target_auth_type_chap";
|
|
send_key "tab";
|
|
type_safely $user;
|
|
send_key "tab";
|
|
type_safely $password;
|
|
}
|
|
assert_and_click "anaconda_install_destination_target_login";
|
|
assert_and_click "anaconda_install_destination_select_target";
|
|
}
|
|
assert_and_click "anaconda_spoke_done";
|
|
}
|
|
|
|
# If this is a custom partitioning test, select custom partitioning. For testing blivet-gui,
|
|
# name of test module should start with custom_blivet_, otherwise it should start with custom_.
|
|
if (get_var('PARTITIONING') =~ /^custom_blivet_/) {
|
|
assert_and_click "anaconda_manual_blivet_partitioning";
|
|
} elsif (get_var('PARTITIONING') =~ /^custom_/) {
|
|
assert_and_click "anaconda_manual_partitioning";
|
|
}
|
|
}
|
|
|
|
sub custom_scheme_select {
|
|
# Used for setting custom partitioning scheme (such as LVM).
|
|
# Should be called when custom partitioning spoke is displayed.
|
|
# Pass the name of the partitioning scheme. Needle
|
|
# `anaconda_part_scheme_$scheme` should exist. Example usage:
|
|
# `custom_scheme_select("btrfs");` uses needle
|
|
# `anaconda_part_scheme_btrfs` to set partition scheme to Btrfs.
|
|
my ($scheme) = @_;
|
|
assert_and_click "anaconda_part_scheme";
|
|
# Move the mouse away from the menu
|
|
mouse_set(10, 10);
|
|
# workaround for bug aarch64 tests sometimes hit - menu doesn't
|
|
# open when clicked. just click it again.
|
|
if (check_screen "anaconda_part_scheme_active", 5) {
|
|
assert_and_click "anaconda_part_scheme_active";
|
|
mouse_set(10, 10);
|
|
}
|
|
assert_and_click "anaconda_part_scheme_$scheme";
|
|
}
|
|
|
|
sub custom_blivet_add_partition {
|
|
# Used to add partition on blivet-gui partitioning screen
|
|
# in Anaconda. Should be called when blivet-gui is displayed and free space is selected.
|
|
# You can pass device type for partition (needle tagged anaconda_blivet_devicetype_$devicetype should exist),
|
|
# whether partitions should be of RAID1 (devicetype is then automatically handled) - you then
|
|
# need to have two disks added, size of that partition in MiBs, desired filesystem of that partition
|
|
# (anaconda_blivet_part_fs_$filesystem should exist) and mountpoint of that partition (e. g. string "/boot").
|
|
my %args = (
|
|
devicetype => "",
|
|
raid1 => 0,
|
|
size => 0,
|
|
filesystem => "",
|
|
mountpoint => "",
|
|
@_
|
|
);
|
|
$args{devicetype} = "raid" if $args{raid1};
|
|
|
|
assert_and_click "anaconda_add";
|
|
mouse_set(10, 10);
|
|
if ($args{devicetype}) {
|
|
assert_and_click "anaconda_blivet_part_devicetype";
|
|
mouse_set(10, 10);
|
|
assert_and_click "anaconda_blivet_part_devicetype_$args{devicetype}";
|
|
}
|
|
|
|
if ($args{raid1}) {
|
|
# for RAID1, two disks should be selected
|
|
send_key "tab";
|
|
send_key "down";
|
|
send_key "spc";
|
|
assert_screen "anaconda_blivet_vdb_selected";
|
|
|
|
assert_and_click "anaconda_blivet_raidlevel_select";
|
|
mouse_set(10, 10);
|
|
assert_and_click "anaconda_blivet_raidlevel_raid1";
|
|
}
|
|
|
|
if ($args{size}) {
|
|
assert_and_click "anaconda_blivet_size_unit";
|
|
assert_and_click "anaconda_blivet_size_unit_mib";
|
|
|
|
send_key "shift-tab"; # input is one tab back from unit selection listbox
|
|
|
|
# size input can contain whole set of different values, so we can't match it with needle
|
|
type_safely $args{size} . "\n";
|
|
}
|
|
# if no filesystem was specified or filesystem is already selected, do nothing
|
|
if ($args{filesystem} && !check_screen("anaconda_blivet_part_fs_$args{filesystem}_selected", 5)) {
|
|
assert_and_click "anaconda_blivet_part_fs";
|
|
# Move the mouse away from the menu
|
|
mouse_set(10, 10);
|
|
assert_and_click "anaconda_blivet_part_fs_$args{filesystem}";
|
|
}
|
|
if ($args{mountpoint}) {
|
|
assert_and_click "anaconda_blivet_mountpoint";
|
|
type_safely $args{mountpoint} . "\n";
|
|
}
|
|
# seems we can get a lost click here if we click too soon
|
|
wait_still_screen 3;
|
|
assert_and_click "anaconda_blivet_btn_ok";
|
|
# select "free space" in blivet-gui if it exists, so we could run this function again to add another partition
|
|
if (check_screen("anaconda_blivet_free_space", 15)) {
|
|
assert_and_click "anaconda_blivet_free_space";
|
|
}
|
|
}
|
|
|
|
sub custom_blivet_format_partition {
|
|
# This subroutine formats a selected partition. To use it, you must select the
|
|
# partition by other means before you format it using this routine.
|
|
# You have to create a needle for any non-existing filesystem that is
|
|
# passed via the $type, such as anaconda_blivet_part_fs_ext4.
|
|
my %args = @_;
|
|
# Start editing the partition and select the Format option
|
|
assert_and_click "anaconda_blivet_part_edit";
|
|
assert_and_click "anaconda_blivet_part_format";
|
|
# Select the appropriate filesystem type.
|
|
assert_and_click "anaconda_blivet_part_drop_select";
|
|
assert_and_click "anaconda_blivet_part_fs_$args{type}";
|
|
wait_still_screen 2;
|
|
# Fill in the label if needed.
|
|
send_key "tab";
|
|
if ($args{label}) {
|
|
type_very_safely $args{label};
|
|
}
|
|
# Fill in the mountpoint.
|
|
send_key "tab";
|
|
type_very_safely $args{mountpoint};
|
|
assert_and_click "anaconda_blivet_part_format_button";
|
|
}
|
|
|
|
sub custom_blivet_resize_partition {
|
|
# This subroutine resizes the selected (active) partition to a given value. Note, that
|
|
# if the selected value is bigger than the available space, it will only be
|
|
# resized to fill up the available space no matter the number.
|
|
# This routine cannot will not be able to select a particular partition!!!
|
|
my %args = @_;
|
|
# Start editing the partition and select the Resize option
|
|
assert_and_click "anaconda_blivet_part_edit";
|
|
assert_and_click "anaconda_blivet_part_resize";
|
|
# Select the appropriate units. Note, that there must a be needle existing
|
|
# for each possible unit that you might want to use, such as
|
|
# "anaconda_blivet_size_unit_gib".
|
|
assert_and_click "anaconda_blivet_part_drop_select";
|
|
assert_and_click "anaconda_blivet_size_unit_$args{units}";
|
|
# Move back to the value field.
|
|
send_key "shift-tab";
|
|
# Type in the new size.
|
|
type_very_safely $args{size};
|
|
assert_and_click "anaconda_blivet_part_resize_button";
|
|
}
|
|
|
|
|
|
sub custom_change_type {
|
|
# Used to set different device types for specified partition (e.g.
|
|
# RAID). Should be called when custom partitioning spoke is
|
|
# displayed. Pass it type of partition and name of partition.
|
|
# Needles `anaconda_part_select_$part` and
|
|
# `anaconda_part_device_type_$type` should exist. Example usage:
|
|
# `custom_change_type("raid", "root");` uses
|
|
# `anaconda_part_select_root` and `anaconda_part_device_type_raid`
|
|
# needles to set RAID for root partition.
|
|
my ($type, $part) = @_;
|
|
$part ||= "root";
|
|
assert_and_click "anaconda_part_select_$part";
|
|
assert_and_click "anaconda_part_device_type";
|
|
# Move the mouse away from the menu
|
|
mouse_set(10, 10);
|
|
assert_and_click "anaconda_part_device_type_$type";
|
|
assert_and_click "anaconda_part_update_settings";
|
|
wait_still_screen 5;
|
|
}
|
|
|
|
sub custom_change_fs {
|
|
# Used to set different file systems for specified partition.
|
|
# Should be called when custom partitioning spoke is displayed.
|
|
# Pass filesystem name and name of partition. Needles
|
|
# `anaconda_part_select_$part` and `anaconda_part_fs_$fs` should
|
|
# exist. Example usage:
|
|
# `custom_change_fs("ext4", "root");` uses
|
|
# `anaconda_part_select_root` and `anaconda_part_fs_ext4` needles
|
|
# to set ext4 file system for root partition.
|
|
my ($fs, $part) = @_;
|
|
$part ||= "root";
|
|
assert_and_click "anaconda_part_select_$part";
|
|
wait_still_screen 5;
|
|
# if fs is already set correctly, do nothing
|
|
return if (check_screen "anaconda_part_fs_${fs}_selected", 5);
|
|
assert_and_click "anaconda_part_fs";
|
|
# Move the mouse away from the menu
|
|
mouse_set(10, 10);
|
|
assert_and_click "anaconda_part_fs_$fs";
|
|
assert_and_click "anaconda_part_update_settings";
|
|
wait_still_screen 5;
|
|
}
|
|
|
|
sub custom_change_device {
|
|
my ($part, $devices) = @_;
|
|
assert_and_click "anaconda_part_select_$part";
|
|
assert_and_click "anaconda_part_device_modify";
|
|
foreach my $device (split(/ /, $devices)) {
|
|
assert_and_click "anaconda_part_device_${device}";
|
|
}
|
|
assert_and_click "anaconda_part_device_select";
|
|
assert_and_click "anaconda_part_update_settings";
|
|
wait_still_screen 5;
|
|
}
|
|
|
|
sub custom_delete_part {
|
|
# Used for deletion of previously added partitions in custom
|
|
# partitioning spoke. Should be called when custom partitioning
|
|
# spoke is displayed. Pass the partition name. Needle
|
|
# `anaconda_part_select_$part` should exist. Example usage:
|
|
# `custom_delete_part('swap');` uses needle
|
|
# `anaconda_part_select_swap` to delete previously added swap
|
|
# partition.
|
|
my ($part) = @_;
|
|
return if not $part;
|
|
assert_and_click "anaconda_part_select_$part";
|
|
assert_and_click "anaconda_part_delete";
|
|
}
|
|
|
|
sub get_full_repo {
|
|
my ($repourl) = @_;
|
|
# trivial thing we kept repeating: fill out an HTTP or HTTPS
|
|
# repo URL with flavor and arch, leave hd & NFS ones alone
|
|
# (as for those tests we just use a mounted ISO and URL is complete)
|
|
if ($repourl !~ m/^(nfs|hd:)/) {
|
|
# Everything variant doesn't exist for modular composes atm,
|
|
# only Server
|
|
my $variant = 'Everything';
|
|
$variant = 'Server' if (get_var("MODULAR"));
|
|
$repourl .= "/${variant}/".get_var("ARCH")."/os";
|
|
}
|
|
return $repourl;
|
|
}
|
|
|
|
sub get_mirrorlist_url {
|
|
return "mirrors.fedoraproject.org/mirrorlist?repo=fedora-" . lc(get_var("VERSION")) . "&arch=" . get_var('ARCH');
|
|
}
|
|
|
|
sub check_help_on_pane {
|
|
# This subroutine opens the selected Anaconda pane and checks
|
|
# if the Help button can be clicked to obtain relevant help.
|
|
#
|
|
# Pass an argument to select particular pane to check.
|
|
my $screen = shift;
|
|
|
|
# Some Help buttons need to be accessed directly according
|
|
# to various installation steps (and not from the main hub),
|
|
# namely the Main hub Help button, Language selection Help button
|
|
# and Installation progress Help button. For the aforementioned
|
|
# step, we are skipping selecting the panes.
|
|
if ($screen ne "main" && $screen ne "language_selection" && $screen ne "installation_progress") {
|
|
send_key_until_needlematch("anaconda_main_hub_$screen", "shift-tab");
|
|
wait_screen_change { click_lastmatch; };
|
|
}
|
|
# For Help, click on the the Help button.
|
|
assert_and_click "anaconda_help_button";
|
|
|
|
# On the main hub, the Help summary is shown, from where a link
|
|
# takes us to Installation progress. This is a specific situation,
|
|
# so let's handle this differently.
|
|
if ($screen eq "main") {
|
|
# Check the Installation Summary screen.
|
|
assert_screen "anaconda_help_summary";
|
|
# Click on Installation Progress link
|
|
assert_and_click "anaconda_help_progress_link";
|
|
# Check the Installation Progress screen
|
|
assert_screen "anaconda_help_installation_progress";
|
|
}
|
|
# Otherwise, only check the relevant screen.
|
|
else {
|
|
assert_screen "anaconda_help_$screen";
|
|
}
|
|
# Close Help window
|
|
assert_and_click "anaconda_help_quit";
|
|
# Where panes were not opened, we will not close them.
|
|
if ($screen ne "main" && $screen ne "language_selection" && $screen ne "installation_progress") {
|
|
assert_and_click "anaconda_spoke_done";
|
|
}
|
|
# In the situation, when we do not arrive at main hub, we will skip
|
|
# testing that main hub is shown.
|
|
if ($screen ne "language_selection" && $screen ne "installation_progress") {
|
|
# on leaving a spoke, it is highlighted on the main hub, which
|
|
# can throw off the match here. so we'll try hitting shift-tab
|
|
# a few times to shift focus
|
|
send_key_until_needlematch("anaconda_main_hub", "shift-tab");
|
|
# things can take some time to settle after this one
|
|
wait_still_screen 10 if ($screen eq "install_destination");
|
|
}
|
|
}
|
|
|
|
sub crash_anaconda_text {
|
|
# This routine uses the Anaconda crash trigger to break the ongoing Anaconda installation to simulate
|
|
# an Anaconda crash and runs a series of steps that results in creating a bug in Bugzilla.
|
|
# It is used in the `install_text.pm` test and can be switched on by using the CRASH_REPORT
|
|
# variable set to 1.
|
|
#
|
|
# First let us navigate to reach the shell window in Anaconda using the alt-f3 combo,
|
|
# this should take us to another terminal, where we can simulate the crash.
|
|
send_key "alt-f3";
|
|
assert_screen("anaconda_text_install_shell");
|
|
# We use the trigger command to do the simulated crash.
|
|
type_string "kill -USR1 `cat /var/run/anaconda.pid`\n";
|
|
# And navigate back to the main panel of Anaconda. This should require
|
|
send_key "alt-f1";
|
|
assert_screen("anaconda_text_install_main");
|
|
# We wait until the crash menu appears. This usually takes some time,
|
|
# so let's try for 300 seconds, this should be long enough.
|
|
my $trials = 1;
|
|
until (check_screen("anaconda_text_crash_menu_ready") || $trials > 30) {
|
|
sleep 10;
|
|
++$trials;
|
|
}
|
|
# If the crash menu never appears, let's assert it to fail.
|
|
if ($trials > 30) {
|
|
assert_screen("anaconda_text_crash_menu_ready");
|
|
}
|
|
|
|
}
|
|
|
|
sub report_bug_text {
|
|
# This routine handles the Bugzilla reporting after a simulated crash on
|
|
# a textual console.
|
|
# We will not create a needle for every menu item, and we will fail,
|
|
# if there will be no positive Bugzilla confirmation shown at the end
|
|
# of the process and then we will fail.
|
|
#
|
|
# Let us record the time of this test run. Later, we will use it to
|
|
# limit the Bugzilla search.
|
|
my $timestamp = time();
|
|
#
|
|
# First, collect the credentials.
|
|
my $login = get_var("BUGZILLA_LOGIN");
|
|
my $password = get_var("_SECRET_BUGZILLA_PASSWORD");
|
|
my $apikey = get_var("_SECRET_BUGZILLA_APIKEY");
|
|
# Choose item 1 - Report the bug.
|
|
type_string "1\n";
|
|
sleep 2;
|
|
# Choose item 1 - Report to Bugzilla
|
|
type_string "1\n";
|
|
sleep 5;
|
|
# Do login.
|
|
type_string $login;
|
|
type_string "\n";
|
|
sleep 5;
|
|
# Enter the name of the Zilla.
|
|
type_password $password;
|
|
type_string "\n";
|
|
sleep 10;
|
|
# Save the report without changing it.
|
|
# It would need some more tweaking to actually type into the report, but since
|
|
# it is reported even if unchanged, we leave it as such.
|
|
type_string ":wq\n";
|
|
# Wait until the Crash menu appears again.
|
|
# The same screen shows the result of the Bugzilla operation,
|
|
# so if the needle matches, the bug has been created in Bugzilla.
|
|
# Bugzilla connection is slow so we need to wait out some time,
|
|
# therefore let's use a cycle that will check each 10 seconds and
|
|
# ends if there is no correct answer from Bugzilla in 120 seconds.
|
|
my $counter = 0;
|
|
until (check_screen("anaconda_text_bug_reported") || $counter > 12) {
|
|
sleep 10;
|
|
++$counter;
|
|
}
|
|
# Sometimes, Bugzilla throws out a communication error although the bug has been
|
|
# created successfully. If this happens, we will softfail and leave the creation
|
|
# check to a later step.
|
|
if ($counter > 12) {
|
|
record_soft_failure "Warning: Bugzilla has reported an error which could mean that the bug has not been created correctly, but it probably is not a real problem, if the test has not failed completely. ";
|
|
}
|
|
|
|
# Now, let us check with Bugzilla directly, if the bug has been created.
|
|
# First, we shall get a Bugzilla format timestamp to use it in the query.
|
|
# The timestamp will limit the list of bugs to those that have been created since
|
|
# the then -> resulting with high probability in the one that this test run
|
|
# has just created.
|
|
$timestamp = convert_to_bz_timestamp($timestamp);
|
|
# Then we fetch the latest bug from Bugzilla.
|
|
my $lastbug = get_newest_bug($timestamp, $login);
|
|
unless ($lastbug) {
|
|
die "Bugzilla returned no newly created bug. It seems that the bug has not been created.";
|
|
}
|
|
else {
|
|
print("BUGZILLA: The last bug was found: $lastbug\n");
|
|
}
|
|
# We have found that the bug indeed is in the bugzilla (otherwise
|
|
# we would have died already) so now we close it to clean up after this test run.
|
|
my $result = close_notabug($lastbug, $apikey);
|
|
unless ($result) {
|
|
record_soft_failure "The bug has not been closed for some reason. Check manually.";
|
|
}
|
|
else {
|
|
print("BUGZILLA: The last bug $lastbug changed status to CLOSED.\n");
|
|
}
|
|
|
|
# Quit anaconda
|
|
type_string "4\n";
|
|
|
|
}
|