Skip to content

Commit

Permalink
fix: consistent fixture file naming (#34)
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec authored Oct 19, 2024
1 parent 91e5c64 commit 55e1d3b
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 57 deletions.
1 change: 1 addition & 0 deletions fuzz/fixture/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use {
};

/// Instruction context fixture.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Context {
/// The compute budget to use for the simulation.
pub compute_budget: ComputeBudget,
Expand Down
1 change: 1 addition & 0 deletions fuzz/fixture/src/effects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use {
};

/// Represents the effects of a single instruction.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Effects {
/// Compute units consumed by the instruction.
pub compute_units_consumed: u64,
Expand Down
4 changes: 3 additions & 1 deletion fuzz/fixture/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use {

/// A fixture for invoking a single instruction against a simulated SVM
/// program runtime environment, for a given program.
#[derive(Clone, Debug, Default, PartialEq)]
pub struct Fixture {
/// The fixture inputs.
pub input: Context,
Expand Down Expand Up @@ -65,10 +66,11 @@ impl Fixture {
/// Dumps the `Fixture` to a JSON file.
/// The file name is a hash of the fixture with the `.json` extension.
pub fn dump_to_json_file(self, dir_path: &str) {
let blob = self.clone().encode();
let json = serde_json::to_string_pretty(&ProtoFixture::from(self))
.expect("Failed to serialize fixture to JSON");

let hash = solana_sdk::hash::hash(json.as_bytes());
let hash = solana_sdk::hash::hash(&blob);
let file_name = format!("instr-{}.json", bs58::encode(hash).into_string());

write_file(Path::new(dir_path), &file_name, json.as_bytes());
Expand Down
15 changes: 14 additions & 1 deletion fuzz/fixture/src/sysvars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use {
};

/// A fixture of runtime sysvars.
#[derive(Default)]
#[derive(Debug, Default, PartialEq)]
pub struct Sysvars {
/// `Clock` sysvar.
pub clock: Clock,
Expand All @@ -36,6 +36,19 @@ pub struct Sysvars {
pub stake_history: StakeHistory,
}

impl Clone for Sysvars {
fn clone(&self) -> Self {
Self {
clock: self.clock.clone(),
epoch_rewards: self.epoch_rewards.clone(),
epoch_schedule: self.epoch_schedule.clone(),
rent: self.rent.clone(),
slot_hashes: SlotHashes::new(self.slot_hashes.slot_hashes()),
stake_history: self.stake_history.clone(),
}
}
}

// Clock sysvar.
impl From<ProtoClock> for Clock {
fn from(value: ProtoClock) -> Self {
Expand Down
109 changes: 54 additions & 55 deletions harness/tests/dump_fixture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
use {
mollusk_svm::{result::Check, Mollusk},
mollusk_svm_fuzz_fixture::Fixture,
solana_sdk::{
account::AccountSharedData, instruction::Instruction, pubkey::Pubkey, system_instruction,
system_program,
},
solana_sdk::{account::AccountSharedData, pubkey::Pubkey, system_instruction, system_program},
std::path::Path,
};

Expand Down Expand Up @@ -62,7 +59,12 @@ fn clear() {
}
}

fn mollusk_test() -> (Mollusk, Instruction, [(Pubkey, AccountSharedData); 2]) {
#[test]
fn test_dump() {
clear();
std::env::set_var("EJECT_FUZZ_FIXTURES", EJECT_FUZZ_FIXTURES);
std::env::set_var("EJECT_FUZZ_FIXTURES_JSON", EJECT_FUZZ_FIXTURES);

let sender = Pubkey::new_unique();
let recipient = Pubkey::new_unique();

Expand All @@ -72,7 +74,7 @@ fn mollusk_test() -> (Mollusk, Instruction, [(Pubkey, AccountSharedData); 2]) {
let mollusk = Mollusk::default();

let instruction = system_instruction::transfer(&sender, &recipient, transfer_amount);
let accounts = [
let accounts = vec![
(
sender,
AccountSharedData::new(base_lamports, 0, &system_program::id()),
Expand All @@ -94,54 +96,51 @@ fn mollusk_test() -> (Mollusk, Instruction, [(Pubkey, AccountSharedData); 2]) {

mollusk.process_and_validate_instruction(&instruction, &accounts, &checks);

(mollusk, instruction, accounts)
}

#[test]
fn test_dump() {
clear();

// First try protobuf.
{
std::env::set_var("EJECT_FUZZ_FIXTURES", EJECT_FUZZ_FIXTURES);

let (mollusk, instruction, accounts) = mollusk_test();

let fixture_path = find_fixture(&FileType::Blob).unwrap();
let fixture = Fixture::load_from_blob_file(&fixture_path);

assert_eq!(fixture.input.compute_budget, mollusk.compute_budget);
assert_eq!(fixture.input.feature_set, mollusk.feature_set);
assert_eq!(fixture.input.sysvars.clock, mollusk.sysvars.clock);
assert_eq!(fixture.input.sysvars.rent, mollusk.sysvars.rent);
assert_eq!(fixture.input.program_id, instruction.program_id);
assert_eq!(fixture.input.instruction_accounts, instruction.accounts);
assert_eq!(fixture.input.instruction_data, instruction.data);
assert_eq!(fixture.input.accounts, accounts);

std::env::remove_var("EJECT_FUZZ_FIXTURES");
}

// Now try JSON.
{
std::env::set_var("EJECT_FUZZ_FIXTURES_JSON", EJECT_FUZZ_FIXTURES);

let (mollusk, instruction, accounts) = mollusk_test();

let fixture_path = find_fixture(&FileType::Json).unwrap();
let fixture = Fixture::load_from_json_file(&fixture_path);

assert_eq!(fixture.input.compute_budget, mollusk.compute_budget);
assert_eq!(fixture.input.feature_set, mollusk.feature_set);
assert_eq!(fixture.input.sysvars.clock, mollusk.sysvars.clock);
assert_eq!(fixture.input.sysvars.rent, mollusk.sysvars.rent);
assert_eq!(fixture.input.program_id, instruction.program_id);
assert_eq!(fixture.input.instruction_accounts, instruction.accounts);
assert_eq!(fixture.input.instruction_data, instruction.data);
assert_eq!(fixture.input.accounts, accounts);

std::env::remove_var("EJECT_FUZZ_FIXTURES_JSON");
}

// Validate the protobuf fixture matches the test environment.
let blob_fixture_path = find_fixture(&FileType::Blob).unwrap();
let blob_fixture = Fixture::load_from_blob_file(&blob_fixture_path);
assert_eq!(blob_fixture.input.compute_budget, mollusk.compute_budget);
assert_eq!(blob_fixture.input.feature_set, mollusk.feature_set);
assert_eq!(blob_fixture.input.sysvars.clock, mollusk.sysvars.clock);
assert_eq!(blob_fixture.input.sysvars.rent, mollusk.sysvars.rent);
assert_eq!(blob_fixture.input.program_id, instruction.program_id);
assert_eq!(
blob_fixture.input.instruction_accounts,
instruction.accounts
);
assert_eq!(blob_fixture.input.instruction_data, instruction.data);
assert_eq!(blob_fixture.input.accounts, accounts);

// Validate the JSON fixture matches the test environment.
let json_fixture_path = find_fixture(&FileType::Json).unwrap();
let json_fixture = Fixture::load_from_json_file(&json_fixture_path);
assert_eq!(json_fixture.input.compute_budget, mollusk.compute_budget);
assert_eq!(json_fixture.input.feature_set, mollusk.feature_set);
assert_eq!(json_fixture.input.sysvars.clock, mollusk.sysvars.clock);
assert_eq!(json_fixture.input.sysvars.rent, mollusk.sysvars.rent);
assert_eq!(json_fixture.input.program_id, instruction.program_id);
assert_eq!(
json_fixture.input.instruction_accounts,
instruction.accounts
);
assert_eq!(json_fixture.input.instruction_data, instruction.data);
assert_eq!(json_fixture.input.accounts, accounts);

// Ensure both files have the same name.
assert_eq!(
Path::new(&blob_fixture_path)
.file_stem()
.unwrap()
.to_str()
.unwrap(),
Path::new(&json_fixture_path)
.file_stem()
.unwrap()
.to_str()
.unwrap()
);

std::env::remove_var("EJECT_FUZZ_FIXTURES");
std::env::remove_var("EJECT_FUZZ_FIXTURES_JSON");
clear();
}

0 comments on commit 55e1d3b

Please sign in to comment.