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
};
27 our $CMDB = "git-update-dirs";
28 our $CMD = "../$CMDB";
42 $progname =~ s/^.*\/(.*?)$/$1/;
43 our $VERSION = '0.0.0';
46 my %descriptions = ();
47 my %disable_already_tested = ();
49 Getopt
::Long
::Configure
('bundling');
52 'all|a' => \
$Opt{'all'},
53 'help|h' => \
$Opt{'help'},
54 'quiet|q+' => \
$Opt{'quiet'},
55 'todo|t' => \
$Opt{'todo'},
56 'verbose|v+' => \
$Opt{'verbose'},
57 'version' => \
$Opt{'version'},
59 ) || die("$progname: Option error. Use -h for help.\n");
61 $Opt{'verbose'} -= $Opt{'quiet'};
62 $Opt{'help'} && usage
(0);
63 if ($Opt{'version'}) {
74 diag
(sprintf('========== Executing %s v%s ==========',
75 $progname, $VERSION));
77 if ($Opt{'todo'} && !$Opt{'all'}) {
83 testcmd("$CMD command", # {{{
96 my $Tmptop = "tmp-git-update-dirs-t-$$-" . substr(rand, 2, 8);
97 ok
(mkdir($Tmptop), "mkdir [Tmptop]") ||
98 BAIL_OUT
("$Tmptop: mkdir error, can't continue\n");
99 ok
(chdir($Tmptop), "chdir [Tmptop]") ||
100 BAIL_OUT
("$progname: $Tmptop: chdir error, can't continue\n");
101 chomp($ENV{'HOME'} = `pwd`);
102 testcmd
('git config --global user.name "Suttleif Fisen"', '', '', 0,
103 'git config --global user.name "Suttleif Fisen"');
104 testcmd
('git config --global user.email suttleif@example.com', '', '', 0,
105 'git config --global user.email suttleif@example.com');
106 testcmd
('git config --global init.defaultbranch master', '', '', 0,
107 'git config --global init.defaultbranch master');
110 diag
('Testing -h (--help) option...');
111 likecmd
("$CMD -h", # {{{
112 '/ Show this help/i',
115 'Option -h prints help screen',
119 diag
('Testing -v (--verbose) option...');
120 likecmd
("$CMD -hv", # {{{
121 '/^\n\S+ \d+\.\d+\.\d+/s',
124 'Option -v with -h returns version number and help screen',
128 diag
('Testing --version option...');
129 likecmd
("$CMD --version", # {{{
130 '/^\S+ \d+\.\d+\.\d+/',
133 'Option --version returns version number',
137 likecmd
("git --version", # {{{
142 ) || BAIL_OUT
("git is not installed, cannot continue");
145 if (`git-annex version 2>/dev/null` !~ /^git-annex version/) {
146 # FIXME: Use with existing annex tests instead
147 diag
("git-annex is not installed here, skipping tests");
150 likecmd
("git annex version", # {{{
151 '/^git-annex version:/',
154 'git-annex is installed',
155 ) || BAIL_OUT
("git-annex is not installed, cannot continue");
158 diag
('Initialise repositories');
159 likecmd
("git init --bare bare.git", # {{{
163 'Create bare Git repository',
167 likecmd
("git clone bare.git repo", # {{{
171 'Clone bare.git to \'repo\'',
176 test_repo
('repo', 0);
177 test_repo
('bare.git', 1);
184 repo
/sub1/subrepo
1/subsubrepo1
.git
187 for my $dir (@dir_list) {
188 my $bare_str = ($dir =~ /\.git$/ ?
' --bare' : '');
189 likecmd
("git$bare_str init $dir",
193 "Create repo '$dir'",
197 testcmd
("$CMD --recursive -nf", # {{{
199 ================ ./repo ================
201 ================ ./repo/sub1 ================
203 ================ ./repo/sub1/subrepo1 ================
205 ================ ./repo/sub2 ================
208 "git-update-dirs: Simulating 'git fetch --all'...\n" x
4,
210 "--recursive option",
214 testcmd
("$CMD -rfn", # {{{
216 ================ ./repo ================
218 ================ ./repo/sub1 ================
220 ================ ./repo/sub1/subrepo1 ================
222 ================ ./repo/sub2 ================
225 "git-update-dirs: Simulating 'git fetch --all'...\n" x
4,
227 "-r (recursive) option",
231 create_file
("filelist.txt", join("\n", @dir_list));
232 testcmd
("$CMD --dirs-from filelist.txt -nf", # {{{
234 ================ repo/sub2 ================
236 ================ repo/sub1 ================
238 ================ repo/sub1/subrepo1 ================
240 ================ repo/bare1.git ================
242 ================ repo/sub1/subrepo1/subsubrepo1.git ================
245 "git-update-dirs: Simulating 'git fetch --all'...\n" x
5,
247 "--dirs-from option",
251 testcmd
("$CMD --fetch -n --dirs-from - <filelist.txt", # {{{
253 ================ repo/sub2 ================
255 ================ repo/sub1 ================
257 ================ repo/sub1/subrepo1 ================
259 ================ repo/bare1.git ================
261 ================ repo/sub1/subrepo1/subsubrepo1.git ================
264 "git-update-dirs: Simulating 'git fetch --all'...\n" x
5,
266 "Read file list from stdin with '--dirs-from -'",
270 create_file
("filelist2.txt", <<END);
275 testcmd
("$CMD --fetch -n --dirs-from filelist.txt " .
276 "--dirs-from filelist2.txt", # {{{
278 ================ repo/sub2 ================
280 ================ repo/sub1 ================
282 ================ repo/sub1/subrepo1 ================
284 ================ repo/bare1.git ================
286 ================ repo/sub1/subrepo1/subsubrepo1.git ================
288 ================ repo/sub2 ================
290 ================ repo/bare1.git ================
292 ================ repo/sub1 ================
295 "git-update-dirs: Simulating 'git fetch --all'...\n" x
8,
297 "--dirs-from is specified twice, read from two files",
301 ok
(unlink("filelist.txt"), "Delete filelist.txt");
302 ok
(unlink("filelist2.txt"), "Delete filelist2.txt");
305 testcmd
("rm -rf bare.git", # {{{
309 'Remove bare test repository',
313 testcmd
("rm -rf repo", # {{{
317 'Remove non-bare test repository',
321 ok
(unlink(".gitconfig"), "Delete .gitconfig");
322 testcmd
("rm -rf .cache", "", "", 0, "Delete .cache/, created by git-annex");
323 testcmd
("rm -rf .ssh", "", "", 0, "Delete .ssh/, created by git-annex");
324 ok
(chdir(".."), "chdir ..");
325 ok
(-d
$Tmptop, "[Tmptop] exists");
326 ok
(rmdir($Tmptop), "rmdir [Tmptop]");
327 ok
(!-d
$Tmptop, "[Tmptop] is gone");
332 if ($Opt{'all'} || $Opt{'todo'}) {
333 diag
('Running TODO tests...'); # {{{
338 # Insert TODO tests here.
344 diag
('Testing finished.');
351 my ($repo, $is_bare) = @_;
353 diag
("Run tests in $repo");
354 $current_repo = $repo;
355 ok
(chdir($repo), "chdir $repo") || BAIL_OUT
('chdir error');
356 $CMD = "../../../$CMDB";
358 BAIL_OUT
("test_repo(): \$CMD is '$CMD', that's wrong");
361 likecmd
("git remote add bare ../bare.git", # {{{
365 'Create bare remote',
369 likecmd
("git commit --allow-empty -m 'Empty start commit'", # {{{
373 'Create empty start commit',
377 likecmd
("git push bare master", # {{{
381 'Push master to the bare repo',
386 likecmd
("git annex init " . ($is_bare ?
"bare" : "repo"), # {{{
390 "Make $repo an annex",
394 my $sep = "================ . ================\n";
396 diag
('--exec-before');
397 testcmd
("$CMD -E 'echo This is nice' .", # {{{
398 "${sep}This is nice\n\n",
399 "git-update-dirs: Executing 'echo This is nice'...\n",
401 "$repo: Test -E option",
405 testcmd
("$CMD --exec-before 'echo This is nice' .", # {{{
406 "${sep}This is nice\n\n",
407 "git-update-dirs: Executing 'echo This is nice'...\n",
409 "$repo: Test --exec-before option",
413 test_disabled
("exec-before", "$CMD --exec-before echo .");
415 testcmd
("$CMD -n -l .", # {{{
417 "git-update-dirs: Simulating 'lpar'...\n" .
418 "git-update-dirs: Simulating 'lpar'...\n",
420 "$repo: Test -l option",
424 testcmd
("$CMD -n --lpar .", # {{{
426 "git-update-dirs: Simulating 'lpar'...\n" .
427 "git-update-dirs: Simulating 'lpar'...\n",
429 "$repo: Test --lpar option",
433 test_disabled
("lpar");
435 test_option
('-t', 'git fsck');
436 test_option
('--test', 'git fsck');
437 diag
('--fetch-prune');
438 test_option
('-F', 'git fetch --all --prune');
439 test_option
('--fetch-prune', 'git fetch --all --prune');
441 test_option
('-f', 'git fetch --all');
442 test_option
('--fetch', 'git fetch --all');
445 testcmd
("$CMD -n -p", '', '', 0, "$repo: Test -p");
446 testcmd
("$CMD -n --pull", '', '', 0, "$repo: Test --pull");
448 test_option
('-p', 'git pull --ff-only');
449 test_option
('--pull', 'git pull --ff-only');
452 test_option
('-g', 'ga sync');
453 test_option
('--ga-sync', 'ga sync');
454 diag
('--ga-dropget');
455 test_option
('-G', nolf
(<<END)); # {{{
457 git-update-dirs: Simulating 'ga drop --auto'...
458 git-update-dirs: Simulating 'ga sync'...
459 git-update-dirs: Simulating 'ga get --auto'...
460 git-update-dirs: Simulating 'ga sync
464 test_option
('--ga-dropget', nolf
(<<END)); # {{{
466 git-update-dirs: Simulating 'ga drop --auto'...
467 git-update-dirs: Simulating 'ga sync'...
468 git-update-dirs: Simulating 'ga get --auto'...
469 git-update-dirs: Simulating 'ga sync
473 diag
('--ga-dropunused');
474 test_option
('-u', nolf
(<<END)); # {{{
476 git-update-dirs: Simulating 'ga unused'...
477 git-update-dirs: Simulating 'ga dropunused all'...
478 git-update-dirs: Simulating 'ga sync
482 test_option
('--ga-dropunused', nolf
(<<END)); # {{{
484 git-update-dirs: Simulating 'ga unused'...
485 git-update-dirs: Simulating 'ga dropunused all'...
486 git-update-dirs: Simulating 'ga sync
490 diag
('--ga-moveunused');
491 test_option
('-U', nolf
(<<END)); # {{{
496 testcmd
('git remote add seagate-3tb yep', # {{{
500 "$repo: Add fake seagate-3tb remote",
504 test_option
('--ga-moveunused', nolf
(<<END)); # {{{
506 git-update-dirs: Simulating 'ga unused'...
507 git-update-dirs: Simulating 'ga move --unused --to seagate-3tb'...
508 git-update-dirs: Simulating 'ga sync
513 test_option
('-N', 'ga-getnew');
514 test_option
('--ga-getnew', 'ga-getnew');
515 diag
('--ga-update-desc');
516 test_option
('-S', 'ga update-desc');
517 test_option
('--ga-update-desc', 'ga update-desc');
519 test_option
('-d', 'git dangling');
520 test_option
('--dangling', 'git dangling');
523 test_option
('-a', nolf
(<<END)); # {{{
525 git-update-dirs: Simulating 'git allbr -a'...
526 git-update-dirs: Simulating 'git checkout -
530 test_option
('--allbr', nolf
(<<END)); # {{{
532 git-update-dirs: Simulating 'git allbr -a'...
533 git-update-dirs: Simulating 'git checkout -
538 testcmd
("$CMD . -n --allbr", # {{{
542 'Ignore --allbr if it\'s only specified once in a non-bare repo',
546 testcmd
("$CMD . -n -a", # {{{
550 'Ignore -a if it\'s only specified once in a non-bare repo',
555 testcmd
("$CMD -aan .", # {{{
558 git-update-dirs: Simulating 'git nobr'...
559 git-update-dirs: Simulating 'git allbr -a'...
560 git-update-dirs: Simulating 'git checkout -'...
563 "$repo: -aa works in non-bare repos, though",
568 test_option
('-P', 'git pa');
569 test_option
('--push', 'git pa');
571 testcmd
("$CMD --dry-run -s .", # {{{
572 "================ . ================\n\n",
575 "$repo: Test -s option, .gitmodules is missing",
579 testcmd
("touch .gitmodules", '', '', 0, "$repo: Create empty .gitmodules");
580 test_option
('--submodule', nolf
(<<END)); # {{{
581 git submodule init'...
582 git-update-dirs: Simulating 'git submodule update
587 my $objects = $is_bare ?
'objects' : '.git\/objects';
588 my $compress_output = # {{{
590 '================ \. ================\n' .
594 'Saved : \d+ \(\d+.\d+%\)\n' .
595 'Number of files in ' .
597 ': before: \d+, after: \d+, saved: \d+\n' .
601 'Total : \d+ \(\d+.\d+%\)\n' .
602 'Number of object files: before: \d+, after: \d+, saved: \d+\n' .
606 likecmd
("$CMD -n -c .", # {{{
609 'git-update-dirs: Simulating \'git count-objects -vH\'\.\.\.\n' .
610 'git-update-dirs: Simulating \'git gc\'\.\.\.\n' .
613 "$repo: Test -c option",
617 likecmd
("$CMD -n --compress .", # {{{
620 'git-update-dirs: Simulating \'git count-objects -vH\'\.\.\.\n' .
621 'git-update-dirs: Simulating \'git gc\'\.\.\.\n' .
624 "$repo: Test --compress option",
628 system("git config git-update-dirs.no-compress true");
629 likecmd
("$CMD -n -c .", # {{{
630 '/^================ \. ================\n\n' .
633 'Number of object files: before: \d+, after: \d+, saved: \d+\n/',
636 "$repo: Test disabling of -c",
640 system("git config --unset git-update-dirs.no-compress");
641 diag
('--aggressive-compress');
642 likecmd
("$CMD -n -C .", # {{{
645 'git-update-dirs: Simulating \'git count-objects -vH\'\.\.\.\n' .
646 'git-update-dirs: Simulating \'git gc --aggressive\'\.\.\.\n' .
649 "$repo: Test -C option",
653 likecmd
("$CMD --dry-run --aggressive-compress .", # {{{
656 'git-update-dirs: Simulating \'git count-objects -vH\'\.\.\.\n' .
657 'git-update-dirs: Simulating \'git gc --aggressive\'\.\.\.\n' .
660 "$repo: Test --aggressive-compress option",
664 system("git config git-update-dirs.no-aggressive-compress true");
665 likecmd
("$CMD -n -C .", # {{{
666 '/^================ \. ================\n\n' .
669 'Number of object files: before: \d+, after: \d+, saved: \d+\n/',
672 "$repo: Test disabling of -C",
676 system("git config --unset git-update-dirs.no-aggressive-compress");
677 diag
('--delete-dangling');
679 # FIXME: This behaviour is up for debate. Should -D be ignored
680 # in bare repositories by default?
681 testcmd
("$CMD -n -D .", # {{{
689 testcmd
("$CMD -n --delete-dangling .", # {{{
693 "$repo: Test --delete-dangling",
698 test_option
('-D', 'git dangling -D');
699 test_option
('--delete-dangling', 'git dangling -D');
701 diag
('--exec-after');
702 testcmd
("$CMD -e 'echo This is nice' .", # {{{
703 "${sep}This is nice\n\n",
704 "git-update-dirs: Executing 'echo This is nice'...\n",
706 "$repo: Test -e option",
710 testcmd
("$CMD --exec-after 'echo This is nice' .", # {{{
711 "${sep}This is nice\n\n",
712 "git-update-dirs: Executing 'echo This is nice'...\n",
714 "$repo: Test --exec-after option",
718 test_disabled
("exec-after", "$CMD --exec-after echo .");
719 diag
('--all-options');
720 my ($allbr_str, $pull_str);
723 git-update-dirs: Simulating 'git nobr'...
724 git-update-dirs: Simulating 'git allbr -a'...
725 git-update-dirs: Simulating 'git checkout -'...
730 $pull_str = "git-update-dirs: Simulating 'git pull --ff-only'...\n";
732 testcmd
("$CMD --all-options -n .", # {{{
735 git-update-dirs: Simulating 'lpar'...
736 git-update-dirs: Simulating 'git fetch --all --prune'...
737 ${pull_str}git-update-dirs: Simulating 'ga sync'...
738 git-update-dirs: Simulating 'ga update-desc'...
739 git-update-dirs: Simulating 'git dangling'...
740 ${allbr_str}git-update-dirs: Simulating 'git pa'...
741 git-update-dirs: Simulating 'git submodule init'...
742 git-update-dirs: Simulating 'git submodule update'...
743 git-update-dirs: Simulating 'lpar'...
746 "$repo: Test --all-options, allbr is ignored",
750 testcmd
("$CMD -Ana .", # {{{
753 git-update-dirs: Simulating 'lpar'...
754 git-update-dirs: Simulating 'git fetch --all --prune'...
755 ${pull_str}git-update-dirs: Simulating 'ga sync'...
756 git-update-dirs: Simulating 'ga update-desc'...
757 git-update-dirs: Simulating 'git dangling'...
758 git-update-dirs: Simulating 'git nobr'...
759 git-update-dirs: Simulating 'git allbr -a'...
760 git-update-dirs: Simulating 'git checkout -'...
761 git-update-dirs: Simulating 'git pa'...
762 git-update-dirs: Simulating 'git submodule init'...
763 git-update-dirs: Simulating 'git submodule update'...
764 git-update-dirs: Simulating 'lpar'...
767 "$repo: Test the -A option with an extra -a to get some allbr action",
771 ok
(chdir('..'), "$repo: chdir ..");
772 $CMD = "../../$CMDB";
778 # Strip \n from string, replacement for chomp() {{{
787 my ($option, $cmd) = @_;
790 BAIL_OUT
("\$CMD is '$CMD', that's wrong");
792 testcmd
("$CMD -n $option .",
793 "================ . ================\n\n",
794 "git-update-dirs: Simulating '$cmd'...\n",
796 "$current_repo: Test $option option",
798 if ($option =~ /^--(.+)$/ && !defined($disable_already_tested{$1})) {
806 # Test disabling of commands {{{
807 my ($longopt, $command) = @_;
808 system("git config git-update-dirs.no-$longopt true");
809 # Some commands calls "ga sync", so also disable "ga sync" to
810 # avoid that single line appear in the output.
811 if ($longopt =~ /^(ga-dropget|ga-dropunused|ga-moveunused)$/) {
812 system("git config git-update-dirs.no-ga-sync true");
814 defined($command) || ($command = "../../../$CMDB -n --$longopt .");
816 "================ . ================\n\n",
819 "$current_repo: --$longopt is disabled",
821 system("git config --unset git-update-dirs.no-$longopt");
822 if ($longopt =~ /^(ga-dropget|ga-dropunused|ga-moveunused)$/) {
823 system("git config --unset git-update-dirs.no-ga-sync");
825 $disable_already_tested{$longopt} = 1;
832 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
833 defined($descriptions{$Desc}) &&
834 BAIL_OUT
("testcmd(): '$Desc' description is used twice");
835 $descriptions{$Desc} = 1;
837 my $cmd_outp_str = $Opt{'verbose'} >= 1 ?
"\"$Cmd\" - " : '';
838 my $Txt = join('', $cmd_outp_str, defined($Desc) ?
$Desc : '');
839 my $TMP_STDERR = "$CMDB-stderr.tmp";
842 if (defined($Exp_stderr)) {
843 $stderr_cmd = " 2>$TMP_STDERR";
845 $retval &= is
(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
847 if (defined($Exp_stderr)) {
848 $retval &= is
(file_data
($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
851 diag
("Warning: stderr not defined for '$Txt'");
853 $retval &= is
($ret_val >> 8, $Exp_retval, "$Txt (retval)");
861 my ($Cmd, $Exp_stdout, $Exp_stderr, $Exp_retval, $Desc) = @_;
862 defined($descriptions{$Desc}) &&
863 BAIL_OUT
("likecmd(): '$Desc' description is used twice");
864 $descriptions{$Desc} = 1;
866 my $cmd_outp_str = $Opt{'verbose'} >= 1 ?
"\"$Cmd\" - " : '';
867 my $Txt = join('', $cmd_outp_str, defined($Desc) ?
$Desc : '');
868 my $TMP_STDERR = "$CMDB-stderr.tmp";
871 if (defined($Exp_stderr)) {
872 $stderr_cmd = " 2>$TMP_STDERR";
874 $retval &= like
(`$Cmd$stderr_cmd`, $Exp_stdout, "$Txt (stdout)");
876 if (defined($Exp_stderr)) {
877 $retval &= like
(file_data
($TMP_STDERR), $Exp_stderr, "$Txt (stderr)");
880 diag
("Warning: stderr not defined for '$Txt'");
882 $retval &= is
($ret_val >> 8, $Exp_retval, "$Txt (retval)");
889 # Return file content as a string {{{
893 open(my $fp, '<', $File) or return undef;
902 # Create new file and fill it with data {{{
903 my ($file, $text) = @_;
905 if (open(my $fp, ">$file")) {
911 "$file was successfully created",
914 return($retval); # 0 if error, 1 if ok
919 # Print program version {{{
920 print("$progname $VERSION\n");
926 # Send the help message to stdout {{{
929 if ($Opt{'verbose'}) {
935 Usage: $progname [options]
937 Contains tests for the $CMDB(1) program.
942 Run all tests, also TODOs.
946 Be more quiet. Can be repeated to increase silence.
948 Run only the TODO tests.
950 Increase level of verbosity. Can be repeated.
952 Print version information.
960 # Print a status message to stderr based on verbosity level {{{
961 my ($verbose_level, $Txt) = @_;
963 $verbose_level > $Opt{'verbose'} && return;
964 print(STDERR
"$progname: $Txt\n");
971 # This program is free software; you can redistribute it and/or modify
972 # it under the terms of the GNU General Public License as published by
973 # the Free Software Foundation; either version 2 of the License, or (at
974 # your option) any later version.
976 # This program is distributed in the hope that it will be useful, but
977 # WITHOUT ANY WARRANTY; without even the implied warranty of
978 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
979 # See the GNU General Public License for more details.
981 # You should have received a copy of the GNU General Public License
982 # along with this program.
983 # If not, see L<http://www.gnu.org/licenses/>.
985 # vim: set fenc=UTF-8 ft=perl fdm=marker ts=4 sw=4 sts=4 et fo+=w :