Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 78dd6a4

Browse files
authoredJan 18, 2022
Reorganize and expand the testing chapters. (#1281)
* Reorganize and expand the testing chapters. * Update tests chapters for review comments. * Fix typo.
1 parent 4d46bd0 commit 78dd6a4

File tree

14 files changed

+2055
-1100
lines changed

14 files changed

+2055
-1100
lines changed
 

‎book.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ follow-web-links = true
2424
exclude = [ "crates\\.io", "gcc\\.godbolt\\.org", "youtube\\.com", "youtu\\.be", "dl\\.acm\\.org", "cs\\.bgu\\.ac\\.il", "www\\.amazon\\.com", "www\\.rustaceans\\.org", "play\\.rust-lang\\.org" ]
2525
cache-timeout = 86400
2626
warning-policy = "error"
27+
28+
[output.html.redirect]
29+
"/compiletest.html" = "tests/compiletest.html"

‎src/SUMMARY.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,16 @@
1515
- [Documenting Compiler](./building/compiler-documenting.md)
1616
- [Rustdoc overview](./rustdoc.md)
1717
- [Adding a new target](./building/new-target.md)
18-
- [The compiler testing framework](./tests/intro.md)
18+
- [Testing the compiler](./tests/intro.md)
1919
- [Running tests](./tests/running.md)
20+
- [Testing with Docker](./tests/docker.md)
21+
- [Testing with CI](./tests/ci.md)
2022
- [Adding new tests](./tests/adding.md)
21-
- [Using `compiletest` commands to control test execution](./compiletest.md)
23+
- [Compiletest](./tests/compiletest.md)
24+
- [UI tests](./tests/ui.md)
25+
- [Test headers](./tests/headers.md)
26+
- [Performance testing](./tests/perf.md)
27+
- [Crater](./tests/crater.md)
2228
- [Debugging the Compiler](./compiler-debugging.md)
2329
- [Using the tracing/logging instrumentation](./tracing.md)
2430
- [Profiling the compiler](./profiling.md)

‎src/compiletest.md

Lines changed: 0 additions & 223 deletions
This file was deleted.

‎src/profiling.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@ This section talks about how to profile the compiler and find out where it spend
44

55
Depending on what you're trying to measure, there are several different approaches:
66

7-
- If you want to see if a PR improves or regresses compiler performance:
8-
- The [rustc-perf](https://github.com/rust-lang/rustc-perf) project makes this easy and can be triggered to run on a PR via the `@rust-timer` bot.
9-
The `@bors try @rust-timer queue` command, in a comment on the PR, will queue a try build and a
10-
benchmarking run.
11-
Note: you need `try` privileges to be able to do this. More details are available in the [perf collector documentation](https://github.com/rust-lang/rustc-perf/blob/master/collector/README.md).
7+
- If you want to see if a PR improves or regresses compiler performance,
8+
see the [rustc-perf chapter](tests/perf.md) for requesting a benchmarking run.
129

1310
- If you want a medium-to-high level overview of where `rustc` is spending its time:
1411
- The `-Z self-profile` flag and [measureme](https://github.com/rust-lang/measureme) tools offer a query-based approach to profiling.

‎src/tests/adding.md

Lines changed: 139 additions & 524 deletions
Large diffs are not rendered by default.

‎src/tests/ci.md

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
# Testing with CI
2+
3+
## Testing infrastructure
4+
5+
When a Pull Request is opened on GitHub, [GitHub Actions] will automatically
6+
launch a build that will run all tests on some configurations
7+
(x86_64-gnu-llvm-12 linux. x86_64-gnu-tools linux, mingw-check linux).
8+
In essence, each runs `./x.py test` with various different options.
9+
10+
The integration bot [bors] is used for coordinating merges to the master branch.
11+
When a PR is approved, it goes into a [queue] where merges are tested one at a
12+
time on a wide set of platforms using GitHub Actions. Due to the limit on the
13+
number of parallel jobs, we run CI under the [rust-lang-ci] organization except
14+
for PRs.
15+
Most platforms only run the build steps, some run a restricted set of tests,
16+
only a subset run the full suite of tests (see Rust's [platform tiers]).
17+
18+
If everything passes, then all of the distribution artifacts that were
19+
generated during the CI run are published.
20+
21+
[GitHub Actions]: https://github.com/rust-lang/rust/actions
22+
[rust-lang-ci]: https://github.com/rust-lang-ci/rust/actions
23+
[bors]: https://github.com/servo/homu
24+
[queue]: https://bors.rust-lang.org/queue/rust
25+
[platform tiers]: https://forge.rust-lang.org/release/platform-support.html#rust-platform-support
26+
27+
## Using CI to test
28+
29+
In some cases, a PR may run into problems with running tests on a particular
30+
platform or configuration.
31+
If you can't run those tests locally, don't hesitate to use CI resources to
32+
try out a fix.
33+
34+
As mentioned above, opening or updating a PR will only run on a small subset
35+
of configurations.
36+
Only when a PR is approved will it go through the full set of test configurations.
37+
However, you can try one of those configurations in your PR before it is approved.
38+
For example, if a Windows build fails, but you don't have access to a Windows
39+
machine, you can try running the Windows job that failed on CI within your PR
40+
after pushing a possible fix.
41+
42+
To do this, you'll need to edit [`src/ci/github-actions/ci.yml`].
43+
The `jobs` section defines the jobs that will run.
44+
The `jobs.pr` section defines everything that will run in a push to a PR.
45+
The `jobs.auto` section defines the full set of tests that are run after a PR is approved.
46+
You can copy one of the definitions from the `auto` section up to the `pr` section.
47+
48+
For example, the `x86_64-msvc-1` and `x86_64-msvc-2` jobs are responsible for
49+
running the 64-bit MSVC tests.
50+
You can copy those up to the `jobs.pr.strategy.matrix.include` section with
51+
the other jobs.
52+
53+
The comment at the top of `ci.yml` will tell you to run this command:
54+
55+
```sh
56+
./x.py run src/tools/expand-yaml-anchors
57+
````
58+
59+
This will generate the true [`.github/workflows/ci.yml`] which is what GitHub
60+
Actions uses.
61+
62+
Then, you can commit those two files and push to GitHub.
63+
GitHub Actions should launch the tests.
64+
65+
After you have finished, don't forget to remove any changes you have made to `ci.yml`.
66+
67+
Although you are welcome to use CI, just be conscientious that this is a shared
68+
resource with limited concurrency.
69+
Try not to enable too many jobs at once (one or two should be sufficient in
70+
most cases).
71+
72+
[`src/ci/github-actions/ci.yml`]: https://github.com/rust-lang/rust/blob/master/src/ci/github-actions/ci.yml
73+
[`.github/workflows/ci.yml`]: https://github.com/rust-lang/rust/blob/master/.github/workflows/ci.yml#L1

‎src/tests/compiletest.md

Lines changed: 526 additions & 0 deletions
Large diffs are not rendered by default.

‎src/tests/crater.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# Crater
2+
3+
[Crater](https://github.com/rust-lang/crater) is a tool for compiling
4+
and running tests for _every_ crate on [crates.io](https://crates.io) (and a
5+
few on GitHub). It is mainly used for checking the extent of breakage when
6+
implementing potentially breaking changes and ensuring lack of breakage by
7+
running beta vs stable compiler versions.
8+
9+
## When to run Crater
10+
11+
You should request a crater run if your PR makes large changes to the compiler
12+
or could cause breakage. If you are unsure, feel free to ask your PR's reviewer.
13+
14+
## Requesting Crater Runs
15+
16+
The rust team maintains a few machines that can be used for running crater runs
17+
on the changes introduced by a PR. If your PR needs a crater run, leave a
18+
comment for the triage team in the PR thread. Please inform the team whether
19+
you require a "check-only" crater run, a "build only" crater run, or a
20+
"build-and-test" crater run. The difference is primarily in time; the
21+
conservative (if you're not sure) option is to go for the build-and-test run.
22+
If making changes that will only have an effect at compile-time (e.g.,
23+
implementing a new trait) then you only need a check run.
24+
25+
Your PR will be enqueued by the triage team and the results will be posted when
26+
they are ready. Check runs will take around ~3-4 days, with the other two
27+
taking 5-6 days on average.
28+
29+
While crater is really useful, it is also important to be aware of a few
30+
caveats:
31+
32+
- Not all code is on crates.io! There is a lot of code in repos on GitHub and
33+
elsewhere. Also, companies may not wish to publish their code. Thus, a
34+
successful crater run is not a magically green light that there will be no
35+
breakage; you still need to be careful.
36+
37+
- Crater only runs Linux builds on x86_64. Thus, other architectures and
38+
platforms are not tested. Critically, this includes Windows.
39+
40+
- Many crates are not tested. This could be for a lot of reasons, including
41+
that the crate doesn't compile any more (e.g. used old nightly features),
42+
has broken or flaky tests, requires network access, or other reasons.
43+
44+
- Before crater can be run, `@bors try` needs to succeed in building artifacts.
45+
This means that if your code doesn't compile, you cannot run crater.

‎src/tests/docker.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Testing with Docker
2+
3+
The Rust tree includes [Docker] image definitions for the platforms used on
4+
GitHub Actions in [`src/ci/docker`].
5+
The script [`src/ci/docker/run.sh`] is used to build the Docker image, run it,
6+
build Rust within the image, and run the tests.
7+
8+
You can run these images on your local development machine. This can be
9+
helpful to test environments different from your local system. First you will
10+
need to install Docker on a Linux, Windows, or macOS system (typically Linux
11+
will be much faster than Windows or macOS because the later use virtual
12+
machines to emulate a Linux environment). To enter interactive mode which will
13+
start a bash shell in the container, run `src/ci/docker/run.sh --dev <IMAGE>`
14+
where `<IMAGE>` is one of the directory names in `src/ci/docker` (for example
15+
`x86_64-gnu` is a fairly standard Ubuntu environment).
16+
17+
The docker script will mount your local Rust source tree in read-only mode,
18+
and an `obj` directory in read-write mode. All of the compiler artifacts will
19+
be stored in the `obj` directory. The shell will start out in the `obj`
20+
directory. From there, you can run `../src/ci/run.sh` which will run the build
21+
as defined by the image.
22+
23+
Alternatively, you can run individual commands to do specific tasks. For
24+
example, you can run `python3 ../x.py test src/test/ui` to just run UI tests.
25+
Note that there is some configuration in the [`src/ci/run.sh`] script that you
26+
may need to recreate. Particularly, set `submodules = false` in your
27+
`config.toml` so that it doesn't attempt to modify the read-only directory.
28+
29+
Some additional notes about using the Docker images:
30+
31+
- Some of the std tests require IPv6 support. Docker on Linux seems to have it
32+
disabled by default. Run the commands in [`enable-docker-ipv6.sh`] to enable
33+
IPv6 before creating the container. This only needs to be done once.
34+
- The container will be deleted automatically when you exit the shell, however
35+
the build artifacts persist in the `obj` directory. If you are switching
36+
between different Docker images, the artifacts from previous environments
37+
stored in the `obj` directory may confuse the build system. Sometimes you
38+
will need to delete parts or all of the `obj` directory before building
39+
inside the container.
40+
- The container is bare-bones, with only a minimal set of packages. You may
41+
want to install some things like `apt install less vim`.
42+
- You can open multiple shells in the container. First you need the container
43+
name (a short hash), which is displayed in the shell prompt, or you can run
44+
`docker container ls` outside of the container to list the available
45+
containers. With the container name, run `docker exec -it <CONTAINER>
46+
/bin/bash` where `<CONTAINER>` is the container name like `4ba195e95cef`.
47+
48+
[Docker]: https://www.docker.com/
49+
[`src/ci/docker`]: https://github.com/rust-lang/rust/tree/master/src/ci/docker
50+
[`src/ci/docker/run.sh`]: https://github.com/rust-lang/rust/blob/master/src/ci/docker/run.sh
51+
[`src/ci/run.sh`]: https://github.com/rust-lang/rust/blob/master/src/ci/run.sh
52+
[`enable-docker-ipv6.sh`]: https://github.com/rust-lang/rust/blob/master/src/ci/scripts/enable-docker-ipv6.sh

‎src/tests/headers.md

Lines changed: 403 additions & 0 deletions
Large diffs are not rendered by default.

‎src/tests/intro.md

Lines changed: 134 additions & 330 deletions
Large diffs are not rendered by default.

‎src/tests/perf.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Performance testing
2+
3+
## rustc-perf
4+
5+
A lot of work is put into improving the performance of the compiler and
6+
preventing performance regressions.
7+
The [rustc-perf](https://github.com/rust-lang/rustc-perf) project provides
8+
several services for testing and tracking performance.
9+
It provides hosted infrastructure for running benchmarks as a service.
10+
At this time, only `x86_64-unknown-linux-gnu` builds are tracked.
11+
12+
A "perf run" is used to compare the performance of the compiler in different
13+
configurations for a large collection of popular crates.
14+
Different configurations include "fresh builds", builds with incremental compilation, etc.
15+
16+
The result of a perf run is a comparison between two versions of the compiler
17+
(by their commit hashes).
18+
19+
### Automatic perf runs
20+
21+
After every PR is merged, a suite of benchmarks are run against the compiler.
22+
The results are tracked over time on the <https://perf.rust-lang.org/> website.
23+
Any changes are noted in a comment on the PR.
24+
25+
### Manual perf runs
26+
27+
Additionally, performance tests can be ran before a PR is merged on an as-needed basis.
28+
You should request a perf run if your PR may affect performance, especially if
29+
it can affect performance adversely.
30+
31+
To evaluate the performance impact of a PR, write this comment on the PR:
32+
33+
`@bors try @rust-timer queue`
34+
35+
> **Note**: Only users authorized to do perf runs are allowed to post this comment.
36+
> Teams that are allowed to use it are tracked in the [Teams
37+
> repository](https://github.com/rust-lang/team) with the `perf = true` value
38+
> in the `[permissions]` section (and bors permissions are also required).
39+
> If you are not on one of those teams, feel free to ask for someone to post
40+
> it for you (either on Zulip or ask the assigned reviewer).
41+
42+
This will first tell bors to do a "try" build which do a full release build
43+
for `x86_64-unknown-linux-gnu`.
44+
After the build finishes, it will place it in the queue to run the performance
45+
suite against it.
46+
After the performance tests finish, the bot will post a comment on the PR with
47+
a summary and a link to a full report.
48+
49+
More details are available in the [perf collector
50+
documentation](https://github.com/rust-lang/rustc-perf/blob/master/collector/README.md).

‎src/tests/running.md

Lines changed: 120 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ I think is done, but rarely otherwise. -nmatsakis)
1818
The test results are cached and previously successful tests are
1919
`ignored` during testing. The stdout/stderr contents as well as a
2020
timestamp file for every test can be found under `build/ARCH/test/`.
21-
To force-rerun a test (e.g. in case the test runner fails to notice
22-
a change) you can simply remove the timestamp file.
21+
To force-rerun a test (e.g. in case the test runner fails to notice a change)
22+
you can simply remove the timestamp file, or use the `--force-rerun` CLI
23+
option.
2324

2425
Note that some tests require a Python-enabled gdb. You can test if
2526
your gdb install supports Python by using the `python` command from
@@ -143,6 +144,18 @@ to automatically adjust the `.stderr`, `.stdout` or `.fixed` files of
143144
all tests. Of course you can also target just specific tests with the
144145
`--test-args your_test_name` flag, just like when running the tests.
145146

147+
## Configuring test running
148+
149+
There are a few options for running tests:
150+
151+
* `config.toml` has the `rust.verbose-tests` option.
152+
If `false`, each test will print a single dot (the default).
153+
If `true`, the name of every test will be printed.
154+
This is equivalent to the `--quiet` option in the [Rust test
155+
harness](https://doc.rust-lang.org/rustc/tests/)
156+
* The environment variable `RUST_TEST_THREADS` can be set to the number of
157+
concurrent threads to use for testing.
158+
146159
## Passing `--pass $mode`
147160

148161
Pass UI tests now have three modes, `check-pass`, `build-pass` and
@@ -156,9 +169,8 @@ exists in the test file. For example, you can run all the tests in
156169
```
157170

158171
By passing `--pass $mode`, you can reduce the testing time. For each
159-
mode, please see [here][mode].
160-
161-
[mode]: ./adding.md#tests-that-do-not-result-in-compile-errors
172+
mode, please see [Controlling pass/fail
173+
expectations](ui.md#controlling-passfail-expectations).
162174

163175
## Using incremental compilation
164176

@@ -193,17 +205,7 @@ To run the UI test suite in NLL mode, one would use the following:
193205
./x.py test src/test/ui --compare-mode=nll
194206
```
195207

196-
The possible compare modes are:
197-
198-
* nll - currently nll is implemented in migrate mode, this option runs with true nll.
199-
* polonius
200-
* chalk
201-
* split-dwarf
202-
* split-dwarf-single
203-
204-
Note that compare modes are separate to [revisions](./adding.html#revisions).
205-
All revisions are tested when running `./x.py test src/test/ui`,
206-
however compare-modes must be manually run individually via the `--compare-mode` flag.
208+
See [Compare modes](compiletest.md#compare-modes) for more details.
207209

208210
## Running tests manually
209211

@@ -219,3 +221,105 @@ rustc +stage1 src/test/ui/issue-1234.rs
219221
This is much faster, but doesn't always work. For example, some tests
220222
include directives that specify specific compiler flags, or which rely
221223
on other crates, and they may not run the same without those options.
224+
225+
226+
## Running tests on a remote machine
227+
228+
Tests may be run on a remote machine (e.g. to test builds for a different
229+
architecture). This is done using `remote-test-client` on the build machine
230+
to send test programs to `remote-test-server` running on the remote machine.
231+
`remote-test-server` executes the test programs and sends the results back to
232+
the build machine. `remote-test-server` provides *unauthenticated remote code
233+
execution* so be careful where it is used.
234+
235+
To do this, first build `remote-test-server` for the remote
236+
machine, e.g. for RISC-V
237+
```sh
238+
./x.py build src/tools/remote-test-server --target riscv64gc-unknown-linux-gnu
239+
```
240+
241+
The binary will be created at
242+
`./build/$HOST_ARCH/stage2-tools/$TARGET_ARCH/release/remote-test-server`. Copy
243+
this over to the remote machine.
244+
245+
On the remote machine, run the `remote-test-server` with the `remote` argument
246+
(and optionally `-v` for verbose output). Output should look like this:
247+
```sh
248+
$ ./remote-test-server -v remote
249+
starting test server
250+
listening on 0.0.0.0:12345!
251+
```
252+
253+
You can test if the `remote-test-server` is working by connecting to it and
254+
sending `ping\n`. It should reply `pong`:
255+
```sh
256+
$ nc $REMOTE_IP 12345
257+
ping
258+
pong
259+
```
260+
261+
To run tests using the remote runner, set the `TEST_DEVICE_ADDR` environment
262+
variable then use `x.py` as usual. For example, to run `ui` tests for a RISC-V
263+
machine with the IP address `1.2.3.4` use
264+
```sh
265+
export TEST_DEVICE_ADDR="1.2.3.4:12345"
266+
./x.py test src/test/ui --target riscv64gc-unknown-linux-gnu
267+
```
268+
269+
If `remote-test-server` was run with the verbose flag, output on the test machine
270+
may look something like
271+
```
272+
[...]
273+
run "/tmp/work/test1007/a"
274+
run "/tmp/work/test1008/a"
275+
run "/tmp/work/test1009/a"
276+
run "/tmp/work/test1010/a"
277+
run "/tmp/work/test1011/a"
278+
run "/tmp/work/test1012/a"
279+
run "/tmp/work/test1013/a"
280+
run "/tmp/work/test1014/a"
281+
run "/tmp/work/test1015/a"
282+
run "/tmp/work/test1016/a"
283+
run "/tmp/work/test1017/a"
284+
run "/tmp/work/test1018/a"
285+
[...]
286+
```
287+
288+
Tests are built on the machine running `x.py` not on the remote machine. Tests
289+
which fail to build unexpectedly (or `ui` tests producing incorrect build
290+
output) may fail without ever running on the remote machine.
291+
292+
## Testing on emulators
293+
294+
Some platforms are tested via an emulator for architectures that aren't
295+
readily available. For architectures where the standard library is well
296+
supported and the host operating system supports TCP/IP networking, see the
297+
above instructions for testing on a remote machine (in this case the
298+
remote machine is emulated).
299+
300+
There is also a set of tools for orchestrating running the
301+
tests within the emulator. Platforms such as `arm-android` and
302+
`arm-unknown-linux-gnueabihf` are set up to automatically run the tests under
303+
emulation on GitHub Actions. The following will take a look at how a target's tests
304+
are run under emulation.
305+
306+
The Docker image for [armhf-gnu] includes [QEMU] to emulate the ARM CPU
307+
architecture. Included in the Rust tree are the tools [remote-test-client]
308+
and [remote-test-server] which are programs for sending test programs and
309+
libraries to the emulator, and running the tests within the emulator, and
310+
reading the results. The Docker image is set up to launch
311+
`remote-test-server` and the build tools use `remote-test-client` to
312+
communicate with the server to coordinate running tests (see
313+
[src/bootstrap/test.rs]).
314+
315+
> TODO:
316+
> Is there any support for using an iOS emulator?
317+
>
318+
> It's also unclear to me how the wasm or asm.js tests are run.
319+
320+
[armhf-gnu]: https://github.com/rust-lang/rust/tree/master/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile
321+
[QEMU]: https://www.qemu.org/
322+
[remote-test-client]: https://github.com/rust-lang/rust/tree/master/src/tools/remote-test-client
323+
[remote-test-server]: https://github.com/rust-lang/rust/tree/master/src/tools/remote-test-server
324+
[src/bootstrap/test.rs]: https://github.com/rust-lang/rust/tree/master/src/bootstrap/test.rs
325+

‎src/tests/ui.md

Lines changed: 500 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.