1use fidl_diagnostics_validate::{Action, LazyAction, LinkDisposition, ROOT_ID, Value, ValueType};
6
7pub enum Step {
8 Actions(Vec<Action>),
9 LazyActions(Vec<LazyAction>),
10 ActLazyThreadLocalActions(Vec<LazyAction>),
11 WithMetrics(Vec<Action>, String),
12}
13
14pub struct Trial {
15 pub name: String,
16 pub steps: Vec<Step>,
17}
18
19pub fn real_trials() -> Vec<Trial> {
20 vec![
21 basic_node(),
22 basic_int(),
23 basic_uint(),
24 basic_double(),
25 basic_string(),
26 basic_bytes(),
27 basic_bool(),
28 basic_int_array(),
29 basic_string_array(),
30 basic_uint_array(),
31 basic_double_array(),
32 int_histogram_ops_trial(),
33 uint_histogram_ops_trial(),
34 double_histogram_ops_trial(),
35 deletions_trial(),
36 lazy_nodes_trial(),
37 repeated_names(),
38 act_lazy_thread_local_trial(),
39 ]
40}
41
42fn act_lazy_thread_local_trial() -> Trial {
43 Trial {
44 name: "ActLazyThreadLocal".into(),
45 steps: vec![Step::ActLazyThreadLocalActions(vec![
46 crate::create_lazy_node!(
48 parent: ROOT_ID,
49 id: 1,
50 name: "child",
51 disposition: LinkDisposition::Child,
52 actions: vec![crate::create_bytes_property!(parent: ROOT_ID, id: 1, name: "child_bytes",value: vec!(3u8, 4u8))]
53 ),
54 crate::create_lazy_node!(
55 parent: ROOT_ID,
56 id: 2,
57 name: "child",
58 disposition: LinkDisposition::Child,
59 actions: vec![crate::create_bytes_property!(parent: ROOT_ID, id: 1, name: "child_bytes",value: vec!(3u8, 4u8))]
60 ),
61 crate::delete_lazy_node!(id: 1),
62 crate::delete_lazy_node!(id: 2),
63 crate::create_lazy_node!(
65 parent: ROOT_ID,
66 id: 1,
67 name: "child",
68 disposition: LinkDisposition::Child,
69 actions: vec![crate::create_bytes_property!(parent: ROOT_ID, id: 1, name: "child_bytes_new",value: vec!(1u8, 2u8))]
70 ),
71 crate::delete_lazy_node!(id: 1),
72 crate::create_lazy_node!(
74 parent: ROOT_ID,
75 id: 1,
76 name: "inline_child",
77 disposition: LinkDisposition::Inline,
78 actions: vec![crate::create_bytes_property!(parent: ROOT_ID, id: 1, name: "inline_child",value: vec!(1u8, 2u8))]
79 ),
80 crate::delete_lazy_node!(id: 1),
81 ])],
82 }
83}
84
85fn basic_node() -> Trial {
86 Trial {
87 name: "Basic Node".into(),
88 steps: vec![Step::Actions(vec![
89 crate::create_node!(parent: ROOT_ID, id: 1, name: "child"),
90 crate::create_node!(parent: 1, id: 2, name: "grandchild"),
91 crate::delete_node!( id: 2),
92 crate::delete_node!( id: 1 ),
93 crate::create_node!(parent: ROOT_ID, id: 1, name: "child"),
95 crate::create_node!(parent: 1, id: 2, name: "grandchild"),
96 crate::delete_node!( id: 1),
97 crate::delete_node!( id: 2 ),
98 ])],
99 }
100}
101
102fn basic_string() -> Trial {
103 Trial {
104 name: "Basic String".into(),
105 steps: vec![Step::Actions(vec![
106 crate::create_string_property!(parent: ROOT_ID, id:1, name: "str", value: "foo"),
107 crate::set_string!(id: 1, value: "bar"),
108 crate::set_string!(id: 1, value: "This Is A Longer String"),
109 crate::set_string!(id: 1, value: "."),
110 crate::set_string!(id: 1, value: ["1234567890"; 300].to_vec().join("")),
112 crate::delete_property!(id: 1),
113 ])],
114 }
115}
116
117fn basic_bytes() -> Trial {
118 Trial {
119 name: "Basic bytes".into(),
120 steps: vec![Step::Actions(vec![
121 crate::create_bytes_property!(parent: ROOT_ID, id: 8, name: "bytes", value: vec![1u8, 2u8]),
122 crate::set_bytes!(id: 8, value: vec![3u8, 4, 5, 6, 7]),
123 crate::set_bytes!(id: 8, value: vec![8u8]),
124 crate::delete_property!(id: 8),
125 ])],
126 }
127}
128
129fn basic_bool() -> Trial {
130 Trial {
131 name: "Basic Bool".into(),
132 steps: vec![Step::Actions(vec![
133 crate::create_bool_property!(parent: ROOT_ID, id: 1, name: "bool", value: true),
134 crate::set_bool!(id: 1, value: false),
135 crate::set_bool!(id: 1, value: true),
136 crate::delete_property!(id: 1),
137 ])],
138 }
139}
140
141fn basic_int() -> Trial {
142 Trial {
143 name: "Basic Int".into(),
144 steps: vec![Step::Actions(vec![
145 crate::create_numeric_property!(parent: ROOT_ID, id: 5, name: "int", value: Value::IntT(10)),
146 crate::set_number!(id: 5, value: Value::IntT(i64::MAX)),
147 crate::subtract_number!(id: 5, value: Value::IntT(3)),
148 crate::set_number!(id: 5, value: Value::IntT(i64::MIN)),
149 crate::add_number!(id: 5, value: Value::IntT(2)),
150 crate::delete_property!(id: 5),
151 ])],
152 }
153}
154
155fn basic_uint() -> Trial {
156 Trial {
157 name: "Basic Uint".into(),
158 steps: vec![Step::Actions(vec![
159 crate::create_numeric_property!(parent: ROOT_ID, id: 5, name: "uint", value: Value::UintT(1)),
160 crate::set_number!(id: 5, value: Value::UintT(u64::MAX)),
161 crate::subtract_number!(id: 5, value: Value::UintT(3)),
162 crate::set_number!(id: 5, value: Value::UintT(0)),
163 crate::add_number!(id: 5, value: Value::UintT(2)),
164 crate::delete_property!(id: 5),
165 ])],
166 }
167}
168
169fn basic_double() -> Trial {
170 Trial {
171 name: "Basic Double".into(),
172 steps: vec![Step::Actions(vec![
173 crate::create_numeric_property!(parent: ROOT_ID, id: 5, name: "double",
174 value: Value::DoubleT(1.0)),
175 crate::set_number!(id: 5, value: Value::DoubleT(f64::MAX)),
176 crate::subtract_number!(id: 5, value: Value::DoubleT(f64::MAX/10_f64)),
177 crate::set_number!(id: 5, value: Value::DoubleT(f64::MIN)),
178 crate::add_number!(id: 5, value: Value::DoubleT(f64::MAX / 10_f64)),
179 crate::delete_property!(id: 5),
180 ])],
181 }
182}
183
184fn repeated_names() -> Trial {
185 let mut actions = vec![crate::create_node!(parent: ROOT_ID, id: 1, name: "measurements")];
186
187 for i in 100..120 {
188 actions.push(crate::create_node!(parent: 1, id: i, name: format!("{}", i)));
189 actions.push(crate::create_numeric_property!(parent: i, id: i + 1000, name: "count", value: Value::UintT(i as u64 * 2)));
190 actions.push(crate::create_numeric_property!(parent: i, id: i + 2000, name: "time_spent", value: Value::UintT(i as u64 * 1000 + 10)));
191 }
192
193 Trial {
194 name: "Many repeated names".into(),
195 steps: vec![Step::WithMetrics(actions, "Many repeated names".into())],
196 }
197}
198
199fn array_indexes_to_test() -> Vec<u64> {
200 let mut ret: Vec<u64> = (0..10).collect();
201 ret.push(1000);
202 ret.push(10000);
203 ret.push(u64::MAX);
204 ret
205}
206
207fn basic_int_array() -> Trial {
208 let mut actions =
209 vec![crate::create_array_property!(parent: ROOT_ID, id: 5, name: "int", slots: 5,
210 type: ValueType::Int)];
211 for index in array_indexes_to_test().iter() {
212 actions.push(crate::array_add!(id: 5, index: *index, value: Value::IntT(7)));
213 actions.push(crate::array_subtract!(id: 5, index: *index, value: Value::IntT(3)));
214 actions.push(crate::array_set!(id: 5, index: *index, value: Value::IntT(19)));
215 }
216 actions.push(crate::delete_property!(id: 5));
217 Trial { name: "Int Array Ops".into(), steps: vec![Step::Actions(actions)] }
218}
219
220fn basic_string_array() -> Trial {
221 const ID: u32 = 5;
222 let mut actions = vec![
223 crate::create_array_property!(parent: ROOT_ID, id: ID, name: "string", slots: 5, type: ValueType::String),
224 ];
225
226 for index in array_indexes_to_test().iter() {
227 if (*index).is_multiple_of(2) {
228 actions
229 .push(crate::array_set!(id: ID, index: *index, value: Value::StringT(format!("string data {}", *index))));
230 } else if (*index).is_multiple_of(3) {
231 actions.push(
232 crate::array_set!(id: ID, index: *index, value: Value::StringT(String::new())),
233 );
234 } else {
235 actions.push(
236 crate::array_set!(id: ID, index: *index, value: Value::StringT("string data".into())),
237 );
238 }
239 }
240
241 for index in array_indexes_to_test().iter() {
242 if (*index).is_multiple_of(2) {
243 actions
244 .push(crate::array_set!(id: ID, index: *index, value: Value::StringT("".into())));
245 }
246 }
247
248 for index in array_indexes_to_test().iter() {
249 if (*index).is_multiple_of(4) {
250 actions.push(
251 crate::array_set!(id: ID, index: *index, value: Value::StringT(format!("{}", *index))),
252 );
253 }
254 }
255
256 actions.push(crate::delete_property!(id: ID));
257 Trial { name: "String Array Ops".into(), steps: vec![Step::Actions(actions)] }
258}
259
260fn basic_uint_array() -> Trial {
261 let mut actions =
262 vec![crate::create_array_property!(parent: ROOT_ID, id: 6, name: "uint", slots: 5,
263 type: ValueType::Uint)];
264 for index in array_indexes_to_test().iter() {
265 actions.push(crate::array_add!(id: 6, index: *index, value: Value::UintT(11)));
266 actions.push(crate::array_subtract!(id: 6, index: *index, value: Value::UintT(3)));
267 actions.push(crate::array_set!(id: 6, index: *index, value: Value::UintT(19)));
268 }
269 actions.push(crate::delete_property!(id: 6));
270 Trial { name: "Unt Array Ops".into(), steps: vec![Step::Actions(actions)] }
271}
272
273fn basic_double_array() -> Trial {
274 let mut actions =
275 vec![crate::create_array_property!(parent: ROOT_ID, id: 4, name: "float", slots: 5,
276 type: ValueType::Double)];
277 for index in array_indexes_to_test().iter() {
278 actions.push(crate::array_add!(id: 4, index: *index, value: Value::DoubleT(2.0)));
279 actions.push(crate::array_subtract!(id: 4, index: *index, value: Value::DoubleT(3.5)));
280 actions.push(crate::array_set!(id: 4, index: *index, value: Value::DoubleT(19.0)));
281 }
282 actions.push(crate::delete_property!(id: 4));
283 Trial { name: "Int Array Ops".into(), steps: vec![Step::Actions(actions)] }
284}
285
286fn int_histogram_ops_trial() -> Trial {
287 fn push_ops(actions: &mut Vec<Action>, value: i64) {
288 actions.push(crate::insert!(id: 4, value: Value::IntT(value)));
289 actions.push(crate::insert_multiple!(id: 4, value: Value::IntT(value), count: 3));
290 actions.push(crate::insert!(id: 5, value: Value::IntT(value)));
291 actions.push(crate::insert_multiple!(id: 5, value: Value::IntT(value), count: 3));
292 }
293 let mut actions = vec![
294 crate::create_linear_histogram!(parent: ROOT_ID, id: 4, name: "Lhist", floor: -5,
295 step_size: 3, buckets: 3, type: IntT),
296 crate::create_exponential_histogram!(parent: ROOT_ID, id: 5, name: "Ehist", floor: -5,
297 initial_step: 2, step_multiplier: 4,
298 buckets: 3, type: IntT),
299 ];
300 for value in [i64::MIN, i64::MAX, 0] {
301 push_ops(&mut actions, value);
302 }
303 for value in [-10_i64, -5_i64, 0_i64, 3_i64, 100_i64] {
304 push_ops(&mut actions, value);
305 }
306 actions.push(crate::delete_property!(id: 4));
307 actions.push(crate::delete_property!(id: 5));
308 Trial { name: "Int Histogram Ops".into(), steps: vec![Step::Actions(actions)] }
309}
310
311fn uint_histogram_ops_trial() -> Trial {
312 fn push_ops(actions: &mut Vec<Action>, value: u64) {
313 actions.push(crate::insert!(id: 4, value: Value::UintT(value)));
314 actions.push(crate::insert_multiple!(id: 4, value: Value::UintT(value), count: 3));
315 actions.push(crate::insert!(id: 5, value: Value::UintT(value)));
316 actions.push(crate::insert_multiple!(id: 5, value: Value::UintT(value), count: 3));
317 }
318 let mut actions = vec![
319 crate::create_linear_histogram!(parent: ROOT_ID, id: 4, name: "Lhist", floor: 5,
320 step_size: 3, buckets: 3, type: UintT),
321 crate::create_exponential_histogram!(parent: ROOT_ID, id: 5, name: "Ehist", floor: 5,
322 initial_step: 2, step_multiplier: 4,
323 buckets: 3, type: UintT),
324 ];
325 for value in [u64::MAX, 0] {
326 push_ops(&mut actions, value);
327 }
328 for value in [0_u64, 5_u64, 8_u64, 20u64, 200_u64] {
329 push_ops(&mut actions, value);
330 }
331 actions.push(crate::delete_property!(id: 4));
332 actions.push(crate::delete_property!(id: 5));
333 Trial { name: "Uint Histogram Ops".into(), steps: vec![Step::Actions(actions)] }
334}
335
336fn double_histogram_ops_trial() -> Trial {
337 fn push_ops(actions: &mut Vec<Action>, value: f64) {
338 actions.push(crate::insert!(id: 4, value: Value::DoubleT(value)));
339 actions.push(crate::insert_multiple!(id: 4, value: Value::DoubleT(value), count: 3));
340 actions.push(crate::insert!(id: 5, value: Value::DoubleT(value)));
341 actions.push(crate::insert_multiple!(id: 5, value: Value::DoubleT(value), count: 3));
342 }
343 let mut actions = vec![
344 crate::create_exponential_histogram!(parent: ROOT_ID, id: 5, name: "Ehist",
347 floor: std::f64::consts::PI, initial_step: 2.0,
348 step_multiplier: 4.0, buckets: 3, type: DoubleT),
349 crate::create_linear_histogram!(parent: ROOT_ID, id: 4, name: "Lhist", floor: 5.0,
350 step_size: 3.0, buckets: 3, type: DoubleT),
351 ];
352 for value in &[f64::MIN, f64::MAX, f64::MIN_POSITIVE, 0.0] {
353 push_ops(&mut actions, *value);
354 }
355 for value in [3.0, 3.15, 5.0, 10.0] {
356 push_ops(&mut actions, value);
357 }
358 actions.push(crate::delete_property!(id: 4));
359 actions.push(crate::delete_property!(id: 5));
360 Trial { name: "Double Histogram Ops".into(), steps: vec![Step::Actions(actions)] }
361}
362
363fn deletions_trial() -> Trial {
364 fn n1() -> Action {
367 crate::create_node!(parent: ROOT_ID, id: 1, name: "root_child")
368 }
369 fn n2() -> Action {
370 crate::create_node!(parent: 1, id: 2, name: "parent")
371 }
372 fn n3() -> Action {
373 crate::create_node!(parent: 2, id: 3, name: "child")
374 }
375 fn p1() -> Action {
376 crate::create_numeric_property!(parent: 1, id: 4, name: "root_int", value: Value::IntT(1))
377 }
378 fn p2() -> Action {
379 crate::create_numeric_property!(parent: 2, id: 5, name: "parent_int", value: Value::IntT(2))
380 }
381 fn p3() -> Action {
382 crate::create_numeric_property!(parent: 3, id: 6, name: "child_int", value: Value::IntT(3))
383 }
384 fn create() -> Vec<Action> {
385 vec![n1(), n2(), n3(), p1(), p2(), p3()]
386 }
387 fn create2() -> Vec<Action> {
388 vec![n1(), p1(), n2(), p2(), n3(), p3()]
389 }
390 fn d1() -> Action {
391 crate::delete_node!(id: 1)
392 }
393 fn d2() -> Action {
394 crate::delete_node!(id: 2)
395 }
396 fn d3() -> Action {
397 crate::delete_node!(id: 3)
398 }
399 fn x1() -> Action {
400 crate::delete_property!(id: 4)
401 }
402 fn x2() -> Action {
403 crate::delete_property!(id: 5)
404 }
405 fn x3() -> Action {
406 crate::delete_property!(id: 6)
407 }
408 let steps = vec![
409 Step::Actions(create()),
410 Step::Actions(vec![d3(), d2(), d1(), x3(), x2(), x1()]),
411 Step::Actions(create2()),
412 Step::WithMetrics(vec![d1(), d2()], "Delete Except Grandchild".into()),
413 Step::WithMetrics(vec![d3(), x3(), x2(), x1()], "Deleted Grandchild".into()),
414 Step::Actions(create()),
417 Step::Actions(vec![d1(), d2(), d3(), x3(), x2(), x1()]),
418 Step::Actions(create2()),
419 Step::Actions(vec![d1(), x3(), d2(), x1(), d3(), x2()]),
420 Step::Actions(create()),
421 Step::Actions(vec![d1(), x2(), d3(), x3(), d2(), x1()]),
422 Step::Actions(create2()),
423 Step::Actions(vec![x1(), x3(), d2(), d1(), d3(), x2()]),
424 Step::Actions(create()),
425 Step::Actions(vec![d2(), x3(), x2(), x1(), d3(), d1()]),
426 Step::Actions(create2()),
427 Step::Actions(vec![d3(), x3(), d2(), x1(), d1(), x2()]),
428 Step::Actions(create2()),
429 Step::Actions(vec![x3(), d3(), d1(), x1(), d2(), x2()]),
430 Step::WithMetrics(vec![], "Everything should be gone".into()),
431 ];
432 Trial { name: "Delete With Metrics".into(), steps }
433}
434
435fn lazy_nodes_trial() -> Trial {
436 Trial {
437 name: "Lazy Nodes".into(),
438 steps: vec![Step::LazyActions(vec![
439 crate::create_lazy_node!(
441 parent: ROOT_ID,
442 id: 1,
443 name: "child",
444 disposition: LinkDisposition::Child,
445 actions: vec![crate::create_bytes_property!(parent: ROOT_ID, id: 1, name: "child_bytes",value: vec!(3u8, 4u8))]
446 ),
447 crate::create_lazy_node!(
448 parent: ROOT_ID,
449 id: 2,
450 name: "child",
451 disposition: LinkDisposition::Child,
452 actions: vec![crate::create_bytes_property!(parent: ROOT_ID, id: 1, name: "child_bytes",value: vec!(3u8, 4u8))]
453 ),
454 crate::delete_lazy_node!(id: 1),
455 crate::delete_lazy_node!(id: 2),
456 crate::create_lazy_node!(
458 parent: ROOT_ID,
459 id: 1,
460 name: "child",
461 disposition: LinkDisposition::Child,
462 actions: vec![crate::create_bytes_property!(parent: ROOT_ID, id: 1, name: "child_bytes_new",value: vec!(1u8, 2u8))]
463 ),
464 crate::delete_lazy_node!(id: 1),
465 crate::create_lazy_node!(
467 parent: ROOT_ID,
468 id: 1,
469 name: "inline_child",
470 disposition: LinkDisposition::Inline,
471 actions: vec![crate::create_bytes_property!(parent: ROOT_ID, id: 1, name: "inline_child",value: vec!(1u8, 2u8))]
472 ),
473 crate::delete_lazy_node!(id: 1),
474 ])],
475 }
476}
477
478#[cfg(test)]
479pub(crate) mod tests {
480 use super::*;
481
482 pub fn trial_with_action(name: &str, action: Action) -> Trial {
483 Trial { name: name.into(), steps: vec![Step::Actions(vec![action])] }
484 }
485}