5个版本 (3个破坏性更新)
0.5.0 | 2023年8月28日 |
---|---|
0.4.1 | 2023年8月21日 |
0.4.0 | 2022年12月13日 |
0.3.0 |
|
0.1.0 | 2022年7月14日 |
#278 in 神奇豆
每月45次下载
465KB
9K SLoC
Trdelník是一个基于Rust的测试框架,为测试使用Anchor编写的Solana程序提供了几个方便的开发者工具。
- Trdelnik客户端 - 在本地集群上构建和部署Anchor程序,并对其运行测试套件;
- Trdelnik控制台 - 内置控制台,为开发者提供命令提示符以快速交互程序;
- Trdelnik模糊测试 - 基于属性和状态测试;
- Trdelnik浏览器 - 探索账本变化。
依赖项
- 安装Rust (
nightly
版本) - 安装Solana工具套件 (
stable
版本) - 安装Anchor
- 可选安装Honggfuzz-rs进行模糊测试
安装
cargo install trdelnik-cli
# or the specific version
cargo install --version <version> trdelnik-cli
使用方法
# navigate to your project root directory
trdelnik init
# it will generate `.program_client` and `trdelnik-tests` directories with all the necessary files
trdelnik test
# want more?
trdelnik --help
如何编写测试?
// <my_project>/trdelnik-tests/tests/test.rs
// TODO: do not forget to add all necessary dependencies to the generated `trdelnik-tests/Cargo.toml`
use program_client::my_instruction;
use trdelnik_client::*;
use my_program;
#[throws]
#[fixture]
async fn init_fixture() -> Fixture {
// create a test fixture
let mut fixture = Fixture {
client: Client::new(system_keypair(0)),
// make sure your program is using a correct program ID
program: program_keypair(1),
state: keypair(42),
};
// deploy a tested program
fixture.deploy().await?;
// call instruction init
my_instruction::initialize(
&fixture.client,
fixture.state.pubkey(),
fixture.client.payer().pubkey(),
System::id(),
Some(fixture.state.clone()),
).await?;
fixture
}
#[trdelnik_test]
async fn test_happy_path(#[future] init_fixture: Result<Fixture>) {
let fixture = init_fixture.await?;
// call the instruction
my_instruction::do_something(
&fixture.client,
"dummy_string".to_owned(),
fixture.state.pubkey(),
None,
).await?;
// check the test result
let state = fixture.get_state().await?;
assert_eq!(state.something_changed, "yes");
}
确保您的程序在宏 derive_id!(...)
中使用正确的程序 ID,并在 Anchor.toml
文件中。如果不是这样,请获取您所使用的密钥对公钥,并在这两个地方进行替换。要获取密钥对(密钥对的公钥)的程序 ID,可以使用 trdelnik key-pair
命令。例如
$ trdelnik key-pair program 7
将打印来自 program_keypair(7)
的密钥对信息。
具有自定义结构的说明
- 如果您想测试一个以自定义结构作为参数的指令
pub struct MyStruct {
amount: u64,
}
// ...
pub fn my_instruction(ctx: Context<Ctx>, data: MyStruct) { /* ... */ }
- 您应该在
.program_client
载体中添加导入
// .program_client/src/lib.rs
// DO NOT EDIT - automatically generated file
pub mod my_program_instruction {
use trdelnik_client::*;
use my_program::MyStruct; // add this import
// ...
}
- 此文件是自动生成的,但
use
语句将不会重新生成
跳过测试
- 您可以使用
#[ignore]
宏来跳过测试。
#[trdelnik_test]
#[ignore]
async fn test() {}
测试与关联代币账户相关联的程序
Trdelnik
不导出anchor-spl
和spl-associated-token-account
,因此您必须手动添加它们。
# <my-project>/trdelnik-tests/Cargo.toml
# import the correct versions manually
anchor-spl = "0.28.0"
spl-associated-token-account = "2.0.0"
// <my-project>/trdelnik-tests/tests/test.rs
use anchor_spl::token::Token;
use spl_associated_token_account;
async fn init_fixture() -> Fixture {
// ...
let account = keypair(1);
let mint = keypair(2);
// constructs a token mint
client
.create_token_mint(&mint, mint.pubkey(), None, 0)
.await?;
// constructs associated token account
let token_account = client
.create_associated_token_account(&account, mint.pubkey())
.await?;
let associated_token_program = spl_associated_token_account::id();
// derives the associated token account address for the given wallet and mint
let associated_token_address = spl_associated_token_account::get_associated_token_address(&account.pubkey(), mint);
Fixture {
// ...
token_program: Token::id(),
}
}
trdelnik init
命令为您生成了一个虚拟测试套件。- 有关更多详细信息,请参阅 完整的测试实现。
如何使用 fuzzer?
一旦在 Anchor 项目中初始化 Trdelnik,您将在 trdelnik-tests/src/bin
文件夹中找到一个模糊测试模板,您可以根据需要对其进行修改或创建新的目标。不要忘记使用 cargo install honggfuzz
安装 honggfuzz-rs。
# To run the fuzz test, execute this command from your terminal and replace <TARGET_NAME> with the name of your fuzz target (by default "fuzz_target")
trdelnik fuzz run <TARGET_NAME>
# To debug your fuzz target crash with parameters from a crash file
trdelnik fuzz run-debug <TARGET_NAME> <CRASH_FILE_PATH>
在内部,Trdelnik 使用 honggfuzz-rs。您可以通过 环境变量 传递参数。hongfuzz 参数的列表可以在 hongfuzz 用法文档 中找到。例如
# Time-out: 10 secs
# Number of concurrent fuzzing threads: 1
# Number of fuzzing iterations: 10000
# Display Solana logs in the terminal
HFUZZ_RUN_ARGS="-t 10 -n 1 -N 10000 -Q" trdelnik fuzz run <TARGET_NAME>
注意:如果您将使用
solana-program-test
载体进行模糊测试,使用ProgramTest::new()
创建新的测试程序将在您的/tmp
目录中创建临时文件夹,如果您的程序崩溃,则不会清除这些文件夹。您可能需要手动清除这些文件夹。
支持的版本
- 我们支持下表中指定的
Anchor
和Solana
版本。
Trdelnik CLI | Anchor | Solana |
---|---|---|
最新版 |
~0.28.* |
=1.16.6 |
v0.4.0 |
~0.27.* |
>=1.15 |
v0.3.0 |
~0.25.* |
>=1.10 |
v0.2.0 |
~0.24.* |
>=1.9 |
- 我们正在探索 Anchor 的新版本,请确保您只使用受支持的版本。我们正在努力工作 💪
配置
配置变量可以在生成的 Trdelnik.toml
文件中进行编辑,该文件将位于项目的根目录中。
名称 | 默认值 | 描述 |
---|---|---|
测试.validator_startup_timeout |
10 000 | 在失败之前等待 solana-test-validator 的时间(以毫秒为单位) |
路线图
- Q1/22 在索拉纳黑客之家布拉格宣布 Trdelnik
- Trdelnik 客户端可用于测试
- Q2/22 Trdelnik 探索者可用
- Q2/22 在索拉纳黑客之家巴塞罗那介绍了 Trdelnik 客户端和探索者
- Q3/23 在索拉纳黑客之家柏林介绍了 Trdelnik 模糊测试
奖项
Marinade社区奖 - 2022年Solana Riptide黑客马拉松Marinade奖金的获得者。
贡献
感谢您对Trdelník的贡献兴趣!请参阅CONTRIBUTING.md了解如何进行。
许可协议
本项目采用MIT许可协议。
大学和投资合作伙伴
依赖项
~77MB
~1.5M SLoC