varnish-cache/bin/varnishtest/vtc_subr.c
1
/*-
2
 * Copyright (c) 2008-2017 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions
9
 * are met:
10
 * 1. Redistributions of source code must retain the above copyright
11
 *    notice, this list of conditions and the following disclaimer.
12
 * 2. Redistributions in binary form must reproduce the above copyright
13
 *    notice, this list of conditions and the following disclaimer in the
14
 *    documentation and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
20
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 * SUCH DAMAGE.
27
 */
28
29
#include "config.h"
30
31
#include <sys/types.h>
32
#include <math.h>
33
#include <stdio.h>
34
#include <string.h>
35
#include <stdint.h>
36
#include <unistd.h>
37
#include <sys/wait.h>
38
#include <sys/resource.h>
39
40
#include "vtc.h"
41
42
#include "vct.h"
43
#include "vnum.h"
44
#include "vre.h"
45
46
struct vsb *
47 1260
vtc_hex_to_bin(struct vtclog *vl, const char *arg)
48
{
49
        struct vsb *vsb;
50 1260
        unsigned sh = 4;
51 1260
        unsigned c, b = 0;
52
53 1260
        vsb = VSB_new_auto();
54 1260
        AN(vsb);
55 41388
        for (; *arg != '\0'; arg++) {
56 40128
                if (vct_issp(*arg) || *arg == '\n')
57 13160
                        continue;
58 26968
                c = (uint8_t)*arg;
59 26968
                if (c >= '0' && c <= '9')
60 22624
                        b |= (c - 48U) << sh;
61 4344
                else if (c >= 'A' && c <= 'F')
62 128
                        b |= (c - 55U) << sh;
63 4216
                else if (c >= 'a' && c <= 'f')
64 4216
                        b |= (c - 87U) << sh;
65
                else
66 0
                        vtc_fatal(vl,"Illegal hex string");
67 26968
                sh = 4 - sh;
68 26968
                if (sh == 4) {
69 13484
                        VSB_putc(vsb, b);
70 13484
                        b = 0;
71 13484
                }
72 26968
        }
73 1260
        if (sh != 4)
74 0
                VSB_putc(vsb, b);
75 1260
        AZ(VSB_finish(vsb));
76 1260
        return (vsb);
77
}
78
79
void
80 24125
vtc_expect(struct vtclog *vl,
81
    const char *olhs, const char *lhs,
82
    const char *cmp,
83
    const char *orhs, const char *rhs)
84
{
85
        vre_t *vre;
86
        const char *error;
87
        int erroroffset;
88 24125
        int i, j, retval = -1;
89
        double fl, fr;
90
91 24125
        j = lhs == NULL || rhs == NULL;
92 24125
        if (lhs == NULL)
93 692
                lhs = "<undef>";
94 24125
        if (rhs == NULL)
95 4
                rhs = "<undef>";
96
97 24125
        if (!strcmp(cmp, "~") || !strcmp(cmp, "!~")) {
98 132
                vre = VRE_compile(rhs, 0, &error, &erroroffset);
99 132
                if (vre == NULL)
100 0
                        vtc_fatal(vl, "REGEXP error: %s (@%d) (%s)",
101 0
                            error, erroroffset, rhs);
102 132
                i = VRE_exec(vre, lhs, strlen(lhs), 0, 0, NULL, 0, 0);
103 132
                retval = (i >= 0 && *cmp == '~') || (i < 0 && *cmp == '!');
104 132
                VRE_free(&vre);
105 24121
        } else if (!strcmp(cmp, "==")) {
106 23435
                retval = strcmp(lhs, rhs) == 0;
107 23991
        } else if (!strcmp(cmp, "!=")) {
108 108
                retval = strcmp(lhs, rhs) != 0;
109 556
        } else if (j) {
110
                // fail inequality comparisons if either side is undef'ed
111 0
                retval = 0;
112 0
        } else {
113 448
                fl = VNUM(lhs);
114 448
                fr = VNUM(rhs);
115 448
                if (!strcmp(cmp, "<"))
116 28
                        retval = isless(fl, fr);
117 420
                else if (!strcmp(cmp, ">"))
118 192
                        retval = isgreater(fl, fr);
119 228
                else if (!strcmp(cmp, "<="))
120 112
                        retval = islessequal(fl, fr);
121 116
                else if (!strcmp(cmp, ">="))
122 116
                        retval = isgreaterequal(fl, fr);
123
        }
124
125 24122
        if (retval == -1)
126 0
                vtc_fatal(vl,
127
                    "EXPECT %s (%s) %s %s (%s) test not implemented",
128 0
                    olhs, lhs, cmp, orhs, rhs);
129 24123
        else if (retval == 0)
130 0
                vtc_fatal(vl, "EXPECT %s (%s) %s \"%s\" failed",
131 0
                    olhs, lhs, cmp, rhs);
132
        else
133 48248
                vtc_log(vl, 4, "EXPECT %s (%s) %s \"%s\" match",
134 24124
                    olhs, lhs, cmp, rhs);
135 24125
}
136
137
/**********************************************************************
138
 * Wait for a subprocess.
139
 *
140
 * if expect_signal > 0, the process must die on that signal.
141
 * if expect_signal < 0, dying on that signal is allowed, but not required.
142
 * if allow_core > 0, a coredump is allowed, but not required.
143
 * otherwise, the process must die on exit(expect_status)
144
 */
145
146
#ifndef WCOREDUMP
147
#  define WCOREDUMP(s) (-1)
148
#endif
149
150
void
151 3132
vtc_wait4(struct vtclog *vl, long pid,
152
    int expect_status, int expect_signal, int allow_core)
153
{
154
        int status, r;
155
        struct rusage ru;
156
157 3132
        r = wait4(pid, &status, 0, &ru);
158 3132
        if (r < 0)
159 0
                vtc_fatal(vl, "wait4 failed on pid %ld: %s",
160 0
                    pid, strerror(errno));
161 3132
        assert(r == pid);
162 6264
        vtc_log(vl, 2, "WAIT4 pid=%ld status=0x%04x (user %.6f sys %.6f)",
163 3132
            pid, status,
164 3132
            ru.ru_utime.tv_sec + 1e-6 * ru.ru_utime.tv_usec,
165 3132
            ru.ru_stime.tv_sec + 1e-6 * ru.ru_stime.tv_usec
166
        );
167
168 3132
        if (WIFEXITED(status) && expect_signal <= 0 &&
169 3088
            WEXITSTATUS(status) == expect_status)
170 3088
                return;
171
172 44
        if (expect_signal < 0)
173 44
                expect_signal = -expect_signal;
174
175 44
        if (WIFSIGNALED(status) && WCOREDUMP(status) <= allow_core &&
176 44
            WTERMSIG(status) == expect_signal)
177 44
                return;
178 0
        vtc_log(vl, 1, "Expected exit: 0x%x signal: %d core: %d",
179 0
            expect_status, expect_signal, allow_core);
180 0
        vtc_fatal(vl, "Bad exit status: 0x%04x exit 0x%x signal %d core %d",
181 0
            status,
182 0
            WEXITSTATUS(status),
183 0
            WIFSIGNALED(status) ? WTERMSIG(status) : 0,
184 0
            WCOREDUMP(status));
185 3132
}
186
187
void *
188 2996
vtc_record(struct vtclog *vl, int fd, struct vsb *vsb)
189
{
190
        char buf[BUFSIZ];
191
        int i;
192
193 29174
        while (1) {
194 29174
                errno = 0;
195 29174
                i = read(fd, buf, sizeof buf - 1);
196 29174
                if (i > 0) {
197 26178
                        if (vsb != NULL)
198 12
                                VSB_bcat(vsb, buf, i);
199 26178
                        buf[i] = '\0';
200 26178
                        vtc_dump(vl, 3, "debug", buf, -2);
201 29174
                } else if (i == 0 && errno == 0) {
202 2996
                        vtc_log(vl, 4, "STDOUT EOF");
203 2996
                        break;
204
                } else {
205 0
                        vtc_log(vl, 4,
206
                            "STDOUT read failed with %d - %s.",
207 0
                            errno, strerror(errno));
208 0
                        break;
209
                }
210
        }
211 2996
        return (NULL);
212
}
213