1use rand::{prelude::*, rngs::ChaCha8Rng};
2use std::{collections::VecDeque, time::Duration};
3
4use upc::Class;
5
6pub const VID: u16 = 4;
7pub const PID: u16 = 5;
8
9pub const CLASS: Class = Class::vendor_specific(22, 3);
10pub const TOPIC: &[u8] = b"TEST TOPIC";
11pub const INFO: &[u8] = b"TEST INFO";
12
13pub const HOST_SEED: u64 = 12523;
14pub const DEVICE_SEED: u64 = 23152;
15pub const TEST_PACKETS: usize = 1_000;
16pub const TEST_PACKET_MAX_SIZE: usize = 1_000_000;
17
18pub const DELAY: bool = false;
19
20#[cfg(not(feature = "web"))]
21pub fn init_log() {
22 use std::sync::Once;
23 use tracing_subscriber::{fmt, prelude::*, EnvFilter};
24
25 static ONCE: Once = Once::new();
26 ONCE.call_once(|| {
27 tracing_subscriber::registry().with(fmt::layer()).with(EnvFilter::from_default_env()).init();
28 tracing_log::LogTracer::init().unwrap();
29 });
30}
31
32#[cfg(not(feature = "web"))]
33use tokio::time::sleep;
34
35#[cfg(feature = "web")]
36pub async fn sleep(duration: Duration) {
37 use js_sys::Promise;
38 use wasm_bindgen_futures::JsFuture;
39 use web_sys::window;
40
41 let ms = duration.as_millis() as i32;
42 let promise = Promise::new(&mut |resolve, _reject| {
43 let window = window().unwrap();
44 window.set_timeout_with_callback_and_timeout_and_arguments_0(&resolve, ms).unwrap();
45 });
46 JsFuture::from(promise).await.unwrap();
47}
48
49pub struct TestData {
50 rng: ChaCha8Rng,
51 max_length: usize,
52 pre_lengths: VecDeque<usize>,
53}
54
55impl TestData {
56 pub fn new(seed: u64, max_length: usize) -> Self {
57 Self {
58 rng: ChaCha8Rng::seed_from_u64(seed),
59 max_length,
60 pre_lengths: [
61 0,
62 1,
63 2,
64 3,
65 511,
66 512,
67 513,
68 1023,
69 1024,
70 1025,
71 0,
72 2000,
73 2048,
74 0,
75 4096,
76 5000,
77 8191,
78 8192,
79 8193,
80 0,
81 8193,
82 TEST_PACKET_MAX_SIZE,
83 ]
84 .into(),
85 }
86 }
87
88 pub fn generate(&mut self) -> Vec<u8> {
89 let len = match self.pre_lengths.pop_front() {
90 Some(len) => len,
91 None => self.rng.random_range(0..self.max_length),
92 };
93 let mut data = vec![0; len];
94 self.rng.fill_bytes(&mut data);
95 data
96 }
97
98 pub fn validate(&mut self, data: &[u8]) {
99 let expected = self.generate();
100 assert_eq!(data.len(), expected.len(), "data length mismatch");
101 assert_eq!(data, &expected, "data mismatch");
102 }
103}
104
105pub struct TestDelayer {
106 rng: ChaCha8Rng,
107}
108
109impl TestDelayer {
110 pub fn new(seed: u64) -> Self {
111 Self { rng: ChaCha8Rng::seed_from_u64(seed) }
112 }
113
114 pub async fn delay(&mut self) {
115 if !DELAY {
116 return;
117 }
118
119 if self.rng.random_ratio(1, 1000) {
120 let ms = self.rng.random_range(0..1000);
121 sleep(Duration::from_millis(ms)).await;
122 }
123 }
124}