Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf tests: Add a test for time-utils

Test time ranges work as expected.

Committer testing:

$ perf test "time utils"
59: time utils : Ok
$ perf test -v "time utils"
59: time utils :
--- start ---
test child forked, pid 31711

parse_nsec_time("0")
0

parse_nsec_time("1")
1000000000

parse_nsec_time("0.000000001")
1

parse_nsec_time("1.000000001")
1000000001

parse_nsec_time("123456.123456")
123456123456000

parse_nsec_time("1234567.123456789")
1234567123456789

parse_nsec_time("18446744073.709551615")
18446744073709551615

perf_time__parse_str("1234567.123456789,1234567.123456789")
start time 1234567123456789, end time 1234567123456789

perf_time__parse_str("1234567.123456789,1234567.123456790")
start time 1234567123456789, end time 1234567123456790

perf_time__parse_str("1234567.123456789,")
start time 1234567123456789, end time 0

perf_time__parse_str(",1234567.123456789")
start time 0, end time 1234567123456789

perf_time__parse_str("0,1234567.123456789")
start time 0, end time 1234567123456789

perf_time__parse_for_ranges("1234567.123456789,1234567.123456790")
start time 1234567123456789, end time 1234567123456790

perf_time__parse_for_ranges("10%/1")
first_sample_time 7654321000000000 last_sample_time 7654321000000100
start time 0: 7654321000000000, end time 0: 7654321000000009

perf_time__parse_for_ranges("10%/2")
first_sample_time 7654321000000000 last_sample_time 7654321000000100
start time 0: 7654321000000010, end time 0: 7654321000000019

perf_time__parse_for_ranges("10%/1,10%/2")
first_sample_time 11223344000000000 last_sample_time 11223344000000100
start time 0: 11223344000000000, end time 0: 11223344000000009
start time 1: 11223344000000010, end time 1: 11223344000000019

perf_time__parse_for_ranges("10%/1,10%/3,10%/10")
first_sample_time 11223344000000000 last_sample_time 11223344000000100
start time 0: 11223344000000000, end time 0: 11223344000000009
start time 1: 11223344000000020, end time 1: 11223344000000029
start time 2: 11223344000000090, end time 2: 11223344000000100

test child finished with 0
---- end ----
time utils: Ok
$

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jin Yao <yao.jin@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20190604130017.31207-19-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Adrian Hunter and committed by
Arnaldo Carvalho de Melo
e39a12cb 929afa00

+240
+1
tools/perf/tests/Build
··· 51 51 perf-y += unit_number__scnprintf.o 52 52 perf-y += mem2node.o 53 53 perf-y += map_groups.o 54 + perf-y += time-utils-test.o 54 55 55 56 $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build 56 57 $(call rule_mkdir)
+4
tools/perf/tests/builtin-test.c
··· 290 290 .func = test__mem2node, 291 291 }, 292 292 { 293 + .desc = "time utils", 294 + .func = test__time_utils, 295 + }, 296 + { 293 297 .desc = "map_groups__merge_in", 294 298 .func = test__map_groups__merge_in, 295 299 },
+1
tools/perf/tests/tests.h
··· 108 108 int test__unit_number__scnprint(struct test *test, int subtest); 109 109 int test__mem2node(struct test *t, int subtest); 110 110 int test__map_groups__merge_in(struct test *t, int subtest); 111 + int test__time_utils(struct test *t, int subtest); 111 112 112 113 bool test__bp_signal_is_supported(void); 113 114 bool test__wp_is_supported(void);
+234
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 = 7654321ULL * NSEC_PER_SEC; 173 + struct test_data d = { 174 + .str = "10%/1", 175 + .first = b, 176 + .last = b + 100, 177 + .ptime = { {b, b + 9}, }, 178 + .num = 1, 179 + .skip = { b - 1, b + 10, }, 180 + .noskip = { b, b + 9, }, 181 + }; 182 + 183 + pass &= test__perf_time__parse_for_ranges(&d); 184 + } 185 + 186 + { 187 + u64 b = 7654321ULL * NSEC_PER_SEC; 188 + struct test_data d = { 189 + .str = "10%/2", 190 + .first = b, 191 + .last = b + 100, 192 + .ptime = { {b + 10, b + 19}, }, 193 + .num = 1, 194 + .skip = { b + 9, b + 20, }, 195 + .noskip = { b + 10, b + 19, }, 196 + }; 197 + 198 + pass &= test__perf_time__parse_for_ranges(&d); 199 + } 200 + 201 + { 202 + u64 b = 11223344ULL * NSEC_PER_SEC; 203 + struct test_data d = { 204 + .str = "10%/1,10%/2", 205 + .first = b, 206 + .last = b + 100, 207 + .ptime = { {b, b + 9}, {b + 10, b + 19}, }, 208 + .num = 2, 209 + .skip = { b - 1, b + 20, }, 210 + .noskip = { b, b + 8, b + 9, b + 10, b + 11, b + 12, b + 19, }, 211 + }; 212 + 213 + pass &= test__perf_time__parse_for_ranges(&d); 214 + } 215 + 216 + { 217 + u64 b = 11223344ULL * NSEC_PER_SEC; 218 + struct test_data d = { 219 + .str = "10%/1,10%/3,10%/10", 220 + .first = b, 221 + .last = b + 100, 222 + .ptime = { {b, b + 9}, {b + 20, b + 29}, { b + 90, b + 100}, }, 223 + .num = 3, 224 + .skip = { b - 1, b + 10, b + 19, b + 30, b + 89, b + 101 }, 225 + .noskip = { b, b + 9, b + 20, b + 29, b + 90, b + 100}, 226 + }; 227 + 228 + pass &= test__perf_time__parse_for_ranges(&d); 229 + } 230 + 231 + pr_debug("\n"); 232 + 233 + return pass ? 0 : TEST_FAIL; 234 + }