dpkg_divert.t 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624
  1. #!/usr/bin/perl
  2. #
  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.
  7. #
  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.
  12. #
  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/>.
  15. use strict;
  16. use warnings;
  17. use Test::More;
  18. use File::Spec;
  19. use Dpkg::File;
  20. use Dpkg::IPC;
  21. # Cleanup environment from variables that pollute the test runs.
  22. delete $ENV{DPKG_MAINTSCRIPT_PACKAGE};
  23. delete $ENV{DPKG_MAINTSCRIPT_ARCH};
  24. my $srcdir = $ENV{srcdir} || '.';
  25. my $builddir = $ENV{builddir} || '.';
  26. my $tmpdir = 't.tmp/dpkg_divert';
  27. my $admindir = File::Spec->rel2abs("$tmpdir/admindir");
  28. my $testdir = File::Spec->rel2abs("$tmpdir/testdir");
  29. my @dd = ("$builddir/../src/dpkg-divert");
  30. if (! -x "@dd") {
  31. plan skip_all => 'dpkg-divert not available';
  32. exit(0);
  33. }
  34. plan tests => 257;
  35. sub cleanup {
  36. system("rm -rf $tmpdir && mkdir -p $testdir");
  37. system("mkdir -p $admindir/updates");
  38. system("rm -f $admindir/status && touch $admindir/status");
  39. system("rm -rf $admindir/info && mkdir -p $admindir/info");
  40. }
  41. sub install_diversions {
  42. my ($txt) = @_;
  43. open(my $db_fh, '>', "$admindir/diversions")
  44. or die "cannot create $admindir/diversions";
  45. print { $db_fh } $txt;
  46. close($db_fh);
  47. }
  48. sub install_filelist {
  49. my ($pkg, $arch, @files) = @_;
  50. open(my $fileslist_fh, '>', "$admindir/info/$pkg.list")
  51. or die "cannot create $admindir/info/$pkg.list";
  52. for my $file (@files) {
  53. print { $fileslist_fh } "$file\n";
  54. }
  55. close($fileslist_fh);
  56. # Only installed packages have their files list considered.
  57. open(my $status_fh, '>>', "$admindir/status")
  58. or die "cannot append to $admindir/status";
  59. print { $status_fh } <<"EOF";
  60. Package: $pkg
  61. Status: install ok installed
  62. Version: 0
  63. Architecture: $arch
  64. Maintainer: dummy
  65. Description: dummy
  66. EOF
  67. close($status_fh);
  68. }
  69. sub call {
  70. my ($prog, $args, %opts) = @_;
  71. my ($output, $error);
  72. spawn(exec => [@$prog, @$args], wait_child => 1, nocheck => 1,
  73. to_pipe => \$output, error_to_pipe => \$error, %opts);
  74. if ($opts{expect_failure}) {
  75. ok($? != 0, "@$args should fail");
  76. } else {
  77. ok($? == 0, "@$args should not fail");
  78. }
  79. if (defined $opts{expect_stdout}) {
  80. my (@output) = <$output>;
  81. my (@expect) = split(/^/, $opts{expect_stdout});
  82. if (defined $opts{expect_sorted_stdout}) {
  83. @output = sort @output;
  84. @expect = sort @expect;
  85. }
  86. is(join('', @output), join('', @expect), "@$args stdout");
  87. }
  88. if (defined $opts{expect_stdout_like}) {
  89. like(file_slurp($output), $opts{expect_stdout_like}, "@$args stdout");
  90. }
  91. if (defined $opts{expect_stderr}) {
  92. is(file_slurp($error), $opts{expect_stderr}, "@$args stderr");
  93. }
  94. if (defined $opts{expect_stderr_like}) {
  95. like(file_slurp($error), $opts{expect_stderr_like}, "@$args stderr");
  96. }
  97. close($output);
  98. close($error);
  99. }
  100. sub call_divert {
  101. my ($params, %opts) = @_;
  102. call([@dd, '--admindir', $admindir], $params, %opts);
  103. }
  104. sub call_divert_sort {
  105. my ($params, %opts) = @_;
  106. $opts{expect_sorted_stdout} = 1;
  107. call_divert($params, %opts);
  108. }
  109. sub diversions_pack {
  110. my (@data) = @_;
  111. my @data_packed;
  112. ## no critic (ControlStructures::ProhibitCStyleForLoops)
  113. for (my ($i) = 0; $i < $#data; $i += 3) {
  114. push @data_packed, [ @data[$i .. $i + 2] ];
  115. }
  116. ## use critic
  117. my @list = sort { $a->[0] cmp $b->[0] } @data_packed;
  118. return @list;
  119. }
  120. sub diversions_eq {
  121. my (@expected) = split /^/, shift;
  122. open(my $db_fh, '<', "$admindir/diversions")
  123. or die "cannot open $admindir/diversions";
  124. my (@contents) = <$db_fh>;
  125. close($db_fh);
  126. my (@expected_pack) = diversions_pack(@expected);
  127. my (@contents_pack) = diversions_pack(@contents);
  128. is_deeply(\@contents_pack, \@expected_pack, 'diversions contents');
  129. }
  130. ### Tests
  131. cleanup();
  132. note('Command line parsing testing');
  133. my $usagere = qr/.*Usage.*dpkg-divert.*Commands.*Options.*/s;
  134. sub call_divert_badusage {
  135. my ($args, $err) = @_;
  136. call_divert($args, expect_failure => 1, expect_stderr_like => $err);
  137. }
  138. call_divert(['--help'], expect_stdout_like => $usagere,
  139. expect_stderr => '');
  140. call_divert(['--version'], expect_stdout_like => qr/.*dpkg-divert.*free software.*/s,
  141. expect_stderr => '');
  142. call_divert_badusage(['--jachsmitbju'], qr/unknown option/);
  143. call_divert_badusage(['--add', '--remove'], qr/(conflicting|two).*remove.*add.*/s);
  144. call_divert_badusage(['--divert'], qr/(takes a value|needs.*argument)/);
  145. call_divert_badusage(['--divert', 'foo'], qr/absolute/);
  146. call_divert_badusage(['--divert', "/foo\nbar"], qr/newline/);
  147. call_divert_badusage(['--package'], qr/(takes a value|needs.*argument)/);
  148. call_divert_badusage(['--package', "foo\nbar"], qr/newline/);
  149. install_diversions('');
  150. call_divert_badusage(['--add',], qr/needs a single argument/);
  151. call_divert_badusage(['--add', 'foo'], qr/absolute/);
  152. call_divert_badusage(['--add', "/foo\nbar"], qr/newline/);
  153. call_divert_badusage(['--add', "$testdir"], qr/director(y|ies)/);
  154. call_divert_badusage(['--add', '--divert', 'bar', '/foo/bar'], qr/absolute/);
  155. call_divert_badusage(['--remove'], qr/needs a single argument/);
  156. call_divert_badusage(['--remove', 'foo'], qr/absolute/);
  157. call_divert_badusage(['--remove', "/foo\nbar"], qr/newline/);
  158. call_divert_badusage(['--listpackage'], qr/needs a single argument/);
  159. call_divert_badusage(['--listpackage', 'foo'], qr/absolute/);
  160. call_divert_badusage(['--listpackage', "/foo\nbar"], qr/newline/);
  161. call_divert_badusage(['--truename'], qr/needs a single argument/);
  162. call_divert_badusage(['--truename', 'foo'], qr/absolute/);
  163. call_divert_badusage(['--truename', "/foo\nbar"], qr/newline/);
  164. call([@dd, '--admindir'], [],
  165. expect_failure => 1, expect_stderr_like => qr/(takes a value|needs.*argument)/);
  166. cleanup();
  167. note('Querying information from diverts db (empty one)');
  168. install_diversions('');
  169. call_divert_sort(['--list'], expect_stdout => '', expect_stderr => '');
  170. call_divert_sort(['--list', '*'], expect_stdout => '', expect_stderr => '');
  171. call_divert_sort(['--list', 'baz'], expect_stdout => '', expect_stderr => '');
  172. cleanup();
  173. note('Querying information from diverts db (1)');
  174. install_diversions(<<'EOF');
  175. /bin/sh
  176. /bin/sh.distrib
  177. dash
  178. /usr/share/man/man1/sh.1.gz
  179. /usr/share/man/man1/sh.distrib.1.gz
  180. dash
  181. /usr/bin/nm
  182. /usr/bin/nm.single
  183. binutils-multiarch
  184. EOF
  185. my $di_dash = "diversion of /bin/sh to /bin/sh.distrib by dash\n";
  186. my $di_dashman = "diversion of /usr/share/man/man1/sh.1.gz to /usr/share/man/man1/sh.distrib.1.gz by dash\n";
  187. my $di_nm = "diversion of /usr/bin/nm to /usr/bin/nm.single by binutils-multiarch\n";
  188. my $all_di = $di_dash . $di_dashman . $di_nm;
  189. call_divert_sort(['--list'], expect_stdout => $all_di, expect_stderr => '');
  190. call_divert_sort(['--list', '*'], expect_stdout => $all_di, expect_stderr => '');
  191. call_divert_sort(['--list', ''], expect_stdout => '', expect_stderr => '');
  192. call_divert_sort(['--list', '???????'], expect_stdout => $di_dash, expect_stderr => '');
  193. call_divert_sort(['--list', '*/sh'], expect_stdout => $di_dash, expect_stderr => '');
  194. call_divert_sort(['--list', '/bin/*'], expect_stdout => $di_dash, expect_stderr => '');
  195. call_divert_sort(['--list', 'binutils-multiarch'], expect_stdout => $di_nm, expect_stderr => '');
  196. call_divert_sort(['--list', '/bin/sh'], expect_stdout => $di_dash, expect_stderr => '');
  197. call_divert_sort(['--list', '--', '/bin/sh'], expect_stdout => $di_dash, expect_stderr => '');
  198. call_divert_sort(['--list', '/usr/bin/nm.single'], expect_stdout => $di_nm, expect_stderr => '');
  199. call_divert_sort(['--list', '/bin/sh', '/usr/share/man/man1/sh.1.gz'], expect_stdout => $di_dash . $di_dashman,
  200. expect_stderr => '');
  201. cleanup();
  202. note('Querying information from diverts db (2)');
  203. install_diversions(<<'EOF');
  204. /bin/sh
  205. /bin/sh.distrib
  206. dash
  207. /bin/true
  208. /bin/true.coreutils
  209. :
  210. EOF
  211. call_divert(['--listpackage', 'foo', 'bar'], expect_failure => 1);
  212. call_divert(['--listpackage', '/bin/sh'], expect_stdout => "dash\n", expect_stderr => '');
  213. call_divert(['--listpackage', '/bin/true'], expect_stdout => "LOCAL\n", expect_stderr => '');
  214. call_divert(['--listpackage', '/bin/false'], expect_stdout => '', expect_stderr => '');
  215. call_divert(['--truename', '/bin/sh'], expect_stdout => "/bin/sh.distrib\n", expect_stderr => '');
  216. call_divert(['--truename', '/bin/sh.distrib'], expect_stdout => "/bin/sh.distrib\n", expect_stderr => '');
  217. call_divert(['--truename', '/bin/something'], expect_stdout => "/bin/something\n", expect_stderr => '');
  218. cleanup();
  219. note('Adding diversion');
  220. my $diversions_added_foo_local = <<"EOF";
  221. $testdir/foo
  222. $testdir/foo.distrib
  223. :
  224. EOF
  225. install_diversions('');
  226. system("touch $testdir/foo");
  227. call_divert(['--rename', '--add', "$testdir/foo"],
  228. expect_stdout_like => qr{Adding.*local.*diversion.*\Q$testdir\E/foo.*\Q$testdir\E/foo.distrib},
  229. expect_stderr => '');
  230. ok(-e "$testdir/foo.distrib", 'foo diverted');
  231. ok(!-e "$testdir/foo", 'foo diverted');
  232. diversions_eq($diversions_added_foo_local);
  233. cleanup();
  234. note('Adding diversion (2)');
  235. install_diversions('');
  236. system("touch $testdir/foo");
  237. call_divert(['--add', "$testdir/foo"],
  238. expect_stdout_like => qr{Adding.*local.*diversion.*\Q$testdir\E/foo.*\Q$testdir\E/foo.distrib},
  239. expect_stderr => '');
  240. ok(!-e "$testdir/foo.distrib", 'foo diverted');
  241. ok(-e "$testdir/foo", 'foo diverted');
  242. diversions_eq($diversions_added_foo_local);
  243. cleanup();
  244. note('Adding diversion (3)');
  245. install_diversions('');
  246. system("touch $testdir/foo");
  247. call_divert(['--quiet', '--rename', '--add', "$testdir/foo"],
  248. expect_stdout => '', expect_stderr => '');
  249. ok(-e "$testdir/foo.distrib", 'foo diverted');
  250. ok(!-e "$testdir/foo", 'foo diverted');
  251. diversions_eq($diversions_added_foo_local);
  252. cleanup();
  253. note('Adding diversion (4)');
  254. install_diversions('');
  255. system("touch $testdir/foo");
  256. call_divert(['--quiet', '--rename', '--test', "$testdir/foo"],
  257. expect_stdout => '', expect_stderr => '');
  258. ok(-e "$testdir/foo", 'foo not diverted');
  259. ok(!-e "$testdir/foo.distrib", 'foo diverted');
  260. diversions_eq('');
  261. cleanup();
  262. note('Adding diversion (5)');
  263. install_diversions('');
  264. call_divert(['--quiet', '--rename', "$testdir/foo"],
  265. expect_stdout => '', expect_stderr => '');
  266. ok(!-e "$testdir/foo", 'foo does not exist');
  267. ok(!-e "$testdir/foo.distrib", 'foo was not created out of thin air');
  268. cleanup();
  269. note('Adding diversion (6)');
  270. install_diversions('');
  271. system("touch $testdir/foo");
  272. call_divert(['--quiet', '--local', '--rename', "$testdir/foo"],
  273. expect_stdout => '', expect_stderr => '');
  274. ok(-e "$testdir/foo.distrib", 'foo diverted');
  275. ok(!-e "$testdir/foo", 'foo diverted');
  276. diversions_eq($diversions_added_foo_local);
  277. cleanup();
  278. note('Adding diversion (7)');
  279. install_diversions('');
  280. call_divert(['--quiet', '--rename', '--package', 'bash', "$testdir/foo"],
  281. expect_stdout => '', expect_stderr => '');
  282. diversions_eq(<<"EOF");
  283. $testdir/foo
  284. $testdir/foo.distrib
  285. bash
  286. EOF
  287. note('Adding diversion (8)');
  288. install_diversions('');
  289. system("touch $testdir/foo; ln $testdir/foo $testdir/foo.distrib");
  290. call_divert(['--rename', "$testdir/foo"]);
  291. diversions_eq($diversions_added_foo_local);
  292. ok(!-e "$testdir/foo", 'foo diverted');
  293. ok(-e "$testdir/foo.distrib", 'foo diverted');
  294. cleanup();
  295. note('Adding diversion (9)');
  296. install_diversions('');
  297. system("touch $testdir/foo $testdir/foo.distrib");
  298. call_divert(['--rename', "$testdir/foo"], expect_failure => 1,
  299. expect_stderr_like => qr/overwriting/);
  300. diversions_eq('');
  301. cleanup();
  302. note('Adding second diversion');
  303. install_diversions('');
  304. call_divert(["$testdir/foo"]);
  305. call_divert(["$testdir/foo"], expect_stdout_like => qr/Leaving/);
  306. call_divert(['--quiet', "$testdir/foo"], expect_stdout => '');
  307. call_divert(['--divert', "$testdir/foo.bar", "$testdir/foo"],
  308. expect_failure => 1, expect_stderr_like => qr/clashes/);
  309. call_divert(['--package', 'foobar', "$testdir/foo"], expect_failure => 1,
  310. expect_stderr_like => qr/clashes/);
  311. call_divert(['--divert', "$testdir/foo.distrib", "$testdir/bar"],
  312. expect_failure => 1, expect_stderr_like => qr/clashes/);
  313. call_divert(["$testdir/foo.distrib"],
  314. expect_failure => 1, expect_stderr_like => qr/clashes/);
  315. call_divert(['--divert', "$testdir/foo", "$testdir/bar"],
  316. expect_failure => 1, expect_stderr_like => qr/clashes/);
  317. cleanup();
  318. note('Adding third diversion');
  319. install_diversions('');
  320. call_divert(["$testdir/foo"]);
  321. call_divert(["$testdir/bar"]);
  322. call_divert(['--quiet', "$testdir/foo"], expect_stdout => '');
  323. call_divert(['--package', 'foobar', "$testdir/bar"], expect_failure => 1,
  324. expect_stderr_like => qr/clashes/);
  325. cleanup();
  326. note('Adding diversion in non-existing directory');
  327. install_diversions('');
  328. call_divert(['--quiet', '--rename', '--add', "$testdir/zoo/foo"],
  329. expect_stderr => '', expect_stdout => '');
  330. diversions_eq(<<"EOF");
  331. $testdir/zoo/foo
  332. $testdir/zoo/foo.distrib
  333. :
  334. EOF
  335. cleanup();
  336. note('Adding diversion of file owned by --package');
  337. install_filelist('coreutils', 'i386', "$testdir/foo");
  338. install_diversions('');
  339. system("touch $testdir/foo");
  340. call_divert(['--quiet', '--rename', '--add', '--package', 'coreutils', "$testdir/foo"],
  341. expect_stderr => '', expect_stdout => '');
  342. ok(-e "$testdir/foo", 'foo not renamed');
  343. ok(!-e "$testdir/foo.distrib", 'foo renamed');
  344. diversions_eq(<<"EOF");
  345. $testdir/foo
  346. $testdir/foo.distrib
  347. coreutils
  348. EOF
  349. cleanup();
  350. note('Remove diversions');
  351. install_diversions('');
  352. call_divert(['--remove', '/bin/sh'], expect_stdout_like => qr/No diversion/, expect_stderr => '');
  353. call_divert(['--remove', '--quiet', '/bin/sh'], expect_stdout => '', expect_stderr => '');
  354. cleanup();
  355. note('Remove diversion (2)');
  356. install_diversions('');
  357. call_divert(["$testdir/foo"]);
  358. call_divert(["$testdir/bar"]);
  359. call_divert(["$testdir/baz"]);
  360. call_divert(['--divert', "$testdir/foo.my", '--remove', "$testdir/foo"],
  361. expect_failure => 1, expect_stderr_like => qr/mismatch on divert-to/);
  362. call_divert(['--package', 'baz', '--remove', "$testdir/foo"],
  363. expect_failure => 1, expect_stderr_like => qr/mismatch on package/);
  364. call_divert(['--package', 'baz', '--divert', "$testdir/foo.my", '--remove', "$testdir/foo"],
  365. expect_failure => 1, expect_stderr_like =>qr/mismatch on (package|divert-to)/);
  366. call_divert(['--divert', "$testdir/foo.distrib", '--remove', "$testdir/foo"],
  367. expect_stdout_like => qr{Removing.*\Q$testdir\E/foo});
  368. diversions_eq(<<"EOF");
  369. $testdir/bar
  370. $testdir/bar.distrib
  371. :
  372. $testdir/baz
  373. $testdir/baz.distrib
  374. :
  375. EOF
  376. cleanup();
  377. note('Remove diversion (3)');
  378. install_diversions('');
  379. call_divert(["$testdir/foo"]);
  380. call_divert(["$testdir/bar"]);
  381. call_divert(["$testdir/baz"]);
  382. call_divert(['--remove', "$testdir/bar"],
  383. expect_stdout_like => qr{Removing.*\Q$testdir\E/bar});
  384. diversions_eq(<<"EOF");
  385. $testdir/foo
  386. $testdir/foo.distrib
  387. :
  388. $testdir/baz
  389. $testdir/baz.distrib
  390. :
  391. EOF
  392. cleanup();
  393. note('Remove diversion (4)');
  394. install_diversions('');
  395. call_divert(["$testdir/foo"]);
  396. call_divert(["$testdir/bar"]);
  397. call_divert(['--package', 'bash', "$testdir/baz"]);
  398. call_divert(['--quiet', '--package', 'bash', '--remove', "$testdir/baz"],
  399. expect_stdout => '', expect_stderr => '');
  400. diversions_eq(<<"EOF");
  401. $testdir/foo
  402. $testdir/foo.distrib
  403. :
  404. $testdir/bar
  405. $testdir/bar.distrib
  406. :
  407. EOF
  408. cleanup();
  409. note('Remove diversion(5)');
  410. install_diversions('');
  411. system("touch $testdir/foo");
  412. call_divert(['--rename', "$testdir/foo"]);
  413. call_divert(['--test', '--rename', '--remove', "$testdir/foo"],
  414. expect_stdout_like => qr{Removing.*\Q$testdir\E/foo}, expect_stderr => '');
  415. ok(-e "$testdir/foo.distrib", 'foo diversion not removed');
  416. ok(!-e "$testdir/foo", 'foo diversion not removed');
  417. diversions_eq($diversions_added_foo_local);
  418. call_divert(['--quiet', '--rename', '--remove', "$testdir/foo"],
  419. expect_stdout => '', expect_stderr => '');
  420. ok(-e "$testdir/foo", 'foo diversion removed');
  421. ok(!-e "$testdir/foo.distrib", 'foo diversion removed');
  422. diversions_eq('');
  423. cleanup();
  424. note('Corrupted divertions db handling');
  425. SKIP: {
  426. skip 'running as root or similar', 3, if (defined($ENV{FAKEROOTKEY}) or $> == 0);
  427. # An inexistent diversions db file should not be considered a failure,
  428. # but a failure to open it should be.
  429. install_diversions('');
  430. system("chmod 000 $admindir/diversions");
  431. call_divert_sort(['--list'], expect_failure => 1,
  432. expect_stderr_like => qr/(cannot|failed).*open/, expect_stdout => '');
  433. system("chmod 644 $admindir/diversions");
  434. }
  435. install_diversions(<<'EOF');
  436. /bin/sh
  437. EOF
  438. call_divert_sort(['--list'], expect_failure => 1,
  439. expect_stderr_like => qr/(corrupt|unexpected eof)/, expect_stdout => '');
  440. install_diversions(<<'EOF');
  441. /bin/sh
  442. bash
  443. EOF
  444. call_divert_sort(['--list'], expect_failure => 1,
  445. expect_stderr_like => qr/(corrupt|unexpected eof)/, expect_stdout => '');
  446. cleanup();
  447. SKIP: {
  448. skip 'running as root or similar', 10, if (defined($ENV{FAKEROOTKEY}) or $> == 0);
  449. note('R/O directory');
  450. install_diversions('');
  451. system("mkdir $testdir/rodir && touch $testdir/rodir/foo $testdir/bar && chmod 500 $testdir/rodir");
  452. call_divert(['--rename', '--add', "$testdir/rodir/foo"],
  453. expect_failure => 1, expect_stderr_like => qr/error/);
  454. call_divert(['--rename', '--divert', "$testdir/rodir/bar", '--add', "$testdir/bar"],
  455. expect_failure => 1, expect_stderr_like => qr/error/);
  456. diversions_eq('');
  457. system("chmod 755 $testdir/rodir");
  458. cleanup();
  459. note('Unavailable file');
  460. install_diversions('');
  461. system("mkdir $testdir/nadir && chmod 000 $testdir/nadir");
  462. call_divert(['--rename', '--add', "$testdir/nadir/foo"],
  463. expect_failure => 1, expect_stderr_like => qr/Permission denied/);
  464. system("touch $testdir/foo");
  465. call_divert(['--rename', '--divert', "$testdir/nadir/foo", '--add', "$testdir/foo"],
  466. expect_failure => 1, expect_stderr_like => qr/Permission denied/);
  467. diversions_eq('');
  468. cleanup();
  469. }
  470. note('Errors during saving diversions db');
  471. install_diversions('');
  472. SKIP: {
  473. skip 'running as root or similar', 4, if (defined($ENV{FAKEROOTKEY}) or $> == 0);
  474. system("chmod 500 $admindir");
  475. call_divert(["$testdir/foo"], expect_failure => 1, expect_stderr_like => qr/create.*new/);
  476. system("chmod 755 $admindir; ln -s /dev/full $admindir/diversions-new");
  477. call_divert(["$testdir/foo"], expect_failure => 1, expect_stderr_like => qr/(write|flush|close).*new/);
  478. }
  479. system("rm -f $admindir/diversions-new; mkdir $admindir/diversions-old");
  480. call_divert(["$testdir/foo"], expect_failure => 1, expect_stderr_like => qr/remov.*old/);