Skip to content

Commit

Permalink
[graphql/rpc] testing infra: capture addrs variables (MystenLabs#14957)
Browse files Browse the repository at this point in the history
## Description 

Maps resolved named addresses and published packages to graphql
variables so they can be used in graphql queries.
Two variables are made for each mapping. One for the required
`SuiAddress!` type, and another for optional `SuiAddress` type (variable
name is suffixed with `_opt`).
To declare a variable for use in a query, one must add `--variables
{space separated list of var names}`
e.g
Note: publishing `Test` as done below changes its address from 0x0. This
new address is what shows up in graphql variable value.

```
//# init --addresses Test=0x0 A=0x42 --simulator

//# publish
module Test::M1 {}

// Do some stuff

//# run-graphql --variables Test A
{
  address(address: $Test) {
    objectConnection{
      edges {
        node {
          location
          digest
          kind
        }
      }
    }
  }
  second: address(address: $A) {
    objectConnection{
      edges {
        node {
          location
          digest
          kind
        }
      }
    }
  }
}

```

One can also list all the variable mappings with
`view-graphql-variables`:

```
Name: A
Type: SuiAddress!
Value: "0x42"

Name: A_opt
Type: SuiAddress
Value: "0x42"

Name: Test
Type: SuiAddress!
Value: "0xB214F63E7E7CEA32DC57EDBA9C924524F44A7BB50E72D0E102265219D4DE7D0E"

Name: Test_opt
Type: SuiAddress
Value: "0xB214F63E7E7CEA32DC57EDBA9C924524F44A7BB50E72D0E102265219D4DE7D0E"

```


## Test Plan 

Included

---
If your changes are not user-facing and not a breaking change, you can
skip the following section. Otherwise, please indicate what changed, and
then add to the Release Notes section as highlighted during the release
process.

### Type of Change (Check all that apply)

- [ ] protocol change
- [ ] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes
  • Loading branch information
oxade authored Nov 21, 2023
1 parent 01a8af7 commit 3afbf53
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 4 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.

98 changes: 95 additions & 3 deletions crates/sui-graphql-e2e-tests/tests/call/simple.exp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
processed 15 tasks
processed 18 tasks

task 1 'publish'. lines 6-28:
created: object(1,0)
Expand Down Expand Up @@ -26,7 +26,7 @@ task 6 'advance-epoch'. lines 39-39:
Epoch advanced: 5

task 7 'view-checkpoint'. lines 41-41:
CheckpointSummary { epoch: 5, seq: 10, content_digest: BVsPCtqsoq7tCkDUZeoFQkNsj23Bqjjt8khNPCnAFwRK,
CheckpointSummary { epoch: 5, seq: 10, content_digest: AYWnAH2mnV56mBixSbTBco6dqZRksmeHncHKJEEiAL7w,
epoch_rolling_gas_cost_summary: GasCostSummary { computation_cost: 0, storage_cost: 0, storage_rebate: 0, non_refundable_storage_fee: 0 }}

task 8 'run-graphql'. lines 43-49:
Expand Down Expand Up @@ -82,5 +82,97 @@ task 13 'view-checkpoint'. lines 70-70:
CheckpointSummary { epoch: 6, seq: 11, content_digest: D3oWLCcqoa1D15gxzvMaDemNNY8YYVspAkYkcmtQKWRt,
epoch_rolling_gas_cost_summary: GasCostSummary { computation_cost: 0, storage_cost: 0, storage_rebate: 0, non_refundable_storage_fee: 0 }}

task 14 'advance-epoch'. lines 72-72:
task 14 'advance-epoch'. lines 72-75:
Epoch advanced: 6

task 15 'run-graphql'. lines 77-90:
Response: {
"data": {
"address": {
"objectConnection": {
"edges": [
{
"node": {
"location": "0x5dee0c408687d51a12f9edd765733887eb5d784bf38a8511195cf2bc64e3d801",
"digest": "8MCxnZGPBDtTuHSdZJrfEc4nAAmhxAMbXhRdAYYNGi26",
"kind": "OWNED"
}
}
]
}
}
}
}

task 16 'run-graphql'. lines 92-116:
Response: {
"data": {
"address": {
"objectConnection": {
"edges": []
}
},
"second": {
"objectConnection": {
"edges": [
{
"node": {
"location": "0x5dee0c408687d51a12f9edd765733887eb5d784bf38a8511195cf2bc64e3d801",
"digest": "8MCxnZGPBDtTuHSdZJrfEc4nAAmhxAMbXhRdAYYNGi26",
"kind": "OWNED"
}
}
]
}
}
}
}

task 17 'view-graphql-variables'. lines 119-120:
Name: A
Type: SuiAddress!
Value: "0x42"

Name: A_opt
Type: SuiAddress
Value: "0x42"

Name: Test
Type: SuiAddress!
Value: "0xB214F63E7E7CEA32DC57EDBA9C924524F44A7BB50E72D0E102265219D4DE7D0E"

Name: Test_opt
Type: SuiAddress
Value: "0xB214F63E7E7CEA32DC57EDBA9C924524F44A7BB50E72D0E102265219D4DE7D0E"

Name: deepbook
Type: SuiAddress!
Value: "0xDEE9"

Name: deepbook_opt
Type: SuiAddress
Value: "0xDEE9"

Name: std
Type: SuiAddress!
Value: "0x1"

Name: std_opt
Type: SuiAddress
Value: "0x1"

Name: sui
Type: SuiAddress!
Value: "0x2"

Name: sui_opt
Type: SuiAddress
Value: "0x2"

Name: sui_system
Type: SuiAddress!
Value: "0x3"

Name: sui_system_opt
Type: SuiAddress
Value: "0x3"
48 changes: 48 additions & 0 deletions crates/sui-graphql-e2e-tests/tests/call/simple.move
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,51 @@ module Test::M1 {
//# view-checkpoint

//# advance-epoch

// Demonstrates using variables
// If the variable ends in _opt, this is the optional variant

//# run-graphql --variables A
{
address(address: $A) {
objectConnection{
edges {
node {
location
digest
kind
}
}
}
}
}

//# run-graphql --variables Test A
{
address(address: $Test) {
objectConnection{
edges {
node {
location
digest
kind
}
}
}
}
second: address(address: $A) {
objectConnection{
edges {
node {
location
digest
kind
}
}
}
}
}


//# view-graphql-variables
// List all the graphql variables
1 change: 1 addition & 0 deletions crates/sui-graphql-rpc/src/client/simple_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::collections::BTreeMap;

use super::response::GraphqlResponse;

#[derive(Clone, Debug)]
pub struct GraphqlQueryVariable {
pub name: String,
pub ty: String,
Expand Down
1 change: 1 addition & 0 deletions crates/sui-transactional-test-runner/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ rand.workspace = true
tempfile.workspace = true
async-trait.workspace = true
tokio.workspace = true
serde_json.workspace = true

fastcrypto.workspace = true
move-binary-format.workspace = true
Expand Down
4 changes: 4 additions & 0 deletions crates/sui-transactional-test-runner/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ pub struct RunGraphqlCommand {
pub show_headers: bool,
#[clap(long = "show-service-version")]
pub show_service_version: bool,
#[clap(long = "variables", num_args(1..))]
pub variables: Vec<String>,
}

#[derive(Debug, clap::Parser)]
Expand Down Expand Up @@ -182,6 +184,8 @@ pub enum SuiSubcommand {
ViewCheckpoint,
#[clap(name = "run-graphql")]
RunGraphql(RunGraphqlCommand),
#[clap(name = "view-graphql-variables")]
ViewGraphqlVariables,
}

#[derive(Clone, Debug)]
Expand Down
71 changes: 70 additions & 1 deletion crates/sui-transactional-test-runner/src/test_adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use std::{
use sui_core::authority::test_authority_builder::TestAuthorityBuilder;
use sui_core::authority::AuthorityState;
use sui_framework::DEFAULT_FRAMEWORK_PATH;
use sui_graphql_rpc::client::simple_client::GraphqlQueryVariable;
use sui_graphql_rpc::config::ConnectionConfig;
use sui_graphql_rpc::test_infra::cluster::serve_executor;
use sui_graphql_rpc::test_infra::cluster::ExecutorCluster;
Expand Down Expand Up @@ -133,6 +134,7 @@ pub(crate) struct StagedPackage {
pub(crate) digest: Vec<u8>,
}

#[derive(Debug)]
struct TestAccount {
address: SuiAddress,
key_pair: AccountKeyPair,
Expand Down Expand Up @@ -474,10 +476,24 @@ impl<'a> MoveTestAdapter<'a> for SuiTestAdapter<'a> {
}};
}
match command {
SuiSubcommand::ViewGraphqlVariables => {
let variables = self.graphql_variables();
let mut res = vec![];
for (name, value) in variables {
res.push(format!(
"Name: {}\nType: {}\nValue: {}",
name,
value.ty,
serde_json::to_string_pretty(&value.value).unwrap()
));
}
Ok(Some(res.join("\n\n")))
}
SuiSubcommand::RunGraphql(RunGraphqlCommand {
show_usage,
show_headers,
show_service_version,
variables,
}) => {
let file = data.ok_or_else(|| anyhow::anyhow!("Missing GraphQL query"))?;
let contents = std::fs::read_to_string(file.path())?;
Expand All @@ -487,9 +503,15 @@ impl<'a> MoveTestAdapter<'a> for SuiTestAdapter<'a> {
.wait_for_checkpoint_catchup(highest_checkpoint, Duration::from_secs(10))
.await;

let used_variables = self.resolve_graphql_variables(&variables)?;
let resp = cluster
.graphql_client
.execute_to_graphql(contents.trim().to_owned(), show_usage, vec![], vec![])
.execute_to_graphql(
contents.trim().to_owned(),
show_usage,
used_variables,
vec![],
)
.await?;

let mut output = vec![];
Expand Down Expand Up @@ -933,6 +955,53 @@ impl<'a> SuiTestAdapter<'a> {
self.executor
}

fn graphql_variables(&self) -> BTreeMap<String, GraphqlQueryVariable> {
let mut variables = BTreeMap::new();
for (name, addr) in &self.compiled_state.named_address_mapping {
let addr = addr.to_string();

// Required variant
variables.insert(
name.to_owned(),
GraphqlQueryVariable {
name: name.to_string(),
value: serde_json::json!(addr),
ty: "SuiAddress!".to_string(),
},
);
// Optional variant
let name = name.to_string() + "_opt";
variables.insert(
name.clone(),
GraphqlQueryVariable {
name: name.to_string(),
value: serde_json::json!(addr),
ty: "SuiAddress".to_string(),
},
);
}
variables
}
fn resolve_graphql_variables(
&self,
declared: &[String],
) -> anyhow::Result<Vec<GraphqlQueryVariable>> {
let variables = self.graphql_variables();
let mut res = vec![];
for decl in declared {
if let Some(var) = variables.get(decl) {
res.push(var.clone());
} else {
return Err(anyhow!(
"Unknown variable: {}\nAllowed variable mappings are are {:#?}",
decl,
variables
));
}
}
Ok(res)
}

async fn upgrade_package(
&mut self,
before_upgrade: NumericalAddress,
Expand Down

0 comments on commit 3afbf53

Please sign in to comment.