Skip to content

Commit

Permalink
http2: migrates metadata_encoder_test.cc away from direct usage of ng…
Browse files Browse the repository at this point in the history
…http2 (#25122)

Part of addressing #23596.

Commit Message: Migrates metadata_encoder_test.cc away from direct usage of nghttp2.
Additional Description:
Risk Level: low
Testing: ran the unit tests locally
Docs Changes:
Release Notes:
Platform Specific Features:

Signed-off-by: Biren Roy <[email protected]>
  • Loading branch information
birenroy authored Jan 26, 2023
1 parent 91b9196 commit a874dc1
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 56 deletions.
4 changes: 4 additions & 0 deletions bazel/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -901,6 +901,10 @@ def _com_github_google_quiche():
name = "quiche_http2_protocol",
actual = "@com_github_google_quiche//:http2_adapter_http2_protocol",
)
native.bind(
name = "quiche_http2_test_tools",
actual = "@com_github_google_quiche//:http2_adapter_mock_http2_visitor",
)
native.bind(
name = "quiche_quic_platform",
actual = "@com_github_google_quiche//:quic_platform",
Expand Down
2 changes: 1 addition & 1 deletion test/common/http/http2/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ envoy_cc_test(
name = "metadata_encoder_test",
srcs = ["metadata_encoder_test.cc"],
external_deps = [
"nghttp2",
"quiche_http2_adapter",
"quiche_http2_test_tools",
],
deps = [
"//source/common/buffer:buffer_lib",
Expand Down
90 changes: 35 additions & 55 deletions test/common/http/http2/metadata_encoder_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "http2_frame.h"
#include "nghttp2/nghttp2.h"
#include "quiche/http2/adapter/callback_visitor.h"
#include "quiche/http2/adapter/data_source.h"
#include "quiche/http2/adapter/mock_http2_visitor.h"
#include "quiche/http2/adapter/nghttp2_adapter.h"

// A global variable in nghttp2 to disable preface and initial settings for tests.
Expand All @@ -39,45 +39,41 @@ struct TestBuffer {
size_t length = 0;
};

// The application data structure passes to nghttp2 session.
struct UserData {
NewMetadataEncoder* encoder;
MetadataDecoder* decoder;
// Stores data sent by encoder and received by the decoder.
TestBuffer* output_buffer;
};

// Nghttp2 callback function for receiving extension frame.
static int onExtensionChunkRecvCallback(nghttp2_session* /*session*/, const nghttp2_frame_hd* hd,
const uint8_t* data, size_t len, void* user_data) {
EXPECT_GE(hd->length, len);
class MetadataUnpackingVisitor : public http2::adapter::test::MockHttp2Visitor {
public:
MetadataUnpackingVisitor(MetadataDecoder* decoder, TestBuffer* output_buffer)
: decoder_(decoder), buffer_(output_buffer) {
// These calls are not important to intercept for these tests.
EXPECT_CALL(*this, OnBeforeFrameSent).Times(testing::AnyNumber());
EXPECT_CALL(*this, OnFrameSent).Times(testing::AnyNumber());
EXPECT_CALL(*this, OnFrameHeader).Times(testing::AnyNumber());
}

MetadataDecoder* decoder = reinterpret_cast<UserData*>(user_data)->decoder;
bool success = decoder->receiveMetadata(data, len);
return success ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
}
void OnBeginMetadataForStream(http2::adapter::Http2StreamId /*stream_id*/,
size_t payload_length) override {
remaining_payload_ = payload_length;
}

// Nghttp2 callback function for unpack extension frames.
static int unpackExtensionCallback(nghttp2_session* /*session*/, void** payload,
const nghttp2_frame_hd* hd, void* user_data) {
EXPECT_NE(nullptr, hd);
EXPECT_NE(nullptr, payload);
bool OnMetadataForStream(http2::adapter::Http2StreamId /*stream_id*/,
absl::string_view metadata) override {
return decoder_->receiveMetadata(reinterpret_cast<const uint8_t*>(metadata.data()),
metadata.size());
}

MetadataDecoder* decoder = reinterpret_cast<UserData*>(user_data)->decoder;
bool result = decoder->onMetadataFrameComplete((hd->flags == END_METADATA_FLAG) ? true : false);
return result ? 0 : NGHTTP2_ERR_CALLBACK_FAILURE;
}
bool OnMetadataEndForStream(http2::adapter::Http2StreamId /*stream_id*/) override {
return decoder_->onMetadataFrameComplete(true);
}

// Nghttp2 callback function for sending data to peer.
static ssize_t sendCallback(nghttp2_session* /*session*/, const uint8_t* buf, size_t len, int flags,
void* user_data) {
EXPECT_LE(0, flags);
int64_t OnReadyToSend(absl::string_view serialized) override {
memcpy(buffer_->buf + buffer_->length, serialized.data(), serialized.size());
buffer_->length += serialized.size();
return serialized.size();
}

TestBuffer* buffer = (reinterpret_cast<UserData*>(user_data))->output_buffer;
memcpy(buffer->buf + buffer->length, buf, len);
buffer->length += len;
return len;
}
MetadataDecoder* decoder_;
TestBuffer* buffer_;
size_t remaining_payload_ = 0;
};

} // namespace

Expand All @@ -91,27 +87,13 @@ class MetadataEncoderTest : public testing::Test {
nghttp2_option_new(&option);
nghttp2_option_set_user_recv_extension_type(option, METADATA_FRAME_TYPE);

// Sets callback functions.
nghttp2_session_callbacks* callbacks;
nghttp2_session_callbacks_new(&callbacks);
nghttp2_session_callbacks_set_send_callback(callbacks, sendCallback);
nghttp2_session_callbacks_set_on_extension_chunk_recv_callback(callbacks,
onExtensionChunkRecvCallback);
nghttp2_session_callbacks_set_unpack_extension_callback(callbacks, unpackExtensionCallback);

// Sets application data to pass to nghttp2 session.
user_data_.encoder = &encoder_;
user_data_.decoder = decoder_.get();
user_data_.output_buffer = &output_buffer_;

// Creates new nghttp2 session.
nghttp2_enable_strict_preface = 0;
visitor_ = std::make_unique<http2::adapter::CallbackVisitor>(
http2::adapter::Perspective::kClient, *callbacks, &user_data_);
visitor_ = std::make_unique<MetadataUnpackingVisitor>(decoder_.get(), &output_buffer_);

session_ = http2::adapter::NgHttp2Adapter::CreateClientAdapter(*visitor_, option);
nghttp2_enable_strict_preface = 1;
nghttp2_option_del(option);
nghttp2_session_callbacks_del(callbacks);
}

void verifyMetadataMapVector(MetadataMapVector& expect, MetadataMapPtr&& metadata_map_ptr) {
Expand All @@ -133,17 +115,14 @@ class MetadataEncoderTest : public testing::Test {
}

std::unique_ptr<http2::adapter::NgHttp2Adapter> session_;
std::unique_ptr<http2::adapter::CallbackVisitor> visitor_;
std::unique_ptr<MetadataUnpackingVisitor> visitor_;
NewMetadataEncoder encoder_;
std::unique_ptr<MetadataDecoder> decoder_;
int count_ = 0;

// Stores data received by peer.
TestBuffer output_buffer_;

// Application data passed to nghttp2.
UserData user_data_;

Random::RandomGeneratorImpl random_generator_;
};

Expand Down Expand Up @@ -188,6 +167,7 @@ TEST_F(MetadataEncoderTest, VerifyEncoderDecoderMultipleMetadataReachSizeLimit)

ssize_t result = 0;

EXPECT_CALL(*visitor_, OnConnectionError);
for (int i = 0; i < 100; i++) {
// Cleans up the output buffer.
memset(output_buffer_.buf, 0, output_buffer_.length);
Expand Down

0 comments on commit a874dc1

Please sign in to comment.