diff --git a/envoy/stream_info/stream_info.h b/envoy/stream_info/stream_info.h index c81720053b047..7b51a3033cef9 100644 --- a/envoy/stream_info/stream_info.h +++ b/envoy/stream_info/stream_info.h @@ -310,6 +310,99 @@ struct BytesMeter { using BytesMeterSharedPtr = std::shared_ptr; +// TODO(alyssawilk) after landing this, remove all the duplicate getters and +// setters from StreamInfo. +class UpstreamInfo { +public: + virtual ~UpstreamInfo() = default; + + /** + * Dump the upstream info to the specified ostream. + * + * @param os the ostream to dump state to + * @param indent_level the depth, for pretty-printing. + * + * This function is called on Envoy fatal errors so should avoid memory allocation. + */ + virtual void dumpState(std::ostream& os, int indent_level = 0) const PURE; + + /** + * @param connection ID of the upstream connection. + */ + virtual void setUpstreamConnectionId(uint64_t id) PURE; + + /** + * @return the ID of the upstream connection, or absl::nullopt if not available. + */ + virtual absl::optional upstreamConnectionId() const PURE; + + /** + * @param connection_info sets the upstream ssl connection. + */ + virtual void + setUpstreamSslConnection(const Ssl::ConnectionInfoConstSharedPtr& ssl_connection_info) PURE; + + /** + * @return the upstream SSL connection. This will be nullptr if the upstream + * connection does not use SSL. + */ + virtual Ssl::ConnectionInfoConstSharedPtr upstreamSslConnection() const PURE; + + /** + * Sets the upstream timing information for this stream. This is useful for + * when multiple upstream requests are issued and we want to save timing + * information for the one that "wins". + */ + virtual void setUpstreamTiming(const UpstreamTiming& upstream_timing) PURE; + + /* + * @return the upstream timing for this stream + * */ + virtual UpstreamTiming& upstreamTiming() PURE; + virtual const UpstreamTiming& upstreamTiming() const PURE; + + /** + * @param upstream_local_address sets the local address of the upstream connection. Note that it + * can be different than the local address of the downstream connection. + */ + virtual void setUpstreamLocalAddress( + const Network::Address::InstanceConstSharedPtr& upstream_local_address) PURE; + + /** + * @return the upstream local address. + */ + virtual const Network::Address::InstanceConstSharedPtr& upstreamLocalAddress() const PURE; + + /** + * @param failure_reason the upstream transport failure reason. + */ + virtual void setUpstreamTransportFailureReason(absl::string_view failure_reason) PURE; + + /** + * @return const std::string& the upstream transport failure reason, e.g. certificate validation + * failed. + */ + virtual const std::string& upstreamTransportFailureReason() const PURE; + + /** + * @param host the selected upstream host for the request. + */ + virtual void setUpstreamHost(Upstream::HostDescriptionConstSharedPtr host) PURE; + + /** + * @return upstream host description. + */ + virtual Upstream::HostDescriptionConstSharedPtr upstreamHost() const PURE; + + /** + * Filter State object to be shared between upstream and downstream filters. + * @param pointer to upstream connections filter state. + * @return pointer to filter state to be used by upstream connections. + */ + virtual const FilterStateSharedPtr& upstreamFilterState() const PURE; + virtual void setUpstreamFilterState(const FilterStateSharedPtr& filter_state) PURE; +}; + /** * Additional information about a completed request for logging. */ @@ -422,13 +515,23 @@ class StreamInfo { */ virtual void setUpstreamTiming(const UpstreamTiming& upstream_timing) PURE; + /** + * Sets the upstream information for this stream. + */ + virtual void setUpstreamInfo(std::shared_ptr) PURE; + + /** + * Returns the upstream information for this stream. + */ + virtual std::shared_ptr upstreamInfo() PURE; + virtual OptRef upstreamInfo() const PURE; + /** * Returns the upstream timing information for this stream. * It is not expected that the fields in upstreamTiming() will be set until * the upstream request is complete. */ virtual UpstreamTiming& upstreamTiming() PURE; - virtual const UpstreamTiming& upstreamTiming() const PURE; /** * @return the duration between the first byte of the request was sent upstream and the start of diff --git a/source/common/router/upstream_request.cc b/source/common/router/upstream_request.cc index 3098174538746..213e71cb58a1f 100644 --- a/source/common/router/upstream_request.cc +++ b/source/common/router/upstream_request.cc @@ -427,10 +427,12 @@ void UpstreamRequest::onPoolReady( stream_info_.protocol(protocol.value()); } - upstream_timing_.upstream_connect_start_ = info.upstreamTiming().upstream_connect_start_; - upstream_timing_.upstream_connect_complete_ = info.upstreamTiming().upstream_connect_complete_; - upstream_timing_.upstream_handshake_complete_ = - info.upstreamTiming().upstream_handshake_complete_; + if (info.upstreamInfo().has_value()) { + auto& upstream_timing = info.upstreamInfo().value().get().upstreamTiming(); + upstream_timing_.upstream_connect_start_ = upstream_timing.upstream_connect_start_; + upstream_timing_.upstream_connect_complete_ = upstream_timing.upstream_connect_complete_; + upstream_timing_.upstream_handshake_complete_ = upstream_timing.upstream_handshake_complete_; + } stream_info_.setUpstreamFilterState(std::make_shared( info.filterState().parent()->parent(), StreamInfo::FilterState::LifeSpan::Request)); diff --git a/source/common/stream_info/stream_info_impl.h b/source/common/stream_info/stream_info_impl.h index f66f5e891de5f..bbf1bef50e4b8 100644 --- a/source/common/stream_info/stream_info_impl.h +++ b/source/common/stream_info/stream_info_impl.h @@ -34,6 +34,64 @@ const ReplacementMap& emptySpaceReplacement() { } // namespace +struct UpstreamInfoImpl : public UpstreamInfo { + void setUpstreamConnectionId(uint64_t id) override { upstream_connection_id_ = id; } + + absl::optional upstreamConnectionId() const override { return upstream_connection_id_; } + + void + setUpstreamSslConnection(const Ssl::ConnectionInfoConstSharedPtr& ssl_connection_info) override { + upstream_ssl_info_ = ssl_connection_info; + } + + Ssl::ConnectionInfoConstSharedPtr upstreamSslConnection() const override { + return upstream_ssl_info_; + } + void setUpstreamTiming(const UpstreamTiming& upstream_timing) override { + upstream_timing_ = upstream_timing; + } + UpstreamTiming& upstreamTiming() override { return upstream_timing_; } + const UpstreamTiming& upstreamTiming() const override { return upstream_timing_; } + const Network::Address::InstanceConstSharedPtr& upstreamLocalAddress() const override { + return upstream_local_address_; + } + void setUpstreamLocalAddress( + const Network::Address::InstanceConstSharedPtr& upstream_local_address) override { + upstream_local_address_ = upstream_local_address; + } + void setUpstreamTransportFailureReason(absl::string_view failure_reason) override { + upstream_transport_failure_reason_ = std::string(failure_reason); + } + const std::string& upstreamTransportFailureReason() const override { + return upstream_transport_failure_reason_; + } + void setUpstreamHost(Upstream::HostDescriptionConstSharedPtr host) override { + upstream_host_ = host; + } + const FilterStateSharedPtr& upstreamFilterState() const override { + return upstream_filter_state_; + } + void setUpstreamFilterState(const FilterStateSharedPtr& filter_state) override { + upstream_filter_state_ = filter_state; + } + + Upstream::HostDescriptionConstSharedPtr upstreamHost() const override { return upstream_host_; } + + void dumpState(std::ostream& os, int indent_level = 0) const override { + const char* spaces = spacesForLevel(indent_level); + os << spaces << "UpstreamInfoImpl " << this << DUMP_OPTIONAL_MEMBER(upstream_connection_id_) + << "\n"; + } + + Upstream::HostDescriptionConstSharedPtr upstream_host_{}; + Network::Address::InstanceConstSharedPtr upstream_local_address_; + UpstreamTiming upstream_timing_; + Ssl::ConnectionInfoConstSharedPtr upstream_ssl_info_; + absl::optional upstream_connection_id_; + std::string upstream_transport_failure_reason_; + FilterStateSharedPtr upstream_filter_state_; +}; + struct StreamInfoImpl : public StreamInfo { StreamInfoImpl( TimeSource& time_source, @@ -71,9 +129,23 @@ struct StreamInfoImpl : public StreamInfo { start_time_monotonic_); } - void setUpstreamConnectionId(uint64_t id) override { upstream_connection_id_ = id; } + void maybeCreateUpstreamInfo() { + if (!upstream_info_) { + upstream_info_ = std::make_shared(); + } + } - absl::optional upstreamConnectionId() const override { return upstream_connection_id_; } + void setUpstreamConnectionId(uint64_t id) override { + maybeCreateUpstreamInfo(); + upstream_info_->setUpstreamConnectionId(id); + } + + absl::optional upstreamConnectionId() const override { + if (!upstream_info_) { + return absl::nullopt; + } + return upstream_info_->upstreamConnectionId(); + } absl::optional lastDownstreamRxByteReceived() const override { if (!downstream_timing_.has_value()) { @@ -83,26 +155,49 @@ struct StreamInfoImpl : public StreamInfo { } void setUpstreamTiming(const UpstreamTiming& upstream_timing) override { - upstream_timing_ = upstream_timing; + maybeCreateUpstreamInfo(); + upstream_info_->setUpstreamTiming(upstream_timing); } - UpstreamTiming& upstreamTiming() override { return upstream_timing_; } - const UpstreamTiming& upstreamTiming() const override { return upstream_timing_; } + void setUpstreamInfo(std::shared_ptr info) override { upstream_info_ = info; } + std::shared_ptr upstreamInfo() override { return upstream_info_; } + OptRef upstreamInfo() const override { + if (!upstream_info_) { + return {}; + } + return *upstream_info_; + } + UpstreamTiming& upstreamTiming() override { + maybeCreateUpstreamInfo(); + return upstream_info_->upstreamTiming(); + } absl::optional firstUpstreamTxByteSent() const override { - return duration(upstream_timing_.first_upstream_tx_byte_sent_); + if (!upstream_info_) { + return absl::nullopt; + } + return duration(upstream_info_->upstreamTiming().first_upstream_tx_byte_sent_); } absl::optional lastUpstreamTxByteSent() const override { - return duration(upstream_timing_.last_upstream_tx_byte_sent_); + if (!upstream_info_) { + return absl::nullopt; + } + return duration(upstream_info_->upstreamTiming().last_upstream_tx_byte_sent_); } absl::optional firstUpstreamRxByteReceived() const override { - return duration(upstream_timing_.first_upstream_rx_byte_received_); + if (!upstream_info_) { + return absl::nullopt; + } + return duration(upstream_info_->upstreamTiming().first_upstream_rx_byte_received_); } absl::optional lastUpstreamRxByteReceived() const override { - return duration(upstream_timing_.last_upstream_rx_byte_received_); + if (!upstream_info_) { + return absl::nullopt; + } + return duration(upstream_info_->upstreamTiming().last_upstream_rx_byte_received_); } absl::optional firstDownstreamTxByteSent() const override { @@ -180,10 +275,16 @@ struct StreamInfoImpl : public StreamInfo { uint64_t responseFlags() const override { return response_flags_; } void onUpstreamHostSelected(Upstream::HostDescriptionConstSharedPtr host) override { - upstream_host_ = host; + maybeCreateUpstreamInfo(); + upstream_info_->setUpstreamHost(host); } - Upstream::HostDescriptionConstSharedPtr upstreamHost() const override { return upstream_host_; } + Upstream::HostDescriptionConstSharedPtr upstreamHost() const override { + if (!upstream_info_) { + return nullptr; + } + return upstream_info_->upstreamHost(); + } void setRouteName(absl::string_view route_name) override { route_name_ = std::string(route_name); @@ -193,11 +294,15 @@ struct StreamInfoImpl : public StreamInfo { void setUpstreamLocalAddress( const Network::Address::InstanceConstSharedPtr& upstream_local_address) override { - upstream_local_address_ = upstream_local_address; + maybeCreateUpstreamInfo(); + upstream_info_->setUpstreamLocalAddress(upstream_local_address); } const Network::Address::InstanceConstSharedPtr& upstreamLocalAddress() const override { - return upstream_local_address_; + if (!upstream_info_) { + return legacy_upstream_local_address_; + } + return upstream_info_->upstreamLocalAddress(); } bool healthCheck() const override { return health_check_request_; } @@ -209,11 +314,12 @@ struct StreamInfoImpl : public StreamInfo { } void setUpstreamSslConnection(const Ssl::ConnectionInfoConstSharedPtr& connection_info) override { - upstream_ssl_info_ = connection_info; + maybeCreateUpstreamInfo(); + upstream_info_->setUpstreamSslConnection(connection_info); } Ssl::ConnectionInfoConstSharedPtr upstreamSslConnection() const override { - return upstream_ssl_info_; + return upstream_info_ ? upstream_info_->upstreamSslConnection() : nullptr; } Router::RouteConstSharedPtr route() const override { return route_; } @@ -229,18 +335,26 @@ struct StreamInfoImpl : public StreamInfo { const FilterState& filterState() const override { return *filter_state_; } const FilterStateSharedPtr& upstreamFilterState() const override { - return upstream_filter_state_; + if (!upstream_info_) { + return legacy_upstream_filter_state_; + } + return upstream_info_->upstreamFilterState(); } void setUpstreamFilterState(const FilterStateSharedPtr& filter_state) override { - upstream_filter_state_ = filter_state; + maybeCreateUpstreamInfo(); + return upstream_info_->setUpstreamFilterState(filter_state); } void setUpstreamTransportFailureReason(absl::string_view failure_reason) override { - upstream_transport_failure_reason_ = std::string(failure_reason); + maybeCreateUpstreamInfo(); + upstream_info_->setUpstreamTransportFailureReason(failure_reason); } const std::string& upstreamTransportFailureReason() const override { - return upstream_transport_failure_reason_; + if (!upstream_info_) { + return legacy_upstream_transport_failure_reason_; + } + return upstream_info_->upstreamTransportFailureReason(); } void setRequestHeaders(const Http::RequestHeaderMap& headers) override { @@ -262,10 +376,11 @@ struct StreamInfoImpl : public StreamInfo { void dumpState(std::ostream& os, int indent_level = 0) const { const char* spaces = spacesForLevel(indent_level); - os << spaces << "StreamInfoImpl " << this << DUMP_OPTIONAL_MEMBER(upstream_connection_id_) - << DUMP_OPTIONAL_MEMBER(protocol_) << DUMP_OPTIONAL_MEMBER(response_code_) - << DUMP_OPTIONAL_MEMBER(response_code_details_) << DUMP_OPTIONAL_MEMBER(attempt_count_) - << DUMP_MEMBER(health_check_request_) << DUMP_MEMBER(route_name_) << "\n"; + os << spaces << "StreamInfoImpl " << this << DUMP_OPTIONAL_MEMBER(protocol_) + << DUMP_OPTIONAL_MEMBER(response_code_) << DUMP_OPTIONAL_MEMBER(response_code_details_) + << DUMP_OPTIONAL_MEMBER(attempt_count_) << DUMP_MEMBER(health_check_request_) + << DUMP_MEMBER(route_name_); + DUMP_DETAILS(upstream_info_); } void setUpstreamClusterInfo( @@ -282,7 +397,6 @@ struct StreamInfoImpl : public StreamInfo { } const std::string& filterChainName() const override { return filter_chain_name_; } - void setAttemptCount(uint32_t attempt_count) override { attempt_count_ = attempt_count; } absl::optional attemptCount() const override { return attempt_count_; } @@ -301,7 +415,6 @@ struct StreamInfoImpl : public StreamInfo { upstream_bytes_meter->addWireBytesReceived(upstream_bytes_meter_->wireBytesReceived()); upstream_bytes_meter->addHeaderBytesSent(upstream_bytes_meter_->headerBytesSent()); upstream_bytes_meter->addHeaderBytesReceived(upstream_bytes_meter_->headerBytesReceived()); - upstream_bytes_meter_ = upstream_bytes_meter; } @@ -323,14 +436,12 @@ struct StreamInfoImpl : public StreamInfo { absl::optional response_code_details_; absl::optional connection_termination_details_; uint64_t response_flags_{}; - Upstream::HostDescriptionConstSharedPtr upstream_host_{}; bool health_check_request_{}; Router::RouteConstSharedPtr route_; envoy::config::core::v3::Metadata metadata_{}; FilterStateSharedPtr filter_state_; - FilterStateSharedPtr upstream_filter_state_; + FilterStateSharedPtr legacy_upstream_filter_state_; std::string route_name_; - absl::optional upstream_connection_id_; absl::optional attempt_count_; private: @@ -352,17 +463,16 @@ struct StreamInfoImpl : public StreamInfo { : emptyDownstreamAddressProvider()), trace_reason_(Tracing::Reason::NotTraceable) {} + std::shared_ptr upstream_info_; uint64_t bytes_received_{}; uint64_t bytes_sent_{}; - Network::Address::InstanceConstSharedPtr upstream_local_address_; + Network::Address::InstanceConstSharedPtr legacy_upstream_local_address_; const Network::ConnectionInfoProviderSharedPtr downstream_connection_info_provider_; - Ssl::ConnectionInfoConstSharedPtr upstream_ssl_info_; std::string requested_server_name_; const Http::RequestHeaderMap* request_headers_{}; Http::RequestIdStreamInfoProviderSharedPtr request_id_provider_; absl::optional downstream_timing_; - UpstreamTiming upstream_timing_; - std::string upstream_transport_failure_reason_; + std::string legacy_upstream_transport_failure_reason_; absl::optional upstream_cluster_info_; std::string filter_chain_name_; Tracing::Reason trace_reason_; diff --git a/test/common/access_log/access_log_impl_test.cc b/test/common/access_log/access_log_impl_test.cc index 93cf53e0baf5d..d2d4c291f110d 100644 --- a/test/common/access_log/access_log_impl_test.cc +++ b/test/common/access_log/access_log_impl_test.cc @@ -106,8 +106,8 @@ name: accesslog EXPECT_CALL(*file_, write(_)); auto cluster = std::make_shared>(); - stream_info_.upstream_host_ = - Upstream::makeTestHostDescription(cluster, "tcp://10.0.0.5:1234", simTime()); + stream_info_.onUpstreamHostSelected( + Upstream::makeTestHostDescription(cluster, "tcp://10.0.0.5:1234", simTime())); stream_info_.setResponseFlag(StreamInfo::ResponseFlag::DownstreamConnectionTermination); log->log(&request_headers_, &response_headers_, &response_trailers_, stream_info_); @@ -217,8 +217,8 @@ name: accesslog TEST_F(AccessLogImplTest, UpstreamHost) { auto cluster = std::make_shared>(); - stream_info_.upstream_host_ = - Upstream::makeTestHostDescription(cluster, "tcp://10.0.0.5:1234", simTime()); + stream_info_.onUpstreamHostSelected( + Upstream::makeTestHostDescription(cluster, "tcp://10.0.0.5:1234", simTime())); const std::string yaml = R"EOF( name: accesslog diff --git a/test/common/stream_info/stream_info_impl_test.cc b/test/common/stream_info/stream_info_impl_test.cc index 40343f1c04224..74ad2c1dcbabe 100644 --- a/test/common/stream_info/stream_info_impl_test.cc +++ b/test/common/stream_info/stream_info_impl_test.cc @@ -137,7 +137,9 @@ TEST_F(StreamInfoImplTest, MiscSettersAndGetters) { { StreamInfoImpl stream_info(Http::Protocol::Http2, test_time_.timeSystem(), nullptr); + EXPECT_EQ(nullptr, stream_info.upstreamInfo()); EXPECT_EQ(Http::Protocol::Http2, stream_info.protocol().value()); + EXPECT_FALSE(stream_info.upstreamConnectionId().has_value()); stream_info.protocol(Http::Protocol::Http10); EXPECT_EQ(Http::Protocol::Http10, stream_info.protocol().value()); @@ -147,6 +149,11 @@ TEST_F(StreamInfoImplTest, MiscSettersAndGetters) { ASSERT_TRUE(stream_info.responseCode()); EXPECT_EQ(200, stream_info.responseCode().value()); + EXPECT_FALSE(stream_info.attemptCount().has_value()); + stream_info.setAttemptCount(93); + ASSERT_TRUE(stream_info.attemptCount().has_value()); + EXPECT_EQ(stream_info.attemptCount().value(), 93); + EXPECT_FALSE(stream_info.responseCodeDetails().has_value()); stream_info.setResponseCodeDetails(ResponseCodeDetails::get().ViaUpstream); ASSERT_TRUE(stream_info.responseCodeDetails().has_value()); @@ -177,6 +184,7 @@ TEST_F(StreamInfoImplTest, MiscSettersAndGetters) { FilterState::LifeSpan::FilterChain); EXPECT_EQ(1, stream_info.filterState()->getDataReadOnly("test").access()); + EXPECT_EQ(nullptr, stream_info.upstreamFilterState()); stream_info.setUpstreamFilterState(stream_info.filterState()); EXPECT_EQ(1, stream_info.upstreamFilterState()->getDataReadOnly("test").access()); @@ -198,6 +206,11 @@ TEST_F(StreamInfoImplTest, MiscSettersAndGetters) { stream_info.setUpstreamConnectionId(12345); ASSERT_TRUE(stream_info.upstreamConnectionId().has_value()); EXPECT_EQ(12345, stream_info.upstreamConnectionId().value()); + + std::shared_ptr new_info = std::make_shared(); + EXPECT_NE(stream_info.upstreamInfo(), new_info); + stream_info.setUpstreamInfo(new_info); + EXPECT_EQ(stream_info.upstreamInfo(), new_info); } } @@ -266,6 +279,24 @@ TEST_F(StreamInfoImplTest, Details) { EXPECT_EQ(stream_info.responseCodeDetails().value(), "two_words"); } +TEST(UpstreamInfoImplTest, DumpState) { + UpstreamInfoImpl upstream_info; + + { + std::stringstream out; + upstream_info.dumpState(out, 0); + std::string state = out.str(); + EXPECT_THAT(state, testing::HasSubstr("upstream_connection_id_: null")); + } + upstream_info.setUpstreamConnectionId(5); + { + std::stringstream out; + upstream_info.dumpState(out, 0); + std::string state = out.str(); + EXPECT_THAT(state, testing::HasSubstr("upstream_connection_id_: 5")); + } +} + } // namespace } // namespace StreamInfo } // namespace Envoy diff --git a/test/fuzz/utility.h b/test/fuzz/utility.h index 1fc315ab732fe..6647c6cf4d591 100644 --- a/test/fuzz/utility.h +++ b/test/fuzz/utility.h @@ -157,7 +157,7 @@ inline std::unique_ptr fromStreamInfo(const test::fuzz::StreamIn auto upstream_metadata = std::make_shared( replaceInvalidStringValues(stream_info.upstream_metadata())); ON_CALL(*upstream_host, metadata()).WillByDefault(testing::Return(upstream_metadata)); - test_stream_info->upstream_host_ = upstream_host; + test_stream_info->onUpstreamHostSelected(upstream_host); auto address = stream_info.has_address() ? Envoy::Network::Address::resolveProtoAddress(stream_info.address()) : Network::Utility::resolveUrl("tcp://10.0.0.1:443"); diff --git a/test/mocks/stream_info/mocks.cc b/test/mocks/stream_info/mocks.cc index 4bdd1eaba8632..3bc5473c55385 100644 --- a/test/mocks/stream_info/mocks.cc +++ b/test/mocks/stream_info/mocks.cc @@ -142,7 +142,7 @@ MockStreamInfo::MockStreamInfo() downstream_bytes_meter_ = downstream_bytes_meter; })); ON_CALL(*this, upstreamTiming()).WillByDefault(ReturnRef(upstream_timing_)); - ON_CALL(Const(*this), upstreamTiming()).WillByDefault(ReturnRef(upstream_timing_)); + ON_CALL(Const(*this), upstreamTiming()).WillByDefault(Return(upstream_timing_)); } MockStreamInfo::~MockStreamInfo() = default; diff --git a/test/mocks/stream_info/mocks.h b/test/mocks/stream_info/mocks.h index 115a0f283c39d..4f96a1d16ff4b 100644 --- a/test/mocks/stream_info/mocks.h +++ b/test/mocks/stream_info/mocks.h @@ -31,8 +31,11 @@ class MockStreamInfo : public StreamInfo { MOCK_METHOD(MonotonicTime, startTimeMonotonic, (), (const)); MOCK_METHOD(absl::optional, lastDownstreamRxByteReceived, (), (const)); MOCK_METHOD(void, setUpstreamTiming, (const UpstreamTiming&)); + MOCK_METHOD(void, setUpstreamInfo, (std::shared_ptr)); + MOCK_METHOD(std::shared_ptr, upstreamInfo, ()); + MOCK_METHOD(OptRef, upstreamInfo, (), (const)); MOCK_METHOD(UpstreamTiming&, upstreamTiming, ()); - MOCK_METHOD(const UpstreamTiming&, upstreamTiming, (), (const)); + MOCK_METHOD(OptRef, upstreamTiming, (), (const)); MOCK_METHOD(absl::optional, firstUpstreamTxByteSent, (), (const)); MOCK_METHOD(void, onFirstUpstreamTxByteSent, ()); MOCK_METHOD(absl::optional, lastUpstreamTxByteSent, (), (const));