#[test] pub fn reproducibly_builds() { use std::{collections::HashSet, path::PathBuf, process::Command}; use rand_core::{RngCore, OsRng}; const RUNS: usize = 3; const TIMEOUT: u16 = 3 * 60 * 60; // 3 hours let mut images = vec![]; for _ in 0 .. RUNS { let mut image = [0; 32]; OsRng.fill_bytes(&mut image); images.push(format!("runtime-{}", hex::encode(image))); } let path = Command::new("cargo") .arg("locate-project") .arg("--workspace") .arg("--message-format") .arg("plain") .output() .unwrap(); assert!(path.status.success()); let mut path = PathBuf::from(String::from_utf8(path.stdout).unwrap().trim()); assert_eq!(path.file_name().unwrap(), "Cargo.toml"); assert!(path.pop()); let mut commands = vec![]; for image in &images { commands.push( Command::new("docker") .current_dir(&path) .arg("build") .arg("--progress") .arg("plain") .arg("--no-cache") .arg("--file") .arg("./orchestration/runtime/Dockerfile") .arg("--tag") .arg(image) .arg(".") .spawn() .unwrap(), ); } let mut outputs = vec![]; for (image, mut command) in images.into_iter().zip(commands) { assert!(command.wait().unwrap().success()); outputs.push( Command::new("docker") .arg("run") .arg("--quiet") .arg("--rm") .arg(&image) .arg("busybox") .arg("sha256sum") .arg("/serai.wasm") .output(), ); // Attempt to clean up the image let _ = Command::new("docker").arg("rmi").arg(&image).output(); } let mut expected = None; for output in outputs { let output = output.unwrap(); assert!(output.status.success()); if expected.is_none() { expected = Some(output.stdout.clone()); } assert_eq!(expected, Some(output.stdout)); } let result = String::from_utf8(expected.unwrap()).unwrap(); let hash = result.split_whitespace().next().unwrap(); // Check this appears to be a 32-byte hash (encoded as hex) assert_eq!(hash.len(), 64); hex::decode(hash).unwrap(); println!("Hash: {hash}"); }