Repository: envoyproxy/envoy
File: test/common/upstream/load_stats_reporter_test.cc (C++)

Code before:
  load_stats_reporter_->onRemoteClose(Grpc::Status::WellKnownGrpcStatus::Canceled, "");
  EXPECT_CALL(*async_client_, startRaw(_, _, _, _)).WillOnce(Return(&async_stream_));
  expectSendMessage({});
  retry_timer_cb_();
  EXPECT_EQ(load_stats_reporter_->getStats().errors_.value(), 1);
  EXPECT_EQ(load_stats_reporter_->getStats().retries_.value(), 1);
}

// Validate that errors stat is not incremented for a graceful stream termination.
TEST_F(LoadStatsReporterTest, RemoteStreamGracefulClose) {
  EXPECT_CALL(*async_client_, startRaw(_, _, _, _)).WillOnce(Return(&async_stream_));
  expectSendMessage({});
  createLoadStatsReporter();
  EXPECT_CALL(*response_timer_, disableTimer());
  EXPECT_CALL(*retry_timer_, enableTimer(_, _));
  load_stats_reporter_->onRemoteClose(Grpc::Status::WellKnownGrpcStatus::Ok, "");
  EXPECT_CALL(*async_client_, startRaw(_, _, _, _)).WillOnce(Return(&async_stream_));
  expectSendMessage({});
  retry_timer_cb_();
  EXPECT_EQ(load_stats_reporter_->getStats().errors_.value(), 0);
  EXPECT_EQ(load_stats_reporter_->getStats().retries_.value(), 1);
}

// Validate that when
// "envoy.reloadable_features.report_load_when_rq_active_is_non_zero" is set and
// rq_active is non-zero, a load report is sent even if rq_issued is 0.
TEST_F(LoadStatsReporterTest, ReportLoadWhenRqActiveIsNonZero) {
  TestScopedRuntime scoped_runtime;
  scoped_runtime.mergeValues(
      {{"envoy.reloadable_features.report_load_when_rq_active_is_non_zero", "true"}});

  EXPECT_CALL(*async_client_, startRaw(_, _, _, _)).WillOnce(Return(&async_stream_));
  expectSendMessage({});
  createLoadStatsReporter();
  time_system_.setMonotonicTime(std::chrono::microseconds(100));

  NiceMock<MockClusterMockPrioritySet> cluster;
  MockHostSet& host_set = *cluster.prioritySet().getMockHostSet(0);
  ::envoy::config::core::v3::Locality locality;
  locality.set_region("test_region");

  HostSharedPtr host1 = makeTestHost("host1", locality);
  host_set.hosts_per_locality_ = makeHostsPerLocality({{host1}});

  // Set rq_active to non-zero, rq_issued to zero.
  host1->stats().rq_active_.set(5);
  // Do not call addStats to ensure rq_issued and rq_success remain 0.

  cluster.info_->eds_service_name_ = "eds_service_for_foo";

  ON_CALL(cm_, getActiveCluster("foo"))

Review comment (suggestion):
```suggestion
// Validate that when rq_active is non-zero, a load report is sent even if rq_issued is 0.
```

Code after:
  load_stats_reporter_->onRemoteClose(Grpc::Status::WellKnownGrpcStatus::Canceled, "");
  EXPECT_CALL(*async_client_, startRaw(_, _, _, _)).WillOnce(Return(&async_stream_));
  expectSendMessage({});
  retry_timer_cb_();
  EXPECT_EQ(load_stats_reporter_->getStats().errors_.value(), 1);
  EXPECT_EQ(load_stats_reporter_->getStats().retries_.value(), 1);
}

// Validate that errors stat is not incremented for a graceful stream termination.
TEST_F(LoadStatsReporterTest, RemoteStreamGracefulClose) {
  EXPECT_CALL(*async_client_, startRaw(_, _, _, _)).WillOnce(Return(&async_stream_));
  expectSendMessage({});
  createLoadStatsReporter();
  EXPECT_CALL(*response_timer_, disableTimer());
  EXPECT_CALL(*retry_timer_, enableTimer(_, _));
  load_stats_reporter_->onRemoteClose(Grpc::Status::WellKnownGrpcStatus::Ok, "");
  EXPECT_CALL(*async_client_, startRaw(_, _, _, _)).WillOnce(Return(&async_stream_));
  expectSendMessage({});
  retry_timer_cb_();
  EXPECT_EQ(load_stats_reporter_->getStats().errors_.value(), 0);
  EXPECT_EQ(load_stats_reporter_->getStats().retries_.value(), 1);
}

// Validate that when rq_active is non-zero, a load report is sent even if rq_issued is 0.
TEST_F(LoadStatsReporterTest, ReportLoadWhenRqActiveIsNonZero) {
  // Keep this test when deprecating the runtime flag.
  TestScopedRuntime scoped_runtime;
  scoped_runtime.mergeValues(
      {{"envoy.reloadable_features.report_load_when_rq_active_is_non_zero", "true"}});

  EXPECT_CALL(*async_client_, startRaw(_, _, _, _)).WillOnce(Return(&async_stream_));
  expectSendMessage({});
  createLoadStatsReporter();
  time_system_.setMonotonicTime(std::chrono::microseconds(100));

  NiceMock<MockClusterMockPrioritySet> cluster;
  MockHostSet& host_set = *cluster.prioritySet().getMockHostSet(0);
  ::envoy::config::core::v3::Locality locality;
  locality.set_region("test_region");

  HostSharedPtr host1 = makeTestHost("host1", locality);
  host_set.hosts_per_locality_ = makeHostsPerLocality({{host1}});

  // Set rq_active to non-zero, rq_issued to zero.
  host1->stats().rq_active_.set(5);
  // Do not call addStats to ensure rq_issued and rq_success remain 0.

  cluster.info_->eds_service_name_ = "eds_service_for_foo";

  ON_CALL(cm_, getActiveCluster("foo"))
      .WillByDefault(Return(OptRef<const Upstream::Cluster>(cluster)));