Dpkg::Vendor::Debian: Move time64 buildflags feature from future to abi
[dpkg.git] / utils / t / update_alternatives.t
blobef7d66f66a9bc843f9dd523322e914a0cff81bdf
1 #!/usr/bin/perl
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program. If not, see <https://www.gnu.org/licenses/>.
16 use strict;
17 use warnings;
19 use Test::More;
21 use File::Spec;
23 use Dpkg::IPC;
24 use Dpkg::File qw(file_slurp);
25 use Dpkg::Path qw(find_command);
27 my $srcdir = $ENV{srcdir} || '.';
28 my $tmpdir = 't.tmp/update_alternatives';
29 my $admindir = File::Spec->rel2abs("$tmpdir/admindir"),
30 my $altdir = File::Spec->rel2abs("$tmpdir/alternatives");
31 my $bindir = File::Spec->rel2abs("$tmpdir/bin");
32 my @ua = ("$ENV{builddir}/update-alternatives", '--log', '/dev/null',
33 '--quiet', '--admindir', "$admindir", '--altdir', "$altdir");
35 my $rootdir_envvar = $ENV{UA_ROOTDIR_ENVVAR} // 'DPKG_ROOT';
36 my $admindir_envvar = $ENV{UA_ADMINDIR_ENVVAR} // 'DPKG_ADMINDIR';
38 delete $ENV{$rootdir_envvar};
39 delete $ENV{$admindir_envvar};
41 my %paths = (
42 true => find_command('true'),
43 false => find_command('false'),
44 yes => find_command('yes'),
45 cat => find_command('cat'),
46 date => find_command('date'),
47 sleep => find_command('sleep'),
50 if (! -x "$ENV{builddir}/update-alternatives") {
51 plan skip_all => 'update-alternatives not available';
52 exit(0);
55 my $main_link = "$bindir/generic-test";
56 my $main_name = 'generic-test';
57 my @choices = (
59 path => $paths{true},
60 priority => 20,
61 slaves => [
63 link => "$bindir/slave2",
64 name => 'slave2',
65 path => $paths{cat},
68 link => "$bindir/slave3",
69 name => 'slave3',
70 path => $paths{cat},
73 link => "$bindir/slave1",
74 name => 'slave1',
75 path => $paths{yes},
78 link => "$bindir/slave4",
79 name => 'slave4',
80 path => $paths{cat},
85 path => $paths{false},
86 priority => 10,
87 slaves => [
89 link => "$bindir/slave1",
90 name => 'slave1',
91 path => $paths{date},
96 path => $paths{sleep},
97 priority => 5,
98 slaves => [],
101 my $nb_slaves = 4;
102 plan tests => (4 * ($nb_slaves + 1) + 2) * 26 # number of check_choices
103 + 30 # number of directory checks
104 + 110; # rest
106 sub cleanup {
107 system("rm -rf $tmpdir && mkdir -p $admindir && mkdir -p $altdir");
108 system("mkdir -p $bindir/more");
111 sub call_ua {
112 my ($params, %opts) = @_;
114 my %env;
115 %env = %{delete $opts{env}} if exists $opts{env};
116 my @cmd;
117 if (exists $opts{cmd}) {
118 @cmd = @{delete $opts{cmd}};
119 } else {
120 @cmd = @ua;
123 spawn(exec => [ @cmd, @{$params} ], nocheck => 1,
124 wait_child => 1, env => { LC_ALL => 'C', %env }, %opts);
125 my $test_id = '';
126 $test_id = "$opts{test_id}: " if defined $opts{test_id};
127 if ($opts{expect_failure}) {
128 ok($? != 0, "${test_id}update-alternatives @$params should fail.") or
129 diag("Did not fail as expected: @ua @$params");
130 } else {
131 ok($? == 0, "${test_id}update-alternatives @$params should work.") or
132 diag("Did not succeed as expected: @ua @$params");
136 sub call_ua_dirs {
137 my (%opts) = @_;
139 $opts{cmd} = [ "$ENV{builddir}/update-alternatives" ];
141 my @params;
142 @params = @{delete $opts{params}} if exists $opts{params};
143 push @params, qw(--debug);
144 push @params, qw(--log /dev/null);
145 push @params, qw(--get-selections);
147 die unless exists $opts{expected};
149 my $stderr;
150 my $expected = delete $opts{expected};
151 $opts{to_file} = '/dev/null';
152 $opts{error_to_string} = \$stderr;
154 call_ua(\@params, %opts);
156 ok($stderr =~ $expected, "output '$stderr' does not match expected '$expected'");
159 sub install_choice {
160 my ($id, %opts) = @_;
161 my $alt = $choices[$id];
162 my @params;
163 push @params, @{$opts{params}} if exists $opts{params};
164 push @params, '--install', "$main_link", "$main_name",
165 $alt->{path}, $alt->{priority};
166 foreach my $slave (@{ $alt->{slaves} }) {
167 push @params, '--slave', $slave->{link}, $slave->{name}, $slave->{path};
169 call_ua(\@params, %opts);
172 sub remove_choice {
173 my ($id, %opts) = @_;
174 my $alt = $choices[$id];
175 my @params;
176 push @params, @{$opts{params}} if exists $opts{params};
177 push @params, '--remove', $main_name, $alt->{path};
178 call_ua(\@params, %opts);
181 sub remove_all_choices {
182 my (%opts) = @_;
183 my @params;
184 push @params, @{$opts{params}} if exists $opts{params};
185 push @params, '--remove-all', $main_name;
186 call_ua(\@params, %opts);
189 sub set_choice {
190 my ($id, %opts) = @_;
191 my $alt = $choices[$id];
192 my @params;
193 push @params, @{$opts{params}} if exists $opts{params};
194 push @params, '--set', $main_name, $alt->{path};
195 call_ua(\@params, %opts);
198 sub config_choice {
199 my ($id, %opts) = @_;
200 my ($input, $output) = ('', '');
201 if ($id >= 0) {
202 my $alt = $choices[$id];
203 $input = $alt->{path};
204 } else {
205 $input = '0';
207 $input .= "\n";
208 $opts{from_string} = \$input;
209 $opts{to_string} = \$output;
210 my @params;
211 push @params, @{$opts{params}} if exists $opts{params};
212 push @params, '--config', $main_name;
213 call_ua(\@params, %opts);
216 sub get_slaves_status {
217 my ($id) = @_;
218 my %slaves;
219 # None of the slaves are installed
220 foreach my $alt (@choices) {
221 for my $i (0 .. @{$alt->{slaves}} - 1) {
222 $slaves{$alt->{slaves}[$i]{name}} = $alt->{slaves}[$i];
223 $slaves{$alt->{slaves}[$i]{name}}{installed} = 0;
226 # except those of the current alternative (minus optional slaves)
227 if (defined($id)) {
228 my $alt = $choices[$id];
229 for my $i (0 .. @{$alt->{slaves}} - 1) {
230 $slaves{$alt->{slaves}[$i]{name}} = $alt->{slaves}[$i];
231 if (-e $alt->{slaves}[$i]{path}) {
232 $slaves{$alt->{slaves}[$i]{name}}{installed} = 1;
236 my @slaves = sort { $a->{name} cmp $b->{name} } values %slaves;
238 return @slaves;
241 sub check_link {
242 my ($link, $value, $msg) = @_;
243 ok(-l $link, "$msg: $link disappeared.");
244 is(readlink($link), $value, "$link doesn't point to $value.");
246 sub check_no_link {
247 my ($link, $msg) = @_;
248 lstat($link);
249 ok(!-e _, "$msg: $link still exists.");
250 ok(1, 'fake test'); # Same number of tests as check_link
253 sub check_slaves {
254 my ($id, $msg) = @_;
255 foreach my $slave (get_slaves_status($id)) {
256 if ($slave->{installed}) {
257 check_link("$altdir/$slave->{name}", $slave->{path}, $msg);
258 check_link($slave->{link}, "$altdir/$slave->{name}", $msg);
259 } else {
260 check_no_link("$altdir/$slave->{name}", $msg);
261 check_no_link($slave->{link}, $msg);
265 # (4 * (nb_slaves+1) + 2) tests in each check_choice() call
266 sub check_choice {
267 my ($id, $mode, $msg) = @_;
268 my $output;
269 if (defined $id) {
270 # Check status
271 call_ua([ '--query', "$main_name" ], to_string => \$output, test_id => $msg);
272 my $status = q{};
273 if ($output =~ /^Status: (.*)$/im) {
274 $status = $1;
276 is($status, $mode, "$msg: status is not $mode.");
277 # Check links
278 my $alt = $choices[$id];
279 check_link("$altdir/$main_name", $alt->{path}, $msg);
280 check_link($main_link, "$altdir/$main_name", $msg);
281 check_slaves($id, $msg);
282 } else {
283 call_ua([ '--query', "$main_name" ], error_to_string => \$output,
284 expect_failure => 1, test_id => $msg);
285 ok($output =~ /no alternatives/, "$msg: bad error message for --query.");
286 # Check that all links have disappeared
287 check_no_link("$altdir/$main_name", $msg);
288 check_no_link($main_link, $msg);
289 check_slaves(undef, $msg);
293 ### START OF TESTS
294 cleanup();
296 # check directory overrides
298 my $DEFAULT_ROOTDIR = '';
299 my $DEFAULT_ADMINDIR = $ENV{UA_ADMINDIR_DEFAULT} // '/var/lib/dpkg/alternatives';
301 # ENV_ADMINDIR + defaults
302 call_ua_dirs(
303 env => {
304 $admindir_envvar => '/admindir_env',
306 expected => "root=$DEFAULT_ROOTDIR admdir=/admindir_env",
309 # ENV_ROOT + defaults
310 call_ua_dirs(
311 env => { $rootdir_envvar => '/rootdir_env' },
312 expected => "root=/rootdir_env admdir=/rootdir_env$DEFAULT_ADMINDIR",
315 # ENV_ROOT + ENV_ADMINDIR
316 call_ua_dirs(
317 env => {
318 $rootdir_envvar => '/rootdir_env',
319 $admindir_envvar => '/admindir_env',
321 expected => 'root=/rootdir_env admdir=/admindir_env',
324 # ENV_ADMINDIR + options
325 call_ua_dirs(
326 env => { $admindir_envvar => '/admindir_env' },
327 params => [ qw(--root /rootdir_opt) ],
328 expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
330 call_ua_dirs(
331 env => { $admindir_envvar => '/admindir_env' },
332 params => [ qw(--admindir /admindir_opt) ],
333 expected => "root=$DEFAULT_ROOTDIR admdir=/admindir_opt",
335 call_ua_dirs(
336 env => { $admindir_envvar => '/admindir_env' },
337 params => [ qw(--root /rootdir_opt --admindir /admindir_opt) ],
338 expected => 'root=/rootdir_opt admdir=/admindir_opt',
340 call_ua_dirs(
341 env => { $admindir_envvar => '/admindir_env' },
342 params => [ qw(--admindir /admindir_opt --root /rootdir_opt) ],
343 expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
346 # ENV_ROOT + options
347 call_ua_dirs(
348 env => { $rootdir_envvar => '/rootdir_env' },
349 params => [ qw(--root /rootdir_opt) ],
350 expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
352 call_ua_dirs(
353 env => { $rootdir_envvar => '/rootdir_env' },
354 params => [ qw(--admindir /admindir_opt) ],
355 expected => 'root=/rootdir_env admdir=/admindir_opt',
357 call_ua_dirs(
358 env => { $rootdir_envvar => '/rootdir_env' },
359 params => [ qw(--root /rootdir_opt --admindir /admindir_opt) ],
360 expected => 'root=/rootdir_opt admdir=/admindir_opt',
362 call_ua_dirs(
363 env => { $rootdir_envvar => '/rootdir_env' },
364 params => [ qw(--admindir /admindir_opt --root /rootdir_opt) ],
365 expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
368 # ENV_ROOT + ENV_ADMINDIR + options
369 call_ua_dirs(
370 env => {
371 $rootdir_envvar => '/rootdir_env',
372 $admindir_envvar => '/admindir_env',
374 params => [ qw(--root /rootdir_opt) ],
375 expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
377 call_ua_dirs(
378 env => {
379 $rootdir_envvar => '/rootdir_env',
380 $admindir_envvar => '/admindir_env',
382 params => [ qw(--admindir /admindir_opt) ],
383 expected => 'root=/rootdir_env admdir=/admindir_opt',
385 call_ua_dirs(
386 env => {
387 $rootdir_envvar => '/rootdir_env',
388 $admindir_envvar => '/admindir_env',
390 params => [ qw(--root /rootdir_opt --admindir /admindir_opt) ],
391 expected => 'root=/rootdir_opt admdir=/admindir_opt',
393 call_ua_dirs(
394 env => {
395 $rootdir_envvar => '/rootdir_env',
396 $admindir_envvar => '/admindir_env',
398 params => [ qw(--admindir /admindir_opt --root /rootdir_opt) ],
399 expected => "root=/rootdir_opt admdir=/rootdir_opt$DEFAULT_ADMINDIR",
402 cleanup();
403 # removal when not installed should not fail
404 remove_choice(0);
405 # successive install in auto mode
406 install_choice(1);
407 check_choice(1, 'auto', 'initial install 1');
408 install_choice(2); # 2 is lower prio, stays at 1
409 check_choice(1, 'auto', 'initial install 2');
410 install_choice(0); # 0 is higher priority
411 check_choice(0, 'auto', 'initial install 3');
413 # verify that the administrative file is sorted properly
415 my $content = file_slurp("$admindir/generic-test");
416 my $expected =
417 "auto
418 $bindir/generic-test
419 slave1
420 $bindir/slave1
421 slave2
422 $bindir/slave2
423 slave3
424 $bindir/slave3
425 slave4
426 $bindir/slave4
430 my %slaves;
432 # Store slaves in a hash to easily retrieve present and missing ones.
433 foreach my $alt (@choices) {
434 foreach my $slave (@{$alt->{slaves}}) {
435 $slaves{$slave->{name}}{$alt->{path}} = $slave;
439 foreach my $alt (sort { $a->{path} cmp $b->{path} } @choices) {
440 $expected .= $alt->{path} . "\n";
441 $expected .= $alt->{priority} . "\n";
442 foreach my $slave_name (sort keys %slaves) {
443 $expected .= $slaves{$slave_name}{$alt->{path}}{path} || '';
444 $expected .= "\n";
447 $expected .= "\n";
449 is($content, $expected, 'administrative file is as expected');
452 # manual change with --set-selections
453 my $input = "doesntexist auto $paths{date}\ngeneric-test manual $paths{false}\n";
454 my $output = '';
455 call_ua(['--set-selections'], from_string => \$input,
456 to_string => \$output, test_id => 'manual update with --set-selections');
457 check_choice(1, 'manual', 'manual update with --set-selections');
458 $input = "generic-test auto $paths{true}\n";
459 call_ua(['--set-selections'], from_string => \$input,
460 to_string => \$output, test_id => 'auto update with --set-selections');
461 check_choice(0, 'auto', 'auto update with --set-selections');
462 # manual change with set
463 set_choice(2, test_id => 'manual update with --set');
464 check_choice(2, 'manual', 'manual update with --set'); # test #388313
465 remove_choice(2, test_id => 'remove manual, back to auto');
466 check_choice(0, 'auto', 'remove manual, back to auto');
467 remove_choice(0, test_id => 'remove best');
468 check_choice(1, 'auto', 'remove best');
469 remove_choice(1, test_id => 'no alternative left');
470 check_choice(undef, '', 'no alternative left');
471 # single choice in manual mode, to be removed
472 install_choice(1);
473 set_choice(1);
474 check_choice(1, 'manual', 'single manual choice');
475 remove_choice(1);
476 check_choice(undef, '', 'removal single manual');
477 # test --remove-all
478 install_choice(0);
479 install_choice(1);
480 install_choice(2);
481 remove_all_choices(test_id => 'remove all');
482 check_choice(undef, '', 'no alternative left');
483 # check auto-recovery of user mistakes (#100135)
484 install_choice(1);
485 ok(unlink("$bindir/generic-test"), 'failed removal');
486 ok(unlink("$bindir/slave1"), 'failed removal');
487 install_choice(1);
488 check_choice(1, 'auto', 'recreate links in auto mode');
489 set_choice(1);
490 ok(unlink("$bindir/generic-test"), 'failed removal');
491 ok(unlink("$bindir/slave1"), 'failed removal');
492 install_choice(1);
493 check_choice(1, 'manual', 'recreate links in manual mode');
494 # check recovery of /etc/alternatives/*
495 install_choice(0);
496 ok(unlink("$altdir/generic-test"), 'failed removal');
497 install_choice(1);
498 check_choice(0, 'auto', '<altdir>/generic-test lost, back to auto');
499 # test --config
500 config_choice(0);
501 check_choice(0, 'manual', 'config to best but manual');
502 config_choice(1);
503 check_choice(1, 'manual', 'config to manual');
504 config_choice(-1);
505 check_choice(0, 'auto', 'config auto');
507 # test rename of links
508 install_choice(0);
509 my $old_slave = $choices[0]{slaves}[0]{link};
510 my $old_link = $main_link;
511 $choices[0]{slaves}[0]{link} = "$bindir/more/generic-slave";
512 $main_link = "$bindir/more/mytest";
513 install_choice(0);
514 check_choice(0, 'auto', 'test rename of links');
515 check_no_link($old_link, 'test rename of links');
516 check_no_link($old_slave, 'test rename of links');
517 # rename with installing other alternatives
518 $old_link = $main_link;
519 $main_link = "$bindir/generic-test";
520 install_choice(1);
521 check_choice(0, 'auto', 'rename link');
522 check_no_link($old_link, 'rename link');
523 # rename with lost file
524 unlink($old_slave);
525 $old_slave = $choices[0]{slaves}[0]{link};
526 $choices[0]{slaves}[0]{link} = "$bindir/generic-slave-bis";
527 install_choice(0);
528 check_choice(0, 'auto', 'rename lost file');
529 check_no_link($old_slave, 'rename lost file');
530 # update of alternative with many slaves not currently installed
531 # and the link of the renamed slave exists while it should not
532 set_choice(1);
533 symlink("$paths{cat}", "$bindir/generic-slave-bis");
534 $choices[0]{slaves}[0]{link} = "$bindir/slave2";
535 install_choice(0, test_id => 'update with non-installed slaves');
536 check_no_link("$bindir/generic-slave-bis",
537 'drop renamed symlink that should not be installed');
539 # test install with empty admin file (#457863)
540 cleanup();
541 system("touch $admindir/generic-test");
542 install_choice(0);
543 # test install with garbage admin file
544 cleanup();
545 system("echo garbage > $admindir/generic-test");
546 install_choice(0, error_to_file => '/dev/null', expect_failure => 1);
548 # test invalid usages
549 cleanup();
550 install_choice(0);
551 # try to install a slave alternative as new master
552 call_ua(['--install', "$bindir/testmaster", 'slave1', "$paths{date}", '10'],
553 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
554 # try to install a master alternative as slave
555 call_ua(['--install', "$bindir/testmaster", 'testmaster', "$paths{date}", '10',
556 '--slave', "$bindir/testslave", 'generic-test', "$paths{true}" ],
557 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
558 # try to reuse master link in slave
559 call_ua(['--install', "$bindir/testmaster", 'testmaster', "$paths{date}", '10',
560 '--slave', "$bindir/testmaster", 'testslave', "$paths{true}" ],
561 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
562 # try to reuse links in master alternative
563 call_ua(['--install', "$bindir/slave1", 'testmaster', "$paths{date}", '10'],
564 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
565 # try to reuse links in slave alternative
566 call_ua(['--install', "$bindir/testmaster", 'testmaster', "$paths{date}", '10',
567 '--slave', "$bindir/generic-test", 'testslave', "$paths{true}" ],
568 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
569 # try to reuse slave link in another slave alternative of another choice of
570 # the same main alternative
571 call_ua(['--install', $main_link, $main_name, "$paths{date}", '10',
572 '--slave', "$bindir/slave1", 'testslave', "$paths{true}" ],
573 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
574 # lack of absolute filenames in links or file path, non-existing path,
575 call_ua(['--install', '../testmaster', 'testmaster', "$paths{date}", '10'],
576 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
577 call_ua(['--install', "$bindir/testmaster", 'testmaster', './update-alternatives.pl', '10'],
578 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
579 # non-existing alternative path
580 call_ua(['--install', "$bindir/testmaster", 'testmaster', "$bindir/doesntexist", '10'],
581 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
582 # invalid alternative name in master
583 call_ua(['--install', "$bindir/testmaster", 'test/master', "$paths{date}", '10'],
584 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
585 # invalid alternative name in slave
586 call_ua(['--install', "$bindir/testmaster", 'testmaster', "$paths{date}", '10',
587 '--slave', "$bindir/testslave", 'test slave', "$paths{true}" ],
588 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
589 # install in non-existing dir should fail
590 call_ua(['--install', "$bindir/doesntexist/testmaster", 'testmaster', "$paths{date}", '10',
591 '--slave', "$bindir/testslave", 'testslave', "$paths{true}" ],
592 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
593 call_ua(['--install', "$bindir/testmaster", 'testmaster', "$paths{date}", '10',
594 '--slave', "$bindir/doesntexist/testslave", 'testslave', "$paths{true}" ],
595 expect_failure => 1, to_file => '/dev/null', error_to_file => '/dev/null');
597 # non-existing alternative path in slave is not a failure
598 my $old_path = $choices[0]{slaves}[0]{path};
599 $old_slave = $choices[0]{slaves}[0]{link};
600 $choices[0]{slaves}[0]{path} = "$bindir/doesntexist";
601 $choices[0]{slaves}[0]{link} = "$bindir/baddir/slave2";
602 # test rename of slave link that existed but that doesn't anymore
603 # and link is moved into non-existing dir at the same time
604 install_choice(0);
605 check_choice(0, 'auto', 'optional renamed slave2 in non-existing dir');
606 # same but on fresh install
607 cleanup();
608 install_choice(0);
609 check_choice(0, 'auto', 'optional slave2 in non-existing dir');
610 $choices[0]{slaves}[0]{link} = $old_slave;
611 # test fresh install with a non-existing slave file
612 cleanup();
613 install_choice(0);
614 check_choice(0, 'auto', 'optional slave2');
615 $choices[0]{slaves}[0]{path} = $old_path;
617 # test management of pre-existing files
618 cleanup();
619 system("touch $main_link $bindir/slave1");
620 install_choice(0);
621 ok(!-l $main_link, 'install preserves files that should be links');
622 ok(!-l "$bindir/slave1", 'install preserves files that should be slave links');
623 remove_choice(0);
624 ok(-f $main_link, 'removal keeps real file installed as master link');
625 ok(-f "$bindir/slave1", 'removal keeps real files installed as slave links');
626 install_choice(0, params => ['--force']);
627 check_choice(0, 'auto', 'install --force replaces files with links');
629 # test management of pre-existing files #2
630 cleanup();
631 system("touch $main_link $bindir/slave2");
632 install_choice(0);
633 install_choice(1);
634 ok(!-l $main_link, 'inactive install preserves files that should be links');
635 ok(!-l "$bindir/slave2", 'inactive install preserves files that should be slave links');
636 ok(-f $main_link, 'inactive install keeps real file installed as master link');
637 ok(-f "$bindir/slave2", 'inactive install keeps real files installed as slave links');
638 set_choice(1);
639 ok(!-l $main_link, 'manual switching preserves files that should be links');
640 ok(!-l "$bindir/slave2", 'manual switching preserves files that should be slave links');
641 ok(-f $main_link, 'manual switching keeps real file installed as master link');
642 ok(-f "$bindir/slave2", 'manual switching keeps real files installed as slave links');
643 remove_choice(1);
644 ok(!-l $main_link, 'auto switching preserves files that should be links');
645 ok(!-l "$bindir/slave2", 'auto switching preserves files that should be slave links');
646 ok(-f $main_link, 'auto switching keeps real file installed as master link');
647 ok(-f "$bindir/slave2", 'auto switching keeps real files installed as slave links');
648 remove_all_choices(params => ['--force']);
649 ok(!-e "$bindir/slave2", 'forced removeall drops real files installed as slave links');
651 # test management of pre-existing files #3
652 cleanup();
653 system("touch $main_link $bindir/slave2");
654 install_choice(0);
655 install_choice(1);
656 remove_choice(0);
657 ok(!-l $main_link, 'removal + switching preserves files that should be links');
658 ok(!-l "$bindir/slave2", 'removal + switching preserves files that should be slave links');
659 ok(-f $main_link, 'removal + switching keeps real file installed as master link');
660 ok(-f "$bindir/slave2", 'removal + switching keeps real files installed as slave links');
661 install_choice(0);
662 ok(!-l $main_link, 'install + switching preserves files that should be links');
663 ok(!-l "$bindir/slave2", 'install + switching preserves files that should be slave links');
664 ok(-f $main_link, 'install + switching keeps real file installed as master link');
665 ok(-f "$bindir/slave2", 'install + switching keeps real files installed as slave links');
666 set_choice(1, params => ['--force']);
667 ok(!-e "$bindir/slave2", 'forced switching w/o slave drops real files installed as slave links');
668 check_choice(1, 'manual', 'set --force replaces files with links');
670 # check disappearence of obsolete slaves (#916799)
671 cleanup();
672 call_ua([
673 '--install', "$bindir/test-obsolete", 'test-obsolete', "$paths{date}", '10',
674 '--slave', "$bindir/test-slave-a", 'test-slave-a', "$bindir/impl-slave-a",
675 '--slave', "$bindir/test-slave-b", 'test-slave-b', "$bindir/impl-slave-b",
676 '--slave', "$bindir/test-slave-c", 'test-slave-c', "$bindir/impl-slave-c",
677 ], to_file => '/dev/null', error_to_file => '/dev/null');
679 my $content;
680 my $expected;
682 $content = file_slurp("$admindir/test-obsolete");
683 $expected =
684 "auto
685 $bindir/test-obsolete
686 test-slave-a
687 $bindir/test-slave-a
688 test-slave-b
689 $bindir/test-slave-b
690 test-slave-c
691 $bindir/test-slave-c
693 $paths{date}
695 $bindir/impl-slave-a
696 $bindir/impl-slave-b
697 $bindir/impl-slave-c
700 is($content, $expected, 'administrative file for non-obsolete slaves is as expected');
702 call_ua([
703 '--install', "$bindir/test-obsolete", 'test-obsolete', "$paths{date}", '20',
704 '--slave', "$bindir/test-slave-c", 'test-slave-c', "$bindir/impl-slave-c",
705 ], to_file => '/dev/null', error_to_file => '/dev/null');
707 $content = file_slurp("$admindir/test-obsolete");
708 $expected =
709 "auto
710 $bindir/test-obsolete
711 test-slave-c
712 $bindir/test-slave-c
714 $paths{date}
716 $bindir/impl-slave-c
719 is($content, $expected, 'administrative file for obsolete slaves is as expected');