Skip to content

Commit ead0539

Browse files
committed
add different tests
1 parent d01c000 commit ead0539

3 files changed

Lines changed: 169 additions & 47 deletions

File tree

tests/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,9 +165,11 @@ add_test_case(h1_client_write_data_exceeds_content_length)
165165
add_test_case(h1_client_write_data_less_than_content_length)
166166
add_test_case(h1_client_write_data_chunked_single)
167167
add_test_case(h1_client_write_data_chunked_multiple)
168-
add_test_case(h1_client_write_data_chunked_end_stream_with_data)
169168
add_test_case(h1_client_write_data_null_data_content_length)
170169
add_test_case(h1_client_write_data_null_data_chunked)
170+
add_test_case(h1_client_write_data_null_data_no_end_stream)
171+
add_test_case(h1_client_write_data_auto_chunked)
172+
add_test_case(h1_client_write_data_body_stream_conflict)
171173

172174
add_test_case(strutil_trim_http_whitespace)
173175
add_test_case(strutil_is_http_token)
@@ -526,6 +528,7 @@ add_test_case(h2_client_batch_auto_window_update)
526528
add_test_case(h2_client_batch_manual_window_update)
527529
add_test_case(h2_client_cap_manual_window_update)
528530
add_test_case(h2_client_unified_write_data_api)
531+
add_test_case(h2_client_unified_write_data_api_new_field)
529532

530533
add_test_case(server_new_destroy)
531534
add_test_case(server_new_destroy_tcp)

tests/test_h1_client.c

Lines changed: 111 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5403,7 +5403,8 @@ H1_CLIENT_TEST_CASE(h1_client_write_data_less_than_content_length) {
54035403
return AWS_OP_SUCCESS;
54045404
}
54055405

5406-
/* Test write_data with chunked encoding - single write */
5406+
/* Test write_data with chunked encoding - single write with end_stream=true
5407+
* should automatically send the termination chunk (0\r\n\r\n) */
54075408
H1_CLIENT_TEST_CASE(h1_client_write_data_chunked_single) {
54085409
(void)ctx;
54095410
struct write_data_test_fixture fixture;
@@ -5413,13 +5414,15 @@ H1_CLIENT_TEST_CASE(h1_client_write_data_chunked_single) {
54135414
};
54145415
ASSERT_SUCCESS(s_write_data_test_setup(&fixture, allocator, headers, AWS_ARRAY_SIZE(headers), true));
54155416

5416-
/* Single write with end_stream=true, termination chunk should be sent automatically */
54175417
struct aws_byte_cursor data = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("write more tests");
54185418
struct aws_input_stream *input_stream = aws_input_stream_new_from_cursor(allocator, &data);
54195419

5420+
struct write_data_callback_tester callback_tester = {0};
54205421
struct aws_http_stream_write_data_options write_options = {
54215422
.data = input_stream,
54225423
.end_stream = true,
5424+
.on_complete = s_on_write_data_complete,
5425+
.user_data = &callback_tester,
54235426
};
54245427
ASSERT_SUCCESS(aws_http_stream_write_data(fixture.stream_tester.stream, &write_options));
54255428

@@ -5435,6 +5438,15 @@ H1_CLIENT_TEST_CASE(h1_client_write_data_chunked_single) {
54355438
"\r\n";
54365439
ASSERT_SUCCESS(testing_channel_check_written_messages_str(&fixture.tester.testing_channel, allocator, expected));
54375440

5441+
ASSERT_INT_EQUALS(1, callback_tester.num_callbacks);
5442+
ASSERT_INT_EQUALS(AWS_ERROR_SUCCESS, callback_tester.last_error_code);
5443+
5444+
ASSERT_SUCCESS(testing_channel_push_read_str(&fixture.tester.testing_channel, "HTTP/1.1 200 OK\r\n\r\n"));
5445+
testing_channel_drain_queued_tasks(&fixture.tester.testing_channel);
5446+
5447+
ASSERT_TRUE(fixture.stream_tester.complete);
5448+
ASSERT_INT_EQUALS(200, fixture.stream_tester.response_status);
5449+
54385450
aws_input_stream_release(input_stream);
54395451
ASSERT_SUCCESS(s_write_data_test_teardown(&fixture));
54405452
return AWS_OP_SUCCESS;
@@ -5483,65 +5495,44 @@ H1_CLIENT_TEST_CASE(h1_client_write_data_chunked_multiple) {
54835495
return AWS_OP_SUCCESS;
54845496
}
54855497

5486-
/* Test: write_data with end_stream=true and non-zero data on chunked stream
5487-
* should automatically send the termination chunk (0\r\n\r\n) */
5488-
H1_CLIENT_TEST_CASE(h1_client_write_data_chunked_end_stream_with_data) {
5498+
/* Test: write_data with NULL data and end_stream=true on Content-Length stream */
5499+
H1_CLIENT_TEST_CASE(h1_client_write_data_null_data_content_length) {
54895500
(void)ctx;
54905501
struct write_data_test_fixture fixture;
54915502
struct aws_http_header headers[] = {
5492-
{.name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
5493-
.value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("chunked")},
5503+
{.name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Content-Length"),
5504+
.value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("0")},
54945505
};
54955506
ASSERT_SUCCESS(s_write_data_test_setup(&fixture, allocator, headers, AWS_ARRAY_SIZE(headers), true));
54965507

5497-
/* Single write with end_stream=true and non-zero data */
5498-
struct aws_byte_cursor data = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("hello");
5499-
struct aws_input_stream *input_stream = aws_input_stream_new_from_cursor(allocator, &data);
5500-
5501-
struct write_data_callback_tester callback_tester = {0};
55025508
struct aws_http_stream_write_data_options write_options = {
5503-
.data = input_stream,
5509+
.data = NULL,
55045510
.end_stream = true,
5505-
.on_complete = s_on_write_data_complete,
5506-
.user_data = &callback_tester,
55075511
};
55085512
ASSERT_SUCCESS(aws_http_stream_write_data(fixture.stream_tester.stream, &write_options));
55095513

55105514
testing_channel_drain_queued_tasks(&fixture.tester.testing_channel);
55115515

5512-
/* The stream should send the data chunk AND the termination chunk automatically */
5513-
const char *expected = "POST /upload HTTP/1.1\r\n"
5514-
"Transfer-Encoding: chunked\r\n"
5515-
"\r\n"
5516-
"5\r\n"
5517-
"hello"
5518-
"\r\n"
5519-
"0\r\n"
5520-
"\r\n";
5521-
ASSERT_SUCCESS(testing_channel_check_written_messages_str(&fixture.tester.testing_channel, allocator, expected));
5522-
5523-
ASSERT_INT_EQUALS(1, callback_tester.num_callbacks);
5524-
ASSERT_INT_EQUALS(AWS_ERROR_SUCCESS, callback_tester.last_error_code);
5516+
ASSERT_SUCCESS(testing_channel_check_written_messages_str(
5517+
&fixture.tester.testing_channel, allocator, "POST /upload HTTP/1.1\r\nContent-Length: 0\r\n\r\n"));
55255518

5526-
/* Send response so stream completes */
55275519
ASSERT_SUCCESS(testing_channel_push_read_str(&fixture.tester.testing_channel, "HTTP/1.1 200 OK\r\n\r\n"));
55285520
testing_channel_drain_queued_tasks(&fixture.tester.testing_channel);
55295521

55305522
ASSERT_TRUE(fixture.stream_tester.complete);
55315523
ASSERT_INT_EQUALS(200, fixture.stream_tester.response_status);
55325524

5533-
aws_input_stream_release(input_stream);
55345525
ASSERT_SUCCESS(s_write_data_test_teardown(&fixture));
55355526
return AWS_OP_SUCCESS;
55365527
}
55375528

5538-
/* Test: write_data with NULL data and end_stream=true on Content-Length stream */
5539-
H1_CLIENT_TEST_CASE(h1_client_write_data_null_data_content_length) {
5529+
/* Test: write_data with NULL data and end_stream=true on chunked stream */
5530+
H1_CLIENT_TEST_CASE(h1_client_write_data_null_data_chunked) {
55405531
(void)ctx;
55415532
struct write_data_test_fixture fixture;
55425533
struct aws_http_header headers[] = {
5543-
{.name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Content-Length"),
5544-
.value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("0")},
5534+
{.name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
5535+
.value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("chunked")},
55455536
};
55465537
ASSERT_SUCCESS(s_write_data_test_setup(&fixture, allocator, headers, AWS_ARRAY_SIZE(headers), true));
55475538

@@ -5553,8 +5544,12 @@ H1_CLIENT_TEST_CASE(h1_client_write_data_null_data_content_length) {
55535544

55545545
testing_channel_drain_queued_tasks(&fixture.tester.testing_channel);
55555546

5556-
ASSERT_SUCCESS(testing_channel_check_written_messages_str(
5557-
&fixture.tester.testing_channel, allocator, "POST /upload HTTP/1.1\r\nContent-Length: 0\r\n\r\n"));
5547+
const char *expected = "POST /upload HTTP/1.1\r\n"
5548+
"Transfer-Encoding: chunked\r\n"
5549+
"\r\n"
5550+
"0\r\n"
5551+
"\r\n";
5552+
ASSERT_SUCCESS(testing_channel_check_written_messages_str(&fixture.tester.testing_channel, allocator, expected));
55585553

55595554
ASSERT_SUCCESS(testing_channel_push_read_str(&fixture.tester.testing_channel, "HTTP/1.1 200 OK\r\n\r\n"));
55605555
testing_channel_drain_queued_tasks(&fixture.tester.testing_channel);
@@ -5566,37 +5561,107 @@ H1_CLIENT_TEST_CASE(h1_client_write_data_null_data_content_length) {
55665561
return AWS_OP_SUCCESS;
55675562
}
55685563

5569-
/* Test: write_data with NULL data and end_stream=true on chunked stream */
5570-
H1_CLIENT_TEST_CASE(h1_client_write_data_null_data_chunked) {
5564+
/* Test: write_data with NULL data and end_stream=false is a no-op */
5565+
H1_CLIENT_TEST_CASE(h1_client_write_data_null_data_no_end_stream) {
55715566
(void)ctx;
55725567
struct write_data_test_fixture fixture;
55735568
struct aws_http_header headers[] = {
5574-
{.name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Transfer-Encoding"),
5575-
.value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("chunked")},
5569+
{.name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Content-Length"),
5570+
.value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("5")},
55765571
};
55775572
ASSERT_SUCCESS(s_write_data_test_setup(&fixture, allocator, headers, AWS_ARRAY_SIZE(headers), true));
55785573

5574+
/* NULL data without end_stream should be a no-op (return success, do nothing) */
55795575
struct aws_http_stream_write_data_options write_options = {
55805576
.data = NULL,
5581-
.end_stream = true,
5577+
.end_stream = false,
55825578
};
55835579
ASSERT_SUCCESS(aws_http_stream_write_data(fixture.stream_tester.stream, &write_options));
55845580

5581+
/* Should still be able to write real data after the no-op */
5582+
struct aws_byte_cursor data = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("hello");
5583+
struct aws_input_stream *input_stream = aws_input_stream_new_from_cursor(allocator, &data);
5584+
struct aws_http_stream_write_data_options real_write = {
5585+
.data = input_stream,
5586+
.end_stream = true,
5587+
};
5588+
ASSERT_SUCCESS(aws_http_stream_write_data(fixture.stream_tester.stream, &real_write));
5589+
testing_channel_drain_queued_tasks(&fixture.tester.testing_channel);
5590+
5591+
ASSERT_SUCCESS(testing_channel_check_written_messages_str(
5592+
&fixture.tester.testing_channel, allocator, "POST /upload HTTP/1.1\r\nContent-Length: 5\r\n\r\nhello"));
5593+
5594+
aws_input_stream_release(input_stream);
5595+
ASSERT_SUCCESS(s_write_data_test_teardown(&fixture));
5596+
return AWS_OP_SUCCESS;
5597+
}
5598+
5599+
/* Test: auto-add Transfer-Encoding: chunked when no Content-Length or Transfer-Encoding is set */
5600+
H1_CLIENT_TEST_CASE(h1_client_write_data_auto_chunked) {
5601+
(void)ctx;
5602+
struct write_data_test_fixture fixture;
5603+
/* No Content-Length or Transfer-Encoding header */
5604+
ASSERT_SUCCESS(s_write_data_test_setup(&fixture, allocator, NULL, 0, true));
5605+
5606+
struct aws_byte_cursor data = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("hello");
5607+
struct aws_input_stream *input_stream = aws_input_stream_new_from_cursor(allocator, &data);
5608+
5609+
struct aws_http_stream_write_data_options write_options = {
5610+
.data = input_stream,
5611+
.end_stream = true,
5612+
};
5613+
ASSERT_SUCCESS(aws_http_stream_write_data(fixture.stream_tester.stream, &write_options));
55855614
testing_channel_drain_queued_tasks(&fixture.tester.testing_channel);
55865615

5616+
/* Transfer-Encoding: chunked should have been auto-added */
55875617
const char *expected = "POST /upload HTTP/1.1\r\n"
55885618
"Transfer-Encoding: chunked\r\n"
55895619
"\r\n"
5620+
"5\r\n"
5621+
"hello"
5622+
"\r\n"
55905623
"0\r\n"
55915624
"\r\n";
55925625
ASSERT_SUCCESS(testing_channel_check_written_messages_str(&fixture.tester.testing_channel, allocator, expected));
55935626

5594-
ASSERT_SUCCESS(testing_channel_push_read_str(&fixture.tester.testing_channel, "HTTP/1.1 200 OK\r\n\r\n"));
5595-
testing_channel_drain_queued_tasks(&fixture.tester.testing_channel);
5627+
aws_input_stream_release(input_stream);
5628+
ASSERT_SUCCESS(s_write_data_test_teardown(&fixture));
5629+
return AWS_OP_SUCCESS;
5630+
}
55965631

5597-
ASSERT_TRUE(fixture.stream_tester.complete);
5598-
ASSERT_INT_EQUALS(200, fixture.stream_tester.response_status);
5632+
/* Test: body stream + use_manual_data_writes is rejected */
5633+
H1_CLIENT_TEST_CASE(h1_client_write_data_body_stream_conflict) {
5634+
(void)ctx;
5635+
struct tester tester;
5636+
ASSERT_SUCCESS(s_tester_init(&tester, allocator));
55995637

5600-
ASSERT_SUCCESS(s_write_data_test_teardown(&fixture));
5638+
struct aws_http_message *request = aws_http_message_new_request(allocator);
5639+
ASSERT_NOT_NULL(request);
5640+
ASSERT_SUCCESS(aws_http_message_set_request_method(request, aws_byte_cursor_from_c_str("POST")));
5641+
ASSERT_SUCCESS(aws_http_message_set_request_path(request, aws_byte_cursor_from_c_str("/upload")));
5642+
5643+
struct aws_http_header headers[] = {
5644+
{.name = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("Content-Length"),
5645+
.value = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("5")},
5646+
};
5647+
ASSERT_SUCCESS(aws_http_message_add_header_array(request, headers, AWS_ARRAY_SIZE(headers)));
5648+
5649+
/* Set a body stream AND use_manual_data_writes — should conflict */
5650+
struct aws_byte_cursor body = AWS_BYTE_CUR_INIT_FROM_STRING_LITERAL("hello");
5651+
struct aws_input_stream *body_stream = aws_input_stream_new_from_cursor(allocator, &body);
5652+
aws_http_message_set_body_stream(request, body_stream);
5653+
5654+
struct aws_http_make_request_options request_options = {
5655+
.self_size = sizeof(request_options),
5656+
.request = request,
5657+
.use_manual_data_writes = true,
5658+
};
5659+
struct aws_http_stream *stream = aws_http_connection_make_request(tester.connection, &request_options);
5660+
ASSERT_NULL(stream);
5661+
ASSERT_INT_EQUALS(AWS_ERROR_HTTP_INVALID_HEADER_FIELD, aws_last_error());
5662+
5663+
aws_input_stream_release(body_stream);
5664+
aws_http_message_destroy(request);
5665+
ASSERT_SUCCESS(s_tester_clean_up(&tester));
56015666
return AWS_OP_SUCCESS;
56025667
}

tests/test_h2_client.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6214,3 +6214,57 @@ TEST_CASE(h2_client_unified_write_data_api) {
62146214

62156215
return s_tester_clean_up();
62166216
}
6217+
6218+
/* Test: H2 write_data using the new use_manual_data_writes field (not the deprecated http2_use_manual_data_writes) */
6219+
TEST_CASE(h2_client_unified_write_data_api_new_field) {
6220+
ASSERT_SUCCESS(s_tester_init(allocator, ctx));
6221+
ASSERT_SUCCESS(h2_fake_peer_send_connection_preface_default_settings(&s_tester.peer));
6222+
ASSERT_SUCCESS(h2_fake_peer_decode_messages_from_testing_channel(&s_tester.peer));
6223+
6224+
struct aws_http_message *request = aws_http2_message_new_request(allocator);
6225+
ASSERT_NOT_NULL(request);
6226+
6227+
struct aws_http_header request_headers_src[] = {
6228+
DEFINE_HEADER(":method", "POST"),
6229+
DEFINE_HEADER(":scheme", "https"),
6230+
DEFINE_HEADER(":path", "/upload"),
6231+
};
6232+
aws_http_message_add_header_array(request, request_headers_src, AWS_ARRAY_SIZE(request_headers_src));
6233+
6234+
struct aws_http_make_request_options request_options = {
6235+
.self_size = sizeof(request_options),
6236+
.request = request,
6237+
.use_manual_data_writes = true,
6238+
};
6239+
struct aws_http_stream *stream = aws_http_connection_make_request(s_tester.connection, &request_options);
6240+
ASSERT_NOT_NULL(stream);
6241+
6242+
aws_http_stream_activate(stream);
6243+
testing_channel_drain_queued_tasks(&s_tester.testing_channel);
6244+
6245+
struct aws_byte_cursor data = aws_byte_cursor_from_c_str("hello");
6246+
struct aws_input_stream *input_stream = aws_input_stream_new_from_cursor(allocator, &data);
6247+
ASSERT_NOT_NULL(input_stream);
6248+
6249+
struct aws_http_stream_write_data_options write_options = {
6250+
.data = input_stream,
6251+
.end_stream = true,
6252+
};
6253+
6254+
ASSERT_SUCCESS(aws_http_stream_write_data(stream, &write_options));
6255+
testing_channel_drain_queued_tasks(&s_tester.testing_channel);
6256+
6257+
uint32_t stream_id = aws_http_stream_get_id(stream);
6258+
ASSERT_SUCCESS(h2_fake_peer_decode_messages_from_testing_channel(&s_tester.peer));
6259+
ASSERT_NOT_NULL(
6260+
h2_decode_tester_find_frame(&s_tester.peer.decode, AWS_H2_FRAME_T_HEADERS, 0 /*search_start_idx*/, NULL));
6261+
ASSERT_SUCCESS(
6262+
h2_decode_tester_check_data_str_across_frames(&s_tester.peer.decode, stream_id, "hello", true /*end_stream*/));
6263+
6264+
aws_input_stream_release(input_stream);
6265+
aws_http_message_release(request);
6266+
aws_http_stream_release(stream);
6267+
aws_http_connection_close(s_tester.connection);
6268+
6269+
return s_tester_clean_up();
6270+
}

0 commit comments

Comments
 (0)