cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

time-utils-test.c (6174B)


      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 = {
     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);