criterion_hypothesis_harness/
lib.rs1mod server;
8
9pub use server::{run_harness, run_harness_async};
10
11use std::collections::HashMap;
12use std::time::Duration;
13
14pub type BenchmarkFn = Box<dyn Fn(u64) -> Duration + Send + Sync>;
24
25pub struct BenchmarkRegistry {
30 benchmarks: HashMap<String, BenchmarkFn>,
31}
32
33impl BenchmarkRegistry {
34 pub fn new() -> Self {
36 Self {
37 benchmarks: HashMap::new(),
38 }
39 }
40
41 pub fn register<F>(&mut self, name: impl Into<String>, f: F)
59 where
60 F: Fn(u64) -> Duration + Send + Sync + 'static,
61 {
62 self.benchmarks.insert(name.into(), Box::new(f));
63 }
64
65 pub fn list(&self) -> Vec<String> {
67 self.benchmarks.keys().cloned().collect()
68 }
69
70 pub fn run(&self, name: &str, iterations: u64) -> Option<Duration> {
74 self.benchmarks.get(name).map(|f| f(iterations))
75 }
76
77 pub fn contains(&self, name: &str) -> bool {
79 self.benchmarks.contains_key(name)
80 }
81
82 pub fn len(&self) -> usize {
84 self.benchmarks.len()
85 }
86
87 pub fn is_empty(&self) -> bool {
89 self.benchmarks.is_empty()
90 }
91}
92
93impl Default for BenchmarkRegistry {
94 fn default() -> Self {
95 Self::new()
96 }
97}
98
99#[cfg(test)]
100mod tests {
101 use super::*;
102
103 #[test]
104 fn test_registry_new() {
105 let registry = BenchmarkRegistry::new();
106 assert!(registry.is_empty());
107 assert_eq!(registry.len(), 0);
108 }
109
110 #[test]
111 fn test_registry_register_and_list() {
112 let mut registry = BenchmarkRegistry::new();
113 registry.register("bench1", |_n| Duration::from_millis(10));
114 registry.register("bench2", |_n| Duration::from_millis(20));
115
116 assert_eq!(registry.len(), 2);
117 assert!(registry.contains("bench1"));
118 assert!(registry.contains("bench2"));
119 assert!(!registry.contains("bench3"));
120
121 let names = registry.list();
122 assert_eq!(names.len(), 2);
123 assert!(names.contains(&"bench1".to_string()));
124 assert!(names.contains(&"bench2".to_string()));
125 }
126
127 #[test]
128 fn test_registry_run_passes_iterations() {
129 use std::sync::atomic::{AtomicU64, Ordering};
130 use std::sync::Arc;
131
132 let observed = Arc::new(AtomicU64::new(0));
133 let observed_clone = Arc::clone(&observed);
134
135 let mut registry = BenchmarkRegistry::new();
136 registry.register("iter_echo", move |n| {
137 observed_clone.store(n, Ordering::SeqCst);
138 Duration::from_nanos(n * 100)
139 });
140
141 let result = registry.run("iter_echo", 42);
142 assert_eq!(result, Some(Duration::from_nanos(4200)));
143 assert_eq!(observed.load(Ordering::SeqCst), 42);
144 }
145
146 #[test]
147 fn test_registry_run_missing() {
148 let mut registry = BenchmarkRegistry::new();
149 registry.register("exists", |_n| Duration::from_millis(5));
150
151 assert!(registry.run("missing", 1).is_none());
152 }
153
154 #[test]
155 fn test_registry_default() {
156 let registry = BenchmarkRegistry::default();
157 assert!(registry.is_empty());
158 }
159}