#trdelnik #anchor #fuzz #deployment #solana #fuzz-testing #test-suite

trdelnik-client

trdelnik_client 库帮助您构建和部署 Anchor 程序到本地集群,并对其运行测试套件。

9 个不稳定版本 (4 个破坏性更新)

0.5.0 2023 年 8 月 28 日
0.4.1 2023 年 8 月 21 日
0.4.0 2022 年 12 月 13 日
0.3.0 2022 年 9 月 23 日
0.1.3 2022 年 5 月 13 日

#2955神奇豆

Download history 2/week @ 2024-03-14 29/week @ 2024-03-28 13/week @ 2024-04-04 134/week @ 2024-04-11 4/week @ 2024-04-18 3/week @ 2024-04-25

每月 73 次下载
用于 trdelnik-cli

自定义许可证

220KB
4K SLoC

Trdelnik Logo

Trdelník

Ackee Blockchain Discord invitation

Ackee Blockchain 开发

Crates.io Crates.io Crates.io Crates.io
lint Test Escrow and Turnstile

Trdelník 是一个基于 Rust 的测试框架,为用 Anchor 编写的 Solana 程序提供了几个方便的开发者工具。

  • Trdelnik 客户端 - 构建 Anchor 程序并将其部署到本地集群,并对其运行测试套件;
  • Trdelnik 控制台 - 内置控制台,为开发者提供快速程序交互的命令提示符;
  • Trdelnik 模糊测试 - 基于属性和状态测试;
  • Trdelnik 探索器 - 探索账本更改。
Trdelnik Demo

依赖项

安装

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-splspl-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目录中创建临时文件夹,在程序崩溃的情况下不会清除。你可能需要手动清除这些文件夹。

支持的版本

  • 我们支持下表中的AnchorSolana版本。
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 在布拉格Solana Hacker House上宣布Trdelnik
    • Trdelnik客户端可用于测试
  • Q2/22 Trdelnik资源管理器可用
  • Q2/22 在巴塞罗那Solana Hacker House上介绍了Trdelnik客户端和资源管理器
  • 2023年Q3/23 Trdelnik模糊测试在柏林Solana黑客屋推出

奖项

腌泡菜社区奖 - 2022年Solana Riptide黑客马拉松腌泡菜补助金的获得者。

贡献

感谢您对贡献Trdelník的兴趣!请参阅CONTRIBUTING.md了解如何进行。

许可证

本项目采用MIT许可证

大学和投资伙伴

依赖项

~61–89MB
~2M SLoC