Adds a set of mock nghttp2 callbacks that can be used with nghttp2 or a similar interface in tests. PiperOrigin-RevId: 371594149 Change-Id: I50c1823485a30289ce93a4badbfe5051d6f98b92
diff --git a/http2/adapter/mock_nghttp2_callbacks.cc b/http2/adapter/mock_nghttp2_callbacks.cc new file mode 100644 index 0000000..c3f9e71 --- /dev/null +++ b/http2/adapter/mock_nghttp2_callbacks.cc
@@ -0,0 +1,115 @@ +#include "http2/adapter/mock_nghttp2_callbacks.h" + +#include "http2/adapter/nghttp2_util.h" + +namespace http2 { +namespace adapter { +namespace test { + +/* static */ +nghttp2_session_callbacks* MockNghttp2Callbacks::GetCallbacks() { + nghttp2_session_callbacks* callbacks; + nghttp2_session_callbacks_new(&callbacks); + + // All of the callback implementations below just delegate to the mock methods + // of |user_data|, which is assumed to be a MockNghttp2Callbacks*. + nghttp2_session_callbacks_set_send_callback( + callbacks, + [](nghttp2_session*, const uint8_t* data, size_t length, int flags, + void* user_data) -> ssize_t { + return static_cast<MockNghttp2Callbacks*>(user_data)->Send(data, length, + flags); + }); + + nghttp2_session_callbacks_set_send_data_callback( + callbacks, + [](nghttp2_session*, nghttp2_frame* frame, const uint8_t* framehd, + size_t length, nghttp2_data_source* source, void* user_data) -> int { + return static_cast<MockNghttp2Callbacks*>(user_data)->SendData( + frame, framehd, length, source); + }); + + nghttp2_session_callbacks_set_on_begin_headers_callback( + callbacks, + [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int { + return static_cast<MockNghttp2Callbacks*>(user_data)->OnBeginHeaders( + frame); + }); + + nghttp2_session_callbacks_set_on_header_callback( + callbacks, + [](nghttp2_session*, const nghttp2_frame* frame, const uint8_t* raw_name, + size_t name_length, const uint8_t* raw_value, size_t value_length, + uint8_t flags, void* user_data) -> int { + absl::string_view name = ToStringView(raw_name, name_length); + absl::string_view value = ToStringView(raw_value, value_length); + return static_cast<MockNghttp2Callbacks*>(user_data)->OnHeader( + frame, name, value, flags); + }); + + nghttp2_session_callbacks_set_on_data_chunk_recv_callback( + callbacks, + [](nghttp2_session*, uint8_t flags, int32_t stream_id, + const uint8_t* data, size_t len, void* user_data) -> int { + absl::string_view chunk = ToStringView(data, len); + return static_cast<MockNghttp2Callbacks*>(user_data)->OnDataChunkRecv( + flags, stream_id, chunk); + }); + + nghttp2_session_callbacks_set_on_begin_frame_callback( + callbacks, + [](nghttp2_session*, const nghttp2_frame_hd* hd, void* user_data) -> int { + return static_cast<MockNghttp2Callbacks*>(user_data)->OnBeginFrame(hd); + }); + + nghttp2_session_callbacks_set_on_frame_recv_callback( + callbacks, + [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int { + return static_cast<MockNghttp2Callbacks*>(user_data)->OnFrameRecv( + frame); + }); + + nghttp2_session_callbacks_set_on_stream_close_callback( + callbacks, + [](nghttp2_session*, int32_t stream_id, uint32_t error_code, + void* user_data) -> int { + return static_cast<MockNghttp2Callbacks*>(user_data)->OnStreamClose( + stream_id, error_code); + }); + + nghttp2_session_callbacks_set_on_frame_send_callback( + callbacks, + [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int { + return static_cast<MockNghttp2Callbacks*>(user_data)->OnFrameSend( + frame); + }); + + nghttp2_session_callbacks_set_before_frame_send_callback( + callbacks, + [](nghttp2_session*, const nghttp2_frame* frame, void* user_data) -> int { + return static_cast<MockNghttp2Callbacks*>(user_data)->BeforeFrameSend( + frame); + }); + + nghttp2_session_callbacks_set_on_frame_not_send_callback( + callbacks, + [](nghttp2_session*, const nghttp2_frame* frame, int lib_error_code, + void* user_data) -> int { + return static_cast<MockNghttp2Callbacks*>(user_data)->OnFrameNotSend( + frame, lib_error_code); + }); + + nghttp2_session_callbacks_set_on_invalid_frame_recv_callback( + callbacks, + [](nghttp2_session*, const nghttp2_frame* frame, int error_code, + void* user_data) -> int { + return static_cast<MockNghttp2Callbacks*>(user_data) + ->OnInvalidFrameRecv(frame, error_code); + }); + + return callbacks; +} + +} // namespace test +} // namespace adapter +} // namespace http2
diff --git a/http2/adapter/mock_nghttp2_callbacks.h b/http2/adapter/mock_nghttp2_callbacks.h new file mode 100644 index 0000000..2d279ad --- /dev/null +++ b/http2/adapter/mock_nghttp2_callbacks.h
@@ -0,0 +1,74 @@ +#ifndef QUICHE_HTTP2_ADAPTER_MOCK_NGHTTP2_CALLBACKS_H_ +#define QUICHE_HTTP2_ADAPTER_MOCK_NGHTTP2_CALLBACKS_H_ + +#include "absl/strings/string_view.h" +#include "third_party/nghttp2/src/lib/includes/nghttp2/nghttp2.h" +#include "common/platform/api/quiche_test.h" + +namespace http2 { +namespace adapter { +namespace test { + +// This class provides a set of mock nghttp2 callbacks for use in unit test +// expectations. +class MockNghttp2Callbacks { + public: + MockNghttp2Callbacks() = default; + + // The caller takes ownership of the |nghttp2_session_callbacks|. + static nghttp2_session_callbacks* GetCallbacks(); + + MOCK_METHOD(ssize_t, + Send, + (const uint8_t* data, size_t length, int flags), + ()); + + MOCK_METHOD(int, + SendData, + (nghttp2_frame * frame, + const uint8_t* framehd, + size_t length, + nghttp2_data_source* source), + ()); + + MOCK_METHOD(int, OnBeginHeaders, (const nghttp2_frame* frame), ()); + + MOCK_METHOD(int, + OnHeader, + (const nghttp2_frame* frame, + absl::string_view name, + absl::string_view value, + uint8_t flags), + ()); + + MOCK_METHOD(int, + OnDataChunkRecv, + (uint8_t flags, int32_t stream_id, absl::string_view data), + ()); + + MOCK_METHOD(int, OnBeginFrame, (const nghttp2_frame_hd* hd), ()); + + MOCK_METHOD(int, OnFrameRecv, (const nghttp2_frame* frame), ()); + + MOCK_METHOD(int, OnStreamClose, (int32_t stream_id, uint32_t error_code), ()); + + MOCK_METHOD(int, OnFrameSend, (const nghttp2_frame* frame), ()); + + MOCK_METHOD(int, BeforeFrameSend, (const nghttp2_frame* frame), ()); + + MOCK_METHOD(int, + OnFrameNotSend, + (const nghttp2_frame* frame, int lib_error_code), + ()); + + MOCK_METHOD(int, + OnInvalidFrameRecv, + (const nghttp2_frame* frame, int error_code), + ()); +}; + +} // namespace test +} // namespace adapter +} // namespace http2 + +#endif // QUICHE_HTTP2_ADAPTER_MOCK_NGHTTP2_CALLBACKS_H_