| #ifndef QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_ | 
 | #define QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_ | 
 |  | 
 | #include <cstdint> | 
 | #include <string> | 
 | #include <vector> | 
 |  | 
 | #include "absl/container/flat_hash_map.h" | 
 | #include "absl/strings/string_view.h" | 
 | #include "http2/adapter/data_source.h" | 
 | #include "http2/adapter/http2_protocol.h" | 
 | #include "http2/adapter/mock_http2_visitor.h" | 
 | #include "common/platform/api/quiche_export.h" | 
 | #include "common/platform/api/quiche_test.h" | 
 | #include "spdy/core/spdy_header_block.h" | 
 | #include "spdy/core/spdy_protocol.h" | 
 |  | 
 | namespace http2 { | 
 | namespace adapter { | 
 | namespace test { | 
 |  | 
 | class QUICHE_NO_EXPORT DataSavingVisitor | 
 |     : public testing::StrictMock<MockHttp2Visitor> { | 
 |  public: | 
 |   int64_t OnReadyToSend(absl::string_view data) override { | 
 |     if (has_write_error_) { | 
 |       return kSendError; | 
 |     } | 
 |     if (is_write_blocked_) { | 
 |       return kSendBlocked; | 
 |     } | 
 |     const size_t to_accept = std::min(send_limit_, data.size()); | 
 |     if (to_accept == 0) { | 
 |       return kSendBlocked; | 
 |     } | 
 |     absl::StrAppend(&data_, data.substr(0, to_accept)); | 
 |     return to_accept; | 
 |   } | 
 |  | 
 |   bool OnMetadataForStream(Http2StreamId stream_id, | 
 |                            absl::string_view metadata) override { | 
 |     const bool ret = testing::StrictMock<MockHttp2Visitor>::OnMetadataForStream( | 
 |         stream_id, metadata); | 
 |     if (ret) { | 
 |       auto result = | 
 |           metadata_map_.try_emplace(stream_id, std::vector<std::string>()); | 
 |       result.first->second.push_back(std::string(metadata)); | 
 |     } | 
 |     return ret; | 
 |   } | 
 |  | 
 |   const std::vector<std::string> GetMetadata(Http2StreamId stream_id) { | 
 |     auto it = metadata_map_.find(stream_id); | 
 |     if (it == metadata_map_.end()) { | 
 |       return {}; | 
 |     } else { | 
 |       return it->second; | 
 |     } | 
 |   } | 
 |  | 
 |   const std::string& data() { return data_; } | 
 |   void Clear() { data_.clear(); } | 
 |  | 
 |   void set_send_limit(size_t limit) { send_limit_ = limit; } | 
 |  | 
 |   bool is_write_blocked() const { return is_write_blocked_; } | 
 |   void set_is_write_blocked(bool value) { is_write_blocked_ = value; } | 
 |  | 
 |   void set_has_write_error() { has_write_error_ = true; } | 
 |  | 
 |  private: | 
 |   std::string data_; | 
 |   absl::flat_hash_map<Http2StreamId, std::vector<std::string>> metadata_map_; | 
 |   size_t send_limit_ = std::numeric_limits<size_t>::max(); | 
 |   bool is_write_blocked_ = false; | 
 |   bool has_write_error_ = false; | 
 | }; | 
 |  | 
 | // A test DataFrameSource. Starts out in the empty, blocked state. | 
 | class QUICHE_NO_EXPORT TestDataFrameSource : public DataFrameSource { | 
 |  public: | 
 |   TestDataFrameSource(Http2VisitorInterface& visitor, bool has_fin); | 
 |  | 
 |   void AppendPayload(absl::string_view payload); | 
 |   void EndData(); | 
 |   void SimulateError() { return_error_ = true; } | 
 |  | 
 |   std::pair<int64_t, bool> SelectPayloadLength(size_t max_length) override; | 
 |   bool Send(absl::string_view frame_header, size_t payload_length) override; | 
 |   bool send_fin() const override { return has_fin_; } | 
 |  | 
 |  private: | 
 |   Http2VisitorInterface& visitor_; | 
 |   std::vector<std::string> payload_fragments_; | 
 |   absl::string_view current_fragment_; | 
 |   // Whether the stream should end with the final frame of data. | 
 |   const bool has_fin_; | 
 |   // Whether |payload_fragments_| contains the final segment of data. | 
 |   bool end_data_ = false; | 
 |   // Whether SelectPayloadLength() should return an error. | 
 |   bool return_error_ = false; | 
 | }; | 
 |  | 
 | class QUICHE_NO_EXPORT TestMetadataSource : public MetadataSource { | 
 |  public: | 
 |   explicit TestMetadataSource(const spdy::SpdyHeaderBlock& entries); | 
 |  | 
 |   size_t NumFrames(size_t max_frame_size) const override { | 
 |     // Round up to the next frame. | 
 |     return (encoded_entries_.size() + max_frame_size - 1) / max_frame_size; | 
 |   } | 
 |   std::pair<int64_t, bool> Pack(uint8_t* dest, size_t dest_len) override; | 
 |  | 
 |  private: | 
 |   const std::string encoded_entries_; | 
 |   absl::string_view remaining_; | 
 | }; | 
 |  | 
 | // 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); | 
 |  | 
 | // Requires that frames match the specified types. | 
 | testing::Matcher<absl::string_view> EqualsFrames( | 
 |     std::vector<spdy::SpdyFrameType> types); | 
 |  | 
 | }  // namespace test | 
 | }  // namespace adapter | 
 | }  // namespace http2 | 
 |  | 
 | #endif  // QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_ |