pathfinder_common/
test_utils.rs1use fake::{Dummy, Fake, Faker};
3use rand::Rng;
4
5pub fn fake_non_empty_with_rng<C, T>(rng: &mut impl Rng) -> C
8where
9 C: std::iter::FromIterator<T>,
10 T: Dummy<Faker>,
11{
12 let len = rng.gen_range(1..10);
13
14 std::iter::repeat_with(|| Faker.fake_with_rng(rng))
15 .take(len)
16 .collect()
17}
18
19pub mod metrics {
21 use std::borrow::Cow;
22 use std::collections::HashMap;
23 use std::sync::atomic::{AtomicU64, Ordering};
24 use std::sync::{Arc, RwLock};
25
26 use metrics::{
27 Counter,
28 CounterFn,
29 Gauge,
30 Histogram,
31 Key,
32 KeyName,
33 Label,
34 Metadata,
35 Recorder,
36 SharedString,
37 Unit,
38 };
39
40 #[derive(Debug, Default)]
44 pub struct FakeRecorder(FakeRecorderHandle);
45
46 #[derive(Clone, Debug, Default)]
49 pub struct FakeRecorderHandle {
50 counters: Arc<RwLock<HashMap<Key, Arc<FakeCounterFn>>>>,
51 methods: Option<&'static [&'static str]>,
52 }
53
54 #[derive(Debug, Default)]
55 struct FakeCounterFn(AtomicU64);
56
57 impl Recorder for FakeRecorder {
58 fn describe_counter(&self, _: KeyName, _: Option<Unit>, _: SharedString) {}
59 fn describe_gauge(&self, _: KeyName, _: Option<Unit>, _: SharedString) {}
60 fn describe_histogram(&self, _: KeyName, _: Option<Unit>, _: SharedString) {}
61
62 fn register_counter(&self, key: &Key, _metadata: &Metadata<'_>) -> Counter {
69 if self.is_key_used(key) {
70 let read_guard = self.0.counters.read().unwrap();
72 if let Some(counter) = read_guard.get(key) {
73 return Counter::from_arc(counter.clone());
75 }
76 drop(read_guard);
77 let mut write_guard = self.0.counters.write().unwrap();
80 let counter = write_guard.entry(key.clone()).or_default();
83 Counter::from_arc(counter.clone())
84 } else {
85 Counter::noop()
87 }
88 }
89
90 fn register_gauge(&self, _: &Key, _metadata: &Metadata<'_>) -> Gauge {
91 unimplemented!()
92 }
93 fn register_histogram(&self, _: &Key, _metadata: &Metadata<'_>) -> Histogram {
94 Histogram::noop()
96 }
97 }
98
99 impl FakeRecorder {
100 pub fn new_for(methods: &'static [&'static str]) -> Self {
105 Self(FakeRecorderHandle {
106 counters: Arc::default(),
107 methods: Some(methods),
108 })
109 }
110
111 pub fn handle(&self) -> FakeRecorderHandle {
113 self.0.clone()
114 }
115
116 fn is_key_used(&self, key: &Key) -> bool {
117 match self.0.methods {
118 Some(methods) => key.labels().any(|label| {
119 label.key() == "method" && methods.iter().any(|&method| method == label.value())
120 }),
121 None => true,
122 }
123 }
124 }
125
126 impl FakeRecorderHandle {
127 pub fn get_counter_value(
134 &self,
135 counter_name: &'static str,
136 method_name: impl Into<Cow<'static, str>>,
137 ) -> u64 {
138 let read_guard = self.counters.read().unwrap();
139 read_guard
140 .get(&Key::from_parts(
141 counter_name,
142 vec![Label::new("method", method_name.into())],
143 ))
144 .unwrap()
145 .0
146 .load(Ordering::Relaxed)
147 }
148
149 pub fn get_counter_value_by_label<const N: usize>(
154 &self,
155 counter_name: &'static str,
156 labels: [(&'static str, &'static str); N],
157 ) -> u64 {
158 let read_guard = self.counters.read().unwrap();
159 read_guard
160 .get(&Key::from_parts(
161 counter_name,
162 labels
163 .iter()
164 .map(|&(key, val)| Label::new(key, val))
165 .collect::<Vec<_>>(),
166 ))
167 .expect("Unregistered counter name")
168 .0
169 .load(Ordering::Relaxed)
170 }
171 }
172
173 impl CounterFn for FakeCounterFn {
174 fn increment(&self, val: u64) {
175 self.0.fetch_add(val, Ordering::Relaxed);
176 }
177 fn absolute(&self, _: u64) {
178 unimplemented!()
179 }
180 }
181}