mirror of
https://pagure.io/fedora-qa/os-autoinst-distri-fedora.git
synced 2024-11-24 06:43:08 +00:00
Create test suite to test DNF5.
This commit is contained in:
parent
725c9b67b6
commit
0b37b4860c
211
lib/dnf.pm
Normal file
211
lib/dnf.pm
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
package dnf;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
|
||||||
|
use base 'Exporter';
|
||||||
|
use Exporter;
|
||||||
|
use lockapi;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
|
||||||
|
our @EXPORT = qw(install check remove reinstall parse_list_output parse_history_info latest_item parse_info parse_package_name confirm_in_lines confirm_in_output);
|
||||||
|
|
||||||
|
|
||||||
|
# This subroutine install a $package using DNF5.
|
||||||
|
# It dies if the command returns a non-zero exit
|
||||||
|
# code or if it times out.
|
||||||
|
sub install {
|
||||||
|
my $package = shift;
|
||||||
|
assert_script_run("dnf5 install -y $package", timeout => 120);
|
||||||
|
}
|
||||||
|
|
||||||
|
# This subroutine checks if the $package is installed
|
||||||
|
# using the rpm command. It returns True if it is
|
||||||
|
# installed.
|
||||||
|
sub check {
|
||||||
|
my $package = shift;
|
||||||
|
if (script_run("rpm -q $package", timeout => 60)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# This subroutine removes the package using DNF5.
|
||||||
|
sub remove {
|
||||||
|
my $package = shift;
|
||||||
|
assert_script_run("dnf5 remove -y $package", timeout => 120);
|
||||||
|
}
|
||||||
|
|
||||||
|
# This subroutine reinstalls the package using DNF5.
|
||||||
|
sub reinstall {
|
||||||
|
my $package = shift;
|
||||||
|
assert_script_run("dnf5 reinstall -y $package", timeout => 120);
|
||||||
|
}
|
||||||
|
|
||||||
|
# This subroutine will parse the DNF5 cli output
|
||||||
|
# and return a hash with activities.
|
||||||
|
# Parsing the output is quite fragile, because
|
||||||
|
# the info is only divided by whitespaces and some
|
||||||
|
# columns are empty, so we retain column information
|
||||||
|
# in this case. Therefore, we will only consider
|
||||||
|
# the following structure, that will do for simple
|
||||||
|
# transactions:
|
||||||
|
# number : dnf5 : command : value : date
|
||||||
|
sub parse_list_output {
|
||||||
|
my $dnf = shift;
|
||||||
|
# Let us split the whole ouput into single lines
|
||||||
|
my @lines = split("\n", $dnf);
|
||||||
|
# The final hash with output information.
|
||||||
|
my $parsed_output = {};
|
||||||
|
# Let's iterate over the single lines and split
|
||||||
|
# them into single columns and store in the
|
||||||
|
# parsed output.
|
||||||
|
my $values = [];
|
||||||
|
for my $line (@lines) {
|
||||||
|
# Split columns on a white space.
|
||||||
|
my @columns = split(" ", $line);
|
||||||
|
# Take the columns
|
||||||
|
$values->[0] = $columns[1];
|
||||||
|
$values->[1] = $columns[2];
|
||||||
|
# When date comes on the third place, it means
|
||||||
|
# that the command did not have any arguments.
|
||||||
|
# We need to remember this and we will store
|
||||||
|
# an empty string instead.
|
||||||
|
if ($columns[3] =~ /\d\d\d\d-\d\d-\d\d/) {
|
||||||
|
$values->[2] = "";
|
||||||
|
$values->[3] = $columns[3];
|
||||||
|
}
|
||||||
|
# All DNF commands have the "-y" argument
|
||||||
|
# which we also need to think about.
|
||||||
|
elsif ($columns[3] eq "-y") {
|
||||||
|
$values->[2] = $columns[4];
|
||||||
|
$values->[3] = $columns[5];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$values->[2] = $columns[3];
|
||||||
|
$values->[3] = $columns[4];
|
||||||
|
}
|
||||||
|
# The output also contains a description line that
|
||||||
|
# we do not want to store. That line leaves the "ID"
|
||||||
|
# string in the first place, so it is easy to find.
|
||||||
|
unless ($columns[0] eq "ID") {
|
||||||
|
$parsed_output->{$columns[0]} = $values;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $parsed_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
# This subroutine parses the DNF5 history info output. We will
|
||||||
|
# only consider several fields in order not to make things overly
|
||||||
|
# complicated, i.e. ID, user, status, releasever, and description.
|
||||||
|
sub parse_history_info {
|
||||||
|
my $dnf = shift;
|
||||||
|
# First, split into single lines.
|
||||||
|
my @lines = split("\n", $dnf);
|
||||||
|
# The final hash with output info
|
||||||
|
my $parsed_output = {};
|
||||||
|
# These are columns we are interested in.
|
||||||
|
my $selected = ["Transaction ID", "User", "Status", "Releasever", "Description"];
|
||||||
|
# Let us iterate over the lines and only choose info we want
|
||||||
|
for my $line (@lines) {
|
||||||
|
my @columns = split(" : ", $line);
|
||||||
|
# Trim the whitespaces from the column name
|
||||||
|
my $name = $columns[0];
|
||||||
|
$name =~ s/^\s+|\s+$//g;
|
||||||
|
# Only remember lines where $name matches
|
||||||
|
if ($name ~~ @$selected) {
|
||||||
|
$parsed_output->{$name} = $columns[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $parsed_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
# This subroutine returns the id number of the latest history item,
|
||||||
|
# based on the parsed history output, see parse_list_output.
|
||||||
|
sub latest_item {
|
||||||
|
# It takes the parsed data already.
|
||||||
|
my $dnfdata = shift;
|
||||||
|
# Take the keys list of ID numbers.
|
||||||
|
my @ids = keys %$dnfdata;
|
||||||
|
# Sort the keys as keys might not be sorted.
|
||||||
|
@ids = sort { $b <=> $a } @ids;
|
||||||
|
# The latest item, with highest number will now be at index 0.
|
||||||
|
return $ids[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
# This subroutine parses info from the 'info' output
|
||||||
|
# and returns a hash where the output comprises
|
||||||
|
# of keys and values.
|
||||||
|
sub parse_info {
|
||||||
|
my $output = shift;
|
||||||
|
my $info = {};
|
||||||
|
|
||||||
|
my @output = split("\n", $output);
|
||||||
|
foreach (@output) {
|
||||||
|
my ($key, $value) = split(" : ", $_);
|
||||||
|
$key =~ s/^\s+|\s+$//g;
|
||||||
|
$value =~ s/^\s+|\s+$//g;
|
||||||
|
$info->{$key} = $value;
|
||||||
|
}
|
||||||
|
return $info;
|
||||||
|
}
|
||||||
|
|
||||||
|
# This routine takes the package name
|
||||||
|
# and splits it into various parts that are
|
||||||
|
# returned as a hash where the values are
|
||||||
|
# easily accessible.
|
||||||
|
sub parse_package_name {
|
||||||
|
my $rpm = shift;
|
||||||
|
my @rpm = split("-", $rpm);
|
||||||
|
my ($name, $version, $suffix) = split("-", $rpm);
|
||||||
|
my ($release, $os, $arch);
|
||||||
|
($release, $os, $arch, $suffix) = split(/\./, $suffix);
|
||||||
|
my $package = {};
|
||||||
|
$package->{name} = $name;
|
||||||
|
$package->{version} = $version;
|
||||||
|
$package->{release} = "$release.$os";
|
||||||
|
$package->{arch} = $arch;
|
||||||
|
return $package;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# This subroutine checks all the lines of $output
|
||||||
|
# for the $keyword and records all lines where
|
||||||
|
# the $keyword is not found and then it dies.
|
||||||
|
sub confirm_in_lines {
|
||||||
|
my ($output, $keyword) = @_;
|
||||||
|
my @unmatched;
|
||||||
|
my @lines = split("\n", $output);
|
||||||
|
# Iterate over the lines and record any line with a discrepancy
|
||||||
|
# into the unmatched array.
|
||||||
|
foreach (@lines) {
|
||||||
|
unless ($_ =~ /Updating and loading/ or $_ =~ /Repositories loaded/) {
|
||||||
|
unless ($_ =~ /$keyword/) {
|
||||||
|
push(@unmatched, $_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# If there are errors in unmatched, log them and die.
|
||||||
|
if (scalar(@unmatched) > 0) {
|
||||||
|
diag("DNF5 Repoquerry errors:");
|
||||||
|
foreach (@unmatched) {
|
||||||
|
diag($_);
|
||||||
|
}
|
||||||
|
die("dnf5 repoquery returned lines that did not match the chosen pattern.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# This subroutine checks that the $keyword
|
||||||
|
# exists in the $output and dies if it does not.
|
||||||
|
sub confirm_in_output {
|
||||||
|
my ($output, $keywords) = @_;
|
||||||
|
my @lines = split("\n", $output);
|
||||||
|
foreach (@$keywords) {
|
||||||
|
unless (grep(/$_/, @lines)) {
|
||||||
|
die("The $_ was not found in the output.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2363,6 +2363,22 @@
|
|||||||
"TEST_TARGET": "NONE"
|
"TEST_TARGET": "NONE"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"dnf5": {
|
||||||
|
"profiles": {
|
||||||
|
"fedora-Server-dvd-iso-aarch64-*-aarch64": 30,
|
||||||
|
"fedora-Server-dvd-iso-ppc64le-*-ppc64le": 30,
|
||||||
|
"fedora-Server-dvd-iso-x86_64-*-64bit": 30
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"BOOTFROM": "c",
|
||||||
|
"HDD_1": "disk_%FLAVOR%_%MACHINE%.qcow2",
|
||||||
|
"LOGIN_SNAPSHOT": "1",
|
||||||
|
"POSTINSTALL_PATH": "tests/dnf5",
|
||||||
|
"ROOT_PASSWORD": "weakpassword",
|
||||||
|
"START_AFTER_TEST": "%DEPLOY_UPLOAD_TEST%",
|
||||||
|
"USER_LOGIN": "false"
|
||||||
|
}
|
||||||
|
},
|
||||||
"podman": {
|
"podman": {
|
||||||
"profiles": {
|
"profiles": {
|
||||||
"fedora-CoreOS-colive-iso-x86_64-*-64bit": 20,
|
"fedora-CoreOS-colive-iso-x86_64-*-64bit": 20,
|
||||||
|
50
tests/dnf5/aaa_setup.pm
Normal file
50
tests/dnf5/aaa_setup.pm
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
|
||||||
|
# The setup script for the DNF5 test suite.
|
||||||
|
#
|
||||||
|
# This script will test if DNF5 is installed on the system.
|
||||||
|
# Currently, this is not the case, but later in the process,
|
||||||
|
# so we will softfail if it is not and we will install it.
|
||||||
|
# Later, when DNF5 is part of Fedora, we will fail instead.
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
# Switch to console
|
||||||
|
$self->root_console(tty => 3);
|
||||||
|
|
||||||
|
# Check that the package is installed. If it is not,
|
||||||
|
# the following command will fail.
|
||||||
|
if (script_run("rpm -q dnf5", timeout => 20)) {
|
||||||
|
# FIXME: When DNF5 is part of Fedora, change this to die instead.
|
||||||
|
record_soft_failure("The dnf5 package is not installed. I am installing it now.");
|
||||||
|
# Install the package, so we can move forward.
|
||||||
|
assert_script_run("dnf install -y dnf5 dnf5-plugins", timeout => 180);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# This is here as notice. When we are seeing this, DNF5 has become
|
||||||
|
# the part of Fedora.
|
||||||
|
record_info("DNF5 is already installed on the system.");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Currently, DNF5 is being invoked by calling "dnf5". We assume,
|
||||||
|
# that later it will be changed into "dnf" when DNF4 will be gone.
|
||||||
|
my $dnfversion = script_output("dnf --version");
|
||||||
|
if ("dnf5" =~ $dnfversion) {
|
||||||
|
record_info("DNF version", "The 'dnf' command uses version 5.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
record_info("DNF version", "The 'dnf' command uses version 4.");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {fatal => 1, milestone => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
103
tests/dnf5/basic_sanity.pm
Normal file
103
tests/dnf5/basic_sanity.pm
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
use dnf;
|
||||||
|
|
||||||
|
# This script follows the basic_sanity test as described
|
||||||
|
# https://fedoraproject.org/wiki/QA:Testcase_DNF_basic_sanity
|
||||||
|
|
||||||
|
|
||||||
|
# We select some packages and we'll do the installation tests.
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
my @packages = ("fortune-mod", "mc", "cowsay", "python3-ipython");
|
||||||
|
|
||||||
|
# Install packages.
|
||||||
|
for my $package (@packages) {
|
||||||
|
install($package);
|
||||||
|
# Check if installed
|
||||||
|
die("$package not installed") unless (check($package));
|
||||||
|
}
|
||||||
|
|
||||||
|
# Remove packages.
|
||||||
|
for my $package (@packages) {
|
||||||
|
remove($package);
|
||||||
|
# Check if removed
|
||||||
|
die("$package not removed") if (check($package));
|
||||||
|
}
|
||||||
|
|
||||||
|
# Reinstall package.
|
||||||
|
#
|
||||||
|
# We will install elinks again and check that
|
||||||
|
# its executable is present on the system.
|
||||||
|
# Then we will delete the executable and check
|
||||||
|
# that it is not on the system any more.
|
||||||
|
# Then we will reinstall the package and check
|
||||||
|
# that everything is ok again.
|
||||||
|
install("elinks");
|
||||||
|
# Check that it is there
|
||||||
|
assert_script_run("which elinks");
|
||||||
|
# Remove the elinks executable
|
||||||
|
assert_script_run("rm -f /usr/bin/elinks");
|
||||||
|
# Check again for non-existence
|
||||||
|
assert_script_run("! which elinks");
|
||||||
|
# Reinstall
|
||||||
|
reinstall("elinks");
|
||||||
|
# Check once more for existence
|
||||||
|
assert_script_run("which elinks");
|
||||||
|
|
||||||
|
# Download package
|
||||||
|
# Create a download directory and cd into it.
|
||||||
|
assert_script_run("mkdir /download && cd /download");
|
||||||
|
assert_script_run("rm -f *");
|
||||||
|
# Download the package
|
||||||
|
assert_script_run("dnf5 download -y mc");
|
||||||
|
# Check that the rpm file has been downloaded
|
||||||
|
assert_script_run("ls mc*.rpm");
|
||||||
|
# Remove everything
|
||||||
|
assert_script_run("rm -f *");
|
||||||
|
|
||||||
|
# Download package and its dependencies
|
||||||
|
# Download the package
|
||||||
|
if (script_run("dnf5 download -y --resolve mc")) {
|
||||||
|
# FIXME: Currently, this command will result in an error, because the --resolve command
|
||||||
|
# does not work as expected. Bug has been reported.
|
||||||
|
record_soft_failure("Bug already reported: https://bugzilla.redhat.com/show_bug.cgi?id=2187981");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Check that the rpm files have been downloaded
|
||||||
|
assert_script_run("ls mc*.rpm");
|
||||||
|
assert_script_run("ls slang*.rpm");
|
||||||
|
}
|
||||||
|
# Remove the downloaded packages.
|
||||||
|
assert_script_run("rm -f *");
|
||||||
|
|
||||||
|
# Download package and all dependencies. There should
|
||||||
|
# be more than 200 files downloaded.
|
||||||
|
# Download the packages
|
||||||
|
if (script_run("dnf5 download -y --resolve --alldeps mc")) {
|
||||||
|
# See above.
|
||||||
|
record_soft_failure("Bug already reported: https://bugzilla.redhat.com/show_bug.cgi?id=2187981");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
# Check that the rpm files have been downloaded, but we will
|
||||||
|
# not be doing an exact comparison of all the dependencies,
|
||||||
|
# because they might vary through time. Instead, we will only
|
||||||
|
# check that a reasonably big number of rpms have been downloaded.
|
||||||
|
my $package_count = script_output("ls | wc -l");
|
||||||
|
if ($package_count < 200) {
|
||||||
|
die("The count of all dependencies is less than expected.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Remove everything
|
||||||
|
assert_script_run("rm -f *");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {always_rollback => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
46
tests/dnf5/cache.pm
Normal file
46
tests/dnf5/cache.pm
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
use dnf;
|
||||||
|
|
||||||
|
# This script will make sure that DNF5 is able to
|
||||||
|
# clean cache and recreate it according to
|
||||||
|
# https://fedoraproject.org/wiki/QA:Testcase_DNF_makecache_and_clean.
|
||||||
|
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# The cache should be clean at this moment, so we will
|
||||||
|
# check that there are no records in libdnf5 directory.
|
||||||
|
#
|
||||||
|
# We will create the cache and check that the data is
|
||||||
|
# there.
|
||||||
|
assert_script_run("dnf5 -y makecache");
|
||||||
|
# We will see how many lines there are in the
|
||||||
|
# directory listings when metadata is present.
|
||||||
|
my $metadata = script_output("ls /var/cache/libdnf5/* | wc -l");
|
||||||
|
#
|
||||||
|
# We will clean the metadata.
|
||||||
|
assert_script_run("dnf5 -y clean metadata");
|
||||||
|
# And we will check again. Now, the metadata
|
||||||
|
# count should be much less, because the
|
||||||
|
# directories should be empty.
|
||||||
|
my $postdelete = script_output("ls /var/cache/libdnf5/* | wc -l");
|
||||||
|
if ($postdelete >= $metadata) {
|
||||||
|
die("The created metadata had $metadata lines and after deletion they have $postdelete.");
|
||||||
|
}
|
||||||
|
|
||||||
|
# We will clean everything again.
|
||||||
|
assert_script_run("dnf5 -y clean all");
|
||||||
|
assert_script_run("! ls /var/cache/libdnf5/*");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {always_rollback => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
67
tests/dnf5/distro_sync.pm
Normal file
67
tests/dnf5/distro_sync.pm
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
use dnf;
|
||||||
|
|
||||||
|
# This script will make sure that DNF5 is able to
|
||||||
|
# distro sync the system according to
|
||||||
|
# https://fedoraproject.org/wiki/QA:Testcase_DNF_distro-sync.
|
||||||
|
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
my $version = get_var("VERSION");
|
||||||
|
$version = get_var("RAWREL") if ($version eq "Rawhide");
|
||||||
|
# Calculate the version numbers around the current release.
|
||||||
|
my $higher = $version + 1;
|
||||||
|
my $lower = $version - 1;
|
||||||
|
|
||||||
|
# Install the packages that we will work with.
|
||||||
|
assert_script_run("dnf5 install -y mc elinks");
|
||||||
|
|
||||||
|
# Downgrade one of the packages.
|
||||||
|
assert_script_run("dnf5 downgrade -y mc --releasever=$lower");
|
||||||
|
|
||||||
|
# Upgrade the other package using the rawhide repositories.
|
||||||
|
if ($version ne "Rawhide") {
|
||||||
|
assert_script_run("dnf5 install -y fedora-repos-rawhide");
|
||||||
|
}
|
||||||
|
assert_script_run("dnf5 upgrade -y elinks --enablerepo=rawhide");
|
||||||
|
|
||||||
|
# Check the versions.
|
||||||
|
my $mcver = script_output("rpm -qa mc");
|
||||||
|
my $elinksver = script_output("rpm -qa elinks");
|
||||||
|
|
||||||
|
my $lmark = "fc$lower";
|
||||||
|
my $hmark = "fc$higher";
|
||||||
|
unless (index($mcver, $lmark) != -1) {
|
||||||
|
die("The mc package could not be downgraded to $lower version.");
|
||||||
|
}
|
||||||
|
unless (index($elinksver, $hmark) != -1) {
|
||||||
|
die("The elinks package could not be upgraded to $higher version.");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Distro-sync the versions
|
||||||
|
assert_script_run("dnf5 distro-sync -y", timeout => 240);
|
||||||
|
|
||||||
|
# Check the versions.
|
||||||
|
$mcver = script_output("rpm -qa mc");
|
||||||
|
$elinksver = script_output("rpm -qa elinks");
|
||||||
|
|
||||||
|
my $mark = "fc$version";
|
||||||
|
unless (index($mcver, $mark) != -1) {
|
||||||
|
die("The mc package was not synced to the current version.");
|
||||||
|
}
|
||||||
|
unless (index($elinksver, $mark) != -1) {
|
||||||
|
die("The elinks package was not synced to the current version.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {always_rollback => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
104
tests/dnf5/history.pm
Normal file
104
tests/dnf5/history.pm
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
use dnf;
|
||||||
|
|
||||||
|
# This script will make sure that DNF5 is able to
|
||||||
|
# record the history of transactions and that it
|
||||||
|
# can perform various activities based on that.
|
||||||
|
# https://fedoraproject.org/wiki/QA:Testcase_DNF_history
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# Install one package
|
||||||
|
assert_script_run("dnf5 install -y mc");
|
||||||
|
|
||||||
|
# Check that the transaction appears in DNF history.
|
||||||
|
my $output = script_output("dnf5 history list");
|
||||||
|
my $history = parse_list_output($output);
|
||||||
|
my $last = latest_item($history);
|
||||||
|
# Read the last transaction
|
||||||
|
my $transaction = $history->{$last};
|
||||||
|
# Read transaction information
|
||||||
|
my $command = $transaction->[1];
|
||||||
|
my $package = $transaction->[2];
|
||||||
|
# Check for errors.
|
||||||
|
my $errors = [];
|
||||||
|
if ($command ne "install") {
|
||||||
|
push(@$errors, "command should be install but is $command.");
|
||||||
|
}
|
||||||
|
if ($package ne "mc") {
|
||||||
|
push(@$errors, "package should be mc but is $package.");
|
||||||
|
}
|
||||||
|
# Check if errors were recorded.
|
||||||
|
my $ecount = scalar @$errors;
|
||||||
|
if ($ecount > 0) {
|
||||||
|
diag("DNF5 history list errors:");
|
||||||
|
foreach (@$errors) {
|
||||||
|
diag($_);
|
||||||
|
}
|
||||||
|
die("The last transaction in the history differs from what we expected.");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check that info can be listed about the last transaction.
|
||||||
|
$errors = [];
|
||||||
|
$output = script_output("dnf5 history info $last");
|
||||||
|
my $info = parse_history_info($output);
|
||||||
|
if ($info->{User} != 0) {
|
||||||
|
push(@$errors, "user");
|
||||||
|
}
|
||||||
|
if ($info->{Status} ne "Ok") {
|
||||||
|
push(@$errors, "status");
|
||||||
|
}
|
||||||
|
if ($info->{Description} ne "dnf5 install -y mc") {
|
||||||
|
push(@$errors, "description");
|
||||||
|
}
|
||||||
|
if ($info->{"Transaction ID"} ne $last) {
|
||||||
|
push(@$errors, "id");
|
||||||
|
}
|
||||||
|
$ecount = scalar @$errors;
|
||||||
|
if ($ecount > 0) {
|
||||||
|
diag("DNF5 history info errors:");
|
||||||
|
foreach (@$errors) {
|
||||||
|
diag($_);
|
||||||
|
}
|
||||||
|
die("The last transaction info differs from what we expected");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check that the transaction can be undone and redone.
|
||||||
|
$errors = [];
|
||||||
|
|
||||||
|
# FIXME WARNING:
|
||||||
|
# The subcommands redo, undo, rollback, etc. are not implemented
|
||||||
|
# yet, so we cannot use them. However, we will try to use them
|
||||||
|
# anyway and let the test softfail if they cannot be used.
|
||||||
|
# Once it stops softfailing, we'll know that they have been
|
||||||
|
# implemented and we'll start checking more strictly.
|
||||||
|
#
|
||||||
|
# See, if subcommands work.
|
||||||
|
my @subcommands = qw(undo redo rollback);
|
||||||
|
foreach (@subcommands) {
|
||||||
|
my $result = script_run("dnf5 history $_ -y $last");
|
||||||
|
# Error code 2 means that the command is not supported
|
||||||
|
# yet and that usage info was returned instead.
|
||||||
|
if ($result == 2) {
|
||||||
|
diag("DNF5 history: $_ is probably not implemented yet.");
|
||||||
|
push(@$errors, $_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# See, if we have errors and softfail if we do.
|
||||||
|
$ecount = scalar @$errors;
|
||||||
|
if ($ecount > 0) {
|
||||||
|
record_soft_failure("The DNF5 subcommands could not be run properly. Check the logs for more info.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {always_rollback => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
62
tests/dnf5/info.pm
Normal file
62
tests/dnf5/info.pm
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
use dnf;
|
||||||
|
|
||||||
|
|
||||||
|
# This script tests if information can be display about a package.
|
||||||
|
# https://fedoraproject.org/wiki/QA:Testcase_DNF_info
|
||||||
|
# For this test we will parse a package NEVRA
|
||||||
|
# and then find out whether the package info matches
|
||||||
|
# the package.
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# Install the 'mc' package
|
||||||
|
assert_script_run("dnf5 install -y mc");
|
||||||
|
|
||||||
|
# Check that info can be listed about the last transaction.
|
||||||
|
my $errors = []; # This will be used to collect possible errors.
|
||||||
|
# Get the info output.
|
||||||
|
my $output = script_output("dnf5 info mc");
|
||||||
|
# Get the package name from the system.
|
||||||
|
my $pname = script_output("rpm -q mc");
|
||||||
|
|
||||||
|
|
||||||
|
my $info = parse_info($output);
|
||||||
|
my $package = parse_package_name($pname);
|
||||||
|
|
||||||
|
if ($info->{Name} ne $package->{name}) {
|
||||||
|
push(@$errors, "Package name differs.");
|
||||||
|
}
|
||||||
|
if ($info->{Version} ne $package->{version}) {
|
||||||
|
push(@$errors, "Package version differs.");
|
||||||
|
}
|
||||||
|
if ($info->{Release} ne $package->{release}) {
|
||||||
|
push(@$errors, "Package release differs.");
|
||||||
|
}
|
||||||
|
if ($info->{"Architecture"} ne $package->{arch}) {
|
||||||
|
push(@$errors, "Package architecture differs.");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now, go over the recorded errors and die if you
|
||||||
|
# find any.
|
||||||
|
my $ecount = scalar @$errors;
|
||||||
|
if ($ecount > 0) {
|
||||||
|
diag("DNF5 history info errors:");
|
||||||
|
foreach (@$errors) {
|
||||||
|
diag($_);
|
||||||
|
}
|
||||||
|
die("The info differs from what we expected");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {always_rollback => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
119
tests/dnf5/list.pm
Normal file
119
tests/dnf5/list.pm
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
use dnf;
|
||||||
|
|
||||||
|
# This script will make sure that DNF5 is able to
|
||||||
|
# list the packages via dnf list.
|
||||||
|
# http://fedoraproject.org/wiki/QA:Testcase_DNF_list
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# First, we will look for available packages. This search should result
|
||||||
|
# in a list of all available packages which is almost 70000 in standard
|
||||||
|
# Fedora repositories.
|
||||||
|
# We will list all those packages and count them via wc, then we will
|
||||||
|
# decide what to do with them.
|
||||||
|
my $count = script_output("dnf5 list --available | wc -l", timeout => 120);
|
||||||
|
# Now, if there are more than 60000 packages, we assume that it is correct.
|
||||||
|
if ($count > 60000) {
|
||||||
|
record_info("Packages counted", "It seems that the number of available packages is realistic ($count)");
|
||||||
|
}
|
||||||
|
elsif ($count > 20000) {
|
||||||
|
record_info("Warning", "The number of available packages seems a little to low. Check that repositories are correctly enabled.");
|
||||||
|
}
|
||||||
|
elsif ($count > 1000) {
|
||||||
|
record_soft_failure("The number of available packages is critically low, check the repositories.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("The number of available packages does not meet any expectations, either there are no repositories or the tested command does not work correctly.");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Also list available packages and look for a certain keyword to see that real packages are listed
|
||||||
|
assert_script_run("dnf5 list --available | grep firefox");
|
||||||
|
assert_script_run("dnf5 list --available | grep vim");
|
||||||
|
assert_script_run("dnf5 list --available | grep bash");
|
||||||
|
assert_script_run("dnf5 list --available | grep python3");
|
||||||
|
assert_script_run("dnf5 list --available | grep gimp");
|
||||||
|
|
||||||
|
# Second, we will list installed packages. The Fedora custom installation has slightly above 400
|
||||||
|
# packages, if the count matches, we can assume the command worked correctly.
|
||||||
|
$count = script_output("dnf5 list --installed | wc -l", timeout => 60);
|
||||||
|
if ($count > 400) {
|
||||||
|
record_info("Packages counted", "It seems that the number of listed packages is realistic ($count).");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("The number of installed packages is too low, the tested system might be corrupted.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Third, we will try to list a single package. If grep finds the name, we can assume that the
|
||||||
|
# package was listed.
|
||||||
|
assert_script_run("dnf5 list inkscape | grep inkscape");
|
||||||
|
|
||||||
|
# The --showduplicates switch shows all available packages. The output is divided into Installed
|
||||||
|
# and Available packages. With the kernel package, we know that it is installed for sure.
|
||||||
|
# There will be one installed package and one or more available packages. If more, we know
|
||||||
|
# the command works as expected.
|
||||||
|
my $output = script_output("dnf5 list kernel --showduplicates");
|
||||||
|
my @olist = split("\n", $output);
|
||||||
|
my ($installed, $available) = (0, 0);
|
||||||
|
my $a = 0;
|
||||||
|
# Let's go over the output
|
||||||
|
foreach (@olist) {
|
||||||
|
# Switch to installed if the label found.
|
||||||
|
if ($_ =~ /Installed/) {
|
||||||
|
$a = 0;
|
||||||
|
}
|
||||||
|
# Switch to available if the label found.
|
||||||
|
elsif ($_ =~ /Available/) {
|
||||||
|
$a = 1;
|
||||||
|
}
|
||||||
|
# When package line found, count it based on
|
||||||
|
# which mode we are in.
|
||||||
|
else {
|
||||||
|
if ($_ =~ /kernel/) {
|
||||||
|
$installed += 1 if ($a == 0);
|
||||||
|
$available += 1 if ($a == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# Now, die under certain conditions
|
||||||
|
if ($installed != 1) {
|
||||||
|
die("Either no kernel or more kernels are installed which indicates an error in the command.");
|
||||||
|
}
|
||||||
|
if ($available == 1) {
|
||||||
|
record_soft_failure("There is only one available kernel package which is not an error, but we could not test if --showduplicates really work either.");
|
||||||
|
}
|
||||||
|
elsif ($available > 1) {
|
||||||
|
record_info("Argument OK", "The --showduplicates argument works normally.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
die("There are problems with the --showduplicates argument.");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Now, we test that we can list packages with --recent, we will grep for the word updates
|
||||||
|
# because that is the repository where new packages are expected.
|
||||||
|
assert_script_run("dnf5 list --recent | grep updates");
|
||||||
|
|
||||||
|
# And test that we can list new updates with --updates, however we will not know if
|
||||||
|
# there will be updates, so just running the command successfully will do.
|
||||||
|
assert_script_run("dnf5 list --updates | grep 'Repositories loaded'");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {always_rollback => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
my $output = `dnf5 search python3-koza`;
|
||||||
|
print($output);
|
||||||
|
if ($output =~ /No matches found/) {
|
||||||
|
print("Package not found.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
54
tests/dnf5/repolist.pm
Normal file
54
tests/dnf5/repolist.pm
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
use dnf;
|
||||||
|
|
||||||
|
# This script will make sure that DNF5 is able to
|
||||||
|
# perform repolist and repoquery --info transactions.
|
||||||
|
# https://fedoraproject.org/wiki/QA:Testcase_DNF_repoquery
|
||||||
|
# We will not rely on exact repositories in this test,
|
||||||
|
# but rather if there is some output and how big the
|
||||||
|
# output is. The repositories might change with various
|
||||||
|
# releases and this would break the tests.
|
||||||
|
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# Let's take the total number of available repositories.
|
||||||
|
my $total = script_output("dnf5 repolist --all | wc -l");
|
||||||
|
# The output has one description line in the beginning that
|
||||||
|
# we should not calculate into the total count of repositories,
|
||||||
|
# therefore:
|
||||||
|
$total -= 1;
|
||||||
|
|
||||||
|
# Now let's the number of enabled repositories
|
||||||
|
my $enabled = script_output("dnf5 repolist | wc -l");
|
||||||
|
$enabled -= 1; # See above
|
||||||
|
|
||||||
|
# And finally the number of disabled repositories
|
||||||
|
my $disabled = script_output("dnf5 repolist --disabled | wc -l");
|
||||||
|
$disabled -= 1; # See above
|
||||||
|
|
||||||
|
# It seems logical that enable plus disabled should make all.
|
||||||
|
my $added = $enabled + $disabled;
|
||||||
|
diag("There are $enabled enabled repos and $disabled repos and $total all repos.");
|
||||||
|
if ($added != $total) {
|
||||||
|
die("The addition of enabled and disabled repositories does not match the count of all repos.");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's also check that at least 'fedora' and 'updates'
|
||||||
|
# are part of enabled repositories.
|
||||||
|
my $output = script_output("dnf5 repolist");
|
||||||
|
my @repos = qw(fedora updates);
|
||||||
|
confirm_in_output($output, \@repos);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {always_rollback => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
57
tests/dnf5/repoquery.pm
Normal file
57
tests/dnf5/repoquery.pm
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
use dnf;
|
||||||
|
|
||||||
|
# This script will make sure that DNF5 is able to
|
||||||
|
# perform several repoquery searches.
|
||||||
|
# https://fedoraproject.org/wiki/QA:Testcase_DNF_repoquery
|
||||||
|
# As of now, the test is based on the examples of
|
||||||
|
# the repoquery command stated in the DNF documentation
|
||||||
|
# at https://dnf.readthedocs.io/en/latest/command_ref.html#repoquery-command
|
||||||
|
# With DNF5 many options are still not implemented. We can add more
|
||||||
|
# querries and commands as needed later.
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# Let's take the total number of available packages in the repos.
|
||||||
|
my $total = script_output("dnf5 repoquery | wc -l", timeout => 60);
|
||||||
|
# The number of packages in default repositories is above 70000,
|
||||||
|
# so if the $total lies there, we could assume that the command
|
||||||
|
# returned something reasonable and thus works correctly:
|
||||||
|
if ($total < 10000) {
|
||||||
|
die("The number of packages is unrealistically low.");
|
||||||
|
}
|
||||||
|
elsif ($total < 70000) {
|
||||||
|
record_soft_failure("The number of packages is lower than we expected (70000).");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Let's check the repoquery can be limited with a search pattern.
|
||||||
|
my $output = script_output("dnf5 repoquery 'light*'", timeout => 60);
|
||||||
|
confirm_in_lines($output, "light");
|
||||||
|
$output = script_output("dnf5 repoquery '*.noarch'", timeout => 60);
|
||||||
|
confirm_in_lines($output, "noarch");
|
||||||
|
|
||||||
|
# Let's check the repoquery can show what a meta package provides.
|
||||||
|
$output = script_output("dnf repoquery --whatprovides webserver", timeout => 60);
|
||||||
|
my @keywords = qw(caddy httpd lighttpd nginx);
|
||||||
|
# Check that correct packages are returned.
|
||||||
|
confirm_in_output($output, \@keywords);
|
||||||
|
|
||||||
|
# Let's check the repoquery can show what a package requires.
|
||||||
|
$output = script_output("dnf repoquery --requires lighttpd", timeout => 60);
|
||||||
|
@keywords = qw(libcrypt libnettle libuuid lighttpd-filesystems systemd);
|
||||||
|
# Check that correct packages are returned.
|
||||||
|
confirm_in_output($output, \@keywords);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {always_rollback => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
29
tests/dnf5/search.pm
Normal file
29
tests/dnf5/search.pm
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
use dnf;
|
||||||
|
|
||||||
|
# This script will make sure that DNF5 is able to
|
||||||
|
# search repositories and get package info.
|
||||||
|
# https://fedoraproject.org/wiki/QA:Testcase_DNF_search
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# We will search for the existing package, python3-tkinter
|
||||||
|
# might be a safe option as python is always ready on Fedora.
|
||||||
|
#
|
||||||
|
assert_script_run("dnf5 search python3-tkinter | grep tkinter", timeout => 60);
|
||||||
|
# The third check checks that "No matches found" string is shown
|
||||||
|
# when we attempt to look for a non-existing package.
|
||||||
|
assert_script_run("dnf5 search jezibaba | grep 'No matches found'", timeout => 60);
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {always_rollback => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
45
tests/dnf5/swap.pm
Normal file
45
tests/dnf5/swap.pm
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
use dnf;
|
||||||
|
|
||||||
|
# This script will make sure that DNF5 is able to
|
||||||
|
# swap (remove and install) two packages that are
|
||||||
|
# conflicting with each other, so we can install
|
||||||
|
# and remove them in one single command.
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# Install one package
|
||||||
|
assert_script_run("dnf5 install -y i3", timeout => 180);
|
||||||
|
|
||||||
|
# Check that the package is installed
|
||||||
|
assert_script_run("rpm -q i3");
|
||||||
|
|
||||||
|
# The I3 package requires the `i3-config` or `i3-config-fedora`
|
||||||
|
# to be installed. By default the first one should be installed.
|
||||||
|
# Let's check
|
||||||
|
assert_script_run("rpm -q i3-config");
|
||||||
|
|
||||||
|
# Try to install the `i3-config-fedora` package ->
|
||||||
|
# this time the operation should fail because the
|
||||||
|
# packages conflict with each other.
|
||||||
|
assert_script_run("! dnf5 install -y i3-config-fedora");
|
||||||
|
|
||||||
|
# Swap packages. The operation should run successfully.
|
||||||
|
assert_script_run("dnf5 swap -y i3-config i3-config-fedora", timeout => 180);
|
||||||
|
|
||||||
|
# Check that the first package was removed and the second installed.
|
||||||
|
assert_script_run("! rpm -q i3-config");
|
||||||
|
assert_script_run("rpm -q i3-config-fedora");
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {always_rollback => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
35
tests/dnf5/upgrade.pm
Normal file
35
tests/dnf5/upgrade.pm
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
use base "installedtest";
|
||||||
|
use strict;
|
||||||
|
use testapi;
|
||||||
|
use utils;
|
||||||
|
use packagetest;
|
||||||
|
use dnf;
|
||||||
|
|
||||||
|
# This script will make sure that DNF5 is able to
|
||||||
|
# upgrade the system when it has some older packages.
|
||||||
|
# https://fedoraproject.org/wiki/QA:Testcase_DNF_basic_update_packages
|
||||||
|
#
|
||||||
|
# This is an adaptation from base_update_cli.
|
||||||
|
|
||||||
|
|
||||||
|
sub run {
|
||||||
|
my $self = shift;
|
||||||
|
|
||||||
|
# Install and verify an outdated package.
|
||||||
|
prepare_test_packages;
|
||||||
|
verify_installed_packages;
|
||||||
|
|
||||||
|
# Upgrade system
|
||||||
|
assert_script_run("dnf5 upgrade -y pandoc-common", timeout => 120);
|
||||||
|
|
||||||
|
# Check the versions.
|
||||||
|
verify_updated_packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_flags {
|
||||||
|
return {always_rollback => 1};
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set sw=4 et:
|
Loading…
Reference in New Issue
Block a user