diff mbox series

[v2,5/5] libtracefs: Unit tests for working with non default tracing dir

Message ID 20210120151256.43075-6-tz.stoyanov@gmail.com (mailing list archive)
State Accepted
Commit 08bfb492f6f7761848647ca17ae94dcb2c8bf5a5
Headers show
Series New libtracefs APIs for trace options and trace dir | expand

Commit Message

Tzvetomir Stoyanov (VMware) Jan. 20, 2021, 3:12 p.m. UTC
All unit tests are modified to work with custom defined trace directory,
instead of default system one. A new tests are added which duplicate
part of the system trace directory and test various library APIs on
that copy.

Signed-off-by: Tzvetomir Stoyanov (VMware) <tz.stoyanov@gmail.com>
---
 utest/tracefs-utest.c | 287 +++++++++++++++++++++++++++++++++---------
 1 file changed, 228 insertions(+), 59 deletions(-)
diff mbox series

Patch

diff --git a/utest/tracefs-utest.c b/utest/tracefs-utest.c
index 1f3c042..ed2693b 100644
--- a/utest/tracefs-utest.c
+++ b/utest/tracefs-utest.c
@@ -10,6 +10,7 @@ 
 #include <unistd.h>
 #include <time.h>
 #include <dirent.h>
+#include <ftw.h>
 
 #include <CUnit/CUnit.h>
 #include <CUnit/Basic.h>
@@ -18,8 +19,15 @@ 
 
 #define TRACEFS_SUITE		"trasefs library"
 #define TEST_INSTANCE_NAME	"cunit_test_iter"
+#define TEST_TRACE_DIR		"/tmp/trace_utest.XXXXXX"
 #define TEST_ARRAY_SIZE		500
 
+#define ALL_TRACERS	"available_tracers"
+#define CUR_TRACER	"current_tracer"
+#define PER_CPU		"per_cpu"
+#define TRACE_ON	"tracing_on"
+#define TRACE_CLOCK	"trace_clock"
+
 static struct tracefs_instance *test_instance;
 static struct tep_handle *test_tep;
 struct test_sample {
@@ -55,7 +63,7 @@  static int test_callback(struct tep_event *event, struct tep_record *record,
 	return 0;
 }
 
-static void test_iter_write(void)
+static void test_iter_write(struct tracefs_instance *instance)
 {
 	int cpus = sysconf(_SC_NPROCESSORS_CONF);
 	cpu_set_t *cpuset, *cpusave;
@@ -70,7 +78,7 @@  static void test_iter_write(void)
 
 	sched_getaffinity(0, cpu_size, cpusave);
 
-	path = tracefs_instance_get_file(test_instance, "trace_marker");
+	path = tracefs_instance_get_file(instance, "trace_marker");
 	CU_TEST(path != NULL);
 	fd = open(path, O_WRONLY);
 	tracefs_put_tracing_file(path);
@@ -94,15 +102,15 @@  static void test_iter_write(void)
 }
 
 
-static void iter_raw_events_on_cpu(int cpu)
+static void iter_raw_events_on_cpu(struct tracefs_instance *instance, int cpu)
 {
 	int check = 0;
 	int ret;
 	int i;
 
 	test_found = 0;
-	test_iter_write();
-	ret = tracefs_iterate_raw_events(test_tep, test_instance, NULL, 0,
+	test_iter_write(instance);
+	ret = tracefs_iterate_raw_events(test_tep, instance, NULL, 0,
 					 test_callback, &cpu);
 	CU_TEST(ret == 0);
 	if (cpu < 0) {
@@ -120,22 +128,27 @@  static void iter_raw_events_on_cpu(int cpu)
 	}
 }
 
-static void test_iter_raw_events(void)
+static void test_instance_iter_raw_events(struct tracefs_instance *instance)
 {
 	int cpus = sysconf(_SC_NPROCESSORS_CONF);
 	int ret;
 	int i;
 
-	ret = tracefs_iterate_raw_events(NULL, test_instance, NULL, 0, test_callback, NULL);
+	ret = tracefs_iterate_raw_events(NULL, instance, NULL, 0, test_callback, NULL);
 	CU_TEST(ret < 0);
 	ret = tracefs_iterate_raw_events(test_tep, NULL, NULL, 0, test_callback, NULL);
 	CU_TEST(ret == 0);
-	ret = tracefs_iterate_raw_events(test_tep, test_instance, NULL, 0, NULL, NULL);
+	ret = tracefs_iterate_raw_events(test_tep, instance, NULL, 0, NULL, NULL);
 	CU_TEST(ret < 0);
 
-	iter_raw_events_on_cpu(-1);
+	iter_raw_events_on_cpu(instance, -1);
 	for (i = 0; i < cpus; i++)
-		iter_raw_events_on_cpu(i);
+		iter_raw_events_on_cpu(instance, i);
+}
+
+static void test_iter_raw_events(void)
+{
+	test_instance_iter_raw_events(test_instance);
 }
 
 #define RAND_STR_SIZE 20
@@ -215,10 +228,6 @@  static void test_instance_file_read(struct tracefs_instance *inst, const char *f
 	free(file);
 }
 
-#define ALL_TRACERS	"available_tracers"
-#define CUR_TRACER	"current_tracer"
-#define PER_CPU		"per_cpu"
-#define TRACE_ON	"tracing_on"
 static void test_instance_file(void)
 {
 	struct tracefs_instance *instance = NULL;
@@ -323,7 +332,7 @@  static void test_instance_file(void)
 	free(inst_dir);
 }
 
-static bool check_fd_name(int fd, char *name)
+static bool check_fd_name(int fd, const char *dir, const char *name)
 {
 	char link[PATH_MAX + 1];
 	char path[PATH_MAX + 1];
@@ -344,6 +353,10 @@  static bool check_fd_name(int fd, char *name)
 	if (ret > PATH_MAX || ret < 0)
 		return false;
 	path[ret] = 0;
+	ret = strncmp(dir, path, strlen(dir));
+	CU_TEST(ret == 0);
+	if (ret)
+		return false;
 	file = basename(path);
 	CU_TEST(file != NULL);
 	if (!file)
@@ -389,23 +402,26 @@  static bool check_fd_mode(int fd, int mode)
 	return true;
 }
 
-static void test_instance_file_fd(void)
+static void test_instance_file_fd(struct tracefs_instance *instance)
 {
 	const char *name = get_rand_str();
+	const char *tdir = tracefs_instance_get_trace_dir(instance);
 	long long res = -1;
 	char rd[2];
 	int fd;
 
-	fd = tracefs_instance_file_open(test_instance, name, -1);
+	CU_TEST(tdir != NULL);
+	fd = tracefs_instance_file_open(instance, name, -1);
 	CU_TEST(fd == -1);
-	fd = tracefs_instance_file_open(test_instance, TRACE_ON, O_RDONLY);
+	fd = tracefs_instance_file_open(instance, TRACE_ON, O_RDONLY);
 	CU_TEST(fd >= 0);
-	CU_TEST(check_fd_name(fd, TRACE_ON));
+
+	CU_TEST(check_fd_name(fd, tdir, TRACE_ON));
 	CU_TEST(check_fd_mode(fd, O_RDONLY));
 
-	CU_TEST(tracefs_instance_file_read_number(test_instance, "available_tracer", &res) != 0);
-	CU_TEST(tracefs_instance_file_read_number(test_instance, name, &res) != 0);
-	CU_TEST(tracefs_instance_file_read_number(test_instance, TRACE_ON, &res) == 0);
+	CU_TEST(tracefs_instance_file_read_number(instance, ALL_TRACERS, &res) != 0);
+	CU_TEST(tracefs_instance_file_read_number(instance, name, &res) != 0);
+	CU_TEST(tracefs_instance_file_read_number(instance, TRACE_ON, &res) == 0);
 	CU_TEST((res == 0 || res == 1));
 	CU_TEST(read(fd, &rd, 1) == 1);
 	rd[1] = 0;
@@ -414,44 +430,56 @@  static void test_instance_file_fd(void)
 	close(fd);
 }
 
-static void test_tracing_onoff(void)
+static void test_file_fd(void)
+{
+	test_instance_file_fd(test_instance);
+}
+
+static void test_instance_tracing_onoff(struct tracefs_instance *instance)
 {
+	const char *tdir = tracefs_instance_get_trace_dir(instance);
 	long long res = -1;
 	int fd;
 
-	fd = tracefs_trace_on_get_fd(test_instance);
+	CU_TEST(tdir != NULL);
+	fd = tracefs_trace_on_get_fd(instance);
 	CU_TEST(fd >= 0);
-	CU_TEST(check_fd_name(fd, TRACE_ON));
+	CU_TEST(check_fd_name(fd, tdir, TRACE_ON));
 	CU_TEST(check_fd_mode(fd, O_RDWR));
-	CU_TEST(tracefs_instance_file_read_number(test_instance, TRACE_ON, &res) == 0);
+	CU_TEST(tracefs_instance_file_read_number(instance, TRACE_ON, &res) == 0);
 	if (res == 1) {
-		CU_TEST(tracefs_trace_is_on(test_instance) == 1);
-		CU_TEST(tracefs_trace_off(test_instance) == 0);
-		CU_TEST(tracefs_trace_is_on(test_instance) == 0);
-		CU_TEST(tracefs_trace_on(test_instance) == 0);
-		CU_TEST(tracefs_trace_is_on(test_instance) == 1);
+		CU_TEST(tracefs_trace_is_on(instance) == 1);
+		CU_TEST(tracefs_trace_off(instance) == 0);
+		CU_TEST(tracefs_trace_is_on(instance) == 0);
+		CU_TEST(tracefs_trace_on(instance) == 0);
+		CU_TEST(tracefs_trace_is_on(instance) == 1);
 
 		CU_TEST(tracefs_trace_off_fd(fd) == 0);
-		CU_TEST(tracefs_trace_is_on(test_instance) == 0);
+		CU_TEST(tracefs_trace_is_on(instance) == 0);
 		CU_TEST(tracefs_trace_on_fd(fd) == 0);
-		CU_TEST(tracefs_trace_is_on(test_instance) == 1);
+		CU_TEST(tracefs_trace_is_on(instance) == 1);
 	} else {
-		CU_TEST(tracefs_trace_is_on(test_instance) == 0);
-		CU_TEST(tracefs_trace_on(test_instance) == 0);
-		CU_TEST(tracefs_trace_is_on(test_instance) == 1);
-		CU_TEST(tracefs_trace_off(test_instance) == 0);
-		CU_TEST(tracefs_trace_is_on(test_instance) == 0);
+		CU_TEST(tracefs_trace_is_on(instance) == 0);
+		CU_TEST(tracefs_trace_on(instance) == 0);
+		CU_TEST(tracefs_trace_is_on(instance) == 1);
+		CU_TEST(tracefs_trace_off(instance) == 0);
+		CU_TEST(tracefs_trace_is_on(instance) == 0);
 
 		CU_TEST(tracefs_trace_on_fd(fd) == 0);
-		CU_TEST(tracefs_trace_is_on(test_instance) == 1);
+		CU_TEST(tracefs_trace_is_on(instance) == 1);
 		CU_TEST(tracefs_trace_off_fd(fd) == 0);
-		CU_TEST(tracefs_trace_is_on(test_instance) == 0);
+		CU_TEST(tracefs_trace_is_on(instance) == 0);
 	}
 
 	if (fd >= 0)
 		close(fd);
 }
 
+static void test_tracing_onoff(void)
+{
+	test_instance_tracing_onoff(test_instance);
+}
+
 static bool check_option(struct tracefs_instance *instance,
 			 enum tracefs_option_id id, bool exist, int enabled)
 {
@@ -625,16 +653,13 @@  static void test_check_files(const char *fdir, char **files)
 		CU_TEST(files[i][0] == '/');
 }
 
-static void test_system_event(void)
+static void system_event(const char *tdir)
 {
-	const char *tdir;
+
 	char **systems;
 	char **events;
 	char *sdir = NULL;
 
-	tdir  = tracefs_tracing_dir();
-	CU_TEST(tdir != NULL);
-
 	systems = tracefs_event_systems(tdir);
 	CU_TEST(systems != NULL);
 
@@ -657,7 +682,16 @@  static void test_system_event(void)
 	free(sdir);
 }
 
-static void test_tracers(void)
+static void test_system_event(void)
+{
+	const char *tdir;
+
+	tdir  = tracefs_tracing_dir();
+	CU_TEST(tdir != NULL);
+	system_event(tdir);
+}
+
+static void test_instance_tracers(struct tracefs_instance *instance)
 {
 	const char *tdir;
 	char **tracers;
@@ -665,7 +699,7 @@  static void test_tracers(void)
 	char *tracer;
 	int i;
 
-	tdir  = tracefs_tracing_dir();
+	tdir  = tracefs_instance_get_trace_dir(instance);
 	CU_TEST(tdir != NULL);
 
 	tracers = tracefs_tracers(tdir);
@@ -686,6 +720,11 @@  static void test_tracers(void)
 	free(tfile);
 }
 
+static void test_tracers(void)
+{
+	test_instance_tracers(test_instance);
+}
+
 static void test_check_events(struct tep_handle *tep, char *system, bool exist)
 {
 	struct dirent *dent;
@@ -725,17 +764,13 @@  static void test_check_events(struct tep_handle *tep, char *system, bool exist)
 
 }
 
-static void test_local_events(void)
+static void local_events(const char *tdir)
 {
 	struct tep_handle *tep;
-	const char *tdir;
 	char **systems;
 	char *lsystems[3];
 	int i;
 
-	tdir  = tracefs_tracing_dir();
-	CU_TEST(tdir != NULL);
-
 	tep = tracefs_local_events(tdir);
 	CU_TEST(tep != NULL);
 
@@ -776,6 +811,15 @@  static void test_local_events(void)
 	tracefs_list_free(systems);
 }
 
+static void test_local_events(void)
+{
+	const char *tdir;
+
+	tdir  = tracefs_tracing_dir();
+	CU_TEST(tdir != NULL);
+	local_events(tdir);
+}
+
 struct test_walk_instance {
 	struct tracefs_instance *instance;
 	bool found;
@@ -825,13 +869,13 @@  static void test_instances_walk(void)
 	}
 }
 
-static void current_clock_check(const char *clock)
+static void current_clock_check(struct tracefs_instance *instance, const char *clock)
 {
 	int size = 0;
 	char *clocks;
 	char *str;
 
-	clocks = tracefs_instance_file_read(test_instance, "trace_clock", &size);
+	clocks = tracefs_instance_file_read(instance, TRACE_CLOCK, &size);
 	CU_TEST(clocks != NULL);
 	CU_TEST(size > strlen(clock));
 	str = strstr(clocks, clock);
@@ -842,16 +886,140 @@  static void current_clock_check(const char *clock)
 	free(clocks);
 }
 
-static void test_get_clock(void)
+static void test_instance_get_clock(struct tracefs_instance *instance)
 {
 	const char *clock;
 
-	clock = tracefs_get_clock(test_instance);
+	clock = tracefs_get_clock(instance);
 	CU_TEST(clock != NULL);
-	current_clock_check(clock);
+	current_clock_check(instance, clock);
 	free((char *)clock);
 }
 
+static void test_get_clock(void)
+{
+	test_instance_get_clock(test_instance);
+}
+
+static void copy_trace_file(const char *from, char *to)
+{
+	int fd_from = -1;
+	int fd_to = -1;
+	char buf[512];
+	int ret;
+
+	fd_from = open(from, O_RDONLY);
+	if (fd_from < 0)
+		goto out;
+	fd_to = open(to, O_WRONLY | O_TRUNC | O_CREAT);
+	if (fd_to < 0)
+		goto out;
+
+	while ((ret = read(fd_from, buf, 512)) > 0) {
+		if (write(fd_to, buf, ret) == -1)
+			break;
+	}
+
+out:
+	if (fd_to >= 0)
+		close(fd_to);
+	if (fd_from >= 0)
+		close(fd_from);
+}
+
+static int trace_dir_base;
+static char *trace_tmp_dir;
+static int copy_trace_walk(const char *fpath, const struct stat *sb,
+			   int typeflag, struct FTW *ftwbuf)
+{
+	char path[PATH_MAX];
+
+	sprintf(path, "%s%s", trace_tmp_dir, fpath + trace_dir_base);
+
+	switch (typeflag) {
+	case FTW_D:
+		mkdir(path, 0750);
+		break;
+	case FTW_F:
+		copy_trace_file(fpath, path);
+		break;
+	default:
+		break;
+	}
+	return 0;
+}
+
+static void dup_trace_dir(char *to, char *dir)
+{
+	const char *trace_dir = tracefs_tracing_dir();
+	char file_from[PATH_MAX];
+	char file_to[PATH_MAX];
+
+	sprintf(file_from, "%s/%s", trace_dir, dir);
+	sprintf(file_to, "%s/%s", to, dir);
+	trace_tmp_dir = file_to;
+	trace_dir_base = strlen(file_from);
+	nftw(file_from, copy_trace_walk, 20, 0);
+}
+
+static void dup_trace_file(char *to, char *file)
+{
+	const char *trace_dir = tracefs_tracing_dir();
+	char file_from[PATH_MAX];
+	char file_to[PATH_MAX];
+
+	sprintf(file_from, "%s/%s", trace_dir, file);
+	sprintf(file_to, "%s/%s", to, file);
+	copy_trace_file(file_from, file_to);
+}
+
+static char *copy_trace_dir(void)
+{
+	char template[] = TEST_TRACE_DIR;
+	char *dname = mkdtemp(template);
+
+	dup_trace_dir(dname, "events");
+	dup_trace_dir(dname, "options");
+	dup_trace_file(dname, TRACE_ON);
+	dup_trace_file(dname, CUR_TRACER);
+	dup_trace_file(dname, TRACE_CLOCK);
+	dup_trace_file(dname, ALL_TRACERS);
+
+	return strdup(dname);
+}
+
+static int del_trace_walk(const char *fpath, const struct stat *sb,
+			  int typeflag, struct FTW *ftwbuf)
+{
+	remove(fpath);
+	return 0;
+}
+
+void del_trace_dir(char *dir)
+{
+	nftw(dir, del_trace_walk, 20, FTW_DEPTH);
+}
+
+static void test_custom_trace_dir(void)
+{
+	struct tracefs_instance *instance;
+	char *dname = copy_trace_dir();
+
+	instance = tracefs_instance_alloc(dname, NULL);
+	CU_TEST(instance != NULL);
+
+	system_event(dname);
+	local_events(dname);
+	test_instance_tracing_options(instance);
+	test_instance_get_clock(instance);
+	test_instance_file_fd(instance);
+	test_instance_tracers(instance);
+
+	tracefs_instance_free(instance);
+	del_trace_dir(dname);
+	free(dname);
+}
+
 static int test_suite_destroy(void)
 {
 	tracefs_instance_destroy(test_instance);
@@ -886,7 +1054,7 @@  void test_tracefs_lib(void)
 	CU_add_test(suite, "tracing file / directory APIs",
 		    test_trace_file);
 	CU_add_test(suite, "instance file / directory APIs",
-		    test_instance_file_fd);
+		    test_file_fd);
 	CU_add_test(suite, "instance file descriptor",
 		    test_instance_file);
 	CU_add_test(suite, "systems and events APIs",
@@ -905,5 +1073,6 @@  void test_tracefs_lib(void)
 		    test_tracing_onoff);
 	CU_add_test(suite, "tracing options",
 		    test_tracing_options);
-
+	CU_add_test(suite, "custom system directory",
+		    test_custom_trace_dir);
 }