change(tests): adds RPC request client for condensing shared code (#5619)
* Adds RPCRequestClient * uses RPCRequestClient in the rest of the rpc calls * removes duplicate expect call * fixed mistaken "get_info" method call with "getinfo" Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
This commit is contained in:
parent
816d845d94
commit
61af406d35
|
@ -161,6 +161,8 @@ use common::{
|
|||
test_type::TestType::{self, *},
|
||||
};
|
||||
|
||||
use crate::common::rpc_client::RPCRequestClient;
|
||||
|
||||
/// The maximum amount of time that we allow the creation of a future to block the `tokio` executor.
|
||||
///
|
||||
/// This should be larger than the amount of time between thread time slices on a busy test VM.
|
||||
|
@ -1320,7 +1322,6 @@ async fn rpc_endpoint_parallel_threads() -> Result<()> {
|
|||
/// Set `parallel_cpu_threads` to true to auto-configure based on the number of CPU cores.
|
||||
#[tracing::instrument]
|
||||
async fn rpc_endpoint(parallel_cpu_threads: bool) -> Result<()> {
|
||||
use hyper::{body::to_bytes, Body, Client, Method, Request};
|
||||
use serde_json::Value;
|
||||
|
||||
let _init_guard = zebra_test::init();
|
||||
|
@ -1331,7 +1332,6 @@ async fn rpc_endpoint(parallel_cpu_threads: bool) -> Result<()> {
|
|||
// Write a configuration that has RPC listen_addr set
|
||||
// [Note on port conflict](#Note on port conflict)
|
||||
let mut config = random_known_rpc_port_config(parallel_cpu_threads)?;
|
||||
let url = format!("http://{}", config.rpc.listen_addr.unwrap());
|
||||
|
||||
let dir = testdir()?.with_config(&mut config)?;
|
||||
let mut child = dir.spawn_child(args!["start"])?;
|
||||
|
@ -1342,24 +1342,15 @@ async fn rpc_endpoint(parallel_cpu_threads: bool) -> Result<()> {
|
|||
)?;
|
||||
|
||||
// Create an http client
|
||||
let client = Client::new();
|
||||
let client = RPCRequestClient::new(config.rpc.listen_addr.unwrap());
|
||||
|
||||
// Create a request to call `getinfo` RPC method
|
||||
let req = Request::builder()
|
||||
.method(Method::POST)
|
||||
.uri(url)
|
||||
.header("content-type", "application/json")
|
||||
.body(Body::from(
|
||||
r#"{"jsonrpc":"1.0","method":"getinfo","params":[],"id":123}"#,
|
||||
))?;
|
||||
|
||||
// Make the call to the RPC endpoint
|
||||
let res = client.request(req).await?;
|
||||
// Make the call to the `getinfo` RPC method
|
||||
let res = client.call("getinfo", "[]".to_string()).await?;
|
||||
|
||||
// Test rpc endpoint response
|
||||
assert!(res.status().is_success());
|
||||
|
||||
let body = to_bytes(res).await;
|
||||
let body = res.bytes().await;
|
||||
let (body, mut child) = child.kill_on_error(body)?;
|
||||
|
||||
let parsed: Value = serde_json::from_slice(&body)?;
|
||||
|
@ -1419,17 +1410,12 @@ fn non_blocking_logger() -> Result<()> {
|
|||
)?;
|
||||
|
||||
// Create an http client
|
||||
let client = reqwest::Client::new();
|
||||
let client = RPCRequestClient::new(zebra_rpc_address);
|
||||
|
||||
// Most of Zebra's lines are 100-200 characters long, so 500 requests should print enough to fill the unix pipe,
|
||||
// fill the channel that tracing logs are queued onto, and drop logs rather than block execution.
|
||||
for _ in 0..500 {
|
||||
let res = client
|
||||
.post(format!("http://{}", &zebra_rpc_address))
|
||||
.body(r#"{"jsonrpc":"1.0","method":"getinfo","params":[],"id":123}"#)
|
||||
.header("Content-Type", "application/json")
|
||||
.send()
|
||||
.await?;
|
||||
let res = client.call("getinfo", "[]".to_string()).await?;
|
||||
|
||||
// Test that zebrad rpc endpoint is still responding to requests
|
||||
assert!(res.status().is_success());
|
||||
|
@ -2042,28 +2028,17 @@ async fn fully_synced_rpc_test() -> Result<()> {
|
|||
return Ok(());
|
||||
};
|
||||
|
||||
zebrad.expect_stdout_line_matches(&format!(
|
||||
"Opened RPC endpoint at {}",
|
||||
zebra_rpc_address.expect("lightwalletd test must have RPC port"),
|
||||
))?;
|
||||
let zebra_rpc_address = zebra_rpc_address.expect("lightwalletd test must have RPC port");
|
||||
|
||||
zebrad.expect_stdout_line_matches(&format!("Opened RPC endpoint at {zebra_rpc_address}"))?;
|
||||
|
||||
let client = RPCRequestClient::new(zebra_rpc_address);
|
||||
|
||||
// Make a getblock test that works only on synced node (high block number).
|
||||
// The block is before the mandatory checkpoint, so the checkpoint cached state can be used
|
||||
// if desired.
|
||||
let client = reqwest::Client::new();
|
||||
let res = client
|
||||
.post(format!(
|
||||
"http://{}",
|
||||
&zebra_rpc_address
|
||||
.expect("lightwalletd test must have RPC port")
|
||||
.to_string()
|
||||
))
|
||||
// Manually constructed request to avoid encoding it, for simplicity
|
||||
.body(r#"{"jsonrpc": "2.0", "method": "getblock", "params": ["1180900", 0], "id":123 }"#)
|
||||
.header("Content-Type", "application/json")
|
||||
.send()
|
||||
.await?
|
||||
.text()
|
||||
.text_from_call("getblock", r#"["1180900", 0]"#.to_string())
|
||||
.await?;
|
||||
|
||||
// Simple textual check to avoid fully parsing the response, for simplicity
|
||||
|
|
|
@ -9,8 +9,6 @@ use std::path::{Path, PathBuf};
|
|||
|
||||
use std::time::Duration;
|
||||
|
||||
use reqwest::Client;
|
||||
|
||||
use color_eyre::eyre::{eyre, Result};
|
||||
use tempfile::TempDir;
|
||||
use tokio::fs;
|
||||
|
@ -26,6 +24,7 @@ use zebra_chain::{
|
|||
use zebra_state::{ChainTipChange, LatestChainTip};
|
||||
|
||||
use crate::common::config::testdir;
|
||||
use crate::common::rpc_client::RPCRequestClient;
|
||||
|
||||
use zebra_state::MAX_BLOCK_REORG_HEIGHT;
|
||||
|
||||
|
@ -231,22 +230,11 @@ pub async fn get_raw_future_blocks(
|
|||
)?;
|
||||
|
||||
// Create an http client
|
||||
let client = Client::new();
|
||||
|
||||
let send_rpc_request = |method, params| {
|
||||
client
|
||||
.post(format!("http://{}", &rpc_address))
|
||||
.body(format!(
|
||||
r#"{{"jsonrpc": "2.0", "method": "{method}", "params": {params}, "id":123 }}"#
|
||||
))
|
||||
.header("Content-Type", "application/json")
|
||||
.send()
|
||||
};
|
||||
let rpc_client = RPCRequestClient::new(rpc_address);
|
||||
|
||||
let blockchain_info: serde_json::Value = serde_json::from_str(
|
||||
&send_rpc_request("getblockchaininfo", "[]".to_string())
|
||||
.await?
|
||||
.text()
|
||||
&rpc_client
|
||||
.text_from_call("getblockchaininfo", "[]".to_string())
|
||||
.await?,
|
||||
)?;
|
||||
|
||||
|
@ -266,9 +254,8 @@ pub async fn get_raw_future_blocks(
|
|||
|
||||
for block_height in (0..max_num_blocks).map(|idx| idx + estimated_finalized_tip_height) {
|
||||
let raw_block: serde_json::Value = serde_json::from_str(
|
||||
&send_rpc_request("getblock", format!(r#"["{block_height}", 0]"#))
|
||||
.await?
|
||||
.text()
|
||||
&rpc_client
|
||||
.text_from_call("getblock", format!(r#"["{block_height}", 0]"#))
|
||||
.await?,
|
||||
)?;
|
||||
|
||||
|
|
|
@ -10,12 +10,12 @@
|
|||
|
||||
use color_eyre::eyre::{Context, Result};
|
||||
|
||||
use reqwest::Client;
|
||||
use zebra_chain::parameters::Network;
|
||||
|
||||
use crate::common::{
|
||||
cached_state::get_raw_future_blocks,
|
||||
launch::{can_spawn_zebrad_for_rpc, spawn_zebrad_for_rpc},
|
||||
rpc_client::RPCRequestClient,
|
||||
test_type::TestType,
|
||||
};
|
||||
|
||||
|
@ -65,16 +65,11 @@ pub(crate) async fn run() -> Result<()> {
|
|||
tracing::info!(?rpc_address, "zebrad opened its RPC port",);
|
||||
|
||||
// Create an http client
|
||||
let client = Client::new();
|
||||
let client = RPCRequestClient::new(rpc_address);
|
||||
|
||||
for raw_block in raw_blocks {
|
||||
let res = client
|
||||
.post(format!("http://{}", &rpc_address))
|
||||
.body(format!(
|
||||
r#"{{"jsonrpc": "2.0", "method": "submitblock", "params": ["{raw_block}"], "id":123 }}"#
|
||||
))
|
||||
.header("Content-Type", "application/json")
|
||||
.send()
|
||||
.call("submitblock", format!(r#"["{raw_block}"]"#))
|
||||
.await?;
|
||||
|
||||
assert!(res.status().is_success());
|
||||
|
|
|
@ -13,6 +13,7 @@ use zebra_test::prelude::*;
|
|||
use crate::common::{
|
||||
launch::ZebradTestDirExt,
|
||||
lightwalletd::wallet_grpc::{connect_to_lightwalletd, ChainSpec},
|
||||
rpc_client::RPCRequestClient,
|
||||
test_type::TestType,
|
||||
};
|
||||
|
||||
|
@ -182,14 +183,9 @@ pub fn are_zebrad_and_lightwalletd_tips_synced(
|
|||
let lightwalletd_tip_height = lightwalletd_tip_block.height;
|
||||
|
||||
// Get the block tip from zebrad
|
||||
let zebrad_json_rpc_client = reqwest::Client::new();
|
||||
let zebrad_blockchain_info = zebrad_json_rpc_client
|
||||
.post(format!("http://{}", &zebra_rpc_address.to_string()))
|
||||
.body(r#"{"jsonrpc": "2.0", "method": "getblockchaininfo", "params": [], "id":123 }"#)
|
||||
.header("Content-Type", "application/json")
|
||||
.send()
|
||||
.await?
|
||||
.text()
|
||||
let client = RPCRequestClient::new(zebra_rpc_address);
|
||||
let zebrad_blockchain_info = client
|
||||
.text_from_call("getblockchaininfo", "[]".to_string())
|
||||
.await?;
|
||||
let zebrad_blockchain_info: serde_json::Value =
|
||||
serde_json::from_str(&zebrad_blockchain_info)?;
|
||||
|
|
|
@ -17,5 +17,6 @@ pub mod failure_messages;
|
|||
pub mod get_block_template_rpcs;
|
||||
pub mod launch;
|
||||
pub mod lightwalletd;
|
||||
pub mod rpc_client;
|
||||
pub mod sync;
|
||||
pub mod test_type;
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
//! A client for calling Zebra's Json-RPC methods
|
||||
|
||||
use std::net::SocketAddr;
|
||||
|
||||
use reqwest::Client;
|
||||
|
||||
/// An http client for making Json-RPC requests
|
||||
pub struct RPCRequestClient {
|
||||
client: Client,
|
||||
rpc_address: SocketAddr,
|
||||
}
|
||||
|
||||
impl RPCRequestClient {
|
||||
/// Creates new RPCRequestSender
|
||||
pub fn new(rpc_address: SocketAddr) -> Self {
|
||||
Self {
|
||||
client: Client::new(),
|
||||
rpc_address,
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds rpc request
|
||||
pub async fn call(
|
||||
&self,
|
||||
method: &'static str,
|
||||
params: impl Into<String>,
|
||||
) -> reqwest::Result<reqwest::Response> {
|
||||
let params = params.into();
|
||||
self.client
|
||||
.post(format!("http://{}", &self.rpc_address))
|
||||
.body(format!(
|
||||
r#"{{"jsonrpc": "2.0", "method": "{method}", "params": {params}, "id":123 }}"#
|
||||
))
|
||||
.header("Content-Type", "application/json")
|
||||
.send()
|
||||
.await
|
||||
}
|
||||
|
||||
/// Builds rpc request and gets text from response
|
||||
pub async fn text_from_call(
|
||||
&self,
|
||||
method: &'static str,
|
||||
params: impl Into<String>,
|
||||
) -> reqwest::Result<String> {
|
||||
self.call(method, params).await?.text().await
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue