projects/linux·blob master · refs

257 lines · 6.2 KiB

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
12static 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
36static 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
60struct 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
70static bool test__perf_time__parse_for_ranges(struct test_data *d)
71{
72 struct evlist *evlist = evlist__new();
73 struct perf_session session = { .evlist = evlist };
74 struct perf_time_interval *ptime = NULL;
75 int range_size, range_num;
76 bool pass = false;
77 int i, err;
78
79 if (!evlist) {
80 pr_debug("Missing evlist\n");
81 return false;
82 }
83 evlist__set_first_sample_time(evlist, d->first);
84 evlist__set_last_sample_time(evlist, d->last);
85 pr_debug("\nperf_time__parse_for_ranges(\"%s\")\n", d->str);
86
87 if (strchr(d->str, '%'))
88 pr_debug("first_sample_time %" PRIu64 " last_sample_time %" PRIu64 "\n",
89 d->first, d->last);
90
91 err = perf_time__parse_for_ranges(d->str, &session, &ptime, &range_size,
92 &range_num);
93 if (err) {
94 pr_debug("error %d\n", err);
95 goto out;
96 }
97
98 if (range_size < d->num || range_num != d->num) {
99 pr_debug("bad size: range_size %d range_num %d expected num %d\n",
100 range_size, range_num, d->num);
101 goto out;
102 }
103
104 for (i = 0; i < d->num; i++) {
105 if (ptime[i].start != d->ptime[i].start ||
106 ptime[i].end != d->ptime[i].end) {
107 pr_debug("bad range %d expected %" PRIu64 " to %" PRIu64 "\n",
108 i, d->ptime[i].start, d->ptime[i].end);
109 goto out;
110 }
111 }
112
113 if (perf_time__ranges_skip_sample(ptime, d->num, 0)) {
114 pr_debug("failed to keep 0\n");
115 goto out;
116 }
117
118 for (i = 0; i < TEST_MAX; i++) {
119 if (d->skip[i] &&
120 !perf_time__ranges_skip_sample(ptime, d->num, d->skip[i])) {
121 pr_debug("failed to skip %" PRIu64 "\n", d->skip[i]);
122 goto out;
123 }
124 if (d->noskip[i] &&
125 perf_time__ranges_skip_sample(ptime, d->num, d->noskip[i])) {
126 pr_debug("failed to keep %" PRIu64 "\n", d->noskip[i]);
127 goto out;
128 }
129 }
130
131 pass = true;
132out:
133 evlist__put(evlist);
134 free(ptime);
135 return pass;
136}
137
138static int test__time_utils(struct test_suite *t __maybe_unused, int subtest __maybe_unused)
139{
140 bool pass = true;
141
142 pass &= test__parse_nsec_time("0", 0);
143 pass &= test__parse_nsec_time("1", 1000000000ULL);
144 pass &= test__parse_nsec_time("0.000000001", 1);
145 pass &= test__parse_nsec_time("1.000000001", 1000000001ULL);
146 pass &= test__parse_nsec_time("123456.123456", 123456123456000ULL);
147 pass &= test__parse_nsec_time("1234567.123456789", 1234567123456789ULL);
148 pass &= test__parse_nsec_time("18446744073.709551615",
149 0xFFFFFFFFFFFFFFFFULL);
150
151 pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456789",
152 1234567123456789ULL, 1234567123456789ULL);
153 pass &= test__perf_time__parse_str("1234567.123456789,1234567.123456790",
154 1234567123456789ULL, 1234567123456790ULL);
155 pass &= test__perf_time__parse_str("1234567.123456789,",
156 1234567123456789ULL, 0);
157 pass &= test__perf_time__parse_str(",1234567.123456789",
158 0, 1234567123456789ULL);
159 pass &= test__perf_time__parse_str("0,1234567.123456789",
160 0, 1234567123456789ULL);
161
162 {
163 u64 b = 1234567123456789ULL;
164 struct test_data d = {
165 .str = "1234567.123456789,1234567.123456790",
166 .ptime = { {b, b + 1}, },
167 .num = 1,
168 .skip = { b - 1, b + 2, },
169 .noskip = { b, b + 1, },
170 };
171
172 pass &= test__perf_time__parse_for_ranges(&d);
173 }
174
175 {
176 u64 b = 1234567123456789ULL;
177 u64 c = 7654321987654321ULL;
178 u64 e = 8000000000000000ULL;
179 struct test_data d = {
180 .str = "1234567.123456789,1234567.123456790 "
181 "7654321.987654321,7654321.987654444 "
182 "8000000,8000000.000000005",
183 .ptime = { {b, b + 1}, {c, c + 123}, {e, e + 5}, },
184 .num = 3,
185 .skip = { b - 1, b + 2, c - 1, c + 124, e - 1, e + 6 },
186 .noskip = { b, b + 1, c, c + 123, e, e + 5 },
187 };
188
189 pass &= test__perf_time__parse_for_ranges(&d);
190 }
191
192 {
193 u64 b = 7654321ULL * NSEC_PER_SEC;
194 struct test_data d = {
195 .str = "10%/1",
196 .first = b,
197 .last = b + 100,
198 .ptime = { {b, b + 9}, },
199 .num = 1,
200 .skip = { b - 1, b + 10, },
201 .noskip = { b, b + 9, },
202 };
203
204 pass &= test__perf_time__parse_for_ranges(&d);
205 }
206
207 {
208 u64 b = 7654321ULL * NSEC_PER_SEC;
209 struct test_data d = {
210 .str = "10%/2",
211 .first = b,
212 .last = b + 100,
213 .ptime = { {b + 10, b + 19}, },
214 .num = 1,
215 .skip = { b + 9, b + 20, },
216 .noskip = { b + 10, b + 19, },
217 };
218
219 pass &= test__perf_time__parse_for_ranges(&d);
220 }
221
222 {
223 u64 b = 11223344ULL * NSEC_PER_SEC;
224 struct test_data d = {
225 .str = "10%/1,10%/2",
226 .first = b,
227 .last = b + 100,
228 .ptime = { {b, b + 9}, {b + 10, b + 19}, },
229 .num = 2,
230 .skip = { b - 1, b + 20, },
231 .noskip = { b, b + 8, b + 9, b + 10, b + 11, b + 12, b + 19, },
232 };
233
234 pass &= test__perf_time__parse_for_ranges(&d);
235 }
236
237 {
238 u64 b = 11223344ULL * NSEC_PER_SEC;
239 struct test_data d = {
240 .str = "10%/1,10%/3,10%/10",
241 .first = b,
242 .last = b + 100,
243 .ptime = { {b, b + 9}, {b + 20, b + 29}, { b + 90, b + 100}, },
244 .num = 3,
245 .skip = { b - 1, b + 10, b + 19, b + 30, b + 89, b + 101 },
246 .noskip = { b, b + 9, b + 20, b + 29, b + 90, b + 100},
247 };
248
249 pass &= test__perf_time__parse_for_ranges(&d);
250 }
251
252 pr_debug("\n");
253
254 return pass ? 0 : TEST_FAIL;
255}
256
257DEFINE_SUITE("time utils", time_utils);