1 /**
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  * SPDX-License-Identifier: Apache-2.0.
4  */
5 
6 #include <aws/event-stream/event_stream_channel_handler.h>
7 #include <aws/testing/aws_test_harness.h>
8 #include <aws/testing/io_testing_channel.h>
9 
10 struct test_data {
11     struct aws_allocator *allocator;
12     struct testing_channel testing_channel;
13     struct aws_channel_handler *handler;
14     aws_event_stream_channel_handler_on_message_received_fn *received_fn;
15     void *user_data;
16 };
17 
18 static struct test_data s_test_data;
19 
s_fixture_on_message(struct aws_event_stream_message * message,int error_code,void * user_data)20 static void s_fixture_on_message(struct aws_event_stream_message *message, int error_code, void *user_data) {
21     struct test_data *test_data = user_data;
22     test_data->received_fn(message, error_code, test_data->user_data);
23 }
24 
s_fixture_setup(struct aws_allocator * allocator,void * ctx)25 static int s_fixture_setup(struct aws_allocator *allocator, void *ctx) {
26     aws_event_stream_library_init(allocator);
27     struct test_data *test_data = ctx;
28     AWS_ZERO_STRUCT(*test_data);
29 
30     test_data->allocator = allocator;
31 
32     struct aws_testing_channel_options testing_channel_options = {
33         .clock_fn = aws_high_res_clock_get_ticks,
34     };
35     ASSERT_SUCCESS(testing_channel_init(&test_data->testing_channel, allocator, &testing_channel_options));
36 
37     struct aws_channel_slot *slot = aws_channel_slot_new(test_data->testing_channel.channel);
38     ASSERT_NOT_NULL(slot);
39     ASSERT_SUCCESS(aws_channel_slot_insert_end(test_data->testing_channel.channel, slot));
40 
41     struct aws_event_stream_channel_handler_options options = {
42         .initial_window_size = SIZE_MAX,
43         .user_data = ctx,
44         .on_message_received = s_fixture_on_message,
45     };
46     test_data->handler = aws_event_stream_channel_handler_new(allocator, &options);
47     ASSERT_NOT_NULL(test_data->handler);
48     ASSERT_SUCCESS(aws_channel_slot_set_handler(slot, test_data->handler));
49     testing_channel_run_currently_queued_tasks(&test_data->testing_channel);
50 
51     return AWS_OP_SUCCESS;
52 }
53 
s_fixture_shutdown(struct aws_allocator * allocator,int setup_result,void * ctx)54 static int s_fixture_shutdown(struct aws_allocator *allocator, int setup_result, void *ctx) {
55     (void)allocator;
56     struct test_data *test_data = ctx;
57 
58     if (!setup_result) {
59         testing_channel_clean_up(&test_data->testing_channel);
60     }
61 
62     aws_event_stream_library_clean_up();
63 
64     return AWS_OP_SUCCESS;
65 }
66 
67 struct single_message_test_data {
68     int last_error_code;
69     struct aws_event_stream_message received_msg_cpy;
70 };
71 
s_test_on_single_message(struct aws_event_stream_message * message,int error_code,void * user_data)72 static void s_test_on_single_message(struct aws_event_stream_message *message, int error_code, void *user_data) {
73 
74     struct single_message_test_data *msg_test_data = user_data;
75     msg_test_data->last_error_code = error_code;
76 
77     if (!error_code) {
78         struct aws_byte_buf message_buf = aws_byte_buf_from_array(
79             aws_event_stream_message_buffer(message), aws_event_stream_message_total_length(message));
80         aws_event_stream_message_from_buffer_copy(
81             &msg_test_data->received_msg_cpy, s_test_data.allocator, &message_buf);
82     }
83 }
84 
85 /* send various valid messages in serial to make sure the happy path of message parsing is correct. */
s_test_channel_handler_single_valid_messages_parse(struct aws_allocator * allocator,void * ctx)86 static int s_test_channel_handler_single_valid_messages_parse(struct aws_allocator *allocator, void *ctx) {
87     struct test_data *test_data = ctx;
88 
89     struct single_message_test_data message_test_data;
90     AWS_ZERO_STRUCT(message_test_data);
91 
92     test_data->received_fn = s_test_on_single_message;
93     test_data->user_data = &message_test_data;
94 
95     uint8_t empty_message[] = {
96         0x00,
97         0x00,
98         0x00,
99         0x10,
100         0x00,
101         0x00,
102         0x00,
103         0x00,
104         0x05,
105         0xc2,
106         0x48,
107         0xeb,
108         0x7d,
109         0x98,
110         0xc8,
111         0xff,
112     };
113 
114     struct aws_byte_cursor empty_message_cursor = aws_byte_cursor_from_array(empty_message, sizeof(empty_message));
115     ASSERT_SUCCESS(testing_channel_push_read_data(&s_test_data.testing_channel, empty_message_cursor));
116     ASSERT_UINT_EQUALS(AWS_OP_SUCCESS, message_test_data.last_error_code);
117     ASSERT_UINT_EQUALS(0x00000010, aws_event_stream_message_total_length(&message_test_data.received_msg_cpy));
118     ASSERT_UINT_EQUALS(0x00000000, aws_event_stream_message_headers_len(&message_test_data.received_msg_cpy));
119     ASSERT_UINT_EQUALS(0x05c248eb, aws_event_stream_message_prelude_crc(&message_test_data.received_msg_cpy));
120     ASSERT_UINT_EQUALS(0x7d98c8ff, aws_event_stream_message_message_crc(&message_test_data.received_msg_cpy));
121     aws_event_stream_message_clean_up(&message_test_data.received_msg_cpy);
122     AWS_ZERO_STRUCT(message_test_data);
123 
124     uint8_t no_headers_data[] = {
125         0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x52, 0x8c, 0x5a, 0x7b, 0x27, 0x66,
126         0x6f, 0x6f, 0x27, 0x3a, 0x27, 0x62, 0x61, 0x72, 0x27, 0x7d, 0xc3, 0x65, 0x39, 0x36,
127     };
128 
129     struct aws_byte_cursor no_headers_cur = aws_byte_cursor_from_array(no_headers_data, sizeof(no_headers_data));
130     ASSERT_SUCCESS(testing_channel_push_read_data(&s_test_data.testing_channel, no_headers_cur));
131     ASSERT_UINT_EQUALS(AWS_OP_SUCCESS, message_test_data.last_error_code);
132     ASSERT_UINT_EQUALS(0x0000001D, aws_event_stream_message_total_length(&message_test_data.received_msg_cpy));
133     ASSERT_UINT_EQUALS(0x00000000, aws_event_stream_message_headers_len(&message_test_data.received_msg_cpy));
134     ASSERT_UINT_EQUALS(0xfd528c5a, aws_event_stream_message_prelude_crc(&message_test_data.received_msg_cpy));
135 
136     const char *expected_str = "{'foo':'bar'}";
137     ASSERT_UINT_EQUALS(strlen(expected_str), aws_event_stream_message_payload_len(&message_test_data.received_msg_cpy));
138 
139     ASSERT_BIN_ARRAYS_EQUALS(
140         expected_str,
141         strlen(expected_str),
142         aws_event_stream_message_payload(&message_test_data.received_msg_cpy),
143         aws_event_stream_message_payload_len(&message_test_data.received_msg_cpy));
144     ASSERT_UINT_EQUALS(0xc3653936, aws_event_stream_message_message_crc(&message_test_data.received_msg_cpy));
145 
146     aws_event_stream_message_clean_up(&message_test_data.received_msg_cpy);
147     AWS_ZERO_STRUCT(message_test_data);
148 
149     uint8_t headers_test_data[] = {
150         0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x20, 0x07, 0xFD, 0x83, 0x96, 0x0C, 'c',  'o',  'n',
151         't',  'e',  'n',  't',  '-',  't',  'y',  'p',  'e',  0x07, 0x00, 0x10, 'a',  'p',  'p',  'l',
152         'i',  'c',  'a',  't',  'i',  'o',  'n',  '/',  'j',  's',  'o',  'n',  0x7b, 0x27, 0x66, 0x6f,
153         0x6f, 0x27, 0x3a, 0x27, 0x62, 0x61, 0x72, 0x27, 0x7d, 0x8D, 0x9C, 0x08, 0xB1,
154     };
155 
156     struct aws_byte_cursor headers_test_cur = aws_byte_cursor_from_array(headers_test_data, sizeof(headers_test_data));
157 
158     ASSERT_SUCCESS(testing_channel_push_read_data(&s_test_data.testing_channel, headers_test_cur));
159     ASSERT_UINT_EQUALS(AWS_OP_SUCCESS, message_test_data.last_error_code);
160 
161     ASSERT_UINT_EQUALS(0x0000003D, aws_event_stream_message_total_length(&message_test_data.received_msg_cpy));
162     ASSERT_UINT_EQUALS(0x00000020, aws_event_stream_message_headers_len(&message_test_data.received_msg_cpy));
163     ASSERT_UINT_EQUALS(0x07FD8396, aws_event_stream_message_prelude_crc(&message_test_data.received_msg_cpy));
164 
165     ASSERT_UINT_EQUALS(strlen(expected_str), aws_event_stream_message_payload_len(&message_test_data.received_msg_cpy));
166 
167     ASSERT_BIN_ARRAYS_EQUALS(
168         expected_str,
169         strlen(expected_str),
170         aws_event_stream_message_payload(&message_test_data.received_msg_cpy),
171         aws_event_stream_message_payload_len(&message_test_data.received_msg_cpy));
172 
173     struct aws_array_list headers;
174     ASSERT_SUCCESS(aws_event_stream_headers_list_init(&headers, allocator));
175 
176     ASSERT_SUCCESS(aws_event_stream_message_headers(&message_test_data.received_msg_cpy, &headers));
177     ASSERT_UINT_EQUALS(1, headers.length, );
178     struct aws_event_stream_header_value_pair header;
179     ASSERT_SUCCESS(aws_array_list_front(&headers, &header));
180 
181     const char *content_type = "content-type";
182     const char *content_type_value = "application/json";
183 
184     struct aws_byte_buf header_name_buf = aws_event_stream_header_name(&header);
185     ASSERT_BIN_ARRAYS_EQUALS(content_type, strlen(content_type), header_name_buf.buffer, header_name_buf.len);
186 
187     struct aws_byte_buf header_value_buf = aws_event_stream_header_value_as_string(&header);
188 
189     ASSERT_BIN_ARRAYS_EQUALS(
190         content_type_value, strlen(content_type_value), header_value_buf.buffer, header_value_buf.len);
191 
192     ASSERT_UINT_EQUALS(0x8D9C08B1, aws_event_stream_message_message_crc(&message_test_data.received_msg_cpy));
193 
194     aws_event_stream_headers_list_cleanup(&headers);
195     aws_event_stream_message_clean_up(&message_test_data.received_msg_cpy);
196 
197     return AWS_OP_SUCCESS;
198 }
199 
200 AWS_TEST_CASE_FIXTURE(
201     test_channel_handler_single_valid_messages_parse,
202     s_fixture_setup,
203     s_test_channel_handler_single_valid_messages_parse,
204     s_fixture_shutdown,
205     &s_test_data)
206 
207 struct multiple_message_test_data {
208     int last_error_code;
209     struct aws_event_stream_message *received_msgs_cpy;
210     size_t msg_count;
211 };
212 
s_test_on_multiple_message(struct aws_event_stream_message * message,int error_code,void * user_data)213 static void s_test_on_multiple_message(struct aws_event_stream_message *message, int error_code, void *user_data) {
214 
215     struct multiple_message_test_data *msg_test_data = user_data;
216     msg_test_data->last_error_code = error_code;
217 
218     if (!error_code) {
219         struct aws_byte_buf message_buf = aws_byte_buf_from_array(
220             aws_event_stream_message_buffer(message), aws_event_stream_message_total_length(message));
221         struct aws_event_stream_message msg_cpy;
222         AWS_ZERO_STRUCT(msg_cpy);
223         aws_event_stream_message_from_buffer_copy(&msg_cpy, s_test_data.allocator, &message_buf);
224         msg_test_data->received_msgs_cpy[msg_test_data->msg_count++] = msg_cpy;
225     }
226 }
227 
228 /* send various valid messages as a batch to make sure the happy path of message parsing is correct. */
s_test_channel_handler_multiple_valid_messages_parse(struct aws_allocator * allocator,void * ctx)229 static int s_test_channel_handler_multiple_valid_messages_parse(struct aws_allocator *allocator, void *ctx) {
230     struct test_data *test_data = ctx;
231 
232     uint8_t multi_message[] = {
233         0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x05, 0xc2, 0x48, 0xeb, 0x7d, 0x98, 0xc8, 0xff,
234 
235         0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0xfd, 0x52, 0x8c, 0x5a, 0x7b, 0x27, 0x66, 0x6f,
236         0x6f, 0x27, 0x3a, 0x27, 0x62, 0x61, 0x72, 0x27, 0x7d, 0xc3, 0x65, 0x39, 0x36,
237 
238         0x00, 0x00, 0x00, 0x3D, 0x00, 0x00, 0x00, 0x20, 0x07, 0xFD, 0x83, 0x96, 0x0C, 'c',  'o',  'n',
239         't',  'e',  'n',  't',  '-',  't',  'y',  'p',  'e',  0x07, 0x00, 0x10, 'a',  'p',  'p',  'l',
240         'i',  'c',  'a',  't',  'i',  'o',  'n',  '/',  'j',  's',  'o',  'n',  0x7b, 0x27, 0x66, 0x6f,
241         0x6f, 0x27, 0x3a, 0x27, 0x62, 0x61, 0x72, 0x27, 0x7d, 0x8D, 0x9C, 0x08, 0xB1,
242     };
243 
244     /* fuzz the parser's boundary conditions */
245     for (size_t fragment_size = 1; fragment_size <= sizeof(multi_message); ++fragment_size) {
246 
247         struct multiple_message_test_data message_test_data;
248         AWS_ZERO_STRUCT(message_test_data);
249 
250         struct aws_event_stream_message messages[100];
251         AWS_ZERO_ARRAY(messages);
252         message_test_data.received_msgs_cpy = messages;
253 
254         test_data->received_fn = s_test_on_multiple_message;
255         test_data->user_data = &message_test_data;
256 
257         size_t processed = 0;
258         while (processed < sizeof(multi_message)) {
259             size_t remaining = sizeof(multi_message) - processed;
260             size_t to_copy = fragment_size < remaining ? fragment_size : remaining;
261             struct aws_byte_cursor multi_message_cursor =
262                 aws_byte_cursor_from_array(multi_message + processed, to_copy);
263             processed += to_copy;
264             ASSERT_SUCCESS(testing_channel_push_read_data(&s_test_data.testing_channel, multi_message_cursor));
265         }
266 
267         ASSERT_UINT_EQUALS(AWS_OP_SUCCESS, message_test_data.last_error_code);
268         ASSERT_UINT_EQUALS(3, message_test_data.msg_count);
269 
270         ASSERT_UINT_EQUALS(0x00000010, aws_event_stream_message_total_length(&message_test_data.received_msgs_cpy[0]));
271         ASSERT_UINT_EQUALS(0x00000000, aws_event_stream_message_headers_len(&message_test_data.received_msgs_cpy[0]));
272         ASSERT_UINT_EQUALS(0x05c248eb, aws_event_stream_message_prelude_crc(&message_test_data.received_msgs_cpy[0]));
273         ASSERT_UINT_EQUALS(0x7d98c8ff, aws_event_stream_message_message_crc(&message_test_data.received_msgs_cpy[0]));
274         aws_event_stream_message_clean_up(&message_test_data.received_msgs_cpy[0]);
275 
276         ASSERT_UINT_EQUALS(0x0000001D, aws_event_stream_message_total_length(&message_test_data.received_msgs_cpy[1]));
277         ASSERT_UINT_EQUALS(0x00000000, aws_event_stream_message_headers_len(&message_test_data.received_msgs_cpy[1]));
278         ASSERT_UINT_EQUALS(0xfd528c5a, aws_event_stream_message_prelude_crc(&message_test_data.received_msgs_cpy[1]));
279 
280         const char *expected_str = "{'foo':'bar'}";
281         ASSERT_UINT_EQUALS(
282             strlen(expected_str), aws_event_stream_message_payload_len(&message_test_data.received_msgs_cpy[1]));
283 
284         ASSERT_BIN_ARRAYS_EQUALS(
285             expected_str,
286             strlen(expected_str),
287             aws_event_stream_message_payload(&message_test_data.received_msgs_cpy[1]),
288             aws_event_stream_message_payload_len(&message_test_data.received_msgs_cpy[1]));
289         ASSERT_UINT_EQUALS(0xc3653936, aws_event_stream_message_message_crc(&message_test_data.received_msgs_cpy[1]));
290 
291         aws_event_stream_message_clean_up(&message_test_data.received_msgs_cpy[1]);
292 
293         ASSERT_UINT_EQUALS(0x0000003D, aws_event_stream_message_total_length(&message_test_data.received_msgs_cpy[2]));
294         ASSERT_UINT_EQUALS(0x00000020, aws_event_stream_message_headers_len(&message_test_data.received_msgs_cpy[2]));
295         ASSERT_UINT_EQUALS(0x07FD8396, aws_event_stream_message_prelude_crc(&message_test_data.received_msgs_cpy[2]));
296 
297         ASSERT_UINT_EQUALS(
298             strlen(expected_str), aws_event_stream_message_payload_len(&message_test_data.received_msgs_cpy[2]));
299 
300         ASSERT_BIN_ARRAYS_EQUALS(
301             expected_str,
302             strlen(expected_str),
303             aws_event_stream_message_payload(&message_test_data.received_msgs_cpy[2]),
304             aws_event_stream_message_payload_len(&message_test_data.received_msgs_cpy[2]));
305 
306         struct aws_array_list headers;
307         ASSERT_SUCCESS(aws_event_stream_headers_list_init(&headers, allocator));
308 
309         ASSERT_SUCCESS(aws_event_stream_message_headers(&message_test_data.received_msgs_cpy[2], &headers));
310         ASSERT_UINT_EQUALS(1, headers.length, );
311         struct aws_event_stream_header_value_pair header;
312         ASSERT_SUCCESS(aws_array_list_front(&headers, &header));
313 
314         const char *content_type = "content-type";
315         const char *content_type_value = "application/json";
316 
317         struct aws_byte_buf header_name_buf = aws_event_stream_header_name(&header);
318         ASSERT_BIN_ARRAYS_EQUALS(content_type, strlen(content_type), header_name_buf.buffer, header_name_buf.len);
319 
320         struct aws_byte_buf header_value_buf = aws_event_stream_header_value_as_string(&header);
321 
322         ASSERT_BIN_ARRAYS_EQUALS(
323             content_type_value, strlen(content_type_value), header_value_buf.buffer, header_value_buf.len);
324 
325         ASSERT_UINT_EQUALS(0x8D9C08B1, aws_event_stream_message_message_crc(&message_test_data.received_msgs_cpy[2]));
326 
327         aws_event_stream_headers_list_cleanup(&headers);
328         aws_event_stream_message_clean_up(&message_test_data.received_msgs_cpy[2]);
329     }
330 
331     return AWS_OP_SUCCESS;
332 }
333 
334 AWS_TEST_CASE_FIXTURE(
335     test_channel_handler_multiple_valid_messages_parse,
336     s_fixture_setup,
337     s_test_channel_handler_multiple_valid_messages_parse,
338     s_fixture_shutdown,
339     &s_test_data)
340 
341 /* send various valid messages in serial to make sure the happy path of message parsing is correct. */
s_test_channel_handler_corrupted_crc_fails(struct aws_allocator * allocator,void * ctx)342 static int s_test_channel_handler_corrupted_crc_fails(struct aws_allocator *allocator, void *ctx) {
343     (void)allocator;
344     struct test_data *test_data = ctx;
345 
346     struct single_message_test_data message_test_data;
347     AWS_ZERO_STRUCT(message_test_data);
348 
349     test_data->received_fn = s_test_on_single_message;
350     test_data->user_data = &message_test_data;
351 
352     /* altered the 9th byte to a single bit flip */
353     uint8_t empty_message[] = {
354         0x00,
355         0x00,
356         0x00,
357         0x10,
358         0x00,
359         0x00,
360         0x00,
361         0x00,
362         0x05,
363         0xc3,
364         0x48,
365         0xeb,
366         0x7d,
367         0x98,
368         0xc8,
369         0xff,
370     };
371 
372     struct aws_byte_cursor empty_message_cursor = aws_byte_cursor_from_array(empty_message, sizeof(empty_message));
373     ASSERT_SUCCESS(testing_channel_push_read_data(&s_test_data.testing_channel, empty_message_cursor));
374     ASSERT_UINT_EQUALS(AWS_ERROR_EVENT_STREAM_PRELUDE_CHECKSUM_FAILURE, message_test_data.last_error_code);
375 
376     return AWS_OP_SUCCESS;
377 }
378 
379 AWS_TEST_CASE_FIXTURE(
380     test_channel_handler_corrupted_crc_fails,
381     s_fixture_setup,
382     s_test_channel_handler_corrupted_crc_fails,
383     s_fixture_shutdown,
384     &s_test_data)
385 
386 /* send various valid messages in serial to make sure the happy path of message parsing is correct. */
s_test_channel_handler_msg_too_large_fails(struct aws_allocator * allocator,void * ctx)387 static int s_test_channel_handler_msg_too_large_fails(struct aws_allocator *allocator, void *ctx) {
388     (void)allocator;
389 
390     struct test_data *test_data = ctx;
391 
392     struct single_message_test_data message_test_data;
393     AWS_ZERO_STRUCT(message_test_data);
394 
395     test_data->received_fn = s_test_on_single_message;
396     test_data->user_data = &message_test_data;
397 
398     /* message is 1 byte too large */
399     uint8_t empty_message[] = {
400         0x01,
401         0x00,
402         0x00,
403         0x01,
404         0x00,
405         0x00,
406         0x00,
407         0x00,
408         0x94,
409         0xE8,
410         0xF6,
411         0x47,
412         0xC8,
413         0x86,
414         0xFB,
415         0xA0,
416     };
417 
418     struct aws_byte_cursor empty_message_cursor = aws_byte_cursor_from_array(empty_message, sizeof(empty_message));
419     ASSERT_SUCCESS(testing_channel_push_read_data(&s_test_data.testing_channel, empty_message_cursor));
420     ASSERT_UINT_EQUALS(AWS_ERROR_EVENT_STREAM_MESSAGE_FIELD_SIZE_EXCEEDED, message_test_data.last_error_code);
421 
422     return AWS_OP_SUCCESS;
423 }
424 
425 AWS_TEST_CASE_FIXTURE(
426     test_channel_handler_msg_too_large_fails,
427     s_fixture_setup,
428     s_test_channel_handler_msg_too_large_fails,
429     s_fixture_shutdown,
430     &s_test_data)
431 
s_on_message_written(struct aws_event_stream_message * message,int error_code,void * user_data)432 static void s_on_message_written(struct aws_event_stream_message *message, int error_code, void *user_data) {
433     struct single_message_test_data *msg_test_data = user_data;
434     msg_test_data->last_error_code = error_code;
435 
436     if (!error_code) {
437         struct aws_byte_buf message_buf = aws_byte_buf_from_array(
438             aws_event_stream_message_buffer(message), aws_event_stream_message_total_length(message));
439         aws_event_stream_message_from_buffer_copy(
440             &msg_test_data->received_msg_cpy, s_test_data.allocator, &message_buf);
441     }
442 }
443 
s_test_channel_handler_write_message(struct aws_allocator * allocator,void * ctx)444 static int s_test_channel_handler_write_message(struct aws_allocator *allocator, void *ctx) {
445     struct test_data *test_data = ctx;
446 
447     struct single_message_test_data message_test_data;
448     AWS_ZERO_STRUCT(message_test_data);
449 
450     uint8_t empty_message[] = {
451         0x00,
452         0x00,
453         0x00,
454         0x10,
455         0x00,
456         0x00,
457         0x00,
458         0x00,
459         0x05,
460         0xc2,
461         0x48,
462         0xeb,
463         0x7d,
464         0x98,
465         0xc8,
466         0xff,
467     };
468 
469     struct aws_byte_buf empty_message_buf = aws_byte_buf_from_array(empty_message, sizeof(empty_message));
470     struct aws_event_stream_message msg_to_send;
471     AWS_ZERO_STRUCT(msg_to_send);
472     ASSERT_SUCCESS(aws_event_stream_message_from_buffer(&msg_to_send, allocator, &empty_message_buf));
473     ASSERT_SUCCESS(aws_event_stream_channel_handler_write_message(
474         test_data->handler, &msg_to_send, s_on_message_written, &message_test_data));
475     testing_channel_drain_queued_tasks(&s_test_data.testing_channel);
476     ASSERT_UINT_EQUALS(0x00000010, aws_event_stream_message_total_length(&message_test_data.received_msg_cpy));
477     ASSERT_UINT_EQUALS(0x00000000, aws_event_stream_message_headers_len(&message_test_data.received_msg_cpy));
478     ASSERT_UINT_EQUALS(0x05c248eb, aws_event_stream_message_prelude_crc(&message_test_data.received_msg_cpy));
479     ASSERT_UINT_EQUALS(0x7d98c8ff, aws_event_stream_message_message_crc(&message_test_data.received_msg_cpy));
480     aws_event_stream_message_clean_up(&message_test_data.received_msg_cpy);
481     aws_event_stream_message_clean_up(&msg_to_send);
482 
483     struct aws_linked_list *list = testing_channel_get_written_message_queue(&test_data->testing_channel);
484     ASSERT_FALSE(aws_linked_list_empty(list));
485     struct aws_linked_list_node *node = aws_linked_list_front(list);
486     ASSERT_NOT_NULL(node);
487     struct aws_io_message *message = AWS_CONTAINER_OF(node, struct aws_io_message, queueing_handle);
488     struct aws_event_stream_message sent_msg;
489     AWS_ZERO_STRUCT(sent_msg);
490 
491     ASSERT_SUCCESS(aws_event_stream_message_from_buffer(&sent_msg, allocator, &message->message_data));
492     ASSERT_UINT_EQUALS(0x00000010, aws_event_stream_message_total_length(&sent_msg));
493     ASSERT_UINT_EQUALS(0x00000000, aws_event_stream_message_headers_len(&sent_msg));
494     ASSERT_UINT_EQUALS(0x05c248eb, aws_event_stream_message_prelude_crc(&sent_msg));
495     ASSERT_UINT_EQUALS(0x7d98c8ff, aws_event_stream_message_message_crc(&sent_msg));
496     aws_event_stream_message_clean_up(&sent_msg);
497     return AWS_OP_SUCCESS;
498 }
499 
500 AWS_TEST_CASE_FIXTURE(
501     test_channel_handler_write_message,
502     s_fixture_setup,
503     s_test_channel_handler_write_message,
504     s_fixture_shutdown,
505     &s_test_data)
506