test_hcsi_reader.c revision 9a690580
1/* Copyright (c) 2017 - 2020 LiteSpeed Technologies Inc.  See LICENSE. */
2#include <assert.h>
3#include <inttypes.h>
4#include <stdlib.h>
5#include <string.h>
6#include <stdio.h>
7#include <sys/queue.h>
8
9#include "lsquic.h"
10#include "lsquic_int_types.h"
11#include "lsquic_varint.h"
12#include "lsquic_hq.h"
13#include "lsquic_hcsi_reader.h"
14#include "lsquic_hash.h"
15#include "lsquic_conn.h"
16
17struct test
18{
19    int             lineno;
20
21    unsigned char   input[0x100];
22    size_t          input_sz;
23
24    int             retval;
25    char            output[0x1000];
26};
27
28
29static const struct test tests[] =
30{
31    {
32        __LINE__,
33        {
34            0x03,
35            0x04,
36            0x80, 0x12, 0x34, 0x45,
37        },
38        6,
39        0,
40        "on_cancel_push: 1193029\n",
41    },
42
43    {
44        __LINE__,
45        {
46            HQFT_MAX_PUSH_ID,
47            0x02,
48            0x41, 0x23,
49        },
50        4,
51        0,
52        "on_max_push_id: 291\n",
53    },
54
55    {
56        __LINE__,
57        {
58            HQFT_SETTINGS,
59            0x00,
60        },
61        2,
62        0,
63        "have SETTINGS frame\n",
64    },
65
66    {   /* Frame contents do not match frame length */
67        __LINE__,
68        {
69            HQFT_MAX_PUSH_ID,
70            0x03,
71            0x41, 0x23,
72        },
73        4,
74        -1,
75        "",
76    },
77
78    {
79        __LINE__,
80        {
81            HQFT_SETTINGS,
82            13,
83            0x52, 0x34,
84            0xC0, 0x12, 0x23, 0x34, 0x45, 0x56, 0x67, 0x78,
85            0x52, 0x35,
86            0x00,
87        },
88        15,
89        0,
90        "on_setting: 0x1234=0x12233445566778\n"
91        "on_setting: 0x1235=0x0\n"
92        "have SETTINGS frame\n"
93        ,
94    },
95
96};
97
98
99static void
100on_cancel_push (void *ctx, uint64_t push_id)
101{
102    fprintf(ctx, "%s: %"PRIu64"\n", __func__, push_id);
103}
104
105static void
106on_max_push_id (void *ctx, uint64_t push_id)
107{
108    fprintf(ctx, "%s: %"PRIu64"\n", __func__, push_id);
109}
110
111static void
112on_settings_frame (void *ctx)
113{
114    fprintf(ctx, "have SETTINGS frame\n");
115}
116
117static void
118on_setting (void *ctx, uint64_t setting_id, uint64_t value)
119{
120    fprintf(ctx, "%s: 0x%"PRIX64"=0x%"PRIX64"\n", __func__, setting_id, value);
121}
122
123static void
124on_goaway (void *ctx, uint64_t stream_id)
125{
126    fprintf(ctx, "%s: %"PRIu64"\n", __func__, stream_id);
127}
128
129static void
130on_unexpected_frame (void *ctx, uint64_t frame_type)
131{
132    fprintf(ctx, "%s: %"PRIu64"\n", __func__, frame_type);
133}
134
135static const struct hcsi_callbacks callbacks =
136{
137    .on_cancel_push         = on_cancel_push,
138    .on_max_push_id         = on_max_push_id,
139    .on_settings_frame      = on_settings_frame,
140    .on_setting             = on_setting,
141    .on_goaway              = on_goaway,
142    .on_unexpected_frame    = on_unexpected_frame,
143};
144
145
146static void
147abort_error (struct lsquic_conn *conn, int is_app, unsigned error_code,
148                                                    const char *format, ...)
149{
150}
151
152
153static const struct conn_iface conn_iface = {
154    .ci_abort_error     = abort_error,
155};
156
157
158static void
159run_test (const struct test *test)
160{
161    struct hcsi_reader reader;
162    size_t read_sz, out_sz, toread;
163    FILE *out_f;
164    char *output;
165    const unsigned char *p;
166    int s;
167    struct lsquic_conn lconn = LSCONN_INITIALIZER_CIDLEN(lconn, 0);
168    lconn.cn_if = &conn_iface;
169
170    for (read_sz = 1; read_sz < test->input_sz; ++read_sz)
171    {
172        out_f = open_memstream(&output, &out_sz);
173        lsquic_hcsi_reader_init(&reader, &lconn, &callbacks, out_f);
174
175        p = test->input;
176        do
177        {
178            toread = test->input + test->input_sz - p;
179            if (toread > read_sz)
180                toread = read_sz;
181            s = lsquic_hcsi_reader_feed(&reader, p, toread);
182            if (s != 0)
183                break;
184            p += toread;
185        }
186        while (p < test->input + test->input_sz);
187
188        assert(s == test->retval);
189
190        fclose(out_f);
191        assert(0 == strcmp(test->output, output));
192        free(output);
193    }
194}
195
196int
197main (void)
198{
199    const struct test *test;
200    struct test coalesced_test;
201
202    for (test = tests; test < tests + sizeof(tests) / sizeof(tests[0]); ++test)
203        run_test(test);
204
205    memset(&coalesced_test, 0, sizeof(coalesced_test));
206    for (test = tests; test < tests + sizeof(tests) / sizeof(tests[0]); ++test)
207        if (test->retval == 0)
208        {
209            memcpy(coalesced_test.input + coalesced_test.input_sz,
210                    test->input, test->input_sz);
211            coalesced_test.input_sz += test->input_sz;
212            strcat(coalesced_test.output, test->output);
213        }
214    run_test(&coalesced_test);
215
216    return 0;
217}
218