varnish-cache/bin/varnishtest/vtc.c
1
/*-
2
 * Copyright (c) 2008-2011 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/wait.h>
32
33
#include <ctype.h>
34
#include <stdarg.h>
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <string.h>
38
#include <unistd.h>
39
40
#include "vtc.h"
41
42
#include "vav.h"
43
#include "vrnd.h"
44
#include "vtim.h"
45
46
#define         MAX_TOKENS              200
47
48
volatile sig_atomic_t   vtc_error;      /* Error encountered */
49
int                     vtc_stop;       /* Stops current test without error */
50
pthread_t               vtc_thread;
51
int                     ign_unknown_macro = 0;
52
static struct vtclog    *vltop;
53
54
static pthread_mutex_t  vtc_vrnd_mtx;
55
56
static void
57 61920
vtc_vrnd_lock(void)
58
{
59 61920
        AZ(pthread_mutex_lock(&vtc_vrnd_mtx));
60 61920
}
61
62
static void
63 61920
vtc_vrnd_unlock(void)
64
{
65 61920
        AZ(pthread_mutex_unlock(&vtc_vrnd_mtx));
66 61920
}
67
68
static const char *tfn;
69
70
/**********************************************************************
71
 * Macro facility
72
 */
73
74
struct macro {
75
        unsigned                magic;
76
#define MACRO_MAGIC             0x803423e3
77
        VTAILQ_ENTRY(macro)     list;
78
        char                    *name;
79
        char                    *val;
80
};
81
82
static VTAILQ_HEAD(,macro) macro_list = VTAILQ_HEAD_INITIALIZER(macro_list);
83
84
static const struct cmds global_cmds[] = {
85
#define CMD_GLOBAL(n) { #n, cmd_##n },
86
#include "cmds.h"
87
        { NULL, NULL }
88
};
89
90
static const struct cmds cmds[] = {
91
#define CMD_TOP(n) { #n, cmd_##n },
92
#include "cmds.h"
93
        { NULL, NULL }
94
};
95
96
/**********************************************************************/
97
98
static struct macro *
99 183630
macro_def_int(const char *name, const char *fmt, va_list ap)
100
{
101
        struct macro *m;
102
        char buf[256];
103
104 1554225
        VTAILQ_FOREACH(m, &macro_list, list)
105 1375140
                if (!strcmp(name, m->name))
106 4545
                        break;
107 183630
        if (m == NULL) {
108 179085
                ALLOC_OBJ(m, MACRO_MAGIC);
109 179085
                AN(m);
110 179085
                REPLACE(m->name, name);
111 179085
                AN(m->name);
112 179085
                VTAILQ_INSERT_TAIL(&macro_list, m, list);
113 179085
        }
114 183630
        AN(m);
115 183630
        vbprintf(buf, fmt, ap);
116 183630
        REPLACE(m->val, buf);
117 183630
        AN(m->val);
118 183630
        return (m);
119
}
120
121
122
/**********************************************************************
123
 * This is for defining macros before we fork the child process which
124
 * runs the test-case.
125
 */
126
127
void
128 58485
extmacro_def(const char *name, const char *fmt, ...)
129
{
130
        va_list ap;
131
132 58485
        va_start(ap, fmt);
133 58485
        (void)macro_def_int(name, fmt, ap);
134 58485
        va_end(ap);
135 58485
}
136
137
/**********************************************************************
138
 * Below this point is run inside the testing child-process.
139
 */
140
141
static pthread_mutex_t          macro_mtx;
142
143
static void
144 12000
init_macro(void)
145
{
146
        struct macro *m;
147
148
        /* Dump the extmacros for completeness */
149 71925
        VTAILQ_FOREACH(m, &macro_list, list)
150 59925
                vtc_log(vltop, 4, "extmacro def %s=%s", m->name, m->val);
151
152 12000
        AZ(pthread_mutex_init(&macro_mtx, NULL));
153 12000
}
154
155
void
156 125145
macro_def(struct vtclog *vl, const char *instance, const char *name,
157
    const char *fmt, ...)
158
{
159
        char buf1[256];
160
        struct macro *m;
161
        va_list ap;
162
163 125145
        AN(fmt);
164
165 125145
        if (instance != NULL) {
166 101145
                bprintf(buf1, "%s_%s", instance, name);
167 101145
                name = buf1;
168 101145
        }
169
170 125145
        AZ(pthread_mutex_lock(&macro_mtx));
171 125145
        va_start(ap, fmt);
172 125145
        m = macro_def_int(name, fmt, ap);
173 125145
        va_end(ap);
174 125145
        vtc_log(vl, 4, "macro def %s=%s", name, m->val);
175 125145
        AZ(pthread_mutex_unlock(&macro_mtx));
176 125145
}
177
178
void
179 41700
macro_undef(struct vtclog *vl, const char *instance, const char *name)
180
{
181
        char buf1[256];
182
        struct macro *m;
183
184 41700
        if (instance != NULL) {
185 41700
                bprintf(buf1, "%s_%s", instance, name);
186 41700
                name = buf1;
187 41700
        }
188
189 41700
        AZ(pthread_mutex_lock(&macro_mtx));
190 353040
        VTAILQ_FOREACH(m, &macro_list, list)
191 352485
                if (!strcmp(name, m->name))
192 41145
                        break;
193 41700
        if (m != NULL) {
194 41145
                if (!vtc_stop)
195 1650
                        vtc_log(vl, 4, "macro undef %s", name);
196 41145
                VTAILQ_REMOVE(&macro_list, m, list);
197 41145
                free(m->name);
198 41145
                free(m->val);
199 41145
                FREE_OBJ(m);
200 41145
        }
201 41700
        AZ(pthread_mutex_unlock(&macro_mtx));
202 41700
}
203
204
char *
205 109200
macro_get(const char *b, const char *e)
206
{
207
        struct macro *m;
208
        int l;
209 109200
        char *retval = NULL;
210
211 109200
        AN(b);
212 109200
        if (e == NULL)
213 46965
                e = strchr(b, '\0');
214 109200
        AN(e);
215 109200
        l = e - b;
216
217 109200
        if (l == 4 && !memcmp(b, "date", l)) {
218 45
                double t = VTIM_real();
219 45
                retval = malloc(64);
220 45
                AN(retval);
221 45
                VTIM_format(t, retval);
222 45
                return (retval);
223
        }
224
225 109155
        AZ(pthread_mutex_lock(&macro_mtx));
226 627825
        VTAILQ_FOREACH(m, &macro_list, list) {
227 627345
                CHECK_OBJ_NOTNULL(m, MACRO_MAGIC);
228 627345
                if (!strncmp(b, m->name, l) && m->name[l] == '\0')
229 108675
                        break;
230 518670
        }
231 109155
        if (m != NULL)
232 108675
                retval = strdup(m->val);
233 109155
        AZ(pthread_mutex_unlock(&macro_mtx));
234 109155
        return (retval);
235 109200
}
236
237
struct vsb *
238 15420
macro_expandf(struct vtclog *vl, const char *fmt, ...)
239
{
240
        va_list ap;
241
        struct vsb *vsb1, *vsb2;
242
243 15420
        vsb1 = VSB_new_auto();
244 15420
        AN(vsb1);
245 15420
        va_start(ap, fmt);
246 15420
        VSB_vprintf(vsb1, fmt, ap);
247 15420
        va_end(ap);
248 15420
        AZ(VSB_finish(vsb1));
249 15420
        vsb2 = macro_expand(vl, VSB_data(vsb1));
250 15420
        VSB_destroy(&vsb1);
251 15420
        return (vsb2);
252
}
253
254
struct vsb *
255 59400
macro_expand(struct vtclog *vl, const char *text)
256
{
257
        struct vsb *vsb;
258
        const char *p, *q;
259
        char *m;
260
261 59400
        vsb = VSB_new_auto();
262 59400
        AN(vsb);
263 121635
        while (*text != '\0') {
264 99975
                p = strstr(text, "${");
265 99975
                if (p == NULL) {
266 37740
                        VSB_cat(vsb, text);
267 37740
                        break;
268
                }
269 62235
                VSB_bcat(vsb, text, p - text);
270 62235
                q = strchr(p, '}');
271 62235
                if (q == NULL) {
272 0
                        VSB_cat(vsb, text);
273 0
                        break;
274
                }
275 62235
                assert(p[0] == '$');
276 62235
                assert(p[1] == '{');
277 62235
                assert(q[0] == '}');
278 62235
                p += 2;
279 62235
                m = macro_get(p, q);
280 62235
                if (m == NULL) {
281 480
                        if (!ign_unknown_macro) {
282 0
                                VSB_destroy(&vsb);
283 0
                                vtc_fatal(vl, "Macro ${%.*s} not found",
284 0
                                          (int)(q - p), p);
285
                                NEEDLESS(return (NULL));
286
                        }
287 480
                        VSB_printf(vsb, "${%.*s}", (int)(q - p), p);
288 480
                } else {
289 61755
                        VSB_printf(vsb, "%s", m);
290 61755
                        free(m);
291
                }
292 62235
                text = q + 1;
293
        }
294 59400
        AZ(VSB_finish(vsb));
295 59400
        return (vsb);
296
}
297
298
/**********************************************************************
299
 * Parse a string
300
 *
301
 * We make a copy of the string and deliberately leak it, so that all
302
 * the cmd functions we call don't have to strdup(3) all over the place.
303
 *
304
 * Static checkers like Coverity may bitch about this, but we don't care.
305
 */
306
307
308
void
309 74426
parse_string(const char *spec, const struct cmds *cmd, void *priv,
310
    struct vtclog *vl)
311
{
312
        char *token_s[MAX_TOKENS], *token_e[MAX_TOKENS];
313
        struct vsb *token_exp;
314
        char *e, *p, *q, *f, *buf;
315
        int nest_brace;
316
        int tn;
317
        const struct cmds *cp;
318
319 74426
        AN(spec);
320 74426
        buf = strdup(spec);
321 74426
        AN(buf);
322 74427
        e = strchr(buf, '\0');
323 74427
        AN(e);
324 1010797
        for (p = buf; p < e; p++) {
325 936976
                if (vtc_error || vtc_stop)
326 144
                        break;
327
                /* Start of line */
328 936831
                if (isspace(*p))
329 502918
                        continue;
330 433966
                if (*p == '\n')
331 0
                        continue;
332
333 433967
                if (*p == '#') {
334 993072
                        for (; *p != '\0' && *p != '\n'; p++)
335
                                ;
336 24165
                        if (*p == '\0')
337 0
                                break;
338 24165
                        continue;
339
                }
340
341 409794
                q = strchr(p, '\n');
342 409794
                if (q == NULL)
343 3764
                        q = strchr(p, '\0');
344 409799
                if (q - p > 60)
345 20010
                        vtc_log(vl, 2, "=== %.60s...", p);
346
                else
347 389789
                        vtc_log(vl, 2, "=== %.*s", (int)(q - p), p);
348
349
                /* First content on line, collect tokens */
350 409808
                memset(token_s, 0, sizeof token_s);
351 409808
                memset(token_e, 0, sizeof token_e);
352 409808
                tn = 0;
353 409808
                f = p;
354 2722670
                while (p < e) {
355 2718629
                        assert(tn < MAX_TOKENS);
356 2718554
                        assert(p < e);
357 2718599
                        if (*p == '\n') { /* End on NL */
358 406026
                                break;
359
                        }
360 2312594
                        if (isspace(*p)) { /* Inter-token whitespace */
361 975810
                                p++;
362 975810
                                continue;
363
                        }
364 1337036
                        if (*p == '\\' && p[1] == '\n') { /* line-cont */
365 13725
                                p += 2;
366 13725
                                continue;
367
                        }
368 1323320
                        if (*p == '"') { /* quotes */
369 136751
                                token_s[tn] = ++p;
370 136751
                                q = p;
371 3196459
                                for (; *p != '\0'; p++) {
372 3196441
                                        assert(p < e);
373 3196431
                                        if (*p == '"')
374 136750
                                                break;
375 3059690
                                        if (*p == '\\') {
376 37080
                                                p += VAV_BackSlash(p, q) - 1;
377 37080
                                                q++;
378 37080
                                        } else {
379 3022613
                                                if (*p == '\n')
380 0
                                                        vtc_fatal(vl,
381
                                "Unterminated quoted string in line: %*.*s",
382 0
                                (int)(p - f), (int)(p - f), f);
383 3022604
                                                assert(*p != '\n');
384 3022629
                                                *q++ = *p;
385
                                        }
386 3059730
                                }
387 136750
                                token_e[tn++] = q;
388 136750
                                p++;
389 1323309
                        } else if (*p == '{') { /* Braces */
390 84785
                                nest_brace = 0;
391 84785
                                token_s[tn] = p + 1;
392 13264122
                                for (; p < e; p++) {
393 13264045
                                        if (*p == '{')
394 152345
                                                nest_brace++;
395 13111780
                                        else if (*p == '}') {
396 152345
                                                if (--nest_brace == 0)
397 84785
                                                        break;
398 67560
                                        }
399 13179416
                                }
400 84785
                                assert(*p == '}');
401 84785
                                token_e[tn++] = p++;
402 84785
                        } else { /* other tokens */
403 1101773
                                token_s[tn] = p;
404 7239486
                                for (; p < e && !isspace(*p); p++)
405 6137692
                                        continue;
406 1101801
                                token_e[tn++] = p;
407
                        }
408
                }
409
410 409806
                assert(p <= e);
411 409805
                assert(tn < MAX_TOKENS);
412 409801
                token_s[tn] = NULL;
413 1733089
                for (tn = 0; token_s[tn] != NULL; tn++) {
414 1323277
                        AN(token_e[tn]);        /*lint !e771 */
415 1323267
                        *token_e[tn] = '\0';    /*lint !e771 */
416 1323267
                        if (NULL != strstr(token_s[tn], "${")) {
417 11100
                                token_exp = macro_expand(vl, token_s[tn]);
418 11100
                                if (vtc_error)
419 0
                                        return;
420 11100
                                token_s[tn] = VSB_data(token_exp);
421 11100
                                token_e[tn] = strchr(token_s[tn], '\0');
422 11100
                        }
423 1323318
                }
424
425 7336576
                for (cp = cmd; cp->name != NULL; cp++)
426 7315454
                        if (!strcmp(token_s[0], cp->name))
427 389171
                                break;
428
429 409796
                if (cp->name == NULL) {
430 39510
                        for (cp = global_cmds; cp->name != NULL; cp++)
431 39510
                                if (!strcmp(token_s[0], cp->name))
432 20625
                                        break;
433 20625
                }
434
435 409801
                if (cp->name == NULL)
436 0
                        vtc_fatal(vl, "Unknown command: \"%s\"", token_s[0]);
437
438 409798
                assert(cp->cmd != NULL);
439 409803
                cp->cmd(token_s, priv, cmd, vl);
440 409803
        }
441 73916
}
442
443
/**********************************************************************
444
 * Reset commands (between tests)
445
 */
446
447
static void
448 24000
reset_cmds(const struct cmds *cmd)
449
{
450
451 204000
        for (; cmd->name != NULL; cmd++)
452 180000
                cmd->cmd(NULL, NULL, NULL, NULL);
453 24000
}
454
455
/**********************************************************************
456
 * Execute a file
457
 */
458
459
int
460 12000
fail_out(void)
461
{
462
        unsigned old_err;
463
        static int once = 0;
464
465 12000
        if (once++) {
466 0
                vtc_log(vltop, 1, "failure during reset");
467 0
                return (vtc_error);
468
        }
469 12000
        old_err = vtc_error;
470 12000
        if (!vtc_stop)
471 11865
                vtc_stop = 1;
472 12000
        vtc_log(vltop, 1, "RESETTING after %s", tfn);
473 12000
        reset_cmds(global_cmds);
474 12000
        reset_cmds(cmds);
475 12000
        vtc_error |= old_err;
476
477 12000
        if (vtc_error)
478 30
                vtc_log(vltop, 1, "TEST %s FAILED", tfn);
479
        else
480 11970
                vtc_log(vltop, 1, "TEST %s completed", tfn);
481
482 12000
        if (vtc_stop > 1)
483 135
                return (1);
484 11865
        return (vtc_error);
485 12000
}
486
487
int
488 12000
exec_file(const char *fn, const char *script, const char *tmpdir,
489
    char *logbuf, unsigned loglen)
490
{
491
        FILE *f;
492
        struct vsb *vsb;
493
        const char *p;
494
        char *q;
495
496 12000
        (void)signal(SIGPIPE, SIG_IGN);
497
498 12000
        AZ(pthread_mutex_init(&vtc_vrnd_mtx, NULL));
499 12000
        VRND_Lock = vtc_vrnd_lock;
500 12000
        VRND_Unlock = vtc_vrnd_unlock;
501 12000
        VRND_SeedAll();
502
503 12000
        tfn = fn;
504 12000
        vtc_loginit(logbuf, loglen);
505 12000
        vltop = vtc_logopen("top");
506 12000
        AN(vltop);
507
508 12000
        vtc_log(vltop, 1, "TEST %s starting", fn);
509
510 12000
        init_macro();
511 12000
        init_server();
512 12000
        init_syslog();
513
514 12000
        vsb = VSB_new_auto();
515 12000
        AN(vsb);
516 12000
        if (*fn != '/') {
517 12000
                q = macro_get("pwd", NULL);
518 12000
                AN(q);
519 12000
                VSB_cat(vsb, q);
520 12000
                free(q);
521 12000
        }
522 12000
        p = strrchr(fn, '/');
523 12000
        if (p != NULL) {
524 11895
                VSB_putc(vsb, '/');
525 11895
                VSB_bcat(vsb, fn, p - fn);
526 11895
        }
527 12000
        if (VSB_len(vsb) == 0)
528 0
                VSB_putc(vsb, '/');
529 12000
        AZ(VSB_finish(vsb));
530 12000
        macro_def(vltop, NULL, "testdir", "%s", VSB_data(vsb));
531 12000
        VSB_destroy(&vsb);
532
533
        /* Move into our tmpdir */
534 12000
        AZ(chdir(tmpdir));
535 12000
        macro_def(vltop, NULL, "tmpdir", "%s", tmpdir);
536
537
        /* Drop file to tell what was going on here */
538 12000
        f = fopen("INFO", "w");
539 12000
        AN(f);
540 12000
        fprintf(f, "Test case: %s\n", fn);
541 12000
        AZ(fclose(f));
542
543 12000
        vtc_stop = 0;
544
545 12000
        vtc_thread = pthread_self();
546 12000
        parse_string(script, cmds, NULL, vltop);
547 12000
        return (fail_out());
548
}