streaming_crypto/core_api/benchmarks/
bench_utils.rs1
2use chrono::{Utc};
3use rand::Rng; use rand::RngCore;
5use std::fs::File;
6use std::io::BufWriter;
7use std::io::{Write};
8use std::io::{Read};
9use std::path::Path;
10use std::path::PathBuf;
11use sysinfo::{System, ProcessesToUpdate}; use async_stream::stream;
13use futures::Stream;
14
15use crate::stream_v2::core::MasterKey;
16
17pub fn dummy_master_key() -> MasterKey {
18 MasterKey::new(vec![0x11u8; 32]) }
20
21pub fn get_timestamp() -> String {
23 Utc::now().to_rfc3339()
24}
25
26pub fn random_bytes(n: usize) -> Vec<u8> {
28 let mut buf = vec![0u8; n];
29 rand::thread_rng().fill_bytes(&mut buf);
30 buf
31}
32
33pub fn measure_memory_mb() -> f64 {
36 let mut sys = System::new_all();
37
38 sys.refresh_processes(ProcessesToUpdate::All, true);
40
41 if let Ok(pid) = sysinfo::get_current_pid() {
42 if let Some(proc) = sys.process(pid) {
43 return proc.memory() as f64 / 1024.0; }
46 }
47 0.0
48}
49
50
51pub fn measure_cpu_percent(duration_sec: f64) -> f64 {
54 let mut sys = System::new();
55 sys.refresh_cpu_usage();
56
57 let _ = sys.global_cpu_usage();
59
60 std::thread::sleep(std::time::Duration::from_secs_f64(duration_sec));
62
63 sys.refresh_cpu_usage();
65 sys.global_cpu_usage() as f64
66}
67
68
69
70pub fn random_chunk_source(total_bytes: usize, max_chunk: usize) -> impl Iterator<Item = Vec<u8>> {
72 let mut remaining = total_bytes;
73 std::iter::from_fn(move || {
74 if remaining == 0 {
75 None
76 } else {
77 let n = remaining.min(max_chunk);
78 remaining -= n;
79 Some(random_bytes(n))
80 }
81 })
82}
83
84pub fn random_chunk_source_async(total_bytes: usize, max_chunk: usize) -> impl Stream<Item = Vec<u8>> {
86 stream! {
87 let mut remaining = total_bytes;
88 while remaining > 0 {
89 let n = remaining.min(max_chunk);
90 remaining -= n;
91 yield random_bytes(n);
92 }
93 }
94}
95
96pub fn fragmented_source(data: &[u8], min_frag: usize, max_frag: usize) -> impl Iterator<Item = Vec<u8>> + '_ {
99 let mut pos = 0;
100 std::iter::from_fn(move || {
101 if pos >= data.len() {
102 None
103 } else {
104 let frag = rand::thread_rng().gen_range(min_frag..=max_frag);
106 let end = (pos + frag).min(data.len());
107 let chunk = data[pos..end].to_vec();
108 pos = end;
109 Some(chunk)
110 }
111 })
112}
113
114
115pub fn fragmented_source_async<'a>(data: &'a [u8], min_frag: usize, max_frag: usize) -> impl Stream<Item = Vec<u8>> + 'a {
117 stream! {
118 let mut pos = 0;
119 while pos < data.len() {
120 let frag = rand::thread_rng().gen_range(min_frag..=max_frag);
121 let end = (pos + frag).min(data.len());
122 let chunk = data[pos..end].to_vec();
123 pos = end;
124 yield chunk;
125 }
126 }
127}
128
129pub fn sync_file_reader(path: &Path, chunk_size: usize) -> impl Iterator<Item = Vec<u8>> {
131 let mut file = File::open(path).expect("file not found");
132 std::iter::from_fn(move || {
133 let mut buf = vec![0u8; chunk_size];
134 match file.read(&mut buf) {
135 Ok(0) => None,
136 Ok(n) => Some(buf[..n].to_vec()),
137 Err(_) => None,
138 }
139 })
140}
141
142pub fn safe_cleanup_sync<T: ?Sized>(obj: &T)
160where
161 T: Cleanup,
162{
163 obj.cleanup();
164}
165
166pub async fn safe_cleanup_async<T: ?Sized>(obj: &T)
168where
169 T: AsyncCleanup,
170{
171 obj.cleanup().await;
172}
173
174pub trait Cleanup {
176 fn cleanup(&self);
177}
178
179#[async_trait::async_trait]
181pub trait AsyncCleanup {
182 async fn cleanup(&self);
183}
184
185pub fn safe_remove(path: &Path) {
187 let _ = std::fs::remove_file(path);
188}
189
190pub fn create_plain_file(path: &str, size_bytes: usize) {
192 let file = File::create(path).expect("Unable to create file");
193 let mut writer = BufWriter::new(file);
194 let data = random_bytes(1024); let mut written = 0;
196
197 while written < size_bytes {
198 let remaining = size_bytes - written;
199 let chunk = if remaining < data.len() {
200 &data[..remaining]
201 }
202 else {
203 &data
204 };
205 writer.write_all(chunk).expect("Write failed");
206 written += chunk.len();
207 }
208 writer.flush().expect("Flush failed");
209}
210
211pub fn cleanup_file(path: Option<PathBuf>) {
212 if let Some(p) = path {
213 if p.exists() {
214 if let Err(e) = std::fs::remove_file(&p) {
215 eprintln!("Failed to delete temp file {:?}: {}", p, e);
216 }
217 }
218 }
219}
220
221