1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * User Events Dyn Events Test Program
4 *
5 * Copyright (c) 2021 Beau Belgrave <beaub@linux.microsoft.com>
6 */
7
8 #include <errno.h>
9 #include <linux/user_events.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <fcntl.h>
13 #include <sys/ioctl.h>
14 #include <sys/stat.h>
15 #include <unistd.h>
16
17 #include "../kselftest_harness.h"
18
19 const char *dyn_file = "/sys/kernel/debug/tracing/dynamic_events";
20 const char *clear = "!u:__test_event";
21
Append(const char * value)22 static int Append(const char *value)
23 {
24 int fd = open(dyn_file, O_RDWR | O_APPEND);
25 int ret = write(fd, value, strlen(value));
26
27 close(fd);
28 return ret;
29 }
30
31 #define CLEAR() \
32 do { \
33 int ret = Append(clear); \
34 if (ret == -1) \
35 ASSERT_EQ(ENOENT, errno); \
36 } while (0)
37
38 #define TEST_PARSE(x) \
39 do { \
40 ASSERT_NE(-1, Append(x)); \
41 CLEAR(); \
42 } while (0)
43
44 #define TEST_NPARSE(x) ASSERT_EQ(-1, Append(x))
45
FIXTURE(user)46 FIXTURE(user) {
47 };
48
FIXTURE_SETUP(user)49 FIXTURE_SETUP(user) {
50 CLEAR();
51 }
52
FIXTURE_TEARDOWN(user)53 FIXTURE_TEARDOWN(user) {
54 CLEAR();
55 }
56
TEST_F(user,basic_types)57 TEST_F(user, basic_types) {
58 /* All should work */
59 TEST_PARSE("u:__test_event u64 a");
60 TEST_PARSE("u:__test_event u32 a");
61 TEST_PARSE("u:__test_event u16 a");
62 TEST_PARSE("u:__test_event u8 a");
63 TEST_PARSE("u:__test_event char a");
64 TEST_PARSE("u:__test_event unsigned char a");
65 TEST_PARSE("u:__test_event int a");
66 TEST_PARSE("u:__test_event unsigned int a");
67 TEST_PARSE("u:__test_event short a");
68 TEST_PARSE("u:__test_event unsigned short a");
69 TEST_PARSE("u:__test_event char[20] a");
70 TEST_PARSE("u:__test_event unsigned char[20] a");
71 TEST_PARSE("u:__test_event char[0x14] a");
72 TEST_PARSE("u:__test_event unsigned char[0x14] a");
73 /* Bad size format should fail */
74 TEST_NPARSE("u:__test_event char[aa] a");
75 /* Large size should fail */
76 TEST_NPARSE("u:__test_event char[9999] a");
77 /* Long size string should fail */
78 TEST_NPARSE("u:__test_event char[0x0000000000001] a");
79 }
80
TEST_F(user,loc_types)81 TEST_F(user, loc_types) {
82 /* All should work */
83 TEST_PARSE("u:__test_event __data_loc char[] a");
84 TEST_PARSE("u:__test_event __data_loc unsigned char[] a");
85 TEST_PARSE("u:__test_event __rel_loc char[] a");
86 TEST_PARSE("u:__test_event __rel_loc unsigned char[] a");
87 }
88
TEST_F(user,size_types)89 TEST_F(user, size_types) {
90 /* Should work */
91 TEST_PARSE("u:__test_event struct custom a 20");
92 /* Size not specified on struct should fail */
93 TEST_NPARSE("u:__test_event struct custom a");
94 /* Size specified on non-struct should fail */
95 TEST_NPARSE("u:__test_event char a 20");
96 }
97
TEST_F(user,flags)98 TEST_F(user, flags) {
99 /* Should work */
100 TEST_PARSE("u:__test_event:BPF_ITER u32 a");
101 /* Forward compat */
102 TEST_PARSE("u:__test_event:BPF_ITER,FLAG_FUTURE u32 a");
103 }
104
TEST_F(user,matching)105 TEST_F(user, matching) {
106 /* Register */
107 ASSERT_NE(-1, Append("u:__test_event struct custom a 20"));
108 /* Should not match */
109 TEST_NPARSE("!u:__test_event struct custom b");
110 /* Should match */
111 TEST_PARSE("!u:__test_event struct custom a");
112 /* Multi field reg */
113 ASSERT_NE(-1, Append("u:__test_event u32 a; u32 b"));
114 /* Non matching cases */
115 TEST_NPARSE("!u:__test_event u32 a");
116 TEST_NPARSE("!u:__test_event u32 b");
117 TEST_NPARSE("!u:__test_event u32 a; u32 ");
118 TEST_NPARSE("!u:__test_event u32 a; u32 a");
119 /* Matching case */
120 TEST_PARSE("!u:__test_event u32 a; u32 b");
121 /* Register */
122 ASSERT_NE(-1, Append("u:__test_event u32 a; u32 b"));
123 /* Ensure trailing semi-colon case */
124 TEST_PARSE("!u:__test_event u32 a; u32 b;");
125 }
126
main(int argc,char ** argv)127 int main(int argc, char **argv)
128 {
129 return test_harness_run(argc, argv);
130 }
131