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