Skip to content

Commit

Permalink
[transaction test] refactoring publishing flow to test_context (#6529)
Browse files Browse the repository at this point in the history
* move helper functions to text_context.rs and fix some typo

* remove a line

* [transaction test] adding new move module for transaction tests and rewrite the test test_get_txn_execute_failed_by_entry_function_execution_failure

* [transaction test] move create_account() to test_context to share with other tests

* [transaction tests] fix lint

* address comments and further refactoring

* rebase and make changes to publish_packages

* refactor root_account and make it async base on #5894

* fix lint errors

* fix merge conflicts
  • Loading branch information
angieyth authored Feb 23, 2023
1 parent 57c10f2 commit 1755e84
Show file tree
Hide file tree
Showing 12 changed files with 256 additions and 284 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

16 changes: 8 additions & 8 deletions api/src/tests/accounts_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@ async fn test_account_modules_structs() {
async fn test_get_account_resources_by_ledger_version() {
let mut context = new_test_context(current_function_name!());
let account = context.gen_account();
let txn = context.create_user_account(&account);
let txn = context.create_user_account(&account).await;
context.commit_block(&vec![txn.clone()]).await;

let ledger_version_1_resources = context
.get(&account_resources(
&context.root_account().address().to_hex_literal(),
&context.root_account().await.address().to_hex_literal(),
))
.await;
let root_account = find_value(&ledger_version_1_resources, |f| {
Expand All @@ -127,7 +127,7 @@ async fn test_get_account_resources_by_ledger_version() {

let ledger_version_0_resources = context
.get(&account_resources_with_ledger_version(
&context.root_account().address().to_hex_literal(),
&context.root_account().await.address().to_hex_literal(),
0,
))
.await;
Expand All @@ -143,7 +143,7 @@ async fn test_get_account_resources_by_too_large_ledger_version() {
let resp = context
.expect_status_code(404)
.get(&account_resources_with_ledger_version(
&context.root_account().address().to_hex_literal(),
&context.root_account().await.address().to_hex_literal(),
1000000000000000000,
))
.await;
Expand All @@ -156,7 +156,7 @@ async fn test_get_account_resources_by_invalid_ledger_version() {
let resp = context
.expect_status_code(400)
.get(&account_resources_with_ledger_version(
&context.root_account().address().to_hex_literal(),
&context.root_account().await.address().to_hex_literal(),
-1,
))
.await;
Expand All @@ -169,7 +169,7 @@ async fn test_get_account_resources_by_invalid_ledger_version() {
async fn test_get_account_modules_by_ledger_version() {
let mut context = new_test_context(current_function_name!());
let code = "a11ceb0b0300000006010002030205050703070a0c0816100c260900000001000100000102084d794d6f64756c650269640000000000000000000000000b1e55ed00010000000231010200";
let mut root_account = context.root_account();
let mut root_account = context.root_account().await;
let txn = root_account.sign_with_transaction_builder(
context
.transaction_factory()
Expand All @@ -178,15 +178,15 @@ async fn test_get_account_modules_by_ledger_version() {
context.commit_block(&vec![txn.clone()]).await;
let modules = context
.get(&account_modules(
&context.root_account().address().to_hex_literal(),
&context.root_account().await.address().to_hex_literal(),
))
.await;

assert_ne!(modules, json!([]));

let modules = context
.get(&account_modules_with_ledger_version(
&context.root_account().address().to_hex_literal(),
&context.root_account().await.address().to_hex_literal(),
0,
))
.await;
Expand Down
14 changes: 5 additions & 9 deletions api/src/tests/modules.rs
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
// Copyright © Aptos Foundation
// SPDX-License-Identifier: Apache-2.0

use super::{
new_test_context,
resource_groups::{build_package, publish_package},
};
use aptos_api_test_context::current_function_name;
use super::new_test_context;
use aptos_api_test_context::{current_function_name, TestContext};
use std::path::PathBuf;

#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_abi() {
let mut context = new_test_context(current_function_name!());
let mut root_account = context.root_account();
let mut root_account = context.root_account().await;
let mut account = context.gen_account();
let txn = context.create_user_account_by(&mut root_account, &account);
context.commit_block(&vec![txn]).await;

// Publish packages
let named_addresses = vec![("abi".to_string(), account.address())];
// TODO: Switch to build_package and publish_package in test_context once they're moved there.
let txn = futures::executor::block_on(async move {
let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR")).join("src/tests/move/pack_abi");
build_package(path, named_addresses)
TestContext::build_package(path, named_addresses)
});
publish_package(&mut context, &mut account, txn).await;
context.publish_package(&mut account, txn).await;

// Get abi.
let modules = context
Expand Down
186 changes: 34 additions & 152 deletions api/src/tests/resource_groups.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,28 @@

use super::new_test_context;
use aptos_api_test_context::{current_function_name, TestContext};
use aptos_cached_packages::aptos_stdlib;
use aptos_framework::BuiltPackage;
use aptos_sdk::types::LocalAccount;
use aptos_types::{account_address::AccountAddress, transaction::TransactionPayload};
use serde_json::{json, Value};
use serde_json::json;
use std::path::PathBuf;

// This test verifies that both READ APIs can seamlessly translate from resource group to resource
// 1. Create accounts
// 2. Publish a resource group package
// 3. Verify default data exists
// 4. Read the resources from that resource group anad verify they don't exist
// 4. Read the resources from that resource group and verify they don't exist
// 5. Init data for that resource group / member
// 6. Read and ensure data is present
// 7. Publish another resource group member
// 8. Read the resources from the new resource group anad verify they don't exist
// 8. Read the resources from the new resource group and verify they don't exist
// 9. Init data for that resource group / member
// 10. Read and ensure data is present
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_read_resoure_group() {
async fn test_gen_resource_group() {
let mut context = new_test_context(current_function_name!());

// Prepare accounts
let mut root = context.root_account();
let mut admin0 = create_account(&mut context, &mut root).await;
let mut admin1 = create_account(&mut context, &mut root).await;
let mut user = create_account(&mut context, &mut root).await;
let mut admin0 = context.create_account().await;
let mut admin1 = context.create_account().await;
let mut user = context.create_account().await;

// Publish packages
let named_addresses = vec![
Expand All @@ -41,171 +36,58 @@ async fn test_read_resoure_group() {
let txn = futures::executor::block_on(async move {
let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR"))
.join("../aptos-move/move-examples/resource_groups/primary");
build_package(path, named_addresses_clone)
TestContext::build_package(path, named_addresses_clone)
});
publish_package(&mut context, &mut admin0, txn).await;
context.publish_package(&mut admin0, txn).await;

let named_addresses_clone = named_addresses.clone();
let txn = futures::executor::block_on(async move {
let path = PathBuf::from(std::env!("CARGO_MANIFEST_DIR"))
.join("../aptos-move/move-examples/resource_groups/secondary");
build_package(path, named_addresses_clone)
TestContext::build_package(path, named_addresses_clone)
});
publish_package(&mut context, &mut admin1, txn).await;
context.publish_package(&mut admin1, txn).await;

// Read default data
let primary = format!("0x{}::{}::{}", admin0.address(), "primary", "Primary");
let secondary = format!("0x{}::{}::{}", admin1.address(), "secondary", "Secondary");

let response = read_resource(&context, &admin0.address(), &primary).await;
assert_eq!(response["data"]["value"], "3");

let response = maybe_read_resource(&context, &admin0.address(), &primary).await;
let response = context.gen_resource(&admin0.address(), &primary).await;
assert_eq!(response.unwrap()["data"]["value"], "3");

// Verify account is empty
let response = maybe_read_resource(&context, &user.address(), &primary).await;
let response = context.gen_resource(&user.address(), &primary).await;
assert!(response.is_none());
let response = maybe_read_resource(&context, &user.address(), &secondary).await;
let response = context.gen_resource(&user.address(), &secondary).await;
assert!(response.is_none());

// Init secondary
execute_entry_function(
&mut context,
&mut user,
&format!("0x{}::secondary::init", admin1.address()),
json!([]),
json!([55]),
)
.await;
let response = read_resource(&context, &user.address(), &secondary).await;
assert_eq!(response["data"]["value"], 55);

let response = maybe_read_resource(&context, &user.address(), &secondary).await;
context
.api_execute_entry_function(
&mut user,
&format!("0x{}::secondary::init", admin1.address()),
json!([]),
json!([55]),
)
.await;
let response = context.gen_resource(&user.address(), &secondary).await;
assert_eq!(response.unwrap()["data"]["value"], 55);

let response = maybe_read_resource(&context, &user.address(), &primary).await;
let response = context.gen_resource(&user.address(), &primary).await;
assert!(response.is_none());

// Init primary
execute_entry_function(
&mut context,
&mut user,
&format!("0x{}::primary::init", admin0.address()),
json!([]),
json!(["35"]),
)
.await;
let response = read_resource(&context, &user.address(), &primary).await;
assert_eq!(response["data"]["value"], "35");

let response = maybe_read_resource(&context, &user.address(), &primary).await;
assert_eq!(response.unwrap()["data"]["value"], "35");

let response = read_resource(&context, &user.address(), &secondary).await;
assert_eq!(response["data"]["value"], 55);

let response = maybe_read_resource(&context, &user.address(), &secondary).await;
assert_eq!(response.unwrap()["data"]["value"], 55);
}

// TODO: The TestContext code is a bit of a mess, the following likely should be added and that
// code likely needs a good cleanup to merge to a common approach.

async fn create_account(context: &mut TestContext, root: &mut LocalAccount) -> LocalAccount {
let account = context.gen_account();
let factory = context.transaction_factory();
let txn = root.sign_with_transaction_builder(
factory
.account_transfer(account.address(), 10_000_000)
.expiration_timestamp_secs(u64::MAX),
);

let bcs_txn = bcs::to_bytes(&txn).unwrap();
context
.expect_status_code(202)
.post_bcs_txn("/transactions", bcs_txn)
.await;
context.commit_mempool_txns(1).await;
account
}

async fn maybe_read_resource(
context: &TestContext,
account_address: &AccountAddress,
resource: &str,
) -> Option<Value> {
let response = read_resources(context, account_address).await;
response
.as_array()
.unwrap()
.iter()
.find(|entry| entry["type"] == resource)
.cloned()
}

async fn read_resources(context: &TestContext, account_address: &AccountAddress) -> Value {
let request = format!("/accounts/{}/resources", account_address);
context.get(&request).await
}

async fn read_resource(
context: &TestContext,
account_address: &AccountAddress,
resource: &str,
) -> Value {
let request = format!("/accounts/{}/resource/{}", account_address, resource);
context.get(&request).await
}

pub fn build_package(
path: PathBuf,
named_addresses: Vec<(String, AccountAddress)>,
) -> TransactionPayload {
let mut build_options = aptos_framework::BuildOptions::default();
let _ = named_addresses
.into_iter()
.map(|(name, address)| build_options.named_addresses.insert(name, address))
.collect::<Vec<_>>();

let package = BuiltPackage::build(path, build_options).unwrap();
let code = package.extract_code();
let metadata = package.extract_metadata().unwrap();

aptos_stdlib::code_publish_package_txn(bcs::to_bytes(&metadata).unwrap(), code)
}

pub async fn publish_package(
context: &mut TestContext,
publisher: &mut LocalAccount,
payload: TransactionPayload,
) {
let txn =
publisher.sign_with_transaction_builder(context.transaction_factory().payload(payload));
let bcs_txn = bcs::to_bytes(&txn).unwrap();
context
.expect_status_code(202)
.post_bcs_txn("/transactions", bcs_txn)
.await;
context.commit_mempool_txns(1).await;
}

async fn execute_entry_function(
context: &mut TestContext,
account: &mut LocalAccount,
function: &str,
type_args: serde_json::Value,
args: serde_json::Value,
) {
context
.api_execute_txn(
account,
json!({
"type": "entry_function_payload",
"function": function,
"type_arguments": type_args,
"arguments": args
}),
.api_execute_entry_function(
&mut user,
&format!("0x{}::primary::init", admin0.address()),
json!([]),
json!(["35"]),
)
.await;
let response = context.gen_resource(&user.address(), &primary).await;
assert_eq!(response.unwrap()["data"]["value"], "35");

let response = context.gen_resource(&user.address(), &secondary).await;
assert_eq!(response.unwrap()["data"]["value"], 55);
}
Loading

0 comments on commit 1755e84

Please sign in to comment.