Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / tools / perf / tests / time-utils-test.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/compiler.h>
3 #include <linux/time64.h>
4 #include <inttypes.h>
5 #include <string.h>
6 #include "time-utils.h"
7 #include "evlist.h"
8 #include "session.h"
9 #include "debug.h"
10 #include "tests.h"
11
12 static bool test__parse_nsec_time(const char *str, u64 expected)
13 {
14         u64 ptime;
15         int err;
16
17         pr_debug("\nparse_nsec_time(\"%s\")\n", str);
18
19         err = parse_nsec_time(str, &ptime);
20         if (err) {
21                 pr_debug("error %d\n", err);
22                 return false;
23         }
24
25         if (ptime != expected) {
26                 pr_debug("Failed. ptime %" PRIu64 " expected %" PRIu64 "\n",
27                          ptime, expected);
28                 return false;
29         }
30
31         pr_debug("%" PRIu64 "\n", ptime);
32
33         return true;
34 }
35
36 static bool test__perf_time__parse_str(const char *ostr, u64 start, u64 end)
37 {
38         struct perf_time_interval ptime;
39         int err;
40
41         pr_debug("\nperf_time__parse_str(\"%s\")\n", ostr);
42
43         err = perf_time__parse_str(&ptime, ostr);
44         if (err) {
45                 pr_debug("Error %d\n", err);
46                 return false;
47         }
48
49         if (ptime.start != start || ptime.end != end) {
50                 pr_debug("Failed. Expected %" PRIu64 " to %" PRIu64 "\n",
51                          start, end);
52                 return false;
53         }
54
55         return true;
56 }
57
58 #define TEST_MAX 64
59
60 struct test_data {
61         const char *str;
62         u64 first;
63         u64 last;
64         struct perf_time_interval ptime[TEST_MAX];
65         int num;
66         u64 skip[TEST_MAX];
67         u64 noskip[TEST_MAX];
68 };
69
70 static bool test__perf_time__parse_for_ranges(struct test_data *d)
71 {
72         struct perf_evlist evlist = {
73                 .first_sample_time = d->first,
74                 .last_sample_time = d->last,
75         };
76         struct perf_session session = { .evlist = &evlist };
77         struct perf_time_interval *ptime = NULL;
78         int range_size, range_num;
79         bool pass = false;
80         int i, err;
81
82         pr_debug("\nperf_time__parse_for_ranges(\"%s\")\n", d->str);
83
84         if (strchr(d->str, '%'))
85                 pr_debug("first_sample_time %" PRIu64 " last_sample_time %" PRIu64 "\n",
86                          d->first, d->last);
87
88         err = perf_time__parse_for_ranges(d->str, &session, &ptime, &range_size,
89                                           &range_num);
90         if (err) {
91                 pr_debug("error %d\n", err);
92                 goto out;
93         }
94
95         if (range_size < d->num || range_num != d->num) {
96                 pr_debug("bad size: range_size %d range_num %d expected num %d\n",
97                          range_size, range_num, d->num);
98                 goto out;
99         }
100
101         for (i = 0; i < d->num; i++) {
102                 if (ptime[i].start != d->ptime[i].start ||
103                     ptime[i].end != d->ptime[i].end) {
104                         pr_debug("bad range %d expected %" PRIu64 " to %" PRIu64 "\n",
105                                  i, d->ptime[i].start, d->ptime[i].end);
106                         goto out;
107                 }
108         }
109
110         if (perf_time__ranges_skip_sample(ptime, d->num, 0)) {
111                 pr_debug("failed to keep 0\n");
112                 goto out;
113         }
114
115         for (i = 0; i < TEST_MAX; i++) {
116                 if (d->skip[i] &&
117                     !perf_time__ranges_skip_sample(ptime, d->num, d->skip[i])) {
118                         pr_debug("failed to skip %" PRIu64 "\n", d->skip[i]);
119                         goto out;
120                 }
121                 if (d->noskip[i] &&
122                     perf_time__ranges_skip_sample(ptime, d->num, d->noskip[i])) {
123                         pr_debug("failed to keep %" PRIu64 "\n", d->noskip[i]);
124                         goto out;
125                 }
126         }
127
128         pass = true;
129 out:
130         free(ptime);
131         return pass;
132 }
133
134 int test__time_utils(struct test *t __maybe_unused, int subtest __maybe_unused)
135 {
136         bool pass = true;
137
138         pass &= test__parse_nsec_time("0", 0);
139         pass &= test__parse_nsec_time("1", 1000000000ULL);
140         pass &= test__parse_nsec_time("0.000000001", 1);
141         pass &= test__parse_nsec_time("1.000000001", 1000000001ULL);
142         pass &= test__parse_nsec_time("123456.123456", 123456123456000ULL);
143         pass &= test__parse_nsec_time("1234567.123456789", 1234567123456789ULL);
144         pass &= test__parse_nsec_time("18446744073.709551615",
145                                       0xFFFFFFFFFFFFFFFFULL);
146
147         pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456789",
148                                            1234567123456789ULL, 1234567123456789ULL);
149         pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456790",
150                                            1234567123456789ULL, 1234567123456790ULL);
151         pass &= test__perf_time__parse_str("1234567.123456789,",
152                                            1234567123456789ULL, 0);
153         pass &= test__perf_time__parse_str(",1234567.123456789",
154                                            0, 1234567123456789ULL);
155         pass &= test__perf_time__parse_str("0,1234567.123456789",
156                                            0, 1234567123456789ULL);
157
158         {
159                 u64 b = 1234567123456789ULL;
160                 struct test_data d = {
161                         .str   = "1234567.123456789,1234567.123456790",
162                         .ptime = { {b, b + 1}, },
163                         .num = 1,
164                         .skip = { b - 1, b + 2, },
165                         .noskip = { b, b + 1, },
166                 };
167
168                 pass &= test__perf_time__parse_for_ranges(&d);
169         }
170
171         {
172                 u64 b = 1234567123456789ULL;
173                 u64 c = 7654321987654321ULL;
174                 u64 e = 8000000000000000ULL;
175                 struct test_data d = {
176                         .str   = "1234567.123456789,1234567.123456790 "
177                                  "7654321.987654321,7654321.987654444 "
178                                  "8000000,8000000.000000005",
179                         .ptime = { {b, b + 1}, {c, c + 123}, {e, e + 5}, },
180                         .num = 3,
181                         .skip = { b - 1, b + 2, c - 1, c + 124, e - 1, e + 6 },
182                         .noskip = { b, b + 1, c, c + 123, e, e + 5 },
183                 };
184
185                 pass &= test__perf_time__parse_for_ranges(&d);
186         }
187
188         {
189                 u64 b = 7654321ULL * NSEC_PER_SEC;
190                 struct test_data d = {
191                         .str    = "10%/1",
192                         .first  = b,
193                         .last   = b + 100,
194                         .ptime  = { {b, b + 9}, },
195                         .num    = 1,
196                         .skip   = { b - 1, b + 10, },
197                         .noskip = { b, b + 9, },
198                 };
199
200                 pass &= test__perf_time__parse_for_ranges(&d);
201         }
202
203         {
204                 u64 b = 7654321ULL * NSEC_PER_SEC;
205                 struct test_data d = {
206                         .str    = "10%/2",
207                         .first  = b,
208                         .last   = b + 100,
209                         .ptime  = { {b + 10, b + 19}, },
210                         .num    = 1,
211                         .skip   = { b + 9, b + 20, },
212                         .noskip = { b + 10, b + 19, },
213                 };
214
215                 pass &= test__perf_time__parse_for_ranges(&d);
216         }
217
218         {
219                 u64 b = 11223344ULL * NSEC_PER_SEC;
220                 struct test_data d = {
221                         .str    = "10%/1,10%/2",
222                         .first  = b,
223                         .last   = b + 100,
224                         .ptime  = { {b, b + 9}, {b + 10, b + 19}, },
225                         .num    = 2,
226                         .skip   = { b - 1, b + 20, },
227                         .noskip = { b, b + 8, b + 9, b + 10, b + 11, b + 12, b + 19, },
228                 };
229
230                 pass &= test__perf_time__parse_for_ranges(&d);
231         }
232
233         {
234                 u64 b = 11223344ULL * NSEC_PER_SEC;
235                 struct test_data d = {
236                         .str    = "10%/1,10%/3,10%/10",
237                         .first  = b,
238                         .last   = b + 100,
239                         .ptime  = { {b, b + 9}, {b + 20, b + 29}, { b + 90, b + 100}, },
240                         .num    = 3,
241                         .skip   = { b - 1, b + 10, b + 19, b + 30, b + 89, b + 101 },
242                         .noskip = { b, b + 9, b + 20, b + 29, b + 90, b + 100},
243                 };
244
245                 pass &= test__perf_time__parse_for_ranges(&d);
246         }
247
248         pr_debug("\n");
249
250         return pass ? 0 : TEST_FAIL;
251 }