TEST_F(HttpConnectionManagerImplTest, FilterSetRouteToDelegatingRouteWithClusterOverride) {
  setup(false, "");
  setupFilterChain(2, 0);

  // Cluster mocks: default and foo
  const std::string default_cluster_name = "default";
  const std::string foo_cluster_name = "foo";

  std::shared_ptr<Upstream::MockThreadLocalCluster> default_cluster =
      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
  EXPECT_CALL(cluster_manager_, getThreadLocalCluster(absl::string_view{default_cluster_name}))
      .Times(1)
      .WillRepeatedly(Return(default_cluster.get()));

  std::shared_ptr<Upstream::MockThreadLocalCluster> foo_cluster =
      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
  EXPECT_CALL(cluster_manager_, getThreadLocalCluster(absl::string_view{foo_cluster_name}))
      .Times(1)
      .WillRepeatedly(Return(foo_cluster.get()));

  // Route mock: default
  std::shared_ptr<Router::MockRoute> default_route =
      std::make_shared<NiceMock<Router::MockRoute>>();
  EXPECT_CALL(default_route->route_entry_, clusterName())
      .Times(2) // Expected call twice: once from refreshCachedRoute, once from EXPECT_EQ macro
      .WillRepeatedly(ReturnRef(default_cluster_name));

  // RouteConstSharedPtr of DelegatingRoute for foo
  // Initialization separate from declaration to be in scope for both decoder_filters_
  std::shared_ptr<const Router::ExampleDerivedDelegatingRoute> foo_route_override(nullptr);

  // Route config mock
  EXPECT_CALL(*route_config_provider_.route_config_, route(_, _, _, _))
      .WillOnce(Return(default_route));

  // Filter that performs setRoute (sets cached_route_ & cached_cluster_info_)
  EXPECT_CALL(*decoder_filters_[0], decodeHeaders(_, true))
      .WillOnce(InvokeWithoutArgs([&]() -> FilterHeadersStatus {
        // Calls ConnectionManagerImpl::ActiveStream::route(cb), which calls
        // refreshCachedRoute(cb), which (1) calls route_config_->route(_, _, _, _) mock to set
        // default_route as cached_route_, and (2) calls getThreadLocalCluster mock to set
        // cached_cluster_info_.
        EXPECT_EQ(default_route, decoder_filters_[0]->callbacks_->route());
        EXPECT_EQ(default_cluster_name,
                  decoder_filters_[0]->callbacks_->route()->routeEntry()->clusterName());
        EXPECT_EQ(default_route->routeEntry(),
                  decoder_filters_[0]->callbacks_->streamInfo().routeEntry());
        EXPECT_EQ(default_cluster->info(), decoder_filters_[0]->callbacks_->clusterInfo());

        // Instantiate a DelegatingRoute child class object and invoke setRoute from
        // StreamFilterCallbacks to manually override the cached route for the current request.
        foo_route_override = std::make_shared<Router::ExampleDerivedDelegatingRoute>(
            decoder_filters_[0]->callbacks_->route(), foo_cluster_name);
        decoder_filters_[0]->callbacks_->setRoute(foo_route_override);

        return FilterHeadersStatus::Continue;
      }));
  EXPECT_CALL(*decoder_filters_[0], decodeComplete());

  // Router filter
  EXPECT_CALL(*decoder_filters_[1], decodeHeaders(_, true))
      .WillOnce(InvokeWithoutArgs([&]() -> FilterHeadersStatus {
        // Returns cached_route, does not invoke route(cb)
        EXPECT_EQ(foo_route_override, decoder_filters_[1]->callbacks_->route());
        // Note: The route filter determines the finalized route's upstream cluster name via
        // routeEntry()->clusterName(), so that's the key piece to check.
        // This should directly call the ExampleDerivedDelegatingRouteEntry overridden
        // clusterName() method.
        EXPECT_EQ(foo_cluster_name,
                  decoder_filters_[1]->callbacks_->route()->routeEntry()->clusterName());
        EXPECT_EQ(foo_route_override->routeEntry(),
                  decoder_filters_[1]->callbacks_->streamInfo().routeEntry());
        // Tests that setRoute correctly sets cached_cluster_info_
        EXPECT_EQ(foo_cluster->info(), decoder_filters_[1]->callbacks_->clusterInfo());

        return FilterHeadersStatus::StopIteration;
      }));
  EXPECT_CALL(*decoder_filters_[1], decodeComplete());

  // Kick off the incoming data. end_stream set to true to indicate this is a header only request.
  startRequest(true);

  // Clean up.
  expectOnDestroy();
  filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose);
}
TEST_F(HttpConnectionManagerImplTest, FilterSetRouteToDelegatingRouteWithClusterOverride) {
  setup(false, "");
  setupFilterChain(2, 0);

   
  const std::string default_cluster_name = "default";
  const std::string foo_cluster_name = "foo";

  std::shared_ptr<Upstream::MockThreadLocalCluster> default_cluster =
      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
  EXPECT_CALL(cluster_manager_, getThreadLocalCluster(absl::string_view{default_cluster_name}))
      .Times(1)
      .WillRepeatedly(Return(default_cluster.get()));

  std::shared_ptr<Upstream::MockThreadLocalCluster> foo_cluster =
      std::make_shared<NiceMock<Upstream::MockThreadLocalCluster>>();
  EXPECT_CALL(cluster_manager_, getThreadLocalCluster(absl::string_view{foo_cluster_name}))
      .Times(1)
      .WillRepeatedly(Return(foo_cluster.get()));

   
  std::shared_ptr<Router::MockRoute> default_route =
      std::make_shared<NiceMock<Router::MockRoute>>();
  EXPECT_CALL(default_route->route_entry_, clusterName())
      .Times(2)  
      .WillRepeatedly(ReturnRef(default_cluster_name));

   
   
  std::shared_ptr<const Router::ExampleDerivedDelegatingRoute> foo_route_override(nullptr);

   
  EXPECT_CALL(*route_config_provider_.route_config_, route(_, _, _, _))
      .WillOnce(Return(default_route));

   
  EXPECT_CALL(*decoder_filters_[0], decodeHeaders(_, true))
      .WillOnce(InvokeWithoutArgs([&]() -> FilterHeadersStatus {
         
         
         
         
        EXPECT_EQ(default_route, decoder_filters_[0]->callbacks_->route());
        EXPECT_EQ(default_cluster_name,
                  decoder_filters_[0]->callbacks_->route()->routeEntry()->clusterName());
        EXPECT_EQ(default_route->routeEntry(),
                  decoder_filters_[0]->callbacks_->streamInfo().routeEntry());
        EXPECT_EQ(default_cluster->info(), decoder_filters_[0]->callbacks_->clusterInfo());

         
         
        foo_route_override = std::make_shared<Router::ExampleDerivedDelegatingRoute>(
            decoder_filters_[0]->callbacks_->route(), foo_cluster_name);
        decoder_filters_[0]->callbacks_->setRoute(foo_route_override);

        return FilterHeadersStatus::Continue;
      }));
  EXPECT_CALL(*decoder_filters_[0], decodeComplete());

   
  EXPECT_CALL(*decoder_filters_[1], decodeHeaders(_, true))
      .WillOnce(InvokeWithoutArgs([&]() -> FilterHeadersStatus {
         
        EXPECT_EQ(foo_route_override, decoder_filters_[1]->callbacks_->route());
         
         
         
         
        EXPECT_EQ(foo_cluster_name,
                  decoder_filters_[1]->callbacks_->route()->routeEntry()->clusterName());
        EXPECT_EQ(foo_route_override->routeEntry(),
                  decoder_filters_[1]->callbacks_->streamInfo().routeEntry());
         
        EXPECT_EQ(foo_cluster->info(), decoder_filters_[1]->callbacks_->clusterInfo());

        return FilterHeadersStatus::StopIteration;
      }));
  EXPECT_CALL(*decoder_filters_[1], decodeComplete());

   
  startRequest(true);

   
  expectOnDestroy();
  filter_callbacks_.connection_.raiseEvent(Network::ConnectionEvent::RemoteClose);
}