[xDS] Accept cpu_utilization over 100% (#32954)

<!--

If you know who should review your pull request, please assign it to
that
person, otherwise the pull request would get assigned randomly.

If your pull request is for a specific language, please add the
appropriate
lang label.

-->
pull/32981/head
Yousuk Seung 2 years ago committed by GitHub
parent ac228814a0
commit 8b02295e58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      CMakeLists.txt
  2. 8
      bazel/grpc_deps.bzl
  3. 8
      build_autogenerated.yaml
  4. 4
      include/grpcpp/ext/call_metric_recorder.h
  5. 7
      include/grpcpp/ext/server_metric_recorder.h
  6. 11
      src/cpp/server/backend_metric_recorder.cc
  7. 4
      src/proto/grpc/testing/xds/v3/orca_load_report.proto
  8. 340
      test/cpp/end2end/client_lb_end2end_test.cc
  9. 4
      test/cpp/end2end/orca_service_end2end_test.cc
  10. 24
      test/cpp/end2end/xds/xds_wrr_end2end_test.cc
  11. 2
      third_party/xds
  12. 2
      tools/run_tests/sanity/check_submodules.sh

12
CMakeLists.txt generated

@ -397,18 +397,18 @@ if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/xds)
# Download the archive via HTTP, validate the checksum, and extract to third_party/xds.
download_archive(
${CMAKE_CURRENT_SOURCE_DIR}/third_party/xds
https://storage.googleapis.com/grpc-bazel-mirror/github.com/cncf/xds/archive/32f1caf87195bf3390061c29f18987e51ca56a88.tar.gz
fcd0b50c013452fda9c5e28c131c287b655ebb361271a76ad3bffc08b3ecd82e
xds-32f1caf87195bf3390061c29f18987e51ca56a88
https://storage.googleapis.com/grpc-bazel-mirror/github.com/cncf/xds/archive/4003588d1b747e37e911baa5a9c1c07fde4ca518.tar.gz
aef36c29bd0ef95509f7f52693dbdafe4a2c2c5d1eb406bf68e6364a0d12e11b
xds-4003588d1b747e37e911baa5a9c1c07fde4ca518
)
endif()
if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/third_party/xds)
# Download the archive via HTTP, validate the checksum, and extract to third_party/xds.
download_archive(
${CMAKE_CURRENT_SOURCE_DIR}/third_party/xds
https://github.com/cncf/xds/archive/32f1caf87195bf3390061c29f18987e51ca56a88.tar.gz
fcd0b50c013452fda9c5e28c131c287b655ebb361271a76ad3bffc08b3ecd82e
xds-32f1caf87195bf3390061c29f18987e51ca56a88
https://github.com/cncf/xds/archive/4003588d1b747e37e911baa5a9c1c07fde4ca518.tar.gz
aef36c29bd0ef95509f7f52693dbdafe4a2c2c5d1eb406bf68e6364a0d12e11b
xds-4003588d1b747e37e911baa5a9c1c07fde4ca518
)
endif()

@ -500,11 +500,11 @@ def grpc_deps():
if "com_github_cncf_udpa" not in native.existing_rules():
http_archive(
name = "com_github_cncf_udpa",
sha256 = "fcd0b50c013452fda9c5e28c131c287b655ebb361271a76ad3bffc08b3ecd82e",
strip_prefix = "xds-32f1caf87195bf3390061c29f18987e51ca56a88",
sha256 = "aef36c29bd0ef95509f7f52693dbdafe4a2c2c5d1eb406bf68e6364a0d12e11b",
strip_prefix = "xds-4003588d1b747e37e911baa5a9c1c07fde4ca518",
urls = [
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/cncf/xds/archive/32f1caf87195bf3390061c29f18987e51ca56a88.tar.gz",
"https://github.com/cncf/xds/archive/32f1caf87195bf3390061c29f18987e51ca56a88.tar.gz",
"https://storage.googleapis.com/grpc-bazel-mirror/github.com/cncf/xds/archive/4003588d1b747e37e911baa5a9c1c07fde4ca518.tar.gz",
"https://github.com/cncf/xds/archive/4003588d1b747e37e911baa5a9c1c07fde4ca518.tar.gz",
],
)

@ -13992,10 +13992,10 @@ external_proto_libraries:
- https://storage.googleapis.com/grpc-bazel-mirror/github.com/census-instrumentation/opencensus-proto/archive/v0.3.0.tar.gz
- https://github.com/census-instrumentation/opencensus-proto/archive/v0.3.0.tar.gz
- destination: third_party/xds
hash: fcd0b50c013452fda9c5e28c131c287b655ebb361271a76ad3bffc08b3ecd82e
hash: aef36c29bd0ef95509f7f52693dbdafe4a2c2c5d1eb406bf68e6364a0d12e11b
proto_prefix: third_party/xds/
strip_prefix: xds-32f1caf87195bf3390061c29f18987e51ca56a88
strip_prefix: xds-4003588d1b747e37e911baa5a9c1c07fde4ca518
urls:
- https://storage.googleapis.com/grpc-bazel-mirror/github.com/cncf/xds/archive/32f1caf87195bf3390061c29f18987e51ca56a88.tar.gz
- https://github.com/cncf/xds/archive/32f1caf87195bf3390061c29f18987e51ca56a88.tar.gz
- https://storage.googleapis.com/grpc-bazel-mirror/github.com/cncf/xds/archive/4003588d1b747e37e911baa5a9c1c07fde4ca518.tar.gz
- https://github.com/cncf/xds/archive/4003588d1b747e37e911baa5a9c1c07fde4ca518.tar.gz
tests: []

@ -40,7 +40,9 @@ class CallMetricRecorder {
/// Records a call metric measurement for CPU utilization.
/// Multiple calls to this method will override the stored value.
/// Values outside of the valid range [0, 1] are ignored.
/// Values may be larger than 1.0 when the usage exceeds the reporter
/// dependent notion of soft limits.
/// Values outside of the valid range [0, infy] are ignored.
virtual CallMetricRecorder& RecordCpuUtilizationMetric(double value) = 0;
/// Records a call metric measurement for memory utilization.

@ -43,9 +43,10 @@ class ServerMetricRecorder {
public:
// Factory method. Use this to create.
static std::unique_ptr<ServerMetricRecorder> Create();
/// Records the server CPU utilization in the range [0, 1].
/// Values outside of the valid range are rejected.
/// Overrides the stored value when called again with a valid value.
/// Records the server CPU utilization in the range [0, infy).
/// Values may be larger than 1.0 when the usage exceeds the reporter
/// dependent notion of soft limits. Values outside of the valid range are
/// rejected. Overrides the stored value when called again with a valid value.
void SetCpuUtilization(double value);
/// Records the server memory utilization in the range [0, 1].
/// Values outside of the valid range are rejected.

@ -34,7 +34,10 @@
using grpc_core::BackendMetricData;
namespace {
// All utilization values must be in [0, 1].
// CPU utilization values must be in [0, infy).
bool IsCpuUtilizationValid(double cpu) { return cpu >= 0.0; }
// Other utilization values must be in [0, 1].
bool IsUtilizationValid(double utilization) {
return utilization >= 0.0 && utilization <= 1.0;
}
@ -65,7 +68,7 @@ void ServerMetricRecorder::UpdateBackendMetricDataState(
}
void ServerMetricRecorder::SetCpuUtilization(double value) {
if (!IsUtilizationValid(value)) {
if (!IsCpuUtilizationValid(value)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] CPU utilization rejected: %f", this, value);
}
@ -220,7 +223,7 @@ ServerMetricRecorder::GetMetricsIfChanged() const {
experimental::CallMetricRecorder&
BackendMetricState::RecordCpuUtilizationMetric(double value) {
if (!IsUtilizationValid(value)) {
if (!IsCpuUtilizationValid(value)) {
if (GRPC_TRACE_FLAG_ENABLED(grpc_backend_metric_trace)) {
gpr_log(GPR_INFO, "[%p] CPU utilization value rejected: %f", this, value);
}
@ -330,7 +333,7 @@ BackendMetricData BackendMetricState::GetBackendMetricData() {
}
// Only overwrite if the value is set i.e. in the valid range.
const double cpu = cpu_utilization_.load(std::memory_order_relaxed);
if (IsUtilizationValid(cpu)) {
if (IsCpuUtilizationValid(cpu)) {
data.cpu_utilization = cpu;
}
const double mem = mem_utilization_.load(std::memory_order_relaxed);

@ -23,7 +23,9 @@ package xds.data.orca.v3;
message OrcaLoadReport {
// CPU utilization expressed as a fraction of available CPU resources. This
// should be derived from the latest sample or measurement.
// should be derived from the latest sample or measurement. The value may be
// larger than 1.0 when the usage exceeds the reporter dependent notion of
// soft limits.
double cpu_utilization = 1;
// Memory utilization expressed as a fraction of available memory

@ -84,6 +84,7 @@ namespace grpc {
namespace testing {
namespace {
using xds::data::orca::v3::OrcaLoadReport;
constexpr char kRequestMessage[] = "Live long and prosper.";
// A noop health check service that just terminates the call and returns OK
@ -380,8 +381,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
void CheckRpcSendOk(
const grpc_core::DebugLocation& location,
const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub,
bool wait_for_ready = false,
xds::data::orca::v3::OrcaLoadReport* load_report = nullptr,
bool wait_for_ready = false, const OrcaLoadReport* load_report = nullptr,
int timeout_ms = 2000) {
EchoResponse response;
EchoRequest request;
@ -2345,30 +2345,94 @@ TEST_F(ClientLbPickArgsTest, Basic) {
<< ArgsSeenListString(pick_args_seen_list);
}
class OrcaLoadReportBuilder {
public:
OrcaLoadReportBuilder() = default;
explicit OrcaLoadReportBuilder(const OrcaLoadReport& report)
: report_(report) {}
OrcaLoadReportBuilder& SetCpuUtilization(double v) {
report_.set_cpu_utilization(v);
return *this;
}
OrcaLoadReportBuilder& SetMemUtilization(double v) {
report_.set_mem_utilization(v);
return *this;
}
OrcaLoadReportBuilder& SetQps(double v) {
report_.set_rps_fractional(v);
return *this;
}
OrcaLoadReportBuilder& SetEps(double v) {
report_.set_eps(v);
return *this;
}
OrcaLoadReportBuilder& SetRequestCost(absl::string_view n, double v) {
(*report_.mutable_request_cost())[n] = v;
return *this;
}
OrcaLoadReportBuilder& SetUtilization(absl::string_view n, double v) {
(*report_.mutable_utilization())[n] = v;
return *this;
}
OrcaLoadReportBuilder& SetNamedMetrics(absl::string_view n, double v) {
(*report_.mutable_named_metrics())[n] = v;
return *this;
}
OrcaLoadReport Build() { return std::move(report_); }
private:
OrcaLoadReport report_;
};
//
// tests that LB policies can get the call's trailing metadata
//
xds::data::orca::v3::OrcaLoadReport BackendMetricDataToOrcaLoadReport(
OrcaLoadReport BackendMetricDataToOrcaLoadReport(
const grpc_core::BackendMetricData& backend_metric_data) {
xds::data::orca::v3::OrcaLoadReport load_report;
load_report.set_cpu_utilization(backend_metric_data.cpu_utilization);
load_report.set_mem_utilization(backend_metric_data.mem_utilization);
load_report.set_rps_fractional(backend_metric_data.qps);
load_report.set_eps(backend_metric_data.eps);
auto builder = OrcaLoadReportBuilder()
.SetCpuUtilization(backend_metric_data.cpu_utilization)
.SetMemUtilization(backend_metric_data.mem_utilization)
.SetQps(backend_metric_data.qps)
.SetEps(backend_metric_data.eps);
for (const auto& p : backend_metric_data.request_cost) {
std::string name(p.first);
(*load_report.mutable_request_cost())[name] = p.second;
builder.SetRequestCost(std::string(p.first), p.second);
}
for (const auto& p : backend_metric_data.utilization) {
std::string name(p.first);
(*load_report.mutable_utilization())[name] = p.second;
builder.SetUtilization(std::string(p.first), p.second);
}
for (const auto& p : backend_metric_data.named_metrics) {
std::string name(p.first);
(*load_report.mutable_named_metrics())[name] = p.second;
builder.SetNamedMetrics(std::string(p.first), p.second);
}
return builder.Build();
}
// TODO(roth): Change this to use EqualsProto() once that becomes available in
// OSS.
void CheckLoadReportAsExpected(const OrcaLoadReport& actual,
const OrcaLoadReport& expected) {
EXPECT_EQ(actual.cpu_utilization(), expected.cpu_utilization());
EXPECT_EQ(actual.mem_utilization(), expected.mem_utilization());
EXPECT_EQ(actual.rps_fractional(), expected.rps_fractional());
EXPECT_EQ(actual.eps(), expected.eps());
EXPECT_EQ(actual.request_cost().size(), expected.request_cost().size());
for (const auto& p : actual.request_cost()) {
auto it = expected.request_cost().find(p.first);
ASSERT_NE(it, expected.request_cost().end());
EXPECT_EQ(it->second, p.second);
}
EXPECT_EQ(actual.utilization().size(), expected.utilization().size());
for (const auto& p : actual.utilization()) {
auto it = expected.utilization().find(p.first);
ASSERT_NE(it, expected.utilization().end());
EXPECT_EQ(it->second, p.second);
}
EXPECT_EQ(actual.named_metrics().size(), expected.named_metrics().size());
for (const auto& p : actual.named_metrics()) {
auto it = expected.named_metrics().find(p.first);
ASSERT_NE(it, expected.named_metrics().end());
EXPECT_EQ(it->second, p.second);
}
return load_report;
}
class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest {
@ -2408,7 +2472,7 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest {
return std::move(trailing_metadata_);
}
absl::optional<xds::data::orca::v3::OrcaLoadReport> backend_load_report() {
absl::optional<OrcaLoadReport> backend_load_report() {
grpc_core::MutexLock lock(&mu_);
return std::move(load_report_);
}
@ -2423,6 +2487,28 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest {
return true;
}
void RunPerRpcMetricReportingTest(const OrcaLoadReport& reported,
const OrcaLoadReport& expected) {
const int kNumServers = 1;
const int kNumRpcs = 10;
StartServers(kNumServers);
auto response_generator = BuildResolverResponseGenerator();
auto channel =
BuildChannel("intercept_trailing_metadata_lb", response_generator);
auto stub = BuildStub(channel);
response_generator.SetNextResolution(GetServersPorts());
for (size_t i = 0; i < kNumRpcs; ++i) {
CheckRpcSendOk(DEBUG_LOCATION, stub, false, &reported);
auto actual = backend_load_report();
ASSERT_TRUE(actual.has_value());
CheckLoadReportAsExpected(*actual, expected);
}
// Check LB policy name for the channel.
EXPECT_EQ("intercept_trailing_metadata_lb",
channel->GetLoadBalancingPolicyName());
EXPECT_EQ(kNumRpcs, num_trailers_intercepted());
}
private:
static void ReportTrailerIntercepted(
const grpc_core::TrailingMetadataArgsSeen& args_seen) {
@ -2447,7 +2533,7 @@ class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest {
grpc_core::CondVar cond_;
absl::Status last_status_;
grpc_core::MetadataVector trailing_metadata_;
absl::optional<xds::data::orca::v3::OrcaLoadReport> load_report_;
absl::optional<OrcaLoadReport> load_report_;
};
ClientLbInterceptTrailingMetadataTest*
@ -2583,74 +2669,62 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, InterceptsRetriesEnabled) {
EXPECT_FALSE(backend_load_report().has_value());
}
// TODO(roth): Change this to use EqualsProto() once that becomes available in
// OSS.
void CheckLoadReportAsExpected(
const xds::data::orca::v3::OrcaLoadReport& actual,
const xds::data::orca::v3::OrcaLoadReport& expected) {
EXPECT_EQ(actual.cpu_utilization(), expected.cpu_utilization());
EXPECT_EQ(actual.mem_utilization(), expected.mem_utilization());
EXPECT_EQ(actual.rps_fractional(), expected.rps_fractional());
EXPECT_EQ(actual.eps(), expected.eps());
EXPECT_EQ(actual.request_cost().size(), expected.request_cost().size());
for (const auto& p : actual.request_cost()) {
auto it = expected.request_cost().find(p.first);
ASSERT_NE(it, expected.request_cost().end());
EXPECT_EQ(it->second, p.second);
}
EXPECT_EQ(actual.utilization().size(), expected.utilization().size());
for (const auto& p : actual.utilization()) {
auto it = expected.utilization().find(p.first);
ASSERT_NE(it, expected.utilization().end());
EXPECT_EQ(it->second, p.second);
}
EXPECT_EQ(actual.named_metrics().size(), expected.named_metrics().size());
for (const auto& p : actual.named_metrics()) {
auto it = expected.named_metrics().find(p.first);
ASSERT_NE(it, expected.named_metrics().end());
EXPECT_EQ(it->second, p.second);
}
}
TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricData) {
const int kNumServers = 1;
const int kNumRpcs = 10;
StartServers(kNumServers);
xds::data::orca::v3::OrcaLoadReport load_report;
load_report.set_cpu_utilization(0.5);
load_report.set_mem_utilization(0.75);
load_report.set_rps_fractional(0.25);
load_report.set_eps(0.10);
auto& request_cost = *load_report.mutable_request_cost();
request_cost["foo"] = -0.8;
request_cost["bar"] = 1.4;
auto& utilization = *load_report.mutable_utilization();
utilization["baz"] = 1.0;
utilization["quux"] = 0.9;
// This will be rejected.
utilization["out_of_range_invalid1"] = 1.1;
utilization["out_of_range_invalid2"] = -1.1;
auto& named_metrics = *load_report.mutable_named_metrics();
named_metrics["metric0"] = 3.0;
named_metrics["metric1"] = -1.0;
auto expected = load_report;
expected.mutable_utilization()->erase("out_of_range_invalid1");
expected.mutable_utilization()->erase("out_of_range_invalid2");
auto response_generator = BuildResolverResponseGenerator();
auto channel =
BuildChannel("intercept_trailing_metadata_lb", response_generator);
auto stub = BuildStub(channel);
response_generator.SetNextResolution(GetServersPorts());
for (size_t i = 0; i < kNumRpcs; ++i) {
CheckRpcSendOk(DEBUG_LOCATION, stub, false, &load_report);
auto actual = backend_load_report();
ASSERT_TRUE(actual.has_value());
CheckLoadReportAsExpected(*actual, expected);
}
// Check LB policy name for the channel.
EXPECT_EQ("intercept_trailing_metadata_lb",
channel->GetLoadBalancingPolicyName());
EXPECT_EQ(kNumRpcs, num_trailers_intercepted());
TEST_F(ClientLbInterceptTrailingMetadataTest, Valid) {
RunPerRpcMetricReportingTest(OrcaLoadReportBuilder()
.SetCpuUtilization(0.5)
.SetMemUtilization(0.75)
.SetQps(0.25)
.SetEps(0.1)
.SetRequestCost("foo", -0.8)
.SetRequestCost("bar", 1.4)
.SetUtilization("baz", 1.0)
.SetUtilization("quux", 0.9)
.SetNamedMetrics("metric0", 3.0)
.SetNamedMetrics("metric1", -1.0)
.Build(),
OrcaLoadReportBuilder()
.SetCpuUtilization(0.5)
.SetMemUtilization(0.75)
.SetQps(0.25)
.SetEps(0.1)
.SetRequestCost("foo", -0.8)
.SetRequestCost("bar", 1.4)
.SetUtilization("baz", 1.0)
.SetUtilization("quux", 0.9)
.SetNamedMetrics("metric0", 3.0)
.SetNamedMetrics("metric1", -1.0)
.Build());
}
TEST_F(ClientLbInterceptTrailingMetadataTest, NegativeValues) {
RunPerRpcMetricReportingTest(OrcaLoadReportBuilder()
.SetCpuUtilization(-0.1)
.SetMemUtilization(-0.2)
.SetQps(-3)
.SetEps(-4)
.SetRequestCost("foo", -5)
.SetUtilization("bar", -0.6)
.SetNamedMetrics("baz", -0.7)
.Build(),
OrcaLoadReportBuilder()
.SetRequestCost("foo", -5)
.SetNamedMetrics("baz", -0.7)
.Build());
}
TEST_F(ClientLbInterceptTrailingMetadataTest, AboveOneUtilization) {
RunPerRpcMetricReportingTest(OrcaLoadReportBuilder()
.SetCpuUtilization(1.1)
.SetMemUtilization(2)
.SetQps(3)
.SetEps(4)
.SetUtilization("foo", 5)
.Build(),
OrcaLoadReportBuilder()
.SetCpuUtilization(1.1)
.SetQps(3)
.SetEps(4)
.Build());
}
TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricDataMerge) {
@ -2663,13 +2737,14 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricDataMerge) {
servers_[0]->server_metric_recorder_->SetEps(0.99);
servers_[0]->server_metric_recorder_->SetNamedUtilization("foo", 0.99);
servers_[0]->server_metric_recorder_->SetNamedUtilization("bar", 0.1);
xds::data::orca::v3::OrcaLoadReport per_server_load;
per_server_load.set_cpu_utilization(0.99);
per_server_load.set_mem_utilization(0.99);
per_server_load.set_rps_fractional(0.99);
per_server_load.set_eps(0.99);
(*per_server_load.mutable_utilization())["foo"] = 0.99;
(*per_server_load.mutable_utilization())["bar"] = 0.1;
OrcaLoadReport per_server_load = OrcaLoadReportBuilder()
.SetCpuUtilization(0.99)
.SetMemUtilization(0.99)
.SetQps(0.99)
.SetEps(0.99)
.SetUtilization("foo", 0.99)
.SetUtilization("bar", 0.1)
.Build();
auto response_generator = BuildResolverResponseGenerator();
auto channel =
BuildChannel("intercept_trailing_metadata_lb", response_generator);
@ -2677,10 +2752,10 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricDataMerge) {
response_generator.SetNextResolution(GetServersPorts());
size_t total_num_rpcs = 0;
{
xds::data::orca::v3::OrcaLoadReport load_report;
load_report.set_cpu_utilization(0.5);
auto expected = per_server_load;
expected.set_cpu_utilization(0.5);
OrcaLoadReport load_report =
OrcaLoadReportBuilder().SetCpuUtilization(0.5).Build();
OrcaLoadReport expected =
OrcaLoadReportBuilder(per_server_load).SetCpuUtilization(0.5).Build();
for (size_t i = 0; i < kNumRpcs; ++i) {
CheckRpcSendOk(DEBUG_LOCATION, stub, false, &load_report);
auto actual = backend_load_report();
@ -2690,10 +2765,10 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricDataMerge) {
}
}
{
xds::data::orca::v3::OrcaLoadReport load_report;
load_report.set_mem_utilization(0.5);
auto expected = per_server_load;
expected.set_mem_utilization(0.5);
OrcaLoadReport load_report =
OrcaLoadReportBuilder().SetMemUtilization(0.5).Build();
OrcaLoadReport expected =
OrcaLoadReportBuilder(per_server_load).SetMemUtilization(0.5).Build();
for (size_t i = 0; i < kNumRpcs; ++i) {
CheckRpcSendOk(DEBUG_LOCATION, stub, false, &load_report);
auto actual = backend_load_report();
@ -2703,10 +2778,9 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricDataMerge) {
}
}
{
xds::data::orca::v3::OrcaLoadReport load_report;
load_report.set_rps_fractional(0.5);
auto expected = per_server_load;
expected.set_rps_fractional(0.5);
OrcaLoadReport load_report = OrcaLoadReportBuilder().SetQps(0.5).Build();
OrcaLoadReport expected =
OrcaLoadReportBuilder(per_server_load).SetQps(0.5).Build();
for (size_t i = 0; i < kNumRpcs; ++i) {
CheckRpcSendOk(DEBUG_LOCATION, stub, false, &load_report);
auto actual = backend_load_report();
@ -2716,10 +2790,9 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricDataMerge) {
}
}
{
xds::data::orca::v3::OrcaLoadReport load_report;
load_report.set_eps(0.5);
auto expected = per_server_load;
expected.set_eps(0.5);
OrcaLoadReport load_report = OrcaLoadReportBuilder().SetEps(0.5).Build();
OrcaLoadReport expected =
OrcaLoadReportBuilder(per_server_load).SetEps(0.5).Build();
for (size_t i = 0; i < kNumRpcs; ++i) {
CheckRpcSendOk(DEBUG_LOCATION, stub, false, &load_report);
auto actual = backend_load_report();
@ -2729,15 +2802,16 @@ TEST_F(ClientLbInterceptTrailingMetadataTest, BackendMetricDataMerge) {
}
}
{
xds::data::orca::v3::OrcaLoadReport load_report;
auto& utilization = *load_report.mutable_utilization();
utilization["foo"] = 0.5;
// Out of range, won't override.
utilization["bar"] = 1.1;
utilization["baz"] = 1.0;
auto expected = per_server_load;
(*expected.mutable_utilization())["foo"] = 0.5;
(*expected.mutable_utilization())["baz"] = 1.0;
OrcaLoadReport load_report =
OrcaLoadReportBuilder()
.SetUtilization("foo", 0.5)
.SetUtilization("bar", 1.1) // Out of range.
.SetUtilization("baz", 1.0)
.Build();
auto expected = OrcaLoadReportBuilder(per_server_load)
.SetUtilization("foo", 0.5)
.SetUtilization("baz", 1.0)
.Build();
for (size_t i = 0; i < kNumRpcs; ++i) {
CheckRpcSendOk(DEBUG_LOCATION, stub, false, &load_report);
auto actual = backend_load_report();
@ -2848,8 +2922,7 @@ TEST_F(ClientLbAddressTest, Basic) {
class OobBackendMetricTest : public ClientLbEnd2endTest {
protected:
using BackendMetricReport =
std::pair<int /*port*/, xds::data::orca::v3::OrcaLoadReport>;
using BackendMetricReport = std::pair<int /*port*/, OrcaLoadReport>;
void SetUp() override {
ClientLbEnd2endTest::SetUp();
@ -2943,7 +3016,7 @@ TEST_F(OobBackendMetricTest, Basic) {
servers_[0]->server_metric_recorder_->SetEps(0.6);
servers_[0]->server_metric_recorder_->SetQps(0.8);
servers_[0]->server_metric_recorder_->SetMemoryUtilization(0.5);
servers_[0]->server_metric_recorder_->SetCpuUtilization(0.4);
servers_[0]->server_metric_recorder_->SetCpuUtilization(2.4);
// Wait for client to see new report.
report_seen = false;
for (size_t i = 0; i < 5; ++i) {
@ -2951,7 +3024,7 @@ TEST_F(OobBackendMetricTest, Basic) {
if (report.has_value()) {
EXPECT_EQ(report->first, servers_[0]->port_);
if (report->second.cpu_utilization() != 0.1) {
EXPECT_EQ(report->second.cpu_utilization(), 0.4);
EXPECT_EQ(report->second.cpu_utilization(), 2.4);
EXPECT_EQ(report->second.mem_utilization(), 0.5);
EXPECT_EQ(report->second.eps(), 0.6);
EXPECT_EQ(report->second.rps_fractional(), 0.8);
@ -3121,17 +3194,17 @@ class WeightedRoundRobinTest : public ClientLbEnd2endTest {
TEST_F(WeightedRoundRobinTest, CallAndServerMetric) {
const int kNumServers = 3;
StartServers(kNumServers);
// Report server metrics that should give 1:2:4 WRR picks.
// Report server metrics that should give 6:4:3 WRR picks.
// weights = qps / (cpu_util + (eps/qps)) =
// 1/(0.4+0.4) : 1/(0.2+0.2) : 2/(0.3+0.1) = 1:2:4
servers_[0]->server_metric_recorder_->SetCpuUtilization(0.4);
servers_[0]->server_metric_recorder_->SetEps(40);
// 1/(0.2+0.2) : 1/(0.3+0.3) : 2/(1.5+0.1) = 6:4:3
servers_[0]->server_metric_recorder_->SetCpuUtilization(0.2);
servers_[0]->server_metric_recorder_->SetEps(20);
servers_[0]->server_metric_recorder_->SetQps(100);
servers_[1]->server_metric_recorder_->SetCpuUtilization(0.2);
servers_[1]->server_metric_recorder_->SetEps(20);
servers_[1]->server_metric_recorder_->SetCpuUtilization(0.3);
servers_[1]->server_metric_recorder_->SetEps(30);
servers_[1]->server_metric_recorder_->SetQps(100);
servers_[2]->server_metric_recorder_->SetCpuUtilization(0.3);
servers_[2]->server_metric_recorder_->SetEps(5);
servers_[2]->server_metric_recorder_->SetCpuUtilization(1.5);
servers_[2]->server_metric_recorder_->SetEps(20);
servers_[2]->server_metric_recorder_->SetQps(200);
// Create channel.
auto response_generator = BuildResolverResponseGenerator();
@ -3140,20 +3213,19 @@ TEST_F(WeightedRoundRobinTest, CallAndServerMetric) {
response_generator.SetNextResolution(GetServersPorts(),
kServiceConfigPerCall);
// Send requests with per-call reported EPS/QPS set to 0/100.
// This should override per-server QPS above and give 1/4:1/2:1/3 = 3:6:4 WRR
// picks.
// This should give 1/2:1/3:1/15 = 15:10:2 WRR picks.
EchoRequest request;
// We cannot override with 0 with proto3, so setting it to almost 0.
request.mutable_param()->mutable_backend_metrics()->set_eps(
std::numeric_limits<double>::min());
request.mutable_param()->mutable_backend_metrics()->set_rps_fractional(100);
ExpectWeightedRoundRobinPicks(DEBUG_LOCATION, stub,
/*expected_weights=*/{3, 6, 4},
/*expected_weights=*/{15, 10, 2},
/*total_passes=*/3, &request);
// Now send requests without per-call reported QPS.
// This should change WRR picks back to 1:2:4.
// This should change WRR picks back to 6:4:3.
ExpectWeightedRoundRobinPicks(DEBUG_LOCATION, stub,
/*expected_weights=*/{1, 2, 4});
/*expected_weights=*/{6, 4, 3});
// Check LB policy name for the channel.
EXPECT_EQ("weighted_round_robin", channel->GetLoadBalancingPolicyName());
}

@ -153,10 +153,10 @@ TEST_F(OrcaServiceEnd2endTest, Basic) {
EXPECT_THAT(response.utilization(), ::testing::UnorderedElementsAre());
});
// Update CPU utilization and set memory utilization.
server_metric_recorder_->SetCpuUtilization(0.8);
server_metric_recorder_->SetCpuUtilization(1.8);
server_metric_recorder_->SetMemoryUtilization(0.4);
ReadResponses([](const OrcaLoadReport& response) {
EXPECT_EQ(response.cpu_utilization(), 0.8);
EXPECT_EQ(response.cpu_utilization(), 1.8);
EXPECT_EQ(response.mem_utilization(), 0.4);
EXPECT_THAT(response.utilization(), ::testing::UnorderedElementsAre());
});

@ -51,16 +51,16 @@ TEST_P(WrrTest, Basic) {
ScopedExperimentalEnvVar env_var2("GRPC_EXPERIMENTAL_XDS_WRR_LB");
CreateAndStartBackends(3);
// Expected weights = qps / (cpu_util + (eps/qps)) =
// 1/(0.4+0.4) : 1/(0.2+0.2) : 1/(0.1+0.1) = 1:2:4
// 1/(0.2+0.2) : 1/(0.3+0.3) : 2/(1.5+0.1) = 6:4:3
backends_[0]->server_metric_recorder()->SetQps(100);
backends_[0]->server_metric_recorder()->SetEps(40);
backends_[0]->server_metric_recorder()->SetCpuUtilization(0.4);
backends_[0]->server_metric_recorder()->SetEps(20);
backends_[0]->server_metric_recorder()->SetCpuUtilization(0.2);
backends_[1]->server_metric_recorder()->SetQps(100);
backends_[1]->server_metric_recorder()->SetEps(20);
backends_[1]->server_metric_recorder()->SetCpuUtilization(0.2);
backends_[2]->server_metric_recorder()->SetQps(100);
backends_[2]->server_metric_recorder()->SetEps(10);
backends_[2]->server_metric_recorder()->SetCpuUtilization(0.1);
backends_[1]->server_metric_recorder()->SetEps(30);
backends_[1]->server_metric_recorder()->SetCpuUtilization(0.3);
backends_[2]->server_metric_recorder()->SetQps(200);
backends_[2]->server_metric_recorder()->SetEps(20);
backends_[2]->server_metric_recorder()->SetCpuUtilization(1.5);
auto cluster = default_cluster_;
WrrLocality wrr_locality;
wrr_locality.mutable_endpoint_picking_policy()
@ -78,14 +78,14 @@ TEST_P(WrrTest, Basic) {
balancer_->ads_service()->SetEdsResource(BuildEdsResource(args));
size_t num_picks = 0;
SendRpcsUntil(DEBUG_LOCATION, [&](const RpcResult&) {
if (++num_picks == 7) {
if (++num_picks == 13) {
gpr_log(GPR_INFO, "request counts: %" PRIuPTR " %" PRIuPTR " %" PRIuPTR,
backends_[0]->backend_service()->request_count(),
backends_[1]->backend_service()->request_count(),
backends_[2]->backend_service()->request_count());
if (backends_[0]->backend_service()->request_count() == 1 &&
backends_[1]->backend_service()->request_count() == 2 &&
backends_[2]->backend_service()->request_count() == 4) {
if (backends_[0]->backend_service()->request_count() == 6 &&
backends_[1]->backend_service()->request_count() == 4 &&
backends_[2]->backend_service()->request_count() == 3) {
return false;
}
num_picks = 0;

2
third_party/xds vendored

@ -1 +1 @@
Subproject commit 32f1caf87195bf3390061c29f18987e51ca56a88
Subproject commit 4003588d1b747e37e911baa5a9c1c07fde4ca518

@ -38,7 +38,7 @@ third_party/opencensus-proto 4aa53e15cbf1a47bc9087e6cfdca214c1eea4e89
third_party/opentelemetry 60fa8754d890b5c55949a8c68dcfd7ab5c2395df
third_party/protobuf 5ddb1fc609d2416e8575c9e7435c608222c2edb2
third_party/re2 0c5616df9c0aaa44c9440d87422012423d91c7d1
third_party/xds 32f1caf87195bf3390061c29f18987e51ca56a88
third_party/xds 4003588d1b747e37e911baa5a9c1c07fde4ca518
third_party/zlib 04f42ceca40f73e2978b50e93806c2a18c1281fc
EOF

Loading…
Cancel
Save