==> tests/wire.c <==1/* infer.rs's messages_and_layers_round_trip, over a socketpair. */
2#include "mesh/check.h"
3#include "mesh/infer_wire.h"
4
5#include <stdlib.h>
6#include <string.h>
7#include <sys/socket.h>
8#include <unistd.h>
9
10int main(void) {
11 mesh_infer_msg m;
12 mesh_infer_msg_init(&m);
13 mesh_infer_msg_set(&m, "mode", "exact");
14 mesh_infer_msg_setf(&m, "max", "%d", 7);
15 mesh_infer_msg_set(&m, "x", "a\nb");
16 mesh_buf e = MESH_BUF_INIT;
17 mesh_infer_msg_encode(&m, &e);
18 CHECK_S(mesh_buf_str(&e), "max=7\nmode=exact\nx=a b\n\n");
19 mesh_infer_msg_set_body(&m, "line one\n\nline three");
20 mesh_buf_clear(&e);
21 mesh_infer_msg_encode(&m, &e);
22 mesh_infer_msg d;
23 char *err = NULL;
24 CHECK_I(mesh_infer_msg_decode(e.data, e.len, &d, &err), 0);
25 CHECK_S(mesh_infer_msg_get(&d, "mode"), "exact");
26 CHECK_S(mesh_infer_msg_get(&d, "x"), "a b");
27 CHECK_S(d.body, "line one\n\nline three");
28 uint64_t v;
29 CHECK_I(mesh_infer_msg_num(&d, "max", &v, &err), 0);
30 CHECK_U(v, 7);
31 CHECK_I(mesh_infer_msg_num(&d, "mode", &v, &err), -1);
32 CHECK_S(err, "mode: not a number");
33 free(err);
34 CHECK_I(mesh_infer_msg_num(&d, "nope", &v, &err), -1);
35 CHECK_S(err, "missing nope");
36 free(err);
37 mesh_infer_msg_free(&d);
38 /* No body: a message that ends in its blank line. */
39 mesh_infer_msg_set_body(&m, "");
40 mesh_buf_clear(&e);
41 mesh_infer_msg_encode(&m, &e);
42 CHECK_I(mesh_infer_msg_decode(e.data, e.len, &d, &err), 0);
43 CHECK_S(d.body, "");
44 mesh_infer_msg_free(&d);
45 CHECK_I(mesh_infer_msg_decode("a=1\nbad\n\nx", 10, &d, &err), -1);
46 CHECK_S(err, "a header line without '=': \"bad\"");
47 free(err);
48 CHECK_I(mesh_infer_msg_decode("\xff", 1, &d, &err), -1);
49 CHECK_S(err, "a message that is not UTF-8");
50 free(err);
51
52 unsigned char bytes[1001];
53 for (unsigned i = 0; i < 1001; i++) bytes[i] = (unsigned char)(i * 7);
54 mesh_buf f = MESH_BUF_INIT;
55 mesh_infer_layer_frame(&f, 5, 3, bytes, sizeof bytes);
56 uint32_t l, rows;
57 const uint8_t *p;
58 size_t n;
59 CHECK_I(mesh_infer_parse_layer(f.data, f.len, &l, &rows, &p, &n, &err), 0);
60 CHECK(l == 5 && rows == 3 && n == 1001 && memcmp(p, bytes, n) == 0);
61 f.data[100] ^= 1;
62 CHECK_I(mesh_infer_parse_layer(f.data, f.len, &l, &rows, &p, &n, &err), -1);
63 CHECK_S(err, "KV layer 5: checksum mismatch (1001 bytes)");
64 free(err);
65 f.data[100] ^= 1;
66
67 int sv[2];
68 CHECK_I(socketpair(AF_UNIX, SOCK_STREAM, 0, sv), 0);
69 CHECK_I(mesh_infer_write_frame(sv[0], MESH_INFER_K_LAYER, f.data, f.len), 0);
70 CHECK_I(mesh_infer_write_frame(sv[0], MESH_INFER_K_FIRST, "token=3\n", 8), 0);
71 close(sv[0]);
72 uint8_t kind;
73 mesh_buf body = MESH_BUF_INIT;
74 CHECK_I(mesh_infer_read_frame(sv[1], &kind, &body, NULL, &err), 0);
75 CHECK(kind == MESH_INFER_K_LAYER && body.len == f.len && memcmp(body.data, f.data, f.len) == 0);
76 mesh_buf_clear(&body);
77 CHECK_I(mesh_infer_read_frame(sv[1], &kind, &body, NULL, &err), 0);
78 CHECK(kind == MESH_INFER_K_FIRST);
79 CHECK_S(mesh_buf_str(&body), "token=3\n");
80 CHECK_I(mesh_infer_read_frame(sv[1], &kind, &body, NULL, &err), -1);
81 CHECK_S(err, "read: failed to fill whole buffer");
82 free(err);
83 close(sv[1]);
84 mesh_infer_msg_free(&m);
85 mesh_buf_free(&e);
86 mesh_buf_free(&f);
87 mesh_buf_free(&body);
88 return mesh_check_done();
89}