include(AwsTestHarness)
include(AwsLibFuzzer)
enable_testing()

file(GLOB TEST_HDRS "*.h")
file(GLOB TEST_SRC "*.c")
file(GLOB TESTS ${TEST_HDRS} ${TEST_SRC})

add_test_case(headers_add)
add_test_case(headers_add_array)
add_test_case(headers_set)
add_test_case(headers_erase_index)
add_test_case(headers_erase)
add_test_case(headers_erase_value)
add_test_case(headers_clear)

add_test_case(message_sanity_check)
add_test_case(message_request_method)
add_test_case(message_request_path)
add_test_case(message_response_status)
add_test_case(message_refcounts)
add_test_case(message_with_existing_headers)
add_test_case(message_handles_oom)

add_test_case(h1_test_get_request)
add_test_case(h1_test_request_bad_version)
add_test_case(h1_test_response_unsupported_version)
add_test_case(h1_test_response_1_0)
add_test_case(h1_test_get_status_code)
add_test_case(h1_test_overflow_scratch_space)
add_test_case(h1_test_receive_request_headers)
add_test_case(h1_test_receive_response_headers)
add_test_case(h1_test_get_transfer_encoding_flags)
add_test_case(h1_test_body_unchunked)
add_test_case(h1_test_body_chunked)
add_test_case(h1_decode_trailers)
add_test_case(h1_decode_one_byte_at_a_time)
add_test_case(h1_decode_messages_at_random_intervals)
add_test_case(h1_decode_bad_requests_and_assert_failure)
add_test_case(h1_decode_bad_responses_and_assert_failure)
add_test_case(h1_test_extraneous_buffer_data_ensure_not_processed)
add_test_case(h1_test_ignore_chunk_extensions)

add_test_case(h1_client_sanity_check)
add_test_case(h1_client_request_send_1liner)
add_test_case(h1_client_request_send_headers)
add_test_case(h1_client_request_send_body)
add_test_case(h1_client_request_send_large_body)
add_test_case(h1_client_request_send_large_head)
add_test_case(h1_client_request_content_length_0_ok)
add_test_case(h1_client_request_content_length_too_small_is_error)
add_test_case(h1_client_request_content_length_too_large_is_error)
add_test_case(h1_client_request_send_multiple_in_1_io_message)
add_test_case(h1_client_request_close_header_ends_connection)
add_test_case(h1_client_request_close_header_with_pipelining)
add_test_case(h1_client_response_get_1liner)
add_test_case(h1_client_response_get_headers)
add_test_case(h1_client_response_get_body)
add_test_case(h1_client_response_get_no_body_for_head_request)
add_test_case(h1_client_response_get_no_body_from_304)
add_test_case(h1_client_response_get_100)
add_test_case(h1_client_response_get_1_from_multiple_io_messages)
add_test_case(h1_client_response_get_multiple_from_1_io_message)
add_test_case(h1_client_response_with_bad_data_shuts_down_connection)
add_test_case(h1_client_response_with_too_much_data_shuts_down_connection)
add_test_case(h1_client_response_arrives_before_request_done_sending_is_ok)
add_test_case(h1_client_response_without_request_shuts_down_connection)
add_test_case(h1_client_response_close_header_ends_connection)
add_test_case(h1_client_response_close_header_with_pipelining)
add_test_case(h1_client_window_reopens_by_default)
add_test_case(h1_client_window_shrinks_if_user_says_so)
add_test_case(h1_client_window_manual_update)
add_test_case(h1_client_window_manual_update_off_thread)
add_test_case(h1_client_request_cancelled_by_channel_shutdown)
add_test_case(h1_client_multiple_requests_cancelled_by_channel_shutdown)
add_test_case(h1_client_new_request_fails_if_channel_shut_down)
add_test_case(h1_client_error_from_outgoing_body_callback_stops_decoder)
add_test_case(h1_client_error_from_incoming_headers_callback_stops_decoder)
add_test_case(h1_client_error_from_incoming_headers_done_callback_stops_decoder)
add_test_case(h1_client_error_from_incoming_body_callback_stops_decoder)
add_test_case(h1_client_close_from_off_thread_makes_not_open)
add_test_case(h1_client_close_from_on_thread_makes_not_open)
add_test_case(h1_client_midchannel_sanity_check)
add_test_case(h1_client_midchannel_read)
add_test_case(h1_client_midchannel_read_immediately)
add_test_case(h1_client_midchannel_read_with_small_downstream_window)
add_test_case(h1_client_midchannel_write)
add_test_case(h1_client_midchannel_write_continues_after_shutdown_in_read_dir)
add_test_case(h1_client_midchannel_requires_switching_protocols)
add_test_case(h1_client_switching_protocols_fails_pending_requests)
add_test_case(h1_client_switching_protocols_fails_subsequent_requests)
add_test_case(h1_client_switching_protocols_requires_downstream_handler)

add_test_case(strutil_read_unsigned_num)
add_test_case(strutil_read_unsigned_hex)
add_test_case(strutil_trim_http_whitespace)

add_net_test_case(tls_download_medium_file)

add_test_case(websocket_decoder_sanity_check)
add_test_case(websocket_decoder_simplest_frame)
add_test_case(websocket_decoder_rsv)
add_test_case(websocket_decoder_data_frame)
add_test_case(websocket_decoder_stops_at_frame_end)
add_test_case(websocket_decoder_masking)
add_test_case(websocket_decoder_extended_length_2byte)
add_test_case(websocket_decoder_extended_length_8byte)
add_test_case(websocket_decoder_1byte_at_a_time)
add_test_case(websocket_decoder_fail_on_unknown_opcode)
add_test_case(websocket_decoder_fragmented_message)
add_test_case(websocket_decoder_fail_on_bad_fragmentation)
add_test_case(websocket_decoder_control_frame_cannot_be_fragmented)
add_test_case(websocket_decoder_on_frame_callback_can_fail_decoder)
add_test_case(websocket_decoder_on_payload_callback_can_fail_decoder)
add_test_case(websocket_encoder_sanity_check)
add_test_case(websocket_encoder_simplest_frame)
add_test_case(websocket_encoder_rsv)
add_test_case(websocket_encoder_data_frame)
add_test_case(websocket_encoder_fail_if_payload_exceeds_stated_length)
add_test_case(websocket_encoder_masking)
add_test_case(websocket_encoder_extended_length)
add_test_case(websocket_encoder_1_byte_at_a_time)
add_test_case(websocket_encoder_fragmented_message)
add_test_case(websocket_encoder_fragmentation_failure_checks)
add_test_case(websocket_encoder_payload_callback_can_fail_encoder)
add_test_case(websocket_handler_sanity_check)
add_test_case(websocket_handler_send_frame)
add_test_case(websocket_handler_send_frame_off_thread)
add_test_case(websocket_handler_send_multiple_frames)
add_test_case(websocket_handler_send_huge_frame)
add_test_case(websocket_handler_send_payload_slowly)
add_test_case(websocket_handler_send_payload_with_pauses)
add_test_case(websocket_handler_send_high_priority_frame)
add_test_case(websocket_handler_sends_nothing_after_close_frame)
add_test_case(websocket_handler_send_frames_always_complete)
add_test_case(websocket_handler_send_one_io_msg_at_a_time)
add_test_case(websocket_handler_send_halts_if_payload_fn_returns_false)
add_test_case(websocket_handler_shutdown_automatically_sends_close_frame)
add_test_case(websocket_handler_shutdown_handles_queued_close_frame)
# add_test_case(websocket_handler_shutdown_immediately_in_emergency) disabled until channel API exposes immediate shutdown
add_test_case(websocket_handler_shutdown_handles_unexpected_write_error)
add_test_case(websocket_handler_close_on_thread)
add_test_case(websocket_handler_close_off_thread)
add_test_case(websocket_handler_read_frame)
add_test_case(websocket_handler_read_multiple_frames)
add_test_case(websocket_handler_read_frames_split_across_io_messages)
add_test_case(websocket_handler_read_frames_complete_on_shutdown)
add_test_case(websocket_handler_read_halts_if_begin_fn_returns_false)
add_test_case(websocket_handler_read_halts_if_payload_fn_returns_false)
add_test_case(websocket_handler_read_halts_if_complete_fn_returns_false)
add_test_case(websocket_handler_window_reopens_by_default)
add_test_case(websocket_handler_window_manual_increment)
add_test_case(websocket_handler_window_manual_increment_off_thread)
add_test_case(websocket_midchannel_sanity_check)
add_test_case(websocket_midchannel_write_message)
add_test_case(websocket_midchannel_write_multiple_messages)
add_test_case(websocket_midchannel_write_huge_message)
add_test_case(websocket_midchannel_read_message)
add_test_case(websocket_midchannel_read_multiple_messages)
add_test_case(websocket_boot_sanity_check)
add_test_case(websocket_boot_golden_path)
add_test_case(websocket_boot_fail_at_http_connect)
add_test_case(websocket_boot_fail_at_http_connect_error)
add_test_case(websocket_boot_fail_at_new_request)
add_test_case(websocket_boot_fail_at_response_error)
add_test_case(websocket_boot_fail_at_response_status)
add_test_case(websocket_boot_fail_at_new_handler)
add_test_case(websocket_boot_report_unexpected_http_shutdown)
add_test_case(websocket_boot_fail_because_oom)
add_test_case(websocket_handshake_key_max_length)
add_test_case(websocket_handshake_key_randomness)

add_test_case(hpack_encode_integer)
add_test_case(hpack_decode_integer)
add_test_case(hpack_static_table_find)
add_test_case(hpack_static_table_get)
add_test_case(hpack_dynamic_table_find)
add_test_case(hpack_dynamic_table_get)

add_test_case(h2_header_ex_2_1)
add_test_case(h2_header_ex_2_2)
add_test_case(h2_header_ex_2_3)
add_test_case(h2_header_ex_2_4)
add_test_case(h2_header_ex_3_1)
add_test_case(h2_header_ex_4_1)
add_test_case(h2_header_ex_5_1)
add_test_case(h2_header_ex_6_1)

add_test_case(h2_frame_data)
add_test_case(h2_frame_headers)
add_test_case(h2_frame_priority)
add_test_case(h2_frame_rst_stream)
add_test_case(h2_frame_settings)
add_test_case(h2_frame_push_promise)
add_test_case(h2_frame_ping)
add_test_case(h2_frame_goaway)
add_test_case(h2_frame_window_update)
add_test_case(h2_frame_continuation)

add_test_case(server_new_destroy)
add_test_case(connection_setup_shutdown)
add_test_case(connection_destroy_server_with_connection_existing)
add_test_case(connection_destroy_server_with_multiple_connections_existing)
add_test_case(connection_server_shutting_down_new_connection_setup_fail)

add_net_test_case(test_connection_manager_setup_shutdown)
add_net_test_case(test_connection_manager_single_connection)
add_net_test_case(test_connection_manager_many_connections)
add_net_test_case(test_connection_manager_acquire_release)
add_net_test_case(test_connection_manager_close_and_release)
add_net_test_case(test_connection_manager_acquire_release_mix)
add_net_test_case(test_connection_manager_acquire_release_mix_synchronous)
add_net_test_case(test_connection_manager_connect_callback_failure)
add_net_test_case(test_connection_manager_connect_immediate_failure)
add_net_test_case(test_connection_manager_success_then_cancel_pending_from_failure)
add_net_test_case(test_connection_manager_proxy_setup_shutdown)
add_net_test_case(test_connection_manager_proxy_acquire_single)

add_test_case(h1_server_sanity_check)
add_test_case(h1_server_receive_1line_request)
add_test_case(h1_server_receive_headers)
add_test_case(h1_server_receive_body)
add_test_case(h1_server_receive_1_request_from_multiple_io_messages)
add_test_case(h1_server_receive_multiple_requests_from_1_io_messages)
add_test_case(h1_server_receive_bad_request_shut_down_connection)
add_test_case(h1_server_receive_close_header_ends_connection)
add_test_case(h1_server_receive_close_header_more_requests_illegal)

add_test_case(h1_server_send_1line_response)
add_test_case(h1_server_send_response_headers)
add_test_case(h1_server_send_response_body)
add_test_case(h1_server_send_response_to_HEAD_request)
add_test_case(h1_server_send_304_response)
add_test_case(h1_server_send_multiple_responses_in_order)
add_test_case(h1_server_send_multiple_responses_out_of_order)
add_test_case(h1_server_send_multiple_responses_out_of_order_only_one_sent)
add_test_case(h1_server_send_response_before_request_finished)
add_test_case(h1_server_send_response_large_body)
add_test_case(h1_server_send_response_large_head)
add_test_case(h1_server_send_close_header_ends_connection)
add_test_case(h1_server_send_close_header_with_pipelining)

add_test_case(h1_server_close_before_message_is_sent)
add_test_case(h1_server_error_from_incoming_request_callback_stops_decoder)
add_test_case(h1_server_error_from_incoming_headers_callback_stops_decoder)
add_test_case(h1_server_error_from_incoming_headers_done_callback_stops_decoder)
add_test_case(h1_server_error_from_incoming_request_done_callback_stops_decoder)
add_test_case(h1_server_error_from_incoming_body_callback_stops_decoder)
add_test_case(h1_server_error_from_outgoing_body_callback_stops_sending)
add_test_case(h1_server_close_from_off_thread_makes_not_open)
add_test_case(h1_server_close_from_on_thread_makes_not_open)

add_test_case(test_http_proxy_connection_proxy_target)
add_test_case(test_http_proxy_connection_channel_failure)
add_test_case(test_http_proxy_connection_connect_failure)
add_test_case(test_https_proxy_connection_success)
add_test_case(test_https_proxy_connection_failure_connect)
add_test_case(test_https_proxy_connection_failure_tls)
add_test_case(test_http_proxy_request_transform)
add_test_case(test_http_proxy_request_transform_basic_auth)
add_test_case(test_http_proxy_uri_rewrite)
add_test_case(test_http_proxy_uri_rewrite_options_star)

# integration  tests that require a locally-installed proxy server
if (ENABLE_PROXY_INTEGRATION_TESTS)
    add_test_case(test_http_proxy_connection_options_star)
    add_test_case(test_http_proxy_connection_new_destroy)
    add_test_case(test_http_proxy_connection_get)
    add_test_case(test_https_proxy_connection_new_destroy)
    add_test_case(test_https_proxy_connection_get)
endif()

set(TEST_BINARY_NAME ${CMAKE_PROJECT_NAME}-tests)
generate_test_driver(${TEST_BINARY_NAME})

file(GLOB FUZZ_TESTS "fuzz/*.c")
aws_add_fuzz_tests("${FUZZ_TESTS}" "" "")

#SSL certificates to use for testing.
add_custom_command(TARGET ${TEST_BINARY_NAME} PRE_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy_directory
        ${CMAKE_CURRENT_SOURCE_DIR}/resources ${CMAKE_CURRENT_BINARY_DIR})
