Skip to content

Commit

Permalink
Refactor tests for RevokePendingActivation (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec authored Aug 15, 2024
1 parent 13dcd40 commit 0f12ca8
Show file tree
Hide file tree
Showing 3 changed files with 235 additions and 135 deletions.
135 changes: 0 additions & 135 deletions program/tests/functional.rs

This file was deleted.

187 changes: 187 additions & 0 deletions program/tests/revoke_pending_activation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#![cfg(feature = "test-sbf")]

mod setup;

use {
setup::{setup, setup_active_feature, setup_pending_feature},
solana_feature_gate_program::{
error::FeatureGateError, instruction::revoke_pending_activation,
},
solana_program::instruction::InstructionError,
solana_program_test::*,
solana_sdk::{
account::{Account, AccountSharedData},
feature::Feature,
pubkey::Pubkey,
signature::{Keypair, Signer},
transaction::{Transaction, TransactionError},
},
};

#[tokio::test]
async fn fail_feature_not_signer() {
let mut context = setup().start_with_context().await;

let mut instruction = revoke_pending_activation(&Pubkey::new_unique());
instruction.accounts[0].is_signer = false;

let transaction = Transaction::new_signed_with_payer(
&[instruction],
Some(&context.payer.pubkey()),
&[&context.payer],
context.last_blockhash,
);

let error = context
.banks_client
.process_transaction(transaction)
.await
.unwrap_err()
.unwrap();

assert_eq!(
error,
TransactionError::InstructionError(0, InstructionError::MissingRequiredSignature)
);
}

#[tokio::test]
async fn fail_feature_incorrect_owner() {
let feature_keypair = Keypair::new();

let mut context = setup().start_with_context().await;

// Set up a feature account with incorrect owner.
{
context.set_account(
&feature_keypair.pubkey(),
&AccountSharedData::from(Account {
lamports: 100_000_000,
data: vec![0; Feature::size_of()],
owner: Pubkey::new_unique(), // Incorrect owner.
..Account::default()
}),
);
}

let transaction = Transaction::new_signed_with_payer(
&[revoke_pending_activation(&feature_keypair.pubkey())],
Some(&context.payer.pubkey()),
&[&context.payer, &feature_keypair],
context.last_blockhash,
);

let error = context
.banks_client
.process_transaction(transaction)
.await
.unwrap_err()
.unwrap();

assert_eq!(
error,
TransactionError::InstructionError(0, InstructionError::InvalidAccountOwner)
);
}

#[tokio::test]
async fn fail_feature_invalid_data() {
let feature_keypair = Keypair::new();

let mut context = setup().start_with_context().await;

// Set up a feature account with invalid data.
{
context.set_account(
&feature_keypair.pubkey(),
&AccountSharedData::from(Account {
lamports: 100_000_000,
data: vec![8; Feature::size_of()],
owner: solana_feature_gate_program::id(),
..Account::default()
}),
);
}

let transaction = Transaction::new_signed_with_payer(
&[revoke_pending_activation(&feature_keypair.pubkey())],
Some(&context.payer.pubkey()),
&[&context.payer, &feature_keypair],
context.last_blockhash,
);

let error = context
.banks_client
.process_transaction(transaction)
.await
.unwrap_err()
.unwrap();

assert_eq!(
error,
TransactionError::InstructionError(0, InstructionError::InvalidAccountData)
);
}

#[tokio::test]
async fn fail_feature_already_activated() {
let feature_keypair = Keypair::new();

let mut context = setup().start_with_context().await;

// Set up an active feature account.
setup_active_feature(&mut context, &feature_keypair.pubkey());

let transaction = Transaction::new_signed_with_payer(
&[revoke_pending_activation(&feature_keypair.pubkey())],
Some(&context.payer.pubkey()),
&[&context.payer, &feature_keypair],
context.last_blockhash,
);

let error = context
.banks_client
.process_transaction(transaction)
.await
.unwrap_err()
.unwrap();

assert_eq!(
error,
TransactionError::InstructionError(
0,
InstructionError::Custom(FeatureGateError::FeatureAlreadyActivated as u32)
)
);
}

#[tokio::test]
async fn success() {
let feature_keypair = Keypair::new();

let mut context = setup().start_with_context().await;

// Set up a pending feature account.
setup_pending_feature(&mut context, &feature_keypair.pubkey());

let transaction = Transaction::new_signed_with_payer(
&[revoke_pending_activation(&feature_keypair.pubkey())],
Some(&context.payer.pubkey()),
&[&context.payer, &feature_keypair],
context.last_blockhash,
);

context
.banks_client
.process_transaction(transaction)
.await
.unwrap();

// Confirm feature account was closed.
let feature_account = context
.banks_client
.get_account(feature_keypair.pubkey())
.await
.unwrap();
assert!(feature_account.is_none());
}
48 changes: 48 additions & 0 deletions program/tests/setup.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#![cfg(feature = "test-sbf")]
#![allow(dead_code)]

use {
solana_program_test::*,
solana_sdk::{
account::{Account, AccountSharedData},
pubkey::Pubkey,
},
};

pub fn setup() -> ProgramTest {
ProgramTest::new(
"solana_feature_gate_program",
solana_feature_gate_program::id(),
processor!(solana_feature_gate_program::processor::process),
)
}

pub fn setup_pending_feature(context: &mut ProgramTestContext, feature_id: &Pubkey) {
context.set_account(
feature_id,
&AccountSharedData::from(Account {
lamports: 100_000_000,
data: vec![
0, // `None`
0, 0, 0, 0, 0, 0, 0, 0,
],
owner: solana_feature_gate_program::id(),
..Account::default()
}),
);
}

pub fn setup_active_feature(context: &mut ProgramTestContext, feature_id: &Pubkey) {
context.set_account(
feature_id,
&AccountSharedData::from(Account {
lamports: 100_000_000,
data: vec![
1, // `Some`
45, 0, 0, 0, 0, 0, 0, 0, // Random slot `u64`
],
owner: solana_feature_gate_program::id(),
..Account::default()
}),
);
}

0 comments on commit 0f12ca8

Please sign in to comment.