254 lines · c
1// SPDX-License-Identifier: GPL-2.02#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 6459 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 = {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;129out:130 free(ptime);131 return pass;132}133 134static int test__time_utils(struct test_suite *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}252 253DEFINE_SUITE("time utils", time_utils);254