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