Skip to content

Commit

Permalink
migrate smoke tests to use rest api client
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiao Li authored and bors-libra committed Dec 17, 2021
1 parent 0d1754c commit e85ec8f
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 134 deletions.
12 changes: 11 additions & 1 deletion crates/diem-rest-client/src/dpn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@ use serde::{Deserialize, Serialize};

pub use diem_types::account_config::{diem_root_address, BalanceResource, CORE_CODE_ADDRESS};
pub use diem_types::on_chain_config::{
config_struct_tag, DiemVersion as OnChainDiemVersion, OnChainConfig,
config_struct_tag, ConfigurationResource, DiemVersion as OnChainDiemVersion, OnChainConfig,
};

use crate::types::EventHandle;

#[derive(Debug, Serialize, Deserialize)]
pub struct Diem {
pub value: U64,
Expand Down Expand Up @@ -45,3 +47,11 @@ pub struct DiemConfig<T> {
pub struct DiemVersion {
pub major: U64,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Configuration {
#[serde(rename = "epoch")]
pub next_block_epoch: U64,
pub last_reconfiguration_time: U64,
pub events: EventHandle,
}
42 changes: 30 additions & 12 deletions crates/diem-rest-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use move_core_types::{
move_resource::MoveStructType,
};
use reqwest::{header::CONTENT_TYPE, Client as ReqwestClient, StatusCode};
use serde::Deserialize;
use serde::{de::DeserializeOwned, Deserialize};
use std::time::Duration;
use url::Url;

Expand Down Expand Up @@ -65,8 +65,7 @@ impl Client {
dpn::CORE_CODE_ADDRESS,
&dpn::BalanceResource::module_identifier(),
&dpn::BalanceResource::struct_identifier(),
)
.await?;
).await?;
resp.and_then(|resources| {
resources
.into_iter()
Expand All @@ -88,17 +87,16 @@ impl Client {
})
}

// Returns root account DiemAccount::Config<DiemVersion> resource
pub async fn get_diem_version(&self) -> Result<Response<dpn::DiemConfig<dpn::DiemVersion>>> {
let resp = self.get_account_resource(
dpn::diem_root_address(), &dpn::config_struct_tag(dpn::diem_version_identifier())).await?;
resp.and_then(|conf| {
if let Some(val) = conf {
serde_json::from_value(val).map_err(|e| anyhow!("deserialize DiemConfig<DiemVersion> failed: {}", e))
} else {
Err(anyhow!("could not find diem version resource from {}", dpn::diem_root_address()))
}
})
self.get_resource::<dpn::DiemConfig<dpn::DiemVersion>>(dpn::diem_root_address(), &dpn::config_struct_tag(dpn::diem_version_identifier())).await
}

// Returns root account DiemAccount::Configuration resource
pub async fn get_epoch_configuration(&self) -> Result<Response<dpn::Configuration>> {
self.get_resource::<dpn::Configuration>(dpn::diem_root_address(), &dpn::ConfigurationResource::struct_tag()).await
}

}

pub async fn get_ledger_information(&self) -> Result<Response<State>> {
Expand Down Expand Up @@ -293,6 +291,26 @@ impl Client {
})
}

pub async fn get_resource<T: DeserializeOwned>(
&self,
address: AccountAddress,
resource_type: &StructTag,
) -> Result<Response<T>> {
let resp = self.get_account_resource(address, resource_type).await?;
resp.and_then(|conf| {
if let Some(val) = conf {
serde_json::from_value(val)
.map_err(|e| anyhow!("deserialize {} failed: {}", resource_type, e))
} else {
Err(anyhow!(
"could not find resource {} in account {}",
resource_type,
address
))
}
})
}

pub async fn get_account_resource(
&self,
address: AccountAddress,
Expand Down
27 changes: 25 additions & 2 deletions crates/diem-rest-client/src/types.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use diem_api_types::U64;
use diem_api_types::{Address, U64};
use diem_types::transaction::authenticator::AuthenticationKey;
use move_core_types::{language_storage::StructTag, parser::parse_struct_tag};
use serde::{Deserialize, Deserializer};
use serde::{Deserialize, Deserializer, Serialize};
use std::str::FromStr;

#[derive(Clone, Debug, PartialEq, Deserialize)]
Expand Down Expand Up @@ -64,3 +64,26 @@ pub struct DiemAccount {
#[serde(deserialize_with = "deserialize_from_string")]
pub sequence_number: u64,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct EventHandle {
counter: U64,
guid: EventHandleGUID,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct EventHandleGUID {
len_bytes: u8,
guid: GUID,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct GUID {
id: ID,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ID {
creation_num: U64,
addr: Address,
}
16 changes: 8 additions & 8 deletions testsuite/smoke-test/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use diem_types::{
};
use forge::{LocalSwarm, Node, NodeExt, Swarm};
use std::{convert::TryInto, str::FromStr};
use tokio::runtime::Runtime;

#[test]
fn test_consensus_observer_mode_storage_error() {
Expand Down Expand Up @@ -53,20 +54,19 @@ fn test_consensus_observer_mode_storage_error() {
assert_eq!(VMStatusView::Executed, txn_ctx.execution_result.unwrap());
}

let runtime = Runtime::new().unwrap();
// Verify validator 1 is still able to stay up to date with validator 0 (despite safety rules failing)
let client_0 = swarm.validators().next().unwrap().json_rpc_client();
let sequence_number_0 = client_0
.get_account(txn_ctx.address)
let client_0 = swarm.validators().next().unwrap().rest_client();
let sequence_number_0 = runtime
.block_on(client_0.get_account(txn_ctx.address))
.unwrap()
.into_inner()
.unwrap()
.sequence_number;
let client_1 = swarm.validators().nth(1).unwrap().json_rpc_client();
let sequence_number_1 = client_1
.get_account(txn_ctx.address)
let client_1 = swarm.validators().nth(1).unwrap().rest_client();
let sequence_number_1 = runtime
.block_on(client_1.get_account(txn_ctx.address))
.unwrap()
.into_inner()
.unwrap()
.sequence_number;
assert_eq!(sequence_number_0, sequence_number_1);
}
Expand Down
52 changes: 29 additions & 23 deletions testsuite/smoke-test/src/fullnode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@

use std::time::{Duration, Instant};

use anyhow::bail;
use diem_config::config::NodeConfig;
use diem_sdk::{client::views::AmountView, transaction_builder::Currency, types::LocalAccount};
use diem_rest_client::Client as RestClient;
use diem_sdk::{transaction_builder::Currency, types::LocalAccount};
use diem_types::account_address::AccountAddress;
use forge::{NetworkContext, NetworkTest, NodeExt, Result, Test};
use tokio::runtime::Runtime;

#[derive(Debug)]
pub struct LaunchFullnode;
Expand All @@ -25,7 +29,7 @@ impl NetworkTest for LaunchFullnode {

let fullnode = ctx.swarm().full_node_mut(fullnode_peer_id).unwrap();
fullnode.wait_until_healthy(Instant::now() + Duration::from_secs(10))?;
let client = fullnode.json_rpc_client();
let client = fullnode.rest_client();

let factory = ctx.swarm().chain_info().transaction_factory();
let mut account1 = LocalAccount::generate(ctx.core().rng());
Expand All @@ -40,38 +44,40 @@ impl NetworkTest for LaunchFullnode {
.chain_info()
.create_parent_vasp_account(Currency::XUS, account2.authentication_key())?;

loop {
if client
.get_account(account1.address())?
.into_inner()
.is_some()
{
println!("hello");
break;
}
}
let runtime = Runtime::new().unwrap();
runtime.block_on(wait_for_account(&client, account1.address()))?;

let txn = account1.sign_with_transaction_builder(factory.peer_to_peer(
Currency::XUS,
account2.address(),
10,
));

client.submit(&txn)?;
client.wait_for_signed_transaction(&txn, None, None)?;
runtime.block_on(client.submit_and_wait(&txn))?;
let balances = runtime
.block_on(client.get_account_balances(account1.address()))?
.into_inner();

assert_eq!(
vec![AmountView {
amount: 90,
currency: "XUS".to_string()
}],
client
.get_account(account1.address())?
.into_inner()
.unwrap()
.balances
vec![(90, "XUS".to_string())],
balances
.into_iter()
.map(|b| (b.amount, b.currency_code()))
.collect::<Vec<(u64, String)>>()
);

Ok(())
}
}

async fn wait_for_account(client: &RestClient, address: AccountAddress) -> Result<()> {
const DEFAULT_WAIT_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(120);
let start = std::time::Instant::now();
while start.elapsed() < DEFAULT_WAIT_TIMEOUT {
if client.get_account(address).await.is_ok() {
return Ok(());
}
std::thread::sleep(std::time::Duration::from_millis(10));
}
bail!("wait for account(address={}) timeout", address,)
}
39 changes: 17 additions & 22 deletions testsuite/smoke-test/src/operational_tooling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ use diem_operational_tool::{
keys::{EncodingType, KeyType},
test_helper::OperationalTool,
};
use diem_sdk::client::{views::VMStatusView, BlockingClient};
use diem_rest_client::Client as RestClient;
use diem_sdk::client::views::VMStatusView;
use diem_secure_storage::{CryptoStorage, KVStorage, Storage};
use diem_temppath::TempPath;
use diem_types::{
Expand All @@ -48,6 +49,7 @@ use std::{
str::FromStr,
time::{Duration, Instant},
};
use tokio::runtime::Runtime;

#[test]
fn test_account_resource() {
Expand Down Expand Up @@ -88,7 +90,7 @@ fn test_auto_validate_options() {
assert!(txn_ctx.execution_result.is_none());

// Now wait for transaction execution
let client = swarm.validators().next().unwrap().json_rpc_client();
let client = swarm.validators().next().unwrap().rest_client();
wait_for_account_sequence_number(&client, txn_ctx.address, txn_ctx.sequence_number).unwrap();

// Verify that the transaction was executed correctly
Expand Down Expand Up @@ -248,7 +250,7 @@ fn test_set_operator_and_add_new_validator() {
.unwrap();

// Wait for transaction execution
let client = validator.json_rpc_client();
let client = validator.rest_client();
wait_for_account_sequence_number(&client, txn_ctx.address, txn_ctx.sequence_number).unwrap();

// Verify that the transaction was executed
Expand Down Expand Up @@ -591,7 +593,7 @@ fn test_fullnode_network_key_rotation() {
assert!(txn_ctx.execution_result.is_none());

// Wait for transaction execution
let client = env.validators().next().unwrap().json_rpc_client();
let client = env.validators().next().unwrap().rest_client();
wait_for_account_sequence_number(&client, txn_ctx.address, txn_ctx.sequence_number).unwrap();

// Verify that the config has been loaded correctly with new key
Expand Down Expand Up @@ -713,7 +715,7 @@ fn test_operator_key_rotation() {
assert!(txn_ctx.execution_result.is_none());

// Wait for transaction execution
let client = env.validators().next().unwrap().json_rpc_client();
let client = env.validators().next().unwrap().rest_client();
wait_for_account_sequence_number(&client, txn_ctx.address, txn_ctx.sequence_number).unwrap();

// Verify that the transaction was executed correctly
Expand Down Expand Up @@ -770,7 +772,7 @@ fn test_operator_key_rotation_recovery() {
assert_eq!(rotated_operator_key, new_operator_key);

// Wait for transaction execution
let client = env.validators().next().unwrap().json_rpc_client();
let client = env.validators().next().unwrap().rest_client();
wait_for_account_sequence_number(&client, txn_ctx.address, txn_ctx.sequence_number).unwrap();

// Verify that the transaction was executed correctly
Expand Down Expand Up @@ -857,7 +859,7 @@ fn test_validate_transaction() {

// Submit a transaction (rotate the operator key) and validate the transaction execution
let (txn_ctx, _) = op_tool.rotate_operator_key(&backend, true).unwrap();
let client = swarm.validators().next().unwrap().json_rpc_client();
let client = swarm.validators().next().unwrap().rest_client();
wait_for_account_sequence_number(&client, operator_account, txn_ctx.sequence_number).unwrap();

let result = op_tool
Expand Down Expand Up @@ -1084,7 +1086,7 @@ fn create_validator_with_file_writer(file_writer: fn(&Ed25519PublicKey, PathBuf)
let (validator_key, validator_account) = create_new_test_account();

let validator = swarm.validators().next().unwrap();
let client = validator.json_rpc_client();
let client = validator.rest_client();
// Verify the corresponding account doesn't exist on-chain
let diem_json_rpc = JsonRpcDiemInterface::new(validator.json_rpc_endpoint().to_string());
diem_json_rpc
Expand Down Expand Up @@ -1162,27 +1164,20 @@ fn write_key_to_file(
}

fn wait_for_account_sequence_number(
client: &BlockingClient,
client: &RestClient,
address: AccountAddress,
seq: u64,
) -> Result<()> {
const DEFAULT_WAIT_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(120);

let start = std::time::Instant::now();
let runtime = Runtime::new().unwrap();
while start.elapsed() < DEFAULT_WAIT_TIMEOUT {
let account_txn = client
.get_account_transaction(address, seq, false)?
let txns = runtime
.block_on(client.get_account_transactions(address, Some(seq), Some(1)))?
.into_inner();
if let Some(txn) = account_txn {
if let diem_sdk::client::views::TransactionDataView::UserTransaction {
sequence_number,
..
} = txn.transaction
{
if sequence_number >= seq {
return Ok(());
}
}
if txns.len() == 1 {
return Ok(());
}
std::thread::sleep(std::time::Duration::from_millis(10));
}
Expand All @@ -1199,7 +1194,7 @@ pub fn wait_for_transaction_on_all_nodes(
sequence_number: u64,
) {
for validator in swarm.validators() {
let client = validator.json_rpc_client();
let client = validator.rest_client();
wait_for_account_sequence_number(&client, account, sequence_number).unwrap();
}
}
Loading

0 comments on commit e85ec8f

Please sign in to comment.