context_allocator_end2end_test.cc
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2020 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 
19 #include <algorithm>
20 #include <atomic>
21 #include <condition_variable>
22 #include <functional>
23 #include <memory>
24 #include <mutex>
25 #include <sstream>
26 #include <thread>
27 
28 #include <gtest/gtest.h>
29 
30 #include <grpc/impl/codegen/log.h>
31 #include <grpcpp/channel.h>
32 #include <grpcpp/client_context.h>
33 #include <grpcpp/create_channel.h>
34 #include <grpcpp/server.h>
35 #include <grpcpp/server_builder.h>
36 #include <grpcpp/server_context.h>
39 
41 #include "src/proto/grpc/testing/echo.grpc.pb.h"
42 #include "test/core/util/port.h"
46 
47 namespace grpc {
48 namespace testing {
49 namespace {
50 
51 enum class Protocol { INPROC, TCP };
52 
53 class TestScenario {
54  public:
55  TestScenario(Protocol protocol, const std::string& creds_type)
56  : protocol(protocol), credentials_type(creds_type) {}
57  void Log() const;
58  Protocol protocol;
60 };
61 
62 std::ostream& operator<<(std::ostream& out, const TestScenario& scenario) {
63  return out << "TestScenario{protocol="
64  << (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP")
65  << "," << scenario.credentials_type << "}";
66 }
67 
68 void TestScenario::Log() const {
69  std::ostringstream out;
70  out << *this;
71  gpr_log(GPR_INFO, "%s", out.str().c_str());
72 }
73 
74 class ContextAllocatorEnd2endTestBase
75  : public ::testing::TestWithParam<TestScenario> {
76  protected:
77  static void SetUpTestCase() { grpc_init(); }
78  static void TearDownTestCase() { grpc_shutdown(); }
79  ContextAllocatorEnd2endTestBase() {}
80 
81  ~ContextAllocatorEnd2endTestBase() override = default;
82 
83  void SetUp() override { GetParam().Log(); }
84 
85  void CreateServer(std::unique_ptr<grpc::ContextAllocator> context_allocator) {
86  ServerBuilder builder;
87 
88  auto server_creds = GetCredentialsProvider()->GetServerCredentials(
89  GetParam().credentials_type);
90  if (GetParam().protocol == Protocol::TCP) {
92  server_address_ << "localhost:" << picked_port_;
93  builder.AddListeningPort(server_address_.str(), server_creds);
94  }
95  builder.SetContextAllocator(std::move(context_allocator));
96  builder.RegisterService(&callback_service_);
97 
98  server_ = builder.BuildAndStart();
99  }
100 
101  void DestroyServer() {
102  if (server_) {
103  server_->Shutdown();
104  server_.reset();
105  }
106  }
107 
108  void ResetStub() {
109  ChannelArguments args;
110  auto channel_creds = GetCredentialsProvider()->GetChannelCredentials(
111  GetParam().credentials_type, &args);
112  switch (GetParam().protocol) {
113  case Protocol::TCP:
115  channel_creds, args);
116  break;
117  case Protocol::INPROC:
118  channel_ = server_->InProcessChannel(args);
119  break;
120  default:
121  assert(false);
122  }
123  stub_ = EchoTestService::NewStub(channel_);
124  }
125 
126  void TearDown() override {
127  DestroyServer();
128  if (picked_port_ > 0) {
130  }
131  }
132 
133  void SendRpcs(int num_rpcs) {
134  std::string test_string("");
135  for (int i = 0; i < num_rpcs; i++) {
136  EchoRequest request;
137  EchoResponse response;
138  ClientContext cli_ctx;
139 
140  test_string += std::string(1024, 'x');
141  request.set_message(test_string);
142  std::string val;
143  cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP);
144 
145  std::mutex mu;
146  std::condition_variable cv;
147  bool done = false;
148  stub_->async()->Echo(
149  &cli_ctx, &request, &response,
150  [&request, &response, &done, &mu, &cv, val](Status s) {
151  GPR_ASSERT(s.ok());
152 
153  EXPECT_EQ(request.message(), response.message());
154  std::lock_guard<std::mutex> l(mu);
155  done = true;
156  cv.notify_one();
157  });
158  std::unique_lock<std::mutex> l(mu);
159  while (!done) {
160  cv.wait(l);
161  }
162  }
163  }
164 
165  int picked_port_{0};
166  std::shared_ptr<Channel> channel_;
167  std::unique_ptr<EchoTestService::Stub> stub_;
168  CallbackTestServiceImpl callback_service_;
169  std::unique_ptr<Server> server_;
170  std::ostringstream server_address_;
171 };
172 
173 class DefaultContextAllocatorTest : public ContextAllocatorEnd2endTestBase {};
174 
175 TEST_P(DefaultContextAllocatorTest, SimpleRpc) {
176  const int kRpcCount = 10;
177  CreateServer(nullptr);
178  ResetStub();
179  SendRpcs(kRpcCount);
180 }
181 
182 class NullContextAllocatorTest : public ContextAllocatorEnd2endTestBase {
183  public:
184  class NullAllocator : public grpc::ContextAllocator {
185  public:
186  NullAllocator(std::atomic<int>* allocation_count,
187  std::atomic<int>* deallocation_count)
189  deallocation_count_(deallocation_count) {}
190  grpc::CallbackServerContext* NewCallbackServerContext() override {
191  allocation_count_->fetch_add(1, std::memory_order_relaxed);
192  return nullptr;
193  }
194 
195  GenericCallbackServerContext* NewGenericCallbackServerContext() override {
196  allocation_count_->fetch_add(1, std::memory_order_relaxed);
197  return nullptr;
198  }
199 
200  void Release(
201  grpc::CallbackServerContext* /*callback_server_context*/) override {
202  deallocation_count_->fetch_add(1, std::memory_order_relaxed);
203  }
204 
205  void Release(
206  GenericCallbackServerContext* /*generic_callback_server_context*/)
207  override {
208  deallocation_count_->fetch_add(1, std::memory_order_relaxed);
209  }
210 
211  std::atomic<int>* allocation_count_;
212  std::atomic<int>* deallocation_count_;
213  };
214 };
215 
216 TEST_P(NullContextAllocatorTest, UnaryRpc) {
217  const int kRpcCount = 10;
218  std::atomic<int> allocation_count{0};
219  std::atomic<int> deallocation_count{0};
220  std::unique_ptr<NullAllocator> allocator(
221  new NullAllocator(&allocation_count, &deallocation_count));
222  CreateServer(std::move(allocator));
223  ResetStub();
224  SendRpcs(kRpcCount);
225  // messages_deallocaton_count is updated in Release after server side
226  // OnDone.
227  DestroyServer();
228  EXPECT_EQ(kRpcCount, allocation_count);
229  EXPECT_EQ(kRpcCount, deallocation_count);
230 }
231 
232 class SimpleContextAllocatorTest : public ContextAllocatorEnd2endTestBase {
233  public:
234  class SimpleAllocator : public grpc::ContextAllocator {
235  public:
236  SimpleAllocator(std::atomic<int>* allocation_count,
237  std::atomic<int>* deallocation_count)
239  deallocation_count_(deallocation_count) {}
240  grpc::CallbackServerContext* NewCallbackServerContext() override {
241  allocation_count_->fetch_add(1, std::memory_order_relaxed);
242  return new grpc::CallbackServerContext();
243  }
244  GenericCallbackServerContext* NewGenericCallbackServerContext() override {
245  allocation_count_->fetch_add(1, std::memory_order_relaxed);
246  return new GenericCallbackServerContext();
247  }
248 
249  void Release(
250  grpc::CallbackServerContext* callback_server_context) override {
251  deallocation_count_->fetch_add(1, std::memory_order_relaxed);
252  delete callback_server_context;
253  }
254 
255  void Release(GenericCallbackServerContext* generic_callback_server_context)
256  override {
257  deallocation_count_->fetch_add(1, std::memory_order_relaxed);
258  delete generic_callback_server_context;
259  }
260 
261  std::atomic<int>* allocation_count_;
262  std::atomic<int>* deallocation_count_;
263  };
264 };
265 
266 TEST_P(SimpleContextAllocatorTest, UnaryRpc) {
267  const int kRpcCount = 10;
268  std::atomic<int> allocation_count{0};
269  std::atomic<int> deallocation_count{0};
270  std::unique_ptr<SimpleAllocator> allocator(
271  new SimpleAllocator(&allocation_count, &deallocation_count));
272  CreateServer(std::move(allocator));
273  ResetStub();
274  SendRpcs(kRpcCount);
275  // messages_deallocaton_count is updated in Release after server side
276  // OnDone.
277  DestroyServer();
278  EXPECT_EQ(kRpcCount, allocation_count);
279  EXPECT_EQ(kRpcCount, deallocation_count);
280 }
281 
282 std::vector<TestScenario> CreateTestScenarios(bool test_insecure) {
283  std::vector<TestScenario> scenarios;
284  std::vector<std::string> credentials_types{
286  auto insec_ok = [] {
287  // Only allow insecure credentials type when it is registered with the
288  // provider. User may create providers that do not have insecure.
290  kInsecureCredentialsType, nullptr) != nullptr;
291  };
292  if (test_insecure && insec_ok()) {
293  credentials_types.push_back(kInsecureCredentialsType);
294  }
295  GPR_ASSERT(!credentials_types.empty());
296 
297  Protocol parr[]{Protocol::INPROC, Protocol::TCP};
298  for (Protocol p : parr) {
299  for (const auto& cred : credentials_types) {
300  if (p == Protocol::INPROC &&
301  (cred != kInsecureCredentialsType || !insec_ok())) {
302  continue;
303  }
304  scenarios.emplace_back(p, cred);
305  }
306  }
307  return scenarios;
308 }
309 
310 // TODO(ddyihai): adding client streaming/server streaming/bidi streaming
311 // test.
312 
313 INSTANTIATE_TEST_SUITE_P(DefaultContextAllocatorTest,
314  DefaultContextAllocatorTest,
316 INSTANTIATE_TEST_SUITE_P(NullContextAllocatorTest, NullContextAllocatorTest,
318 INSTANTIATE_TEST_SUITE_P(SimpleContextAllocatorTest, SimpleContextAllocatorTest,
320 
321 } // namespace
322 } // namespace testing
323 } // namespace grpc
324 
325 int main(int argc, char** argv) {
326  grpc::testing::TestEnvironment env(&argc, argv);
327  ::testing::InitGoogleTest(&argc, argv);
328  int ret = RUN_ALL_TESTS();
329  return ret;
330 }
test_credentials_provider.h
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
testing
Definition: aws_request_signer_test.cc:25
iomgr.h
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
grpc::testing::CredentialsProvider::GetChannelCredentials
virtual std::shared_ptr< ChannelCredentials > GetChannelCredentials(const std::string &type, ChannelArguments *args)=0
port.h
message_allocator.h
generate.env
env
Definition: generate.py:37
grpc
Definition: grpcpp/alarm.h:33
testing::internal::Log
GTEST_API_ void Log(LogSeverity severity, const std::string &message, int stack_frames_to_skip)
Definition: bloaty/third_party/googletest/googlemock/src/gmock-internal-utils.cc:149
mutex
static uv_mutex_t mutex
Definition: threadpool.c:34
protocol
Protocol protocol
Definition: context_allocator_end2end_test.cc:58
benchmark.request
request
Definition: benchmark.py:77
grpc_recycle_unused_port
void grpc_recycle_unused_port(int port)
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
log.h
absl::FormatConversionChar::s
@ s
test_service_impl.h
scenario
Definition: test/core/fling/client.cc:135
testing::TestWithParam
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1883
client_callback.h
grpc::testing::kInsecureCredentialsType
const char kInsecureCredentialsType[]
Definition: test_credentials_provider.h:31
grpc::ContextAllocator
Definition: grpcpp/impl/codegen/server_context.h:650
credentials_type
const std::string credentials_type
Definition: context_allocator_end2end_test.cc:59
grpc::testing::CredentialsProvider::GetServerCredentials
virtual std::shared_ptr< ServerCredentials > GetServerCredentials(const std::string &type)=0
allocation_count
int allocation_count
Definition: message_allocator_end2end_test.cc:246
profile_analyzer.builder
builder
Definition: profile_analyzer.py:159
asyncio_get_stats.args
args
Definition: asyncio_get_stats.py:40
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
picked_port_
int picked_port_
Definition: context_allocator_end2end_test.cc:165
main
int main(int argc, char **argv)
Definition: context_allocator_end2end_test.cc:325
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
done
struct tab * done
Definition: bloaty/third_party/zlib/examples/enough.c:176
channel.h
grpc::testing::INSTANTIATE_TEST_SUITE_P
INSTANTIATE_TEST_SUITE_P(HistogramTestCases, HistogramTest, ::testing::Range< int >(0, GRPC_STATS_HISTOGRAM_COUNT))
scenarios
static const scenario scenarios[]
Definition: test/core/fling/client.cc:141
TCP
@ TCP
Definition: task.h:82
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)
channel_
std::shared_ptr< Channel > channel_
Definition: context_allocator_end2end_test.cc:166
server_address_
std::ostringstream server_address_
Definition: context_allocator_end2end_test.cc:170
grpc::CallbackServerContext
Definition: grpcpp/impl/codegen/server_context.h:606
test_config.h
client_context.h
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
allocation_count_
std::atomic< int > * allocation_count_
Definition: context_allocator_end2end_test.cc:211
grpc::testing::cv
static gpr_cv cv
Definition: bm_cq.cc:163
grpc::testing::GetCredentialsProvider
CredentialsProvider * GetCredentialsProvider()
Definition: test_credentials_provider.cc:169
performance.scenario_config.INPROC
string INPROC
Definition: scenario_config.py:25
ret
UniquePtr< SSL_SESSION > ret
Definition: ssl_x509.cc:1029
server_context.h
callback_service_
CallbackTestServiceImpl callback_service_
Definition: context_allocator_end2end_test.cc:168
asyncio_get_stats.response
response
Definition: asyncio_get_stats.py:28
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
GRPC_COMPRESS_GZIP
@ GRPC_COMPRESS_GZIP
Definition: compression_types.h:63
grpc::CreateCustomChannel
std::shared_ptr< Channel > CreateCustomChannel(const grpc::string &target, const std::shared_ptr< ChannelCredentials > &creds, const ChannelArguments &args)
grpc::protobuf::util::Status
GRPC_CUSTOM_UTIL_STATUS Status
Definition: include/grpcpp/impl/codegen/config_protobuf.h:93
CreateTestScenarios
std::vector< std::string > CreateTestScenarios()
Definition: time_jump_test.cc:84
grpc::testing::EXPECT_EQ
EXPECT_EQ(options.token_exchange_service_uri, "https://foo/exchange")
grpc::testing::CredentialsProvider::GetSecureCredentialsTypeList
virtual std::vector< std::string > GetSecureCredentialsTypeList()=0
stub_
std::unique_ptr< EchoTestService::Stub > stub_
Definition: context_allocator_end2end_test.cc:167
grpc::testing::TEST_P
TEST_P(HistogramTest, IncHistogram)
Definition: stats_test.cc:87
testing::ValuesIn
internal::ParamGenerator< typename std::iterator_traits< ForwardIterator >::value_type > ValuesIn(ForwardIterator begin, ForwardIterator end)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest-param-test.h:297
server.h
grpc_init
GRPCAPI void grpc_init(void)
Definition: init.cc:146
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
grpc::operator<<
std::ostream & operator<<(std::ostream &out, const string_ref &string)
Definition: grpcpp/impl/codegen/string_ref.h:145
grpc::testing::CreateServer
static std::unique_ptr< Server > CreateServer(const ServerConfig &config)
Definition: qps_worker.cc:72
deallocation_count_
std::atomic< int > * deallocation_count_
Definition: context_allocator_end2end_test.cc:212
server_
std::unique_ptr< Server > server_
Definition: context_allocator_end2end_test.cc:169
grpc_shutdown
GRPCAPI void grpc_shutdown(void)
Definition: init.cc:209
server_builder.h
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
create_channel.h
grpc::testing::mu
static gpr_mu mu
Definition: bm_cq.cc:162


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:58:55