vyre-conform 0.1.0

Conformance suite for vyre backends — proves byte-identical output to CPU reference
Documentation
use crate::spec::types::ParityFailure;
use std::fs;
use std::io::{self, Write};
use std::path::PathBuf;
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(loom)]
use loom::sync::Mutex as LoomMutex;
use super::hex::*;

/// Load regressions from all versions of an operation, including
/// legacy unversioned regressions and all versioned subdirectories.
///
/// This is the migration path: when version increments, regressions from
/// prior versions are still loaded and re-tested (they should still pass
/// under the new version if the change was backwards-compatible).
#[inline]
pub fn load_all_versions(op_id: &str) -> Vec<(String, Vec<u8>)> {
    #[cfg(loom)]
    {
        let store = LOOM_STORE.lock().unwrap();
        let mut results: Vec<_> = store
            .iter()
            .filter(|f| f.op_id == op_id)
            .map(|f| (f.input_label.clone(), f.input.clone()))
            .collect();
        results.sort_by(|a, b| a.0.cmp(&b.0));
        results
    }
    #[cfg(not(loom))]
    {
        let mut results = Vec::new();
        // Legacy unversioned regressions (before version migration was added).
        let legacy_dir = regression_dir(op_id);
        results.extend(load_from_dir(&legacy_dir, "legacy"));
        // Versioned regressions.
        if let Ok(entries) = fs::read_dir(&legacy_dir) {
            for entry in entries.flatten() {
                let path = entry.path();
                if path.is_dir() {
                    if let Some(name) = path.file_name().and_then(|n| n.to_str()) {
                        if name.starts_with('v') {
                            results.extend(load_from_dir(&path, name));
                        }
                    }
                }
            }
        }
        results.sort_by(|a, b| a.0.cmp(&b.0));
        results
    }
}