3 #=======================================================================
5 # File ID: 9072b5a4-f909-11e4-b80e-000df06acc56
7 # Test suite for git-update-dirs(1).
10 # ©opyleft 2015– Øyvind A. Holm <sunny@sunbase.org>
11 # License: GNU General Public License version 2 or later, see end of
12 # file for legal stuff.
13 #=======================================================================
19 use Test
::More
qw{no_plan
};
23 use Cwd
qw{ abs_path getcwd
};
28 our $CMDB = "git-update-dirs";
29 our $CMD = "../$CMDB";
43 $progname =~ s/^.*\/(.*?)$/$1/;
44 our $VERSION = '0.0.0';
47 my %descriptions = ();
48 my %disable_already_tested = ();
49 my $abspwd = abs_path
(getcwd
());
51 Getopt
::Long
::Configure
('bundling');
54 'all|a' => \
$Opt{'all'},
55 'help|h' => \
$Opt{'help'},
56 'quiet|q+' => \
$Opt{'quiet'},
57 'todo|t' => \
$Opt{'todo'},
58 'verbose|v+' => \
$Opt{'verbose'},
59 'version' => \
$Opt{'version'},
61 ) || die("$progname: Option error. Use -h for help.\n");
63 $Opt{'verbose'} -= $Opt{'quiet'};
64 $Opt{'help'} && usage
(0);
65 if ($Opt{'version'}) {
76 diag
(sprintf('========== Executing %s v%s ==========',
77 $progname, $VERSION));
79 if ($Opt{'todo'} && !$Opt{'all'}) {
85 testcmd("$CMD command", # {{{
98 my $Tmptop = "tmp-git-update-dirs-t-$$-" . substr(rand, 2, 8);
99 my $abstop = "$abspwd/$Tmptop";
100 ok
(mkdir($Tmptop), "mkdir [Tmptop]") ||
101 BAIL_OUT
("$Tmptop: mkdir error, can't continue\n");
102 ok
(chdir($Tmptop), "chdir [Tmptop]") ||
103 BAIL_OUT
("$progname: $Tmptop: chdir error, can't continue\n");
104 chomp($ENV{'HOME'} = `pwd`);
105 testcmd
('git config --global user.name "Suttleif Fisen"', '', '', 0,
106 'git config --global user.name "Suttleif Fisen"');
107 testcmd
('git config --global user.email suttleif@example.com', '', '', 0,
108 'git config --global user.email suttleif@example.com');
109 testcmd
('git config --global init.defaultbranch master', '', '', 0,
110 'git config --global init.defaultbranch master');
113 diag
('Testing -h (--help) option...');
114 likecmd
("$CMD -h", # {{{
115 '/ Show this help/i',
118 'Option -h prints help screen',
122 diag
('Testing -v (--verbose) option...');
123 likecmd
("$CMD -hv", # {{{
124 '/^\n\S+ \d+\.\d+\.\d+/s',
127 'Option -v with -h returns version number and help screen',
131 diag
('Testing --version option...');
132 likecmd
("$CMD --version", # {{{
133 '/^\S+ \d+\.\d+\.\d+/',
136 'Option --version returns version number',
140 likecmd
("git --version", # {{{
145 ) || BAIL_OUT
("git is not installed, cannot continue");
148 if (`git-annex version 2>/dev/null` !~ /^git-annex version/) {
149 # FIXME: Use with existing annex tests instead
150 diag
("git-annex is not installed here, skipping tests");
153 likecmd
("git annex version", # {{{
154 '/^git-annex version:/',
157 'git-annex is installed',
158 ) || BAIL_OUT
("git-annex is not installed, cannot continue");
161 diag
('Initialise repositories');
162 likecmd
("git init --bare bare.git", # {{{
166 'Create bare Git repository',
170 likecmd
("git clone bare.git repo", # {{{
174 'Clone bare.git to \'repo\'',
179 test_repo
('repo', 0, $abspwd, $Tmptop);
180 test_repo
('bare.git', 1, $abspwd, $Tmptop);
187 repo
/sub1/subrepo
1/subsubrepo1
.git
190 for my $dir (@dir_list) {
191 my $bare_str = ($dir =~ /\.git$/ ?
' --bare' : '');
192 likecmd
("git$bare_str init $dir",
196 "Create repo '$dir'",
200 testcmd
("$CMD --recursive -nf", # {{{
202 ================ $abstop/repo ================
204 ================ $abstop/repo/sub1 ================
206 ================ $abstop/repo/sub1/subrepo1 ================
208 ================ $abstop/repo/sub2 ================
211 "git-update-dirs: Simulating 'git fetch --all'...\n" x
4,
213 "--recursive option",
217 testcmd
("$CMD -rfn", # {{{
219 ================ $abstop/repo ================
221 ================ $abstop/repo/sub1 ================
223 ================ $abstop/repo/sub1/subrepo1 ================
225 ================ $abstop/repo/sub2 ================
228 "git-update-dirs: Simulating 'git fetch --all'...\n" x
4,
230 "-r (recursive) option",
234 create_file
("filelist.txt", join("\n", @dir_list));
235 testcmd
("$CMD --dirs-from filelist.txt -nf", # {{{
237 ================ $abstop/repo/sub2 ================
239 ================ $abstop/repo/sub1 ================
241 ================ $abstop/repo/sub1/subrepo1 ================
243 ================ $abstop/repo/bare1.git ================
245 ================ $abstop/repo/sub1/subrepo1/subsubrepo1.git ================
248 "git-update-dirs: Simulating 'git fetch --all'...\n" x
5,
250 "--dirs-from option",
254 testcmd
("$CMD --fetch -n --dirs-from - <filelist.txt", # {{{
256 ================ $abstop/repo/sub2 ================
258 ================ $abstop/repo/sub1 ================
260 ================ $abstop/repo/sub1/subrepo1 ================
262 ================ $abstop/repo/bare1.git ================
264 ================ $abstop/repo/sub1/subrepo1/subsubrepo1.git ================
267 "git-update-dirs: Simulating 'git fetch --all'...\n" x
5,
269 "Read file list from stdin with '--dirs-from -'",
273 create_file
("filelist2.txt", <<END);
278 testcmd
("$CMD --fetch -n --dirs-from filelist.txt " .
279 "--dirs-from filelist2.txt", # {{{
281 ================ $abstop/repo/sub2 ================
283 ================ $abstop/repo/sub1 ================
285 ================ $abstop/repo/sub1/subrepo1 ================
287 ================ $abstop/repo/bare1.git ================
289 ================ $abstop/repo/sub1/subrepo1/subsubrepo1.git ================
291 ================ $abstop/repo/sub2 ================
293 ================ $abstop/repo/bare1.git ================
295 ================ $abstop/repo/sub1 ================
298 "git-update-dirs: Simulating 'git fetch --all'...\n" x
8,
300 "--dirs-from is specified twice, read from two files",
304 ok
(unlink("filelist.txt"), "Delete filelist.txt");
305 ok
(unlink("filelist2.txt"), "Delete filelist2.txt");
308 testcmd
("rm -rf bare.git", # {{{
312 'Remove bare test repository',
316 testcmd
("rm -rf repo", # {{{
320 'Remove non-bare test repository',
324 ok
(unlink(".gitconfig"), "Delete .gitconfig");
325 testcmd
("rm -rf .cache", "", "", 0, "Delete .cache/, created by git-annex");
326 testcmd
("rm -rf .ssh", "", "", 0, "Delete .ssh/, created by git-annex");
327 ok
(chdir(".."), "chdir ..");
328 ok
(-d
$Tmptop, "[Tmptop] exists");
329 ok
(rmdir($Tmptop), "rmdir [Tmptop]");
330 ok
(!-d
$Tmptop, "[Tmptop] is gone");
335 if ($Opt{'all'} || $Opt{'todo'}) {
336 diag
('Running TODO tests...'); # {{{
341 # Insert TODO tests here.
347 diag
('Testing finished.');
354 my ($repo, $is_bare, $abspwd, $Tmptop) = @_;
355 my $absrepo = "$abspwd/$Tmptop/$repo";
357 diag
("Run tests in $repo");
358 $current_repo = $repo;
359 ok
(chdir($repo), "chdir $repo") || BAIL_OUT
('chdir error');
360 $CMD = "../../../$CMDB";
362 BAIL_OUT
("test_repo(): \$CMD is '$CMD', that's wrong");
365 likecmd
("git remote add bare ../bare.git", # {{{
369 'Create bare remote',
373 likecmd
("git commit --allow-empty -m 'Empty start commit'", # {{{
377 'Create empty start commit',
381 likecmd
("git push bare master", # {{{
385 'Push master to the bare repo',
390 likecmd
("git annex init " . ($is_bare ?
"bare" : "repo"), # {{{
394 "Make $repo an annex",
398 my $sep = "================ $absrepo ================\n";
400 diag
('--exec-before');
401 testcmd
("$CMD -E 'echo This is nice' .", # {{{
402 "${sep}This is nice\n\n",
403 "git-update-dirs: Executing 'echo This is nice'...\n",
405 "$repo: Test -E option",
409 testcmd
("$CMD --exec-before 'echo This is nice' .", # {{{
410 "${sep}This is nice\n\n",
411 "git-update-dirs: Executing 'echo This is nice'...\n",
413 "$repo: Test --exec-before option",
417 test_disabled
("exec-before", "$CMD --exec-before echo .", $absrepo);
419 testcmd
("$CMD -n -l .", # {{{
421 "git-update-dirs: Simulating 'lpar'...\n" .
422 "git-update-dirs: Simulating 'lpar'...\n",
424 "$repo: Test -l option",
428 testcmd
("$CMD -n --lpar .", # {{{
430 "git-update-dirs: Simulating 'lpar'...\n" .
431 "git-update-dirs: Simulating 'lpar'...\n",
433 "$repo: Test --lpar option",
437 test_disabled
("lpar", undef, $absrepo);
439 test_option
('-t', 'git fsck', $absrepo);
440 test_option
('--test', 'git fsck', $absrepo);
441 diag
('--fetch-prune');
442 test_option
('-F', 'git fetch --all --prune', $absrepo);
443 test_option
('--fetch-prune', 'git fetch --all --prune', $absrepo);
445 test_option
('-f', 'git fetch --all', $absrepo);
446 test_option
('--fetch', 'git fetch --all', $absrepo);
449 testcmd
("$CMD -n -p", '', '', 0, "$repo: Test -p");
450 testcmd
("$CMD -n --pull", '', '', 0, "$repo: Test --pull");
452 test_option
('-p', 'git pull --ff-only', $absrepo);
453 test_option
('--pull', 'git pull --ff-only', $absrepo);
456 test_option
('-g', 'ga sync', $absrepo);
457 test_option
('--ga-sync', 'ga sync', $absrepo);
458 diag
('--ga-dropget');
459 test_option
('-G', nolf
(<<END), $absrepo); # {{{
461 git-update-dirs: Simulating 'ga drop --auto'...
462 git-update-dirs: Simulating 'ga sync'...
463 git-update-dirs: Simulating 'ga get --auto'...
464 git-update-dirs: Simulating 'ga sync
468 test_option
('--ga-dropget', nolf
(<<END), $absrepo); # {{{
470 git-update-dirs: Simulating 'ga drop --auto'...
471 git-update-dirs: Simulating 'ga sync'...
472 git-update-dirs: Simulating 'ga get --auto'...
473 git-update-dirs: Simulating 'ga sync
477 diag
('--ga-dropunused');
478 test_option
('-u', nolf
(<<END), $absrepo); # {{{
480 git-update-dirs: Simulating 'ga unused'...
481 git-update-dirs: Simulating 'ga dropunused all'...
482 git-update-dirs: Simulating 'ga sync
486 test_option
('--ga-dropunused', nolf
(<<END), $absrepo); # {{{
488 git-update-dirs: Simulating 'ga unused'...
489 git-update-dirs: Simulating 'ga dropunused all'...
490 git-update-dirs: Simulating 'ga sync
494 diag
('--ga-moveunused');
495 test_option
('-U', nolf
(<<END), $absrepo); # {{{
500 testcmd
('git remote add seagate-3tb yep', # {{{
504 "$repo: Add fake seagate-3tb remote",
508 test_option
('--ga-moveunused', nolf
(<<END), $absrepo); # {{{
510 git-update-dirs: Simulating 'ga unused'...
511 git-update-dirs: Simulating 'ga move --unused --to seagate-3tb'...
512 git-update-dirs: Simulating 'ga sync
517 test_option
('-N', 'ga-getnew', $absrepo);
518 test_option
('--ga-getnew', 'ga-getnew', $absrepo);
519 diag
('--ga-update-desc');
520 test_option
('-S', 'ga update-desc', $absrepo);
521 test_option
('--ga-update-desc', 'ga update-desc', $absrepo);
523 test_option
('-d', 'git dangling', $absrepo);
524 test_option
('--dangling', 'git dangling', $absrepo);
527 test_option
('-a', nolf
(<<END), $absrepo); # {{{
529 git-update-dirs: Simulating 'git allbr -a'...
530 git-update-dirs: Simulating 'git checkout -
534 test_option
('--allbr', nolf
(<<END), $absrepo); # {{{
536 git-update-dirs: Simulating 'git allbr -a'...
537 git-update-dirs: Simulating 'git checkout -
542 testcmd
("$CMD . -n --allbr", # {{{
546 'Ignore --allbr if it\'s only specified once in a non-bare repo',
550 testcmd
("$CMD . -n -a", # {{{
554 'Ignore -a if it\'s only specified once in a non-bare repo',
559 testcmd
("$CMD -aan .", # {{{
562 git-update-dirs: Simulating 'git nobr'...
563 git-update-dirs: Simulating 'git allbr -a'...
564 git-update-dirs: Simulating 'git checkout -'...
567 "$repo: -aa works in non-bare repos, though",
572 test_option
('-P', 'git pa', $absrepo);
573 test_option
('--push', 'git pa', $absrepo);
575 testcmd
("$CMD --dry-run -s .", # {{{
576 "================ $absrepo ================\n\n",
579 "$repo: Test -s option, .gitmodules is missing",
583 testcmd
("touch .gitmodules", '', '', 0, "$repo: Create empty .gitmodules");
584 test_option
('--submodule', nolf
(<<END), $absrepo); # {{{
585 git submodule init'...
586 git-update-dirs: Simulating 'git submodule update
591 my $objects = $is_bare ?
'objects' : '.git\/objects';
592 my $absrepo_r = $absrepo;
593 $absrepo_r =~ s
,/,\\/,g
;
594 my $compress_output = # {{{
596 "================ $absrepo_r ================\\n" .
600 'Saved : \d+ \(\d+.\d+%\)\n' .
601 'Number of files in ' .
603 ': before: \d+, after: \d+, saved: \d+\n' .
607 'Total : \d+ \(\d+.\d+%\)\n' .
608 'Number of object files: before: \d+, after: \d+, saved: \d+\n' .
612 likecmd
("$CMD -n -c .", # {{{
615 'git-update-dirs: Simulating \'git count-objects -vH\'\.\.\.\n' .
616 'git-update-dirs: Simulating \'git gc\'\.\.\.\n' .
619 "$repo: Test -c option",
623 likecmd
("$CMD -n --compress .", # {{{
626 'git-update-dirs: Simulating \'git count-objects -vH\'\.\.\.\n' .
627 'git-update-dirs: Simulating \'git gc\'\.\.\.\n' .
630 "$repo: Test --compress option",
634 system("git config git-update-dirs.no-compress true");
635 likecmd
("$CMD -n -c .", # {{{
636 "/^================ $absrepo_r ================\\n\\n" .
639 'Number of object files: before: \d+, after: \d+, saved: \d+\n/',
642 "$repo: Test disabling of -c",
646 system("git config --unset git-update-dirs.no-compress");
647 diag
('--aggressive-compress');
648 likecmd
("$CMD -n -C .", # {{{
651 'git-update-dirs: Simulating \'git count-objects -vH\'\.\.\.\n' .
652 'git-update-dirs: Simulating \'git gc --aggressive\'\.\.\.\n' .
655 "$repo: Test -C option",
659 likecmd
("$CMD --dry-run --aggressive-compress .", # {{{
662 'git-update-dirs: Simulating \'git count-objects -vH\'\.\.\.\n' .
663 'git-update-dirs: Simulating \'git gc --aggressive\'\.\.\.\n' .
666 "$repo: Test --aggressive-compress option",
670 system("git config git-update-dirs.no-aggressive-compress true");
671 likecmd
("$CMD -n -C .", # {{{
672 "/^================ $absrepo_r ================\\n\\n" .
675 'Number of object files: before: \d+, after: \d+, saved: \d+\n/',
678 "$repo: Test disabling of -C",
682 system("git config --unset git-update-dirs.no-aggressive-compress");
683 diag
('--delete-dangling');
685 # FIXME: This behaviour is up for debate. Should -D be ignored
686 # in bare repositories by default?
687 testcmd
("$CMD -n -D .", # {{{
695 testcmd
("$CMD -n --delete-dangling .", # {{{
699 "$repo: Test --delete-dangling",
704 test_option
('-D', 'git dangling -D', $absrepo);
705 test_option
('--delete-dangling', 'git dangling -D', $absrepo);
707 diag
('--exec-after');
708 testcmd
("$CMD -e 'echo This is nice' .", # {{{
709 "${sep}This is nice\n\n",
710 "git-update-dirs: Executing 'echo This is nice'...\n",
712 "$repo: Test -e option",
716 testcmd
("$CMD --exec-after 'echo This is nice' .", # {{{
717 "${sep}This is nice\n\n",
718 "git-update-dirs: Executing 'echo This is nice'...\n",
720 "$repo: Test --exec-after option",
724 test_disabled
("exec-after", "$CMD --exec-after echo .", $absrepo);
725 diag
('--all-options');
726 my ($allbr_str, $pull_str);
729 git-update-dirs: Simulating 'git nobr'...
730 git-update-dirs: Simulating 'git allbr -a'...
731 git-update-dirs: Simulating 'git checkout -'...
736 $pull_str = "git-update-dirs: Simulating 'git pull --ff-only'...\n";
738 testcmd
("$CMD --all-options -n .", # {{{
741 git-update-dirs: Simulating 'lpar'...
742 git-update-dirs: Simulating 'git fetch --all --prune'...
743 ${pull_str}git-update-dirs: Simulating 'ga sync'...
744 git-update-dirs: Simulating 'ga update-desc'...
745 git-update-dirs: Simulating 'git dangling'...
746 ${allbr_str}git-update-dirs: Simulating 'git pa'...
747 git-update-dirs: Simulating 'git submodule init'...
748 git-update-dirs: Simulating 'git submodule update'...
749 git-update-dirs: Simulating 'lpar'...
752 "$repo: Test --all-options, allbr is ignored",
756 testcmd
("$CMD -Ana .", # {{{
759 git-update-dirs: Simulating 'lpar'...
760 git-update-dirs: Simulating 'git fetch --all --prune'...
761 ${pull_str}git-update-dirs: Simulating 'ga sync'...
762 git-update-dirs: Simulating 'ga update-desc'...
763 git-update-dirs: Simulating 'git dangling'...
764 git-update-dirs: Simulating 'git nobr'...
765 git-update-dirs: Simulating 'git allbr -a'...
766 git-update-dirs: Simulating 'git checkout -'...
767 git-update-dirs: Simulating 'git pa'...
768 git-update-dirs: Simulating 'git submodule init'...
769 git-update-dirs: Simulating 'git submodule update'...
770 git-update-dirs: Simulating 'lpar'...
773 "$repo: Test the -A option with an extra -a to get some allbr action",
777 ok
(chdir('..'), "$repo: chdir ..");
778 $CMD = "../../$CMDB";
784 # Strip \n from string, replacement for chomp() {{{
793 my ($option, $cmd, $absrepo) = @_;
796 BAIL_OUT
("\$CMD is '$CMD', that's wrong");
798 testcmd
("$CMD -n $option .",
799 "================ $absrepo ================\n\n",
800 "git-update-dirs: Simulating '$cmd'...\n",
802 "$current_repo: Test $option option",
804 if ($option =~ /^--(.+)$/ && !defined($disable_already_tested{$1})) {
805 test_disabled
($1, undef, $absrepo);
812 # Test disabling of commands {{{
813 my ($longopt, $command, $absrepo) = @_;
814 system("git config git-update-dirs.no-$longopt true");
815 # Some commands calls "ga sync", so also disable "ga sync" to
816 # avoid that single line appear in the output.
817 if ($longopt =~ /^(ga-dropget|ga-dropunused|ga-moveunused)$/) {
818 system("git config git-update-dirs.no-ga-sync true");
820 defined($command) || ($command = "../../../$CMDB -n --$longopt .");
822 "================ $absrepo ================\n\n",
825 "$current_repo: --$longopt is disabled",
827 system("git config --unset git-update-dirs.no-$longopt");
828 if ($longopt =~ /^(ga-dropget|ga-dropunused|ga-moveunused)$/) {
829 system("git config --unset git-update-dirs.no-ga-sync");
831 $disable_already_tested{$longopt} = 1;
838 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
839 defined($descriptions{$Desc}) &&
840 BAIL_OUT
("testcmd(): '$Desc' description is used twice");
841 $descriptions{$Desc} = 1;
843 my $cmd_outp_str = $Opt{'verbose'} >= 1 ?
"\"$Cmd\" - " : '';
844 my $Txt = join('', $cmd_outp_str, defined($Desc) ?
$Desc : '');
845 my $TMP_STDERR = "$CMDB-stderr.tmp";
848 if (defined($Exp_stderr)) {
849 $stderr_cmd = " 2>$TMP_STDERR";
851 $retval &= is
(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
853 if (defined($Exp_stderr)) {
854 $retval &= is
(file_data
($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
857 diag
("Warning: stderr not defined for '$Txt'");
859 $retval &= is
($ret_val >> 8, $Exp_retval, "$Txt (retval)");
867 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
868 defined($descriptions{$Desc}) &&
869 BAIL_OUT
("likecmd(): '$Desc' description is used twice");
870 $descriptions{$Desc} = 1;
872 my $cmd_outp_str = $Opt{'verbose'} >= 1 ?
"\"$Cmd\" - " : '';
873 my $Txt = join('', $cmd_outp_str, defined($Desc) ?
$Desc : '');
874 my $TMP_STDERR = "$CMDB-stderr.tmp";
877 if (defined($Exp_stderr)) {
878 $stderr_cmd = " 2>$TMP_STDERR";
880 $retval &= like
(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
882 if (defined($Exp_stderr)) {
883 $retval &= like
(file_data
($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
886 diag
("Warning: stderr not defined for '$Txt'");
888 $retval &= is
($ret_val >> 8, $Exp_retval, "$Txt (retval)");
895 # Return file content as a string {{{
899 open(my $fp, '<', $File) or return undef;
908 # Create new file and fill it with data {{{
909 my ($file, $text) = @_;
911 if (open(my $fp, ">$file")) {
917 "$file was successfully created",
920 return($retval); # 0 if error, 1 if ok
925 # Print program version {{{
926 print("$progname $VERSION\n");
932 # Send the help message to stdout {{{
935 if ($Opt{'verbose'}) {
941 Usage: $progname [options]
943 Contains tests for the $CMDB(1) program.
948 Run all tests, also TODOs.
952 Be more quiet. Can be repeated to increase silence.
954 Run only the TODO tests.
956 Increase level of verbosity. Can be repeated.
958 Print version information.
966 # Print a status message to stderr based on verbosity level {{{
967 my ($verbose_level, $Txt) = @_;
969 $verbose_level > $Opt{'verbose'} && return;
970 print(STDERR
"$progname: $Txt\n");
977 # This program is free software; you can redistribute it and/or modify
978 # it under the terms of the GNU General Public License as published by
979 # the Free Software Foundation; either version 2 of the License, or (at
980 # your option) any later version.
982 # This program is distributed in the hope that it will be useful, but
983 # WITHOUT ANY WARRANTY; without even the implied warranty of
984 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
985 # See the GNU General Public License for more details.
987 # You should have received a copy of the GNU General Public License
988 # along with this program.
989 # If not, see L<http://www.gnu.org/licenses/>.
991 # vim: set fenc=UTF-8 ft=perl fdm=marker ts=4 sw=4 sts=4 et fo+=w :