[4.1] b091673 Rework the shell command, so that expected exit code and pattern to be found are options to "shell". Deprecate err_shell.
Federico G. Schwindt
fgsch at lodoss.net
Mon Jun 12 04:49:20 CEST 2017
commit b0916736e6fe5211856b5cce673b94f26714a011
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Sun Jan 15 12:35:52 2017 +0000
Rework the shell command, so that expected exit code and pattern to
be found are options to "shell". Deprecate err_shell.
Structure output to always be prefixed by "shell" since we're running
at the top level.
Also prefix commands with "exec 2>&1 ;" to join stdout+stderr by default.
This still doesn't cover the shells stderr in case of bad shell syntax,
which is annoying, but not worth fighting for right now.
diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c
index 4d75686..bd97fb2 100644
--- a/bin/varnishtest/vtc.c
+++ b/bin/varnishtest/vtc.c
@@ -425,27 +425,111 @@ cmd_varnishtest(CMD_ARGS)
AZ(av[2]);
}
-/**********************************************************************
- * Shell command execution
+/* SECTION: shell shell
+ *
+ * Pass the string given as argument to a shell. If you have multiple commands
+ * to run, you can use curly barces to describe a multi-lines script, eg::
+ *
+ * shell {
+ * echo begin
+ * cat /etc/fstab
+ * echo end
+ * }
+ *
+ * By default a zero exit code is expected.
+ *
+ * Notice that the commandstring is prefixed with "exec 2>&1;" to join
+ * stderr and stdout back to the varnishtest process.
+ *
+ * Optional arguments:
+ *
+ * -err - expect non-zero exit code
+ *
+ * -exit N - expect exit code N
+ *
+ * -expect string - expect str to be found in stdout+err
+ *
+ * The vtc will fail if the return code of the shell is not 0.
+ */
+/* SECTION: client-server.spec.shell shell
+ *
+ * Same as for the top-level shell.
*/
static void
+cmd_shell_engine(struct vtclog *vl, int ok,
+ const char *cmd, const char *expect)
+{
+ struct vsb *vsb;
+ FILE *fp;
+ int r, c;
+
+ AN(vl);
+ AN(cmd);
+ vsb = VSB_new_auto();
+ AN(vsb);
+ VSB_printf(vsb, "exec 2>&1 ; %s", cmd);
+ AZ(VSB_finish(vsb));
+ vtc_dump(vl, 4, "shell_cmd", VSB_data(vsb), -1);
+ fp = popen(VSB_data(vsb), "r");
+ if (fp == NULL)
+ vtc_log(vl, 0, "popen fails: %s", strerror(errno));
+ VSB_clear(vsb);
+ do {
+ c = getc(fp);
+ if (c != EOF)
+ VSB_putc(vsb, c);
+ } while (c != EOF);
+ r = pclose(fp);
+ vtc_log(vl, 4, "shell_status = 0x%04x", WEXITSTATUS(r));
+ if (WIFSIGNALED(r))
+ vtc_log(vl, 4, "shell_signal = %d", WTERMSIG(r));
+ if (ok < 0 && !WEXITSTATUS(r))
+ vtc_log(vl, 0, "shell did not fail as expected");
+ else if (ok >= 0 && WEXITSTATUS(r) != ok) {
+ vtc_log(vl, 0,
+ "shell_exit not as expected: got 0x%04x wanted 0x%04x",
+ WEXITSTATUS(r), ok);
+ }
+ AZ(VSB_finish(vsb));
+ vtc_dump(vl, 4, "shell_out", VSB_data(vsb), VSB_len(vsb));
+ if (expect != NULL) {
+ if (strstr(VSB_data(vsb), expect) == NULL)
+ vtc_log(vl, 0,
+ "shell_expect not found: (\"%s\")", expect);
+ else
+ vtc_log(vl, 4, "shell_expect found");
+ }
+ VSB_destroy(&vsb);
+}
+
+
+static void
cmd_shell(CMD_ARGS)
{
(void)priv;
(void)cmd;
- int r, s;
+ int n;
+ int ok = 0;
+ const char *expect = NULL;
if (av == NULL)
return;
- AN(av[1]);
- AZ(av[2]);
- vtc_dump(vl, 4, "shell", av[1], -1);
- r = system(av[1]);
- s = WEXITSTATUS(r);
- if (s != 0)
- vtc_log(vl, 0, "CMD '%s' failed with status %d (%s)",
- av[1], s, strerror(errno));
+ for (n = 1; av[n] != NULL; n++) {
+ if (!strcmp(av[n], "-err")) {
+ ok = -1;
+ } else if (!strcmp(av[n], "-exit")) {
+ n += 1;
+ ok = atoi(av[n]);
+ } else if (!strcmp(av[n], "-expect")) {
+ n += 1;
+ expect = av[n];
+ } else {
+ break;
+ }
+ }
+ AN(av[n]);
+ cmd_shell_engine(vl, ok, av[n], expect);
}
/**********************************************************************
@@ -457,43 +541,15 @@ cmd_err_shell(CMD_ARGS)
{
(void)priv;
(void)cmd;
- struct vsb *vsb;
- FILE *fp;
- int r, c;
if (av == NULL)
return;
AN(av[1]);
AN(av[2]);
AZ(av[3]);
- vsb = VSB_new_auto();
- AN(vsb);
- vtc_dump(vl, 4, "cmd", av[2], -1);
- fp = popen(av[2], "r");
- if (fp == NULL)
- vtc_log(vl, 0, "popen fails: %s", strerror(errno));
- do {
- c = getc(fp);
- if (c != EOF)
- VSB_putc(vsb, c);
- } while (c != EOF);
- r = pclose(fp);
- vtc_log(vl, 4, "Status = %d", WEXITSTATUS(r));
- if (WIFSIGNALED(r))
- vtc_log(vl, 4, "Signal = %d", WTERMSIG(r));
- if (WEXITSTATUS(r) == 0) {
- vtc_log(vl, 0,
- "expected error from shell");
- }
- AZ(VSB_finish(vsb));
- vtc_dump(vl, 4, "stdout", VSB_data(vsb), VSB_len(vsb));
- if (strstr(VSB_data(vsb), av[1]) == NULL)
- vtc_log(vl, 0,
- "Did not find expected string: (\"%s\")", av[1]);
- else
- vtc_log(vl, 4,
- "Found expected string: (\"%s\")", av[1]);
- VSB_delete(vsb);
+ vtc_log(vl, 1,
+ "NOTICE: err_shell is deprecated, use 'shell -err -expect'");
+ cmd_shell_engine(vl, -1, av[2], av[1]);
}
/**********************************************************************
More information about the varnish-commit
mailing list