Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

hide heavy tests behind feature flag #108

Merged
merged 1 commit into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions rust/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = ["sanctum-lst-list", "tojup"]
borsh = "^0.9"
clap = { version = "^4", features = ["derive"] }
csv = "^1"
lazy_static = "^1"
mpl-token-metadata = "^4"
reqwest = "^0.11"
sanctum-macros = "^1"
Expand Down
5 changes: 5 additions & 0 deletions rust/sanctum-lst-list/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ edition = "2021"

include = ["README.md", "sanctum-lst-list.toml", "src/"]

[features]
default = []
test-all = []

[dependencies]
serde = { workspace = true }
serde_with = { workspace = true }
Expand All @@ -14,6 +18,7 @@ toml = { workspace = true }

[dev-dependencies]
borsh = { workspace = true }
lazy_static = { workspace = true }
mpl-token-metadata = { workspace = true }
reqwest = { workspace = true }
solana-client = { workspace = true }
Expand Down
15 changes: 15 additions & 0 deletions rust/sanctum-lst-list/tests/common/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,16 @@
use lazy_static::lazy_static;
use sanctum_lst_list::{SanctumLst, SanctumLstList};

lazy_static! {
pub static ref SANCTUM_LST_LIST: SanctumLstList = SanctumLstList::load();
}

pub const SOLANA_RPC_URL: &str = "https://api.mainnet-beta.solana.com";

pub fn find_sanctum_lst_by_symbol_unwrapped(symbol: &str) -> &SanctumLst {
SANCTUM_LST_LIST
.sanctum_lst_list
.iter()
.find(|lst| lst.symbol == symbol)
.unwrap()
}
45 changes: 31 additions & 14 deletions rust/sanctum-lst-list/tests/tests/logo.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
use std::error::Error;

use reqwest::header;
use sanctum_lst_list::{SanctumLst, SanctumLstList};
use tokio::task::JoinSet;
use sanctum_lst_list::SanctumLst;

use crate::common::find_sanctum_lst_by_symbol_unwrapped;

// Tests for latest batch

#[tokio::test]
async fn verify_all_token_logo_image_uri_valid() {
let client: &'static reqwest::Client = Box::leak(Box::new(reqwest::Client::new()));
let SanctumLstList { sanctum_lst_list } = SanctumLstList::load();
let mut js = JoinSet::new();
sanctum_lst_list.into_iter().for_each(|slst| {
js.spawn(verify_token_logo_image_uri_valid(client, slst));
});
while let Some(res) = js.join_next().await {
res.unwrap();
}
async fn verify_logo_image_uri_valid_rugsol() {
verify_token_logo_image_uri_valid_by_symbol("rugSOL").await;
}

async fn verify_token_logo_image_uri_valid_by_symbol(symbol: &str) {
let client = reqwest::Client::new();
let sanctum_lst = find_sanctum_lst_by_symbol_unwrapped(symbol);
verify_token_logo_image_uri_valid(&client, sanctum_lst).await;
}

async fn verify_token_logo_image_uri_valid(
client: &reqwest::Client,
SanctumLst {
logo_uri, symbol, ..
}: SanctumLst,
}: &SanctumLst,
) {
let content_type = match fetch_logo_image_uri_content_type(client, &logo_uri).await {
let content_type = match fetch_logo_image_uri_content_type(client, logo_uri).await {
Ok(ct) => ct,
Err(e) => panic!("{symbol} fetch failed: {e}"),
};
Expand All @@ -48,3 +49,19 @@ async fn fetch_logo_image_uri_content_type(
.to_str()?
.to_owned())
}

#[cfg(feature = "test-all")]
#[tokio::test]
async fn verify_all_token_logo_image_uri_valid() {
let client: &'static reqwest::Client = Box::leak(Box::new(reqwest::Client::new()));
let mut js = tokio::task::JoinSet::new();
crate::common::SANCTUM_LST_LIST
.sanctum_lst_list
.iter()
.for_each(|slst| {
js.spawn(verify_token_logo_image_uri_valid(client, slst));
});
while let Some(res) = js.join_next().await {
res.unwrap();
}
}
110 changes: 63 additions & 47 deletions rust/sanctum-lst-list/tests/tests/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,66 +1,34 @@
use std::{collections::HashSet, error::Error};

use mpl_token_metadata::accounts::Metadata;
use sanctum_lst_list::{SanctumLst, SanctumLstList};
use sanctum_lst_list::SanctumLst;
use serde::Deserialize;
use solana_client::nonblocking::rpc_client::RpcClient;
use solana_sdk::commitment_config::CommitmentConfig;

use crate::common::SOLANA_RPC_URL;
use crate::common::{find_sanctum_lst_by_symbol_unwrapped, SOLANA_RPC_URL};

#[tokio::test]
async fn verify_all_lsts_token_metadata() {
let client: &'static reqwest::Client = Box::leak(Box::new(reqwest::Client::new()));
let rpc = RpcClient::new(SOLANA_RPC_URL.to_owned());
let SanctumLstList { sanctum_lst_list } = SanctumLstList::load();
// just do it sequentially to avoid rpc limits
let mut no_metadata_lsts = Vec::new();

let ignore_symbols = [
"wifSOL", // name is `dogwifSOL` but onchain is `wifSOL`
"juicingJupSOL", // symbol onchain is "jjupSOL"
"fmSOL", // name is `SolanaFM Staked SOL` but onchain is `fmSOL`
"dSOL", // name is `Drift Staked SOL` but onchain is `Drift Staked Sol`
"stakeSOL", // name is `Stake City SOL` but onchain is `stakeSOL`
"pumpkinSOL", // name is `Pumpkin's Staked SOL` but onchain is `pumpkinSOL`
"JSOL", // name is `JPOOL Solana Token` but onchain is `JPool Staked SOL`
"thugSOL", // name is `Thugbirdz Staked SOL` but onchain is `ThugBirdz Staked SOL`
"wenSOL", // symbol onchain is `WenSOL`
"dlgtSOL", // name is `Delegate Liquid Staking SOL` but onchain is `Delegate Liquid Staking Token`
"hausSOL", // name is `StakeHaus Staked SOL` but onchain is `hausSOL`
"rSOL", // name is `reflectSOL` but onchain is `Reflect Staked Solana`
"xSOL", // name is `ElagabalX Staked SOL` but onchain is `xSOL`
"stepSOL", // name is `Step Staked SOL` but onchain is `stepSOL`
"SOL", // name is `SOL` but onchain is `Wrapped SOL`
"mSOL", // name is `Marinade staked SOL` but onchain is `Marinade staked SOL (mSOL)`
"spikySOL", // malformed linked metadata json
"pineSOL", // metadata URI links to logo instead of json
"uwuSOL", // name is `UwU Staked SOL` but onchain is Uwu Staked SOL`
]
.into_iter()
.collect();
// Tests for latest batch

for sanctum_lst in sanctum_lst_list.iter() {
match verify_lst_token_metadata(client, &rpc, sanctum_lst, &ignore_symbols).await {
Ok(Some(..)) => (),
Ok(None) => {
no_metadata_lsts.push(&sanctum_lst.symbol);
}
Err(e) => {
panic!("{}: {}", sanctum_lst.symbol, e);
}
}
}
if !no_metadata_lsts.is_empty() {
eprintln!("LSTs with no onchain token metadata: {no_metadata_lsts:?}");
}
#[tokio::test]
async fn verify_lst_token_metadata_rugsol() {
verify_lst_token_metadata_by_symbol("rugSOL").await;
}

#[derive(Debug, Deserialize)]
struct OffchainMetadata {
image: String,
}

async fn verify_lst_token_metadata_by_symbol(symbol: &str) {
let client = reqwest::Client::new();
let rpc = RpcClient::new(SOLANA_RPC_URL.to_owned());
let sanctum_lst = find_sanctum_lst_by_symbol_unwrapped(symbol);
verify_lst_token_metadata(&client, &rpc, sanctum_lst, &HashSet::new())
.await
.unwrap();
}

async fn verify_lst_token_metadata(
client: &reqwest::Client,
rpc: &RpcClient,
Expand Down Expand Up @@ -119,3 +87,51 @@ async fn verify_lst_token_metadata(

Ok(Some(()))
}

#[cfg(feature = "test-all")]
#[tokio::test]
async fn verify_all_lsts_token_metadata() {
let client: &'static reqwest::Client = Box::leak(Box::new(reqwest::Client::new()));
let rpc = RpcClient::new(SOLANA_RPC_URL.to_owned());
// just do it sequentially to avoid rpc limits
let mut no_metadata_lsts = Vec::new();

let ignore_symbols = [
"wifSOL", // name is `dogwifSOL` but onchain is `wifSOL`
"juicingJupSOL", // symbol onchain is "jjupSOL"
"fmSOL", // name is `SolanaFM Staked SOL` but onchain is `fmSOL`
"dSOL", // name is `Drift Staked SOL` but onchain is `Drift Staked Sol`
"stakeSOL", // name is `Stake City SOL` but onchain is `stakeSOL`
"pumpkinSOL", // name is `Pumpkin's Staked SOL` but onchain is `pumpkinSOL`
"JSOL", // name is `JPOOL Solana Token` but onchain is `JPool Staked SOL`
"thugSOL", // name is `Thugbirdz Staked SOL` but onchain is `ThugBirdz Staked SOL`
"wenSOL", // symbol onchain is `WenSOL`
"dlgtSOL", // name is `Delegate Liquid Staking SOL` but onchain is `Delegate Liquid Staking Token`
"hausSOL", // name is `StakeHaus Staked SOL` but onchain is `hausSOL`
"rSOL", // name is `reflectSOL` but onchain is `Reflect Staked Solana`
"xSOL", // name is `ElagabalX Staked SOL` but onchain is `xSOL`
"stepSOL", // name is `Step Staked SOL` but onchain is `stepSOL`
"SOL", // name is `SOL` but onchain is `Wrapped SOL`
"mSOL", // name is `Marinade staked SOL` but onchain is `Marinade staked SOL (mSOL)`
"spikySOL", // malformed linked metadata json
"pineSOL", // metadata URI links to logo instead of json
"uwuSOL", // name is `UwU Staked SOL` but onchain is Uwu Staked SOL`
]
.into_iter()
.collect();

for sanctum_lst in crate::common::SANCTUM_LST_LIST.sanctum_lst_list.iter() {
match verify_lst_token_metadata(client, &rpc, sanctum_lst, &ignore_symbols).await {
Ok(Some(..)) => (),
Ok(None) => {
no_metadata_lsts.push(&sanctum_lst.symbol);
}
Err(e) => {
panic!("{}: {}", sanctum_lst.symbol, e);
}
}
}
if !no_metadata_lsts.is_empty() {
eprintln!("LSTs with no onchain token metadata: {no_metadata_lsts:?}");
}
}
31 changes: 22 additions & 9 deletions rust/sanctum-lst-list/tests/tests/pool.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
use borsh::BorshDeserialize;
use sanctum_lst_list::{PoolInfo, SanctumLst, SanctumLstList};
use sanctum_lst_list::{PoolInfo, SanctumLst};
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;
use spl_stake_pool_interface::{StakePool, ValidatorList, ValidatorStakeInfo};
use spl_token_2022::extension::StateWithExtensions;

use crate::common::SOLANA_RPC_URL;
use crate::common::{find_sanctum_lst_by_symbol_unwrapped, SOLANA_RPC_URL};

// Tests for latest batch

// this takes around 30s with around 70 pools
#[test]
fn verify_all_pools_valid() {
fn verify_pool_valid_rugsol() {
verify_pool_valid_by_symbol("rugSOL");
}

fn verify_pool_valid_by_symbol(symbol: &str) {
let rpc = RpcClient::new(SOLANA_RPC_URL);
let SanctumLstList { sanctum_lst_list } = SanctumLstList::load();
// just do it sequentially to avoid rpc limits
for sanctum_lst in sanctum_lst_list {
verify_pool_valid(&rpc, &sanctum_lst);
}
let sanctum_lst = find_sanctum_lst_by_symbol_unwrapped(symbol);
verify_pool_valid(&rpc, sanctum_lst);
}

fn verify_pool_valid(
Expand Down Expand Up @@ -112,3 +114,14 @@ fn verify_pool_valid(
}
}
}

// this takes around 30s with around 70 pools
#[cfg(feature = "test-all")]
#[test]
fn verify_all_pools_valid() {
let rpc = RpcClient::new(SOLANA_RPC_URL);
// just do it sequentially to avoid rpc limits
for sanctum_lst in crate::common::SANCTUM_LST_LIST.sanctum_lst_list.iter() {
verify_pool_valid(&rpc, sanctum_lst);
}
}
36 changes: 25 additions & 11 deletions rust/sanctum-lst-list/tests/tests/sanctum_router.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
use std::error::Error;

use sanctum_lst_list::SanctumLstList;
use solana_client::rpc_client::RpcClient;
use solana_program::pubkey::Pubkey;
use spl_token_2022::{extension::StateWithExtensions, state::AccountState};

use crate::common::SOLANA_RPC_URL;
use crate::common::{find_sanctum_lst_by_symbol_unwrapped, SOLANA_RPC_URL};

// Tests for latest batch

#[test]
fn verify_sanctum_router_fee_token_acc_created_rugsol() {
verify_sanctum_router_fee_token_acc_created_by_symbol("rugSOL").unwrap();
}

// Copied from
// https://github.com/igneous-labs/stakedex-sdk/blob/master/common/src/pda.rs
Expand All @@ -25,16 +31,12 @@ fn find_fee_token_acc(mint: &Pubkey) -> (Pubkey, u8) {
Pubkey::find_program_address(&fee_token_account_seeds(mint), &stakedex_interface::ID)
}

#[test]
fn verify_all_lsts_have_router_fee_token_acc_created() {
fn verify_sanctum_router_fee_token_acc_created_by_symbol(
symbol: &str,
) -> Result<(), Box<dyn Error>> {
let rpc = RpcClient::new(SOLANA_RPC_URL);
let SanctumLstList { sanctum_lst_list } = SanctumLstList::load();
// just do it sequentially to avoid rpc limits
for sanctum_lst in sanctum_lst_list {
if let Err(e) = verify_sanctum_router_fee_token_acc_created(&rpc, &sanctum_lst.mint) {
panic!("{}: {}", sanctum_lst.symbol, e);
}
}
let slst = find_sanctum_lst_by_symbol_unwrapped(symbol);
verify_sanctum_router_fee_token_acc_created(&rpc, &slst.mint)
}

fn verify_sanctum_router_fee_token_acc_created(
Expand All @@ -54,3 +56,15 @@ fn verify_sanctum_router_fee_token_acc_created(
}
Ok(())
}

#[cfg(feature = "test-all")]
#[test]
fn verify_all_lsts_have_router_fee_token_acc_created() {
let rpc = RpcClient::new(SOLANA_RPC_URL);
// just do it sequentially to avoid rpc limits
for sanctum_lst in crate::common::SANCTUM_LST_LIST.sanctum_lst_list.iter() {
if let Err(e) = verify_sanctum_router_fee_token_acc_created(&rpc, &sanctum_lst.mint) {
panic!("{}: {}", sanctum_lst.symbol, e);
}
}
}
Loading