<p>Philip Prindeville has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18526">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">test: Add test coverage for capture child process output<br><br>Signed-off-by: Philip Prindeville <philipp@redfish-solutions.com><br>Change-Id: I0273e85eeeb6b8e46703f24cd74d84f3daf0a69a<br>---<br>M tests/Makefile<br>A tests/test_capture.c<br>2 files changed, 355 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/26/18526/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/tests/Makefile b/tests/Makefile</span><br><span>index 715c3f8..04acd69 100644</span><br><span>--- a/tests/Makefile</span><br><span>+++ b/tests/Makefile</span><br><span>@@ -20,5 +20,6 @@</span><br><span> include $(ASTTOPDIR)/Makefile.moddir_rules</span><br><span> </span><br><span> test_astobj2.o: _ASTCFLAGS+=$(call get_menuselect_cflags,AO2_DEBUG)</span><br><span style="color: hsl(120, 100%, 40%);">+test_capture.o: _ASTCFLAGS+=-Wno-format-y2k</span><br><span> test_strings.o: _ASTCFLAGS+=$(AST_NO_FORMAT_TRUNCATION) $(AST_NO_STRINGOP_TRUNCATION)</span><br><span> test_voicemail_api.o: _ASTCFLAGS+=$(AST_NO_FORMAT_TRUNCATION)</span><br><span>diff --git a/tests/test_capture.c b/tests/test_capture.c</span><br><span>new file mode 100644</span><br><span>index 0000000..39f0cba</span><br><span>--- /dev/null</span><br><span>+++ b/tests/test_capture.c</span><br><span>@@ -0,0 +1,354 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Asterisk -- An open source telephony toolkit.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2022, Philip Prindeville</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Philip Prindeville <philipp@redfish-solutions.com></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See http://www.asterisk.org for more information about</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Asterisk project. Please do not directly contact</span><br><span style="color: hsl(120, 100%, 40%);">+ * any of the maintainers of this project for assistance;</span><br><span style="color: hsl(120, 100%, 40%);">+ * the project provides a web site, mailing lists and IRC</span><br><span style="color: hsl(120, 100%, 40%);">+ * channels for your use.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software, distributed under the terms of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the GNU General Public License Version 2. See the LICENSE file</span><br><span style="color: hsl(120, 100%, 40%);">+ * at the top of the source tree.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*!</span><br><span style="color: hsl(120, 100%, 40%);">+ * \file</span><br><span style="color: hsl(120, 100%, 40%);">+ * \brief Make basic use of capture capability in test framework.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \author\verbatim Philip Prindeville <philipp@redfish-solutions.com> \endverbatim</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Exercise the capture capabilities built into the test framework so</span><br><span style="color: hsl(120, 100%, 40%);">+ * that external commands might be used to generate validating results</span><br><span style="color: hsl(120, 100%, 40%);">+ * used on corroborating tests.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \ingroup tests</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*** MODULEINFO</span><br><span style="color: hsl(120, 100%, 40%);">+   <depend>TEST_FRAMEWORK</depend></span><br><span style="color: hsl(120, 100%, 40%);">+   <support_level>core</support_level></span><br><span style="color: hsl(120, 100%, 40%);">+ ***/</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/utils.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/module.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/test.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_TEST_DEFINE(test_capture_true)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     int status = AST_TEST_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ast_test_capture cap;</span><br><span style="color: hsl(120, 100%, 40%);">+  const char *path = "true";</span><br><span style="color: hsl(120, 100%, 40%);">+  char *const args[] = { "true", NULL };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case TEST_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+               info->name = "test_capture_true";</span><br><span style="color: hsl(120, 100%, 40%);">+                info->category = "/main/test_capture/";</span><br><span style="color: hsl(120, 100%, 40%);">+          info->summary = "capture true exit unit test";</span><br><span style="color: hsl(120, 100%, 40%);">+           info->description =</span><br><span style="color: hsl(120, 100%, 40%);">+                        "Capture exit code from true command.";</span><br><span style="color: hsl(120, 100%, 40%);">+             return AST_TEST_NOT_RUN;</span><br><span style="color: hsl(120, 100%, 40%);">+      case TEST_EXECUTE:</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_status_update(test, "Executing true exit test...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (ast_test_capture_command(&cap, path, args, NULL, 0) != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_test_status_update(test, "ast_test_capture_command() failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return status;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.outlen != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_test_status_update(test, "unexpected value for stdout\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.errlen != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_test_status_update(test, "unexpected value for stderr\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.pid == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_test_status_update(test, "invalid process id\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.exitcode != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_test_status_update(test, "child exited %d\n", cap.exitcode);</span><br><span style="color: hsl(120, 100%, 40%);">+            goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   status = AST_TEST_PASS;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+cleanup:</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_capture_free(&cap);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return status;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_TEST_DEFINE(test_capture_false)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int status = AST_TEST_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ast_test_capture cap;</span><br><span style="color: hsl(120, 100%, 40%);">+  const char *path = "false";</span><br><span style="color: hsl(120, 100%, 40%);">+ char *const args[] = { "false", NULL };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case TEST_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+               info->name = "test_capture_false";</span><br><span style="color: hsl(120, 100%, 40%);">+               info->category = "/main/test_capture/";</span><br><span style="color: hsl(120, 100%, 40%);">+          info->summary = "capture false exit unit test";</span><br><span style="color: hsl(120, 100%, 40%);">+          info->description =</span><br><span style="color: hsl(120, 100%, 40%);">+                        "Capture exit code from false command.";</span><br><span style="color: hsl(120, 100%, 40%);">+            return AST_TEST_NOT_RUN;</span><br><span style="color: hsl(120, 100%, 40%);">+      case TEST_EXECUTE:</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_status_update(test, "Executing false exit test...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ast_test_capture_command(&cap, path, args, NULL, 0) != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_test_status_update(test, "ast_test_capture_command() failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return status;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.outlen != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_test_status_update(test, "unexpected value for stdout\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.errlen != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_test_status_update(test, "unexpected value for stderr\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.pid == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_test_status_update(test, "invalid process id\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.exitcode != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_test_status_update(test, "child exited %d\n", cap.exitcode);</span><br><span style="color: hsl(120, 100%, 40%);">+            goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   status = AST_TEST_PASS;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+cleanup:</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_capture_free(&cap);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return status;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_TEST_DEFINE(test_capture_with_stdin)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      int status = AST_TEST_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ast_test_capture cap;</span><br><span style="color: hsl(120, 100%, 40%);">+  const char *path = "base64";</span><br><span style="color: hsl(120, 100%, 40%);">+        char *const args[] = { "base64", NULL };</span><br><span style="color: hsl(120, 100%, 40%);">+    const char data[] = "Mary had a little lamb.";</span><br><span style="color: hsl(120, 100%, 40%);">+      const unsigned datalen = sizeof(data) - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+    const char output[] = "TWFyeSBoYWQgYSBsaXR0bGUgbGFtYi4=\n";</span><br><span style="color: hsl(120, 100%, 40%);">+ const unsigned outputlen = sizeof(output) - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case TEST_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+               info->name = "test_capture_with_stdin";</span><br><span style="color: hsl(120, 100%, 40%);">+          info->category = "/main/test_capture/";</span><br><span style="color: hsl(120, 100%, 40%);">+          info->summary = "capture with stdin unit test";</span><br><span style="color: hsl(120, 100%, 40%);">+          info->description =</span><br><span style="color: hsl(120, 100%, 40%);">+                        "Capture output from stdin transformation command.";</span><br><span style="color: hsl(120, 100%, 40%);">+                return AST_TEST_NOT_RUN;</span><br><span style="color: hsl(120, 100%, 40%);">+      case TEST_EXECUTE:</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_status_update(test, "Executing stdin test...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (ast_test_capture_command(&cap, path, args, data, datalen) != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_test_status_update(test, "ast_test_capture_command() failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return status;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.outlen != outputlen || memcmp(cap.outbuf, output, cap.outlen)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_test_status_update(test, "unexpected value for stdout\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.errlen != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_test_status_update(test, "unexpected value for stderr\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.pid == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_test_status_update(test, "invalid process id\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.exitcode != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_test_status_update(test, "child exited %d\n", cap.exitcode);</span><br><span style="color: hsl(120, 100%, 40%);">+            goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   status = AST_TEST_PASS;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+cleanup:</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_capture_free(&cap);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return status;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_TEST_DEFINE(test_capture_with_dynamic)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    int status = AST_TEST_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ast_test_capture cap;</span><br><span style="color: hsl(120, 100%, 40%);">+  const char *path = "date";</span><br><span style="color: hsl(120, 100%, 40%);">+  char *args[] = { "date", "DATE", "FORMAT", NULL };</span><br><span style="color: hsl(120, 100%, 40%);">+      char date[40];</span><br><span style="color: hsl(120, 100%, 40%);">+        const char format[] = "+%a, %d %b %y %T %z";</span><br><span style="color: hsl(120, 100%, 40%);">+        const char format2[] = "%a, %d %b %y %T %z\n";</span><br><span style="color: hsl(120, 100%, 40%);">+      char myresult[64];</span><br><span style="color: hsl(120, 100%, 40%);">+    unsigned myresultlen;</span><br><span style="color: hsl(120, 100%, 40%);">+ time_t now;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct tm *tm;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case TEST_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+               info->name = "test_capture_with_dynamic";</span><br><span style="color: hsl(120, 100%, 40%);">+                info->category = "/main/test_capture/";</span><br><span style="color: hsl(120, 100%, 40%);">+          info->summary = "capture with dynamic argument unit test";</span><br><span style="color: hsl(120, 100%, 40%);">+               info->description =</span><br><span style="color: hsl(120, 100%, 40%);">+                        "Capture output from dynamic transformation command.";</span><br><span style="color: hsl(120, 100%, 40%);">+              return AST_TEST_NOT_RUN;</span><br><span style="color: hsl(120, 100%, 40%);">+      case TEST_EXECUTE:</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_status_update(test, "Executing dynamic argument test...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     time(&now);</span><br><span style="color: hsl(120, 100%, 40%);">+       snprintf(date, sizeof(date), "--date=@%lu", now);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ tm = localtime(&now);</span><br><span style="color: hsl(120, 100%, 40%);">+     strftime(myresult, sizeof(myresult), format2, tm);</span><br><span style="color: hsl(120, 100%, 40%);">+    myresultlen = strlen(myresult);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     args[1] = date;</span><br><span style="color: hsl(120, 100%, 40%);">+       args[2] = (char *)format;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ast_test_capture_command(&cap, path, args, NULL, 0) != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_test_status_update(test, "ast_test_capture_command() failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return status;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.outlen != myresultlen || memcmp(cap.outbuf, myresult, cap.outlen)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_test_status_update(test, "unexpected value for stdout\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.errlen != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_test_status_update(test, "unexpected value for stderr\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.pid == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_test_status_update(test, "invalid process id\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.exitcode != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_test_status_update(test, "child exited %d\n", cap.exitcode);</span><br><span style="color: hsl(120, 100%, 40%);">+            goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   status = AST_TEST_PASS;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+cleanup:</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_capture_free(&cap);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return status;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_TEST_DEFINE(test_capture_stdout_stderr)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int status = AST_TEST_FAIL;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ast_test_capture cap;</span><br><span style="color: hsl(120, 100%, 40%);">+  const char *path = "bash";</span><br><span style="color: hsl(120, 100%, 40%);">+  char *const args[] = { "bash", "-c", "echo -n 'foo' >&2 ; echo -n 'zzz' >&1 ; echo -n 'bar' >&2", NULL };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case TEST_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+               info->name = "test_capture_stdout_stderr";</span><br><span style="color: hsl(120, 100%, 40%);">+               info->category = "/main/test_capture/";</span><br><span style="color: hsl(120, 100%, 40%);">+          info->summary = "capture stdout & stderr unit test";</span><br><span style="color: hsl(120, 100%, 40%);">+         info->description =</span><br><span style="color: hsl(120, 100%, 40%);">+                        "Capture both stdout and stderr from bash.";</span><br><span style="color: hsl(120, 100%, 40%);">+                return AST_TEST_NOT_RUN;</span><br><span style="color: hsl(120, 100%, 40%);">+      case TEST_EXECUTE:</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_status_update(test, "Executing stdout/stderr test...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (ast_test_capture_command(&cap, path, args, NULL, 0) != 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_test_status_update(test, "ast_test_capture_command() failed\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return status;</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.outlen != 3 || memcmp(cap.outbuf, "zzz", 3)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_test_status_update(test, "unexpected value for stdout\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.errlen != 6 || memcmp(cap.errbuf, "foobar", 6)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_test_status_update(test, "unexpected value for stderr\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.pid == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_test_status_update(test, "invalid process id\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cap.exitcode != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_test_status_update(test, "child exited %d\n", cap.exitcode);</span><br><span style="color: hsl(120, 100%, 40%);">+            goto cleanup;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   status = AST_TEST_PASS;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+cleanup:</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_test_capture_free(&cap);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return status;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int unload_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_TEST_UNREGISTER(test_capture_with_stdin);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_TEST_UNREGISTER(test_capture_with_dynamic);</span><br><span style="color: hsl(120, 100%, 40%);">+       AST_TEST_UNREGISTER(test_capture_stdout_stderr);</span><br><span style="color: hsl(120, 100%, 40%);">+      AST_TEST_UNREGISTER(test_capture_true);</span><br><span style="color: hsl(120, 100%, 40%);">+       AST_TEST_UNREGISTER(test_capture_false);</span><br><span style="color: hsl(120, 100%, 40%);">+      return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int load_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       AST_TEST_REGISTER(test_capture_with_stdin);</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_TEST_REGISTER(test_capture_with_dynamic);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_TEST_REGISTER(test_capture_stdout_stderr);</span><br><span style="color: hsl(120, 100%, 40%);">+        AST_TEST_REGISTER(test_capture_true);</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_TEST_REGISTER(test_capture_false);</span><br><span style="color: hsl(120, 100%, 40%);">+        return AST_MODULE_LOAD_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Capture support test");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18526">change 18526</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/18526"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I0273e85eeeb6b8e46703f24cd74d84f3daf0a69a </div>
<div style="display:none"> Gerrit-Change-Number: 18526 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Philip Prindeville <philipp@redfish-solutions.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>