1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23 #pragma once
24
25 #include <inttypes.h>
26
27 #include <lib/unittest/unittest.h>
28 #include "trusty_bench_option_cb.h"
29
30 /*
31 * Up this by one if any change to the output is performed in a way that prevent
32 * schema validation. Schema is available in the same folder as this file
33 * "trusty_bench_json_schema.vXXX.json"
34 */
35 #define BENCH_SCHEMA_VERSION "3"
36
37 /**
38 * trusty_bench_print_json_metric_list - Prints a machine readable json of all
39 * statistical aggregates for all param/metric in the last BENCH
40 * @metric_list: List of metrics aggregated during all BENCH runs.
41 * @nb_params: Number of Parameters in the param array of BENCH.
42 * @suite_name: Name of the Bench Suite
43 * @bench_name: Name of the Bench
44 */
trusty_bench_print_json_metric_list(struct list_node * metric_list,size_t nb_params,const char * suite_name,const char * bench_name)45 static inline void trusty_bench_print_json_metric_list(
46 struct list_node* metric_list,
47 size_t nb_params,
48 const char* suite_name,
49 const char* bench_name) {
50 trusty_unittest_printf("{");
51 trusty_unittest_printf("\"schema_version\": " BENCH_SCHEMA_VERSION ",\n");
52 trusty_unittest_printf("\"suite_name\": \"%s\",\n", suite_name);
53 trusty_unittest_printf("\"bench_name\": \"%s\",\n", bench_name);
54
55 trusty_unittest_printf("\"results\": [");
56 struct bench_metric_list_node* entry;
57 char buf[BENCH_MAX_COL_SIZE];
58 bool first_iter = true;
59
60 list_for_every_entry(metric_list, entry, struct bench_metric_list_node,
61 node) {
62 if (!first_iter) {
63 trusty_unittest_printf(",");
64 }
65 first_iter = false;
66 trusty_unittest_printf("{");
67 trusty_unittest_printf("\"metric_name\": \"%s\", ", entry->name);
68 if (nb_params > 1 || trusty_bench_nb_cpu > 1) {
69 trusty_unittest_printf("\"param_id\": %zu, ",
70 entry->param_idx % entry->nb_params);
71 if (entry->param_name_cb) {
72 entry->param_name_cb(buf, sizeof(buf),
73 entry->param_idx % entry->nb_params);
74 trusty_unittest_printf("\"param_name\": \"%s\", ", buf);
75 } else if (trusty_bench_get_param_name_cb) {
76 trusty_bench_get_param_name_cb(
77 buf, sizeof(buf), entry->param_idx % entry->nb_params);
78 trusty_unittest_printf("\"param_name\": \"%s\", ", buf);
79 }
80 }
81 /* print formatted values */
82 trusty_bench_sprint_col_stat(
83 buf, sizeof(buf), entry->metric.aggregates[BENCH_AGGREGATE_MIN],
84 entry->name);
85 trusty_unittest_printf("\"min\": \"%s\",", buf);
86 trusty_bench_sprint_col_stat(
87 buf, sizeof(buf), entry->metric.aggregates[BENCH_AGGREGATE_MAX],
88 entry->name);
89 trusty_unittest_printf("\"max\": \"%s\",", buf);
90 trusty_bench_sprint_col_stat(
91 buf, sizeof(buf), entry->metric.aggregates[BENCH_AGGREGATE_AVG],
92 entry->name);
93 trusty_unittest_printf("\"avg\": \"%s\",", buf);
94 trusty_bench_sprint_col_stat(buf, sizeof(buf), entry->metric.cold,
95 entry->name);
96 trusty_unittest_printf("\"cold\": \"%s\",", buf);
97
98 /* Formatting is conditional to Metric Name, so we always print raw
99 * values even when a formatter callback is present
100 */
101 trusty_unittest_printf("\"raw_min\": %" PRId64 ", ",
102 entry->metric.aggregates[BENCH_AGGREGATE_MIN]);
103 trusty_unittest_printf("\"raw_max\": %" PRId64 ", ",
104 entry->metric.aggregates[BENCH_AGGREGATE_MAX]);
105 trusty_unittest_printf("\"raw_avg\": %" PRId64 ", ",
106 entry->metric.aggregates[BENCH_AGGREGATE_AVG]);
107 trusty_unittest_printf("\"raw_cold\": %" PRId64, entry->metric.cold);
108 trusty_unittest_printf("}\n");
109 }
110 trusty_unittest_printf("]");
111 trusty_unittest_printf("}\n");
112 }
113