测试和调试 Rust 代码¶
此页面说明如何在 Firefox 中测试和调试 Rust 代码。
该 构建文档 解释了如何将新的 Rust 代码添加到 Firefox。该 代码文档 解释了如何在 Firefox 中编写和使用 Rust 代码。
测试 Mozilla crate¶
Rust 代码将自然地作为系统测试(例如 Mochitests)的一部分进行测试。本节介绍了单元测试单个 Rust crate 的两种方法。应根据具体情况选择使用哪种方法。
Rust 测试¶
如果一个 Mozilla crate 具有“普通”Rust 测试(即 #[test]
使用 cargo test
运行的函数),您可以将 crate 的名称添加到 toolkit/library/rust/moz.build 中的 RUST_TESTS
中。(可以通过将 Cargo 特性添加到同一文件中的 RUST_TEST_FEATURES
中来为 Rust 测试激活它们。)
Rust 测试使用 ./mach rusttests
运行。它们在几个 rusttests
作业的自动化中运行,但并非在所有平台上都运行。
Rust 测试有一个主要限制:它们不能链接到 Gecko 符号。因此,Rust 测试不能用于使用 Gecko crate(如 nsstring
和 xpcom
)的 crate。
也可以在不同的 moz.build
文件中使用 RUST_TESTS
。请参阅 testing/geckodriver/moz.build
和 geckodriver 测试文档 以了解示例。
GTests¶
单元测试 Mozilla crate 的另一种方法是编写一个 GTest,它使用 FFI 调用 Rust 代码。这需要以下步骤。
创建一个新的测试 crate,其名称与正在测试的 crate 的名称相同,并在末尾添加
-gtest
后缀。向测试 crate 中添加一个 Rust 文件、一个包含 GTest
TEST()
函数的 C++ 文件(这些函数使用 FFI 调用 Rust 文件)、一个引用 Rust 文件的Cargo.toml
文件和一个引用 C++ 文件的moz.build
文件。在 toolkit/library/gtest/rust/Cargo.toml 中的
[dependencies]
部分添加一个条目。在 toolkit/library/gtest/rust/lib.rs 中添加一个
extern crate
条目。
请参阅 xpcom/rust/gtest/nsstring/ 以了解一个简单的示例。(请注意,该 moz.build
文件位于该 crate 的父目录中。)
Rust GTest 可以像任何其他 GTest 一样通过 ./mach gtest
运行,使用 C++ TEST()
函数作为起点。
与 Rust 测试不同,当需要链接到 Gecko 符号时,可以使用 GTests。
测试第三方 crate¶
通常我们不会运行第三方 crate 的测试。假设这些 crate 在其他地方已经得到了充分的测试。
调试 Rust 代码¶
理论上,Rust 代码的调试方式与 C++ 代码非常相似,可以使用标准工具(如 gdb
、rr
和 Microsoft Visual Studio 调试器)。实际上,体验可能会更差,因为可能会出现以下缺点。
无法打印局部变量,即使在非优化构建中。
无法调用泛型函数。
缺少行号和堆栈帧。
诸如
Option
和Vec
之类的基本类型的打印有时不是最佳的。如果在启动gdb
时看到警告“Missing auto-load script at offset 0 in section.debug_gdb_scripts
”,则rust-gdb
包装器可能会提供更好的结果。
从 Rust 代码记录日志¶
Rust 日志记录¶
可以使用 RUST_LOG
环境变量(来自 env_logger
crate)来启用从 Firefox 中的 Rust 代码到 stderr 的日志记录。可以使用 log
crate 中的日志记录宏。按重要性排序,它们是:error!
、warn!
、info!
、debug!
、trace!
。
例如,要显示所有 info
级别或更高的日志消息,请运行
RUST_LOG=info firefox
还可以指定模块级日志记录,请参阅 文档,了解 env_logger
crate 的详细信息。
要将日志记录限制为子进程,请使用 RUST_LOG_CHILD
而不是 RUST_LOG
。
Gecko 日志记录¶
Rust 日志记录也可以转发到 Gecko 日志记录器,以便通过 MOZ_LOG
和 MOZ_LOG_FILE
进行捕获。
在从
MOZ_LOG
解析模块时,包含::
的模块被认为是 Rust 模块。要记录顶级模块(如neqo_transport
)中的所有内容,请将其指定为neqo_transport::*
。例如
MOZ_LOG=timestamp,sync,nsHostResolver:5,neqo_transport::*:5,proxy:5 firefox
从子模块记录日志时,允许使用
::*
,但不是必需的。因此,这两行是等效的
MOZ_LOG=timestamp,sync,neqo_transport::recovery:5 firefox
MOZ_LOG=timestamp,sync,neqo_transport::recovery::*:5 firefox
debug!
和trace!
日志不会出现在非调试构建中。这是由于我们在log
crate 中使用了release_max_level_info
特性。同时使用
MOZ_LOG
和RUST_LOG
时,在MOZ_LOG
中指定的模块不会出现在RUST_LOG
中。