ソースを参照

Add non-regression test-suite for update-alternatives

* scripts/t/900_update_alternatives.t: New test-suite for
update-alternatives.
* scripts/Makefile.am: Add the previous file.
Raphael Hertzog 17 年 前
コミット
79bf3c4054
共有3 個のファイルを変更した274 個の追加1 個の削除を含む
  1. 6 0
      ChangeLog
  2. 2 1
      scripts/Makefile.am
  3. 266 0
      scripts/t/900_update_alternatives.t

+ 6 - 0
ChangeLog

@@ -3,6 +3,12 @@
 	* lib/dpkg.h (ohshitvb): Remove function prototype.
 	* lib/ehandle.c (ohshitvb): Remove function definition.
 
+2009-02-06  Raphael Hertzog  <hertzog@debian.org>
+
+	* scripts/t/900_update_alternatives.t: New test-suite for
+	update-alternatives.
+	* scripts/Makefile.am: Add the previous file.
+
 2009-02-06  Raphael Hertzog  <hertzog@debian.org>
 
 	* scripts/update-alternatives.pl: Deal with empty

+ 2 - 1
scripts/Makefile.am

@@ -78,7 +78,8 @@ EXTRA_DIST = \
 	t/600_Dpkg_Changelog/shadow \
 	t/700_Dpkg_Control.t \
 	t/700_Dpkg_Control/control-1 \
-	t/800_Dpkg_IPC.t
+	t/800_Dpkg_IPC.t \
+	t/900_update_alternatives.t
 
 CLEANFILES = \
 	$(bin_SCRIPTS) $(sbin_SCRIPTS) $(changelog_SCRIPTS) \

+ 266 - 0
scripts/t/900_update_alternatives.t

@@ -0,0 +1,266 @@
+# -*- mode: cperl;-*-
+
+use Dpkg::IPC;
+use File::Spec;
+use Test::More;
+
+use strict;
+use warnings;
+
+my $srcdir = $ENV{srcdir} || '.';
+my $admindir = File::Spec->rel2abs("$srcdir/t.tmp/ua/admindir"),
+my $altdir = File::Spec->rel2abs("$srcdir/t.tmp/ua/alternatives");
+my $bindir = File::Spec->rel2abs("$srcdir/t.tmp/ua/bin");
+# XXX: switch to version without .pl
+my @ua = ("$srcdir/update-alternatives.pl", "--quiet", "--admindir",
+	  "$admindir", "--altdir", "$altdir");
+
+my $main_link = "$bindir/generic-test";
+my $main_name = "generic-test";
+my @choices = (
+    {
+	path => "/bin/true",
+	priority => 20,
+	slaves => [
+	    {
+		"link" => "$bindir/slave2",
+		name => "slave2",
+		path => "/bin/cat",
+	    },
+	    {
+		"link" => "$bindir/slave1",
+		name => "slave1",
+		path => "/bin/yes",
+	    },
+	],
+    },
+    {
+        path => "/bin/false",
+        priority => 10,
+        slaves => [
+	    {
+		"link" => "$bindir/slave1",
+		name => "slave1",
+		path => "/bin/date",
+	    },
+        ],
+    },
+    {
+        path => "/bin/sleep",
+        priority => 5,
+        slaves => [],
+    },
+);
+my $nb_slaves = 2;
+plan tests => (4 * ($nb_slaves + 1) + 2) * 18 # number of check_choices
+		+ 39;			      # rest
+
+sub cleanup {
+    system("rm -rf $srcdir/t.tmp/ua && mkdir -p $admindir && mkdir -p $altdir");
+    system("mkdir -p $bindir/more");
+}
+
+sub call_ua {
+    my ($params, %opts) = @_;
+    fork_and_exec("exec" => [ @ua, @$params ], nocheck => 1,
+		  wait_child => 1, env => { LC_ALL => "C" }, %opts);
+    if ($opts{"expect_failure"}) {
+	ok($? != 0, "update-alternatives @$params did not fail.");
+    } else {
+	ok($? == 0, "update-alternatives @$params failed.");
+    }
+}
+
+sub install_choice {
+    my ($id, %opts) = @_;
+    my $alt = $choices[$id];
+    my @params = ("--install", "$main_link", "$main_name",
+		  $alt->{path}, $alt->{priority});
+    foreach my $slave (@{ $alt->{slaves} }) {
+	push @params, "--slave", $slave->{"link"}, $slave->{"name"}, $slave->{"path"};
+    }
+    call_ua(\@params, %opts);
+}
+
+sub remove_choice {
+    my ($id, %opts) = @_;
+    my $alt = $choices[$id];
+    my @params = ("--remove", $main_name, $alt->{path});
+    call_ua(\@params, %opts);
+}
+
+sub set_choice {
+    my ($id, %opts) = @_;
+    my $alt = $choices[$id];
+    my @params = ("--set", $main_name, $alt->{path});
+    call_ua(\@params, %opts);
+}
+
+sub config_choice {
+    my ($id, %opts) = @_;
+    my ($input,	$output) = ("", "");
+    if (defined $id) {
+	$input = $id + 1;
+    }
+    $input .= "\n";
+    $opts{from_string} = \$input;
+    $opts{to_string} = \$output;
+    my @params = ("--config", $main_name);
+    call_ua(\@params, %opts);
+    #print STDERR "Output of @params for choice $input $output\n";
+}
+
+sub get_slaves_status {
+    my ($id) = @_;
+    my %slaves;
+    # None of the slaves are installed
+    foreach my $alt (@choices) {
+	for(my $i = 0; $i < @{$alt->{slaves}}; $i++) {
+	    $slaves{$alt->{slaves}[$i]{name}} = $alt->{slaves}[$i];
+	    $slaves{$alt->{slaves}[$i]{name}}{"installed"} = 0;
+	}
+    }
+    # except those of the current alternative
+    if (defined($id)) {
+	my $alt = $choices[$id];
+	for(my $i = 0; $i < @{$alt->{slaves}}; $i++) {
+	    $slaves{$alt->{slaves}[$i]{name}} = $alt->{slaves}[$i];
+	    $slaves{$alt->{slaves}[$i]{name}}{"installed"} = 1;
+	}
+    }
+    return sort { $a->{name} cmp $b->{name} } values %slaves;
+}
+
+sub check_link {
+    my ($link, $value, $msg) = @_;
+    ok(-l $link, "$msg: $link disappeared.");
+    is(readlink($link), $value, "$link doesn't point to $value.");
+}
+sub check_no_link {
+    my ($link, $msg) = @_;
+    lstat($link);
+    ok(!-e _, "$msg: $link still exists.");
+    ok(1, "fake test"); # Same number of tests as check_link
+}
+
+sub check_slaves {
+    my ($id, $msg) = @_;
+    foreach my $slave (get_slaves_status($id)) {
+	if ($slave->{installed}) {
+	    check_link("$altdir/$slave->{name}", $slave->{path}, $msg);
+	    check_link($slave->{"link"}, "$altdir/$slave->{name}", $msg);
+	} else {
+	    check_no_link("$altdir/$slave->{name}", $msg);
+	    check_no_link($slave->{"link"}, $msg);
+	}
+    }
+}
+# (4 * (nb_slaves+1) + 2) tests in each check_choice() call
+sub check_choice {
+    my ($id, $mode, $msg) = @_;
+    my $output;
+    if (defined $id) {
+	# Check status
+	call_ua([ "--query", "$main_name" ], to_string => \$output);
+	ok(($output =~ /^Status: $mode$/im), "$msg: status is not $mode.");
+	# Check links
+	my $alt = $choices[$id];
+	check_link("$altdir/$main_name", $alt->{path}, $msg);
+	check_link($main_link, "$altdir/$main_name", $msg);
+	check_slaves($id, $msg);
+    } else {
+	call_ua([ "--query", "$main_name" ], to_string => \$output, expect_failure => 1);
+	ok($output =~ /No alternatives/, "$msg: bad error message for --query.");
+	# Check that all links have disappeared
+	check_no_link("$altdir/$main_name", $msg);
+	check_no_link($main_link, $msg);
+	check_slaves(undef, $msg);
+    }
+}
+
+### START OF TESTS
+cleanup();
+# removal when not installed should not fail
+remove_choice(0);
+# successive install in auto mode
+install_choice(1);
+check_choice(1, "auto", "initial install 1");
+install_choice(2); # 2 is lower prio, stays at 1
+check_choice(1, "auto", "initial install 2");
+install_choice(0); # 0 is higher priority
+check_choice(0, "auto", "initial install 3");
+# manual change with set
+set_choice(2);
+check_choice(2, "manual", "manual update with --set"); # test #388313
+remove_choice(2);
+check_choice(0, "auto", "remove manual, back to auto");
+remove_choice(0);
+check_choice(1, "auto", "remove best");
+remove_choice(1);
+check_choice(undef, "", "no alternative left");
+# single choice in manual mode, to be removed
+install_choice(1);
+set_choice(1);
+check_choice(1, "manual", "single manual choice");
+remove_choice(1);
+check_choice(undef, "", "removal single manual");
+# check auto-recovery of user mistakes (#100135)
+install_choice(1);
+ok(unlink("$bindir/generic-test"), "failed removal");
+ok(unlink("$bindir/slave1"), "failed removal");
+install_choice(1);
+check_choice(1, "auto", "recreate links in auto mode");
+set_choice(1);
+ok(unlink("$bindir/generic-test"), "failed removal");
+ok(unlink("$bindir/slave1"), "failed removal");
+install_choice(1);
+check_choice(1, "manual", "recreate links in manual mode");
+# check recovery of /etc/alternatives/*
+install_choice(0);
+ok(unlink("$altdir/generic-test"), "failed removal");
+install_choice(1);
+check_choice(0, "auto", "<altdir>/generic-test lost, back to auto");
+# test --config
+# TODO: for now order of choices in config depends on order of --install calls
+# it's not very "test-friendly"
+config_choice(1);
+check_choice(0, "manual", "config to best but manual");
+config_choice(0);
+check_choice(1, "manual", "config to manual");
+config_choice(-1);
+check_choice(0, "auto", "config auto");
+
+# test rename of links
+install_choice(0);
+my $old_slave = $choices[0]{"slaves"}[0]{"link"};
+my $old_link = $main_link;
+$choices[0]{"slaves"}[0]{"link"} = "$bindir/more/generic-slave";
+$main_link = "$bindir/more/mytest";
+install_choice(0);
+check_choice(0, "auto", "test rename of links");
+check_no_link($old_link, "test rename of links");
+check_no_link($old_slave, "test rename of links");
+# rename with installing other alternatives
+$old_link = $main_link;
+$main_link = "$bindir/generic-test";
+install_choice(1);
+check_choice(0, "auto", "rename link");
+check_no_link($old_link, "rename link");
+# rename with lost file
+unlink($old_slave);
+$old_slave = $choices[0]{"slaves"}[0]{"link"};
+$choices[0]{"slaves"}[0]{"link"} = "$bindir/generic-slave-bis";
+install_choice(0);
+check_choice(0, "auto", "rename lost file");
+check_no_link($old_slave, "rename lost file");
+# test install with empty admin file (#457863)
+cleanup();
+system("touch $admindir/generic-test");
+install_choice(0);
+# test install with garbage admin file
+cleanup();
+system("echo garbage > $admindir/generic-test");
+install_choice(0, error_to_file => "/dev/null", expect_failure => 1);
+
+# TODO: add checks for invalid values of parameters, add checks for
+# usage of links as both master and slave