Simultaenously build Docker images used in tests

This commit is contained in:
Luke Parker
2023-11-27 01:10:23 -05:00
parent 571195bfda
commit 292263b21e
23 changed files with 639 additions and 526 deletions

View File

@@ -1,5 +1,5 @@
#[test]
pub fn reproducibly_builds() {
#[tokio::test]
pub async fn reproducibly_builds() {
use std::{collections::HashSet, process::Command};
use rand_core::{RngCore, OsRng};
@@ -9,7 +9,7 @@ pub fn reproducibly_builds() {
const RUNS: usize = 3;
const TIMEOUT: u16 = 180 * 60; // 3 hours
serai_docker_tests::build("runtime".to_string());
serai_docker_tests::build("runtime".to_string()).await;
let mut ids = vec![[0; 8]; RUNS];
for id in &mut ids {
@@ -38,64 +38,66 @@ pub fn reproducibly_builds() {
);
}
test.run(|_| async {
let ids = ids;
let mut containers = vec![];
for container in String::from_utf8(
Command::new("docker").arg("ps").arg("--format").arg("{{.Names}}").output().unwrap().stdout,
)
.expect("output wasn't utf-8")
.lines()
{
for id in &ids {
if container.contains(&hex::encode(id)) {
containers.push(container.trim().to_string());
test
.run_async(|_| async {
let ids = ids;
let mut containers = vec![];
for container in String::from_utf8(
Command::new("docker").arg("ps").arg("--format").arg("{{.Names}}").output().unwrap().stdout,
)
.expect("output wasn't utf-8")
.lines()
{
for id in &ids {
if container.contains(&hex::encode(id)) {
containers.push(container.trim().to_string());
}
}
}
}
assert_eq!(containers.len(), RUNS, "couldn't find all containers");
assert_eq!(containers.len(), RUNS, "couldn't find all containers");
let mut res = vec![None; RUNS];
'attempt: for _ in 0 .. (TIMEOUT / 10) {
tokio::time::sleep(core::time::Duration::from_secs(10)).await;
let mut res = vec![None; RUNS];
'attempt: for _ in 0 .. (TIMEOUT / 10) {
tokio::time::sleep(core::time::Duration::from_secs(10)).await;
'runner: for (i, container) in containers.iter().enumerate() {
if res[i].is_some() {
continue;
'runner: for (i, container) in containers.iter().enumerate() {
if res[i].is_some() {
continue;
}
let logs = Command::new("docker").arg("logs").arg(container).output().unwrap();
let Some(last_log) =
std::str::from_utf8(&logs.stdout).expect("output wasn't utf-8").lines().last()
else {
continue 'runner;
};
let split = last_log.split("Runtime hash: ").collect::<Vec<_>>();
if split.len() == 2 {
res[i] = Some(split[1].to_string());
continue 'runner;
}
}
let logs = Command::new("docker").arg("logs").arg(container).output().unwrap();
let Some(last_log) =
std::str::from_utf8(&logs.stdout).expect("output wasn't utf-8").lines().last()
else {
continue 'runner;
};
let split = last_log.split("Runtime hash: ").collect::<Vec<_>>();
if split.len() == 2 {
res[i] = Some(split[1].to_string());
continue 'runner;
for item in &res {
if item.is_none() {
continue 'attempt;
}
}
break;
}
// If we didn't get results from all runners, panic
for item in &res {
if item.is_none() {
continue 'attempt;
panic!("couldn't get runtime hashes within allowed time");
}
}
break;
}
// If we didn't get results from all runners, panic
for item in &res {
if item.is_none() {
panic!("couldn't get runtime hashes within allowed time");
let mut identical = HashSet::new();
for res in res.clone() {
identical.insert(res.unwrap());
}
}
let mut identical = HashSet::new();
for res in res.clone() {
identical.insert(res.unwrap());
}
assert_eq!(identical.len(), 1, "got different runtime hashes {:?}", res);
});
assert_eq!(identical.len(), 1, "got different runtime hashes {:?}", res);
})
.await;
}