-
Notifications
You must be signed in to change notification settings - Fork 8
How to Start Working with Tests in the Perl Core Distribution
If you are reading this document, we presume that you would like to contribute to the development of a proof-of-concept for the next major version of the Perl programming language -- a major version likely to have new default behavior.
You should already have read these two documents:
The latter pertains more to writing code for this project rather than understanding test files, but should nonetheless be read at least once.
You should by now have two git checkouts on your machine, one for Perl 5 and one for (unofficial) Perl 7.
- 1 Perl 5 repository: https://github.com/Perl/perl5
-
-
Default branch:
blead
-
Reference branch:
jkeenan/v5.32.0
-
Recommended name for local root directory:
perl
-
- 2 Perl 7 repository: https://github.com/atoomic/perl
-
-
Default branch:
alpha
-
Working branch: Currently
alpha-dev-02-strict
The working branch will change depending on which Objective is the current target of our work.
-
Recommended name for local root directory:
perl-atoomic
-
In the course of your work in either of these repositories you may occasion to create patches or submit pull requests. Acceptance of either patches or pull requests entitles you to be listed in the AUTHORS file in the Perl core distribution. For that listing, we need valid entries for [name]
and [email]
in the [user]
entry in your ~/.gitconfig file or in the .gitconfig file in your checkout directory.
The name
should be your real name or your professional name. Unless there is a reason why your contributions to Perl should be secret, we discourage use of IRC nicks, GitHub or Twitter '@s', and so forth.
The email
address should be one at which the managers of the Perl core distribution can reach you. For spam reduction or other reasons, you may wish to create a free email account which you only use for the purpose of making contributions to the Perl core distribution, but that is up to you.
Example of .gitconfig:
[user]
email = some_perl_contributor@yahoo.com
name = Some Perl User
[core]
editor = vi
[push]
default = simple
... where email
, name
, editor
and default
are preceded by hard-tabs.
Assuming that you have forked each source repository to your own github account and then cloned down each to your local machine, when you type git remote -v
in the root directory of your checkout, you should see something like this:
- 1 Perl 5
-
origin git@github.com:username/perl5.git (fetch) origin git@github.com:username/perl5.git (push)
- 2 Perl 7
-
origin git@github.com:username/perl.git (fetch) origin git@github.com:username/perl.git (push)
When you get to the point of submitting pull requests for Perl 7, you will find it useful to have two "remotes" on github.com:
- 1 remote
origin
-
This is the remote which you established automatically by cloning your Perl 5 and Perl 7 repositories from your github.com site to your local machine. Until such time as you get commit privileges to the Perl 7 repository, this is the remote (a) to which you will push commits (via
git commit
) and from which you will file pull requests. - 2 remote
upstream
-
From time to time you will want to refresh your local checkout of the Perl 7 codebase with the changes that developers have uploaded. To do this you will need to establish the (quasi-)official Perl 7 repository as a second remote which we will conventionally name
upstream
. That can be done with the following command in yourperl-atoomic
checkout of Perl 7:$ git remote add upstream git@github.com:atoomic/perl.git
Now, in your
perl-atoomic
directory, when you say:$ git remote --verbose
... you should see something like this:
origin git@github.com:username/perl.git (fetch) origin git@github.com:username/perl.git (push) upstream git@github.com:atoomic/perl.git (fetch) upstream git@github.com:atoomic/perl.git (push)
(You could similarly add an
upstream
remote to your Perl 5 checkout, but that would only be useful if you were working on that codebase.)We will discuss how to refresh your local checkout with changes from
upstream
further below.
For the purpose of working on a given Objective you will need to be able to make quick comparisons between the state of a given file in the Perl 7 codebase and the state of the same file at the point where Perl 7 development forked off from Perl 5 development. That point is designated by tag v5.32.0
in the Perl 5 repository. For convenience, it is also represented by the following branch in that repository: jkeenan/v5.32.0
. We'll call this branch the reference branch for Perl 5. So in your checkout of Perl 5, you should probably do a checkout of that branch and (unless, you want to work on Perl 5 blead
) leave it there as a baseline point of reference.
$ git checkout -b jkeenan/v5.32.0 origin/jkeenan/v5.32.0
In your Perl 7 repository, you should checkout whatever is the working branch (sometimes referred to as the objective branch at the present time). As of Aug 14 2020, that would be:
$ git checkout -b alpha-dev-02-strict origin/alpha-dev-02-strict
You may wish to write a small shell script to make a rapid comparison between the same file in the two different repositories. Something like this:
$ cat qdiff
#!/bin/sh
set -u
set -e
if [ "$#" -gt 0 ]; then
TESTFILE=$1
else
exit 1
fi
# for suitably defined directories for your two checkouts
diff -w "$GIT_WORKDIR/perl/$TESTFILE" \
"$GIT_WORKDIR/perl-atoomic/$TESTFILE"
Called like this:
$ qdiff lib/Symbol.t
18c18
< $sym1 = gensym;
---
> my $sym1 = gensym;
21c21
< $sym2 = gensym;
---
> my $sym2 = gensym;
36c36
< $FOO = 'Eymascalar';
---
> $::FOO = 'Eymascalar';
41c41
< is( $FOO, 'Eymascalar', 'leaves scalar alone' );
---
> is( $::FOO, 'Eymascalar', 'leaves scalar alone' );
YMMV.
In each checkout, you should build (but not install) a perl
executable capable of running any test in the codebase.
$ sh ./Configure -des -Dusedevel -Dusethreads && make test_prep
We recommend building a threaded perl
not because Perl has great support for threading -- many would say it doesn't -- but because many test files only get run on threaded builds.
make test_prep
is a command you will run many times as you work on the test suite. Certain code changes cause changes in Perl's header files. Running make test_prep
updates those header files for you before you run individual tests. Whenever you have pulled new code from upstream, you should probably run make test_prep
.
$ git pull upstream <working_branch>
# upstream changes are pulled into your local branch
$ make test_prep
Should you want to leave your machine for 10 to 15 minutes for coffee or beer, you might want to run make test_harness
while you're AFK. That command runs the entire test-suite. In part as a result of your work, each day the number of files that FAIL
during make test_harness
goes down.
Generally speaking an individual test file can be run in one or two ways:
- 1
./perl -Ilib path/to/testfile.t
-
Let's call this "running from the root directory". This is fine for one test at a time.
$ ./perl -Ilib lib/Symbol.t 1..26 ok 1 - check $_ clobbering ok 2 - gensym() returns a GLOB ok 3 - gensym() returns a different GLOB ... ok 24 - third transient stash exists ok 25 - third transient variable in stash ok 26 - delete_package() returns undef due to undefined leaf
Occasionally, a test file expects to be run in Perl's
taint
mode.$ ./perl -Ilib t/op/utftaint.t "-T" is on the #! line, it must also be used on the command line at t/op/utftaint.t line 1.
The file will have to be called with a
-T
switch on the command-line. So this file needs to be invoked as:$ ./perl -Ilib -T t/op/utftaint.t | head -5 1..89 ok 1 - tainted: ascii, before test ok 2 - compare: ascii, concat left ok 3 - tainted: ascii, concat left ok 4 - compare: ascii, concat right ... ok 87 - matching a regexp is taint agnostic ok 88 - therefore swash_init should be taint agnostic ok 89 - RT \#122148
- 2 Running tests via a harness
-
You can also run one or more tests in one process by having them run by a harness. Because the program called harness lives in the t/ subdirectory, to run the harness you first need to switch to the t/ subdirectory, run the tests, then switch back at the end. You have to specify a relative path to the test files starting from the t/ subdirectory. Examples:
-
Single file run through the harness
$ cd t; ./perl harness op/utftaint.t; cd - op/utftaint.t .. ok All tests successful. Files=1, Tests=89, ... Result: PASS
Note that the harness program takes care of providing the
-T
switch for this file. -
Single file run through the harness with verbose output requested
$ cd t; ./perl harness -v op/utftaint.t; cd - ok 1 - tainted: ascii, before test ok 2 - compare: ascii, concat left ok 3 - tainted: ascii, concat left ok 4 - compare: ascii, concat right ... ok 88 - therefore swash_init should be taint agnostic ok 89 - RT \#122148 ok All tests successful. Files=1, Tests=89, ... Result: PASS
-
Multiple files, specified via shell expansion, run through the harness
$ cd t; ./perl harness op/*taint.t; cd - op/utftaint.t .. ok op/taint.t ..... ok All tests successful. Files=2, Tests=1141, ... Result: PASS $ cd t; TEST_JOBS=1 ./perl harness ../ext/File-Find/t/*.t; cd - ../ext/File-Find/t/find.t ... ok ../ext/File-Find/t/taint.t .. ok All tests successful. Files=2, Tests=283, ... Result: PASS
-
A test file which still has compilation errors
$ cd t; TEST_JOBS=1 ./perl harness ../lib/overload.t; cd - ../lib/overload.t .. Global symbol "$c" requires explicit package name (did you forget to declare "my $c"?) at ../lib/overload.t line 64. ... Global symbol "$aI" requires explicit package name (did you forget to declare "my $aI"?) at ../lib/overload.t line 343. Execution of ../lib/overload.t aborted due to compilation errors. ../lib/overload.t .. Dubious, test returned 2 (wstat 512, 0x200) No subtests run Test Summary Report ------------------- ../lib/overload.t (Wstat: 512 Tests: 0 Failed: 0) Non-zero exit status: 2 Parse errors: No plan found in TAP output Files=1, Tests=0, ... Result: FAIL
-
At long last, we've gotten the preliminaries out of the way. Now will take a look at a typical assignment.
We will be creating many tickets in our Issue Tracker which ask you or a fellow "code understander" to examine a list of 10 to 20 files each of which is found in both repositories.
Your mission, should you choose to accept it, is to:
-
Understand that file as it exists in the Perl 5 repository (at least as of tag
v5.32.0
), at least to the point where you could say to someone else, "Here's what's going on in t/op/utftaint.t -- generally speaking."For some files, this will be child's play. For others -- particularly those that have been accumulating unit tests since Larry wrote them in 1987 -- this will be more difficult. Feel free to acknowledge when you do not understand what is going on in a given file. By doing so you will join the company of many Perl core developers.
-
Examine the version of the file as it exists in your Perl 7 checkout, perhaps using the qdiff program described above, or perhaps using a more conventional tool like vimdiff.
-
Note the differences that a Perl 7 developer has introduced into the file. Given the current Objective ("strict-by-default" as of Aug 14 2020), form a judgment as to whether or not the changes in the file reasonably fulfill the objective.
-
Note that we are asking you first and foremost to make a judgment call about the changes that have been introduced into the file. We are not asking you to make a line-by-line critique of the changes as you might do in a typical "code review" of a pull request on GitHub.
You are encouraged to write down your judgments about the files you have been assigned in a separate plain-text file. Should you be looking at a file via the GitHub web interface -- something which we are not recommending you do -- please resist the temptation to click on individual lines, and enter a comment which starts a "conversation" and generates email which fills up the developer's Inbox. We much prefer that, for each ticket that you take on, you write one, nice summary comment in the issue tracker that says something like:
I'm satisifed with the changes introduced in all the files I was asked to study, except ____. Also, note that file ____ is still not yet passing all its tests.
-
Post your summary in the ticket.
In short, for a given list of test files, both you and the developer should understand the code.
At this stage we're not concerned with, say, misspellings in inline comments. Don't sweat the small stuff; we're still in proof-of-concept mode.