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

[api] Add threads and timestamps to api tests #9349

Merged
merged 8 commits into from
Jul 31, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
120 changes: 46 additions & 74 deletions crates/aptos-api-tester/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,25 @@
mod counters;
mod tests;
mod utils;
mod wrappers;

use crate::{
tests::{test_cointransfer, test_mintnft, test_module, test_newaccount},
utils::{
set_metrics, NetworkName, TestFailure, TestName, TestResult, DEVNET_FAUCET_URL,
DEVNET_NODE_URL, TESTNET_FAUCET_URL, TESTNET_NODE_URL,
utils::{set_metrics, NetworkName, TestFailure, TestName, TestResult},
wrappers::{
wrapper_cointransfer, wrapper_newaccount, wrapper_nfttransfer, wrapper_publishmodule,
},
};
use anyhow::{anyhow, Result};
use anyhow::Result;
use aptos_logger::{info, Level, Logger};
use aptos_push_metrics::MetricsPusher;
use aptos_rest_client::{Client, FaucetClient};
use aptos_sdk::{coin_client::CoinClient, token_client::TokenClient, types::LocalAccount};
use std::{future::Future, time::Instant};

// Processes a test result.
async fn handle_result<Fut: Future<Output = Result<(), TestFailure>>>(
async fn process_result<Fut: Future<Output = Result<(), TestFailure>>>(
test_name: TestName,
network_type: NetworkName,
network_name: NetworkName,
fut: Fut,
) -> Result<TestResult> {
) {
// start timer
let start = Instant::now();

Expand All @@ -46,77 +44,63 @@ async fn handle_result<Fut: Future<Output = Result<(), TestFailure>>>(
set_metrics(
&output,
&test_name.to_string(),
&network_type.to_string(),
&network_name.to_string(),
time,
);
info!(
"{} {} result:{:?} in time:{:?}",
network_type.to_string(),
network_name.to_string(),
test_name.to_string(),
output,
time,
);

Ok(output)
}

async fn test_flows(
network_type: NetworkName,
client: Client,
faucet_client: FaucetClient,
) -> Result<()> {
info!("testing {}", network_type.to_string());

// create clients
let coin_client = CoinClient::new(&client);
let token_client = TokenClient::new(&client);

// create and fund account for tests
let mut giray = LocalAccount::generate(&mut rand::rngs::OsRng);
faucet_client.fund(giray.address(), 100_000_000).await?;
info!("{:?}", giray.address());

let mut giray2 = LocalAccount::generate(&mut rand::rngs::OsRng);
faucet_client.fund(giray2.address(), 100_000_000).await?;
info!("{:?}", giray2.address());
async fn test_flows(network_name: NetworkName) -> Result<()> {
info!("testing {}", network_name.to_string());

// Test new account creation and funding
// this test is critical to pass for the next tests
match handle_result(
TestName::NewAccount,
network_type,
test_newaccount(&client, &giray, 100_000_000),
)
.await?
{
TestResult::Success => {},
_ => return Err(anyhow!("returning early because new account test failed")),
}
let handle_newaccount = tokio::spawn(async move {
process_result(
TestName::NewAccount,
network_name,
wrapper_newaccount(network_name),
)
.await;
});

// Flow 1: Coin transfer
let _ = handle_result(
TestName::CoinTransfer,
network_type,
test_cointransfer(&client, &coin_client, &mut giray, giray2.address(), 1_000),
)
.await;
let handle_cointransfer = tokio::spawn(async move {
process_result(
TestName::CoinTransfer,
network_name,
wrapper_cointransfer(network_name),
)
.await;
});

// Flow 2: NFT transfer
let _ = handle_result(
TestName::NftTransfer,
network_type,
test_mintnft(&client, &token_client, &mut giray, &mut giray2),
)
.await;
let handle_nfttransfer = tokio::spawn(async move {
process_result(
TestName::NftTransfer,
network_name,
wrapper_nfttransfer(network_name),
)
.await;
});

// Flow 3: Publishing module
let _ = handle_result(
process_result(
TestName::PublishModule,
network_type,
test_module(&client, &mut giray),
network_name,
wrapper_publishmodule(network_name),
)
.await;

handle_newaccount.await?;
handle_cointransfer.await?;
handle_nfttransfer.await?;
ngkuru marked this conversation as resolved.
Show resolved Hide resolved

Ok(())
}

Expand All @@ -126,21 +110,9 @@ async fn main() -> Result<()> {
Logger::builder().level(Level::Info).build();
let _mp = MetricsPusher::start_for_local_run("api-tester");

// test flows on testnet
let _ = test_flows(
NetworkName::Testnet,
Client::new(TESTNET_NODE_URL.clone()),
FaucetClient::new(TESTNET_FAUCET_URL.clone(), TESTNET_NODE_URL.clone()),
)
.await;

// test flows on devnet
let _ = test_flows(
NetworkName::Devnet,
Client::new(DEVNET_NODE_URL.clone()),
FaucetClient::new(DEVNET_FAUCET_URL.clone(), DEVNET_NODE_URL.clone()),
)
.await;
// test flows
let _ = test_flows(NetworkName::Testnet).await;
let _ = test_flows(NetworkName::Devnet).await;
ngkuru marked this conversation as resolved.
Show resolved Hide resolved

Ok(())
}
7 changes: 5 additions & 2 deletions crates/aptos-api-tester/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ pub async fn test_cointransfer(
/// - collection data exists
/// - token data exists
/// - token balance reflects transferred amount
pub async fn test_mintnft(
pub async fn test_nfttransfer(
client: &Client,
token_client: &TokenClient<'_>,
account: &mut LocalAccount,
Expand Down Expand Up @@ -440,7 +440,10 @@ async fn get_message(client: &Client, address: AccountAddress) -> Option<String>
/// - module data exists
/// - can interact with module
/// - resources reflect interaction
pub async fn test_module(client: &Client, account: &mut LocalAccount) -> Result<(), TestFailure> {
pub async fn test_publishmodule(
client: &Client,
account: &mut LocalAccount,
) -> Result<(), TestFailure> {
// publish module
let blob = publish_module(client, account).await?;

Expand Down
45 changes: 43 additions & 2 deletions crates/aptos-api-tester/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
// Copyright © Aptos Foundation

use crate::counters::{test_error, test_fail, test_latency, test_success};
use aptos_rest_client::error::RestError;
use anyhow::Result;
use aptos_logger::info;
use aptos_rest_client::{error::RestError, Client, FaucetClient};
use aptos_sdk::types::LocalAccount;
use once_cell::sync::Lazy;
use url::Url;

Expand Down Expand Up @@ -82,7 +85,7 @@ impl ToString for NetworkName {
}
}

// Helper function to set metrics based on the result.
// Set metrics based on the result.
pub fn set_metrics(output: &TestResult, test_name: &str, network_name: &str, time: f64) {
match output {
TestResult::Success => {
Expand All @@ -105,3 +108,41 @@ pub fn set_metrics(output: &TestResult, test_name: &str, network_name: &str, tim
},
}
}

// Create a REST client.
pub fn get_client(network_name: NetworkName) -> Client {
match network_name {
NetworkName::Testnet => Client::new(TESTNET_NODE_URL.clone()),
NetworkName::Devnet => Client::new(DEVNET_NODE_URL.clone()),
}
}

// Create a faucet client.
pub fn get_faucet_client(network_name: NetworkName) -> FaucetClient {
match network_name {
NetworkName::Testnet => {
FaucetClient::new(TESTNET_FAUCET_URL.clone(), TESTNET_NODE_URL.clone())
},
NetworkName::Devnet => {
FaucetClient::new(DEVNET_FAUCET_URL.clone(), DEVNET_NODE_URL.clone())
},
}
}

// Create an account with zero balance.
pub async fn create_account(faucet_client: &FaucetClient) -> Result<LocalAccount> {
let account = LocalAccount::generate(&mut rand::rngs::OsRng);
faucet_client.create_account(account.address()).await?;
info!("{:?}", account.address());

Ok(account)
}

// Create an account with 100_000_000 balance.
pub async fn create_and_fund_account(faucet_client: &FaucetClient) -> Result<LocalAccount> {
let account = LocalAccount::generate(&mut rand::rngs::OsRng);
faucet_client.fund(account.address(), 100_000_000).await?;
info!("{:?}", account.address());

Ok(account)
}
70 changes: 70 additions & 0 deletions crates/aptos-api-tester/src/wrappers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright © Aptos Foundation

use crate::{
tests::{test_cointransfer, test_newaccount, test_nfttransfer, test_publishmodule},
utils::{
create_account, create_and_fund_account, get_client, get_faucet_client, NetworkName,
TestFailure,
},
};
use anyhow::Result;
use aptos_sdk::{coin_client::CoinClient, token_client::TokenClient};

pub async fn wrapper_newaccount(network_name: NetworkName) -> Result<(), TestFailure> {
// spin up clients
let client = get_client(network_name);
let faucet_client = get_faucet_client(network_name);

// create and fund account
let account = create_and_fund_account(&faucet_client).await?;

// run test
test_newaccount(&client, &account, 100_000_000).await
}

pub async fn wrapper_cointransfer(network_name: NetworkName) -> Result<(), TestFailure> {
ngkuru marked this conversation as resolved.
Show resolved Hide resolved
// spin up clients
let client = get_client(network_name);
let faucet_client = get_faucet_client(network_name);
let coin_client = CoinClient::new(&client);

// create and fund accounts
let mut account = create_and_fund_account(&faucet_client).await?;
let receiver = create_account(&faucet_client).await?;

// run test
test_cointransfer(
&client,
&coin_client,
&mut account,
receiver.address(),
1_000,
)
.await
}

pub async fn wrapper_nfttransfer(network_name: NetworkName) -> Result<(), TestFailure> {
// spin up clients
let client = get_client(network_name);
let faucet_client = get_faucet_client(network_name);
let token_client = TokenClient::new(&client);

// create and fund accounts
let mut account = create_and_fund_account(&faucet_client).await?;
let mut receiver = create_and_fund_account(&faucet_client).await?;

// run test
test_nfttransfer(&client, &token_client, &mut account, &mut receiver).await
}

pub async fn wrapper_publishmodule(network_name: NetworkName) -> Result<(), TestFailure> {
// spin up clients
let client = get_client(network_name);
let faucet_client = get_faucet_client(network_name);

// create and fund accounts
let mut account = create_and_fund_account(&faucet_client).await?;

// run test
test_publishmodule(&client, &mut account).await
}