Skip to content

Commit a2c6726

Browse files
committed
Merge branch 'ab/test-2'
* ab/test-2: (51 commits) tests: factor HOME=$(pwd) in test-lib.sh test-lib: use subshell instead of cd $new && .. && cd $old tests: simplify "missing PREREQ" message t/t0000-basic.sh: Run the passing TODO test inside its own test-lib test-lib: Allow overriding of TEST_DIRECTORY test-lib: Use "$GIT_BUILD_DIR" instead of "$TEST_DIRECTORY"/../ test-lib: Use $TEST_DIRECTORY or $GIT_BUILD_DIR instead of $(pwd) and ../ test: Introduce $GIT_BUILD_DIR cvs tests: do not touch test CVS repositories shipped with source t/t9602-cvsimport-branches-tags.sh: Add a PERL prerequisite t/t9601-cvsimport-vendor-branch.sh: Add a PERL prerequisite t/t7105-reset-patch.sh: Add a PERL prerequisite t/t9001-send-email.sh: convert setup code to tests t/t9001-send-email.sh: change from skip_all=* to prereq skip t/t9001-send-email.sh: Remove needless PROG=* assignment t/t9600-cvsimport.sh: change from skip_all=* to prereq skip lib-patch-mode tests: change from skip_all=* to prereq skip t/t3701-add-interactive.sh: change from skip_all=* to prereq skip tests: Move FILEMODE prerequisite to lib-prereq-FILEMODE.sh t/Makefile: Create test-results dir for smoke target ... Conflicts: t/t6035-merge-dir-to-symlink.sh
2 parents b480d38 + e4c62e6 commit a2c6726

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+968
-559
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@
186186
*.[aos]
187187
*.py[co]
188188
.depend/
189+
*.gcda
190+
*.gcno
191+
*.gcov
192+
/coverage-untested-functions
193+
/cover_db/
194+
/cover_db_html/
189195
*+
190196
/config.mak
191197
/autom4te.cache

Makefile

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,7 @@ TCL_PATH = tclsh
310310
TCLTK_PATH = wish
311311
PTHREAD_LIBS = -lpthread
312312
PTHREAD_CFLAGS =
313+
GCOV = gcov
313314

314315
export TCL_PATH TCLTK_PATH
315316

@@ -1499,6 +1500,7 @@ ifndef V
14991500
QUIET_BUILT_IN = @echo ' ' BUILTIN $@;
15001501
QUIET_GEN = @echo ' ' GEN $@;
15011502
QUIET_LNCP = @echo ' ' LN/CP $@;
1503+
QUIET_GCOV = @echo ' ' GCOV $@;
15021504
QUIET_SUBDIR0 = +@subdir=
15031505
QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \
15041506
$(MAKE) $(PRINT_DIR) -C $$subdir
@@ -2324,19 +2326,36 @@ coverage:
23242326
$(MAKE) coverage-build
23252327
$(MAKE) coverage-report
23262328

2329+
object_dirs := $(sort $(dir $(OBJECTS)))
23272330
coverage-clean:
2328-
rm -f *.gcda *.gcno
2331+
$(RM) $(addsuffix *.gcov,$(object_dirs))
2332+
$(RM) $(addsuffix *.gcda,$(object_dirs))
2333+
$(RM) $(addsuffix *.gcno,$(object_dirs))
2334+
$(RM) coverage-untested-functions
2335+
$(RM) -r cover_db/
2336+
$(RM) -r cover_db_html/
23292337

23302338
COVERAGE_CFLAGS = $(CFLAGS) -O0 -ftest-coverage -fprofile-arcs
23312339
COVERAGE_LDFLAGS = $(CFLAGS) -O0 -lgcov
2340+
GCOVFLAGS = --preserve-paths --branch-probabilities --all-blocks
23322341

23332342
coverage-build: coverage-clean
23342343
$(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" all
23352344
$(MAKE) CFLAGS="$(COVERAGE_CFLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" \
23362345
-j1 test
23372346

23382347
coverage-report:
2339-
gcov -b *.c
2348+
$(QUIET_GCOV)for dir in $(object_dirs); do \
2349+
$(GCOV) $(GCOVFLAGS) --object-directory=$$dir $$dir*.c || exit; \
2350+
done
2351+
2352+
coverage-untested-functions: coverage-report
23402353
grep '^function.*called 0 ' *.c.gcov \
23412354
| sed -e 's/\([^:]*\)\.gcov: *function \([^ ]*\) called.*/\1: \2/' \
2342-
| tee coverage-untested-functions
2355+
> coverage-untested-functions
2356+
2357+
cover_db: coverage-report
2358+
gcov2perl -db cover_db *.gcov
2359+
2360+
cover_db_html: cover_db
2361+
cover -report html -outputdir cover_db_html cover_db

t/Makefile

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#GIT_TEST_OPTS=--verbose --debug
1010
SHELL_PATH ?= $(SHELL)
11+
PERL_PATH ?= /usr/bin/perl
1112
TAR ?= $(TAR)
1213
RM ?= rm -f
1314

@@ -28,7 +29,6 @@ pre-clean:
2829

2930
clean:
3031
$(RM) -r 'trash directory'.* test-results
31-
$(RM) t????/cvsroot/CVSROOT/?*
3232
$(RM) -r valgrind/bin
3333
$(RM) .prove
3434

@@ -49,4 +49,42 @@ full-svn-test:
4949
valgrind:
5050
GIT_TEST_OPTS=--valgrind $(MAKE)
5151

52-
.PHONY: pre-clean $(T) aggregate-results clean valgrind
52+
# Smoke testing targets
53+
-include ../GIT-VERSION-FILE
54+
uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo unknown')
55+
uname_M := $(shell sh -c 'uname -m 2>/dev/null || echo unknown')
56+
57+
test-results:
58+
mkdir -p test-results
59+
60+
test-results/git-smoke.tar.gz: test-results
61+
$(PERL_PATH) ./harness \
62+
--archive="test-results/git-smoke.tar.gz" \
63+
$(T)
64+
65+
smoke: test-results/git-smoke.tar.gz
66+
67+
SMOKE_UPLOAD_FLAGS =
68+
ifdef SMOKE_USERNAME
69+
SMOKE_UPLOAD_FLAGS += -F username="$(SMOKE_USERNAME)" -F password="$(SMOKE_PASSWORD)"
70+
endif
71+
ifdef SMOKE_COMMENT
72+
SMOKE_UPLOAD_FLAGS += -F comments="$(SMOKE_COMMENT)"
73+
endif
74+
ifdef SMOKE_TAGS
75+
SMOKE_UPLOAD_FLAGS += -F tags="$(SMOKE_TAGS)"
76+
endif
77+
78+
smoke_report: smoke
79+
curl \
80+
-H "Expect: " \
81+
-F project=Git \
82+
-F architecture="$(uname_M)" \
83+
-F platform="$(uname_S)" \
84+
-F revision="$(GIT_VERSION)" \
85+
-F report_file=@test-results/git-smoke.tar.gz \
86+
$(SMOKE_UPLOAD_FLAGS) \
87+
http://smoke.git.nix.is/app/projects/process_add_report/1 \
88+
| grep -v ^Redirecting
89+
90+
.PHONY: pre-clean $(T) aggregate-results clean valgrind smoke smoke_report

t/README

Lines changed: 193 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,18 @@ Do:
268268
git push gh &&
269269
test ...
270270

271+
- Check the test coverage for your tests. See the "Test coverage"
272+
below.
273+
274+
Don't blindly follow test coverage metrics, they're a good way to
275+
spot if you've missed something. If a new function you added
276+
doesn't have any coverage you're probably doing something wrong,
277+
but having 100% coverage doesn't necessarily mean that you tested
278+
everything.
279+
280+
Tests that are likely to smoke out future regressions are better
281+
than tests that just inflate the coverage metrics.
282+
271283
Don't:
272284

273285
- exit() within a <script> part.
@@ -307,16 +319,31 @@ Keep in mind:
307319
Skipping tests
308320
--------------
309321

310-
If you need to skip all the remaining tests you should set skip_all
311-
and immediately call test_done. The string you give to skip_all will
312-
be used as an explanation for why the test was skipped. for instance:
322+
If you need to skip tests you should do so be using the three-arg form
323+
of the test_* functions (see the "Test harness library" section
324+
below), e.g.:
325+
326+
test_expect_success PERL 'I need Perl' "
327+
'$PERL_PATH' -e 'hlagh() if unf_unf()'
328+
"
329+
330+
The advantage of skipping tests like this is that platforms that don't
331+
have the PERL and other optional dependencies get an indication of how
332+
many tests they're missing.
333+
334+
If the test code is too hairy for that (i.e. does a lot of setup work
335+
outside test assertions) you can also skip all remaining tests by
336+
setting skip_all and immediately call test_done:
313337

314338
if ! test_have_prereq PERL
315339
then
316340
skip_all='skipping perl interface tests, perl not available'
317341
test_done
318342
fi
319343

344+
The string you give to skip_all will be used as an explanation for why
345+
the test was skipped.
346+
320347
End with test_done
321348
------------------
322349

@@ -350,6 +377,12 @@ library for your script to use.
350377
test_expect_success TTY 'git --paginate rev-list uses a pager' \
351378
' ... '
352379

380+
You can also supply a comma-separated list of prerequisites, in the
381+
rare case where your test depends on more than one:
382+
383+
test_expect_success PERL,PYTHON 'yo dawg' \
384+
' test $(perl -E 'print eval "1 +" . qx[python -c "print 2"]') == "4" '
385+
353386
- test_expect_failure [<prereq>] <message> <script>
354387

355388
This is NOT the opposite of test_expect_success, but is used
@@ -404,11 +437,12 @@ library for your script to use.
404437
- test_set_prereq SOME_PREREQ
405438

406439
Set a test prerequisite to be used later with test_have_prereq. The
407-
test-lib will set some prerequisites for you, e.g. PERL and PYTHON
408-
which are derived from ./GIT-BUILD-OPTIONS (grep test_set_prereq
409-
test-lib.sh for more). Others you can set yourself and use later
410-
with either test_have_prereq directly, or the three argument
411-
invocation of test_expect_success and test_expect_failure.
440+
test-lib will set some prerequisites for you, see the
441+
"Prerequisites" section below for a full list of these.
442+
443+
Others you can set yourself and use later with either
444+
test_have_prereq directly, or the three argument invocation of
445+
test_expect_success and test_expect_failure.
412446

413447
- test_have_prereq SOME PREREQ
414448

@@ -488,6 +522,45 @@ library for your script to use.
488522
...
489523
'
490524

525+
Prerequisites
526+
-------------
527+
528+
These are the prerequisites that the test library predefines with
529+
test_have_prereq.
530+
531+
See the prereq argument to the test_* functions in the "Test harness
532+
library" section above and the "test_have_prereq" function for how to
533+
use these, and "test_set_prereq" for how to define your own.
534+
535+
- PERL & PYTHON
536+
537+
Git wasn't compiled with NO_PERL=YesPlease or
538+
NO_PYTHON=YesPlease. Wrap any tests that need Perl or Python in
539+
these.
540+
541+
- POSIXPERM
542+
543+
The filesystem supports POSIX style permission bits.
544+
545+
- BSLASHPSPEC
546+
547+
Backslashes in pathspec are not directory separators. This is not
548+
set on Windows. See 6fd1106a for details.
549+
550+
- EXECKEEPSPID
551+
552+
The process retains the same pid across exec(2). See fb9a2bea for
553+
details.
554+
555+
- SYMLINKS
556+
557+
The filesystem we're on supports symbolic links. E.g. a FAT
558+
filesystem doesn't support these. See 704a3143 for details.
559+
560+
- SANITY
561+
562+
Test is not run by root user, and an attempt to write to an
563+
unwritable file is expected to fail correctly.
491564

492565
Tips for Writing Tests
493566
----------------------
@@ -515,3 +588,115 @@ the purpose of t0000-basic.sh, which is to isolate that level of
515588
validation in one place. Your test also ends up needing
516589
updating when such a change to the internal happens, so do _not_
517590
do it and leave the low level of validation to t0000-basic.sh.
591+
592+
Test coverage
593+
-------------
594+
595+
You can use the coverage tests to find code paths that are not being
596+
used or properly exercised yet.
597+
598+
To do that, run the coverage target at the top-level (not in the t/
599+
directory):
600+
601+
make coverage
602+
603+
That'll compile Git with GCC's coverage arguments, and generate a test
604+
report with gcov after the tests finish. Running the coverage tests
605+
can take a while, since running the tests in parallel is incompatible
606+
with GCC's coverage mode.
607+
608+
After the tests have run you can generate a list of untested
609+
functions:
610+
611+
make coverage-untested-functions
612+
613+
You can also generate a detailed per-file HTML report using the
614+
Devel::Cover module. To install it do:
615+
616+
# On Debian or Ubuntu:
617+
sudo aptitude install libdevel-cover-perl
618+
619+
# From the CPAN with cpanminus
620+
curl -L http://cpanmin.us | perl - --sudo --self-upgrade
621+
cpanm --sudo Devel::Cover
622+
623+
Then, at the top-level:
624+
625+
make cover_db_html
626+
627+
That'll generate a detailed cover report in the "cover_db_html"
628+
directory, which you can then copy to a webserver, or inspect locally
629+
in a browser.
630+
631+
Smoke testing
632+
-------------
633+
634+
The Git test suite has support for smoke testing. Smoke testing is
635+
when you submit the results of a test run to a central server for
636+
analysis and aggregation.
637+
638+
Running a smoke tester is an easy and valuable way of contributing to
639+
Git development, particularly if you have access to an uncommon OS on
640+
obscure hardware.
641+
642+
After building Git you can generate a smoke report like this in the
643+
"t" directory:
644+
645+
make clean smoke
646+
647+
You can also pass arguments via the environment. This should make it
648+
faster:
649+
650+
GIT_TEST_OPTS='--root=/dev/shm' TEST_JOBS=10 make clean smoke
651+
652+
The "smoke" target will run the Git test suite with Perl's
653+
"TAP::Harness" module, and package up the results in a .tar.gz archive
654+
with "TAP::Harness::Archive". The former is included with Perl v5.10.1
655+
or later, but you'll need to install the latter from the CPAN. See the
656+
"Test coverage" section above for how you might do that.
657+
658+
Once the "smoke" target finishes you'll see a message like this:
659+
660+
TAP Archive created at <path to git>/t/test-results/git-smoke.tar.gz
661+
662+
To upload the smoke report you need to have curl(1) installed, then
663+
do:
664+
665+
make smoke_report
666+
667+
To upload the report anonymously. Hopefully that'll return something
668+
like "Reported #7 added.".
669+
670+
If you're going to be uploading reports frequently please request a
671+
user account by E-Mailing [email protected]. Once you have a username
672+
and password you'll be able to do:
673+
674+
SMOKE_USERNAME=<username> SMOKE_PASSWORD=<password> make smoke_report
675+
676+
You can also add an additional comment to attach to the report, and/or
677+
a comma separated list of tags:
678+
679+
SMOKE_USERNAME=<username> SMOKE_PASSWORD=<password> \
680+
SMOKE_COMMENT=<comment> SMOKE_TAGS=<tags> \
681+
make smoke_report
682+
683+
Once the report is uploaded it'll be made available at
684+
http://smoke.git.nix.is, here's an overview of Recent Smoke Reports
685+
for Git:
686+
687+
http://smoke.git.nix.is/app/projects/smoke_reports/1
688+
689+
The reports will also be mirrored to GitHub every few hours:
690+
691+
http://github.com/gitsmoke/smoke-reports
692+
693+
The Smolder SQLite database is also mirrored and made available for
694+
download:
695+
696+
http://github.com/gitsmoke/smoke-database
697+
698+
Note that the database includes hashed (with crypt()) user passwords
699+
and E-Mail addresses. Don't use a valuable password for the smoke
700+
service if you have an account, or an E-Mail address you don't want to
701+
be publicly known. The user accounts are just meant to be convenient
702+
labels, they're not meant to be secure.

t/harness

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/usr/bin/perl
2+
use strict;
3+
use warnings;
4+
use Getopt::Long ();
5+
use TAP::Harness::Archive;
6+
7+
Getopt::Long::Parser->new(
8+
config => [ qw/ pass_through / ],
9+
)->getoptions(
10+
'jobs:1' => \(my $jobs = $ENV{TEST_JOBS}),
11+
'archive=s' => \my $archive,
12+
) or die "$0: Couldn't getoptions()";
13+
14+
TAP::Harness::Archive->new({
15+
jobs => $jobs,
16+
archive => $archive,
17+
($ENV{GIT_TEST_OPTS}
18+
? (test_args => [ split /\s+/, $ENV{GIT_TEST_OPTS} ])
19+
: ()),
20+
extra_properties => {},
21+
})->runtests(@ARGV);

0 commit comments

Comments
 (0)