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 4725
vtc_hex_to_bin(struct vtclog *vl, const char *arg)
48
{
49
        struct vsb *vsb;
50 4725
        unsigned sh = 4;
51 4725
        unsigned c, b = 0;
52
53 4725
        vsb = VSB_new_auto();
54 4725
        AN(vsb);
55 155205
        for (; *arg != '\0'; arg++) {
56 150480
                if (vct_issp(*arg) || *arg == '\n')
57 49350
                        continue;
58 101130
                c = (uint8_t)*arg;
59 101130
                if (c >= '0' && c <= '9')
60 84840
                        b |= (c - 48U) << sh;
61 16290
                else if (c >= 'A' && c <= 'F')
62 480
                        b |= (c - 55U) << sh;
63 15810
                else if (c >= 'a' && c <= 'f')
64 15810
                        b |= (c - 87U) << sh;
65
                else
66 0
                        vtc_fatal(vl,"Illegal hex string");
67 101130
                sh = 4 - sh;
68 101130
                if (sh == 4) {
69 50565
                        VSB_putc(vsb, b);
70 50565
                        b = 0;
71 50565
                }
72 101130
        }
73 4725
        if (sh != 4)
74 0
                VSB_putc(vsb, b);
75 4725
        AZ(VSB_finish(vsb));
76 4725
        return (vsb);
77
}
78
79
void
80 90761
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 90761
        int i, j, retval = -1;
89
        double fl, fr;
90
91 90761
        j = lhs == NULL || rhs == NULL;
92 90759
        if (lhs == NULL)
93 2625
                lhs = "<undef>";
94 90758
        if (rhs == NULL)
95 15
                rhs = "<undef>";
96
97 90763
        if (!strcmp(cmp, "~") || !strcmp(cmp, "!~")) {
98 495
                vre = VRE_compile(rhs, 0, &error, &erroroffset);
99 495
                if (vre == NULL)
100 0
                        vtc_fatal(vl, "REGEXP error: %s (@%d) (%s)",
101 0
                            error, erroroffset, rhs);
102 495
                i = VRE_exec(vre, lhs, strlen(lhs), 0, 0, NULL, 0, 0);
103 495
                retval = (i >= 0 && *cmp == '~') || (i < 0 && *cmp == '!');
104 495
                VRE_free(&vre);
105 90762
        } else if (!strcmp(cmp, "==")) {
106 88185
                retval = strcmp(lhs, rhs) == 0;
107 90270
        } else if (!strcmp(cmp, "!=")) {
108 405
                retval = strcmp(lhs, rhs) != 0;
109 2085
        } else if (j) {
110
                // fail inequality comparisons if either side is undef'ed
111 0
                retval = 0;
112 0
        } else {
113 1680
                fl = VNUM(lhs);
114 1680
                fr = VNUM(rhs);
115 1680
                if (!strcmp(cmp, "<"))
116 105
                        retval = isless(fl, fr);
117 1575
                else if (!strcmp(cmp, ">"))
118 720
                        retval = isgreater(fl, fr);
119 855
                else if (!strcmp(cmp, "<="))
120 420
                        retval = islessequal(fl, fr);
121 435
                else if (!strcmp(cmp, ">="))
122 435
                        retval = isgreaterequal(fl, fr);
123
        }
124
125 90748
        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 90748
        else if (retval == 0)
130 0
                vtc_fatal(vl, "EXPECT %s (%s) %s \"%s\" failed",
131 0
                    olhs, lhs, cmp, rhs);
132
        else
133 181524
                vtc_log(vl, 4, "EXPECT %s (%s) %s \"%s\" match",
134 90762
                    olhs, lhs, cmp, rhs);
135 90768
}
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 11910
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 11910
        r = wait4(pid, &status, 0, &ru);
158 11910
        if (r < 0)
159 0
                vtc_fatal(vl, "wait4 failed on pid %ld: %s",
160 0
                    pid, strerror(errno));
161 11910
        assert(r == pid);
162 23820
        vtc_log(vl, 2, "WAIT4 pid=%ld status=0x%04x (user %.6f sys %.6f)",
163 11910
            pid, status,
164 11910
            ru.ru_utime.tv_sec + 1e-6 * ru.ru_utime.tv_usec,
165 11910
            ru.ru_stime.tv_sec + 1e-6 * ru.ru_stime.tv_usec
166
        );
167
168 11910
        if (WIFEXITED(status) && expect_signal <= 0 &&
169 11745
            WEXITSTATUS(status) == expect_status)
170 11745
                return;
171
172 165
        if (expect_signal < 0)
173 165
                expect_signal = -expect_signal;
174
175 165
        if (WIFSIGNALED(status) && WCOREDUMP(status) <= allow_core &&
176 165
            WTERMSIG(status) == expect_signal)
177 165
                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 11910
}
186
187
void *
188 11280
vtc_record(struct vtclog *vl, int fd, struct vsb *vsb)
189
{
190
        char buf[BUFSIZ];
191
        int i;
192
193 117307
        while (1) {
194 117307
                errno = 0;
195 117307
                i = read(fd, buf, sizeof buf - 1);
196 117307
                if (i > 0) {
197 106027
                        if (vsb != NULL)
198 45
                                VSB_bcat(vsb, buf, i);
199 106027
                        buf[i] = '\0';
200 106027
                        vtc_dump(vl, 3, "debug", buf, -2);
201 117307
                } else if (i == 0 && errno == 0) {
202 11280
                        vtc_log(vl, 4, "STDOUT EOF");
203 11280
                        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 11280
        return (NULL);
212
}
213