generic.mm 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. *
  3. * Copyright 2017 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. #import <XCTest/XCTest.h>
  19. #include <sstream>
  20. #include <grpc/grpc.h>
  21. #include <grpc/support/time.h>
  22. #include <grpcpp/channel.h>
  23. #include <grpcpp/client_context.h>
  24. #include <grpcpp/create_channel.h>
  25. #include <grpcpp/generic/async_generic_service.h>
  26. #include <grpcpp/generic/generic_stub.h>
  27. #include <grpcpp/server.h>
  28. #include <grpcpp/server_builder.h>
  29. #include <grpcpp/server_context.h>
  30. #include <grpcpp/support/slice.h>
  31. #include "src/core/lib/gprpp/thd.h"
  32. #include "test/core/util/port.h"
  33. #include "test/core/util/test_config.h"
  34. using std::chrono::system_clock;
  35. using namespace grpc;
  36. void* tag(int i) { return (void*)(intptr_t)i; }
  37. static grpc_slice merge_slices(grpc_slice* slices, size_t nslices) {
  38. size_t i;
  39. size_t len = 0;
  40. uint8_t* cursor;
  41. grpc_slice out;
  42. for (i = 0; i < nslices; i++) {
  43. len += GRPC_SLICE_LENGTH(slices[i]);
  44. }
  45. out = grpc_slice_malloc(len);
  46. cursor = GRPC_SLICE_START_PTR(out);
  47. for (i = 0; i < nslices; i++) {
  48. memcpy(cursor, GRPC_SLICE_START_PTR(slices[i]), GRPC_SLICE_LENGTH(slices[i]));
  49. cursor += GRPC_SLICE_LENGTH(slices[i]);
  50. }
  51. return out;
  52. }
  53. int byte_buffer_eq_string(ByteBuffer* bb, const char* str) {
  54. int res;
  55. std::vector<Slice> slices;
  56. bb->Dump(&slices);
  57. grpc_slice* c_slices = new grpc_slice[slices.size()];
  58. for (int i = 0; i < slices.size(); i++) {
  59. c_slices[i] = slices[i].c_slice();
  60. }
  61. grpc_slice a = merge_slices(c_slices, slices.size());
  62. grpc_slice b = grpc_slice_from_copied_string(str);
  63. res = (GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b)) &&
  64. (0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b), GRPC_SLICE_LENGTH(a)));
  65. grpc_slice_unref(a);
  66. grpc_slice_unref(b);
  67. for (int i = 0; i < slices.size(); i++) {
  68. grpc_slice_unref(c_slices[i]);
  69. }
  70. delete[] c_slices;
  71. return res;
  72. }
  73. @interface GenericTest : XCTestCase
  74. @end
  75. @implementation GenericTest {
  76. std::string server_host_;
  77. CompletionQueue cli_cq_;
  78. std::unique_ptr<ServerCompletionQueue> srv_cq_;
  79. std::unique_ptr<GenericStub> generic_stub_;
  80. std::unique_ptr<Server> server_;
  81. AsyncGenericService generic_service_;
  82. std::ostringstream server_address_;
  83. }
  84. - (void)verify_ok:(grpc::CompletionQueue*)cq i:(int)i expect_ok:(bool)expect_ok {
  85. bool ok;
  86. void* got_tag;
  87. XCTAssertTrue(cq->Next(&got_tag, &ok));
  88. XCTAssertEqual(expect_ok, ok);
  89. XCTAssertEqual(tag(i), got_tag);
  90. }
  91. - (void)server_ok:(int)i {
  92. [self verify_ok:srv_cq_.get() i:i expect_ok:true];
  93. }
  94. - (void)client_ok:(int)i {
  95. [self verify_ok:&cli_cq_ i:i expect_ok:true];
  96. }
  97. - (void)server_fail:(int)i {
  98. [self verify_ok:srv_cq_.get() i:i expect_ok:false];
  99. }
  100. - (void)client_fail:(int)i {
  101. [self verify_ok:&cli_cq_ i:i expect_ok:false];
  102. }
  103. - (void)setUp {
  104. [super setUp];
  105. server_host_ = "localhost";
  106. int port = grpc_pick_unused_port_or_die();
  107. server_address_ << server_host_ << ":" << port;
  108. // Setup server
  109. ServerBuilder builder;
  110. builder.AddListeningPort(server_address_.str(), InsecureServerCredentials());
  111. builder.RegisterAsyncGenericService(&generic_service_);
  112. // Include a second call to RegisterAsyncGenericService to make sure that
  113. // we get an error in the log, since it is not allowed to have 2 async
  114. // generic services
  115. builder.RegisterAsyncGenericService(&generic_service_);
  116. srv_cq_ = builder.AddCompletionQueue();
  117. server_ = builder.BuildAndStart();
  118. }
  119. - (void)tearDown {
  120. // Put teardown code here. This method is called after the invocation of each test method in the
  121. // class.
  122. server_->Shutdown();
  123. void* ignored_tag;
  124. bool ignored_ok;
  125. cli_cq_.Shutdown();
  126. srv_cq_->Shutdown();
  127. while (cli_cq_.Next(&ignored_tag, &ignored_ok))
  128. ;
  129. while (srv_cq_->Next(&ignored_tag, &ignored_ok))
  130. ;
  131. [super tearDown];
  132. }
  133. - (void)ResetStub {
  134. std::shared_ptr<Channel> channel =
  135. CreateChannel(server_address_.str(), InsecureChannelCredentials());
  136. generic_stub_.reset(new GenericStub(channel));
  137. }
  138. - (void)SendRpc:(int)num_rpcs {
  139. [self SendRpc:num_rpcs check_deadline:false deadline:gpr_inf_future(GPR_CLOCK_MONOTONIC)];
  140. }
  141. - (void)SendRpc:(int)num_rpcs check_deadline:(bool)check_deadline deadline:(gpr_timespec)deadline {
  142. const std::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo");
  143. for (int i = 0; i < num_rpcs; i++) {
  144. Status recv_status;
  145. ClientContext cli_ctx;
  146. GenericServerContext srv_ctx;
  147. GenericServerAsyncReaderWriter stream(&srv_ctx);
  148. // The string needs to be long enough to test heap-based slice.
  149. /*send_request.set_message("Hello world. Hello world. Hello world.");*/
  150. if (check_deadline) {
  151. cli_ctx.set_deadline(deadline);
  152. }
  153. std::unique_ptr<GenericClientAsyncReaderWriter> call =
  154. generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
  155. [self client_ok:1];
  156. Slice send_slice = Slice("hello world", 11);
  157. std::unique_ptr<ByteBuffer> send_buffer =
  158. std::unique_ptr<ByteBuffer>(new ByteBuffer(&send_slice, 1));
  159. call->Write(*send_buffer, tag(2));
  160. // Send ByteBuffer can be destroyed after calling Write.
  161. send_buffer.reset();
  162. [self client_ok:2];
  163. call->WritesDone(tag(3));
  164. [self client_ok:3];
  165. generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), srv_cq_.get(), tag(4));
  166. [self verify_ok:srv_cq_.get() i:4 expect_ok:true];
  167. XCTAssertEqual(server_host_, srv_ctx.host().substr(0, server_host_.length()));
  168. XCTAssertEqual(kMethodName, srv_ctx.method());
  169. if (check_deadline) {
  170. XCTAssertTrue(gpr_time_similar(deadline, srv_ctx.raw_deadline(),
  171. gpr_time_from_millis(1000, GPR_TIMESPAN)));
  172. }
  173. ByteBuffer recv_buffer;
  174. stream.Read(&recv_buffer, tag(5));
  175. [self server_ok:5];
  176. XCTAssertTrue(byte_buffer_eq_string(&recv_buffer, "hello world"));
  177. send_buffer = std::unique_ptr<ByteBuffer>(new ByteBuffer(recv_buffer));
  178. stream.Write(*send_buffer, tag(6));
  179. send_buffer.reset();
  180. [self server_ok:6];
  181. stream.Finish(Status::OK, tag(7));
  182. [self server_ok:7];
  183. recv_buffer.Clear();
  184. call->Read(&recv_buffer, tag(8));
  185. [self client_ok:8];
  186. XCTAssertTrue(byte_buffer_eq_string(&recv_buffer, "hello world"));
  187. call->Finish(&recv_status, tag(9));
  188. [self client_ok:9];
  189. XCTAssertTrue(recv_status.ok());
  190. }
  191. }
  192. - (void)testSimpleRpc {
  193. [self ResetStub];
  194. [self SendRpc:1];
  195. }
  196. - (void)testSequentialRpcs {
  197. [self ResetStub];
  198. [self SendRpc:10];
  199. }
  200. + (void)setUp {
  201. grpc_test_init(0, NULL);
  202. }
  203. @end