skip to content
==> 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}