Skip to content

Commit 23e91f1

Browse files
committed
tests: Add runner test that uses file link resolver
1 parent 04590c1 commit 23e91f1

File tree

8 files changed

+181
-103
lines changed

8 files changed

+181
-103
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[
2+
{
3+
"anonymous": false,
4+
"inputs": [
5+
{
6+
"indexed": false,
7+
"internalType": "string",
8+
"name": "testCommand",
9+
"type": "string"
10+
}
11+
],
12+
"name": "TestEvent",
13+
"type": "event"
14+
}
15+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "file-link-resolver",
3+
"version": "0.1.0",
4+
"scripts": {
5+
"codegen": "graph codegen --skip-migrations",
6+
"create:test": "graph create test/file-link-resolver --node $GRAPH_NODE_ADMIN_URI",
7+
"deploy:test": "graph deploy test/file-link-resolver --version-label v0.0.1 --ipfs $IPFS_URI --node $GRAPH_NODE_ADMIN_URI"
8+
},
9+
"devDependencies": {
10+
"@graphprotocol/graph-cli": "0.60.0",
11+
"@graphprotocol/graph-ts": "0.31.0"
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
type Block @entity {
2+
id: ID!
3+
number: BigInt!
4+
hash: Bytes!
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { ethereum, log } from "@graphprotocol/graph-ts";
2+
import { Block } from "../generated/schema";
3+
4+
export function handleBlock(block: ethereum.Block): void {
5+
log.info("Processing block: {}", [block.number.toString()]);
6+
7+
let blockEntity = new Block(block.number.toString());
8+
blockEntity.number = block.number;
9+
blockEntity.hash = block.hash;
10+
blockEntity.save();
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
specVersion: 0.0.8
2+
schema:
3+
file: ./schema.graphql
4+
dataSources:
5+
- kind: ethereum/contract
6+
name: Contract
7+
network: test
8+
source:
9+
address: "0x0000000000000000000000000000000000000000"
10+
abi: Contract
11+
mapping:
12+
kind: ethereum/events
13+
apiVersion: 0.0.7
14+
language: wasm/assemblyscript
15+
entities:
16+
- Block
17+
abis:
18+
- name: Contract
19+
file: ./abis/Contract.abi
20+
blockHandlers:
21+
- handler: handleBlock
22+
file: ./src/mapping.ts

tests/runner-tests/yarn.lock

+1-97
Original file line numberDiff line numberDiff line change
@@ -349,40 +349,6 @@
349349
which "2.0.2"
350350
yaml "1.10.2"
351351

352-
"@graphprotocol/[email protected]":
353-
version "0.79.0-alpha-20240711124603-49edf22"
354-
resolved "https://registry.yarnpkg.com/@graphprotocol/graph-cli/-/graph-cli-0.79.0-alpha-20240711124603-49edf22.tgz#4e3f6201932a0b68ce64d6badd8432cf2bead3c2"
355-
integrity sha512-fZrdPiFbbbBVMnvsjfKA+j48WzzquaHQIpozBqnUKRPCV1n1NenIaq2nH16mlMwovRIS7AAIVCpa0QYQuPzw7Q==
356-
dependencies:
357-
"@float-capital/float-subgraph-uncrashable" "^0.0.0-alpha.4"
358-
"@oclif/core" "2.8.6"
359-
"@oclif/plugin-autocomplete" "^2.3.6"
360-
"@oclif/plugin-not-found" "^2.4.0"
361-
"@whatwg-node/fetch" "^0.8.4"
362-
assemblyscript "0.19.23"
363-
binary-install-raw "0.0.13"
364-
chalk "3.0.0"
365-
chokidar "3.5.3"
366-
debug "4.3.4"
367-
docker-compose "0.23.19"
368-
dockerode "2.5.8"
369-
fs-extra "9.1.0"
370-
glob "9.3.5"
371-
gluegun "5.1.6"
372-
graphql "15.5.0"
373-
immutable "4.2.1"
374-
ipfs-http-client "55.0.0"
375-
jayson "4.0.0"
376-
js-yaml "3.14.1"
377-
open "8.4.2"
378-
prettier "3.0.3"
379-
semver "7.4.0"
380-
sync-request "6.1.0"
381-
tmp-promise "3.0.3"
382-
web3-eth-abi "1.7.0"
383-
which "2.0.2"
384-
yaml "1.10.2"
385-
386352
"@graphprotocol/[email protected]":
387353
version "0.30.0"
388354
resolved "https://registry.npmjs.org/@graphprotocol/graph-ts/-/graph-ts-0.30.0.tgz"
@@ -1507,11 +1473,6 @@ defaults@^1.0.3:
15071473
dependencies:
15081474
clone "^1.0.2"
15091475

1510-
define-lazy-prop@^2.0.0:
1511-
version "2.0.0"
1512-
resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
1513-
integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==
1514-
15151476
delay@^5.0.0:
15161477
version "5.0.0"
15171478
resolved "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz"
@@ -1584,13 +1545,6 @@ [email protected]:
15841545
dependencies:
15851546
jake "^10.6.1"
15861547

1587-
1588-
version "3.1.8"
1589-
resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.8.tgz#758d32910c78047585c7ef1f92f9ee041c1c190b"
1590-
integrity sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==
1591-
dependencies:
1592-
jake "^10.8.5"
1593-
15941548
ejs@^3.1.8:
15951549
version "3.1.9"
15961550
resolved "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz"
@@ -2055,42 +2009,6 @@ [email protected]:
20552009
which "2.0.2"
20562010
yargs-parser "^21.0.0"
20572011

2058-
2059-
version "5.1.6"
2060-
resolved "https://registry.yarnpkg.com/gluegun/-/gluegun-5.1.6.tgz#74ec13193913dc610f5c1a4039972c70c96a7bad"
2061-
integrity sha512-9zbi4EQWIVvSOftJWquWzr9gLX2kaDgPkNR5dYWbM53eVvCI3iKuxLlnKoHC0v4uPoq+Kr/+F569tjoFbA4DSA==
2062-
dependencies:
2063-
apisauce "^2.1.5"
2064-
app-module-path "^2.2.0"
2065-
cli-table3 "0.6.0"
2066-
colors "1.4.0"
2067-
cosmiconfig "7.0.1"
2068-
cross-spawn "7.0.3"
2069-
ejs "3.1.8"
2070-
enquirer "2.3.6"
2071-
execa "5.1.1"
2072-
fs-jetpack "4.3.1"
2073-
lodash.camelcase "^4.3.0"
2074-
lodash.kebabcase "^4.1.1"
2075-
lodash.lowercase "^4.3.0"
2076-
lodash.lowerfirst "^4.3.1"
2077-
lodash.pad "^4.5.1"
2078-
lodash.padend "^4.6.1"
2079-
lodash.padstart "^4.6.1"
2080-
lodash.repeat "^4.1.0"
2081-
lodash.snakecase "^4.1.1"
2082-
lodash.startcase "^4.4.0"
2083-
lodash.trim "^4.5.1"
2084-
lodash.trimend "^4.5.1"
2085-
lodash.trimstart "^4.5.1"
2086-
lodash.uppercase "^4.3.0"
2087-
lodash.upperfirst "^4.3.1"
2088-
ora "4.0.2"
2089-
pluralize "^8.0.0"
2090-
semver "7.3.5"
2091-
which "2.0.2"
2092-
yargs-parser "^21.0.0"
2093-
20942012
graceful-fs@^4.1.6, graceful-fs@^4.2.0:
20952013
version "4.2.11"
20962014
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
@@ -2377,7 +2295,7 @@ is-binary-path@~2.1.0:
23772295
dependencies:
23782296
binary-extensions "^2.0.0"
23792297

2380-
is-docker@^2.0.0, is-docker@^2.1.1:
2298+
is-docker@^2.0.0:
23812299
version "2.2.1"
23822300
resolved "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz"
23832301
integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
@@ -3022,15 +2940,6 @@ onetime@^5.1.0, onetime@^5.1.2:
30222940
dependencies:
30232941
mimic-fn "^2.1.0"
30242942

3025-
3026-
version "8.4.2"
3027-
resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9"
3028-
integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==
3029-
dependencies:
3030-
define-lazy-prop "^2.0.0"
3031-
is-docker "^2.1.1"
3032-
is-wsl "^2.2.0"
3033-
30342943
30352944
version "4.0.2"
30362945
resolved "https://registry.npmjs.org/ora/-/ora-4.0.2.tgz"
@@ -3151,11 +3060,6 @@ [email protected]:
31513060
resolved "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz"
31523061
integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
31533062

3154-
3155-
version "3.0.3"
3156-
resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643"
3157-
integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==
3158-
31593063
process-nextick-args@~2.0.0:
31603064
version "2.0.1"
31613065
resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz"

tests/src/fixture/mod.rs

+44-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ pub mod substreams;
33

44
use std::collections::{BTreeSet, HashMap};
55
use std::marker::PhantomData;
6+
use std::path::PathBuf;
67
use std::sync::Mutex;
78
use std::time::{Duration, Instant};
89

@@ -17,7 +18,9 @@ use graph::blockchain::{
1718
TriggerFilterWrapper, TriggersAdapter, TriggersAdapterSelector,
1819
};
1920
use graph::cheap_clone::CheapClone;
20-
use graph::components::link_resolver::{ArweaveClient, ArweaveResolver, FileSizeLimit};
21+
use graph::components::link_resolver::{
22+
ArweaveClient, ArweaveResolver, FileLinkResolver, FileSizeLimit,
23+
};
2124
use graph::components::metrics::MetricsRegistry;
2225
use graph::components::network_provider::ChainName;
2326
use graph::components::store::{BlockStore, DeploymentLocator, EthereumCallCache, SourceableStore};
@@ -38,7 +41,7 @@ use graph::prelude::ethabi::ethereum_types::H256;
3841
use graph::prelude::serde_json::{self, json};
3942
use graph::prelude::{
4043
async_trait, lazy_static, q, r, ApiVersion, BigInt, BlockNumber, DeploymentHash,
41-
GraphQlRunner as _, IpfsResolver, LoggerFactory, NodeId, QueryError,
44+
GraphQlRunner as _, IpfsResolver, LinkResolver, LoggerFactory, NodeId, QueryError,
4245
SubgraphAssignmentProvider, SubgraphCountMetric, SubgraphName, SubgraphRegistrar,
4346
SubgraphStore as _, SubgraphVersionSwitchingMode, TriggerProcessor,
4447
};
@@ -455,6 +458,38 @@ pub async fn setup<C: Blockchain>(
455458
chain: &impl TestChainTrait<C>,
456459
graft_block: Option<BlockPtr>,
457460
env_vars: Option<EnvVars>,
461+
) -> TestContext {
462+
setup_inner(test_info, stores, chain, graft_block, env_vars, None).await
463+
}
464+
465+
pub async fn setup_with_file_link_resolver<C: Blockchain>(
466+
test_info: &TestInfo,
467+
stores: &Stores,
468+
chain: &impl TestChainTrait<C>,
469+
graft_block: Option<BlockPtr>,
470+
env_vars: Option<EnvVars>,
471+
) -> TestContext {
472+
let mut base_dir = PathBuf::from(test_info.test_dir.clone());
473+
base_dir.push("build");
474+
let link_resolver = Arc::new(FileLinkResolver::with_base_dir(base_dir));
475+
setup_inner(
476+
test_info,
477+
stores,
478+
chain,
479+
graft_block,
480+
env_vars,
481+
Some(link_resolver),
482+
)
483+
.await
484+
}
485+
486+
pub async fn setup_inner<C: Blockchain>(
487+
test_info: &TestInfo,
488+
stores: &Stores,
489+
chain: &impl TestChainTrait<C>,
490+
graft_block: Option<BlockPtr>,
491+
env_vars: Option<EnvVars>,
492+
link_resolver: Option<Arc<dyn LinkResolver>>,
458493
) -> TestContext {
459494
let env_vars = Arc::new(match env_vars {
460495
Some(ev) => ev,
@@ -483,10 +518,13 @@ pub async fn setup<C: Blockchain>(
483518
.unwrap(),
484519
);
485520

486-
let link_resolver = Arc::new(IpfsResolver::new(
487-
ipfs_client.cheap_clone(),
488-
Default::default(),
489-
));
521+
let link_resolver = match link_resolver {
522+
Some(link_resolver) => link_resolver,
523+
None => Arc::new(IpfsResolver::new(
524+
ipfs_client.cheap_clone(),
525+
Default::default(),
526+
)),
527+
};
490528

491529
let ipfs_service = ipfs_service(
492530
ipfs_client.cheap_clone(),

tests/tests/runner_tests.rs

+70
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,24 @@ impl RunnerTestRecipe {
8080
},
8181
}
8282
}
83+
84+
async fn new_with_file_link_resolver(name: &str, subgraph_name: &str, manifest: &str) -> Self {
85+
let subgraph_name = SubgraphName::new(subgraph_name).unwrap();
86+
let test_dir = format!("./runner-tests/{}", subgraph_name);
87+
88+
let stores = stores(name, "./runner-tests/config.simple.toml").await;
89+
build_subgraph(&test_dir, None).await;
90+
let hash = DeploymentHash::new(manifest).unwrap();
91+
Self {
92+
stores,
93+
test_info: TestInfo {
94+
test_dir,
95+
test_name: name.to_string(),
96+
subgraph_name,
97+
hash,
98+
},
99+
}
100+
}
83101
}
84102

85103
fn assert_eq_ignore_backtrace(err: &SubgraphError, expected: &SubgraphError) {
@@ -1152,6 +1170,58 @@ async fn retry_create_ds() {
11521170
assert_eq!(runner.context().hosts_len(), 2);
11531171
}
11541172

1173+
#[tokio::test]
1174+
async fn file_link_resolver() -> anyhow::Result<()> {
1175+
let RunnerTestRecipe { stores, test_info } = RunnerTestRecipe::new_with_file_link_resolver(
1176+
"file_link_resolver",
1177+
"file-link-resolver",
1178+
"subgraph.yaml",
1179+
)
1180+
.await;
1181+
1182+
let blocks = {
1183+
let block_0 = genesis();
1184+
let block_1 = empty_block(block_0.ptr(), test_ptr(1));
1185+
let block_2 = empty_block(block_1.ptr(), test_ptr(2));
1186+
let block_3 = empty_block(block_2.ptr(), test_ptr(3));
1187+
1188+
vec![block_0, block_1, block_2, block_3]
1189+
};
1190+
1191+
let chain = chain(&test_info.test_name, blocks, &stores, None).await;
1192+
1193+
let ctx = fixture::setup_with_file_link_resolver(&test_info, &stores, &chain, None, None).await;
1194+
ctx.start_and_sync_to(test_ptr(3)).await;
1195+
let query = r#"{ blocks(first: 4, orderBy: number) { id, hash } }"#;
1196+
let query_res = ctx.query(query).await.unwrap();
1197+
1198+
assert_eq!(
1199+
query_res,
1200+
Some(object! {
1201+
blocks: vec![
1202+
object! {
1203+
id: test_ptr(0).number.to_string(),
1204+
hash: format!("0x{}", test_ptr(0).hash_hex()),
1205+
},
1206+
object! {
1207+
id: test_ptr(1).number.to_string(),
1208+
hash: format!("0x{}", test_ptr(1).hash_hex()),
1209+
},
1210+
object! {
1211+
id: test_ptr(2).number.to_string(),
1212+
hash: format!("0x{}", test_ptr(2).hash_hex()),
1213+
},
1214+
object! {
1215+
id: test_ptr(3).number.to_string(),
1216+
hash: format!("0x{}", test_ptr(3).hash_hex()),
1217+
},
1218+
]
1219+
})
1220+
);
1221+
1222+
Ok(())
1223+
}
1224+
11551225
#[tokio::test]
11561226
async fn fatal_error() -> anyhow::Result<()> {
11571227
let RunnerTestRecipe { stores, test_info } =

0 commit comments

Comments
 (0)