From d7047578e92ed3adb25326987e3f50e092e0ac1d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bastian=20K=C3=B6cher?= <bkchr@users.noreply.github.com>
Date: Mon, 7 Dec 2020 15:47:39 +0100
Subject: [PATCH] Fix tests on master (#2080)

Because of a bug in the test script, we didn't stopped CI when the main
tests are failed.
---
 polkadot/node/core/backing/src/lib.rs         | 48 ++++++++------
 polkadot/node/core/provisioner/src/lib.rs     |  6 +-
 polkadot/node/core/provisioner/src/tests.rs   | 65 +++++++++++--------
 polkadot/node/overseer/src/lib.rs             |  2 +-
 .../node/test/service/tests/build-blocks.rs   |  2 +-
 polkadot/primitives/src/v1.rs                 |  5 ++
 polkadot/scripts/gitlab/test_linux_stable.sh  |  1 +
 7 files changed, 78 insertions(+), 51 deletions(-)

diff --git a/polkadot/node/core/backing/src/lib.rs b/polkadot/node/core/backing/src/lib.rs
index 1d17827d0a3..54dbe295f7b 100644
--- a/polkadot/node/core/backing/src/lib.rs
+++ b/polkadot/node/core/backing/src/lib.rs
@@ -754,7 +754,7 @@ impl CandidateBackingJob {
 		self.background_validate_and_make_available(BackgroundValidationParams {
 			tx_from: self.tx_from.clone(),
 			tx_command: self.background_validation_tx.clone(),
-			candidate: candidate,
+			candidate,
 			relay_parent: self.parent,
 			pov: None,
 			validator_index: self.table_context.validator.as_ref().map(|v| v.index()),
@@ -1644,28 +1644,38 @@ mod tests {
 				AllMessages::Provisioner(
 					ProvisionerMessage::ProvisionableData(
 						_,
-						ProvisionableData::BackedCandidate(BackedCandidate {
-							candidate,
-							validity_votes,
-							validator_indices,
+						ProvisionableData::BackedCandidate(CandidateReceipt {
+							descriptor,
+							..
 						})
 					)
-				) if candidate == candidate_a => {
-					assert_eq!(validity_votes.len(), 3);
-
-					assert!(validity_votes.contains(
-						&ValidityAttestation::Implicit(signed_a.signature().clone())
-					));
-					assert!(validity_votes.contains(
-						&ValidityAttestation::Explicit(signed_b.signature().clone())
-					));
-					assert!(validity_votes.contains(
-						&ValidityAttestation::Explicit(signed_c.signature().clone())
-					));
-					assert_eq!(validator_indices, bitvec::bitvec![Lsb0, u8; 1, 0, 1, 1]);
-				}
+				) if descriptor == candidate_a.descriptor
+			);
+
+			let (tx, rx) = oneshot::channel();
+			let msg = CandidateBackingMessage::GetBackedCandidates(
+				test_state.relay_parent,
+				vec![candidate_a.hash()],
+				tx,
 			);
 
+			virtual_overseer.send(FromOverseer::Communication{ msg }).await;
+
+			let candidates = rx.await.unwrap();
+			assert_eq!(1, candidates.len());
+			assert_eq!(candidates[0].validity_votes.len(), 3);
+
+			assert!(candidates[0].validity_votes.contains(
+				&ValidityAttestation::Implicit(signed_a.signature().clone())
+			));
+			assert!(candidates[0].validity_votes.contains(
+				&ValidityAttestation::Explicit(signed_b.signature().clone())
+			));
+			assert!(candidates[0].validity_votes.contains(
+				&ValidityAttestation::Explicit(signed_c.signature().clone())
+			));
+			assert_eq!(candidates[0].validator_indices, bitvec::bitvec![Lsb0, u8; 1, 0, 1, 1]);
+
 			virtual_overseer.send(FromOverseer::Signal(
 				OverseerSignal::ActiveLeaves(ActiveLeavesUpdate::stop_work(test_state.relay_parent)))
 			).await;
diff --git a/polkadot/node/core/provisioner/src/lib.rs b/polkadot/node/core/provisioner/src/lib.rs
index be3f38ba1ea..4e985a26220 100644
--- a/polkadot/node/core/provisioner/src/lib.rs
+++ b/polkadot/node/core/provisioner/src/lib.rs
@@ -17,7 +17,7 @@
 //! The provisioner is responsible for assembling a relay chain block
 //! from a set of available parachain candidates of its choice.
 
-#![deny(missing_docs, unused_crate_dependencies, unused_results)]
+#![deny(missing_docs, unused_crate_dependencies)]
 
 use bitvec::vec::BitVec;
 use futures::{
@@ -455,8 +455,8 @@ async fn select_candidates(
 	// maps to either 0 or 1 backed candidate, and the hashes correspond. Therefore, by checking them
 	// in order, we can ensure that the backed candidates are also in order.
 	let mut backed_idx = 0;
-	for selected in selected_candidates.iter() {
-		if *selected == candidates.get(backed_idx).ok_or(Error::BackedCandidateOrderingProblem)?.hash() {
+	for selected in selected_candidates {
+		if selected == candidates.get(backed_idx).ok_or(Error::BackedCandidateOrderingProblem)?.hash() {
 			backed_idx += 1;
 		}
 	}
diff --git a/polkadot/node/core/provisioner/src/tests.rs b/polkadot/node/core/provisioner/src/tests.rs
index 1cfe0cf29fc..cc3750591ee 100644
--- a/polkadot/node/core/provisioner/src/tests.rs
+++ b/polkadot/node/core/provisioner/src/tests.rs
@@ -192,13 +192,13 @@ mod select_availability_bitfields {
 mod select_candidates {
 	use futures_timer::Delay;
 	use super::super::*;
-	use super::{build_occupied_core, default_bitvec, occupied_core, scheduled_core};
+	use super::{build_occupied_core, occupied_core, scheduled_core, default_bitvec};
 	use polkadot_node_subsystem::messages::{
 		AllMessages, RuntimeApiMessage,
 		RuntimeApiRequest::{AvailabilityCores, PersistedValidationData as PersistedValidationDataReq},
 	};
 	use polkadot_primitives::v1::{
-		BlockNumber, CandidateDescriptor, CommittedCandidateReceipt, PersistedValidationData,
+		BlockNumber, CandidateDescriptor, PersistedValidationData, CommittedCandidateReceipt, CandidateCommitments,
 	};
 
 	const BLOCK_UNDER_PRODUCTION: BlockNumber = 128;
@@ -297,7 +297,7 @@ mod select_candidates {
 		]
 	}
 
-	async fn mock_overseer(mut receiver: mpsc::Receiver<FromJobCommand>) {
+	async fn mock_overseer(mut receiver: mpsc::Receiver<FromJobCommand>, expected: Vec<BackedCandidate>) {
 		use ChainApiMessage::BlockNumber;
 		use RuntimeApiMessage::Request;
 
@@ -313,8 +313,12 @@ mod select_candidates {
 				FromJobCommand::SendMessage(AllMessages::RuntimeApi(Request(_parent_hash, AvailabilityCores(tx)))) => {
 					tx.send(Ok(mock_availability_cores())).unwrap()
 				}
-				// non-exhaustive matches are fine for testing
-				_ => unimplemented!(),
+				FromJobCommand::SendMessage(
+					AllMessages::CandidateBacking(CandidateBackingMessage::GetBackedCandidates(_, _, sender))
+				) => {
+					let _ = sender.send(expected.clone());
+				}
+				_ => panic!("Unexpected message: {:?}", from_job),
 			}
 		}
 	}
@@ -341,10 +345,8 @@ mod select_candidates {
 
 	#[test]
 	fn can_succeed() {
-		test_harness(mock_overseer, |mut tx: mpsc::Sender<FromJobCommand>| async move {
-			let result = select_candidates(&[], &[], &[], Default::default(), &mut tx).await;
-			println!("{:?}", result);
-			assert!(result.is_ok());
+		test_harness(|r| mock_overseer(r, Vec::new()), |mut tx: mpsc::Sender<FromJobCommand>| async move {
+			select_candidates(&[], &[], &[], Default::default(), &mut tx).await.unwrap();
 		})
 	}
 
@@ -358,23 +360,19 @@ mod select_candidates {
 
 		let empty_hash = PersistedValidationData::<BlockNumber>::default().hash();
 
-		let candidate_template = BackedCandidate {
-			candidate: CommittedCandidateReceipt {
-				descriptor: CandidateDescriptor {
-					persisted_validation_data_hash: empty_hash,
-					..Default::default()
-				},
+		let candidate_template = CandidateReceipt {
+			descriptor: CandidateDescriptor {
+				persisted_validation_data_hash: empty_hash,
 				..Default::default()
 			},
-			validity_votes: Vec::new(),
-			validator_indices: default_bitvec(n_cores),
+			commitments_hash: CandidateCommitments::default().hash(),
 		};
 
 		let candidates: Vec<_> = std::iter::repeat(candidate_template)
 			.take(mock_cores.len())
 			.enumerate()
 			.map(|(idx, mut candidate)| {
-				candidate.candidate.descriptor.para_id = idx.into();
+				candidate.descriptor.para_id = idx.into();
 				candidate
 			})
 			.cycle()
@@ -386,12 +384,12 @@ mod select_candidates {
 					candidate
 				} else if idx < mock_cores.len() * 2 {
 					// for the second repetition of the candidates, give them the wrong hash
-					candidate.candidate.descriptor.persisted_validation_data_hash
+					candidate.descriptor.persisted_validation_data_hash
 						= Default::default();
 					candidate
 				} else {
 					// third go-around: right hash, wrong para_id
-					candidate.candidate.descriptor.para_id = idx.into();
+					candidate.descriptor.para_id = idx.into();
 					candidate
 				}
 			})
@@ -403,15 +401,28 @@ mod select_candidates {
 			.map(|&idx| candidates[idx].clone())
 			.collect();
 
-		test_harness(mock_overseer, |mut tx: mpsc::Sender<FromJobCommand>| async move {
+		let expected_backed = expected_candidates
+			.iter()
+			.map(|c| BackedCandidate {
+				candidate: CommittedCandidateReceipt { descriptor: c.descriptor.clone(), ..Default::default() },
+				validity_votes: Vec::new(),
+				validator_indices: default_bitvec(n_cores),
+			})
+			.collect();
+
+		test_harness(|r| mock_overseer(r, expected_backed), |mut tx: mpsc::Sender<FromJobCommand>| async move {
 			let result =
 				select_candidates(&mock_cores, &[], &candidates, Default::default(), &mut tx)
-					.await;
-
-			if result.is_err() {
-				println!("{:?}", result);
-			}
-			assert_eq!(result.unwrap(), expected_candidates);
+					.await.unwrap();
+
+			result.into_iter()
+				.for_each(|c|
+					assert!(
+						expected_candidates.iter().any(|c2| c.candidate.corresponds_to(c2)),
+						"Failed to find candidate: {:?}",
+						c,
+					)
+				);
 		})
 	}
 }
diff --git a/polkadot/node/overseer/src/lib.rs b/polkadot/node/overseer/src/lib.rs
index 661ef79b063..bbd9f626fe3 100644
--- a/polkadot/node/overseer/src/lib.rs
+++ b/polkadot/node/overseer/src/lib.rs
@@ -2165,7 +2165,7 @@ mod tests {
 
 	fn test_candidate_backing_msg() -> CandidateBackingMessage {
 		let (sender, _) = oneshot::channel();
-		CandidateBackingMessage::GetBackedCandidates(Default::default(), sender)
+		CandidateBackingMessage::GetBackedCandidates(Default::default(), Vec::new(), sender)
 	}
 
 	fn test_candidate_selection_msg() -> CandidateSelectionMessage {
diff --git a/polkadot/node/test/service/tests/build-blocks.rs b/polkadot/node/test/service/tests/build-blocks.rs
index 777f266a03a..bad22e7f0ff 100644
--- a/polkadot/node/test/service/tests/build-blocks.rs
+++ b/polkadot/node/test/service/tests/build-blocks.rs
@@ -21,7 +21,7 @@ use sp_keyring::Sr25519Keyring;
 
 #[substrate_test_utils::test]
 async fn ensure_test_service_build_blocks(task_executor: TaskExecutor) {
-	sc_cli::init_logger("", Default::default(), None).expect("Sets up logger");
+	sc_cli::init_logger("", Default::default(), None, false).expect("Sets up logger");
 
 	let mut alice = run_validator_node(
 		task_executor.clone(),
diff --git a/polkadot/primitives/src/v1.rs b/polkadot/primitives/src/v1.rs
index 1b469806840..3985254028c 100644
--- a/polkadot/primitives/src/v1.rs
+++ b/polkadot/primitives/src/v1.rs
@@ -231,6 +231,11 @@ impl<H: Clone> CommittedCandidateReceipt<H> {
 	pub fn hash(&self) -> CandidateHash where H: Encode {
 		self.to_plain().hash()
 	}
+
+	/// Does this committed candidate receipt corrensponds to the given [`CandidateReceipt`]?
+	pub fn corresponds_to(&self, receipt: &CandidateReceipt<H>) -> bool where H: PartialEq {
+		receipt.descriptor == self.descriptor && receipt.commitments_hash == self.commitments.hash()
+	}
 }
 
 impl PartialOrd for CommittedCandidateReceipt {
diff --git a/polkadot/scripts/gitlab/test_linux_stable.sh b/polkadot/scripts/gitlab/test_linux_stable.sh
index 17f5c80a72a..b841d8abecf 100755
--- a/polkadot/scripts/gitlab/test_linux_stable.sh
+++ b/polkadot/scripts/gitlab/test_linux_stable.sh
@@ -1,4 +1,5 @@
 #!/usr/bin/env bash
+set -e
 
 #shellcheck source=lib.sh
 source "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/lib.sh"
-- 
GitLab