[master] a33b931 List commands in a single tbl-include file. Move misc commands to separate source file.
Poul-Henning Kamp
phk at FreeBSD.org
Tue Mar 27 09:13:08 UTC 2018
commit a33b931e6ddd9b6fa74782560b7334636a23749f
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Mar 27 09:11:23 2018 +0000
List commands in a single tbl-include file.
Move misc commands to separate source file.
diff --git a/bin/varnishtest/Makefile.am b/bin/varnishtest/Makefile.am
index 974aaf9..efbac2a 100644
--- a/bin/varnishtest/Makefile.am
+++ b/bin/varnishtest/Makefile.am
@@ -27,22 +27,24 @@ bin_PROGRAMS = varnishtest
varnishtest_SOURCES = \
hpack.h \
programs.h \
+ cmds.h \
vmods.h \
- vtc.c \
vtc.h \
+ vtc.c \
vtc_barrier.c \
vtc_client.c \
- vtc_http.c \
- vtc_http.h \
- vtc_log.c \
- vtc_http2.c \
vtc_h2_dectbl.h \
vtc_h2_enctbl.h \
vtc_h2_hpack.c \
vtc_h2_priv.h \
vtc_h2_stattbl.h \
vtc_h2_tbl.c \
+ vtc_http.c \
+ vtc_http.h \
+ vtc_http2.c \
+ vtc_log.c \
vtc_logexp.c \
+ vtc_misc.c \
vtc_main.c \
vtc_process.c \
vtc_proxy.c \
diff --git a/bin/varnishtest/cmds.h b/bin/varnishtest/cmds.h
new file mode 100644
index 0000000..58c2e7b
--- /dev/null
+++ b/bin/varnishtest/cmds.h
@@ -0,0 +1,47 @@
+/*-
+ * Copyright (c) 2018 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+/*lint -save -e525 -e539 */
+
+CMD(barrier)
+CMD(client)
+CMD(delay)
+CMD(err_shell)
+CMD(feature)
+//CMD(haproxy)
+CMD(logexpect)
+CMD(process)
+CMD(server)
+CMD(setenv)
+CMD(shell)
+CMD(varnish)
+CMD(varnishtest)
+#undef CMD
+
+/*lint -restore */
diff --git a/bin/varnishtest/flint.lnt b/bin/varnishtest/flint.lnt
index 1dc2716..25eace2 100644
--- a/bin/varnishtest/flint.lnt
+++ b/bin/varnishtest/flint.lnt
@@ -35,6 +35,7 @@
-e788 // enum value not used in defaulted switch
+-efile(451, cmds.h)
-efile(451, vmods.h)
-efile(451, programs.h)
-efile(451, vtc_h2_stattbl.h)
diff --git a/bin/varnishtest/vtc.c b/bin/varnishtest/vtc.c
index 8d7f764..76f1e7a 100644
--- a/bin/varnishtest/vtc.c
+++ b/bin/varnishtest/vtc.c
@@ -31,10 +31,6 @@
#include <sys/wait.h>
#include <ctype.h>
-#include <errno.h>
-#include <grp.h>
-#include <math.h>
-#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
@@ -44,8 +40,6 @@
#include "vtc.h"
#include "vav.h"
-#include "vnum.h"
-#include "vre.h"
#include "vtim.h"
#ifdef HAVE_SYS_PERSONALITY_H
@@ -57,8 +51,8 @@
volatile sig_atomic_t vtc_error; /* Error encountered */
int vtc_stop; /* Stops current test without error */
pthread_t vtc_thread;
+int ign_unknown_macro = 0;
static struct vtclog *vltop;
-static int ign_unknown_macro = 0;
/**********************************************************************
* Macro facility
@@ -426,436 +420,13 @@ reset_cmds(const struct cmds *cmd)
cmd->cmd(NULL, NULL, NULL, NULL);
}
-/* SECTION: varnishtest varnishtest
- *
- * This should be the first command in your vtc as it will identify the test
- * case with a short yet descriptive sentence. It takes exactly one argument, a
- * string, eg::
- *
- * varnishtest "Check that varnishtest is actually a valid command"
- *
- * It will also print that string in the log.
- */
-
-static void
-cmd_varnishtest(CMD_ARGS)
-{
-
- (void)priv;
- (void)cmd;
- (void)vl;
-
- if (av == NULL)
- return;
- AZ(strcmp(av[0], "varnishtest"));
-
- vtc_log(vl, 1, "TEST %s", av[1]);
- AZ(av[2]);
-}
-
-/* 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, otherwise the vtc will fail.
- *
- * 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 instead of zero.
- *
- * \-expect STRING
- * Expect string to be found in stdout+err.
- *
- * \-match REGEXP
- * Expect regexp to match the stdout+err output.
- */
-/* 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, const char *re)
-{
- struct vsb *vsb;
- FILE *fp;
- vre_t *vre = NULL;
- const char *errptr;
- int r, c;
- int err;
-
- AN(vl);
- AN(cmd);
- vsb = VSB_new_auto();
- AN(vsb);
- if (re != NULL) {
- vre = VRE_compile(re, 0, &errptr, &err);
- if (vre == NULL)
- vtc_fatal(vl, "shell_match invalid regexp (\"%s\")",
- re);
- }
- 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_fatal(vl, "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);
- AZ(VSB_finish(vsb));
- vtc_dump(vl, 4, "shell_out", VSB_data(vsb), VSB_len(vsb));
- 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) && !WIFSIGNALED(r))
- vtc_fatal(vl, "shell did not fail as expected");
- else if (ok >= 0 && WEXITSTATUS(r) != ok)
- vtc_fatal(vl, "shell_exit not as expected: "
- "got 0x%04x wanted 0x%04x", WEXITSTATUS(r), ok);
-
- if (expect != NULL) {
- if (strstr(VSB_data(vsb), expect) == NULL)
- vtc_fatal(vl,
- "shell_expect not found: (\"%s\")", expect);
- else
- vtc_log(vl, 4, "shell_expect found");
- } else if (vre != NULL) {
- if (VRE_exec(vre, VSB_data(vsb), VSB_len(vsb), 0, 0,
- NULL, 0, NULL) < 1)
- vtc_fatal(vl,
- "shell_match failed: (\"%s\")", re);
- else
- vtc_log(vl, 4, "shell_match succeeded");
- VRE_free(&vre);
- }
- VSB_destroy(&vsb);
-}
-
-
-void
-cmd_shell(CMD_ARGS)
-{
- const char *expect = NULL;
- const char *re = NULL;
- int n;
- int ok = 0;
-
- (void)priv;
- (void)cmd;
-
- if (av == NULL)
- return;
- 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")) {
- if (re != NULL)
- vtc_fatal(vl,
- "Cannot use -expect with -match");
- n += 1;
- expect = av[n];
- } else if (!strcmp(av[n], "-match")) {
- if (expect != NULL)
- vtc_fatal(vl,
- "Cannot use -match with -expect");
- n += 1;
- re = av[n];
- } else {
- break;
- }
- }
- AN(av[n]);
- cmd_shell_engine(vl, ok, av[n], expect, re);
-}
-
-/* SECTION: err_shell err_shell
- *
- * This is very similar to the the ``shell`` command, except it takes a first
- * string as argument before the command::
- *
- * err_shell "foo" "echo foo"
- *
- * err_shell expect the shell command to fail AND stdout to match the string,
- * failing the test case otherwise.
- */
-
-static void
-cmd_err_shell(CMD_ARGS)
-{
- (void)priv;
- (void)cmd;
-
- if (av == NULL)
- return;
- AN(av[1]);
- AN(av[2]);
- AZ(av[3]);
- vtc_log(vl, 1,
- "NOTICE: err_shell is deprecated, use 'shell -err -expect'");
- cmd_shell_engine(vl, -1, av[2], av[1], NULL);
-}
-
-/* SECTION: setenv setenv
- *
- * Set or change an environment variable::
- *
- * setenv FOO "bar baz"
- *
- * The above will set the environment variable $FOO to the value
- * provided. There is also an ``-ifunset`` argument which will only
- * set the value if the the environment variable does not already
- * exist::
- *
- * setenv -ifunset FOO quux
- */
-static void
-cmd_setenv(CMD_ARGS)
-{
- int r;
- int force;
-
- (void)priv;
- (void)cmd;
-
- if (av == NULL)
- return;
- AN(av[1]);
- AN(av[2]);
-
- force = 1;
- if (strcmp("-ifunset", av[1]) == 0) {
- force = 0;
- av++;
- AN(av[2]);
- }
- if (av[3] != NULL)
- vtc_fatal(vl, "CMD setenv: Unexpected argument '%s'", av[3]);
- r = setenv(av[1], av[2], force);
- if (r != 0)
- vtc_log(vl, 0, "CMD setenv %s=\"%s\" failed: %s",
- av[1], av[2], strerror(errno));
-}
-
-/* SECTION: delay delay
- *
- * Sleep for the number of seconds specified in the argument. The number
- * can include a fractional part, e.g. 1.5.
- */
-/* SECTION: stream.spec.delay delay
- *
- * Same as for the top-level delay.
- */
-void
-cmd_delay(CMD_ARGS)
-{
- double f;
-
- (void)priv;
- (void)cmd;
- if (av == NULL)
- return;
- AN(av[1]);
- AZ(av[2]);
- f = VNUM(av[1]);
- if (isnan(f))
- vtc_fatal(vl, "Syntax error in number (%s)", av[1]);
- vtc_log(vl, 3, "delaying %g second(s)", f);
- VTIM_sleep(f);
-}
-
-/* SECTION: feature feature
- *
- * Test that the required feature(s) for a test are available, and skip
- * the test otherwise; or change the interpretation of the test, as
- * documented below. feature takes any number of arguments from this list:
- *
- * SO_RCVTIMEO_WORKS
- * The SO_RCVTIMEO socket option is working
- * 64bit
- * The environment is 64 bits
- * !OSX
- * The environment is not OSX
- * dns
- * DNS lookups are working
- * topbuild
- * varnishtest has been started with '-i'
- * root
- * varnishtest has been invoked by the root user
- * user_varnish
- * The varnish user is present
- * user_vcache
- * The vcache user is present
- * group_varnish
- * The varnish group is present
- * cmd <command-line>
- * A command line that should execute with a zero exit status
- * ignore_unknown_macro
- * Do not fail the test if a string of the form ${...} is not
- * recognized as a macro.
- * term
- * Support for ADM3A terminal
- *
- * persistent_storage
- * Varnish was built with the deprecated persistent storage.
- *
- * Be careful with ignore_unknown_macro, because it may cause a test with a
- * misspelled macro to fail silently. You should only need it if you must
- * run a test with strings of the form "${...}".
- */
-
-#if WITH_PERSISTENT_STORAGE
-static const unsigned with_persistent_storage = 1;
-#else
-static const unsigned with_persistent_storage = 0;
-#endif
-
-static int
-test_term(struct vtclog *vl)
-{
- FILE *p;
- int a, b;
-
- p = popen("tput -T ansi.sys clear 2>&1", "r");
- if (p == NULL)
- return (0);
- a = fgetc(p);
- b = fgetc(p);
- if (a == 0x1b && b == '[')
- return (1);
- vtc_log(vl, 3, "No 'ansi.sys' terminfo entry.");
- return (0);
-}
-
-static void
-cmd_feature(CMD_ARGS)
-{
- int r;
- int good;
-
- (void)priv;
- (void)cmd;
-
- if (av == NULL)
- return;
-
-#define FEATURE(nm, tst) \
- do { \
- if (!strcmp(*av, nm)) { \
- if (tst) { \
- good = 1; \
- } else { \
- vtc_stop = 2; \
- } \
- } \
- } while (0)
-
- for (av++; *av != NULL; av++) {
- good = 0;
- if (!strcmp(*av, "SO_RCVTIMEO_WORKS")) {
-#ifdef SO_RCVTIMEO_WORKS
- good = 1;
-#else
- vtc_stop = 2;
-#endif
- }
-
- if (!strcmp(*av, "!OSX")) {
-#if !defined(__APPLE__) || !defined(__MACH__)
- good = 1;
-#else
- vtc_stop = 2;
-#endif
- }
- FEATURE("pcre_jit", VRE_has_jit);
- FEATURE("64bit", sizeof(void*) == 8);
- FEATURE("dns", feature_dns);
- FEATURE("topbuild", iflg);
- FEATURE("root", !geteuid());
- FEATURE("user_varnish", getpwnam("varnish") != NULL);
- FEATURE("user_vcache", getpwnam("vcache") != NULL);
- FEATURE("group_varnish", getgrnam("varnish") != NULL);
- FEATURE("term", test_term(vl));
- FEATURE("persistent_storage", with_persistent_storage);
-
- if (!strcmp(*av, "disable_aslr")) {
- good = 1;
-#ifdef HAVE_SYS_PERSONALITY_H
- r = personality(0xffffffff);
- r = personality(r | ADDR_NO_RANDOMIZE);
- if (r < 0) {
- good = 0;
- vtc_stop = 2;
- }
-#endif
- } else if (!strcmp(*av, "cmd")) {
- av++;
- if (*av == NULL)
- vtc_fatal(vl, "Missing the command-line");
- r = system(*av);
- if (WEXITSTATUS(r) == 0)
- good = 1;
- else
- vtc_stop = 2;
- } else if (!strcmp(*av, "ignore_unknown_macro")) {
- ign_unknown_macro = 1;
- good = 1;
- }
- if (good)
- continue;
-
- if (!vtc_stop)
- vtc_fatal(vl, "FAIL test, unknown feature: %s", *av);
- else
- vtc_log(vl, 1,
- "SKIPPING test, lacking feature: %s", *av);
- return;
- }
-}
-
/**********************************************************************
* Execute a file
*/
static const struct cmds cmds[] = {
#define CMD(n) { #n, cmd_##n },
- CMD(server)
- CMD(client)
- CMD(varnish)
- CMD(delay)
- CMD(varnishtest)
- CMD(shell)
- CMD(err_shell)
- CMD(barrier)
- CMD(feature)
- CMD(logexpect)
- CMD(process)
- CMD(setenv)
-#undef CMD
+#include "cmds.h"
{ NULL, NULL }
};
diff --git a/bin/varnishtest/vtc.h b/bin/varnishtest/vtc.h
index 8f0d130..387181c 100644
--- a/bin/varnishtest/vtc.h
+++ b/bin/varnishtest/vtc.h
@@ -69,16 +69,8 @@ void parse_string(const char *spec, const struct cmds *cmd, void *priv,
struct vtclog *vl);
int fail_out(void);
-#define CMD(n) cmd_f cmd_##n
-CMD(delay);
-CMD(server);
-CMD(client);
-CMD(varnish);
-CMD(barrier);
-CMD(logexpect);
-CMD(process);
-CMD(shell);
-#undef CMD
+#define CMD(n) cmd_f cmd_##n;
+#include "cmds.h"
extern volatile sig_atomic_t vtc_error; /* Error, bail out */
extern int vtc_stop; /* Abandon current test, no error */
@@ -90,6 +82,7 @@ extern struct vsb *params_vsb;
extern int leave_temp;
extern int vtc_witness;
extern int feature_dns;
+extern int ign_unknown_macro;
void init_server(void);
diff --git a/bin/varnishtest/vtc_misc.c b/bin/varnishtest/vtc_misc.c
new file mode 100644
index 0000000..30f404e
--- /dev/null
+++ b/bin/varnishtest/vtc_misc.c
@@ -0,0 +1,458 @@
+/*-
+ * Copyright (c) 2008-2011 Varnish Software AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <sys/wait.h>
+
+#include <errno.h>
+#include <grp.h>
+#include <math.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "vtc.h"
+
+#include "vnum.h"
+#include "vre.h"
+#include "vtim.h"
+
+/* SECTION: varnishtest varnishtest
+ *
+ * This should be the first command in your vtc as it will identify the test
+ * case with a short yet descriptive sentence. It takes exactly one argument, a
+ * string, eg::
+ *
+ * varnishtest "Check that varnishtest is actually a valid command"
+ *
+ * It will also print that string in the log.
+ */
+
+void v_matchproto_(cmd_f)
+cmd_varnishtest(CMD_ARGS)
+{
+
+ (void)priv;
+ (void)cmd;
+ (void)vl;
+
+ if (av == NULL)
+ return;
+ AZ(strcmp(av[0], "varnishtest"));
+
+ vtc_log(vl, 1, "TEST %s", av[1]);
+ AZ(av[2]);
+}
+
+/* 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, otherwise the vtc will fail.
+ *
+ * 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 instead of zero.
+ *
+ * \-expect STRING
+ * Expect string to be found in stdout+err.
+ *
+ * \-match REGEXP
+ * Expect regexp to match the stdout+err output.
+ */
+/* 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, const char *re)
+{
+ struct vsb *vsb;
+ FILE *fp;
+ vre_t *vre = NULL;
+ const char *errptr;
+ int r, c;
+ int err;
+
+ AN(vl);
+ AN(cmd);
+ vsb = VSB_new_auto();
+ AN(vsb);
+ if (re != NULL) {
+ vre = VRE_compile(re, 0, &errptr, &err);
+ if (vre == NULL)
+ vtc_fatal(vl, "shell_match invalid regexp (\"%s\")",
+ re);
+ }
+ 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_fatal(vl, "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);
+ AZ(VSB_finish(vsb));
+ vtc_dump(vl, 4, "shell_out", VSB_data(vsb), VSB_len(vsb));
+ 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) && !WIFSIGNALED(r))
+ vtc_fatal(vl, "shell did not fail as expected");
+ else if (ok >= 0 && WEXITSTATUS(r) != ok)
+ vtc_fatal(vl, "shell_exit not as expected: "
+ "got 0x%04x wanted 0x%04x", WEXITSTATUS(r), ok);
+
+ if (expect != NULL) {
+ if (strstr(VSB_data(vsb), expect) == NULL)
+ vtc_fatal(vl,
+ "shell_expect not found: (\"%s\")", expect);
+ else
+ vtc_log(vl, 4, "shell_expect found");
+ } else if (vre != NULL) {
+ if (VRE_exec(vre, VSB_data(vsb), VSB_len(vsb), 0, 0,
+ NULL, 0, NULL) < 1)
+ vtc_fatal(vl,
+ "shell_match failed: (\"%s\")", re);
+ else
+ vtc_log(vl, 4, "shell_match succeeded");
+ VRE_free(&vre);
+ }
+ VSB_destroy(&vsb);
+}
+
+
+void
+cmd_shell(CMD_ARGS)
+{
+ const char *expect = NULL;
+ const char *re = NULL;
+ int n;
+ int ok = 0;
+
+ (void)priv;
+ (void)cmd;
+
+ if (av == NULL)
+ return;
+ 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")) {
+ if (re != NULL)
+ vtc_fatal(vl,
+ "Cannot use -expect with -match");
+ n += 1;
+ expect = av[n];
+ } else if (!strcmp(av[n], "-match")) {
+ if (expect != NULL)
+ vtc_fatal(vl,
+ "Cannot use -match with -expect");
+ n += 1;
+ re = av[n];
+ } else {
+ break;
+ }
+ }
+ AN(av[n]);
+ cmd_shell_engine(vl, ok, av[n], expect, re);
+}
+
+/* SECTION: err_shell err_shell
+ *
+ * This is very similar to the the ``shell`` command, except it takes a first
+ * string as argument before the command::
+ *
+ * err_shell "foo" "echo foo"
+ *
+ * err_shell expect the shell command to fail AND stdout to match the string,
+ * failing the test case otherwise.
+ */
+
+void v_matchproto_(cmd_f)
+cmd_err_shell(CMD_ARGS)
+{
+ (void)priv;
+ (void)cmd;
+
+ if (av == NULL)
+ return;
+ AN(av[1]);
+ AN(av[2]);
+ AZ(av[3]);
+ vtc_log(vl, 1,
+ "NOTICE: err_shell is deprecated, use 'shell -err -expect'");
+ cmd_shell_engine(vl, -1, av[2], av[1], NULL);
+}
+
+/* SECTION: setenv setenv
+ *
+ * Set or change an environment variable::
+ *
+ * setenv FOO "bar baz"
+ *
+ * The above will set the environment variable $FOO to the value
+ * provided. There is also an ``-ifunset`` argument which will only
+ * set the value if the the environment variable does not already
+ * exist::
+ *
+ * setenv -ifunset FOO quux
+ */
+
+void v_matchproto_(cmd_f)
+cmd_setenv(CMD_ARGS)
+{
+ int r;
+ int force;
+
+ (void)priv;
+ (void)cmd;
+
+ if (av == NULL)
+ return;
+ AN(av[1]);
+ AN(av[2]);
+
+ force = 1;
+ if (strcmp("-ifunset", av[1]) == 0) {
+ force = 0;
+ av++;
+ AN(av[2]);
+ }
+ if (av[3] != NULL)
+ vtc_fatal(vl, "CMD setenv: Unexpected argument '%s'", av[3]);
+ r = setenv(av[1], av[2], force);
+ if (r != 0)
+ vtc_log(vl, 0, "CMD setenv %s=\"%s\" failed: %s",
+ av[1], av[2], strerror(errno));
+}
+
+/* SECTION: delay delay
+ *
+ * Sleep for the number of seconds specified in the argument. The number
+ * can include a fractional part, e.g. 1.5.
+ */
+/* SECTION: stream.spec.delay delay
+ *
+ * Same as for the top-level delay.
+ */
+void
+cmd_delay(CMD_ARGS)
+{
+ double f;
+
+ (void)priv;
+ (void)cmd;
+ if (av == NULL)
+ return;
+ AN(av[1]);
+ AZ(av[2]);
+ f = VNUM(av[1]);
+ if (isnan(f))
+ vtc_fatal(vl, "Syntax error in number (%s)", av[1]);
+ vtc_log(vl, 3, "delaying %g second(s)", f);
+ VTIM_sleep(f);
+}
+
+/* SECTION: feature feature
+ *
+ * Test that the required feature(s) for a test are available, and skip
+ * the test otherwise; or change the interpretation of the test, as
+ * documented below. feature takes any number of arguments from this list:
+ *
+ * SO_RCVTIMEO_WORKS
+ * The SO_RCVTIMEO socket option is working
+ * 64bit
+ * The environment is 64 bits
+ * !OSX
+ * The environment is not OSX
+ * dns
+ * DNS lookups are working
+ * topbuild
+ * varnishtest has been started with '-i'
+ * root
+ * varnishtest has been invoked by the root user
+ * user_varnish
+ * The varnish user is present
+ * user_vcache
+ * The vcache user is present
+ * group_varnish
+ * The varnish group is present
+ * cmd <command-line>
+ * A command line that should execute with a zero exit status
+ * ignore_unknown_macro
+ * Do not fail the test if a string of the form ${...} is not
+ * recognized as a macro.
+ * term
+ * Support for ADM3A terminal
+ *
+ * persistent_storage
+ * Varnish was built with the deprecated persistent storage.
+ *
+ * Be careful with ignore_unknown_macro, because it may cause a test with a
+ * misspelled macro to fail silently. You should only need it if you must
+ * run a test with strings of the form "${...}".
+ */
+
+#if WITH_PERSISTENT_STORAGE
+static const unsigned with_persistent_storage = 1;
+#else
+static const unsigned with_persistent_storage = 0;
+#endif
+
+static int
+test_term(struct vtclog *vl)
+{
+ FILE *p;
+ int a, b;
+
+ p = popen("tput -T ansi.sys clear 2>&1", "r");
+ if (p == NULL)
+ return (0);
+ a = fgetc(p);
+ b = fgetc(p);
+ if (a == 0x1b && b == '[')
+ return (1);
+ vtc_log(vl, 3, "No 'ansi.sys' terminfo entry.");
+ return (0);
+}
+
+void v_matchproto_(cmd_f)
+cmd_feature(CMD_ARGS)
+{
+ int r;
+ int good;
+
+ (void)priv;
+ (void)cmd;
+
+ if (av == NULL)
+ return;
+
+#define FEATURE(nm, tst) \
+ do { \
+ if (!strcmp(*av, nm)) { \
+ if (tst) { \
+ good = 1; \
+ } else { \
+ vtc_stop = 2; \
+ } \
+ } \
+ } while (0)
+
+ for (av++; *av != NULL; av++) {
+ good = 0;
+ if (!strcmp(*av, "SO_RCVTIMEO_WORKS")) {
+#ifdef SO_RCVTIMEO_WORKS
+ good = 1;
+#else
+ vtc_stop = 2;
+#endif
+ }
+
+ if (!strcmp(*av, "!OSX")) {
+#if !defined(__APPLE__) || !defined(__MACH__)
+ good = 1;
+#else
+ vtc_stop = 2;
+#endif
+ }
+ FEATURE("pcre_jit", VRE_has_jit);
+ FEATURE("64bit", sizeof(void*) == 8);
+ FEATURE("dns", feature_dns);
+ FEATURE("topbuild", iflg);
+ FEATURE("root", !geteuid());
+ FEATURE("user_varnish", getpwnam("varnish") != NULL);
+ FEATURE("user_vcache", getpwnam("vcache") != NULL);
+ FEATURE("group_varnish", getgrnam("varnish") != NULL);
+ FEATURE("term", test_term(vl));
+ FEATURE("persistent_storage", with_persistent_storage);
+
+ if (!strcmp(*av, "disable_aslr")) {
+ good = 1;
+#ifdef HAVE_SYS_PERSONALITY_H
+ r = personality(0xffffffff);
+ r = personality(r | ADDR_NO_RANDOMIZE);
+ if (r < 0) {
+ good = 0;
+ vtc_stop = 2;
+ }
+#endif
+ } else if (!strcmp(*av, "cmd")) {
+ av++;
+ if (*av == NULL)
+ vtc_fatal(vl, "Missing the command-line");
+ r = system(*av);
+ if (WEXITSTATUS(r) == 0)
+ good = 1;
+ else
+ vtc_stop = 2;
+ } else if (!strcmp(*av, "ignore_unknown_macro")) {
+ ign_unknown_macro = 1;
+ good = 1;
+ }
+ if (good)
+ continue;
+
+ if (!vtc_stop)
+ vtc_fatal(vl, "FAIL test, unknown feature: %s", *av);
+ else
+ vtc_log(vl, 1,
+ "SKIPPING test, lacking feature: %s", *av);
+ return;
+ }
+}
More information about the varnish-commit
mailing list