selftests/user_events: Adapt dyn_test to non-persist events
Now that user_events does not honor persist events the dynamic_events file cannot be easily used to test parsing and matching cases. Update dyn_test to use the direct ABI file instead of dynamic_events so that we still have testing coverage until persist events and dynamic_events file integration has been decided. Link: https://lkml.kernel.org/r/20230614163336.5797-6-beaub@linux.microsoft.com Signed-off-by: Beau Belgrave <beaub@linux.microsoft.com> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
This commit is contained in:
parent
216a137e3e
commit
61701242e8
|
@ -16,42 +16,140 @@
|
||||||
|
|
||||||
#include "../kselftest_harness.h"
|
#include "../kselftest_harness.h"
|
||||||
|
|
||||||
const char *dyn_file = "/sys/kernel/tracing/dynamic_events";
|
const char *abi_file = "/sys/kernel/tracing/user_events_data";
|
||||||
const char *clear = "!u:__test_event";
|
const char *enable_file = "/sys/kernel/tracing/events/user_events/__test_event/enable";
|
||||||
|
|
||||||
static int Append(const char *value)
|
static bool wait_for_delete(void)
|
||||||
{
|
{
|
||||||
int fd = open(dyn_file, O_RDWR | O_APPEND);
|
int i;
|
||||||
int ret = write(fd, value, strlen(value));
|
|
||||||
|
for (i = 0; i < 1000; ++i) {
|
||||||
|
int fd = open(enable_file, O_RDONLY);
|
||||||
|
|
||||||
|
if (fd == -1)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
usleep(1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int reg_event(int fd, int *check, int bit, const char *value)
|
||||||
|
{
|
||||||
|
struct user_reg reg = {0};
|
||||||
|
|
||||||
|
reg.size = sizeof(reg);
|
||||||
|
reg.name_args = (__u64)value;
|
||||||
|
reg.enable_bit = bit;
|
||||||
|
reg.enable_addr = (__u64)check;
|
||||||
|
reg.enable_size = sizeof(*check);
|
||||||
|
|
||||||
|
if (ioctl(fd, DIAG_IOCSREG, ®) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int unreg_event(int fd, int *check, int bit)
|
||||||
|
{
|
||||||
|
struct user_unreg unreg = {0};
|
||||||
|
|
||||||
|
unreg.size = sizeof(unreg);
|
||||||
|
unreg.disable_bit = bit;
|
||||||
|
unreg.disable_addr = (__u64)check;
|
||||||
|
|
||||||
|
return ioctl(fd, DIAG_IOCSUNREG, &unreg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse(int *check, const char *value)
|
||||||
|
{
|
||||||
|
int fd = open(abi_file, O_RDWR);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
if (fd == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* Until we have persist flags via dynamic events, use the base name */
|
||||||
|
if (value[0] != 'u' || value[1] != ':') {
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = reg_event(fd, check, 31, value + 2);
|
||||||
|
|
||||||
|
if (ret != -1) {
|
||||||
|
if (unreg_event(fd, check, 31) == -1)
|
||||||
|
printf("WARN: Couldn't unreg event\n");
|
||||||
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CLEAR() \
|
static int check_match(int *check, const char *first, const char *second, bool *match)
|
||||||
|
{
|
||||||
|
int fd = open(abi_file, O_RDWR);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (fd == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (reg_event(fd, check, 31, first) == -1)
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
if (reg_event(fd, check, 30, second) == -1) {
|
||||||
|
if (errno == EADDRINUSE) {
|
||||||
|
/* Name is in use, with different fields */
|
||||||
|
*match = false;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
*match = true;
|
||||||
|
ret = 0;
|
||||||
|
cleanup:
|
||||||
|
unreg_event(fd, check, 31);
|
||||||
|
unreg_event(fd, check, 30);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
wait_for_delete();
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define TEST_MATCH(x, y) \
|
||||||
do { \
|
do { \
|
||||||
int ret = Append(clear); \
|
bool match; \
|
||||||
if (ret == -1) \
|
ASSERT_NE(-1, check_match(&self->check, x, y, &match)); \
|
||||||
ASSERT_EQ(ENOENT, errno); \
|
ASSERT_EQ(true, match); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TEST_PARSE(x) \
|
#define TEST_NMATCH(x, y) \
|
||||||
do { \
|
do { \
|
||||||
ASSERT_NE(-1, Append(x)); \
|
bool match; \
|
||||||
CLEAR(); \
|
ASSERT_NE(-1, check_match(&self->check, x, y, &match)); \
|
||||||
|
ASSERT_EQ(false, match); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TEST_NPARSE(x) ASSERT_EQ(-1, Append(x))
|
#define TEST_PARSE(x) ASSERT_NE(-1, parse(&self->check, x))
|
||||||
|
|
||||||
|
#define TEST_NPARSE(x) ASSERT_EQ(-1, parse(&self->check, x))
|
||||||
|
|
||||||
FIXTURE(user) {
|
FIXTURE(user) {
|
||||||
|
int check;
|
||||||
};
|
};
|
||||||
|
|
||||||
FIXTURE_SETUP(user) {
|
FIXTURE_SETUP(user) {
|
||||||
CLEAR();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FIXTURE_TEARDOWN(user) {
|
FIXTURE_TEARDOWN(user) {
|
||||||
CLEAR();
|
wait_for_delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(user, basic_types) {
|
TEST_F(user, basic_types) {
|
||||||
|
@ -95,33 +193,30 @@ TEST_F(user, size_types) {
|
||||||
TEST_NPARSE("u:__test_event char a 20");
|
TEST_NPARSE("u:__test_event char a 20");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(user, flags) {
|
|
||||||
/* Should work */
|
|
||||||
TEST_PARSE("u:__test_event:BPF_ITER u32 a");
|
|
||||||
/* Forward compat */
|
|
||||||
TEST_PARSE("u:__test_event:BPF_ITER,FLAG_FUTURE u32 a");
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(user, matching) {
|
TEST_F(user, matching) {
|
||||||
/* Register */
|
/* Single name matches */
|
||||||
ASSERT_NE(-1, Append("u:__test_event struct custom a 20"));
|
TEST_MATCH("__test_event u32 a",
|
||||||
/* Should not match */
|
"__test_event u32 a");
|
||||||
TEST_NPARSE("!u:__test_event struct custom b");
|
|
||||||
/* Should match */
|
/* Multiple names match */
|
||||||
TEST_PARSE("!u:__test_event struct custom a");
|
TEST_MATCH("__test_event u32 a; u32 b",
|
||||||
/* Multi field reg */
|
"__test_event u32 a; u32 b");
|
||||||
ASSERT_NE(-1, Append("u:__test_event u32 a; u32 b"));
|
|
||||||
/* Non matching cases */
|
/* Multiple names match with dangling ; */
|
||||||
TEST_NPARSE("!u:__test_event u32 a");
|
TEST_MATCH("__test_event u32 a; u32 b",
|
||||||
TEST_NPARSE("!u:__test_event u32 b");
|
"__test_event u32 a; u32 b;");
|
||||||
TEST_NPARSE("!u:__test_event u32 a; u32 ");
|
|
||||||
TEST_NPARSE("!u:__test_event u32 a; u32 a");
|
/* Single name doesn't match */
|
||||||
/* Matching case */
|
TEST_NMATCH("__test_event u32 a",
|
||||||
TEST_PARSE("!u:__test_event u32 a; u32 b");
|
"__test_event u32 b");
|
||||||
/* Register */
|
|
||||||
ASSERT_NE(-1, Append("u:__test_event u32 a; u32 b"));
|
/* Multiple names don't match */
|
||||||
/* Ensure trailing semi-colon case */
|
TEST_NMATCH("__test_event u32 a; u32 b",
|
||||||
TEST_PARSE("!u:__test_event u32 a; u32 b;");
|
"__test_event u32 b; u32 a");
|
||||||
|
|
||||||
|
/* Types don't match */
|
||||||
|
TEST_NMATCH("__test_event u64 a; u64 b",
|
||||||
|
"__test_event u32 a; u32 b");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
|
|
Loading…
Reference in New Issue