Skip to content

Commit

Permalink
more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
emmazzz committed Oct 18, 2024
1 parent 5bb764e commit 6637a8c
Show file tree
Hide file tree
Showing 8 changed files with 242 additions and 127 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions crates/sui-cluster-test/src/cluster.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ impl Cluster for LocalNewCluster {
// This cluster has fullnode handle, safe to unwrap
let fullnode_url = test_cluster.fullnode_handle.rpc_url.clone();

// TODO: with TestCluster supporting indexer backed rpc as well, we can remove the indexer related logic here.
let mut cancellation_tokens = vec![];
let (database, indexer_url, graphql_url) = if options.with_indexer_and_graphql {
let database = TempDb::new()?;
Expand Down
1 change: 1 addition & 0 deletions crates/sui-indexer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ dashmap.workspace = true
[dev-dependencies]
sui-keys.workspace = true
sui-move-build.workspace = true
sui-swarm-config.workspace = true
sui-test-transaction-builder.workspace = true
test-cluster.workspace = true
ntest.workspace = true
Expand Down
64 changes: 0 additions & 64 deletions crates/sui-indexer/tests/cluster_tests.rs

This file was deleted.

142 changes: 142 additions & 0 deletions crates/sui-indexer/tests/json_rpc_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use sui_json_rpc_api::{CoinReadApiClient, IndexerApiClient, ReadApiClient};
use sui_json_rpc_types::{
CoinPage, SuiObjectDataOptions, SuiObjectResponse, SuiObjectResponseQuery,
};
use sui_swarm_config::genesis_config::DEFAULT_GAS_AMOUNT;
use test_cluster::TestClusterBuilder;

#[tokio::test]
async fn test_get_owned_objects() -> Result<(), anyhow::Error> {
let cluster = TestClusterBuilder::new()
.with_indexer_backed_rpc()
.build()
.await;

let http_client = cluster.rpc_client();
let address = cluster.get_address_0();

let objects = http_client
.get_owned_objects(
address,
Some(SuiObjectResponseQuery::new_with_options(
SuiObjectDataOptions::new(),
)),
None,
None,
)
.await?;
assert_eq!(5, objects.data.len());

// Multiget objectIDs test
let object_digests = objects
.data
.iter()
.map(|o| o.object().unwrap().object_id)
.collect();

let object_resp = http_client.multi_get_objects(object_digests, None).await?;
assert_eq!(5, object_resp.len());
Ok(())
}

#[tokio::test]
async fn test_get_object_info() -> Result<(), anyhow::Error> {
let cluster = TestClusterBuilder::new()
.with_indexer_backed_rpc()
.build()
.await;
let http_client = cluster.rpc_client();
let address = cluster.get_address_0();
let objects = http_client
.get_owned_objects(
address,
Some(SuiObjectResponseQuery::new_with_options(
SuiObjectDataOptions::new()
.with_type()
.with_owner()
.with_previous_transaction(),
)),
None,
None,
)
.await?
.data;

for obj in objects {
let oref = obj.into_object().unwrap();
let result = http_client
.get_object(
oref.object_id,
Some(SuiObjectDataOptions::new().with_owner()),
)
.await?;
assert!(
matches!(result, SuiObjectResponse { data: Some(object), .. } if oref.object_id == object.object_id && object.owner.unwrap().get_owner_address()? == address)
);
}
Ok(())
}

#[tokio::test]
async fn test_get_coins() -> Result<(), anyhow::Error> {
let cluster = TestClusterBuilder::new()
.with_indexer_backed_rpc()
.build()
.await;
let http_client = cluster.rpc_client();
let address = cluster.get_address_0();

let result: CoinPage = http_client.get_coins(address, None, None, None).await?;
assert_eq!(5, result.data.len());
assert!(!result.has_next_page);

// We should get 0 coins for a non-existent coin type.
let result: CoinPage = http_client
.get_coins(address, Some("0x2::sui::TestCoin".into()), None, None)
.await?;
assert_eq!(0, result.data.len());

// We should get all the 5 coins for SUI with the right balance.
let result: CoinPage = http_client
.get_coins(address, Some("0x2::sui::SUI".into()), None, None)
.await?;
assert_eq!(5, result.data.len());
assert_eq!(result.data[0].balance, DEFAULT_GAS_AMOUNT);
assert!(!result.has_next_page);

// When we have more than 3 coins, we should get a next page.
let result: CoinPage = http_client
.get_coins(address, Some("0x2::sui::SUI".into()), None, Some(3))
.await?;
assert_eq!(3, result.data.len());
assert!(result.has_next_page);

// We should get the remaining 2 coins with the next page.
let result: CoinPage = http_client
.get_coins(
address,
Some("0x2::sui::SUI".into()),
result.next_cursor,
Some(3),
)
.await?;
assert_eq!(2, result.data.len(), "{:?}", result);
assert!(!result.has_next_page);

// No more coins after the last page.
let result: CoinPage = http_client
.get_coins(
address,
Some("0x2::sui::SUI".into()),
result.next_cursor,
None,
)
.await?;
assert_eq!(0, result.data.len(), "{:?}", result);
assert!(!result.has_next_page);

Ok(())
}
76 changes: 76 additions & 0 deletions crates/test-cluster/src/indexer_util.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// Copyright (c) Mysten Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

use jsonrpsee::http_client::{HttpClient, HttpClientBuilder};
use std::path::PathBuf;
use std::time::Duration;
use sui_config::local_ip_utils::get_available_port;
use sui_indexer::tempdb::TempDb;
use sui_indexer::test_utils::{
start_indexer_jsonrpc_for_testing, start_indexer_writer_for_testing,
};
use sui_sdk::{SuiClient, SuiClientBuilder};
use tempfile::TempDir;
use tokio::time::sleep;

pub(crate) struct IndexerHandle {
#[allow(unused)]
cancellation_tokens: Vec<tokio_util::sync::DropGuard>,
#[allow(unused)]
data_ingestion_dir: Option<TempDir>,
#[allow(unused)]
database: TempDb,
}

// TODO: this only starts indexer writer, reader and jsonrpc server today.
// Consider adding graphql server here as well.
pub(crate) async fn setup_indexer_backed_rpc(
fullnode_rpc_url: String,
temp_data_ingestion_dir: Option<TempDir>,
data_ingestion_path: PathBuf,
) -> (HttpClient, SuiClient, String, Option<IndexerHandle>) {
let mut cancellation_tokens = vec![];
let database = TempDb::new().unwrap();
let pg_address = database.database().url().as_str().to_owned();
let indexer_jsonrpc_address = format!("127.0.0.1:{}", get_available_port("127.0.0.1"));

// Start indexer writer
let (_, _, writer_token) = start_indexer_writer_for_testing(
pg_address.clone(),
None,
None,
Some(data_ingestion_path.clone()),
None,
)
.await;
cancellation_tokens.push(writer_token.drop_guard());

// Start indexer jsonrpc service
let (_, reader_token) = start_indexer_jsonrpc_for_testing(
pg_address.clone(),
fullnode_rpc_url,
indexer_jsonrpc_address.clone(),
None,
)
.await;
cancellation_tokens.push(reader_token.drop_guard());

// Give the indexer a few seconds to get started.
sleep(Duration::from_secs(2)).await;

let rpc_address = format!("http://{}", indexer_jsonrpc_address);

let rpc_client = HttpClientBuilder::default().build(&rpc_address).unwrap();

let sui_client = SuiClientBuilder::default()
.build(&rpc_address)
.await
.unwrap();

let indexer_handle = Some(IndexerHandle {
database,
data_ingestion_dir: temp_data_ingestion_dir,
cancellation_tokens,
});
(rpc_client, sui_client, rpc_address, indexer_handle)
}
11 changes: 0 additions & 11 deletions crates/test-cluster/src/indexer_utils.rs

This file was deleted.

Loading

0 comments on commit 6637a8c

Please sign in to comment.