Skip to content

Commit

Permalink
⚡️ Update init and fuzz add command so it support both file and macro…
Browse files Browse the repository at this point in the history
… options, update default for init to fuzz with macro
  • Loading branch information
lukacan committed Jul 7, 2024
1 parent 4fdd9c7 commit 0af6b10
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 45 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
incremented upon a breaking change and the patch version will be incremented for features.

## [dev] - Unreleased
- feat/ add option to initialize Trident with Macro/File (for Snapshots) option based on preference ([179](https://github.com/Ackee-Blockchain/trident/pull/179))
- del/remove localnet subcommand ([178](https://github.com/Ackee-Blockchain/trident/pull/178))
- feat/create AccountsSnapshots derive macro for Snapshots creation ([#177](https://github.com/Ackee-Blockchain/trident/pull/177))
- del/remove unnecessary fuzzing feature as trident is mainly fuzzer ([#176](https://github.com/Ackee-Blockchain/trident/pull/176))
Expand Down
2 changes: 1 addition & 1 deletion crates/cli/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ mod test;
pub use test::test;

mod init;
pub use init::{init, TestsType};
pub use init::{init, SnapshotsType, TestsType};

mod clean;
pub use clean::clean;
2 changes: 1 addition & 1 deletion crates/cli/src/command/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ pub async fn build(root: Option<String>) {
}
}
};
let mut generator: TestGenerator = TestGenerator::new_with_root(root);
let mut generator: TestGenerator = TestGenerator::new_with_root(root, false);
generator.build().await?;
}
14 changes: 11 additions & 3 deletions crates/cli/src/command/fuzz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use trident_client::___private::{Commander, TestGenerator};

use crate::_discover;

use super::SnapshotsType;

pub const TRIDENT_TOML: &str = "Trident.toml";

#[derive(Subcommand)]
Expand All @@ -27,7 +29,10 @@ pub enum FuzzCommand {
crash_file_path: String,
},
/// Add new fuzz test. Explicit fuzz test name is not yet supported. Implicit name is fuzz_ID, where ID is automatically derived.
Add,
Add {
#[clap(default_value = "macro")]
snapshots_type: SnapshotsType,
},
}

#[throws]
Expand Down Expand Up @@ -64,10 +69,13 @@ pub async fn fuzz(root: Option<String>, subcmd: FuzzCommand) {
commander.run_fuzzer_debug(target, crash_file_path).await?;
}

FuzzCommand::Add => {
FuzzCommand::Add { snapshots_type } => {
// generate generator with root so that we do not need to again
// look for root within the generator
let mut generator = TestGenerator::new_with_root(root);
let mut generator = match snapshots_type {
SnapshotsType::Macro => TestGenerator::new_with_root(root, false),
SnapshotsType::File => TestGenerator::new_with_root(root, true),
};
generator.add_fuzz_test().await?;
}
};
Expand Down
12 changes: 10 additions & 2 deletions crates/cli/src/command/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,25 @@ pub enum TestsType {
Fuzz,
Poc,
}
#[derive(ValueEnum, Clone)]
pub enum SnapshotsType {
Macro,
File,
}

#[throws]
pub async fn init(tests_type: TestsType) {
pub async fn init(tests_type: TestsType, snapshots_type: SnapshotsType) {
// look for Anchor.toml
let root = if let Some(r) = _discover(ANCHOR_TOML)? {
r
} else {
bail!("It does not seem that Anchor is initialized because the Anchor.toml file was not found in any parent directory!");
};

let mut generator: TestGenerator = TestGenerator::new_with_root(root);
let mut generator: TestGenerator = match snapshots_type {
SnapshotsType::Macro => TestGenerator::new_with_root(root, false),
SnapshotsType::File => TestGenerator::new_with_root(root, true),
};

match tests_type {
TestsType::Poc => {
Expand Down
12 changes: 9 additions & 3 deletions crates/cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use anyhow::Error;
use anyhow::{Context, Result};
use clap::{Parser, Subcommand};
use command::TestsType;
use command::{SnapshotsType, TestsType};
use fehler::throws;

// subcommand functions to call and nested subcommands
Expand Down Expand Up @@ -48,8 +48,11 @@ enum Command {
/// Initialize test environment
Init {
/// Specifies the types of tests for which the frameworks should be initialized.
#[clap(default_value = "both")]
#[clap(default_value = "fuzz")]
tests_type: TestsType,
/// Specifies type of Accounts Snapshots, i.e used derive macro or generated file
#[clap(default_value = "macro")]
snapshots_type: SnapshotsType,
},
/// Removes target contents except for KeyPair and removes hfuzz_target folder
Clean,
Expand All @@ -64,7 +67,10 @@ pub async fn start() {
Command::KeyPair { subcmd } => command::keypair(subcmd)?,
Command::Test { root } => command::test(root).await?,
Command::Fuzz { root, subcmd } => command::fuzz(root, subcmd).await?,
Command::Init { tests_type } => command::init(tests_type).await?,
Command::Init {
tests_type,
snapshots_type,
} => command::init(tests_type, snapshots_type).await?,
Command::Clean => command::clean().await?,
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ pub fn generate_source_code(programs_data: &[ProgramData]) -> String {
let fuzzer_module: syn::ItemMod = parse_quote! {
pub mod #fuzz_instructions_module_name {
use trident_client::fuzzing::*;
use crate::accounts_snapshots::*;
// use crate::accounts_snapshots::*;

#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)]
pub enum FuzzInstruction {
Expand Down
1 change: 0 additions & 1 deletion crates/client/src/templates/trident-tests/test_fuzz.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use trident_client::fuzzing::*;
mod accounts_snapshots;
mod fuzz_instructions;

const PROGRAM_NAME: &str = "###PROGRAM_NAME###";
Expand Down
86 changes: 54 additions & 32 deletions crates/client/src/test_generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,11 @@ pub struct TestGenerator {
pub programs_data: Vec<ProgramData>,
pub packages: Vec<Package>,
pub use_tokens: Vec<ItemUse>,
pub with_snapshot_file: bool,
}
impl Default for TestGenerator {
fn default() -> Self {
Self::new()
Self::new(false)
}
}

Expand All @@ -133,12 +134,13 @@ impl TestGenerator {
/// # Returns
///
/// A new `TestGenerator` instance.
pub fn new() -> Self {
pub fn new(with_snapshot_file: bool) -> Self {
Self {
root: Path::new("../../").to_path_buf(),
programs_data: Vec::default(),
packages: Vec::default(),
use_tokens: Vec::default(),
with_snapshot_file,
}
}
/// Creates a new instance of `TestGenerator` with a specified root directory.
Expand All @@ -150,12 +152,13 @@ impl TestGenerator {
/// # Returns
///
/// A new `TestGenerator` instance with the specified root directory.
pub fn new_with_root(root: String) -> Self {
pub fn new_with_root(root: String, with_snapshot_file: bool) -> Self {
Self {
root: Path::new(&root).to_path_buf(),
programs_data: Vec::default(),
packages: Vec::default(),
use_tokens: Vec::default(),
with_snapshot_file,
}
}
/// Generates both proof of concept (POC) and fuzz tests along with the necessary setup.
Expand Down Expand Up @@ -420,17 +423,6 @@ impl TestGenerator {
/// If not present add fuzz_tests into the workspace virtual manifest as member
#[throws]
pub async fn add_new_fuzz_test(&self) {
let program_name = if !&self.programs_data.is_empty() {
&self
.programs_data
.first()
.unwrap()
.program_idl
.name
.snake_case
} else {
throw!(Error::NoProgramsFound)
};
let fuzz_dir_path =
construct_path!(self.root, TESTS_WORKSPACE_DIRECTORY, FUZZ_TEST_DIRECTORY);
let fuzz_tests_manifest_path = construct_path!(fuzz_dir_path, CARGO_TOML);
Expand Down Expand Up @@ -473,6 +465,48 @@ impl TestGenerator {

self.create_directory(&new_fuzz_test_dir).await?;

// create fuzz file
self.initialize_fuzz(&new_fuzz_test_dir).await?;

// create fuzz instructions file
self.initialize_fuzz_instructions(&new_fuzz_test_dir)
.await?;

// create accounts_snapshots file
if self.with_snapshot_file {
self.initialize_fuzz_snapshots(&new_fuzz_test_dir).await?;
}

let cargo_toml_content =
load_template!("/src/templates/trident-tests/Cargo_fuzz.toml.tmpl");

self.create_file(&fuzz_tests_manifest_path, cargo_toml_content)
.await?;

self.add_bin_target(&fuzz_tests_manifest_path, &new_fuzz_test, &new_bin_target)
.await?;
self.add_program_dependencies(&fuzz_dir_path, "dependencies", None)
.await?;

self.add_workspace_member(&format!(
"{TESTS_WORKSPACE_DIRECTORY}/{FUZZ_TEST_DIRECTORY}",
))
.await?;
}

#[throws]
pub async fn initialize_fuzz(&self, new_fuzz_test_dir: &Path) {
let program_name = if !&self.programs_data.is_empty() {
&self
.programs_data
.first()
.unwrap()
.program_idl
.name
.snake_case
} else {
throw!(Error::NoProgramsFound)
};
let fuzz_test_path = new_fuzz_test_dir.join(FUZZ_TEST);

let fuzz_test_content = load_template!("/src/templates/trident-tests/test_fuzz.rs");
Expand All @@ -489,39 +523,27 @@ impl TestGenerator {

self.create_file(&fuzz_test_path, &fuzz_test_content)
.await?;
}

// create fuzz instructions file
#[throws]
pub async fn initialize_fuzz_instructions(&self, new_fuzz_test_dir: &Path) {
let fuzz_instructions_path = new_fuzz_test_dir.join(FUZZ_INSTRUCTIONS_FILE_NAME);
let program_fuzzer = fuzzer_generator::generate_source_code(&self.programs_data);
let program_fuzzer = Commander::format_program_code(&program_fuzzer).await?;

self.create_file(&fuzz_instructions_path, &program_fuzzer)
.await?;
}

// // create accounts_snapshots file
#[throws]
pub async fn initialize_fuzz_snapshots(&self, new_fuzz_test_dir: &Path) {
let accounts_snapshots_path = new_fuzz_test_dir.join(ACCOUNTS_SNAPSHOTS_FILE_NAME);
let fuzzer_snapshots = snapshot_generator::generate_snapshots_code(&self.programs_data)
.map_err(Error::ReadProgramCodeFailed)?;
let fuzzer_snapshots = Commander::format_program_code(&fuzzer_snapshots).await?;

self.create_file(&accounts_snapshots_path, &fuzzer_snapshots)
.await?;

let cargo_toml_content =
load_template!("/src/templates/trident-tests/Cargo_fuzz.toml.tmpl");

self.create_file(&fuzz_tests_manifest_path, cargo_toml_content)
.await?;

self.add_bin_target(&fuzz_tests_manifest_path, &new_fuzz_test, &new_bin_target)
.await?;
self.add_program_dependencies(&fuzz_dir_path, "dependencies", None)
.await?;

self.add_workspace_member(&format!(
"{TESTS_WORKSPACE_DIRECTORY}/{FUZZ_TEST_DIRECTORY}",
))
.await?;
}

/// Add/Update .program_client
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
pub mod fuzz_example3_fuzz_instructions {
use crate::accounts_snapshots::*;
use trident_client::fuzzing::*;
#[derive(Arbitrary, DisplayIx, FuzzTestExecutor, FuzzDeserialize)]
pub enum FuzzInstruction {
Expand Down

0 comments on commit 0af6b10

Please sign in to comment.