Extends the ContainsFrames matcher to work with absl::string_view. Also requires that all input data be matched by a frame expectation.
PiperOrigin-RevId: 369494888
Change-Id: I0117497858eb0aaac4a41d2849501b0bbe8105b2
diff --git a/http2/adapter/oghttp2_adapter_test.cc b/http2/adapter/oghttp2_adapter_test.cc
index 799c9bf..d5e7b1d 100644
--- a/http2/adapter/oghttp2_adapter_test.cc
+++ b/http2/adapter/oghttp2_adapter_test.cc
@@ -61,7 +61,7 @@
EXPECT_THAT(
adapter_->GetBytesToWrite(absl::nullopt),
- ContainsFrames(
+ EqualsFrames(
{spdy::SpdyFrameType::SETTINGS, spdy::SpdyFrameType::PRIORITY,
spdy::SpdyFrameType::RST_STREAM, spdy::SpdyFrameType::PING,
spdy::SpdyFrameType::GOAWAY, spdy::SpdyFrameType::WINDOW_UPDATE}));
@@ -83,8 +83,8 @@
EXPECT_FALSE(adapter_->session().want_write());
EXPECT_THAT(
absl::StrCat(first_part, second_part),
- ContainsFrames({spdy::SpdyFrameType::SETTINGS,
- spdy::SpdyFrameType::GOAWAY, spdy::SpdyFrameType::PING}));
+ EqualsFrames({spdy::SpdyFrameType::SETTINGS, spdy::SpdyFrameType::GOAWAY,
+ spdy::SpdyFrameType::PING}));
}
} // namespace
diff --git a/http2/adapter/test_utils.cc b/http2/adapter/test_utils.cc
index 9e1db99..fafdb9f 100644
--- a/http2/adapter/test_utils.cc
+++ b/http2/adapter/test_utils.cc
@@ -23,17 +23,15 @@
return out;
}
-// Custom gMock matcher, used to determine if a particular type of frame
-// is in a string. This is useful in tests where we want to show that a
-// particular control frame type is serialized for sending to the peer.
+// Custom gMock matcher, used to implement EqualsFrames().
class SpdyControlFrameMatcher
- : public testing::MatcherInterface<const std::string> {
+ : public testing::MatcherInterface<absl::string_view> {
public:
explicit SpdyControlFrameMatcher(
std::vector<TypeAndOptionalLength> types_and_lengths)
: expected_types_and_lengths_(std::move(types_and_lengths)) {}
- bool MatchAndExplain(const std::string s,
+ bool MatchAndExplain(absl::string_view s,
testing::MatchResultListener* listener) const override {
spdy::SpdyFrameReader reader(s.data(), s.size());
@@ -43,6 +41,11 @@
return false;
}
}
+ if (!reader.IsDoneReading()) {
+ size_t bytes_remaining = s.size() - reader.GetBytesConsumed();
+ *listener << "; " << bytes_remaining << " bytes left to read!";
+ return false;
+ }
return true;
}
@@ -105,13 +108,13 @@
} // namespace
-testing::Matcher<const std::string> ContainsFrames(
+testing::Matcher<absl::string_view> EqualsFrames(
std::vector<std::pair<spdy::SpdyFrameType, absl::optional<size_t>>>
types_and_lengths) {
return MakeMatcher(new SpdyControlFrameMatcher(std::move(types_and_lengths)));
}
-testing::Matcher<const std::string> ContainsFrames(
+testing::Matcher<absl::string_view> EqualsFrames(
std::vector<spdy::SpdyFrameType> types) {
std::vector<std::pair<spdy::SpdyFrameType, absl::optional<size_t>>>
types_and_lengths;
diff --git a/http2/adapter/test_utils.h b/http2/adapter/test_utils.h
index 6276bf1..41d3b6c 100644
--- a/http2/adapter/test_utils.h
+++ b/http2/adapter/test_utils.h
@@ -4,6 +4,7 @@
#include <string>
#include <vector>
+#include "absl/strings/string_view.h"
#include "common/platform/api/quiche_test.h"
#include "spdy/core/spdy_protocol.h"
@@ -11,15 +12,19 @@
namespace adapter {
namespace test {
-// Matcher that checks whether a string contains HTTP/2 frames of the specified
-// ordered sequence of types and lengths.
-testing::Matcher<const std::string> ContainsFrames(
+// These matchers check whether a string consists entirely of HTTP/2 frames of
+// the specified ordered sequence. This is useful in tests where we want to show
+// that one or more particular frame types are serialized for sending to the
+// peer. The match will fail if there are input bytes not consumed by the
+// matcher.
+
+// Requires that frames match both types and lengths.
+testing::Matcher<absl::string_view> EqualsFrames(
std::vector<std::pair<spdy::SpdyFrameType, absl::optional<size_t>>>
types_and_lengths);
-// Matcher that checks whether a string contains HTTP/2 frames of the specified
-// ordered sequence of types.
-testing::Matcher<const std::string> ContainsFrames(
+// Requires that frames match the specified types.
+testing::Matcher<absl::string_view> EqualsFrames(
std::vector<spdy::SpdyFrameType> types);
} // namespace test
diff --git a/http2/adapter/test_utils_test.cc b/http2/adapter/test_utils_test.cc
index e8f4ebd..0de7b28 100644
--- a/http2/adapter/test_utils_test.cc
+++ b/http2/adapter/test_utils_test.cc
@@ -10,38 +10,37 @@
using spdy::SpdyFramer;
-TEST(ContainsFrames, Empty) {
- EXPECT_THAT("", ContainsFrames(std::vector<spdy::SpdyFrameType>{}));
+TEST(EqualsFrames, Empty) {
+ EXPECT_THAT("", EqualsFrames(std::vector<spdy::SpdyFrameType>{}));
}
-TEST(ContainsFrames, SingleFrameWithLength) {
+TEST(EqualsFrames, SingleFrameWithLength) {
SpdyFramer framer{SpdyFramer::ENABLE_COMPRESSION};
spdy::SpdyPingIR ping{511};
EXPECT_THAT(framer.SerializeFrame(ping),
- ContainsFrames({{spdy::SpdyFrameType::PING, 8}}));
+ EqualsFrames({{spdy::SpdyFrameType::PING, 8}}));
spdy::SpdyWindowUpdateIR window_update{1, 101};
EXPECT_THAT(framer.SerializeFrame(window_update),
- ContainsFrames({{spdy::SpdyFrameType::WINDOW_UPDATE, 4}}));
+ EqualsFrames({{spdy::SpdyFrameType::WINDOW_UPDATE, 4}}));
spdy::SpdyDataIR data{3, "Some example data, ha ha!"};
EXPECT_THAT(framer.SerializeFrame(data),
- ContainsFrames({{spdy::SpdyFrameType::DATA, 25}}));
+ EqualsFrames({{spdy::SpdyFrameType::DATA, 25}}));
}
-TEST(ContainsFrames, SingleFrameWithoutLength) {
+TEST(EqualsFrames, SingleFrameWithoutLength) {
SpdyFramer framer{SpdyFramer::ENABLE_COMPRESSION};
spdy::SpdyRstStreamIR rst_stream{7, spdy::ERROR_CODE_REFUSED_STREAM};
- EXPECT_THAT(
- framer.SerializeFrame(rst_stream),
- ContainsFrames({{spdy::SpdyFrameType::RST_STREAM, absl::nullopt}}));
+ EXPECT_THAT(framer.SerializeFrame(rst_stream),
+ EqualsFrames({{spdy::SpdyFrameType::RST_STREAM, absl::nullopt}}));
spdy::SpdyGoAwayIR goaway{13, spdy::ERROR_CODE_ENHANCE_YOUR_CALM,
"Consider taking some deep breaths."};
EXPECT_THAT(framer.SerializeFrame(goaway),
- ContainsFrames({{spdy::SpdyFrameType::GOAWAY, absl::nullopt}}));
+ EqualsFrames({{spdy::SpdyFrameType::GOAWAY, absl::nullopt}}));
spdy::Http2HeaderBlock block;
block[":method"] = "GET";
@@ -49,10 +48,10 @@
block[":authority"] = "example.com";
spdy::SpdyHeadersIR headers{17, std::move(block)};
EXPECT_THAT(framer.SerializeFrame(headers),
- ContainsFrames({{spdy::SpdyFrameType::HEADERS, absl::nullopt}}));
+ EqualsFrames({{spdy::SpdyFrameType::HEADERS, absl::nullopt}}));
}
-TEST(ContainsFrames, MultipleFrames) {
+TEST(EqualsFrames, MultipleFrames) {
SpdyFramer framer{SpdyFramer::ENABLE_COMPRESSION};
spdy::SpdyPingIR ping{511};
@@ -74,20 +73,48 @@
absl::string_view(framer.SerializeFrame(rst_stream)),
absl::string_view(framer.SerializeFrame(goaway)),
absl::string_view(framer.SerializeFrame(headers)));
+ absl::string_view frame_sequence_view = frame_sequence;
+ EXPECT_THAT(frame_sequence,
+ EqualsFrames({{spdy::SpdyFrameType::PING, absl::nullopt},
+ {spdy::SpdyFrameType::WINDOW_UPDATE, absl::nullopt},
+ {spdy::SpdyFrameType::DATA, 25},
+ {spdy::SpdyFrameType::RST_STREAM, absl::nullopt},
+ {spdy::SpdyFrameType::GOAWAY, 42},
+ {spdy::SpdyFrameType::HEADERS, 19}}));
+ EXPECT_THAT(frame_sequence_view,
+ EqualsFrames({{spdy::SpdyFrameType::PING, absl::nullopt},
+ {spdy::SpdyFrameType::WINDOW_UPDATE, absl::nullopt},
+ {spdy::SpdyFrameType::DATA, 25},
+ {spdy::SpdyFrameType::RST_STREAM, absl::nullopt},
+ {spdy::SpdyFrameType::GOAWAY, 42},
+ {spdy::SpdyFrameType::HEADERS, 19}}));
EXPECT_THAT(
frame_sequence,
- ContainsFrames({{spdy::SpdyFrameType::PING, absl::nullopt},
- {spdy::SpdyFrameType::WINDOW_UPDATE, absl::nullopt},
- {spdy::SpdyFrameType::DATA, 25},
- {spdy::SpdyFrameType::RST_STREAM, absl::nullopt},
- {spdy::SpdyFrameType::GOAWAY, 42},
- {spdy::SpdyFrameType::HEADERS, 19}}));
- EXPECT_THAT(
- frame_sequence,
- ContainsFrames(
+ EqualsFrames(
{spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
spdy::SpdyFrameType::GOAWAY, spdy::SpdyFrameType::HEADERS}));
+ EXPECT_THAT(
+ frame_sequence_view,
+ EqualsFrames(
+ {spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
+ spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
+ spdy::SpdyFrameType::GOAWAY, spdy::SpdyFrameType::HEADERS}));
+
+ // If the final frame type is removed the expectation fails, as there are
+ // bytes left to read.
+ EXPECT_THAT(
+ frame_sequence,
+ testing::Not(EqualsFrames(
+ {spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
+ spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
+ spdy::SpdyFrameType::GOAWAY})));
+ EXPECT_THAT(
+ frame_sequence_view,
+ testing::Not(EqualsFrames(
+ {spdy::SpdyFrameType::PING, spdy::SpdyFrameType::WINDOW_UPDATE,
+ spdy::SpdyFrameType::DATA, spdy::SpdyFrameType::RST_STREAM,
+ spdy::SpdyFrameType::GOAWAY})));
}
} // namespace