9 |
9 |
10 #include <stdlib.h> |
10 #include <stdlib.h> |
11 #include <string.h> |
11 #include <string.h> |
12 #include <assert.h> |
12 #include <assert.h> |
13 |
13 |
14 void assert_strcmp (const char *a, const char *b) |
14 void assert_strcmp (const char *is, const char *should_be) |
15 { |
15 { |
16 if (strcmp(a, b)) |
16 if (strcmp(is, should_be)) |
17 FATAL("'%s' != '%s'", a, b); |
17 FATAL("'%s' != '%s'", is, should_be); |
18 } |
18 } |
19 |
19 |
20 void assert_strncmp (const char *a, const char *b, size_t n) |
20 void assert_strncmp (const char *is, const char *should_be, size_t n) |
21 { |
21 { |
22 if (strncmp(a, b, n)) |
22 if (strncmp(is, should_be, n)) |
23 FATAL("'%s':%d != '%s'", a, n, b); |
23 FATAL("'%s':%d != '%s'", is, n, should_be); |
24 } |
24 } |
25 |
25 |
26 void assert_strlen (const char *str, size_t n) |
26 void assert_strlen (const char *str, size_t n) |
27 { |
27 { |
28 if (strlen(str) != n) |
28 if (strlen(str) != n) |
29 FATAL("strlen('%s') != %u", str, n); |
29 FATAL("strlen('%s') != %u", str, n); |
30 } |
30 } |
31 |
31 |
32 void assert_strnul (const char *str) |
32 void assert_strnull (const char *str) |
33 { |
33 { |
34 if (str != NULL) |
34 if (str != NULL) |
35 FATAL("'%s' != NULL", str); |
35 FATAL("'%s' != NULL", str); |
36 } |
36 } |
37 |
37 |
43 } |
43 } |
44 |
44 |
45 void assert_err (err_t err, err_t target) |
45 void assert_err (err_t err, err_t target) |
46 { |
46 { |
47 if (err != target) |
47 if (err != target) |
48 FATAL("error: <%s> != target <%s>", error_name(err), error_name(target)); |
48 FATAL("error: <%s> != <%s>", error_name(err), error_name(target)); |
|
49 } |
|
50 |
|
51 void assert_error_info (struct error_info *is, struct error_info *should_be) |
|
52 { |
|
53 if (ERROR_CODE(is) != ERROR_CODE(should_be) || ERROR_EXTRA(is) != ERROR_EXTRA(should_be)) |
|
54 FATAL("error: <%s> != <%s>", error_msg(is), error_msg(should_be)); |
49 } |
55 } |
50 |
56 |
51 void assert_sock_read (struct sock_stream *sock, const char *str) |
57 void assert_sock_read (struct sock_stream *sock, const char *str) |
52 { |
58 { |
53 char buf[strlen(str)]; |
59 char buf[strlen(str)]; |
133 if (line_str) { |
139 if (line_str) { |
134 assert(line_buf != NULL); |
140 assert(line_buf != NULL); |
135 assert_strcmp(line_buf, line_str); |
141 assert_strcmp(line_buf, line_str); |
136 |
142 |
137 } else { |
143 } else { |
138 assert_strnul(line_buf); |
144 assert_strnull(line_buf); |
139 |
145 |
140 } |
146 } |
141 } |
147 } |
142 |
148 |
|
149 /** |
|
150 * Context info for test_line_proto callbacks |
|
151 */ |
|
152 struct _lp_test_ctx { |
|
153 /** Expected line */ |
|
154 const char *line; |
|
155 |
|
156 /** Expected error */ |
|
157 struct error_info err; |
|
158 }; |
|
159 |
|
160 static void _lp_on_line (char *line, void *arg) |
|
161 { |
|
162 struct _lp_test_ctx *ctx = arg; |
|
163 |
|
164 log_debug("'%s'", line); |
|
165 |
|
166 assert_strcmp(line, ctx->line); |
|
167 |
|
168 ctx->line = NULL; |
|
169 } |
|
170 |
|
171 static void _lp_on_error (struct error_info *err, void *arg) |
|
172 { |
|
173 struct _lp_test_ctx *ctx = arg; |
|
174 |
|
175 assert_error_info(err, &ctx->err); |
|
176 } |
|
177 |
143 static struct line_proto_callbacks _lp_callbacks = { |
178 static struct line_proto_callbacks _lp_callbacks = { |
144 .on_line = NULL, |
179 .on_line = &_lp_on_line, |
145 .on_error = NULL, |
180 .on_error = &_lp_on_error, |
146 }; |
181 }; |
147 |
182 |
148 void test_line_proto (void) |
183 void test_line_proto (void) |
149 { |
184 { |
150 struct sock_test *sock = sock_test_create(); |
185 struct sock_test *sock = sock_test_create(); |
154 { "this ", 5 }, |
189 { "this ", 5 }, |
155 { "is a line\r", 10 }, |
190 { "is a line\r", 10 }, |
156 { "\nfragment", 9 }, |
191 { "\nfragment", 9 }, |
157 }, _trailing_data = { "\r\n", 2 }; |
192 }, _trailing_data = { "\r\n", 2 }; |
158 struct line_proto *lp; |
193 struct line_proto *lp; |
|
194 struct _lp_test_ctx ctx; |
159 struct error_info err; |
195 struct error_info err; |
160 |
196 |
161 // put the read data |
197 // put the read data |
162 log_debug("set_recv_buffer: %p, %d", _read_data, 5); |
198 log_debug("set_recv_buffer: %p, %d", _read_data, 5); |
163 sock_test_set_recv_buffer(sock, _read_data, 5, false); |
199 sock_test_set_recv_buffer(sock, _read_data, 5, false); |
164 |
200 |
165 // create the lp |
201 // create the lp |
166 assert_success(line_proto_create(&lp, SOCK_TEST_BASE(sock), 128, &_lp_callbacks, NULL, &err)); |
202 assert_success(line_proto_create(&lp, SOCK_TEST_BASE(sock), 128, &_lp_callbacks, &ctx, &err)); |
167 |
203 |
168 log_info("test line_proto_recv"); |
204 log_info("test line_proto_recv"); |
169 |
205 |
170 // then read some lines from it |
206 // then read some lines from it |
171 assert_read_line(lp, "hello"); |
207 assert_read_line(lp, "hello"); |
172 assert_read_line(lp, "world"); |
208 assert_read_line(lp, "world"); |
173 assert_read_line(lp, "this is a line"); |
209 assert_read_line(lp, "this is a line"); |
174 assert_read_line(lp, NULL); |
210 assert_read_line(lp, NULL); |
175 |
211 |
176 // then add a final bit |
212 // then add a final bit to trigger on_line |
|
213 log_info("test on_line"); |
|
214 |
|
215 ctx.line = "fragment"; |
177 sock_test_add_recv_vec(sock, _trailing_data); |
216 sock_test_add_recv_vec(sock, _trailing_data); |
178 |
217 assert_strnull(ctx.line); |
179 // read the final bit |
|
180 assert_read_line(lp, "fragment"); |
|
181 |
218 |
182 // cleanup |
219 // cleanup |
183 line_proto_release(lp); |
220 line_proto_release(lp); |
184 } |
221 } |
185 |
222 |