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_