stat+std_output.sh 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. #!/bin/bash
  2. # perf stat STD output linter
  3. # SPDX-License-Identifier: GPL-2.0
  4. # Tests various perf stat STD output commands for
  5. # default event and metricgroup
  6. set -e
  7. # shellcheck source=lib/stat_output.sh
  8. . "$(dirname $0)"/lib/stat_output.sh
  9. stat_output=$(mktemp /tmp/__perf_test.stat_output.std.XXXXX)
  10. event_name=(cpu-clock task-clock context-switches cpu-migrations page-faults stalled-cycles-frontend stalled-cycles-backend cycles instructions branches branch-misses)
  11. event_metric=("CPUs_utilized" "CPUs_utilized" "cs/sec" "migrations/sec" "faults/sec" "frontend_cycles_idle" "backend_cycles_idle" "GHz" "insn_per_cycle" "/sec" "branch_miss_rate")
  12. skip_metric=("tma_" "TopdownL1")
  13. cleanup() {
  14. rm -f "${stat_output}"
  15. trap - EXIT TERM INT
  16. }
  17. trap_cleanup() {
  18. cleanup
  19. exit 1
  20. }
  21. trap trap_cleanup EXIT TERM INT
  22. function commachecker()
  23. {
  24. local prefix=1
  25. local -i metric_only=0
  26. case "$1"
  27. in "--interval") prefix=2
  28. ;; "--per-thread") prefix=2
  29. ;; "--system-wide-no-aggr") prefix=2
  30. ;; "--per-core") prefix=3
  31. ;; "--per-socket") prefix=3
  32. ;; "--per-node") prefix=3
  33. ;; "--per-die") prefix=3
  34. ;; "--per-cache") prefix=3
  35. ;; "--per-cluster") prefix=3
  36. ;; "--metric-only") metric_only=1
  37. esac
  38. while read line
  39. do
  40. # Ignore initial "started on" comment.
  41. x=${line:0:1}
  42. [ "$x" = "#" ] && continue
  43. # Ignore initial blank line.
  44. [ "$line" = "" ] && continue
  45. # Ignore "Performance counter stats"
  46. x=${line:0:25}
  47. [ "$x" = "Performance counter stats" ] && continue
  48. # Ignore "seconds time elapsed" and break
  49. [[ "$line" == *"time elapsed"* ]] && break
  50. main_body=$(echo $line | cut -d' ' -f$prefix-)
  51. x=${main_body%#*}
  52. [ "$x" = "" ] && continue
  53. # Check metric only - if it has a non-empty result
  54. [ $metric_only -eq 1 ] && return 0
  55. # Skip metrics without event name
  56. y=${main_body#*#}
  57. for i in "${!skip_metric[@]}"; do
  58. [[ "$y" == *"${skip_metric[$i]}"* ]] && break
  59. done
  60. [[ "$y" == *"${skip_metric[$i]}"* ]] && continue
  61. # Check default event
  62. for i in "${!event_name[@]}"; do
  63. [[ "$x" == *"${event_name[$i]}"* ]] && break
  64. done
  65. [[ ! "$x" == *"${event_name[$i]}"* ]] && {
  66. echo "Unknown event name in $line" 1>&2
  67. exit 1;
  68. }
  69. # Check event metric if it exists
  70. [[ ! "$main_body" == *"#"* ]] && continue
  71. [[ ! "$main_body" == *"${event_metric[$i]}"* ]] && {
  72. echo "wrong event metric. expected ${event_metric[$i]} in $line" 1>&2
  73. exit 1;
  74. }
  75. done < "${stat_output}"
  76. if [ $metric_only -ne 1 ]
  77. then
  78. echo "Missing metric only output in:"
  79. cat "${stat_output}"
  80. fi
  81. return 0
  82. }
  83. perf_cmd="-o ${stat_output}"
  84. skip_test=$(check_for_topology)
  85. check_no_args "STD" "$perf_cmd"
  86. check_system_wide "STD" "$perf_cmd"
  87. check_interval "STD" "$perf_cmd"
  88. check_per_thread "STD" "$perf_cmd"
  89. check_per_node "STD" "$perf_cmd"
  90. check_metric_only "STD" "$perf_cmd"
  91. if [ $skip_test -ne 1 ]
  92. then
  93. check_system_wide_no_aggr "STD" "$perf_cmd"
  94. check_per_core "STD" "$perf_cmd"
  95. check_per_cache_instance "STD" "$perf_cmd"
  96. check_per_cluster "STD" "$perf_cmd"
  97. check_per_die "STD" "$perf_cmd"
  98. check_per_socket "STD" "$perf_cmd"
  99. else
  100. echo "[Skip] Skipping tests for system_wide_no_aggr, per_core, per_die and per_socket since socket id exposed via topology is invalid"
  101. fi
  102. cleanup
  103. exit 0