Skip to content

Commit ef78cb8

Browse files
authored
H2 manual write triggers the stream complete test (#510)
1 parent e526ac3 commit ef78cb8

File tree

5 files changed

+70
-1
lines changed

5 files changed

+70
-1
lines changed

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ add_test_case(h2_client_error_from_incoming_headers_callback_reset_stream)
502502
add_test_case(h2_client_error_from_incoming_headers_done_callback_reset_stream)
503503
add_test_case(h2_client_error_from_incoming_body_callback_reset_stream)
504504
add_test_case(h2_client_manual_data_write)
505+
add_test_case(h2_client_manual_data_write_read_broken)
505506
add_test_case(h2_client_manual_data_write_not_enabled)
506507
add_test_case(h2_client_manual_data_write_with_body)
507508
add_test_case(h2_client_manual_data_write_no_data)

tests/py_localhost/server.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,9 @@ def window_updated(self, stream_id, delta):
308308
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
309309
ssl_context.options |= (ssl.OP_NO_COMPRESSION)
310310
ssl_context.load_cert_chain(
311-
certfile="../resources/unittests.crt", keyfile="../resources/unittests.key")
311+
certfile=os.path.join(os.path.dirname(__file__),
312+
"../resources/unittests.crt"),
313+
keyfile=os.path.join(os.path.dirname(__file__), "../resources/unittests.key"))
312314
ssl_context.set_alpn_protocols(["h2"])
313315

314316
loop = asyncio.new_event_loop()

tests/stream_test_helper.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ int client_stream_tester_init(
201201
.on_metrics = s_on_metrics,
202202
.on_complete = s_on_complete,
203203
.on_destroy = s_on_destroy,
204+
.http2_use_manual_data_writes = options->http2_manual_write,
204205
};
205206
tester->stream = aws_http_connection_make_request(options->connection, &request_options);
206207
ASSERT_NOT_NULL(tester->stream);

tests/stream_test_helper.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ struct client_stream_tester {
5151
struct client_stream_tester_options {
5252
struct aws_http_message *request;
5353
struct aws_http_connection *connection;
54+
bool http2_manual_write;
5455
};
5556

5657
int client_stream_tester_init(

tests/test_h2_client.c

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5422,6 +5422,70 @@ TEST_CASE(h2_client_manual_data_write) {
54225422
return s_tester_clean_up();
54235423
}
54245424

5425+
static void s_http_stream_write_complete_fn(struct aws_http_stream *stream, int error_code, void *user_data) {
5426+
(void)stream;
5427+
int *ctx = (int *)user_data;
5428+
*ctx = error_code;
5429+
}
5430+
5431+
TEST_CASE(h2_client_manual_data_write_read_broken) {
5432+
5433+
ASSERT_SUCCESS(s_tester_init(allocator, ctx));
5434+
/* get connection preface and acks out of the way */
5435+
ASSERT_SUCCESS(h2_fake_peer_send_connection_preface_default_settings(&s_tester.peer));
5436+
ASSERT_SUCCESS(h2_fake_peer_decode_messages_from_testing_channel(&s_tester.peer));
5437+
5438+
struct aws_http_message *request = aws_http2_message_new_request(allocator);
5439+
ASSERT_NOT_NULL(request);
5440+
5441+
struct aws_http_header request_headers_src[] = {
5442+
DEFINE_HEADER(":method", "POST"),
5443+
DEFINE_HEADER(":scheme", "https"),
5444+
DEFINE_HEADER(":path", "/"),
5445+
};
5446+
aws_http_message_add_header_array(request, request_headers_src, AWS_ARRAY_SIZE(request_headers_src));
5447+
struct client_stream_tester stream_tester;
5448+
5449+
struct client_stream_tester_options options = {
5450+
.request = request,
5451+
.connection = s_tester.connection,
5452+
.http2_manual_write = true,
5453+
};
5454+
ASSERT_SUCCESS(client_stream_tester_init(&stream_tester, s_tester.alloc, &options));
5455+
struct aws_http_stream *stream = stream_tester.stream;
5456+
ASSERT_NOT_NULL(stream);
5457+
5458+
testing_channel_drain_queued_tasks(&s_tester.testing_channel);
5459+
5460+
struct aws_input_stream *data_stream = aws_input_stream_new_tester(allocator, aws_byte_cursor_from_c_str("abcd"));
5461+
aws_input_stream_tester_set_reading_broken(data_stream, true);
5462+
int error_code = 0;
5463+
struct aws_http2_stream_write_data_options write = {
5464+
.data = data_stream,
5465+
.on_complete = s_http_stream_write_complete_fn,
5466+
.user_data = &error_code,
5467+
};
5468+
5469+
ASSERT_SUCCESS(aws_http2_stream_write_data(stream, &write));
5470+
aws_input_stream_release(data_stream);
5471+
5472+
testing_channel_drain_queued_tasks(&s_tester.testing_channel);
5473+
ASSERT_TRUE(stream_tester.complete);
5474+
/* The stream complete will get the error code from the input stream read. */
5475+
ASSERT_UINT_EQUALS(stream_tester.on_complete_error_code, AWS_IO_STREAM_READ_FAILED);
5476+
/* The write triggers the stream to complete with error, so the write failed as the stream completes. */
5477+
ASSERT_UINT_EQUALS(error_code, AWS_ERROR_HTTP_STREAM_HAS_COMPLETED);
5478+
5479+
aws_http_message_release(request);
5480+
5481+
/* close the connection */
5482+
aws_http_connection_close(s_tester.connection);
5483+
client_stream_tester_clean_up(&stream_tester);
5484+
5485+
/* clean up */
5486+
return s_tester_clean_up();
5487+
}
5488+
54255489
TEST_CASE(h2_client_manual_data_write_not_enabled) {
54265490

54275491
ASSERT_SUCCESS(s_tester_init(allocator, ctx));

0 commit comments

Comments
 (0)