[Tarantool-patches] [PATCH 2/2] test: unit/popen -- provide a child process

Cyrill Gorcunov gorcunov at gmail.com
Tue Mar 24 13:03:47 MSK 2020


Testing via plain C interface with a shell is not stable,
the shell might simply be misconfigured or not found and
we will simply stuck forever (the signal handling in libev
is tricky and requires at least idle cycles or similar to
pass event processing). Thus lets rather run a program we
know is presenting in the system (popen-child executable).

Fixes #4811

Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
 test/unit/CMakeLists.txt |  4 +++
 test/unit/popen-child.c  | 71 ++++++++++++++++++++++++++++++++++++++++
 test/unit/popen.c        | 18 ++++++----
 3 files changed, 86 insertions(+), 7 deletions(-)
 create mode 100644 test/unit/popen-child.c

diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index bc6aebdcb..e1d506f58 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -246,5 +246,9 @@ target_link_libraries(swim_errinj.test unit swim)
 add_executable(merger.test merger.test.c)
 target_link_libraries(merger.test unit core box)
 
+#
+# Client for popen.test
+add_executable(popen-child popen-child.c)
+
 add_executable(popen.test popen.c)
 target_link_libraries(popen.test misc unit core)
diff --git a/test/unit/popen-child.c b/test/unit/popen-child.c
new file mode 100644
index 000000000..40d99faa4
--- /dev/null
+++ b/test/unit/popen-child.c
@@ -0,0 +1,71 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+int
+main(int argc, char *argv[])
+{
+	char buf[1024];
+
+	if (argc < 2) {
+		fprintf(stderr, "Not enough args\n");
+		exit(1);
+	}
+
+	// read -n X and the just echo data read
+	if (!strcmp(argv[1], "read") &&
+	    !strcmp(argv[2], "-n")) {
+		ssize_t nr = (ssize_t)atoi(argv[3]);
+		if (nr <= 0) {
+			fprintf(stderr, "Wrong number of args\n");
+			exit(1);
+		}
+
+		if (nr >= (ssize_t)sizeof(buf)) {
+			fprintf(stderr, "Too many bytes to read\n");
+			exit(1);
+		}
+
+		ssize_t n = read(STDIN_FILENO, buf, nr);
+		if (n != nr) {
+			fprintf(stderr, "Can't read from stdin\n");
+			exit(1);
+		}
+
+		n = write(STDOUT_FILENO, buf, nr);
+		if (n != nr) {
+			fprintf(stderr, "Can't write to stdout\n");
+			exit(1);
+		}
+
+		exit(0);
+	}
+
+	// just echo the data
+	if (!strcmp(argv[1], "echo")) {
+		ssize_t nr = (ssize_t)strlen(argv[2]) + 1;
+		if (nr <= 0) {
+			fprintf(stderr, "Wrong number of bytes\n");
+			exit(1);
+		}
+
+		ssize_t n = write(STDOUT_FILENO, argv[2], nr);
+		if (n != nr) {
+			fprintf(stderr, "Can't write to stdout\n");
+			exit(1);
+		}
+
+		exit(0);
+	}
+
+	// just sleep forever
+	if (!strcmp(argv[1], "loop")) {
+		for (;;)
+			sleep(10);
+		exit(0);
+	}
+
+	fprintf(stderr, "Unknown command passed\n");
+	return 1;
+}
diff --git a/test/unit/popen.c b/test/unit/popen.c
index a40ca514c..44624cd0c 100644
--- a/test/unit/popen.c
+++ b/test/unit/popen.c
@@ -11,9 +11,10 @@
 #include "popen.h"
 #include "say.h"
 
+static char popen_child_path[PATH_MAX];
+
 #define TEST_POPEN_COMMON_FLAGS			\
 	(POPEN_FLAG_SETSID		|	\
-	POPEN_FLAG_SHELL		|	\
 	POPEN_FLAG_RESTORE_SIGNALS)
 
 /**
@@ -40,8 +41,8 @@ popen_write_exit(void)
 {
 	struct popen_handle *handle;
 	char *child_argv[] = {
-		"/bin/sh", "-c",
-		"prompt=''; read -n 5 prompt; echo $prompt",
+		popen_child_path,
+		"read", "-n", "6",
 		NULL,
 	};
 
@@ -108,8 +109,8 @@ popen_read_exit(void)
 {
 	struct popen_handle *handle;
 	char *child_argv[] = {
-		"/bin/sh", "-c",
-		"echo 1 2 3 4 5",
+		popen_child_path,
+		"echo", "1 2 3 4 5",
 		NULL,
 	};
 
@@ -165,8 +166,8 @@ popen_kill(void)
 {
 	struct popen_handle *handle;
 	char *child_argv[] = {
-		"/bin/sh", "-c",
-		"while [ 1 ]; do sleep 10; done",
+		popen_child_path,
+		"loop",
 		NULL,
 	};
 
@@ -237,6 +238,9 @@ main(int argc, char *argv[])
 	//say_logger_init(NULL, S_DEBUG, 0, "plain", 0);
 	memory_init();
 
+	snprintf(popen_child_path, sizeof(popen_child_path),
+		 "%s/test/unit/popen-child", getenv("BUILDDIR"));
+
 	fiber_init(fiber_c_invoke);
 	popen_init();
 	coio_init();
-- 
2.20.1



More information about the Tarantool-patches mailing list