Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 857e635

Browse files
slumberbredamatt
authored andcommitted
Fix flaky test (#6131)
* Split test + decrease test timeout * fmt * spellcheck
1 parent 1e96dfd commit 857e635

3 files changed

Lines changed: 63 additions & 20 deletions

File tree

node/network/collator-protocol/src/validator_side/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,16 @@ const BENEFIT_NOTIFY_GOOD: Rep =
8585
/// to finish on time.
8686
///
8787
/// There is debug logging output, so we can adjust this value based on production results.
88+
#[cfg(not(test))]
8889
const MAX_UNSHARED_DOWNLOAD_TIME: Duration = Duration::from_millis(400);
8990

9091
// How often to check all peers with activity.
9192
#[cfg(not(test))]
9293
const ACTIVITY_POLL: Duration = Duration::from_secs(1);
9394

95+
#[cfg(test)]
96+
const MAX_UNSHARED_DOWNLOAD_TIME: Duration = Duration::from_millis(100);
97+
9498
#[cfg(test)]
9599
const ACTIVITY_POLL: Duration = Duration::from_millis(10);
96100

node/network/collator-protocol/src/validator_side/tests.rs

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use futures::{executor, future, Future};
2020
use sp_core::{crypto::Pair, Encode};
2121
use sp_keyring::Sr25519Keyring;
2222
use sp_keystore::{testing::KeyStore as TestKeyStore, SyncCryptoStore};
23-
use std::{iter, sync::Arc, time::Duration};
23+
use std::{iter, sync::Arc, task::Poll, time::Duration};
2424

2525
use polkadot_node_network_protocol::{
2626
our_view,
@@ -493,17 +493,11 @@ fn collator_authentication_verification_works() {
493493
});
494494
}
495495

496-
// A test scenario that takes the following steps
497-
// - Two collators connect, declare themselves and advertise a collation relevant to
498-
// our view.
499-
// - Collation protocol should request one PoV.
500-
// - Collation protocol should disconnect both collators after having received the collation.
501-
// - The same collators plus an additional collator connect again and send `PoV`s for a different relay parent.
502-
// - Collation protocol will request one PoV, but we will cancel it.
503-
// - Collation protocol should request the second PoV which does not succeed in time.
504-
// - Collation protocol should request third PoV.
496+
/// Tests that a validator fetches only one collation at any moment of time
497+
/// per relay parent and ignores other advertisements once a candidate gets
498+
/// seconded.
505499
#[test]
506-
fn fetch_collations_works() {
500+
fn fetch_one_collation_at_a_time() {
507501
let test_state = TestState::default();
508502

509503
test_harness(|test_harness| async move {
@@ -575,22 +569,38 @@ fn fetch_collations_works() {
575569
)
576570
.await;
577571

578-
overseer_send(
579-
&mut virtual_overseer,
580-
CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerDisconnected(
581-
peer_b.clone(),
582-
)),
583-
)
584-
.await;
572+
// Ensure the subsystem is polled.
573+
test_helpers::Yield::new().await;
574+
575+
// Second collation is not requested since there's already seconded one.
576+
assert_matches!(futures::poll!(virtual_overseer.recv().boxed()), Poll::Pending);
577+
578+
virtual_overseer
579+
})
580+
}
581+
582+
/// Tests that a validator starts fetching next queued collations on [`MAX_UNSHARED_DOWNLOAD_TIME`]
583+
/// timeout and in case of an error.
584+
#[test]
585+
fn fetches_next_collation() {
586+
let test_state = TestState::default();
587+
588+
test_harness(|test_harness| async move {
589+
let TestHarness { mut virtual_overseer } = test_harness;
590+
591+
let second = Hash::random();
585592

586593
overseer_send(
587594
&mut virtual_overseer,
588-
CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::PeerDisconnected(
589-
peer_c.clone(),
595+
CollatorProtocolMessage::NetworkBridgeUpdate(NetworkBridgeEvent::OurViewChange(
596+
our_view![test_state.relay_parent, second],
590597
)),
591598
)
592599
.await;
593600

601+
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
602+
respond_to_core_info_queries(&mut virtual_overseer, &test_state).await;
603+
594604
let peer_b = PeerId::random();
595605
let peer_c = PeerId::random();
596606
let peer_d = PeerId::random();

node/subsystem-test-helpers/src/lib.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ use sp_core::testing::TaskExecutor;
3030

3131
use std::{
3232
convert::Infallible,
33+
future::Future,
3334
pin::Pin,
3435
sync::Arc,
3536
task::{Context, Poll, Waker},
@@ -391,6 +392,34 @@ macro_rules! arbitrary_order {
391392
};
392393
}
393394

395+
/// Future that yields the execution once and resolves
396+
/// immediately after.
397+
///
398+
/// Useful when one wants to poll the background task to completion
399+
/// before sending messages to it in order to avoid races.
400+
pub struct Yield(bool);
401+
402+
impl Yield {
403+
/// Returns new `Yield` future.
404+
pub fn new() -> Self {
405+
Self(false)
406+
}
407+
}
408+
409+
impl Future for Yield {
410+
type Output = ();
411+
412+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
413+
if !self.0 {
414+
self.0 = true;
415+
cx.waker().wake_by_ref();
416+
Poll::Pending
417+
} else {
418+
Poll::Ready(())
419+
}
420+
}
421+
}
422+
394423
#[cfg(test)]
395424
mod tests {
396425
use super::*;

0 commit comments

Comments
 (0)