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