server_load_reporting_end2end_test.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2018 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
20 
21 #include <thread>
22 
23 #include <gmock/gmock.h>
24 #include <gtest/gtest.h>
25 
26 #include <grpc++/grpc++.h>
27 #include <grpc/grpc.h>
28 #include <grpc/support/log.h>
31 #include <grpcpp/server_builder.h>
32 
33 #include "src/proto/grpc/lb/v1/load_reporter.grpc.pb.h"
34 #include "src/proto/grpc/testing/echo.grpc.pb.h"
35 #include "test/core/util/port.h"
37 
38 namespace grpc {
39 namespace testing {
40 namespace {
41 
42 constexpr double kMetricValue = 3.1415;
43 constexpr char kMetricName[] = "METRIC_PI";
44 
45 // Different messages result in different response statuses. For simplicity in
46 // computing request bytes, the message sizes should be the same.
47 const char kOkMessage[] = "hello";
48 const char kServerErrorMessage[] = "sverr";
49 const char kClientErrorMessage[] = "clerr";
50 
51 class EchoTestServiceImpl : public EchoTestService::Service {
52  public:
53  ~EchoTestServiceImpl() override {}
54 
55  Status Echo(ServerContext* context, const EchoRequest* request,
56  EchoResponse* response) override {
57  if (request->message() == kServerErrorMessage) {
58  return Status(StatusCode::UNKNOWN, "Server error requested");
59  }
60  if (request->message() == kClientErrorMessage) {
61  return Status(StatusCode::FAILED_PRECONDITION, "Client error requested");
62  }
63  response->set_message(request->message());
65  context, kMetricName, kMetricValue);
66  return Status::OK;
67  }
68 };
69 
70 class ServerLoadReportingEnd2endTest : public ::testing::Test {
71  protected:
72  void SetUp() override {
75  server_ =
76  ServerBuilder()
77  .AddListeningPort(server_address_, InsecureServerCredentials())
78  .RegisterService(&echo_service_)
79  .SetOption(std::unique_ptr<grpc::ServerBuilderOption>(
81  LoadReportingServiceServerBuilderOption()))
82  .BuildAndStart();
84  std::thread(&ServerLoadReportingEnd2endTest::RunServerLoop, this);
85  }
86 
87  void RunServerLoop() { server_->Wait(); }
88 
89  void TearDown() override {
90  server_->Shutdown();
91  server_thread_.join();
92  }
93 
94  void ClientMakeEchoCalls(const std::string& lb_id, const std::string& lb_tag,
95  const std::string& message, size_t num_requests) {
96  auto stub = EchoTestService::NewStub(
98  std::string lb_token = lb_id + lb_tag;
99  for (size_t i = 0; i < num_requests; ++i) {
100  ClientContext ctx;
101  if (!lb_token.empty()) ctx.AddMetadata(GRPC_LB_TOKEN_MD_KEY, lb_token);
102  EchoRequest request;
103  EchoResponse response;
104  request.set_message(message);
105  Status status = stub->Echo(&ctx, request, &response);
106  if (message == kOkMessage) {
107  ASSERT_EQ(status.error_code(), StatusCode::OK);
108  ASSERT_EQ(request.message(), response.message());
109  } else if (message == kServerErrorMessage) {
110  ASSERT_EQ(status.error_code(), StatusCode::UNKNOWN);
111  } else if (message == kClientErrorMessage) {
113  }
114  }
115  }
116 
118  std::unique_ptr<Server> server_;
120  EchoTestServiceImpl echo_service_;
121 };
122 
123 TEST_F(ServerLoadReportingEnd2endTest, NoCall) {}
124 
125 TEST_F(ServerLoadReportingEnd2endTest, BasicReport) {
126  auto channel =
128  auto stub = grpc::lb::v1::LoadReporter::NewStub(channel);
129  ClientContext ctx;
130  auto stream = stub->ReportLoad(&ctx);
131  grpc::lb::v1::LoadReportRequest request;
132  request.mutable_initial_request()->set_load_balanced_hostname(
134  request.mutable_initial_request()->set_load_key("LOAD_KEY");
135  request.mutable_initial_request()
136  ->mutable_load_report_interval()
137  ->set_seconds(5);
138  stream->Write(request);
139  gpr_log(GPR_INFO, "Initial request sent.");
140  grpc::lb::v1::LoadReportResponse response;
141  stream->Read(&response);
142  const std::string& lb_id = response.initial_response().load_balancer_id();
143  gpr_log(GPR_INFO, "Initial response received (lb_id: %s).", lb_id.c_str());
144  ClientMakeEchoCalls(lb_id, "LB_TAG", kOkMessage, 1);
145 
146  unsigned load_count = 0;
147  bool got_in_progress = false;
148  bool got_orphaned = false;
149  bool got_calls = false;
150  while (load_count < 3) {
151  stream->Read(&response);
152  for (const auto& load : response.load()) {
153  load_count++;
154  if (load.in_progress_report_case()) {
155  // The special load record that reports the number of in-progress
156  // calls.
157  EXPECT_EQ(load.num_calls_in_progress(), 1);
158  EXPECT_FALSE(got_in_progress);
159  got_in_progress = true;
160  } else if (load.orphaned_load_case()) {
161  // The call from the balancer doesn't have any valid LB token.
162  EXPECT_EQ(load.orphaned_load_case(), load.kLoadKeyUnknown);
163  EXPECT_EQ(load.num_calls_started(), 1);
164  EXPECT_EQ(load.num_calls_finished_without_error(), 0);
165  EXPECT_EQ(load.num_calls_finished_with_error(), 0);
166  EXPECT_FALSE(got_orphaned);
167  got_orphaned = true;
168  } else {
169  // This corresponds to the calls from the client.
170  EXPECT_EQ(load.num_calls_started(), 1);
171  EXPECT_EQ(load.num_calls_finished_without_error(), 1);
172  EXPECT_EQ(load.num_calls_finished_with_error(), 0);
173  EXPECT_GE(load.total_bytes_received(), sizeof(kOkMessage));
174  EXPECT_GE(load.total_bytes_sent(), sizeof(kOkMessage));
175  EXPECT_EQ(load.metric_data().size(), 1);
176  EXPECT_EQ(load.metric_data().Get(0).metric_name(), kMetricName);
177  EXPECT_EQ(load.metric_data().Get(0).num_calls_finished_with_metric(),
178  1);
179  EXPECT_EQ(load.metric_data().Get(0).total_metric_value(), kMetricValue);
180  EXPECT_FALSE(got_calls);
181  got_calls = true;
182  }
183  }
184  }
185  EXPECT_EQ(load_count, 3);
186  EXPECT_TRUE(got_in_progress);
187  EXPECT_TRUE(got_orphaned);
188  EXPECT_TRUE(got_calls);
189  stream->WritesDone();
190  EXPECT_EQ(stream->Finish().error_code(), StatusCode::CANCELLED);
191 }
192 
193 // TODO(juanlishen): Add more tests.
194 
195 } // namespace
196 } // namespace testing
197 } // namespace grpc
198 
199 int main(int argc, char** argv) {
200  grpc::testing::TestEnvironment env(&argc, argv);
201  ::testing::InitGoogleTest(&argc, argv);
202  return RUN_ALL_TESTS();
203 }
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
testing
Definition: aws_request_signer_test.cc:25
grpc::status
auto status
Definition: cpp/client/credentials_test.cc:200
log.h
port.h
ctx
Definition: benchmark-async.c:30
generate.env
env
Definition: generate.py:37
grpc::load_reporter::experimental::AddLoadReportingCost
void AddLoadReportingCost(grpc::ServerContext *ctx, const std::string &cost_name, double cost_value)
Definition: src/cpp/server/load_reporter/util.cc:36
grpc
Definition: grpcpp/alarm.h:33
grpc::ASSERT_EQ
ASSERT_EQ(sizeof(valid_json), fwrite(valid_json, 1, sizeof(valid_json), creds_file))
benchmark.request
request
Definition: benchmark.py:77
echo_service_
EchoTestServiceImpl echo_service_
Definition: server_load_reporting_end2end_test.cc:120
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
ctx
static struct test_ctx ctx
Definition: test-ipc-send-recv.c:65
async_greeter_client.stub
stub
Definition: hellostreamingworld/async_greeter_client.py:26
message
char * message
Definition: libuv/docs/code/tty-gravity/main.c:12
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
grpc.StatusCode.FAILED_PRECONDITION
tuple FAILED_PRECONDITION
Definition: src/python/grpcio/grpc/__init__.py:272
server_address_
std::string server_address_
Definition: server_load_reporting_end2end_test.cc:117
string_util.h
channel
wrapped_grpc_channel * channel
Definition: src/php/ext/grpc/call.h:33
grpc.StatusCode.OK
tuple OK
Definition: src/python/grpcio/grpc/__init__.py:260
GRPC_LB_TOKEN_MD_KEY
#define GRPC_LB_TOKEN_MD_KEY
Definition: load_reporting.h:35
grpc.StatusCode.UNKNOWN
tuple UNKNOWN
Definition: src/python/grpcio/grpc/__init__.py:262
grpc::testing::EchoTestServiceImpl::EchoTestServiceImpl
EchoTestServiceImpl(std::string hostname, std::string forwarding_address)
Definition: istio_echo_server_lib.cc:68
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
main
int main(int argc, char **argv)
Definition: server_load_reporting_end2end_test.cc:199
grpc.h
grpc::Status::OK
static const Status & OK
An OK pre-defined instance.
Definition: include/grpcpp/impl/codegen/status.h:113
gen_build_yaml.load
def load(*args)
Definition: test/core/end2end/gen_build_yaml.py:25
grpc++.h
grpc::CreateChannel
std::shared_ptr< Channel > CreateChannel(const grpc::string &target, const std::shared_ptr< ChannelCredentials > &creds)
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
grpc_pick_unused_port_or_die
int grpc_pick_unused_port_or_die(void)
test_config.h
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
grpc::testing::TEST_F
TEST_F(ChannelArgumentsTest, SetInt)
Definition: channel_arguments_test.cc:134
grpc::testing::EchoTestServiceImpl::Echo
grpc::Status Echo(grpc::ServerContext *context, const proto::EchoRequest *request, proto::EchoResponse *response) override
Definition: istio_echo_server_lib.cc:76
asyncio_get_stats.response
response
Definition: asyncio_get_stats.py:28
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
server_load_reporting.h
grpc::protobuf::util::Status
GRPC_CUSTOM_UTIL_STATUS Status
Definition: include/grpcpp/impl/codegen/config_protobuf.h:93
grpc::testing::EXPECT_EQ
EXPECT_EQ(options.token_exchange_service_uri, "https://foo/exchange")
grpc::load_reporter::experimental
Definition: server_load_reporting.h:31
EXPECT_GE
#define EXPECT_GE(val1, val2)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2034
grpc::InsecureServerCredentials
std::shared_ptr< ServerCredentials > InsecureServerCredentials()
Definition: insecure_server_credentials.cc:52
grpc.StatusCode.CANCELLED
tuple CANCELLED
Definition: src/python/grpcio/grpc/__init__.py:261
context
grpc::ClientContext context
Definition: istio_echo_server_lib.cc:61
server_
std::unique_ptr< Server > server_
Definition: server_load_reporting_end2end_test.cc:118
grpc::testing::EXPECT_TRUE
EXPECT_TRUE(grpc::experimental::StsCredentialsOptionsFromJson(minimum_valid_json, &options) .ok())
grpc::InsecureChannelCredentials
std::shared_ptr< ChannelCredentials > InsecureChannelCredentials()
Credentials for an unencrypted, unauthenticated channel.
Definition: cpp/client/insecure_credentials.cc:69
server_thread_
std::thread server_thread_
Definition: server_load_reporting_end2end_test.cc:119
to_string
static bool to_string(zval *from)
Definition: protobuf/php/ext/google/protobuf/convert.c:333
thread
static uv_thread_t thread
Definition: test-async-null-cb.c:29
server_builder.h
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
port_platform.h
stream
voidpf stream
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:11