TEST_F(RouterTest, UpstreamTimingSingleRequest) {
  NiceMock<Http::MockRequestEncoder> encoder;
  Http::ResponseDecoder* response_decoder = nullptr;
  EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_, newStream(_, _))
      .WillOnce(Invoke(
          [&](Http::ResponseDecoder& decoder,
              Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* {
            response_decoder = &decoder;
            callbacks.onPoolReady(encoder, cm_.thread_local_cluster_.conn_pool_.host_,
                                  upstream_stream_info_, Http::Protocol::Http10);
            return nullptr;
          }));
  expectResponseTimerCreate();

  StreamInfo::StreamInfoImpl stream_info(test_time_.timeSystem(), nullptr);
  ON_CALL(callbacks_, streamInfo()).WillByDefault(ReturnRef(stream_info));
  EXPECT_EQ(nullptr, stream_info.upstreamInfo());

  Http::TestRequestHeaderMapImpl headers{};
  HttpTestUtility::addDefaultHeaders(headers);
  router_.decodeHeaders(headers, false);

  test_time_.advanceTimeWait(std::chrono::milliseconds(32));
  Buffer::OwnedImpl data;
  router_.decodeData(data, true);
  EXPECT_EQ(1U,
            callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value());

  Http::ResponseHeaderMapPtr response_headers(
      new Http::TestResponseHeaderMapImpl{{":status", "503"}});
  // NOLINTNEXTLINE(clang-analyzer-core.CallAndMessage)
  response_decoder->decodeHeaders(std::move(response_headers), false);
  test_time_.advanceTimeWait(std::chrono::milliseconds(43));

  // Upstream timing data is now available live.
  ASSERT_NE(nullptr, stream_info.upstreamInfo());
  auto& upstream_timing = stream_info.upstreamInfo()->upstreamTiming();
  EXPECT_TRUE(upstream_timing.first_upstream_tx_byte_sent_.has_value());
  EXPECT_TRUE(upstream_timing.last_upstream_tx_byte_sent_.has_value());
  EXPECT_TRUE(upstream_timing.first_upstream_rx_byte_received_.has_value());
  EXPECT_FALSE(upstream_timing.last_upstream_rx_byte_received_.has_value());

  response_decoder->decodeData(data, true);

  // Now all these should be set.
  EXPECT_TRUE(upstream_timing.first_upstream_tx_byte_sent_.has_value());
  EXPECT_TRUE(upstream_timing.last_upstream_tx_byte_sent_.has_value());
  EXPECT_TRUE(upstream_timing.first_upstream_rx_byte_received_.has_value());
  EXPECT_TRUE(upstream_timing.last_upstream_rx_byte_received_.has_value());

  // Timings should match our sleep() calls.
  EXPECT_EQ(upstream_timing.last_upstream_rx_byte_received_.value() -
                upstream_timing.first_upstream_rx_byte_received_.value(),
            std::chrono::milliseconds(43));
  EXPECT_EQ(upstream_timing.last_upstream_tx_byte_sent_.value() -
                upstream_timing.first_upstream_tx_byte_sent_.value(),
            std::chrono::milliseconds(32));
}
TEST_F(RouterTest, UpstreamTimingSingleRequest) {
  NiceMock<Http::MockRequestEncoder> encoder;
  Http::ResponseDecoder* response_decoder = nullptr;
  EXPECT_CALL(cm_.thread_local_cluster_.conn_pool_, newStream(_, _))
      .WillOnce(Invoke(
          [&](Http::ResponseDecoder& decoder,
              Http::ConnectionPool::Callbacks& callbacks) -> Http::ConnectionPool::Cancellable* {
            response_decoder = &decoder;
            callbacks.onPoolReady(encoder, cm_.thread_local_cluster_.conn_pool_.host_,
                                  upstream_stream_info_, Http::Protocol::Http10);
            return nullptr;
          }));
  expectResponseTimerCreate();

  StreamInfo::StreamInfoImpl stream_info(test_time_.timeSystem(), nullptr);
  ON_CALL(callbacks_, streamInfo()).WillByDefault(ReturnRef(stream_info));
  EXPECT_EQ(nullptr, stream_info.upstreamInfo());

  Http::TestRequestHeaderMapImpl headers{};
  HttpTestUtility::addDefaultHeaders(headers);
  router_.decodeHeaders(headers, false);

  test_time_.advanceTimeWait(std::chrono::milliseconds(32));
  Buffer::OwnedImpl data;
  router_.decodeData(data, true);
  EXPECT_EQ(1U,
            callbacks_.route_->route_entry_.virtual_cluster_.stats().upstream_rq_total_.value());

  Http::ResponseHeaderMapPtr response_headers(
      new Http::TestResponseHeaderMapImpl{{":status", "503"}});
   
  response_decoder->decodeHeaders(std::move(response_headers), false);
  test_time_.advanceTimeWait(std::chrono::milliseconds(43));

   
  ASSERT_NE(nullptr, stream_info.upstreamInfo());
  auto& upstream_timing = stream_info.upstreamInfo()->upstreamTiming();
  EXPECT_TRUE(upstream_timing.first_upstream_tx_byte_sent_.has_value());
  EXPECT_TRUE(upstream_timing.last_upstream_tx_byte_sent_.has_value());
  EXPECT_TRUE(upstream_timing.first_upstream_rx_byte_received_.has_value());
  EXPECT_FALSE(upstream_timing.last_upstream_rx_byte_received_.has_value());

  response_decoder->decodeData(data, true);

   
  EXPECT_TRUE(upstream_timing.first_upstream_tx_byte_sent_.has_value());
  EXPECT_TRUE(upstream_timing.last_upstream_tx_byte_sent_.has_value());
  EXPECT_TRUE(upstream_timing.first_upstream_rx_byte_received_.has_value());
  EXPECT_TRUE(upstream_timing.last_upstream_rx_byte_received_.has_value());

   
  EXPECT_EQ(upstream_timing.last_upstream_rx_byte_received_.value() -
                upstream_timing.first_upstream_rx_byte_received_.value(),
            std::chrono::milliseconds(43));
  EXPECT_EQ(upstream_timing.last_upstream_tx_byte_sent_.value() -
                upstream_timing.first_upstream_tx_byte_sent_.value(),
            std::chrono::milliseconds(32));
}