Skip to content

Commit

Permalink
adding runner_test for auto-graft-sync
Browse files Browse the repository at this point in the history
  • Loading branch information
dwerner committed Sep 6, 2024
1 parent 6302611 commit 3acbeb3
Show file tree
Hide file tree
Showing 9 changed files with 348 additions and 6 deletions.
33 changes: 33 additions & 0 deletions tests/runner-tests/auto-graft-sync/abis/Contract.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
[
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint16",
"name": "x",
"type": "uint16"
}
],
"name": "Trigger",
"type": "event"
},
{
"inputs": [
{
"internalType": "uint16",
"name": "x",
"type": "uint16"
}
],
"name": "emitTrigger",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
22 changes: 22 additions & 0 deletions tests/runner-tests/auto-graft-sync/config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[general]

# This is the config flag for enabling auto-graft-sync, which is the target of this test.
auto_graft_sync = true

[store]
[store.primary]
connection = "$THEGRAPH_STORE_POSTGRES_DIESEL_URL"
pool_size = 10

[deployment]
[[deployment.rule]]
store = "primary"
indexers = ["default"]

[chains]
ingestor = "default"

# The tests do not talk to ethereum clients
[chains.test]
shard = "primary"
provider = [{ label = "penguin", url = "http://localhost:1/", features = [] }]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

const fs = require('fs');
const { execSync } = require('child_process');

// This takes a subgraphName, outPath, and Qm.. hash as a CLI input, which is the graft base.
const outPath = process.argv[2];
const graftBase = process.argv[3];

const yamlPath = './template.yaml';
let yamlContent = fs.readFileSync(yamlPath, 'utf-8');
yamlContent = yamlContent.replace(/base: .+/, `base: ${graftBase}`);
fs.writeFileSync(outPath, yamlContent);
console.log("fuzzba")

// Assuming you have your IPFS_URI exported as environment variables.
// Instead of deploy, run graph build to -only upload to ipfs-.
execSync('graph build ' + outPath + ' --ipfs $IPFS_URI', {
stdio: 'inherit'
});
63 changes: 63 additions & 0 deletions tests/runner-tests/auto-graft-sync/graft-base.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# for this test, this is the lowest level of the grafting hierarchy
specVersion: 0.0.4
features:
- grafting
schema:
file: ./schema.graphql
dataSources:
- kind: ethereum/contract
name: Contract
network: test
source:
address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601"
abi: Contract
mapping:
kind: ethereum/events
apiVersion: 0.0.6
language: wasm/assemblyscript
entities:
- Gravatar
abis:
- name: Contract
file: ./abis/Contract.abi
blockHandlers:
- handler: handleBlock
file: ./src/mapping.ts
# Tests that adding a data source is possible in a graft
- kind: ethereum/contract
name: Contract2
network: test
source:
address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601"
abi: Contract
mapping:
kind: ethereum/events
apiVersion: 0.0.6
language: wasm/assemblyscript
entities:
- Gravatar
abis:
- name: Contract
file: ./abis/Contract.abi
callHandlers:
- handler: handleBlock
function: emitTrigger(uint16)
file: ./src/mapping.ts
templates:
- kind: ethereum/contract
name: Template
network: test
source:
abi: Contract
mapping:
kind: ethereum/events
apiVersion: 0.0.6
language: wasm/assemblyscript
entities:
- Gravatar
abis:
- name: Contract
file: ./abis/Contract.abi
blockHandlers:
- handler: handleBlockTemplate
file: ./src/mapping.ts
13 changes: 13 additions & 0 deletions tests/runner-tests/auto-graft-sync/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"name": "auto-graft-sync",
"version": "0.1.0",
"scripts": {
"codegen": "graph codegen --skip-migrations",
"build-graft-root": "graph build graft-base.yaml --ipfs $IPFS_URI",
"build:test-auto-graft-sync": "node generateManifestFromTemplate.js"
},
"devDependencies": {
"@graphprotocol/graph-cli": "0.60.0",
"@graphprotocol/graph-ts": "0.31.0"
}
}
5 changes: 5 additions & 0 deletions tests/runner-tests/auto-graft-sync/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# The `id` is the block number and `count` the handler invocations at that block.
type DataSourceCount @entity {
id: ID!
count: Int!
}
39 changes: 39 additions & 0 deletions tests/runner-tests/auto-graft-sync/src/mapping.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {
ethereum,
DataSourceContext,
dataSource,
Address,
BigInt,
} from "@graphprotocol/graph-ts";
import { Template } from "../generated/templates";
import { DataSourceCount } from "../generated/schema";

export function handleBlock(block: ethereum.Block): void {
let context = new DataSourceContext();
context.setBigInt("number", block.number);
context.setBytes("hash", block.hash);

Template.createWithContext(
changetype<Address>(Address.fromHexString(
"0x2E645469f354BB4F5c8a05B3b30A929361cf77eC"
)),
context
);
}

export function handleBlockTemplate(block: ethereum.Block): void {
let count = DataSourceCount.load(block.number.toString());
if (count == null) {
count = new DataSourceCount(block.number.toString());
count.count = 0;
}

let ctx = dataSource.context();
let number = ctx.getBigInt("number");
assert(
count.count == number.toI32(),
"wrong count, found " + BigInt.fromI32(count.count).toString()
);
count.count += 1;
count.save();
}
66 changes: 66 additions & 0 deletions tests/runner-tests/auto-graft-sync/template.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
specVersion: 0.0.4
features:
- grafting
schema:
file: ./schema.graphql
graft:
# This value will be overwritten by the templates
base: QmcAL39QSKZvRssr2ToCJrav7XK9ggajxvBR7M1NNUCqdh
block: 3
dataSources:
- kind: ethereum/contract
name: Contract
network: test
source:
address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601"
abi: Contract
mapping:
kind: ethereum/events
apiVersion: 0.0.6
language: wasm/assemblyscript
entities:
- Gravatar
abis:
- name: Contract
file: ./abis/Contract.abi
blockHandlers:
- handler: handleBlock
file: ./src/mapping.ts
# Tests that adding a data source is possible in a graft
- kind: ethereum/contract
name: Contract2
network: test
source:
address: "0xCfEB869F69431e42cdB54A4F4f105C19C080A601"
abi: Contract
mapping:
kind: ethereum/events
apiVersion: 0.0.6
language: wasm/assemblyscript
entities:
- Gravatar
abis:
- name: Contract
file: ./abis/Contract.abi
callHandlers:
- handler: handleBlock
function: emitTrigger(uint16)
file: ./src/mapping.ts
templates:
- kind: ethereum/contract
name: Template
network: test
source:
abi: Contract
mapping:
kind: ethereum/events
apiVersion: 0.0.6
language: wasm/assemblyscript
entities:
- Gravatar
abis:
- name: Contract
file: ./abis/Contract.abi
blockHandlers:
- handler: handleBlockTemplate
file: ./src/mapping.ts
94 changes: 88 additions & 6 deletions tests/tests/runner_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,10 +143,10 @@ async fn data_source_revert() -> anyhow::Result<()> {

// Test grafted version
let subgraph_name = SubgraphName::new("data-source-revert-grafted").unwrap();
let hash = build_subgraph_with_yarn_cmd_and_arg(
let hash = build_subgraph_with_yarn_cmd_and_args(
"./runner-tests/data-source-revert",
"deploy:test-grafted",
Some(&test_info.hash),
vec![&test_info.hash],
)
.await;
let test_info = TestInfo {
Expand Down Expand Up @@ -1261,20 +1261,102 @@ async fn arweave_file_data_sources() {
);
}

#[tokio::test]
async fn auto_graft_sync() -> anyhow::Result<()> {
let stores = fixture::stores(
"auto_graft_sync",
"./runner-tests/auto-graft-sync/config.toml",
)
.await;

let test_name = "auto_graft_sync";

let blocks = {
let block0 = genesis();
let block1 = empty_block(block0.ptr(), test_ptr(1));
let block1_reorged_ptr = BlockPtr {
number: 1,
hash: H256::from_low_u64_be(12).into(),
};
let block1_reorged = empty_block(block0.ptr(), block1_reorged_ptr.clone());
let block2 = empty_block(block1_reorged_ptr, test_ptr(2));
let block3 = empty_block(block2.ptr(), test_ptr(3));
let block4 = empty_block(block3.ptr(), test_ptr(4));
vec![block0, block1, block1_reorged, block2, block3, block4]
};

let chain = chain(&test_name, blocks.clone(), &stores, None).await;

// Root graft
// only build the subgraph and create it, but don't deploy it to be assigned
let root_deployment_hash = build_subgraph_with_yarn_cmd_and_args(
"./runner-tests/auto-graft-sync",
"build-graft-root",
vec![],
)
.await;

let mut prev_hash = root_deployment_hash.clone();
for i in (0..10).rev() {
let outfile = format!("auto-graft-sync-{}.yaml", i);
// Test grafted version
let hash = build_subgraph_with_yarn_cmd_and_args(
"./runner-tests/auto-graft-sync",
"build:test-auto-graft-sync",
vec![&outfile, &prev_hash],
)
.await;
prev_hash = hash;
}

let subgraph_name = SubgraphName::new("auto-graft-sync-tip".to_string()).unwrap();
let test_info = TestInfo {
test_name: test_name.to_string(),
hash: prev_hash.clone(),
test_dir: "./runner-tests/auto-graft-sync".to_string(),
subgraph_name,
};

let base_ctx = fixture::setup(&test_info, &stores, &chain, None, None).await;

let stop_block = test_ptr(3);
base_ctx.start_and_sync_to(stop_block).await;

let graft_block = Some(test_ptr(3));
let grafted_ctx = fixture::setup(&test_info, &stores, &chain, graft_block, None).await;
let stop_block = test_ptr(4);
grafted_ctx.start_and_sync_to(stop_block).await;

let query_res = grafted_ctx
.query(r#"{ dataSourceCount(id: "4") { id, count } }"#)
.await
.unwrap();

// TODO: The semantically correct value for `count` would be 5. But because the test fixture
// uses a `NoopTriggersAdapter` the data sources are not reprocessed in the block in which they
// are created.
assert_eq!(
query_res,
Some(object! { dataSourceCount: object!{ id: "4", count: 4 } })
);

Ok(())
}

/// deploy_cmd is the command to run to deploy the subgraph. If it is None, the
/// default `yarn deploy:test` is used.
async fn build_subgraph(dir: &str, deploy_cmd: Option<&str>) -> DeploymentHash {
build_subgraph_with_yarn_cmd(dir, deploy_cmd.unwrap_or("deploy:test")).await
}

async fn build_subgraph_with_yarn_cmd(dir: &str, yarn_cmd: &str) -> DeploymentHash {
build_subgraph_with_yarn_cmd_and_arg(dir, yarn_cmd, None).await
build_subgraph_with_yarn_cmd_and_args(dir, yarn_cmd, vec![]).await
}

async fn build_subgraph_with_yarn_cmd_and_arg(
async fn build_subgraph_with_yarn_cmd_and_args(
dir: &str,
yarn_cmd: &str,
arg: Option<&str>,
mut additional_args: Vec<&str>,
) -> DeploymentHash {
// Test that IPFS is up.
IpfsClient::localhost()
Expand All @@ -1296,7 +1378,7 @@ async fn build_subgraph_with_yarn_cmd_and_arg(
run_cmd(Command::new("yarn").arg("codegen").current_dir(dir));

let mut args = vec![yarn_cmd];
args.extend(arg);
args.append(&mut additional_args);

// Run `deploy` for the side effect of uploading to IPFS, the graph node url
// is fake and the actual deploy call is meant to fail.
Expand Down

0 comments on commit 3acbeb3

Please sign in to comment.