xref: /openbmc/linux/tools/perf/tests/expr.c (revision 9aba0ada)
1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
207516736SAndi Kleen #include "util/debug.h"
307516736SAndi Kleen #include "util/expr.h"
4a8e4e880SIan Rogers #include "util/smt.h"
507516736SAndi Kleen #include "tests.h"
607516736SAndi Kleen #include <stdlib.h>
78520a98dSArnaldo Carvalho de Melo #include <string.h>
8d8f9da24SArnaldo Carvalho de Melo #include <linux/zalloc.h>
907516736SAndi Kleen 
10114a9d6eSIan Rogers static int test_ids_union(void)
11114a9d6eSIan Rogers {
12114a9d6eSIan Rogers 	struct hashmap *ids1, *ids2;
13114a9d6eSIan Rogers 
14114a9d6eSIan Rogers 	/* Empty union. */
15114a9d6eSIan Rogers 	ids1 = ids__new();
16114a9d6eSIan Rogers 	TEST_ASSERT_VAL("ids__new", ids1);
17114a9d6eSIan Rogers 	ids2 = ids__new();
18114a9d6eSIan Rogers 	TEST_ASSERT_VAL("ids__new", ids2);
19114a9d6eSIan Rogers 
20114a9d6eSIan Rogers 	ids1 = ids__union(ids1, ids2);
21114a9d6eSIan Rogers 	TEST_ASSERT_EQUAL("union", (int)hashmap__size(ids1), 0);
22114a9d6eSIan Rogers 
23114a9d6eSIan Rogers 	/* Union {foo, bar} against {}. */
24114a9d6eSIan Rogers 	ids2 = ids__new();
25114a9d6eSIan Rogers 	TEST_ASSERT_VAL("ids__new", ids2);
26114a9d6eSIan Rogers 
2780be6434SIan Rogers 	TEST_ASSERT_EQUAL("ids__insert", ids__insert(ids1, strdup("foo")), 0);
2880be6434SIan Rogers 	TEST_ASSERT_EQUAL("ids__insert", ids__insert(ids1, strdup("bar")), 0);
29114a9d6eSIan Rogers 
30114a9d6eSIan Rogers 	ids1 = ids__union(ids1, ids2);
31114a9d6eSIan Rogers 	TEST_ASSERT_EQUAL("union", (int)hashmap__size(ids1), 2);
32114a9d6eSIan Rogers 
33114a9d6eSIan Rogers 	/* Union {foo, bar} against {foo}. */
34114a9d6eSIan Rogers 	ids2 = ids__new();
35114a9d6eSIan Rogers 	TEST_ASSERT_VAL("ids__new", ids2);
3680be6434SIan Rogers 	TEST_ASSERT_EQUAL("ids__insert", ids__insert(ids2, strdup("foo")), 0);
37114a9d6eSIan Rogers 
38114a9d6eSIan Rogers 	ids1 = ids__union(ids1, ids2);
39114a9d6eSIan Rogers 	TEST_ASSERT_EQUAL("union", (int)hashmap__size(ids1), 2);
40114a9d6eSIan Rogers 
41114a9d6eSIan Rogers 	/* Union {foo, bar} against {bar,baz}. */
42114a9d6eSIan Rogers 	ids2 = ids__new();
43114a9d6eSIan Rogers 	TEST_ASSERT_VAL("ids__new", ids2);
4480be6434SIan Rogers 	TEST_ASSERT_EQUAL("ids__insert", ids__insert(ids2, strdup("bar")), 0);
4580be6434SIan Rogers 	TEST_ASSERT_EQUAL("ids__insert", ids__insert(ids2, strdup("baz")), 0);
46114a9d6eSIan Rogers 
47114a9d6eSIan Rogers 	ids1 = ids__union(ids1, ids2);
48114a9d6eSIan Rogers 	TEST_ASSERT_EQUAL("union", (int)hashmap__size(ids1), 3);
49114a9d6eSIan Rogers 
50114a9d6eSIan Rogers 	ids__free(ids1);
51114a9d6eSIan Rogers 
52114a9d6eSIan Rogers 	return 0;
53114a9d6eSIan Rogers }
54114a9d6eSIan Rogers 
55aecce63eSJiri Olsa static int test(struct expr_parse_ctx *ctx, const char *e, double val2)
5607516736SAndi Kleen {
5707516736SAndi Kleen 	double val;
5807516736SAndi Kleen 
59fa831fbbSIan Rogers 	if (expr__parse(&val, ctx, e))
6007516736SAndi Kleen 		TEST_ASSERT_VAL("parse test failed", 0);
6107516736SAndi Kleen 	TEST_ASSERT_VAL("unexpected value", val == val2);
6207516736SAndi Kleen 	return 0;
6307516736SAndi Kleen }
6407516736SAndi Kleen 
6533f44bfdSIan Rogers static int test__expr(struct test_suite *t __maybe_unused, int subtest __maybe_unused)
6607516736SAndi Kleen {
67070b3b5aSJiri Olsa 	struct expr_id_data *val_ptr;
6807516736SAndi Kleen 	const char *p;
69fdf1e29bSIan Rogers 	double val, num_cpus, num_cores, num_dies, num_packages;
70ded80bdaSIan Rogers 	int ret;
71cb94a02eSIan Rogers 	struct expr_parse_ctx *ctx;
7207516736SAndi Kleen 
73114a9d6eSIan Rogers 	TEST_ASSERT_EQUAL("ids_union", test_ids_union(), 0);
74114a9d6eSIan Rogers 
75cb94a02eSIan Rogers 	ctx = expr__ctx_new();
76cb94a02eSIan Rogers 	TEST_ASSERT_VAL("expr__ctx_new", ctx);
77cb94a02eSIan Rogers 	expr__add_id_val(ctx, strdup("FOO"), 1);
78cb94a02eSIan Rogers 	expr__add_id_val(ctx, strdup("BAR"), 2);
7907516736SAndi Kleen 
80cb94a02eSIan Rogers 	ret = test(ctx, "1+1", 2);
81cb94a02eSIan Rogers 	ret |= test(ctx, "FOO+BAR", 3);
82cb94a02eSIan Rogers 	ret |= test(ctx, "(BAR/2)%2", 1);
83cb94a02eSIan Rogers 	ret |= test(ctx, "1 - -4",  5);
84cb94a02eSIan Rogers 	ret |= test(ctx, "(FOO-1)*2 + (BAR/2)%2 - -4",  5);
85cb94a02eSIan Rogers 	ret |= test(ctx, "1-1 | 1", 1);
86cb94a02eSIan Rogers 	ret |= test(ctx, "1-1 & 1", 0);
87cb94a02eSIan Rogers 	ret |= test(ctx, "min(1,2) + 1", 2);
88cb94a02eSIan Rogers 	ret |= test(ctx, "max(1,2) + 1", 3);
89cb94a02eSIan Rogers 	ret |= test(ctx, "1+1 if 3*4 else 0", 2);
90cb94a02eSIan Rogers 	ret |= test(ctx, "1.1 + 2.1", 3.2);
91cb94a02eSIan Rogers 	ret |= test(ctx, ".1 + 2.", 2.1);
92cb94a02eSIan Rogers 	ret |= test(ctx, "d_ratio(1, 2)", 0.5);
93cb94a02eSIan Rogers 	ret |= test(ctx, "d_ratio(2.5, 0)", 0);
94cb94a02eSIan Rogers 	ret |= test(ctx, "1.1 < 2.2", 1);
95cb94a02eSIan Rogers 	ret |= test(ctx, "2.2 > 1.1", 1);
96cb94a02eSIan Rogers 	ret |= test(ctx, "1.1 < 1.1", 0);
97cb94a02eSIan Rogers 	ret |= test(ctx, "2.2 > 2.2", 0);
98cb94a02eSIan Rogers 	ret |= test(ctx, "2.2 < 1.1", 0);
99cb94a02eSIan Rogers 	ret |= test(ctx, "1.1 > 2.2", 0);
10007516736SAndi Kleen 
101cb94a02eSIan Rogers 	if (ret) {
102cb94a02eSIan Rogers 		expr__ctx_free(ctx);
10307516736SAndi Kleen 		return ret;
104cb94a02eSIan Rogers 	}
10507516736SAndi Kleen 
10607516736SAndi Kleen 	p = "FOO/0";
107fa831fbbSIan Rogers 	ret = expr__parse(&val, ctx, p);
108d942815aSJiri Olsa 	TEST_ASSERT_VAL("division by zero", ret == -1);
10907516736SAndi Kleen 
11007516736SAndi Kleen 	p = "BAR/";
111fa831fbbSIan Rogers 	ret = expr__parse(&val, ctx, p);
112d942815aSJiri Olsa 	TEST_ASSERT_VAL("missing operand", ret == -1);
11307516736SAndi Kleen 
114cb94a02eSIan Rogers 	expr__ctx_clear(ctx);
1157e06a5e3SIan Rogers 	TEST_ASSERT_VAL("find ids",
1167e06a5e3SIan Rogers 			expr__find_ids("FOO + BAR + BAZ + BOZO", "FOO",
117fa831fbbSIan Rogers 					ctx) == 0);
1187e06a5e3SIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 3);
1197e06a5e3SIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "BAR",
120ded80bdaSIan Rogers 						    (void **)&val_ptr));
1217e06a5e3SIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "BAZ",
122ded80bdaSIan Rogers 						    (void **)&val_ptr));
1237e06a5e3SIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "BOZO",
124ded80bdaSIan Rogers 						    (void **)&val_ptr));
125f97a8991SChangbin Du 
126cb94a02eSIan Rogers 	expr__ctx_clear(ctx);
127fa831fbbSIan Rogers 	ctx->runtime = 3;
1287e06a5e3SIan Rogers 	TEST_ASSERT_VAL("find ids",
1297e06a5e3SIan Rogers 			expr__find_ids("EVENT1\\,param\\=?@ + EVENT2\\,param\\=?@",
130fa831fbbSIan Rogers 					NULL, ctx) == 0);
1317e06a5e3SIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 2);
132ec5c5b3dSIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT1,param=3@",
133ded80bdaSIan Rogers 						    (void **)&val_ptr));
134ec5c5b3dSIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "EVENT2,param=3@",
135ded80bdaSIan Rogers 						    (void **)&val_ptr));
1369022608eSKajol Jain 
137604ce2f0SIan Rogers 	expr__ctx_clear(ctx);
138604ce2f0SIan Rogers 	TEST_ASSERT_VAL("find ids",
139604ce2f0SIan Rogers 			expr__find_ids("dash\\-event1 - dash\\-event2",
140604ce2f0SIan Rogers 				       NULL, ctx) == 0);
141604ce2f0SIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 2);
142604ce2f0SIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "dash-event1",
143604ce2f0SIan Rogers 						    (void **)&val_ptr));
144604ce2f0SIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids, "dash-event2",
145604ce2f0SIan Rogers 						    (void **)&val_ptr));
146604ce2f0SIan Rogers 
147a8e4e880SIan Rogers 	/* Only EVENT1 or EVENT2 need be measured depending on the value of smt_on. */
148a8e4e880SIan Rogers 	expr__ctx_clear(ctx);
149a8e4e880SIan Rogers 	TEST_ASSERT_VAL("find ids",
150a8e4e880SIan Rogers 			expr__find_ids("EVENT1 if #smt_on else EVENT2",
151fa831fbbSIan Rogers 				NULL, ctx) == 0);
152a8e4e880SIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 1);
153a8e4e880SIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__find(ctx->ids,
154a8e4e880SIan Rogers 						  smt_on() ? "EVENT1" : "EVENT2",
155a8e4e880SIan Rogers 						  (void **)&val_ptr));
156a8e4e880SIan Rogers 
15794886961SIan Rogers 	/* The expression is a constant 1.0 without needing to evaluate EVENT1. */
15894886961SIan Rogers 	expr__ctx_clear(ctx);
15994886961SIan Rogers 	TEST_ASSERT_VAL("find ids",
16094886961SIan Rogers 			expr__find_ids("1.0 if EVENT1 > 100.0 else 1.0",
161fa831fbbSIan Rogers 			NULL, ctx) == 0);
16294886961SIan Rogers 	TEST_ASSERT_VAL("find ids", hashmap__size(ctx->ids) == 0);
16394886961SIan Rogers 
164fdf1e29bSIan Rogers 	/* Test toplogy constants appear well ordered. */
165fdf1e29bSIan Rogers 	expr__ctx_clear(ctx);
166fdf1e29bSIan Rogers 	TEST_ASSERT_VAL("#num_cpus", expr__parse(&num_cpus, ctx, "#num_cpus") == 0);
167fdf1e29bSIan Rogers 	TEST_ASSERT_VAL("#num_cores", expr__parse(&num_cores, ctx, "#num_cores") == 0);
168fdf1e29bSIan Rogers 	TEST_ASSERT_VAL("#num_cpus >= #num_cores", num_cpus >= num_cores);
169fdf1e29bSIan Rogers 	TEST_ASSERT_VAL("#num_dies", expr__parse(&num_dies, ctx, "#num_dies") == 0);
170fdf1e29bSIan Rogers 	TEST_ASSERT_VAL("#num_cores >= #num_dies", num_cores >= num_dies);
171fdf1e29bSIan Rogers 	TEST_ASSERT_VAL("#num_packages", expr__parse(&num_packages, ctx, "#num_packages") == 0);
172fdf1e29bSIan Rogers 	TEST_ASSERT_VAL("#num_dies >= #num_packages", num_dies >= num_packages);
173fdf1e29bSIan Rogers 
174*9aba0adaSIan Rogers 	/*
175*9aba0adaSIan Rogers 	 * Source count returns the number of events aggregating in a leader
176*9aba0adaSIan Rogers 	 * event including the leader. Check parsing yields an id.
177*9aba0adaSIan Rogers 	 */
178*9aba0adaSIan Rogers 	expr__ctx_clear(ctx);
179*9aba0adaSIan Rogers 	TEST_ASSERT_VAL("source count",
180*9aba0adaSIan Rogers 			expr__find_ids("source_count(EVENT1)",
181*9aba0adaSIan Rogers 			NULL, ctx) == 0);
182*9aba0adaSIan Rogers 	TEST_ASSERT_VAL("source count", hashmap__size(ctx->ids) == 1);
183*9aba0adaSIan Rogers 	TEST_ASSERT_VAL("source count", hashmap__find(ctx->ids, "EVENT1",
184*9aba0adaSIan Rogers 							(void **)&val_ptr));
185*9aba0adaSIan Rogers 
186cb94a02eSIan Rogers 	expr__ctx_free(ctx);
18707516736SAndi Kleen 
18807516736SAndi Kleen 	return 0;
18907516736SAndi Kleen }
190d68f0365SIan Rogers 
191d68f0365SIan Rogers DEFINE_SUITE("Simple expression parser", expr);
192