Skip to content

Commit 48a9dd8

Browse files
committed
tests: Add test for reverts using fail points
1 parent 389926f commit 48a9dd8

File tree

17 files changed

+292
-11
lines changed

17 files changed

+292
-11
lines changed

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

chain/ethereum/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ serde = "1.0"
1515
config = { version = "0.10", features = ["toml"], default-features = false }
1616
dirs = "3.0"
1717
anyhow = "1.0"
18+
fail = "0.4"
1819

1920
[dev-dependencies]
2021
diesel = { version = "1.4.5", features = ["postgres", "serde_json", "numeric", "r2d2"] }

chain/ethereum/src/block_stream.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ use graph::prelude::{
1111
BlockStream as BlockStreamTrait, BlockStreamBuilder as BlockStreamBuilderTrait, *,
1212
};
1313

14+
use fail::fail_point;
15+
1416
lazy_static! {
1517
/// Maximum number of blocks to request in each chunk.
1618
static ref MAX_BLOCK_RANGE_SIZE: u64 = std::env::var("GRAPH_ETHEREUM_MAX_BLOCK_RANGE_SIZE")
@@ -444,6 +446,11 @@ where
444446
let subgraph_ptr =
445447
subgraph_ptr.expect("subgraph block pointer should not be `None` here");
446448

449+
#[cfg(debug_assertions)]
450+
if test_reorg(subgraph_ptr) {
451+
return Box::new(future::ok(ReconciliationStep::Revert(subgraph_ptr)));
452+
}
453+
447454
// Precondition: subgraph_ptr.number < head_ptr.number
448455
// Walk back to one block short of subgraph_ptr.number
449456
let offset = head_ptr.number - subgraph_ptr.number - 1;
@@ -822,3 +829,25 @@ where
822829
)
823830
}
824831
}
832+
833+
// This always returns `false` in a normal build. A test may configure reorg by enabling
834+
// "test_reorg" fail point with the number of the block that should be reorged.
835+
fn test_reorg(ptr: EthereumBlockPointer) -> bool {
836+
fail_point!("test_reorg", |reorg_at| {
837+
use std::str::FromStr;
838+
839+
static REORGED: std::sync::Once = std::sync::Once::new();
840+
841+
if REORGED.is_completed() {
842+
return false;
843+
}
844+
let reorg_at = u64::from_str(&reorg_at.unwrap()).unwrap();
845+
let should_reorg = ptr.number == reorg_at;
846+
if should_reorg {
847+
REORGED.call_once(|| {})
848+
}
849+
should_reorg
850+
});
851+
852+
false
853+
}

core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ semver = "0.10.0"
1818
serde = "1.0"
1919
serde_json = "1.0"
2020
serde_yaml = "0.8"
21+
fail = "0.4"
2122

2223
[dev-dependencies]
2324
graph-mock = { path = "../mock" }

core/src/subgraph/instance_manager.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use atomic_refcell::AtomicRefCell;
2+
use fail::fail_point;
23
use futures01::sync::mpsc::{channel, Receiver, Sender};
34
use lazy_static::lazy_static;
45
use std::collections::{BTreeSet, HashMap, HashSet};
@@ -1055,16 +1056,19 @@ where
10551056
data_sources.push(data_source);
10561057
runtime_hosts.push(host);
10571058
}
1058-
None => warn!(
1059-
logger,
1060-
"no runtime hosted created, there is already a runtime host instantiated for \
1061-
this data source";
1062-
"name" => &data_source.name,
1063-
"address" => &data_source.source.address
1064-
.map(|address| address.to_string())
1065-
.unwrap_or("none".to_string()),
1066-
"abi" => &data_source.source.abi
1067-
),
1059+
None => {
1060+
fail_point!("error_on_duplicate_ds", |_| Err(anyhow!("duplicate ds")));
1061+
warn!(
1062+
logger,
1063+
"no runtime hosted created, there is already a runtime host instantiated for \
1064+
this data source";
1065+
"name" => &data_source.name,
1066+
"address" => &data_source.source.address
1067+
.map(|address| address.to_string())
1068+
.unwrap_or("none".to_string()),
1069+
"abi" => &data_source.source.abi
1070+
)
1071+
}
10681072
}
10691073
}
10701074

node/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ structopt = "0.3.20"
4242
toml = "0.5.7"
4343
shellexpand = "2.0.0"
4444
diesel = "1.4.5"
45+
fail = "0.4"
4546

4647
[dev-dependencies]
4748
assert_cli = "0.6"

node/src/main.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ fn read_expensive_queries() -> Result<Vec<Arc<q::Document>>, std::io::Error> {
101101
async fn main() {
102102
env_logger::init();
103103

104+
// Allow configuring fail points on debug builds. Used for integration tests.
105+
#[cfg(debug_assertions)]
106+
std::mem::forget(fail::FailScenario::setup());
107+
104108
let opt = opt::Opt::from_args();
105109

106110
// Set up logger

store/postgres/tests/graft.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,6 @@ fn graft() {
269269
TEST_SUBGRAPH_ID.as_str(),
270270
BLOCKS[1],
271271
);
272-
dbg!(&res);
273272
assert!(res.is_ok());
274273

275274
let query = EntityQuery::new(

tests/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@ edition = "2018"
66
[dev-dependencies]
77
duct = "0.13"
88
lazy_static = "1.4.0"
9+
fail = { version = "0.4", features = ["failpoints"] }
10+
defer = "0.1"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
[{"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"}]

0 commit comments

Comments
 (0)