Move test-validator to own module to reduce core dependencies (#20658)
* Move test-validator to own module to reduce core dependencies * Fix a few TestValidator paths * Use solana_test_validator crate for solana_test_validator bin * Move client int tests to separate crate Co-authored-by: Tyera Eulberg <tyera@solana.com>
This commit is contained in:
35
client-test/Cargo.toml
Normal file
35
client-test/Cargo.toml
Normal file
@ -0,0 +1,35 @@
|
||||
[package]
|
||||
name = "solana-client-test"
|
||||
version = "1.9.0"
|
||||
description = "Solana RPC Test"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-client-test"
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
solana-client = { path = "../client", version = "=1.9.0" }
|
||||
solana-measure = { path = "../measure", version = "=1.9.0" }
|
||||
solana-merkle-tree = { path = "../merkle-tree", version = "=1.9.0" }
|
||||
solana-metrics = { path = "../metrics", version = "=1.9.0" }
|
||||
solana-perf = { path = "../perf", version = "=1.9.0" }
|
||||
solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "=1.9.0" }
|
||||
solana-rpc = { path = "../rpc", version = "=1.9.0" }
|
||||
solana-runtime = { path = "../runtime", version = "=1.9.0" }
|
||||
solana-sdk = { path = "../sdk", version = "=1.9.0" }
|
||||
solana-streamer = { path = "../streamer", version = "=1.9.0" }
|
||||
solana-test-validator = { path = "../test-validator", version = "=1.9.0" }
|
||||
solana-version = { path = "../version", version = "=1.9.0" }
|
||||
systemstat = "0.1.10"
|
||||
|
||||
[dev-dependencies]
|
||||
solana-logger = { path = "../logger", version = "=1.9.0" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["lib"]
|
||||
name = "solana_entry"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
1
client-test/src/lib.rs
Normal file
1
client-test/src/lib.rs
Normal file
@ -0,0 +1 @@
|
||||
// This is a test-only crate
|
146
client-test/tests/client.rs
Normal file
146
client-test/tests/client.rs
Normal file
@ -0,0 +1,146 @@
|
||||
use solana_client::{pubsub_client::PubsubClient, rpc_client::RpcClient, rpc_response::SlotInfo};
|
||||
use solana_rpc::{
|
||||
optimistically_confirmed_bank_tracker::OptimisticallyConfirmedBank,
|
||||
rpc_pubsub_service::{PubSubConfig, PubSubService},
|
||||
rpc_subscriptions::RpcSubscriptions,
|
||||
};
|
||||
use solana_runtime::{
|
||||
bank::Bank,
|
||||
bank_forks::BankForks,
|
||||
commitment::BlockCommitmentCache,
|
||||
genesis_utils::{create_genesis_config, GenesisConfigInfo},
|
||||
};
|
||||
use solana_sdk::{
|
||||
commitment_config::CommitmentConfig,
|
||||
native_token::sol_to_lamports,
|
||||
rpc_port,
|
||||
signature::{Keypair, Signer},
|
||||
system_transaction,
|
||||
};
|
||||
use solana_streamer::socket::SocketAddrSpace;
|
||||
use solana_test_validator::TestValidator;
|
||||
use std::{
|
||||
net::{IpAddr, SocketAddr},
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc, RwLock,
|
||||
},
|
||||
thread::sleep,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use systemstat::Ipv4Addr;
|
||||
|
||||
#[test]
|
||||
fn test_rpc_client() {
|
||||
solana_logger::setup();
|
||||
|
||||
let alice = Keypair::new();
|
||||
let test_validator =
|
||||
TestValidator::with_no_fees(alice.pubkey(), None, SocketAddrSpace::Unspecified);
|
||||
|
||||
let bob_pubkey = solana_sdk::pubkey::new_rand();
|
||||
|
||||
let client = RpcClient::new(test_validator.rpc_url());
|
||||
|
||||
assert_eq!(
|
||||
client.get_version().unwrap().solana_core,
|
||||
solana_version::semver!()
|
||||
);
|
||||
|
||||
assert!(client.get_account(&bob_pubkey).is_err());
|
||||
|
||||
assert_eq!(client.get_balance(&bob_pubkey).unwrap(), 0);
|
||||
|
||||
let original_alice_balance = client.get_balance(&alice.pubkey()).unwrap();
|
||||
|
||||
let blockhash = client.get_latest_blockhash().unwrap();
|
||||
|
||||
let tx = system_transaction::transfer(&alice, &bob_pubkey, sol_to_lamports(20.0), blockhash);
|
||||
let signature = client.send_transaction(&tx).unwrap();
|
||||
|
||||
let mut confirmed_tx = false;
|
||||
|
||||
let now = Instant::now();
|
||||
while now.elapsed().as_secs() <= 20 {
|
||||
let response = client
|
||||
.confirm_transaction_with_commitment(&signature, CommitmentConfig::default())
|
||||
.unwrap();
|
||||
|
||||
if response.value {
|
||||
confirmed_tx = true;
|
||||
break;
|
||||
}
|
||||
|
||||
sleep(Duration::from_millis(500));
|
||||
}
|
||||
|
||||
assert!(confirmed_tx);
|
||||
|
||||
assert_eq!(
|
||||
client.get_balance(&bob_pubkey).unwrap(),
|
||||
sol_to_lamports(20.0)
|
||||
);
|
||||
assert_eq!(
|
||||
client.get_balance(&alice.pubkey()).unwrap(),
|
||||
original_alice_balance - sol_to_lamports(20.0)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_slot_subscription() {
|
||||
let pubsub_addr = SocketAddr::new(
|
||||
IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)),
|
||||
rpc_port::DEFAULT_RPC_PUBSUB_PORT,
|
||||
);
|
||||
let exit = Arc::new(AtomicBool::new(false));
|
||||
let GenesisConfigInfo { genesis_config, .. } = create_genesis_config(10_000);
|
||||
let bank = Bank::new_for_tests(&genesis_config);
|
||||
let bank_forks = Arc::new(RwLock::new(BankForks::new(bank)));
|
||||
let optimistically_confirmed_bank =
|
||||
OptimisticallyConfirmedBank::locked_from_bank_forks_root(&bank_forks);
|
||||
let subscriptions = Arc::new(RpcSubscriptions::new_for_tests(
|
||||
&exit,
|
||||
bank_forks,
|
||||
Arc::new(RwLock::new(BlockCommitmentCache::default())),
|
||||
optimistically_confirmed_bank,
|
||||
));
|
||||
let (trigger, pubsub_service) =
|
||||
PubSubService::new(PubSubConfig::default(), &subscriptions, pubsub_addr);
|
||||
std::thread::sleep(Duration::from_millis(400));
|
||||
|
||||
let (mut client, receiver) =
|
||||
PubsubClient::slot_subscribe(&format!("ws://0.0.0.0:{}/", pubsub_addr.port())).unwrap();
|
||||
|
||||
let mut errors: Vec<(SlotInfo, SlotInfo)> = Vec::new();
|
||||
|
||||
for i in 0..3 {
|
||||
subscriptions.notify_slot(i + 1, i, i);
|
||||
|
||||
let maybe_actual = receiver.recv_timeout(Duration::from_millis(400));
|
||||
|
||||
match maybe_actual {
|
||||
Ok(actual) => {
|
||||
let expected = SlotInfo {
|
||||
slot: i + 1,
|
||||
parent: i,
|
||||
root: i,
|
||||
};
|
||||
|
||||
if actual != expected {
|
||||
errors.push((actual, expected));
|
||||
}
|
||||
}
|
||||
Err(_err) => {
|
||||
eprintln!("unexpected websocket receive timeout");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit.store(true, Ordering::Relaxed);
|
||||
trigger.cancel();
|
||||
client.shutdown().unwrap();
|
||||
pubsub_service.close().unwrap();
|
||||
|
||||
assert_eq!(errors, [].to_vec());
|
||||
}
|
Reference in New Issue
Block a user