Skip to content

Commit f2f1d8f

Browse files
committed
graph: add tests for provider checks
1 parent 0972eaa commit f2f1d8f

File tree

6 files changed

+554
-3
lines changed

6 files changed

+554
-3
lines changed

graph/src/components/network_provider/chain_identifier_store.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,20 @@ use crate::components::network_provider::ChainName;
77
use crate::components::store::BlockStore;
88
use crate::components::store::ChainStore;
99

10+
/// Additional requirements for stores that are necessary for provider checks.
1011
pub trait ChainIdentifierStore: Send + Sync + 'static {
12+
/// Verifies that the chain identifier returned by the network provider
13+
/// matches the previously stored value.
14+
///
15+
/// Fails if the identifiers do not match or if something goes wrong.
1116
fn validate_identifier(
1217
&self,
1318
chain_name: &ChainName,
1419
chain_identifier: &ChainIdentifier,
1520
) -> Result<(), ChainIdentifierStoreError>;
1621

22+
/// Saves the provided identifier that will be used as the source of truth
23+
/// for future validations.
1724
fn update_identifier(
1825
&self,
1926
chain_name: &ChainName,

graph/src/components/network_provider/extended_blocks_check.rs

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::time::Instant;
33

44
use async_trait::async_trait;
55
use slog::error;
6+
use slog::warn;
67
use slog::Logger;
78

89
use crate::components::network_provider::ChainName;
@@ -26,6 +27,10 @@ impl ExtendedBlocksCheck {
2627

2728
#[async_trait]
2829
impl ProviderCheck for ExtendedBlocksCheck {
30+
fn name(&self) -> &'static str {
31+
"ExtendedBlocksCheck"
32+
}
33+
2934
async fn check(
3035
&self,
3136
logger: &Logger,
@@ -34,6 +39,13 @@ impl ProviderCheck for ExtendedBlocksCheck {
3439
adapter: &dyn NetworkDetails,
3540
) -> ProviderCheckStatus {
3641
if self.disabled_for_chains.contains(chain_name) {
42+
warn!(
43+
logger,
44+
"Extended blocks check for provider '{}' was disabled on chain '{}'",
45+
provider_name,
46+
chain_name,
47+
);
48+
3749
return ProviderCheckStatus::Valid;
3850
}
3951

@@ -65,3 +77,152 @@ impl ProviderCheck for ExtendedBlocksCheck {
6577
}
6678
}
6779
}
80+
81+
#[cfg(test)]
82+
mod tests {
83+
use std::sync::Mutex;
84+
85+
use anyhow::anyhow;
86+
use anyhow::Result;
87+
88+
use super::*;
89+
use crate::blockchain::ChainIdentifier;
90+
use crate::log::discard;
91+
92+
macro_rules! lock {
93+
($obj:ident.$field:ident. $( $call:tt )+) => {{
94+
$obj.$field.lock().unwrap(). $( $call )+
95+
}};
96+
}
97+
98+
#[derive(Default)]
99+
struct TestAdapter {
100+
provides_extended_blocks_calls: Mutex<Vec<Result<bool>>>,
101+
}
102+
103+
#[async_trait]
104+
impl NetworkDetails for TestAdapter {
105+
fn provider_name(&self) -> ProviderName {
106+
unimplemented!();
107+
}
108+
109+
async fn chain_identifier(&self) -> Result<ChainIdentifier> {
110+
unimplemented!();
111+
}
112+
113+
async fn provides_extended_blocks(&self) -> Result<bool> {
114+
lock!(self.provides_extended_blocks_calls.remove(0))
115+
}
116+
}
117+
118+
impl Drop for TestAdapter {
119+
fn drop(&mut self) {
120+
assert!(lock!(self.provides_extended_blocks_calls.is_empty()));
121+
}
122+
}
123+
124+
#[tokio::test]
125+
async fn check_valid_when_disabled_for_chain() {
126+
let check = ExtendedBlocksCheck::new(["chain-1".into()]);
127+
let adapter = TestAdapter::default();
128+
129+
let status = check
130+
.check(
131+
&discard(),
132+
&("chain-1".into()),
133+
&("provider-1".into()),
134+
&adapter,
135+
)
136+
.await;
137+
138+
assert_eq!(status, ProviderCheckStatus::Valid);
139+
}
140+
141+
#[tokio::test]
142+
async fn check_valid_when_disabled_for_multiple_chains() {
143+
let check = ExtendedBlocksCheck::new(["chain-1".into(), "chain-2".into()]);
144+
let adapter = TestAdapter::default();
145+
146+
let status = check
147+
.check(
148+
&discard(),
149+
&("chain-1".into()),
150+
&("provider-1".into()),
151+
&adapter,
152+
)
153+
.await;
154+
155+
assert_eq!(status, ProviderCheckStatus::Valid);
156+
157+
let status = check
158+
.check(
159+
&discard(),
160+
&("chain-2".into()),
161+
&("provider-2".into()),
162+
&adapter,
163+
)
164+
.await;
165+
166+
assert_eq!(status, ProviderCheckStatus::Valid);
167+
}
168+
169+
#[tokio::test]
170+
async fn check_valid_when_extended_blocks_are_supported() {
171+
let check = ExtendedBlocksCheck::new([]);
172+
173+
let adapter = TestAdapter::default();
174+
lock! { adapter.provides_extended_blocks_calls.push(Ok(true)) };
175+
176+
let status = check
177+
.check(
178+
&discard(),
179+
&("chain-1".into()),
180+
&("provider-1".into()),
181+
&adapter,
182+
)
183+
.await;
184+
185+
assert_eq!(status, ProviderCheckStatus::Valid);
186+
}
187+
188+
#[tokio::test]
189+
async fn check_fails_when_extended_blocks_are_not_supported() {
190+
let check = ExtendedBlocksCheck::new([]);
191+
192+
let adapter = TestAdapter::default();
193+
lock! { adapter.provides_extended_blocks_calls.push(Ok(false)) };
194+
195+
let status = check
196+
.check(
197+
&discard(),
198+
&("chain-1".into()),
199+
&("provider-1".into()),
200+
&adapter,
201+
)
202+
.await;
203+
204+
assert_eq!(status, ProviderCheckStatus::Failed);
205+
}
206+
207+
#[tokio::test]
208+
async fn check_temporary_failure_when_provider_request_fails() {
209+
let check = ExtendedBlocksCheck::new([]);
210+
211+
let adapter = TestAdapter::default();
212+
lock! { adapter.provides_extended_blocks_calls.push(Err(anyhow!("error"))) };
213+
214+
let status = check
215+
.check(
216+
&discard(),
217+
&("chain-1".into()),
218+
&("provider-1".into()),
219+
&adapter,
220+
)
221+
.await;
222+
223+
assert!(matches!(
224+
status,
225+
ProviderCheckStatus::TemporaryFailure { .. }
226+
))
227+
}
228+
}

0 commit comments

Comments
 (0)