#![cfg(any(cargo_difftests, docsrs))]
use std::collections::HashMap;
use std::ffi::{OsStr, OsString};
use std::path::{Path, PathBuf};
use cargo_difftests_core::CoreTestDesc;
#[cfg(cargo_difftests)]
extern "C" {
fn __llvm_profile_set_filename(filename: *const std::ffi::c_char);
}
#[cfg(all(not(cargo_difftests), docsrs))]
unsafe fn __llvm_profile_set_filename(_: *const std::ffi::c_char) {}
pub struct TestDesc {
pub pkg_name: String,
pub crate_name: String,
pub bin_name: Option<String>,
pub bin_path: PathBuf,
pub test_name: String,
pub other_fields: HashMap<String, String>,
}
pub struct DifftestsEnv {
llvm_profile_file_name: OsString,
llvm_profile_file_value: OsString,
}
impl DifftestsEnv {
pub fn env_for_children(&self) -> impl Iterator<Item = (&OsStr, &OsStr)> {
std::iter::once((
self.llvm_profile_file_name.as_os_str(),
self.llvm_profile_file_value.as_os_str(),
))
}
}
pub fn init(desc: TestDesc, tmpdir: &Path) -> std::io::Result<DifftestsEnv> {
if tmpdir.exists() {
std::fs::remove_dir_all(tmpdir)?;
}
std::fs::create_dir_all(tmpdir)?;
let self_profile_file =
tmpdir.join(cargo_difftests_core::CARGO_DIFFTESTS_SELF_PROFILE_FILENAME);
let self_profile_file_str = self_profile_file.to_str().unwrap();
std::fs::write(self_profile_file_str, "")?;
let self_profile_file_str_c = std::ffi::CString::new(self_profile_file_str).unwrap();
unsafe {
__llvm_profile_set_filename(self_profile_file_str_c.as_ptr());
}
let self_info_path = tmpdir.join(cargo_difftests_core::CARGO_DIFFTESTS_SELF_JSON_FILENAME);
let core_test_desc = CoreTestDesc {
pkg_name: desc.pkg_name,
crate_name: desc.crate_name,
bin_name: desc.bin_name,
bin_path: desc.bin_path,
test_name: desc.test_name,
other_fields: desc.other_fields,
};
let self_info = serde_json::to_string(&core_test_desc).unwrap();
std::fs::write(self_info_path, self_info)?;
std::fs::write(
tmpdir.join(cargo_difftests_core::CARGO_DIFFTESTS_VERSION_FILENAME),
env!("CARGO_PKG_VERSION"),
)?;
let profraw_path =
tmpdir.join(cargo_difftests_core::CARGO_DIFFTESTS_OTHER_PROFILE_FILENAME_TEMPLATE);
Ok(DifftestsEnv {
llvm_profile_file_name: "LLVM_PROFILE_FILE".into(),
llvm_profile_file_value: profraw_path.into(),
})
}