Bug 1879774 [wpt PR 44524] - WebKit export: Implement field-sizing support for input...
[gecko.git] / docs / testing-rust-code / index.md
blobfef3ce9c801a9ca1834ecf41af42346dbcde1a5d
1 # Testing & Debugging Rust Code
3 This page explains how to test and debug Rust code in Firefox.
5 The [build documentation](/build/buildsystem/rust.rst) explains how to add
6 new Rust code to Firefox. The [code documentation](/writing-rust-code/index.md)
7 explains how to write and work with Rust code in Firefox.
9 ## Testing Mozilla crates
11 Rust code will naturally be tested as part of system tests such as Mochitests.
12 This section describes the two methods for unit testing of individual Rust
13 crates. Which method should be used depends on the circumstances.
15 ### Rust tests
17 If a Mozilla crate has "normal" Rust tests (i.e. `#[test]` functions that run
18 with `cargo test`), you can add the crate's name to `RUST_TESTS` in
19 [toolkit/library/rust/moz.build](https://searchfox.org/mozilla-central/source/toolkit/library/rust/moz.build).
20 (Cargo features can be activated for Rust tests by adding them to
21 `RUST_TEST_FEATURES` in the same file.)
23 Rust tests are run with `./mach rusttests`. They run on automation in a couple
24 of `rusttests` jobs, but not on all platforms.
26 Rust tests have one major restriction: they cannot link against Gecko symbols.
27 Therefore, Rust tests cannot be used for crates that use Gecko crates like
28 `nsstring` and `xpcom`.
30 It's also possible to use `RUST_TESTS` in a different `moz.build` file. See
31 `testing/geckodriver/moz.build` and the [geckodriver testing docs] for an
32 example.
34 [geckodriver testing docs]: /testing/geckodriver/Testing.md
36 ### GTests
38 Another way to unit test a Mozilla crate is by writing a GTest that uses FFI to
39 call into Rust code. This requires the following steps.
40 - Create a new test crate whose name is the same as the name of crate being
41   tested, with a `-gtest` suffix.
42 - Add to the test crate a Rust file, a C++ file containing GTest `TEST()`
43   functions that use FFI to call into the Rust file, a `Cargo.toml` file that
44   references the Rust file, and a `moz.build` file that references the C++
45   file.
46 - Add an entry to the `[dependencies]` section in
47   [toolkit/library/gtest/rust/Cargo.toml](https://searchfox.org/mozilla-central/source/toolkit/library/gtest/rust/Cargo.toml).
48 - Add an `extern crate` entry to
49   [toolkit/library/gtest/rust/lib.rs](https://searchfox.org/mozilla-central/source/toolkit/library/gtest/rust/lib.rs).
51 See
52 [xpcom/rust/gtest/nsstring/](https://searchfox.org/mozilla-central/source/xpcom/rust/gtest/nsstring)
53 for a simple example. (Note that the `moz.build` file is in the parent
54 directory for that crate.)
56 A Rust GTest can be run like any other GTest via `./mach gtest`, using the C++
57 `TEST()` functions as the starting point.
59 Unlike Rust tests, GTests can be used when linking against Gecko symbols is required.
61 ## Testing third-party crates
63 In general we don't run tests for third-party crates. The assumption is that
64 these crates are sufficiently well-tested elsewhere.
66 ## Debugging Rust code
68 In theory, Rust code is debuggable much like C++ code, using standard tools
69 like `gdb`, `rr`, and the Microsoft Visual Studio Debugger. In practice, the
70 experience can be worse, because shortcomings such as the following can occur.
71 - Inability to print local variables, even in non-optimized builds.
72 - Inability to call generic functions.
73 - Missing line numbers and stack frames.
74 - Printing of basic types such as `Option` and `Vec` is sometimes sub-optimal.
75   If you see a warning "Missing auto-load script at offset 0 in section
76   `.debug_gdb_scripts`" when starting `gdb`, the `rust-gdb` wrapper may give
77   better results.
79 ## Logging from Rust code
81 ### Rust logging
83 The `RUST_LOG` environment variable (from the `env_logger` crate) can be used
84 to enable logging to stderr from Rust code in Firefox. The logging macros from
85 the `log` crate can be used. In order of importance, they are: `error!`,
86 `warn!`, `info!`, `debug!`, `trace!`.
88 For example, to show all log messages of `info` level or higher, run:
89 ```
90 RUST_LOG=info firefox
91 ```
92 Module-level logging can also be specified, see the [documentation] for the
93 `env_logger` crate for details.
95 To restrict logging to child processes, use `RUST_LOG_CHILD` instead of
96 `RUST_LOG`.
98 [documentation]: https://docs.rs/env_logger/
100 ### Gecko logging
102 Rust logging can also be forwarded to the [Gecko logger] for capture via
103 `MOZ_LOG` and `MOZ_LOG_FILE`.
105 [Gecko logger]: /xpcom/logging.rst
107 - When parsing modules from `MOZ_LOG`, modules containing `::` are considered
108   to be Rust modules. To log everything in a top-level module like
109   `neqo_transport`, specify it as `neqo_transport::*`. For example:
111 MOZ_LOG=timestamp,sync,nsHostResolver:5,neqo_transport::*:5,proxy:5 firefox
113 - When logging from a submodule the `::*` is allowed but isn't necessary.
114   So these two lines are equivalent:
116 MOZ_LOG=timestamp,sync,neqo_transport::recovery:5 firefox
117 MOZ_LOG=timestamp,sync,neqo_transport::recovery::*:5 firefox
119 - `debug!` and `trace!` logs will not appear in non-debug builds. This is due
120   to our use of the `release_max_level_info` feature in the `log` crate.
122 - When using both `MOZ_LOG` and `RUST_LOG`, modules that are specified in
123   `MOZ_LOG` will not appear in `RUST_LOG`.