Move all remaining utility functions into exporter modules

Summary:
This adds a couple of new exporter modules, renames main_common
to utils (this is a better name: openSUSE's main_common is
functions used in main.pm, utils is what they call their module
full of miscellaneous commonly-used functions), and moves a
bunch of utility functions that were previously needlessly
implemented as instance methods in base classes into the
exporter modules. That means we can get rid of all the annoying
$self-> syntax for calling them.

We get rid of `fedorabase` entirely, as it's no longer useful
for anything. Other base classes keep the 'standard' methods
(like `post_fail_hook`) and methods which actually need to be
methods (like `root_console`, whose behaviour is different in
anacondatest and installedtest).

Test Plan:
Do a full test suite run and check everything lines
up. There should be no functional differences from before at all,
this is just a re-org.

Reviewers: jskladan, garretraziel_but_actually_jsedlak_who_uses_stupid_nicknames

Reviewed By: garretraziel_but_actually_jsedlak_who_uses_stupid_nicknames

Subscribers: tflink

Differential Revision: https://phab.qa.fedoraproject.org/D1080
This commit is contained in:
Adam Williamson 2017-01-17 23:15:44 -08:00
parent a091185af1
commit b67f604894
53 changed files with 511 additions and 473 deletions

View File

@ -59,14 +59,13 @@ After installation is finished and installed system is fully booted, you can run
### Test inheritance
Your test can inherit from `basetest`, `fedorabase`, `installedtest` or `anacondatest`. Each provides relevant methods that are documented in-line, so read the files (`lib/basetest.pm`, `lib/fedorabase.pm` etc.) for information on these.
Your test can inherit from `basetest`, `installedtest` or `anacondatest`. Each provides relevant methods that are documented in-line, so read the files (`lib/anacondatest.pm`, `lib/installedtest.pm`) for information on these.
- `basetest`: A base class provided by os-autoinst - it has empty `post_fail_hook()` and doesn't set any flags.
- `fedorabase`: doesn't set flags and does nothing in `post_fail_hook()`, but provides some basic methods that will be useful during testing Fedora. It should be used when no other, more specific class can be used.
- `anacondatest`: should be used in tests where Anaconda is running. It uploads Anaconda logs (for example `anaconda.log` or `packaging.log`) in `post_fail_hook()`.
- `installedtest`: should be used in tests that are running on installed system (either in postinstall phase or in upgrade tests).
There are also several modules that export utility functions, currently `main_common`, `freeipa`, and `packagetest`. Your test can `use` any of these modules and then directly call the functions they export. Again, the functions are documented in-line.
There are also several modules that export utility functions, currently `utils`, `anaconda`, `freeipa`, `packagetest` and `tapnet`. Your test can `use` any of these modules and then directly call the functions they export. Again, the functions are documented in-line.
### New test development workflow

180
lib/anaconda.pm Normal file
View File

@ -0,0 +1,180 @@
package anaconda;
use strict;
use base 'Exporter';
use Exporter;
use testapi;
use utils;
our @EXPORT = qw/select_disks custom_scheme_select custom_change_type custom_change_fs custom_change_device custom_delete_part get_full_repo get_mirrorlist_url/;
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.
if (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);
assert_and_click "anaconda_part_scheme_$scheme";
}
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";
}
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("ext3", "root");` uses
# `anaconda_part_select_root` and `anaconda_part_fs_ext3` needles
# to set ext3 file system for root partition.
my ($fs, $part) = @_;
$part ||= "root";
assert_and_click "anaconda_part_select_$part";
# 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";
}
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";
}
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 NFS ones alone (as for
# NFS tests we just use a mounted ISO and the URL is complete)
if ($repourl !~ m/^nfs/) {
$repourl .= "/Everything/".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');
}

View File

@ -1,13 +1,14 @@
package anacondatest;
use base 'fedorabase';
use base 'basetest';
# base class for all Anaconda (installation) tests
# should be used in tests where Anaconda is running - when it makes sense
# to upload Anaconda logs when something fails
# to upload Anaconda logs when something fails. Many tests using this as a
# base likely will also want to `use anaconda` for commonly-used functions.
use testapi;
use main_common;
use utils;
sub post_fail_hook {
my $self = shift;
@ -74,176 +75,6 @@ sub root_console {
console_login(user=>"root");
}
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 `$self->select_disks(2);` from Anaconda main hub,
# installation destination spoke will be displayed and two
# attached disks will be selected for installation.
my $self = shift;
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.
if (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:
# `$self->custom_scheme_select("btrfs");` uses needle
# `anaconda_part_scheme_btrfs` to set partition scheme to Btrfs.
my ($self, $scheme) = @_;
assert_and_click "anaconda_part_scheme";
# Move the mouse away from the menu
mouse_set(10, 10);
assert_and_click "anaconda_part_scheme_$scheme";
}
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:
# `$self->custom_change_type("raid", "root");` uses
# `anaconda_part_select_root` and `anaconda_part_device_type_raid`
# needles to set RAID for root partition.
my ($self, $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";
}
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:
# `$self->custom_change_fs("ext3", "root");` uses
# `anaconda_part_select_root` and `anaconda_part_fs_ext3` needles
# to set ext3 file system for root partition.
my ($self, $fs, $part) = @_;
$part ||= "root";
assert_and_click "anaconda_part_select_$part";
# 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";
}
sub custom_change_device {
my ($self, $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";
}
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:
# `$self->custom_delete_part('swap');` uses
# `anaconda_part_select_swap` to delete previously added swap
# partition.
my ($self, $part) = @_;
return if not $part;
assert_and_click "anaconda_part_select_$part";
assert_and_click "anaconda_part_delete";
}
sub get_full_repo {
my ($self, $repourl) = @_;
# trivial thing we kept repeating: fill out an HTTP or HTTPS
# repo URL with flavor and arch, leave NFS ones alone (as for
# NFS tests we just use a mounted ISO and the URL is complete)
if ($repourl !~ m/^nfs/) {
$repourl .= "/Everything/".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')
}
1;
# vim: set sw=4 et:

View File

@ -1,142 +0,0 @@
package fedorabase;
use base 'basetest';
use lockapi;
# base class for all Fedora tests
# use this class when using other base class doesn't make sense
use testapi;
sub do_bootloader {
# Handle bootloader screen. 'bootloader' is syslinux or grub.
# 'uefi' is whether this is a UEFI install, will get_var UEFI if
# not explicitly set. 'postinstall' is whether we're on an
# installed system or at the installer (this matters for how many
# times we press 'down' to find the kernel line when typing args).
# 'args' is a string of extra kernel args, if desired. 'mutex' is
# a parallel test mutex lock to wait for before proceeding, if
# desired. 'first' is whether to hit 'up' a couple of times to
# make sure we boot the first menu entry. 'timeout' is how long to
# wait for the bootloader screen.
my $self = shift;
my %args = (
postinstall => 0,
params => "",
mutex => "",
first => 1,
timeout => 30,
uefi => get_var("UEFI"),
@_
);
# if not postinstall and not UEFI, syslinux
$args{bootloader} //= ($args{uefi} || $args{postinstall}) ? "grub" : "syslinux";
if ($args{uefi}) {
# we use the firmware-type specific tags because we want to be
# sure we actually did a UEFI boot
assert_screen "bootloader_uefi", $args{timeout};
} else {
assert_screen "bootloader_bios", $args{timeout};
}
if ($args{mutex}) {
# cancel countdown
send_key "left";
mutex_lock $args{mutex};
mutex_unlock $args{mutex};
}
if ($args{first}) {
# press up a couple of times to make sure we're at first entry
send_key "up";
send_key "up";
}
if ($args{params}) {
if ($args{bootloader} eq "syslinux") {
send_key "tab";
}
else {
send_key "e";
# ternary: 13 'downs' to reach the kernel line for installed
# system, 2 for UEFI installer
my $presses = $args{postinstall} ? 13 : 2;
foreach my $i (1..$presses) {
send_key "down";
}
send_key "end";
}
type_string " $args{params}";
}
# ctrl-X boots from grub editor mode
send_key "ctrl-x";
# return boots all other cases
send_key "ret";
}
sub get_milestone {
my $self = shift;
# FIXME: we don't know how to do this with Pungi 4 yet.
return '';
}
sub clone_host_file {
# copy a given file from the host into the guest. Mainly used
# for networking config on tap tests. this is pretty crazy, but
# SUSE do almost the same thing...
my $self = shift;
my $file = shift;
my $text = '';
open(my $fh, '<', $file);
while (<$fh>) {
$text .= $_;
}
# escape any ' characters in the text...
$text =~ s/"/\\"/g;
assert_script_run "printf \"$text\" > $file";
# for debugging...
assert_script_run "cat $file";
}
sub setup_tap_static {
# this is a common thing for tap tests, where we set up networking
# for the system with a static IP address and possibly a specific
# hostname
my $self = shift;
my $ip = shift;
my $hostname = shift || "";
if ($hostname) {
# assigning output of split to a single-item array gives us just
# the first split
my ($short) = split(/\./, $hostname);
# set hostname
assert_script_run "hostnamectl set-hostname $hostname";
# add entry to /etc/hosts
assert_script_run "echo '$ip $hostname $short' >> /etc/hosts";
}
# bring up network. DEFROUTE is *vital* here
assert_script_run "printf 'DEVICE=eth0\nBOOTPROTO=none\nIPADDR=$ip\nGATEWAY=10.0.2.2\nPREFIX=24\nDEFROUTE=yes' > /etc/sysconfig/network-scripts/ifcfg-eth0";
script_run "systemctl restart NetworkManager.service";
}
sub get_host_dns {
# get DNS server addresses from the host
my @forwards;
open(FH, '<', "/etc/resolv.conf");
while (<FH>) {
if ($_ =~ m/^nameserver +(.+)/) {
push @forwards, $1;
}
}
return @forwards;
}
sub boot_decrypt {
# decrypt storage during boot; arg is timeout (in seconds)
my $self = shift;
my $timeout = shift || 60;
assert_screen "boot_enter_passphrase", $timeout; #
type_string get_var("ENCRYPT_PASSWORD");
send_key "ret";
}
1;
# vim: set sw=4 et:

View File

@ -6,7 +6,7 @@ use base 'Exporter';
use Exporter;
use testapi;
use main_common;
use utils;
our @EXPORT = qw/add_user start_webui/;

View File

@ -1,5 +1,5 @@
package installedtest;
use base 'fedorabase';
use base 'basetest';
# base class for tests that run on installed system
@ -7,7 +7,7 @@ use base 'fedorabase';
# of upgrade tests, postinstall phases...
use testapi;
use main_common;
use utils;
sub root_console {
# Switch to a default or specified TTY and log in as root.
@ -45,68 +45,6 @@ sub post_fail_hook {
}
}
sub check_release {
# Checks whether the installed release matches a given value. E.g.
# `check_release(23)` checks whether the installed system is
# Fedora 23. The value can be 'Rawhide' or a Fedora release
# number; often you will want to use `get_var('VERSION')`. Expects
# a console prompt to be active when it is called.
my $self = shift;
my $release = shift;
my $check_command = "grep SUPPORT_PRODUCT_VERSION /usr/lib/os.release.d/os-release-fedora";
validate_script_output $check_command, sub { $_ =~ m/REDHAT_SUPPORT_PRODUCT_VERSION=$release/ };
}
sub menu_launch_type {
# Launch an application in a graphical environment, by opening a
# launcher, typing the specified string and hitting enter. Pass
# the string to be typed to launch whatever it is you want.
my $self = shift;
my $app = shift;
# super does not work on KDE, because fml
send_key 'alt-f1';
# srsly KDE y u so slo
wait_still_screen 3;
type_very_safely $app;
send_key 'ret';
}
sub start_cockpit {
# Starting from a console, get to a browser with Cockpit (running
# on localhost) shown. If $login is truth-y, also log in. Assumes
# X and Firefox are installed.
my $self = shift;
my $login = shift || 0;
# run firefox directly in X as root. never do this, kids!
type_string "startx /usr/bin/firefox -width 1024 -height 768 http://localhost:9090\n";
assert_screen "cockpit_login";
wait_still_screen 5;
if ($login) {
type_safely "root";
wait_screen_change { send_key "tab"; };
type_safely get_var("ROOT_PASSWORD", "weakpassword");
send_key "ret";
assert_screen "cockpit_main";
# wait for any animation or other weirdness
# can't use wait_still_screen because of that damn graph
sleep 3;
}
}
sub repo_setup {
# disable updates-testing and updates and use the compose location
# as the target for fedora and rawhide rather than mirrorlist, so
# tools see only packages from the compose under test
my $location = get_var("LOCATION");
assert_script_run 'dnf config-manager --set-disabled updates-testing updates';
# we use script_run here as the rawhide repo file won't always exist
# and we don't want to bother testing or predicting its existence;
# assert_script_run doesn't buy you much with sed anyway as it'll
# return 0 even if it replaced nothing
script_run "sed -i -e 's,^metalink,#metalink,g' -e 's,^#baseurl.*basearch,baseurl=${location}/Everything/\$basearch,g' /etc/yum.repos.d/{fedora,fedora-rawhide}.repo", 0;
script_run "cat /etc/yum.repos.d/{fedora,fedora-rawhide}.repo", 0;
}
1;
# vim: set sw=4 et:

62
lib/tapnet.pm Normal file
View File

@ -0,0 +1,62 @@
package tapnet;
use strict;
use base 'Exporter';
use Exporter;
use testapi;
our @EXPORT = qw/clone_host_file setup_tap_static get_host_dns/;
sub clone_host_file {
# copy a given file from the host into the guest. Mainly used
# for networking config on tap tests. this is pretty crazy, but
# SUSE do almost the same thing...
my $file = shift;
my $text = '';
open(my $fh, '<', $file);
while (<$fh>) {
$text .= $_;
}
# escape any " characters in the text...
$text =~ s/"/\\"/g;
assert_script_run "printf \"$text\" > $file";
# for debugging...
assert_script_run "cat $file";
}
sub setup_tap_static {
# this is a common thing for tap tests, where we set up networking
# for the system with a static IP address and possibly a specific
# hostname
my $ip = shift;
my $hostname = shift || "";
if ($hostname) {
# assigning output of split to a single-item array gives us just
# the first split
my ($short) = split(/\./, $hostname);
# set hostname
assert_script_run "hostnamectl set-hostname $hostname";
# add entry to /etc/hosts
assert_script_run "echo '$ip $hostname $short' >> /etc/hosts";
}
# bring up network. DEFROUTE is *vital* here
assert_script_run "printf 'DEVICE=eth0\nBOOTPROTO=none\nIPADDR=$ip\nGATEWAY=10.0.2.2\nPREFIX=24\nDEFROUTE=yes' > /etc/sysconfig/network-scripts/ifcfg-eth0";
script_run "systemctl restart NetworkManager.service";
}
sub get_host_dns {
# get DNS server addresses from the host
my @forwards;
open(FH, '<', "/etc/resolv.conf");
while (<FH>) {
if ($_ =~ m/^nameserver +(.+)/) {
push @forwards, $1;
}
}
return @forwards;
}
1;
# vim: set sw=4 et:

View File

@ -1,12 +1,13 @@
package main_common;
package utils;
use strict;
use base 'Exporter';
use Exporter;
use lockapi;
use testapi;
our @EXPORT = qw/run_with_error_check type_safely type_very_safely desktop_vt boot_to_login_screen console_login console_switch_layout desktop_switch_layout console_loadkeys_us/;
our @EXPORT = qw/run_with_error_check type_safely type_very_safely desktop_vt boot_to_login_screen console_login console_switch_layout desktop_switch_layout console_loadkeys_us do_bootloader get_milestone boot_decrypt check_release menu_launch_type start_cockpit repo_setup/;
sub run_with_error_check {
my ($func, $error_screen) = @_;
@ -162,3 +163,141 @@ sub console_loadkeys_us {
script_run "loqdkeys us", 0;
}
}
sub do_bootloader {
# Handle bootloader screen. 'bootloader' is syslinux or grub.
# 'uefi' is whether this is a UEFI install, will get_var UEFI if
# not explicitly set. 'postinstall' is whether we're on an
# installed system or at the installer (this matters for how many
# times we press 'down' to find the kernel line when typing args).
# 'args' is a string of extra kernel args, if desired. 'mutex' is
# a parallel test mutex lock to wait for before proceeding, if
# desired. 'first' is whether to hit 'up' a couple of times to
# make sure we boot the first menu entry. 'timeout' is how long to
# wait for the bootloader screen.
my %args = (
postinstall => 0,
params => "",
mutex => "",
first => 1,
timeout => 30,
uefi => get_var("UEFI"),
@_
);
# if not postinstall and not UEFI, syslinux
$args{bootloader} //= ($args{uefi} || $args{postinstall}) ? "grub" : "syslinux";
if ($args{uefi}) {
# we use the firmware-type specific tags because we want to be
# sure we actually did a UEFI boot
assert_screen "bootloader_uefi", $args{timeout};
} else {
assert_screen "bootloader_bios", $args{timeout};
}
if ($args{mutex}) {
# cancel countdown
send_key "left";
mutex_lock $args{mutex};
mutex_unlock $args{mutex};
}
if ($args{first}) {
# press up a couple of times to make sure we're at first entry
send_key "up";
send_key "up";
}
if ($args{params}) {
if ($args{bootloader} eq "syslinux") {
send_key "tab";
}
else {
send_key "e";
# ternary: 13 'downs' to reach the kernel line for installed
# system, 2 for UEFI installer
my $presses = $args{postinstall} ? 13 : 2;
foreach my $i (1..$presses) {
send_key "down";
}
send_key "end";
}
type_string " $args{params}";
}
# ctrl-X boots from grub editor mode
send_key "ctrl-x";
# return boots all other cases
send_key "ret";
}
sub get_milestone {
# FIXME: we don't know how to do this with Pungi 4 yet.
return '';
}
sub boot_decrypt {
# decrypt storage during boot; arg is timeout (in seconds)
my $timeout = shift || 60;
assert_screen "boot_enter_passphrase", $timeout; #
type_string get_var("ENCRYPT_PASSWORD");
send_key "ret";
}
sub check_release {
# Checks whether the installed release matches a given value. E.g.
# `check_release(23)` checks whether the installed system is
# Fedora 23. The value can be 'Rawhide' or a Fedora release
# number; often you will want to use `get_var('VERSION')`. Expects
# a console prompt to be active when it is called.
my $self = shift;
my $release = shift;
my $check_command = "grep SUPPORT_PRODUCT_VERSION /usr/lib/os.release.d/os-release-fedora";
validate_script_output $check_command, sub { $_ =~ m/REDHAT_SUPPORT_PRODUCT_VERSION=$release/ };
}
sub menu_launch_type {
# Launch an application in a graphical environment, by opening a
# launcher, typing the specified string and hitting enter. Pass
# the string to be typed to launch whatever it is you want.
my $self = shift;
my $app = shift;
# super does not work on KDE, because fml
send_key 'alt-f1';
# srsly KDE y u so slo
wait_still_screen 3;
type_very_safely $app;
send_key 'ret';
}
sub start_cockpit {
# Starting from a console, get to a browser with Cockpit (running
# on localhost) shown. If $login is truth-y, also log in. Assumes
# X and Firefox are installed.
my $self = shift;
my $login = shift || 0;
# run firefox directly in X as root. never do this, kids!
type_string "startx /usr/bin/firefox -width 1024 -height 768 http://localhost:9090\n";
assert_screen "cockpit_login";
wait_still_screen 5;
if ($login) {
type_safely "root";
wait_screen_change { send_key "tab"; };
type_safely get_var("ROOT_PASSWORD", "weakpassword");
send_key "ret";
assert_screen "cockpit_main";
# wait for any animation or other weirdness
# can't use wait_still_screen because of that damn graph
sleep 3;
}
}
sub repo_setup {
# disable updates-testing and updates and use the compose location
# as the target for fedora and rawhide rather than mirrorlist, so
# tools see only packages from the compose under test
my $location = get_var("LOCATION");
assert_script_run 'dnf config-manager --set-disabled updates-testing updates';
# we use script_run here as the rawhide repo file won't always exist
# and we don't want to bother testing or predicting its existence;
# assert_script_run doesn't buy you much with sed anyway as it'll
# return 0 even if it replaced nothing
script_run "sed -i -e 's,^metalink,#metalink,g' -e 's,^#baseurl.*basearch,baseurl=${location}/Everything/\$basearch,g' /etc/yum.repos.d/{fedora,fedora-rawhide}.repo", 0;
script_run "cat /etc/yum.repos.d/{fedora,fedora-rawhide}.repo", 0;
}

View File

@ -1,7 +1,8 @@
use base "anacondatest";
use strict;
use testapi;
use main_common;
use utils;
use anaconda;
sub run {
my $self = shift;
@ -15,7 +16,7 @@ sub run {
# Construct inst.repo arg for REPOSITORY_VARIATION
my $repourl = get_var("REPOSITORY_VARIATION");
if ($repourl) {
$params .= "inst.repo=" . $self->get_full_repo($repourl) . " ";
$params .= "inst.repo=" . get_full_repo($repourl) . " ";
}
$params .= "inst.text " if get_var("ANACONDA_TEXT");
# inst.debug enables memory use tracking
@ -27,7 +28,7 @@ sub run {
my $mutex = get_var("INSTALL_UNLOCK");
# call do_bootloader with postinstall=0, the params, and the mutex
$self->do_bootloader(postinstall=>0, params=>$params, mutex=>$mutex);
do_bootloader(postinstall=>0, params=>$params, mutex=>$mutex);
# proceed to installer
if (get_var("KICKSTART")) {

View File

@ -1,16 +1,17 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
sub run {
my $self = shift;
my $repourl;
if (get_var("MIRRORLIST_GRAPHICAL")) {
$repourl = $self->get_mirrorlist_url();
$repourl = get_mirrorlist_url();
}
else {
$repourl = get_var("REPOSITORY_VARIATION", get_var("REPOSITORY_GRAPHICAL"));
$repourl = $self->get_full_repo($repourl);
$repourl = get_full_repo($repourl);
}
# check that the repo was used

View File

@ -1,6 +1,6 @@
use base "installedtest";
use strict;
use main_common;
use utils;
use testapi;
sub run {

View File

@ -1,7 +1,7 @@
use base "fedorabase";
use base "basetest";
use strict;
use testapi;
use main_common;
use utils;
sub run {
my $self = shift;

View File

@ -1,7 +1,7 @@
use base "fedorabase";
use base "basetest";
use strict;
use testapi;
use main_common;
use utils;
sub run {
my $self = shift;
@ -11,7 +11,7 @@ sub run {
# handle bootloader, if requested
if (get_var("GRUB_POSTINSTALL")) {
$self->do_bootloader(postinstall=>1, params=>get_var("GRUB_POSTINSTALL"), timeout=>$wait_time);
do_bootloader(postinstall=>1, params=>get_var("GRUB_POSTINSTALL"), timeout=>$wait_time);
$wait_time = 180;
}

View File

@ -1,7 +1,7 @@
use base "anacondatest";
use strict;
use testapi;
use main_common;
use utils;
sub type_user_password {
my $self = shift;

View File

@ -1,7 +1,7 @@
use base "installedtest";
use strict;
use testapi;
use main_common;
use utils;
sub run {
# check both layouts are available at the desktop; here,

View File

@ -1,7 +1,7 @@
use base "installedtest";
use strict;
use testapi;
use main_common;
use utils;
sub run {
my $self = shift;

View File

@ -1,7 +1,8 @@
use base "anacondatest";
use strict;
use testapi;
use main_common;
use utils;
use tapnet;
sub run {
my $self = shift;
@ -19,7 +20,7 @@ sub run {
# move to DNS servers
type_safely "\n\t\t\t";
# set DNS from host
type_safely join(',', $self->get_host_dns());
type_safely join(',', get_host_dns());
type_safely "\t\t\t\t\t\n";
# can take a bit of time as it seems to wait for all the pending
# DHCP requests to time out before applying the static config

View File

@ -3,16 +3,17 @@ use strict;
use testapi;
use lockapi;
use mmapi;
use tapnet;
sub run {
my $self=shift;
# clone host's /etc/hosts (for phx2 internal routing to work)
# must come *before* setup_tap_static or else it would overwrite
# its changes
$self->clone_host_file("/etc/hosts");
clone_host_file("/etc/hosts");
# set up networking
$self->setup_tap_static("10.0.2.110", "support.domain.local");
$self->clone_host_file("/etc/resolv.conf");
setup_tap_static("10.0.2.110", "support.domain.local");
clone_host_file("/etc/resolv.conf");
## DNS / DHCP (dnsmasq)
# create config

View File

@ -1,7 +1,7 @@
use base "installedtest";
use strict;
use testapi;
use main_common;
use utils;
sub run {
my $self = shift;

View File

@ -2,19 +2,21 @@ use base "installedtest";
use strict;
use testapi;
use lockapi;
use tapnet;
use utils;
sub run {
my $self=shift;
# clone host's /etc/hosts (for phx2 internal routing to work)
# must come *before* setup_tap_static or else it would overwrite
# its changes
$self->clone_host_file("/etc/hosts");
clone_host_file("/etc/hosts");
# set up networking
$self->setup_tap_static("10.0.2.105", "dbclient.domain.local");
setup_tap_static("10.0.2.105", "dbclient.domain.local");
# clone host's resolv.conf to get name resolution
$self->clone_host_file("/etc/resolv.conf");
clone_host_file("/etc/resolv.conf");
# use compose repo, disable u-t, etc.
$self->repo_setup();
repo_setup();
# install postgresql
assert_script_run "dnf -y install postgresql", 120;
# wait for the server to be ready

View File

@ -1,7 +1,7 @@
use base "installedtest";
use strict;
use testapi;
use main_common;
use utils;
# we are very paranoid with waits and typing speed in this test
# because the system can be very busy; it's effectively first boot of

View File

@ -1,7 +1,7 @@
use base "installedtest";
use strict;
use testapi;
use main_common;
use utils;
use packagetest;
# This test sort of covers QA:Testcase_desktop_update_notification
@ -15,10 +15,10 @@ sub run {
my $desktop = get_var("DESKTOP");
# for the live image case, handle bootloader here
if (get_var("BOOTFROM")) {
$self->do_bootloader(postinstall=>1, params=>'3');
do_bootloader(postinstall=>1, params=>'3');
}
else {
$self->do_bootloader(postinstall=>0, params=>'3');
do_bootloader(postinstall=>0, params=>'3');
}
boot_to_login_screen;
$self->root_console(tty=>3);

View File

@ -1,12 +1,12 @@
use base "installedtest";
use strict;
use testapi;
use main_common;
use utils;
sub run {
my $self=shift;
assert_screen 'graphical_desktop_clean';
$self->menu_launch_type('terminal');
menu_launch_type('terminal');
wait_still_screen 5;
# need to be root
my $rootpass = get_var("ROOT_PASSWORD", "weakpassword");

View File

@ -1,7 +1,7 @@
use base "installedtest";
use strict;
use testapi;
use main_common;
use utils;
use packagetest;
sub run {
@ -22,7 +22,7 @@ sub run {
else {
# this launches GNOME Software on GNOME, dunno for any other
# desktop yet
$self->menu_launch_type('update');
menu_launch_type('update');
}
# GNOME Software has a welcome screen, get rid of it if it shows
# up (but don't fail if it doesn't, we're not testing that)

View File

@ -1,17 +1,18 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
sub run {
my $self = shift;
# Go to INSTALLATION DESTINATION and ensure the disk is selected.
# Because PARTITIONING starts with 'custom_', this will select custom.
$self->select_disks();
select_disks();
assert_and_click "anaconda_spoke_done";
# Manual partitioning spoke should be displayed. Select BTRFS
# partitioning scheme
$self->custom_scheme_select("btrfs");
custom_scheme_select("btrfs");
assert_and_click "anaconda_part_automatic";
assert_and_click "anaconda_spoke_done";
assert_and_click "anaconda_part_accept_changes";

View File

@ -1,21 +1,22 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
sub run {
my $self = shift;
# Go to INSTALLATION DESTINATION and ensure the disk is selected.
# Because PARTITIONING starts with 'custom_', this will select custom.
$self->select_disks();
select_disks();
assert_and_click "anaconda_spoke_done";
# Manual partitioning spoke should be displayed. Select Standard
# Partition scheme
$self->custom_scheme_select("standard");
custom_scheme_select("standard");
# Do 'automatic' partition creation
assert_and_click "anaconda_part_automatic";
# Change root partition to ext3
$self->custom_change_fs("ext3");
custom_change_fs("ext3");
assert_and_click "anaconda_spoke_done";
assert_and_click "anaconda_part_accept_changes";

View File

@ -1,6 +1,7 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
sub run {
my $self = shift;
@ -10,15 +11,15 @@ sub run {
# Anaconda hub
# Go to INSTALLATION DESTINATION and ensure one regular disk
# and the iscsi target are selected.
$self->select_disks(iscsi=>\%iscsi);
select_disks(iscsi=>\%iscsi);
assert_and_click "anaconda_spoke_done";
# now we're at custom part. let's use standard partitioning for
# simplicity
$self->custom_scheme_select("standard");
custom_scheme_select("standard");
# Do 'automatic' partition creation
assert_and_click "anaconda_part_automatic";
# Make sure / is on the iSCSI target (which appears as sda)
$self->custom_change_device("root", "sda");
custom_change_device("root", "sda");
assert_and_click "anaconda_spoke_done";
assert_and_click "anaconda_part_accept_changes";
}

View File

@ -1,17 +1,18 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
sub run {
my $self = shift;
# Go to INSTALLATION DESTINATION and ensure the disk is selected.
# Because PARTITIONING starts with 'custom_', this will select custom.
$self->select_disks();
select_disks();
assert_and_click "anaconda_spoke_done";
# Manual partitioning spoke should be displayed. Select LVM Thin
# Partitioning scheme
$self->custom_scheme_select("lvmthin");
custom_scheme_select("lvmthin");
# Do 'automatic' partition creation
assert_and_click "anaconda_part_automatic";
assert_and_click "anaconda_spoke_done";

View File

@ -1,17 +1,18 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
sub run {
my $self = shift;
# Go to INSTALLATION DESTINATION and ensure the disk is selected.
# Because PARTITIONING starts with 'custom_', this will select custom.
$self->select_disks();
select_disks();
assert_and_click "anaconda_spoke_done";
# Manual partitioning spoke should be displayed
assert_and_click "anaconda_part_automatic";
$self->custom_delete_part('swap');
custom_delete_part('swap');
assert_and_click "anaconda_spoke_done";
# Deleting swap shows a warning and requires a second click to confirm
# Wait a sec first, otherwise sometimes we click too fast

View File

@ -1,17 +1,18 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
sub run {
my $self = shift;
# Go to INSTALLATION DESTINATION and ensure two disks are selected.
# Because PARTITIONING starts with 'custom_', this will select custom.
$self->select_disks(disks=>2);
select_disks(disks=>2);
assert_and_click "anaconda_spoke_done";
# Manual partitioning spoke should be displayed
assert_and_click "anaconda_part_automatic";
$self->custom_change_type("raid");
custom_change_type("raid");
assert_and_click "anaconda_spoke_done";
assert_and_click "anaconda_part_accept_changes";

View File

@ -1,21 +1,22 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
sub run {
my $self = shift;
# Go to INSTALLATION DESTINATION and ensure the disk is selected.
# Because PARTITIONING starts with 'custom_', this will select custom.
$self->select_disks();
select_disks();
assert_and_click "anaconda_spoke_done";
# Manual partitioning spoke should be displayed. Select Standard
# Partition scheme
$self->custom_scheme_select("standard");
custom_scheme_select("standard");
# Do 'automatic' partition creation
assert_and_click "anaconda_part_automatic";
# Change root partition to xfs
$self->custom_change_fs("xfs");
custom_change_fs("xfs");
assert_and_click "anaconda_spoke_done";
assert_and_click "anaconda_part_accept_changes";

View File

@ -1,12 +1,13 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
sub run {
my $self = shift;
# Anaconda hub
# Go to INSTALLATION DESTINATION and ensure one disk is selected.
$self->select_disks();
select_disks();
assert_and_click "anaconda_spoke_done";
# the only provided disk should be automatically selected and full

View File

@ -1,12 +1,13 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
sub run {
my $self = shift;
# Anaconda hub
# Go to INSTALLATION DESTINATION and ensure one disk is selected.
$self->select_disks();
select_disks();
assert_and_click "anaconda_spoke_done";
# the only provided disk should be automatically selected and full

View File

@ -1,12 +1,13 @@
use base "anacondatest";
use strict;
use testapi;
use anaconda;
sub run {
my $self = shift;
# Anaconda hub
# Go to INSTALLATION DESTINATION and ensure one disk is selected.
$self->select_disks();
select_disks();
# updates.img tests work by changing the appearance of the INSTALLATION
# DESTINATION screen, so check that if needed.