rfc822: Allow test infrastructure to handle headers with minor errors
[ccan] / ccan / rfc822 / test / run-hdr-and-body.c
1 #include <ccan/foreach/foreach.h>
2 #include <ccan/failtest/failtest_override.h>
3 #include <ccan/failtest/failtest.h>
4 #include <ccan/tap/tap.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #define CCAN_RFC822_DEBUG
9
10 #include <ccan/rfc822/rfc822.h>
11
12 #include <ccan/rfc822/rfc822.c>
13
14 #include "testdata.h"
15 #include "helper.h"
16
17 #define CHECK_HEADERS(_e, _msg, _h, _n, _crlf)  \
18         do { \
19                 int _i; \
20                 for (_i = 0; _i < (_e)->nhdrs; _i++) {  \
21                         (_h) = rfc822_next_header((_msg), (_h)); \
22                         ok((_h), "header %d exists %s", _i, (_n)); \
23                         if (!(_h)) \
24                                 break; \
25                         check_header((_msg), (_h), (_e)->hdrs[_i].name, \
26                                      (_e)->hdrs[_i].val,                \
27                                      (_e)->hdrs[_i].errors, crlf);      \
28                 } \
29         } while (0)
30
31 static void test_bodyhdr(const struct aexample *e, const char *buf, size_t len,
32                          const char *exname, int crlf)
33 {
34         struct rfc822_msg *msg;
35         struct rfc822_header *h = NULL;
36         struct bytestring body;
37
38         msg = rfc822_start(NULL, buf, len);
39         allocation_failure_check();
40
41         ok(msg, "opened %s", exname);
42
43         body = rfc822_body(msg);
44         allocation_failure_check();
45         ok(bytestring_eq(body, bytestring_from_string(e->body)),
46            "body content %s", exname);
47
48         CHECK_HEADERS(e, msg, h, exname, crlf);
49         h = rfc822_next_header(msg, h);
50         allocation_failure_check();
51         ok(!h, "Too many headers for %s", exname);
52
53         rfc822_free(msg);
54         allocation_failure_check();
55 }
56
57 static void test_hdrbody(const struct aexample *e, const char *buf, size_t len,
58                          const char *exname, int crlf)
59 {
60         struct rfc822_msg *msg;
61         struct rfc822_header *h = NULL;
62         struct bytestring body;
63
64         msg = rfc822_start(NULL, buf, len);
65         allocation_failure_check();
66         ok(msg, "opened %s", exname);
67
68         CHECK_HEADERS(e, msg, h, exname, crlf);
69         h = rfc822_next_header(msg, h);
70         allocation_failure_check();
71         ok(!h, "Too many headers for %s", exname);
72
73         body = rfc822_body(msg);
74         allocation_failure_check();
75         ok(bytestring_eq(body, bytestring_from_string(e->body)),
76            "body content %s", exname);
77
78         rfc822_free(msg);
79         allocation_failure_check();
80 }
81
82 static void test_hdrhdr(const struct aexample *e, const char *buf, size_t len,
83                         const char *exname, int crlf)
84 {
85         struct rfc822_msg *msg;
86         struct rfc822_header *h;
87
88         msg = rfc822_start(NULL, buf, len);
89         allocation_failure_check();
90         ok(msg, "opened %s", exname);
91
92         h = NULL;
93         CHECK_HEADERS(e, msg, h, exname, crlf);
94
95         h = rfc822_next_header(msg, h);
96         allocation_failure_check();
97         ok(!h, "Too many headers for %s", exname);
98
99         /* And again, this time it should be cached */
100         h = NULL;
101         CHECK_HEADERS(e, msg, h, exname, crlf);
102
103         h = rfc822_next_header(msg, h);
104         allocation_failure_check();
105         ok(!h, "Too many headers for %s", exname);
106
107         rfc822_free(msg);
108         allocation_failure_check();
109 }
110
111 int main(int argc, char *argv[])
112 {
113         struct aexample *e;
114
115         /* This is how many tests you plan to run */
116         plan_tests(20*num_aexamples()
117                    + (36 + CHECK_HEADER_NUMTESTS)*num_aexample_hdrs());
118
119         failtest_setup(argc, argv);
120
121         for_each_aexample(e) {
122                 int crlf;
123
124                 foreach_int(crlf, 0, 1) {
125                         const char *buf;
126                         size_t len;
127                         char exname[256];
128
129                         sprintf(exname, "%s[%s]", e->name, NLT(crlf));
130
131                         buf = assemble_msg(e, &len, crlf);
132                         ok((buf), "assembled %s", exname);
133                         if (!buf)
134                                 continue;
135
136                         test_bodyhdr(e, buf, len, exname, crlf);
137                         test_hdrbody(e, buf, len, exname, crlf);
138                         test_hdrhdr(e, buf, len, exname, crlf);
139
140                         talloc_free(buf);
141                 }
142         }
143
144         /* This exits depending on whether all tests passed */
145         failtest_exit(exit_status());
146 }