Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mangas committed Apr 22, 2024
1 parent bf5aa3c commit b486f8a
Showing 1 changed file with 58 additions and 31 deletions.
89 changes: 58 additions & 31 deletions graph/src/components/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ pub enum ProviderManagerError {
}

#[async_trait]
trait NetIdentifiable: Clone + Sync + Send {
trait NetIdentifiable: Sync + Send {
async fn net_identifiers(&self) -> Result<ChainIdentifier, anyhow::Error>;
fn provider_name(&self) -> ProviderName;
}
Expand All @@ -53,11 +53,11 @@ struct Ident {
/// provider for the same chain offers a different ChainIdentifier, this will be considered a
/// failed validation and it will be disabled.
#[derive(Debug)]
struct ProviderManager<T: NetIdentifiable> {
struct ProviderManager<T: NetIdentifiable + Clone> {
inner: Arc<Inner<T>>,
}

impl<T: NetIdentifiable + 'static> ProviderManager<T> {
impl<T: NetIdentifiable + Clone + 'static> ProviderManager<T> {
pub fn new(
logger: Logger,
adapters: impl Iterator<Item = (ChainId, Vec<T>)>,
Expand All @@ -75,7 +75,7 @@ impl<T: NetIdentifiable + 'static> ProviderManager<T> {
// Get status index or add new status.
let index = match status
.iter()
.find_position(|(provider_name, _)| provider_name.eq(&provider_name))
.find_position(|(ident, _)| ident.provider.eq(&name))
{
Some((index, _)) => index,
None => {
Expand Down Expand Up @@ -116,7 +116,7 @@ impl<T: NetIdentifiable + 'static> ProviderManager<T> {
tasks.push(inner.verify_provider(index, adapter));
}

crate::prelude::futures03::future::join_all(tasks)
crate::futures03::future::join_all(tasks)
.await
.into_iter()
.collect::<Result<Vec<()>, ProviderManagerError>>()?;
Expand Down Expand Up @@ -357,7 +357,7 @@ mod test {
static ref UNTESTABLE_ADAPTER: MockAdapter =
MockAdapter{
provider: UNTESTABLE_CHAIN.into(),
ident: VALID_IDENT.clone(),
ident: FAILED_IDENT.clone(),
checked_at: Some(Utc::now()),
};

Expand Down Expand Up @@ -430,6 +430,7 @@ mod test {
struct Case<'a> {
name: &'a str,
chain_id: &'a str,
status: Vec<(ProviderName, GenesisCheckStatus)>,
adapters: Vec<(ChainId, Vec<MockAdapter>)>,
idents: Vec<(ChainId, Option<ChainIdentifier>)>,
expected: Result<Vec<&'a MockAdapter>, ProviderManagerError>,
Expand All @@ -439,40 +440,56 @@ mod test {
Case {
name: "no adapters",
chain_id: EMPTY_CHAIN,
status: vec![],
adapters: vec![],
idents: vec![(VALID_CHAIN.into(), None)],
expected: Ok(vec![]),
},
Case {
name: "adapter temporary failure bypasses checks if Ident None",
name: "adapter temporary failure with Ident None",
chain_id: VALID_CHAIN,
// utc::now means it was just tested so it's untestable at the moment.
status: vec![(
UNTESTABLE_CHAIN.to_string(),
GenesisCheckStatus::TemporaryFailure {
checked_at: UNTESTABLE_ADAPTER.checked_at.unwrap(),
},
)],
// UNTESTABLE_ADAPTER has failed ident, will be valid cause idents has None value
adapters: vec![(VALID_CHAIN.into(), vec![UNTESTABLE_ADAPTER.clone()])],
idents: vec![(VALID_CHAIN.into(), None)],
expected: Ok(vec![&UNTESTABLE_ADAPTER]),
expected: Err(ProviderManagerError::NoProvidersAvailable(
VALID_CHAIN.to_string(),
)),
},
Case {
name: "adapter temporary failure",
chain_id: VALID_CHAIN,
// utc::now means it was just tested so it's untestable at the moment.
status: vec![(
UNTESTABLE_CHAIN.to_string(),
GenesisCheckStatus::TemporaryFailure {
checked_at: Utc::now(),
},
)],
adapters: vec![(VALID_CHAIN.into(), vec![UNTESTABLE_ADAPTER.clone()])],
idents: vec![(VALID_CHAIN.into(), Some(VALID_IDENT.clone()))],
idents: vec![(VALID_CHAIN.into(), Some(FAILED_IDENT.clone()))],
expected: Err(ProviderManagerError::NoProvidersAvailable(
VALID_CHAIN.to_string(),
)),
},
Case {
name: "chain ident None",
chain_id: FAILED_CHAIN,
chain_id: VALID_CHAIN,
// Failed adapter has VALID_CHAIN as the ident, which is not validated if
// the expected ident is None
adapters: vec![(FAILED_CHAIN.into(), vec![FAILED_ADAPTER.clone()])],
idents: vec![(FAILED_CHAIN.into(), None)],
status: vec![],
adapters: vec![(VALID_CHAIN.into(), vec![FAILED_ADAPTER.clone()])],
idents: vec![(VALID_CHAIN.into(), None)],
expected: Ok(vec![&FAILED_ADAPTER]),
},
Case {
name: "wrong chain ident",
chain_id: VALID_CHAIN,
status: vec![],
adapters: vec![(VALID_CHAIN.into(), vec![MockAdapter::failed()])],
idents: vec![(VALID_CHAIN.into(), Some(VALID_IDENT.clone()))],
expected: Err(ProviderManagerError::AllProvidersFailed(
Expand All @@ -482,16 +499,28 @@ mod test {
Case {
name: "all adapters ok or not checkable yet",
chain_id: VALID_CHAIN,
status: vec![(
FAILED_CHAIN.to_string(),
GenesisCheckStatus::TemporaryFailure {
checked_at: Utc::now(),
},
)],
adapters: vec![(
VALID_CHAIN.into(),
vec![VALID_ADAPTER.clone(), UNTESTABLE_ADAPTER.clone()],
vec![VALID_ADAPTER.clone(), FAILED_ADAPTER.clone()],
)],
idents: vec![(VALID_CHAIN.into(), Some(VALID_IDENT.clone()))],
expected: Ok(vec![&VALID_ADAPTER]),
},
Case {
name: "all adapters ok or checkable",
chain_id: VALID_CHAIN,
status: vec![(
TESTABLE_CHAIN.to_string(),
GenesisCheckStatus::TemporaryFailure {
checked_at: TESTABLE_ADAPTER.checked_at.unwrap(),
},
)],
adapters: vec![(
VALID_CHAIN.into(),
vec![VALID_ADAPTER.clone(), TESTABLE_ADAPTER.clone()],
Expand All @@ -505,6 +534,7 @@ mod test {
let Case {
name,
chain_id,
status,
adapters,
idents,
expected,
Expand All @@ -513,22 +543,19 @@ mod test {
let logger = Logger::root(Discard, o!());

let manager = ProviderManager::new(logger, adapters.into_iter(), idents.into_iter());
for (ident, status) in manager.inner.status.iter() {
match ident.chain_id.as_str() {
TESTABLE_CHAIN => {
let mut s = status.write().await;
*s = GenesisCheckStatus::TemporaryFailure {
checked_at: Utc::now().sub(Duration::seconds(1000000)),
};
}
UNTESTABLE_CHAIN => {
let mut s = status.write().await;
*s = GenesisCheckStatus::TemporaryFailure {
checked_at: Utc::now(),
};
}
_ => {}
}

for (provider, status) in status.iter() {
let slot = manager
.inner
.status
.iter()
.find(|(ident, _)| ident.provider.eq(provider))
.expect(&format!(
"case: {} - there should be a status for provider \"{}\"",
name, provider
));
let mut s = slot.1.write().await;
*s = status.clone();
}

let result = manager.get_all(chain_id.into()).await;
Expand Down

0 comments on commit b486f8a

Please sign in to comment.