diff mbox series

[4/4] trace-cmd test: Add test to check conversion from 7 to 6

Message ID 20220616153001.649858-5-rostedt@goodmis.org (mailing list archive)
State Accepted
Commit 9b583bc71fcd0c43f045d09aa144a58734a45aaa
Headers show
Series trace-cmd: Make unit tests for trace-cmd | expand

Commit Message

Steven Rostedt June 16, 2022, 3:30 p.m. UTC
From: "Steven Rostedt (Google)" <rostedt@goodmis.org>

Add a unit test that tests the conversion of trace-cmd 7 to trace-cmd 6.
This also adds infrastructure to do a grep of the output of trace-cmd.

Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
---
 utest/tracecmd-utest.c | 202 +++++++++++++++++++++++++++++++++++------
 1 file changed, 176 insertions(+), 26 deletions(-)
diff mbox series

Patch

diff --git a/utest/tracecmd-utest.c b/utest/tracecmd-utest.c
index 5e17f91c1720..7db5999e17f5 100644
--- a/utest/tracecmd-utest.c
+++ b/utest/tracecmd-utest.c
@@ -25,49 +25,79 @@  static char tracecmd_exec[PATH_MAX];
 
 #define TRACECMD_SUITE		"trace-cmd"
 #define TRACECMD_FILE		"__trace_test__.dat"
+#define TRACECMD_FILE2		"__trace_test__2.dat"
 #define TRACECMD_OUT		"-o", TRACECMD_FILE
+#define TRACECMD_OUT2		"-o", TRACECMD_FILE2
 #define TRACECMD_IN		"-i", TRACECMD_FILE
+#define TRACECMD_IN2		"-i", TRACECMD_FILE2
 
-static void silent_output(void)
-{
-	close(STDOUT_FILENO);
-	open("/dev/null", O_WRONLY);
-	close(STDERR_FILENO);
-	open("/dev/null", O_WRONLY);
-}
-
-static int run_trace(const char *cmd, ...)
+static char **get_args(const char *cmd, va_list ap)
 {
 	const char *param;
-	va_list ap;
-	char **tmp;
 	char **argv;
-	int status;
-	int ret = -1;
-	pid_t pid;
+	char **tmp;
 
 	argv = tracefs_list_add(NULL, tracecmd_exec);
 	if (!argv)
-		return -1;
+		return NULL;
 
 	tmp = tracefs_list_add(argv, cmd);
 	if (!tmp)
-		goto out;
+		goto fail;
 	argv = tmp;
 
-	va_start(ap, cmd);
 	for (param = va_arg(ap, const char *);
 	     param; param = va_arg(ap, const char *)) {
 		tmp = tracefs_list_add(argv, param);
 		if (!tmp)
-			goto out;
+			goto fail;
 		argv = tmp;
 	}
+
+	return argv;
+ fail:
+	tracefs_list_free(argv);
+	return NULL;
+}
+
+static void silent_output(void)
+{
+	close(STDOUT_FILENO);
+	open("/dev/null", O_WRONLY);
+	close(STDERR_FILENO);
+	open("/dev/null", O_WRONLY);
+}
+
+static int wait_for_exec(int pid)
+{
+	int status;
+	int ret;
+
+	ret = waitpid(pid, &status, 0);
+	if (ret != pid)
+		return -1;
+
+	return WEXITSTATUS(status) ? -1 : 0;
+}
+
+static int run_trace(const char *cmd, ...)
+{
+	char **argv;
+	va_list ap;
+	int ret = -1;
+	pid_t pid;
+
+	va_start(ap, cmd);
+	argv = get_args(cmd, ap);
 	va_end(ap);
 
+	if (!argv)
+		return -1;
+
 	pid = fork();
 	if (pid < 0)
 		goto out;
+
 	if (!pid) {
 		if (!show_output)
 			silent_output();
@@ -75,31 +105,149 @@  static int run_trace(const char *cmd, ...)
 		exit (ret);
 	}
 
-	ret = waitpid(pid, &status, 0);
-	if (ret != pid) {
-		ret = -1;
-		goto out;
-	}
-
-	ret = WEXIT_STATUS(status);
+	ret = wait_for_exec(pid);
  out:
 	tracefs_list_free(argv);
 	return ret;
 }
 
+static int pipe_it(int *ofd, int *efd, const char *cmd, va_list ap)
+{
+	char **argv;
+	int obrass[2];
+	int ebrass[2];
+	pid_t pid;
+	int ret;
+
+	if (pipe(obrass) < 0)
+		return -1;
+
+	if (pipe(ebrass) < 0)
+		goto fail_out;
+
+	pid = fork();
+	if (pid < 0)
+		goto fail;
+
+	if (!pid) {
+		argv = get_args(cmd, ap);
+		if (!argv)
+			exit(-1);
+
+		close(obrass[0]);
+		close(STDOUT_FILENO);
+		if (dup2(obrass[1], STDOUT_FILENO) < 0)
+			exit(-1);
+
+		close(ebrass[0]);
+		close(STDERR_FILENO);
+		if (dup2(obrass[1], STDERR_FILENO) < 0)
+			exit(-1);
+
+		ret = execvp(tracecmd_exec, argv);
+		exit(ret);
+	}
+
+	close(obrass[1]);
+	close(ebrass[1]);
+
+	*ofd = obrass[0];
+	*efd = ebrass[0];
+
+	return pid;
+
+ fail:
+	close(ebrass[0]);
+	close(ebrass[1]);
+ fail_out:
+	close(obrass[0]);
+	close(obrass[1]);
+	return -1;
+}
+
+static int grep_it(const char *match, const char *cmd, ...)
+{
+	FILE *fp;
+	regex_t reg;
+	va_list ap;
+	char *buf = NULL;
+	ssize_t n;
+	size_t l = 0;
+	bool found = false;
+	int ofd;
+	int efd;
+	int pid;
+	int ret;
+
+	if (regcomp(&reg, match, REG_ICASE|REG_NOSUB))
+		return -1;
+
+	va_start(ap, cmd);
+	pid = pipe_it(&ofd, &efd, cmd, ap);
+	va_end(ap);
+
+	if (pid < 0) {
+		regfree(&reg);
+		return -1;
+	}
+
+	fp = fdopen(ofd, "r");
+	if (!fp)
+		goto out;
+
+	do {
+		n = getline(&buf, &l, fp);
+		if (show_output && n > 0)
+			printf("%s", buf);
+		if (n > 0 && regexec(&reg, buf, 0, NULL, 0) == 0)
+			found = true;
+	} while (n >= 0);
+
+	free(buf);
+ out:
+	ret = wait_for_exec(pid);
+	if (ret)
+		n = 1;
+	if (fp)
+		fclose(fp);
+	else {
+		perror("fp");
+		close(ofd);
+	}
+	close(efd);
+	regfree(&reg);
+
+	return found ? 0 : 1;
+}
+
 static void test_trace_record_report(void)
 {
 	int ret;
 
 	ret = run_trace("record", TRACECMD_OUT, "-e", "sched", "sleep", "1", NULL);
 	CU_TEST(ret == 0);
-	ret = run_trace("report", TRACECMD_IN, NULL);
+	ret = run_trace("convert", "--file-version", "6", TRACECMD_IN, TRACECMD_OUT2, NULL);
+	CU_TEST(ret == 0);
+}
+
+static void test_trace_convert6(void)
+{
+	struct stat st;
+	int ret;
+
+	/* If the trace data is already created, just use it, otherwise make it again */
+	if (stat(TRACECMD_FILE, &st) < 0) {
+		ret = run_trace("record", TRACECMD_OUT, "-e", "sched", "sleep", "1", NULL);
+		CU_TEST(ret == 0);
+	}
+	ret = grep_it("[ \t]6[ \t]*\\[Version\\]", "dump", TRACECMD_IN2, NULL);
 	CU_TEST(ret == 0);
 }
 
 static int test_suite_destroy(void)
 {
 	unlink(TRACECMD_FILE);
+	unlink(TRACECMD_FILE2);
 	return 0;
 }
 
@@ -142,4 +290,6 @@  void test_tracecmd_lib(void)
 	}
 	CU_add_test(suite, "Simple record and report",
 		    test_trace_record_report);
+	CU_add_test(suite, "Test convert from v7 to v6",
+		    test_trace_convert6);
 }