1pub use super::*;
21
22#[macro_export]
24macro_rules! whitelist {
25 ($acc:ident) => {
26 frame_benchmarking::benchmarking::add_to_whitelist(
27 frame_system::Account::<T>::hashed_key_for(&$acc).into(),
28 );
29 };
30}
31
32#[macro_export]
172macro_rules! benchmarks {
173 (
174 $( $rest:tt )*
175 ) => {
176 $crate::benchmarks_iter!(
177 { }
178 { }
179 { }
180 ( )
181 ( )
182 ( )
183 ( )
184 $( $rest )*
185 );
186 }
187}
188
189#[macro_export]
193macro_rules! benchmarks_instance {
194 (
195 $( $rest:tt )*
196 ) => {
197 $crate::benchmarks_iter!(
198 { }
199 { I: Instance }
200 { }
201 ( )
202 ( )
203 ( )
204 ( )
205 $( $rest )*
206 );
207 }
208}
209
210#[macro_export]
214macro_rules! benchmarks_instance_pallet {
215 (
216 $( $rest:tt )*
217 ) => {
218 $crate::benchmarks_iter!(
219 { }
220 { I: 'static }
221 { }
222 ( )
223 ( )
224 ( )
225 ( )
226 $( $rest )*
227 );
228 }
229}
230
231#[macro_export]
232#[doc(hidden)]
233macro_rules! benchmarks_iter {
234 (
237 { }
238 { $( $instance:ident: $instance_bound:tt )? }
239 { $( $where_clause:tt )* }
240 ( $( $names:tt )* )
241 ( $( $names_extra:tt )* )
242 ( $( $names_skip_meta:tt )* )
243 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
244 impl_benchmark_test_suite!(
245 $bench_module:ident,
246 $new_test_ext:expr,
247 $test:path
248 $(, $( $args:tt )* )?);
249 $( $rest:tt )*
250 ) => {
251 $crate::benchmarks_iter! {
252 { $bench_module, $new_test_ext, $test $(, $( $args )* )? }
253 { $( $instance: $instance_bound )? }
254 { $( $where_clause )* }
255 ( $( $names )* )
256 ( $( $names_extra )* )
257 ( $( $names_skip_meta )* )
258 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
259 $( $rest )*
260 }
261 };
262 (
264 { }
265 { $( $instance:ident: $instance_bound:tt )? }
266 { $( $where_clause:tt )* }
267 ( $( $names:tt )* )
268 ( $( $names_extra:tt )* )
269 ( $( $names_skip_meta:tt )* )
270 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
271 impl_benchmark_test_suite!(
272 $bench_module:ident,
273 $new_test_ext:expr,
274 $test:path
275 $(, $( $args:tt )* )?)
276 $( $rest:tt )*
277 ) => {
278 $crate::benchmarks_iter! {
279 { $bench_module, $new_test_ext, $test $(, $( $args )* )? }
280 { $( $instance: $instance_bound )? }
281 { $( $where_clause )* }
282 ( $( $names )* )
283 ( $( $names_extra )* )
284 ( $( $names_skip_meta )* )
285 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
286 $( $rest )*
287 }
288 };
289 (
291 { $($bench_module:ident, $new_test_ext:expr, $test:path $(, $( $args:tt )* )?)? }
292 { $( $instance:ident: $instance_bound:tt )? }
293 { $( $where_clause:tt )* }
294 ( $( $names:tt )* )
295 ( $( $names_extra:tt )* )
296 ( $( $names_skip_meta:tt )* )
297 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
298 where_clause { where $( $where_bound:tt )* }
299 $( $rest:tt )*
300 ) => {
301 $crate::benchmarks_iter! {
302 { $($bench_module, $new_test_ext, $test $(, $( $args )* )?)? }
303 { $( $instance: $instance_bound)? }
304 { $( $where_bound )* }
305 ( $( $names )* )
306 ( $( $names_extra )* )
307 ( $( $names_skip_meta )* )
308 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
309 $( $rest )*
310 }
311 };
312 (
314 { $($bench_module:ident, $new_test_ext:expr, $test:path $(, $( $args:tt )* )?)? }
315 { $( $instance:ident: $instance_bound:tt )? }
316 { $( $where_clause:tt )* }
317 ( $( $names:tt )* )
318 ( $( $names_extra:tt )* )
319 ( $( $names_skip_meta:tt )* )
320 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
321 #[skip_meta]
322 $( #[ $($attributes:tt)+ ] )*
323 $name:ident
324 $( $rest:tt )*
325 ) => {
326 $crate::benchmarks_iter! {
327 { $($bench_module, $new_test_ext, $test $(, $( $args )* )?)? }
328 { $( $instance: $instance_bound )? }
329 { $( $where_clause )* }
330 ( $( $names )* )
331 ( $( $names_extra )* )
332 ( $( $names_skip_meta )* $name )
333 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
334 $( #[ $( $attributes )+ ] )*
335 $name
336 $( $rest )*
337 }
338 };
339 (
341 { $($bench_module:ident, $new_test_ext:expr, $test:path $(, $( $args:tt )* )?)? }
342 { $( $instance:ident: $instance_bound:tt )? }
343 { $( $where_clause:tt )* }
344 ( $( $names:tt )* )
345 ( $( $names_extra:tt )* )
346 ( $( $names_skip_meta:tt )* )
347 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
348 #[extra]
349 $( #[ $($attributes:tt)+ ] )*
350 $name:ident
351 $( $rest:tt )*
352 ) => {
353 $crate::benchmarks_iter! {
354 { $($bench_module, $new_test_ext, $test $(, $( $args )* )?)? }
355 { $( $instance: $instance_bound )? }
356 { $( $where_clause )* }
357 ( $( $names )* )
358 ( $( $names_extra )* $name )
359 ( $( $names_skip_meta )* )
360 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
361 $( #[ $( $attributes )+ ] )*
362 $name
363 $( $rest )*
364 }
365 };
366 (
368 { $($bench_module:ident, $new_test_ext:expr, $test:path $(, $( $args:tt )* )?)? }
369 { $( $instance:ident: $instance_bound:tt )? }
370 { $( $where_clause:tt )* }
371 ( $( $names:tt )* )
372 ( $( $names_extra:tt )* )
373 ( $( $names_skip_meta:tt )* )
374 ( $( $old_pov_name:ident: $( $old_storage:path = $old_pov_mode:ident )*; )* )
375 #[pov_mode = $mode:ident $( { $( $storage:path: $pov_mode:ident )* } )?]
376 $( #[ $($attributes:tt)+ ] )*
377 $name:ident
378 $( $rest:tt )*
379 ) => {
380 $crate::benchmarks_iter! {
381 { $($bench_module, $new_test_ext, $test $(, $( $args )* )?)? }
382 { $( $instance: $instance_bound )? }
383 { $( $where_clause )* }
384 ( $( $names )* )
385 ( $( $names_extra )* )
386 ( $( $names_skip_meta )* )
387 ( $name: ALL = $mode $($( $storage = $pov_mode )*)?; $( $old_pov_name: $( $old_storage = $old_pov_mode )*; )* )
388 $( #[ $( $attributes )+ ] )*
389 $name
390 $( $rest )*
391 }
392 };
393 (
395 { $($bench_module:ident, $new_test_ext:expr, $test:path $(, $( $args:tt )* )?)? }
396 { $( $instance:ident: $instance_bound:tt )? }
397 { $( $where_clause:tt )* }
398 ( $( $names:tt )* ) ( $( $names_extra:tt )* )
400 ( $( $names_skip_meta:tt )* )
401 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
402 $name:ident { $( $code:tt )* }: _ $(< $origin_type:ty>)? ( $origin:expr $( , $arg:expr )* )
403 verify $postcode:block
404 $( $rest:tt )*
405 ) => {
406 $crate::benchmarks_iter! {
407 { $($bench_module, $new_test_ext, $test $(, $( $args )* )?)? }
408 { $( $instance: $instance_bound )? }
409 { $( $where_clause )* }
410 ( $( $names )* )
411 ( $( $names_extra )* )
412 ( $( $names_skip_meta )* )
413 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
414 $name { $( $code )* }: $name $(< $origin_type >)? ( $origin $( , $arg )* )
415 verify $postcode
416 $( $rest )*
417 }
418 };
419 (
421 { $($bench_module:ident, $new_test_ext:expr, $test:path $(, $( $args:tt )* )?)? }
422 { $( $instance:ident: $instance_bound:tt )? }
423 { $( $where_clause:tt )* }
424 ( $( $names:tt )* )
425 ( $( $names_extra:tt )* )
426 ( $( $names_skip_meta:tt )* )
427 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
428 $name:ident { $( $code:tt )* }: $dispatch:ident $(<$origin_type:ty>)? ( $origin:expr $( , $arg:expr )* )
429 verify $postcode:block
430 $( $rest:tt )*
431 ) => {
432 $crate::__private::paste::paste! {
433 $crate::benchmarks_iter! {
434 { $($bench_module, $new_test_ext, $test $(, $( $args )* )?)? }
435 { $( $instance: $instance_bound )? }
436 { $( $where_clause )* }
437 ( $( $names )* )
438 ( $( $names_extra )* )
439 ( $( $names_skip_meta )* )
440 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
441 $name {
442 $( $code )*
443 let __call = Call::<
444 T
445 $( , $instance )?
446 >:: [< new_call_variant_ $dispatch >] (
447 $($arg),*
448 );
449 let __benchmarked_call_encoded = $crate::__private::codec::Encode::encode(
450 &__call
451 );
452 }: {
453 let __call_decoded = <
454 Call<T $(, $instance )?>
455 as $crate::__private::codec::Decode
456 >::decode(&mut &__benchmarked_call_encoded[..])
457 .expect("call is encoded above, encoding must be correct");
458 let __origin = $crate::to_origin!($origin $(, $origin_type)?);
459 <Call<T $(, $instance)? > as $crate::__private::traits::UnfilteredDispatchable
460 >::dispatch_bypass_filter(__call_decoded, __origin)?;
461 }
462 verify $postcode
463 $( $rest )*
464 }
465 }
466 };
467 (
469 { $($bench_module:ident, $new_test_ext:expr, $test:path $(, $( $args:tt )* )?)? }
470 { $( $instance:ident: $instance_bound:tt )? }
471 { $( $where_clause:tt )* }
472 ( $( $names:tt )* )
473 ( $( $names_extra:tt )* )
474 ( $( $names_skip_meta:tt )* )
475 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
476 $name:ident { $( $code:tt )* }: $eval:block
477 verify $postcode:block
478 $( $rest:tt )*
479 ) => {
480 $crate::benchmark_backend! {
481 { $( $instance: $instance_bound )? }
482 $name
483 { $( $where_clause )* }
484 { }
485 { $eval }
486 { $( $code )* }
487 $postcode
488 }
489
490 #[cfg(test)]
491 $crate::impl_benchmark_test!(
492 { $( $where_clause )* }
493 { $( $instance: $instance_bound )? }
494 $name
495 );
496
497 $crate::benchmarks_iter!(
498 { $($bench_module, $new_test_ext, $test $(, $( $args )* )?)? }
499 { $( $instance: $instance_bound )? }
500 { $( $where_clause )* }
501 ( $( $names )* { $( $instance )? } $name )
502 ( $( $names_extra )* )
503 ( $( $names_skip_meta )* )
504 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
505 $( $rest )*
506 );
507 };
508 (
510 { $bench_module:ident, $new_test_ext:expr, $test:path $(, $( $args:tt )* )? }
511 { $( $instance:ident: $instance_bound:tt )? }
512 { $( $where_clause:tt )* }
513 ( $( $names:tt )* )
514 ( $( $names_extra:tt )* )
515 ( $( $names_skip_meta:tt )* )
516 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
517 ) => {
518 $crate::selected_benchmark!(
519 { $( $where_clause)* }
520 { $( $instance: $instance_bound )? }
521 $( $names )*
522 );
523 $crate::impl_benchmark!(
524 { $( $where_clause )* }
525 { $( $instance: $instance_bound )? }
526 ( $( $names )* )
527 ( $( $names_extra ),* )
528 ( $( $names_skip_meta ),* )
529 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
530 );
531 $crate::impl_test_function!(
532 ( $( $names )* )
533 ( $( $names_extra )* )
534 ( $( $names_skip_meta )* )
535 $bench_module,
536 $new_test_ext,
537 $test
538 $(, $( $args )* )?
539 );
540 };
541 (
543 { }
544 { $( $instance:ident: $instance_bound:tt )? }
545 { $( $where_clause:tt )* }
546 ( $( $names:tt )* )
547 ( $( $names_extra:tt )* )
548 ( $( $names_skip_meta:tt )* )
549 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
550 ) => {
551 $crate::selected_benchmark!(
552 { $( $where_clause)* }
553 { $( $instance: $instance_bound )? }
554 $( $names )*
555 );
556 $crate::impl_benchmark!(
557 { $( $where_clause )* }
558 { $( $instance: $instance_bound )? }
559 ( $( $names )* )
560 ( $( $names_extra ),* )
561 ( $( $names_skip_meta ),* )
562 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
563 );
564 };
565 (
567 { $($bench_module:ident, $new_test_ext:expr, $test:path $(, $( $args:tt )* )?)? }
568 { $( $instance:ident: $instance_bound:tt )? }
569 { $( $where_clause:tt )* }
570 ( $( $names:tt )* )
571 ( $( $names_extra:tt )* )
572 ( $( $names_skip_meta:tt )* )
573 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
574 $name:ident { $( $code:tt )* }: _ $(<$origin_type:ty>)? ( $origin:expr $( , $arg:expr )* )
575 $( $rest:tt )*
576 ) => {
577 $crate::benchmarks_iter! {
578 { $($bench_module, $new_test_ext, $test $(, $( $args )* )?)? }
579 { $( $instance: $instance_bound )? }
580 { $( $where_clause )* }
581 ( $( $names )* )
582 ( $( $names_extra )* )
583 ( $( $names_skip_meta )* )
584 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
585 $name { $( $code )* }: _ $(<$origin_type>)? ( $origin $( , $arg )* )
586 verify { }
587 $( $rest )*
588 }
589 };
590 (
592 { $($bench_module:ident, $new_test_ext:expr, $test:path $(, $( $args:tt )* )?)? }
593 { $( $instance:ident: $instance_bound:tt )? }
594 { $( $where_clause:tt )* }
595 ( $( $names:tt )* )
596 ( $( $names_extra:tt )* )
597 ( $( $names_skip_meta:tt )* )
598 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
599 $name:ident { $( $code:tt )* }: $dispatch:ident $(<$origin_type:ty>)? ( $origin:expr $( , $arg:expr )* )
600 $( $rest:tt )*
601 ) => {
602 $crate::benchmarks_iter! {
603 { $($bench_module, $new_test_ext, $test $(, $( $args )* )?)? }
604 { $( $instance: $instance_bound )? }
605 { $( $where_clause )* }
606 ( $( $names )* )
607 ( $( $names_extra )* )
608 ( $( $names_skip_meta )* )
609 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
610 $name { $( $code )* }: $dispatch $(<$origin_type>)? ( $origin $( , $arg )* )
611 verify { }
612 $( $rest )*
613 }
614 };
615 (
617 { $($bench_module:ident, $new_test_ext:expr, $test:path $(, $( $args:tt )* )?)? }
618 { $( $instance:ident: $instance_bound:tt )? }
619 { $( $where_clause:tt )* }
620 ( $( $names:tt )* )
621 ( $( $names_extra:tt )* )
622 ( $( $names_skip_meta:tt )* )
623 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
624 $name:ident { $( $code:tt )* }: $(<$origin_type:ty>)? $eval:block
625 $( $rest:tt )*
626 ) => {
627 $crate::benchmarks_iter!(
628 { $($bench_module, $new_test_ext, $test $(, $( $args )* )?)? }
629 { $( $instance: $instance_bound )? }
630 { $( $where_clause )* }
631 ( $( $names )* )
632 ( $( $names_extra )* )
633 ( $( $names_skip_meta )* )
634 ( $( $pov_name: $( $storage = $pov_mode )*; )* )
635 $name { $( $code )* }: $(<$origin_type>)? $eval
636 verify { }
637 $( $rest )*
638 );
639 };
640}
641
642#[macro_export]
643#[doc(hidden)]
644macro_rules! to_origin {
645 ($origin:expr) => {
646 $origin.into()
647 };
648 ($origin:expr, $origin_type:ty) => {
649 <<T as frame_system::Config>::RuntimeOrigin as From<$origin_type>>::from($origin)
650 };
651}
652
653#[macro_export]
654#[doc(hidden)]
655macro_rules! benchmark_backend {
656 (
658 { $( $instance:ident: $instance_bound:tt )? }
659 $name:ident
660 { $( $where_clause:tt )* }
661 { $( PRE { $( $pre_parsed:tt )* } )* }
662 { $eval:block }
663 {
664 let $pre_id:tt $( : $pre_ty:ty )? = $pre_ex:expr;
665 $( $rest:tt )*
666 }
667 $postcode:block
668 ) => {
669 $crate::benchmark_backend! {
670 { $( $instance: $instance_bound )? }
671 $name
672 { $( $where_clause )* }
673 {
674 $( PRE { $( $pre_parsed )* } )*
675 PRE { $pre_id , $( $pre_ty , )? $pre_ex }
676 }
677 { $eval }
678 { $( $rest )* }
679 $postcode
680 }
681 };
682 (
683 { $( $instance:ident: $instance_bound:tt )? }
684 $name:ident
685 { $( $where_clause:tt )* }
686 { $( $parsed:tt )* }
687 { $eval:block }
688 {
689 let $param:ident in ( $param_from:expr ) .. $param_to:expr => $param_instancer:expr;
690 $( $rest:tt )*
691 }
692 $postcode:block
693 ) => {
694 $crate::benchmark_backend! {
695 { $( $instance: $instance_bound )? }
696 $name
697 { $( $where_clause )* }
698 {
699 $( $parsed )*
700 PARAM { $param , $param_from , $param_to , $param_instancer }
701 }
702 { $eval }
703 { $( $rest )* }
704 $postcode
705 }
706 };
707 (
709 { $( $instance:ident: $instance_bound:tt )? }
710 $name:ident
711 { $( $where_clause:tt )* }
712 { $( $parsed:tt )* }
713 { $eval:block }
714 {
715 let $param:ident in $param_from:tt .. $param_to:expr => $param_instancer:expr ;
716 $( $rest:tt )*
717 }
718 $postcode:block
719 ) => {
720 $crate::benchmark_backend! {
721 { $( $instance: $instance_bound )? }
722 $name
723 { $( $where_clause )* }
724 { $( $parsed )* }
725 { $eval }
726 {
727 let $param in ( $param_from ) .. $param_to => $param_instancer;
728 $( $rest )*
729 }
730 $postcode
731 }
732 };
733 (
735 { $( $instance:ident: $instance_bound:tt )? }
736 $name:ident
737 { $( $where_clause:tt )* }
738 { $( $parsed:tt )* }
739 { $eval:block }
740 {
741 let $param:ident in $param_from:tt .. $param_to:expr;
742 $( $rest:tt )*
743 }
744 $postcode:block
745 ) => {
746 $crate::benchmark_backend! {
747 { $( $instance: $instance_bound )? }
748 $name
749 { $( $where_clause )* }
750 { $( $parsed )* }
751 { $eval }
752 {
753 let $param in $param_from .. $param_to => ();
754 $( $rest )*
755 }
756 $postcode
757 }
758 };
759 (
761 { $( $instance:ident: $instance_bound:tt )? }
762 $name:ident
763 { $( $where_clause:tt )* }
764 {
765 $( PRE { $pre_id:tt , $( $pre_ty:ty , )? $pre_ex:expr } )*
766 $( PARAM { $param:ident , $param_from:expr , $param_to:expr , $param_instancer:expr } )*
767 }
768 { $eval:block }
769 { $( $post:tt )* }
770 $postcode:block
771 ) => {
772 #[allow(non_camel_case_types)]
773 struct $name;
774 #[allow(unused_variables)]
775 impl<T: Config $( <$instance>, $instance: $instance_bound )? >
776 $crate::BenchmarkingSetup<T $(, $instance)? > for $name
777 where $( $where_clause )*
778 {
779 fn components(&self) -> $crate::__private::Vec<($crate::BenchmarkParameter, u32, u32)> {
780 $crate::__private::vec! [
781 $(
782 ($crate::BenchmarkParameter::$param, $param_from, $param_to)
783 ),*
784 ]
785 }
786
787 fn instance(
788 &self,
789 recording: &mut impl $crate::Recording,
790 components: &[($crate::BenchmarkParameter, u32)],
791 verify: bool
792 ) -> Result<(), $crate::BenchmarkError> {
793 $(
794 let $param = components.iter()
796 .find(|&c| c.0 == $crate::BenchmarkParameter::$param)
797 .ok_or("Could not find component in benchmark preparation.")?
798 .1;
799 )*
800 $(
801 let $pre_id $( : $pre_ty )? = $pre_ex;
802 )*
803 $( $param_instancer ; )*
804 $( $post )*
805
806 recording.start();
807 $eval;
808 recording.stop();
809
810 if verify {
811 $postcode;
812 }
813 Ok(())
814 }
815 }
816 };
817}
818
819#[macro_export]
821#[doc(hidden)]
822macro_rules! impl_bench_case_tests {
823 (
824 { $module:ident, $new_test_exec:expr, $exec_name:ident, $test:path, $extra:expr }
825 { $( $names_extra:tt )* }
826 $( { $( $bench_inst:ident )? } $bench:ident )*
827 )
828 => {
829 $crate::impl_bench_name_tests!(
830 $module, $new_test_exec, $exec_name, $test, $extra,
831 { $( $names_extra )* },
832 $( { $bench } )+
833 );
834 }
835}
836
837#[macro_export]
839#[doc(hidden)]
840macro_rules! impl_bench_name_tests {
841 (
843 $module:ident, $new_test_exec:expr, $exec_name:ident, $test:path, $extra:expr,
844 { $( $names_extra:tt )* },
845 { $name:ident }
846 ) => {
847 $crate::__private::paste::paste! {
848 #[test]
849 fn [<bench_ $name>] () {
850 $new_test_exec.$exec_name(|| {
851 if !($extra) {
853 let disabled = $crate::__private::vec![ $( stringify!($names_extra).as_ref() ),* ];
854 if disabled.contains(&stringify!($name)) {
855 $crate::__private::log::debug!(
856 "extra benchmark skipped - {}",
857 stringify!($name),
858 );
859 return ();
860 }
861 }
862
863 match std::panic::catch_unwind(|| {
866 $module::<$test>::[< test_benchmark_ $name >] ()
867 }) {
868 Err(err) => {
869 panic!("{}: {:?}", stringify!($name), err);
870 },
871 Ok(Err(err)) => {
872 match err {
873 $crate::BenchmarkError::Stop(err) => {
874 panic!("{}: {:?}", stringify!($name), err);
875 },
876 $crate::BenchmarkError::Override(_) => {
877 $crate::__private::log::error!(
879 "benchmark error overridden - {}",
880 stringify!($name),
881 );
882 },
883 $crate::BenchmarkError::Skip => {
884 $crate::__private::log::debug!(
886 "benchmark skipped - {}",
887 stringify!($name),
888 );
889 },
890 $crate::BenchmarkError::Weightless => {
891 $crate::__private::log::debug!(
893 "benchmark weightless skipped - {}",
894 stringify!($name),
895 );
896 }
897 }
898 },
899 Ok(Ok(())) => (),
900 }
901 });
902 }
903 }
904 };
905 (
907 $module:ident, $new_test_exec:expr, $exec_name:ident, $test:path, $extra:expr,
908 { $( $names_extra:tt )* },
909 { $name:ident } $( { $rest:ident } )+
910 ) => {
911 $crate::impl_bench_name_tests!($module, $new_test_exec, $exec_name, $test, $extra,
913 { $( $names_extra )* }, { $name });
914 $crate::impl_bench_name_tests!($module, $new_test_exec, $exec_name, $test, $extra,
916 { $( $names_extra )* }, $( { $rest } )+);
917 };
918}
919
920#[macro_export]
935#[doc(hidden)]
936macro_rules! selected_benchmark {
937 (
938 { $( $where_clause:tt )* }
939 { $( $instance:ident: $instance_bound:tt )? }
940 $( { $( $bench_inst:ident )? } $bench:ident )*
941 ) => {
942 #[allow(non_camel_case_types)]
944 enum SelectedBenchmark {
945 $( $bench, )*
946 }
947
948 impl<T: Config $( <$instance>, $instance: $instance_bound )? >
950 $crate::BenchmarkingSetup<T $(, $instance )? > for SelectedBenchmark
951 where $( $where_clause )*
952 {
953 fn components(&self) -> $crate::__private::Vec<($crate::BenchmarkParameter, u32, u32)> {
954 match self {
955 $(
956 Self::$bench => <
957 $bench as $crate::BenchmarkingSetup<T $(, $bench_inst)? >
958 >::components(&$bench),
959 )*
960 }
961 }
962
963 fn instance(
964 &self,
965 recording: &mut impl $crate::Recording,
966 components: &[($crate::BenchmarkParameter, u32)],
967 verify: bool
968 ) -> Result<(), $crate::BenchmarkError> {
969 match self {
970 $(
971 Self::$bench => <
972 $bench as $crate::BenchmarkingSetup<T $(, $bench_inst)? >
973 >::instance(&$bench, recording, components, verify),
974 )*
975 }
976 }
977 }
978 };
979}
980
981#[macro_export]
982#[doc(hidden)]
983macro_rules! impl_benchmark {
984 (
985 { $( $where_clause:tt )* }
986 { $( $instance:ident: $instance_bound:tt )? }
987 ( $( { $( $name_inst:ident )? } $name:ident )* )
988 ( $( $name_extra:ident ),* )
989 ( $( $name_skip_meta:ident ),* )
990 ( $( $pov_name:ident: $( $storage:path = $pov_mode:ident )*; )* )
991 ) => {
992 #[cfg(any(feature = "runtime-benchmarks", test))]
994 impl<T: Config $(<$instance>, $instance: $instance_bound )? >
995 $crate::Benchmarking for Pallet<T $(, $instance)? >
996 where T: frame_system::Config, $( $where_clause )*
997 {
998 fn benchmarks(extra: bool) -> $crate::__private::Vec<$crate::BenchmarkMetadata> {
999 $($crate::validate_pov_mode!(
1000 $pov_name: $( $storage = $pov_mode )*;
1001 );)*
1002 let mut all_names = $crate::__private::vec![ $( stringify!($name).as_ref() ),* ];
1003 if !extra {
1004 let extra = [ $( stringify!($name_extra).as_ref() ),* ];
1005 all_names.retain(|x| !extra.contains(x));
1006 }
1007 let pov_modes: $crate::__private::Vec<($crate::__private::Vec<u8>, $crate::__private::Vec<($crate::__private::Vec<u8>, $crate::__private::Vec<u8>)>)> = $crate::__private::vec![
1008 $(
1009 (stringify!($pov_name).as_bytes().to_vec(),
1010 $crate::__private::vec![
1011 $( ( stringify!($storage).replace(" ", "").as_bytes().to_vec(),
1013 stringify!($pov_mode).as_bytes().to_vec() ), )*
1014 ]),
1015 )*
1016 ];
1017 all_names.into_iter().map(|benchmark| {
1018 let selected_benchmark = match benchmark {
1019 $( stringify!($name) => SelectedBenchmark::$name, )*
1020 _ => panic!("all benchmarks should be selectable"),
1021 };
1022 let name = benchmark.as_bytes().to_vec();
1023 let components = <
1024 SelectedBenchmark as $crate::BenchmarkingSetup<T $(, $instance)?>
1025 >::components(&selected_benchmark);
1026
1027 $crate::BenchmarkMetadata {
1028 name: name.clone(),
1029 components,
1030 pov_modes: pov_modes.iter().find(|p| p.0 == name).map(|p| p.1.clone()).unwrap_or_default(),
1031 }
1032 }).collect::<$crate::__private::Vec<_>>()
1033 }
1034
1035 fn run_benchmark(
1036 extrinsic: &[u8],
1037 c: &[($crate::BenchmarkParameter, u32)],
1038 whitelist: &[$crate::__private::TrackedStorageKey],
1039 verify: bool,
1040 internal_repeats: u32,
1041 ) -> Result<$crate::__private::Vec<$crate::BenchmarkResult>, $crate::BenchmarkError> {
1042 $crate::benchmarking::wipe_db();
1044 let extrinsic = $crate::__private::str::from_utf8(extrinsic)
1045 .map_err(|_| "`extrinsic` is not a valid utf8 string!")?;
1046 let selected_benchmark = match extrinsic {
1047 $( stringify!($name) => SelectedBenchmark::$name, )*
1048 _ => return Err("Could not find extrinsic.".into()),
1049 };
1050
1051 let mut whitelist = whitelist.to_vec();
1053 let whitelisted_caller_key =
1054 <frame_system::Account::<T> as $crate::__private::storage::StorageMap<_,_>>::hashed_key_for(
1055 $crate::whitelisted_caller::<T::AccountId>()
1056 );
1057 whitelist.push(whitelisted_caller_key.into());
1058 let transactional_layer_key = $crate::__private::TrackedStorageKey::new(
1060 $crate::__private::storage::transactional::TRANSACTION_LEVEL_KEY.into()
1061 );
1062 whitelist.push(transactional_layer_key);
1063 let extrinsic_index = $crate::__private::TrackedStorageKey::new(
1065 $crate::__private::well_known_keys::EXTRINSIC_INDEX.into()
1066 );
1067 whitelist.push(extrinsic_index);
1068 let intrablock_entropy = $crate::__private::TrackedStorageKey::new(
1070 $crate::__private::well_known_keys::INTRABLOCK_ENTROPY.into()
1071 );
1072 whitelist.push(intrablock_entropy);
1073
1074 $crate::benchmarking::set_whitelist(whitelist.clone());
1075
1076 let mut results: $crate::__private::Vec<$crate::BenchmarkResult> = $crate::__private::Vec::new();
1077 let on_before_start = || {
1078 if $crate::__private::Zero::is_zero(&frame_system::Pallet::<T>::block_number()) {
1080 frame_system::Pallet::<T>::set_block_number(1u32.into());
1081 }
1082
1083 $crate::benchmarking::commit_db();
1086
1087 let current_whitelist = $crate::benchmarking::get_whitelist();
1093 for key in ¤t_whitelist {
1094 if let Some(child_trie_key) = &key.child_trie_key {
1095 let child_info = $crate::__private::storage::ChildInfo::new_default(child_trie_key);
1096 $crate::__private::storage::child::get_raw(&child_info, &key.key);
1097 } else {
1098 $crate::__private::storage::unhashed::get_raw(&key.key);
1099 }
1100 }
1101
1102 $crate::benchmarking::reset_read_write_count();
1104 };
1105
1106 for _ in 0 .. internal_repeats.max(1) {
1108 $crate::__private::defer!($crate::benchmarking::wipe_db());
1110
1111 $crate::__private::log::trace!(
1113 target: "benchmark",
1114 "Start Benchmark: {} ({:?}) verify {}",
1115 extrinsic,
1116 c,
1117 verify
1118 );
1119
1120 let mut recording = $crate::BenchmarkRecording::new(&on_before_start);
1123 <SelectedBenchmark as $crate::BenchmarkingSetup<T $(, $instance)?>>::instance(&selected_benchmark, &mut recording, c, verify)?;
1124
1125 let elapsed_extrinsic = recording.elapsed_extrinsic().expect("elapsed time should be recorded");
1127 let diff_pov = recording.diff_pov().unwrap_or_default();
1128
1129 $crate::benchmarking::commit_db();
1131 $crate::__private::log::trace!(
1132 target: "benchmark",
1133 "End Benchmark: {} ns", elapsed_extrinsic
1134 );
1135 let read_write_count = $crate::benchmarking::read_write_count();
1136 $crate::__private::log::trace!(
1137 target: "benchmark",
1138 "Read/Write Count {:?}", read_write_count
1139 );
1140 $crate::__private::log::trace!(
1141 target: "benchmark",
1142 "Proof sizes: before {:?} after {:?} diff {}", recording.start_pov(), recording.end_pov(), &diff_pov
1143 );
1144
1145 let start_storage_root = $crate::current_time();
1147 $crate::__private::storage_root($crate::__private::StateVersion::V1);
1148 let finish_storage_root = $crate::current_time();
1149 let elapsed_storage_root = finish_storage_root - start_storage_root;
1150
1151 let skip_meta = [ $( stringify!($name_skip_meta).as_ref() ),* ];
1152 let read_and_written_keys = if skip_meta.contains(&extrinsic) {
1153 $crate::__private::vec![(b"Skipped Metadata".to_vec(), 0, 0, false)]
1154 } else {
1155 $crate::benchmarking::get_read_and_written_keys()
1156 };
1157
1158 results.push($crate::BenchmarkResult {
1159 components: c.to_vec(),
1160 extrinsic_time: elapsed_extrinsic,
1161 storage_root_time: elapsed_storage_root,
1162 reads: read_write_count.0,
1163 repeat_reads: read_write_count.1,
1164 writes: read_write_count.2,
1165 repeat_writes: read_write_count.3,
1166 proof_size: diff_pov,
1167 keys: read_and_written_keys,
1168 });
1169 }
1170
1171 return Ok(results);
1172 }
1173 }
1174
1175 #[cfg(test)]
1176 impl<T: Config $(<$instance>, $instance: $instance_bound )? >
1177 Pallet<T $(, $instance)? >
1178 where T: frame_system::Config, $( $where_clause )*
1179 {
1180 #[allow(unused)]
1190 fn test_bench_by_name(name: &[u8]) -> Result<(), $crate::BenchmarkError> {
1191 let name = $crate::__private::str::from_utf8(name)
1192 .map_err(|_| -> $crate::BenchmarkError { "`name` is not a valid utf8 string!".into() })?;
1193 match name {
1194 $( stringify!($name) => {
1195 $crate::__private::paste::paste! { Self::[< test_benchmark_ $name >]() }
1196 } )*
1197 _ => Err("Could not find test for requested benchmark.".into()),
1198 }
1199 }
1200 }
1201 };
1202}
1203
1204#[macro_export]
1210#[doc(hidden)]
1211macro_rules! impl_benchmark_test {
1212 (
1213 { $( $where_clause:tt )* }
1214 { $( $instance:ident: $instance_bound:tt )? }
1215 $name:ident
1216 ) => {
1217 $crate::__private::paste::item! {
1218 #[cfg(test)]
1219 impl<T: Config $(<$instance>, $instance: $instance_bound )? >
1220 Pallet<T $(, $instance)? >
1221 where T: frame_system::Config, $( $where_clause )*
1222 {
1223 #[allow(unused)]
1224 fn [<test_benchmark_ $name>] () -> Result<(), $crate::BenchmarkError> {
1225 let selected_benchmark = SelectedBenchmark::$name;
1226 let components = <
1227 SelectedBenchmark as $crate::BenchmarkingSetup<T, _>
1228 >::components(&selected_benchmark);
1229
1230 let execute_benchmark = |
1231 c: $crate::__private::Vec<($crate::BenchmarkParameter, u32)>
1232 | -> Result<(), $crate::BenchmarkError> {
1233 $crate::__private::defer!($crate::benchmarking::wipe_db());
1235
1236 let on_before_start = || {
1237 if $crate::__private::Zero::is_zero(&frame_system::Pallet::<T>::block_number()) {
1239 frame_system::Pallet::<T>::set_block_number(1u32.into());
1240 }
1241 };
1242
1243 <SelectedBenchmark as $crate::BenchmarkingSetup<T, _>>::test_instance(&selected_benchmark, &c, &on_before_start)
1245 };
1246
1247 if components.is_empty() {
1248 execute_benchmark(Default::default())?;
1249 } else {
1250 let num_values: u32 = if let Ok(ev) = std::env::var("VALUES_PER_COMPONENT") {
1251 ev.parse().map_err(|_| {
1252 $crate::BenchmarkError::Stop(
1253 "Could not parse env var `VALUES_PER_COMPONENT` as u32."
1254 )
1255 })?
1256 } else {
1257 6
1258 };
1259
1260 if num_values < 2 {
1261 return Err("`VALUES_PER_COMPONENT` must be at least 2".into());
1262 }
1263
1264 for (name, low, high) in components.clone().into_iter() {
1265 let mut values = $crate::__private::vec![low];
1270 let diff = (high - low).min(num_values - 1);
1271 let slope = (high - low) as f32 / diff as f32;
1272
1273 for i in 1..=diff {
1274 let value = ((low as f32 + slope * i as f32) as u32)
1275 .clamp(low, high);
1276 values.push(value);
1277 }
1278
1279 for component_value in values {
1280 let c: $crate::__private::Vec<($crate::BenchmarkParameter, u32)> = components
1282 .iter()
1283 .map(|(n, _, h)|
1284 if *n == name {
1285 (*n, component_value)
1286 } else {
1287 (*n, *h)
1288 }
1289 )
1290 .collect();
1291
1292 execute_benchmark(c)?;
1293 }
1294 }
1295 }
1296 Ok(())
1297 }
1298 }
1299 }
1300 };
1301}
1302
1303#[macro_export]
1444macro_rules! impl_benchmark_test_suite {
1445 (
1446 $bench_module:ident,
1447 $new_test_ext:expr,
1448 $test:path
1449 $(, $( $rest:tt )* )?
1450 ) => {
1451 $crate::impl_test_function!(
1452 ()
1453 ()
1454 ()
1455 $bench_module,
1456 $new_test_ext,
1457 $test
1458 $(, $( $rest )* )?
1459 );
1460 }
1461}
1462
1463#[macro_export]
1469macro_rules! validate_pov_mode {
1470 () => {};
1471 ( $_bench:ident: ; ) => { };
1472 ( $_bench:ident: $_car:path = Ignored ; ) => { };
1473 ( $bench:ident: $_car:path = Ignored $( $storage:path = $_pov_mode:ident )+; ) => {
1474 compile_error!(
1475 concat!(concat!("`pov_mode = Ignored` is exclusive. Please remove the attribute from keys: ", $( stringify!($storage) )+), " on benchmark '", stringify!($bench), "'"));
1476 };
1477 ( $bench:ident: $car:path = Measured $( $storage:path = $pov_mode:ident )*; ) => {
1478 $crate::validate_pov_mode!(
1479 $bench: $( $storage = $pov_mode )*;
1480 );
1481 };
1482 ( $bench:ident: $car:path = MaxEncodedLen $( $storage:path = $pov_mode:ident )*; ) => {
1483 $crate::validate_pov_mode!(
1484 $bench: $( $storage = $pov_mode )*;
1485 );
1486 };
1487 ( $bench:ident: $key:path = $unknown:ident $( $_storage:path = $_pov_mode:ident )*; ) => {
1488 compile_error!(
1489 concat!("Unknown pov_mode '", stringify!($unknown) ,"' for benchmark '", stringify!($bench), "' on key '", stringify!($key), "'. Must be one of: Ignored, Measured, MaxEncodedLen")
1490 );
1491 };
1492}
1493
1494#[macro_export]
1500#[doc(hidden)]
1501macro_rules! impl_test_function {
1502 (
1506 ( $( $names:tt )* )
1507 ( $( $names_extra:tt )* )
1508 ( $( $names_skip_meta:tt )* )
1509
1510 $bench_module:ident,
1511 $new_test_ext:expr,
1512 $test:path
1513 $(, $( $rest:tt )* )?
1514 ) => {
1515 $crate::impl_test_function!(
1516 @cases:
1517 ( $( $names )* )
1518 ( $( $names_extra )* )
1519 ( $( $names_skip_meta )* )
1520 @selected:
1521 $bench_module,
1522 $new_test_ext,
1523 $test,
1524 benchmarks_path = super,
1525 extra = true,
1526 exec_name = execute_with,
1527 @user:
1528 $( $( $rest )* )?
1529 );
1530 };
1531 (
1533 @cases:
1534 ( $( $names:tt )* )
1535 ( $( $names_extra:tt )* )
1536 ( $( $names_skip_meta:tt )* )
1537 @selected:
1538 $bench_module:ident,
1539 $new_test_ext:expr,
1540 $test:path,
1541 benchmarks_path = $old:ident,
1542 extra = $extra:expr,
1543 exec_name = $exec_name:ident,
1544 @user:
1545 benchmarks_path = $benchmarks_path:ident
1546 $(, $( $rest:tt )* )?
1547 ) => {
1548 $crate::impl_test_function!(
1549 @cases:
1550 ( $( $names )* )
1551 ( $( $names_extra )* )
1552 ( $( $names_skip_meta )* )
1553 @selected:
1554 $bench_module,
1555 $new_test_ext,
1556 $test,
1557 benchmarks_path = $benchmarks_path,
1558 extra = $extra,
1559 exec_name = $exec_name,
1560 @user:
1561 $( $( $rest )* )?
1562 );
1563 };
1564 (
1566 @cases:
1567 ( $( $names:tt )* )
1568 ( $( $names_extra:tt )* )
1569 ( $( $names_skip_meta:tt )* )
1570 @selected:
1571 $bench_module:ident,
1572 $new_test_ext:expr,
1573 $test:path,
1574 benchmarks_path = $benchmarks_path:ident,
1575 extra = $old:expr,
1576 exec_name = $exec_name:ident,
1577 @user:
1578 extra = $extra:expr
1579 $(, $( $rest:tt )* )?
1580 ) => {
1581 $crate::impl_test_function!(
1582 @cases:
1583 ( $( $names )* )
1584 ( $( $names_extra )* )
1585 ( $( $names_skip_meta )* )
1586 @selected:
1587 $bench_module,
1588 $new_test_ext,
1589 $test,
1590 benchmarks_path = $benchmarks_path,
1591 extra = $extra,
1592 exec_name = $exec_name,
1593 @user:
1594 $( $( $rest )* )?
1595 );
1596 };
1597 (
1599 @cases:
1600 ( $( $names:tt )* )
1601 ( $( $names_extra:tt )* )
1602 ( $( $names_skip_meta:tt )* )
1603 @selected:
1604 $bench_module:ident,
1605 $new_test_ext:expr,
1606 $test:path,
1607 benchmarks_path = $benchmarks_path:ident,
1608 extra = $extra:expr,
1609 exec_name = $old:ident,
1610 @user:
1611 exec_name = $exec_name:ident
1612 $(, $( $rest:tt )* )?
1613 ) => {
1614 $crate::impl_test_function!(
1615 @cases:
1616 ( $( $names )* )
1617 ( $( $names_extra )* )
1618 ( $( $names_skip_meta )* )
1619 @selected:
1620 $bench_module,
1621 $new_test_ext,
1622 $test,
1623 benchmarks_path = $benchmarks_path,
1624 extra = $extra,
1625 exec_name = $exec_name,
1626 @user:
1627 $( $( $rest )* )?
1628 );
1629 };
1630 (
1632 @cases:
1633 ( $( $names:tt )+ )
1634 ( $( $names_extra:tt )* )
1635 ( $( $names_skip_meta:tt )* )
1636 @selected:
1637 $bench_module:ident,
1638 $new_test_ext:expr,
1639 $test:path,
1640 benchmarks_path = $path_to_benchmarks_invocation:ident,
1641 extra = $extra:expr,
1642 exec_name = $exec_name:ident,
1643 @user:
1644 $(,)?
1645 ) => {
1646 $crate::impl_bench_case_tests!(
1647 { $bench_module, $new_test_ext, $exec_name, $test, $extra }
1648 { $( $names_extra:tt )* }
1649 $($names)+
1650 );
1651 };
1652 (
1654 @cases:
1655 ()
1656 ()
1657 ()
1658 @selected:
1659 $bench_module:ident,
1660 $new_test_ext:expr,
1661 $test:path,
1662 benchmarks_path = $path_to_benchmarks_invocation:ident,
1663 extra = $extra:expr,
1664 exec_name = $exec_name:ident,
1665 @user:
1666 $(,)?
1667 ) => {
1668 #[cfg(test)]
1669 mod benchmark_tests {
1670 use super::$bench_module;
1671
1672 #[test]
1673 fn test_benchmarks() {
1674 $new_test_ext.$exec_name(|| {
1675 use $crate::Benchmarking;
1676
1677 let mut anything_failed = false;
1678 println!("failing benchmark tests:");
1679 for benchmark_metadata in $bench_module::<$test>::benchmarks($extra) {
1680 let benchmark_name = &benchmark_metadata.name;
1681 match std::panic::catch_unwind(|| {
1682 $bench_module::<$test>::test_bench_by_name(benchmark_name)
1683 }) {
1684 Err(err) => {
1685 println!(
1686 "{}: {:?}",
1687 $crate::__private::str::from_utf8(benchmark_name)
1688 .expect("benchmark name is always a valid string!"),
1689 err,
1690 );
1691 anything_failed = true;
1692 },
1693 Ok(Err(err)) => {
1694 match err {
1695 $crate::BenchmarkError::Stop(err) => {
1696 println!(
1697 "{}: {:?}",
1698 $crate::__private::str::from_utf8(benchmark_name)
1699 .expect("benchmark name is always a valid string!"),
1700 err,
1701 );
1702 anything_failed = true;
1703 },
1704 $crate::BenchmarkError::Override(_) => {
1705 $crate::__private::log::error!(
1707 "WARNING: benchmark error overridden - {}",
1708 $crate::__private::str::from_utf8(benchmark_name)
1709 .expect("benchmark name is always a valid string!"),
1710 );
1711 },
1712 $crate::BenchmarkError::Skip => {
1713 $crate::__private::log::error!(
1715 "WARNING: benchmark error skipped - {}",
1716 $crate::__private::str::from_utf8(benchmark_name)
1717 .expect("benchmark name is always a valid string!"),
1718 );
1719 }
1720 $crate::BenchmarkError::Weightless => {
1721 $crate::__private::log::error!(
1723 "WARNING: benchmark weightless skipped - {}",
1724 $crate::__private::str::from_utf8(benchmark_name)
1725 .expect("benchmark name is always a valid string!"),
1726 );
1727 }
1728 }
1729 },
1730 Ok(Ok(())) => (),
1731 }
1732 }
1733 assert!(!anything_failed);
1734 });
1735 }
1736 }
1737 };
1738}
1739
1740pub fn show_benchmark_debug_info(
1743 instance_string: &[u8],
1744 benchmark: &[u8],
1745 components: &[(BenchmarkParameter, u32)],
1746 verify: &bool,
1747 error_message: &str,
1748) -> alloc::string::String {
1749 alloc::format!(
1750 "\n* Pallet: {}\n\
1751 * Benchmark: {}\n\
1752 * Components: {:?}\n\
1753 * Verify: {:?}\n\
1754 * Error message: {}",
1755 alloc::str::from_utf8(instance_string)
1756 .expect("it's all just strings ran through the wasm interface. qed"),
1757 alloc::str::from_utf8(benchmark)
1758 .expect("it's all just strings ran through the wasm interface. qed"),
1759 components,
1760 verify,
1761 error_message,
1762 )
1763}
1764
1765#[macro_export]
1828macro_rules! add_benchmark {
1829 ( $params:ident, $batches:ident, $name:path, $location:ty ) => {
1830 let pallet_string = stringify!($name).replace(" ", "").into_bytes();
1831 let instance_string = stringify!($location).replace(" ", "").into_bytes();
1832 let (config, whitelist) = $params;
1833 let $crate::BenchmarkConfig {
1834 pallet,
1835 instance,
1836 benchmark,
1837 selected_components,
1838 verify,
1839 internal_repeats,
1840 } = config;
1841 if &pallet[..] == &pallet_string[..] && &instance[..] == &instance_string[..] {
1842 let benchmark_result = <$location as $crate::Benchmarking>::run_benchmark(
1843 &benchmark[..],
1844 &selected_components[..],
1845 whitelist,
1846 *verify,
1847 *internal_repeats,
1848 );
1849
1850 let final_results = match benchmark_result {
1851 Ok(results) => Some(results),
1852 Err($crate::BenchmarkError::Override(mut result)) => {
1853 $crate::__private::log::error!(
1855 "WARNING: benchmark error overridden - {}",
1856 $crate::__private::str::from_utf8(benchmark)
1857 .expect("benchmark name is always a valid string!")
1858 );
1859 result.keys.insert(0, (b"Benchmark Override".to_vec(), 0, 0, false));
1860 Some($crate::__private::vec![result])
1861 },
1862 Err($crate::BenchmarkError::Stop(e)) => {
1863 $crate::show_benchmark_debug_info(
1864 &instance_string,
1865 benchmark,
1866 selected_components,
1867 verify,
1868 e,
1869 );
1870 return Err(e.into());
1871 },
1872 Err($crate::BenchmarkError::Skip) => {
1873 $crate::__private::log::error!(
1874 "WARNING: benchmark error skipped - {}",
1875 $crate::__private::str::from_utf8(benchmark)
1876 .expect("benchmark name is always a valid string!")
1877 );
1878 None
1879 },
1880 Err($crate::BenchmarkError::Weightless) => {
1881 $crate::__private::log::error!(
1882 "WARNING: benchmark weightless skipped - {}",
1883 $crate::__private::str::from_utf8(benchmark)
1884 .expect("benchmark name is always a valid string!")
1885 );
1886 Some($crate::__private::vec![$crate::BenchmarkResult {
1887 components: selected_components.clone(),
1888 ..Default::default()
1889 }])
1890 },
1891 };
1892
1893 if let Some(final_results) = final_results {
1894 $batches.push($crate::BenchmarkBatch {
1895 pallet: pallet_string,
1896 instance: instance_string,
1897 benchmark: benchmark.clone(),
1898 results: final_results,
1899 });
1900 }
1901 }
1902 };
1903}
1904
1905#[macro_export]
1925macro_rules! list_benchmark {
1926 ( $list:ident, $extra:ident, $name:path, $location:ty ) => {
1927 let pallet_string = stringify!($name).replace(" ", "").into_bytes();
1928 let instance_string = stringify!($location).replace(" ", "").into_bytes();
1929 let benchmarks = <$location as $crate::Benchmarking>::benchmarks($extra);
1930 let pallet_benchmarks = $crate::BenchmarkList {
1931 pallet: pallet_string,
1932 instance: instance_string,
1933 benchmarks: benchmarks.to_vec(),
1934 };
1935 $list.push(pallet_benchmarks)
1936 };
1937}
1938
1939#[macro_export]
1943macro_rules! define_benchmarks {
1944 ( $([ $names:path, $locations:ty ])* ) => {
1945 #[macro_export]
1953 macro_rules! list_benchmarks {
1954 ( $list:ident, $extra:ident ) => {
1955 $( $crate::list_benchmark!( $list, $extra, $names, $locations); )*
1956 }
1957 }
1958
1959 #[macro_export]
1967 macro_rules! add_benchmarks {
1968 ( $params:ident, $batches:ident ) => {
1969 $( $crate::add_benchmark!( $params, $batches, $names, $locations ); )*
1970 }
1971 }
1972 }
1973}
1974
1975pub use add_benchmark;
1976pub use benchmark_backend;
1977pub use benchmarks;
1978pub use benchmarks_instance;
1979pub use benchmarks_instance_pallet;
1980pub use benchmarks_iter;
1981pub use define_benchmarks;
1982pub use impl_bench_case_tests;
1983pub use impl_bench_name_tests;
1984pub use impl_benchmark;
1985pub use impl_benchmark_test;
1986pub use impl_benchmark_test_suite;
1987pub use impl_test_function;
1988pub use list_benchmark;
1989pub use selected_benchmark;
1990pub use to_origin;
1991pub use whitelist;