#![cfg_attr(coverage_nightly, coverage(off))]
use std::sync::atomic::{AtomicU64, Ordering};
pub static EMBEDDING_SEED: AtomicU64 = AtomicU64::new(42);
pub static CLUSTERING_SEED: AtomicU64 = AtomicU64::new(12345);
pub static MUTATION_SEED: AtomicU64 = AtomicU64::new(98765);
pub fn set_embedding_seed(seed: u64) {
EMBEDDING_SEED.store(seed, Ordering::SeqCst);
}
pub fn get_embedding_seed() -> u64 {
EMBEDDING_SEED.load(Ordering::SeqCst)
}
pub fn set_clustering_seed(seed: u64) {
CLUSTERING_SEED.store(seed, Ordering::SeqCst);
}
pub fn get_clustering_seed() -> u64 {
CLUSTERING_SEED.load(Ordering::SeqCst)
}
pub fn set_mutation_seed(seed: u64) {
MUTATION_SEED.store(seed, Ordering::SeqCst);
}
pub fn get_mutation_seed() -> u64 {
MUTATION_SEED.load(Ordering::SeqCst)
}
pub fn init_seeds_from_env() {
if let Ok(seed) = std::env::var("PMAT_EMBEDDING_SEED") {
if let Ok(seed) = seed.parse::<u64>() {
set_embedding_seed(seed);
}
}
if let Ok(seed) = std::env::var("PMAT_CLUSTERING_SEED") {
if let Ok(seed) = seed.parse::<u64>() {
set_clustering_seed(seed);
}
}
if let Ok(seed) = std::env::var("PMAT_MUTATION_SEED") {
if let Ok(seed) = seed.parse::<u64>() {
set_mutation_seed(seed);
}
}
}
pub fn create_embedding_rng() -> rand::rngs::StdRng {
use rand::SeedableRng;
rand::rngs::StdRng::seed_from_u64(get_embedding_seed())
}
pub fn create_clustering_rng() -> rand::rngs::StdRng {
use rand::SeedableRng;
rand::rngs::StdRng::seed_from_u64(get_clustering_seed())
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod tests {
use super::*;
use serial_test::serial;
#[test]
#[serial]
fn test_seed_defaults() {
set_embedding_seed(42);
set_clustering_seed(12345);
set_mutation_seed(98765);
assert_eq!(get_embedding_seed(), 42);
assert_eq!(get_clustering_seed(), 12345);
assert_eq!(get_mutation_seed(), 98765);
}
#[test]
#[serial]
fn test_seed_modification() {
set_embedding_seed(100);
assert_eq!(get_embedding_seed(), 100);
set_embedding_seed(42);
}
#[test]
#[serial]
fn test_rng_reproducibility() {
use rand::Rng;
set_embedding_seed(42);
let mut rng1 = create_embedding_rng();
let val1: u64 = rng1.random();
set_embedding_seed(42);
let mut rng2 = create_embedding_rng();
let val2: u64 = rng2.random();
assert_eq!(val1, val2, "Same seed must produce same sequence");
}
#[test]
#[serial]
fn test_clustering_seed_modification() {
set_clustering_seed(999);
assert_eq!(get_clustering_seed(), 999);
set_clustering_seed(12345);
}
#[test]
#[serial]
fn test_mutation_seed_modification() {
set_mutation_seed(555);
assert_eq!(get_mutation_seed(), 555);
set_mutation_seed(98765);
}
#[test]
#[serial]
fn test_create_clustering_rng_reproducibility() {
use rand::Rng;
set_clustering_seed(777);
let mut rng1 = create_clustering_rng();
let val1: u64 = rng1.random();
set_clustering_seed(777);
let mut rng2 = create_clustering_rng();
let val2: u64 = rng2.random();
assert_eq!(val1, val2, "Same seed must produce same sequence");
set_clustering_seed(12345);
}
#[test]
#[serial]
fn test_different_seeds_produce_different_values() {
use rand::Rng;
set_embedding_seed(1);
let mut rng1 = create_embedding_rng();
let val1: u64 = rng1.random();
set_embedding_seed(2);
let mut rng2 = create_embedding_rng();
let val2: u64 = rng2.random();
assert_ne!(
val1, val2,
"Different seeds should produce different values"
);
set_embedding_seed(42);
}
#[test]
#[serial]
fn test_init_seeds_from_env_without_vars() {
std::env::remove_var("PMAT_EMBEDDING_SEED");
std::env::remove_var("PMAT_CLUSTERING_SEED");
std::env::remove_var("PMAT_MUTATION_SEED");
set_embedding_seed(42);
set_clustering_seed(12345);
set_mutation_seed(98765);
init_seeds_from_env();
assert_eq!(get_embedding_seed(), 42);
assert_eq!(get_clustering_seed(), 12345);
assert_eq!(get_mutation_seed(), 98765);
}
#[test]
#[serial]
fn test_init_seeds_from_env_with_vars() {
std::env::set_var("PMAT_EMBEDDING_SEED", "111");
std::env::set_var("PMAT_CLUSTERING_SEED", "222");
std::env::set_var("PMAT_MUTATION_SEED", "333");
init_seeds_from_env();
assert_eq!(get_embedding_seed(), 111);
assert_eq!(get_clustering_seed(), 222);
assert_eq!(get_mutation_seed(), 333);
std::env::remove_var("PMAT_EMBEDDING_SEED");
std::env::remove_var("PMAT_CLUSTERING_SEED");
std::env::remove_var("PMAT_MUTATION_SEED");
set_embedding_seed(42);
set_clustering_seed(12345);
set_mutation_seed(98765);
}
#[test]
#[serial]
fn test_init_seeds_from_env_with_invalid_values() {
set_embedding_seed(42);
std::env::set_var("PMAT_EMBEDDING_SEED", "not_a_number");
init_seeds_from_env();
assert_eq!(get_embedding_seed(), 42);
std::env::remove_var("PMAT_EMBEDDING_SEED");
}
#[test]
#[serial]
fn test_seed_boundary_values() {
set_embedding_seed(0);
assert_eq!(get_embedding_seed(), 0);
set_embedding_seed(u64::MAX);
assert_eq!(get_embedding_seed(), u64::MAX);
set_embedding_seed(42);
}
#[test]
#[serial]
fn test_all_rngs_independent() {
use rand::Rng;
set_embedding_seed(42);
set_clustering_seed(42);
let mut emb_rng = create_embedding_rng();
let mut clust_rng = create_clustering_rng();
let emb_val: u64 = emb_rng.random();
let clust_val: u64 = clust_rng.random();
assert_eq!(emb_val, clust_val);
set_clustering_seed(12345);
}
}