xref: /aosp_15_r20/external/grpc-grpc/test/cpp/cocoapods/generic/generic.mm (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker/*
2*cc02d7e2SAndroid Build Coastguard Worker *
3*cc02d7e2SAndroid Build Coastguard Worker * Copyright 2017 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker *
5*cc02d7e2SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker * You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker *
9*cc02d7e2SAndroid Build Coastguard Worker *     http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker *
11*cc02d7e2SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker * limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker *
17*cc02d7e2SAndroid Build Coastguard Worker */
18*cc02d7e2SAndroid Build Coastguard Worker
19*cc02d7e2SAndroid Build Coastguard Worker#import <XCTest/XCTest.h>
20*cc02d7e2SAndroid Build Coastguard Worker
21*cc02d7e2SAndroid Build Coastguard Worker#include <sstream>
22*cc02d7e2SAndroid Build Coastguard Worker
23*cc02d7e2SAndroid Build Coastguard Worker#include <grpc/grpc.h>
24*cc02d7e2SAndroid Build Coastguard Worker#include <grpc/support/time.h>
25*cc02d7e2SAndroid Build Coastguard Worker#include <grpcpp/channel.h>
26*cc02d7e2SAndroid Build Coastguard Worker#include <grpcpp/client_context.h>
27*cc02d7e2SAndroid Build Coastguard Worker#include <grpcpp/create_channel.h>
28*cc02d7e2SAndroid Build Coastguard Worker#include <grpcpp/generic/async_generic_service.h>
29*cc02d7e2SAndroid Build Coastguard Worker#include <grpcpp/generic/generic_stub.h>
30*cc02d7e2SAndroid Build Coastguard Worker#include <grpcpp/server.h>
31*cc02d7e2SAndroid Build Coastguard Worker#include <grpcpp/server_builder.h>
32*cc02d7e2SAndroid Build Coastguard Worker#include <grpcpp/server_context.h>
33*cc02d7e2SAndroid Build Coastguard Worker#include <grpcpp/support/slice.h>
34*cc02d7e2SAndroid Build Coastguard Worker
35*cc02d7e2SAndroid Build Coastguard Worker#include "src/core/lib/gprpp/thd.h"
36*cc02d7e2SAndroid Build Coastguard Worker#include "test/core/util/port.h"
37*cc02d7e2SAndroid Build Coastguard Worker#include "test/core/util/test_config.h"
38*cc02d7e2SAndroid Build Coastguard Worker
39*cc02d7e2SAndroid Build Coastguard Workerusing std::chrono::system_clock;
40*cc02d7e2SAndroid Build Coastguard Workerusing namespace grpc;
41*cc02d7e2SAndroid Build Coastguard Worker
42*cc02d7e2SAndroid Build Coastguard Workervoid* tag(int i) { return (void*)(intptr_t)i; }
43*cc02d7e2SAndroid Build Coastguard Worker
44*cc02d7e2SAndroid Build Coastguard Workerstatic grpc_slice merge_slices(grpc_slice* slices, size_t nslices) {
45*cc02d7e2SAndroid Build Coastguard Worker  size_t i;
46*cc02d7e2SAndroid Build Coastguard Worker  size_t len = 0;
47*cc02d7e2SAndroid Build Coastguard Worker  uint8_t* cursor;
48*cc02d7e2SAndroid Build Coastguard Worker  grpc_slice out;
49*cc02d7e2SAndroid Build Coastguard Worker
50*cc02d7e2SAndroid Build Coastguard Worker  for (i = 0; i < nslices; i++) {
51*cc02d7e2SAndroid Build Coastguard Worker    len += GRPC_SLICE_LENGTH(slices[i]);
52*cc02d7e2SAndroid Build Coastguard Worker  }
53*cc02d7e2SAndroid Build Coastguard Worker
54*cc02d7e2SAndroid Build Coastguard Worker  out = grpc_slice_malloc(len);
55*cc02d7e2SAndroid Build Coastguard Worker  cursor = GRPC_SLICE_START_PTR(out);
56*cc02d7e2SAndroid Build Coastguard Worker
57*cc02d7e2SAndroid Build Coastguard Worker  for (i = 0; i < nslices; i++) {
58*cc02d7e2SAndroid Build Coastguard Worker    memcpy(cursor, GRPC_SLICE_START_PTR(slices[i]), GRPC_SLICE_LENGTH(slices[i]));
59*cc02d7e2SAndroid Build Coastguard Worker    cursor += GRPC_SLICE_LENGTH(slices[i]);
60*cc02d7e2SAndroid Build Coastguard Worker  }
61*cc02d7e2SAndroid Build Coastguard Worker
62*cc02d7e2SAndroid Build Coastguard Worker  return out;
63*cc02d7e2SAndroid Build Coastguard Worker}
64*cc02d7e2SAndroid Build Coastguard Worker
65*cc02d7e2SAndroid Build Coastguard Workerint byte_buffer_eq_string(ByteBuffer* bb, const char* str) {
66*cc02d7e2SAndroid Build Coastguard Worker  int res;
67*cc02d7e2SAndroid Build Coastguard Worker
68*cc02d7e2SAndroid Build Coastguard Worker  std::vector<Slice> slices;
69*cc02d7e2SAndroid Build Coastguard Worker  bb->Dump(&slices);
70*cc02d7e2SAndroid Build Coastguard Worker  grpc_slice* c_slices = new grpc_slice[slices.size()];
71*cc02d7e2SAndroid Build Coastguard Worker  for (int i = 0; i < slices.size(); i++) {
72*cc02d7e2SAndroid Build Coastguard Worker    c_slices[i] = slices[i].c_slice();
73*cc02d7e2SAndroid Build Coastguard Worker  }
74*cc02d7e2SAndroid Build Coastguard Worker  grpc_slice a = merge_slices(c_slices, slices.size());
75*cc02d7e2SAndroid Build Coastguard Worker  grpc_slice b = grpc_slice_from_copied_string(str);
76*cc02d7e2SAndroid Build Coastguard Worker  res = (GRPC_SLICE_LENGTH(a) == GRPC_SLICE_LENGTH(b)) &&
77*cc02d7e2SAndroid Build Coastguard Worker        (0 == memcmp(GRPC_SLICE_START_PTR(a), GRPC_SLICE_START_PTR(b), GRPC_SLICE_LENGTH(a)));
78*cc02d7e2SAndroid Build Coastguard Worker  grpc_slice_unref(a);
79*cc02d7e2SAndroid Build Coastguard Worker  grpc_slice_unref(b);
80*cc02d7e2SAndroid Build Coastguard Worker  for (int i = 0; i < slices.size(); i++) {
81*cc02d7e2SAndroid Build Coastguard Worker    grpc_slice_unref(c_slices[i]);
82*cc02d7e2SAndroid Build Coastguard Worker  }
83*cc02d7e2SAndroid Build Coastguard Worker  delete[] c_slices;
84*cc02d7e2SAndroid Build Coastguard Worker
85*cc02d7e2SAndroid Build Coastguard Worker  return res;
86*cc02d7e2SAndroid Build Coastguard Worker}
87*cc02d7e2SAndroid Build Coastguard Worker
88*cc02d7e2SAndroid Build Coastguard Worker@interface GenericTest : XCTestCase
89*cc02d7e2SAndroid Build Coastguard Worker
90*cc02d7e2SAndroid Build Coastguard Worker@end
91*cc02d7e2SAndroid Build Coastguard Worker
92*cc02d7e2SAndroid Build Coastguard Worker@implementation GenericTest {
93*cc02d7e2SAndroid Build Coastguard Worker  std::string server_host_;
94*cc02d7e2SAndroid Build Coastguard Worker  CompletionQueue cli_cq_;
95*cc02d7e2SAndroid Build Coastguard Worker  std::unique_ptr<ServerCompletionQueue> srv_cq_;
96*cc02d7e2SAndroid Build Coastguard Worker  std::unique_ptr<GenericStub> generic_stub_;
97*cc02d7e2SAndroid Build Coastguard Worker  std::unique_ptr<Server> server_;
98*cc02d7e2SAndroid Build Coastguard Worker  AsyncGenericService generic_service_;
99*cc02d7e2SAndroid Build Coastguard Worker  std::ostringstream server_address_;
100*cc02d7e2SAndroid Build Coastguard Worker}
101*cc02d7e2SAndroid Build Coastguard Worker
102*cc02d7e2SAndroid Build Coastguard Worker- (void)verify_ok:(grpc::CompletionQueue*)cq i:(int)i expect_ok:(bool)expect_ok {
103*cc02d7e2SAndroid Build Coastguard Worker  bool ok;
104*cc02d7e2SAndroid Build Coastguard Worker  void* got_tag;
105*cc02d7e2SAndroid Build Coastguard Worker  XCTAssertTrue(cq->Next(&got_tag, &ok));
106*cc02d7e2SAndroid Build Coastguard Worker  XCTAssertEqual(expect_ok, ok);
107*cc02d7e2SAndroid Build Coastguard Worker  XCTAssertEqual(tag(i), got_tag);
108*cc02d7e2SAndroid Build Coastguard Worker}
109*cc02d7e2SAndroid Build Coastguard Worker
110*cc02d7e2SAndroid Build Coastguard Worker- (void)server_ok:(int)i {
111*cc02d7e2SAndroid Build Coastguard Worker  [self verify_ok:srv_cq_.get() i:i expect_ok:true];
112*cc02d7e2SAndroid Build Coastguard Worker}
113*cc02d7e2SAndroid Build Coastguard Worker- (void)client_ok:(int)i {
114*cc02d7e2SAndroid Build Coastguard Worker  [self verify_ok:&cli_cq_ i:i expect_ok:true];
115*cc02d7e2SAndroid Build Coastguard Worker}
116*cc02d7e2SAndroid Build Coastguard Worker- (void)server_fail:(int)i {
117*cc02d7e2SAndroid Build Coastguard Worker  [self verify_ok:srv_cq_.get() i:i expect_ok:false];
118*cc02d7e2SAndroid Build Coastguard Worker}
119*cc02d7e2SAndroid Build Coastguard Worker- (void)client_fail:(int)i {
120*cc02d7e2SAndroid Build Coastguard Worker  [self verify_ok:&cli_cq_ i:i expect_ok:false];
121*cc02d7e2SAndroid Build Coastguard Worker}
122*cc02d7e2SAndroid Build Coastguard Worker
123*cc02d7e2SAndroid Build Coastguard Worker- (void)setUp {
124*cc02d7e2SAndroid Build Coastguard Worker  [super setUp];
125*cc02d7e2SAndroid Build Coastguard Worker
126*cc02d7e2SAndroid Build Coastguard Worker  server_host_ = "localhost";
127*cc02d7e2SAndroid Build Coastguard Worker  int port = grpc_pick_unused_port_or_die();
128*cc02d7e2SAndroid Build Coastguard Worker  server_address_ << server_host_ << ":" << port;
129*cc02d7e2SAndroid Build Coastguard Worker  // Setup server
130*cc02d7e2SAndroid Build Coastguard Worker  ServerBuilder builder;
131*cc02d7e2SAndroid Build Coastguard Worker  builder.AddListeningPort(server_address_.str(), InsecureServerCredentials());
132*cc02d7e2SAndroid Build Coastguard Worker  builder.RegisterAsyncGenericService(&generic_service_);
133*cc02d7e2SAndroid Build Coastguard Worker  // Include a second call to RegisterAsyncGenericService to make sure that
134*cc02d7e2SAndroid Build Coastguard Worker  // we get an error in the log, since it is not allowed to have 2 async
135*cc02d7e2SAndroid Build Coastguard Worker  // generic services
136*cc02d7e2SAndroid Build Coastguard Worker  builder.RegisterAsyncGenericService(&generic_service_);
137*cc02d7e2SAndroid Build Coastguard Worker  srv_cq_ = builder.AddCompletionQueue();
138*cc02d7e2SAndroid Build Coastguard Worker  server_ = builder.BuildAndStart();
139*cc02d7e2SAndroid Build Coastguard Worker}
140*cc02d7e2SAndroid Build Coastguard Worker
141*cc02d7e2SAndroid Build Coastguard Worker- (void)tearDown {
142*cc02d7e2SAndroid Build Coastguard Worker  // Put teardown code here. This method is called after the invocation of each test method in the
143*cc02d7e2SAndroid Build Coastguard Worker  // class.
144*cc02d7e2SAndroid Build Coastguard Worker  server_->Shutdown();
145*cc02d7e2SAndroid Build Coastguard Worker  void* ignored_tag;
146*cc02d7e2SAndroid Build Coastguard Worker  bool ignored_ok;
147*cc02d7e2SAndroid Build Coastguard Worker  cli_cq_.Shutdown();
148*cc02d7e2SAndroid Build Coastguard Worker  srv_cq_->Shutdown();
149*cc02d7e2SAndroid Build Coastguard Worker  while (cli_cq_.Next(&ignored_tag, &ignored_ok))
150*cc02d7e2SAndroid Build Coastguard Worker    ;
151*cc02d7e2SAndroid Build Coastguard Worker  while (srv_cq_->Next(&ignored_tag, &ignored_ok))
152*cc02d7e2SAndroid Build Coastguard Worker    ;
153*cc02d7e2SAndroid Build Coastguard Worker  [super tearDown];
154*cc02d7e2SAndroid Build Coastguard Worker}
155*cc02d7e2SAndroid Build Coastguard Worker
156*cc02d7e2SAndroid Build Coastguard Worker- (void)ResetStub {
157*cc02d7e2SAndroid Build Coastguard Worker  std::shared_ptr<Channel> channel =
158*cc02d7e2SAndroid Build Coastguard Worker      CreateChannel(server_address_.str(), InsecureChannelCredentials());
159*cc02d7e2SAndroid Build Coastguard Worker  generic_stub_.reset(new GenericStub(channel));
160*cc02d7e2SAndroid Build Coastguard Worker}
161*cc02d7e2SAndroid Build Coastguard Worker
162*cc02d7e2SAndroid Build Coastguard Worker- (void)SendRpc:(int)num_rpcs {
163*cc02d7e2SAndroid Build Coastguard Worker  [self SendRpc:num_rpcs check_deadline:false deadline:gpr_inf_future(GPR_CLOCK_MONOTONIC)];
164*cc02d7e2SAndroid Build Coastguard Worker}
165*cc02d7e2SAndroid Build Coastguard Worker
166*cc02d7e2SAndroid Build Coastguard Worker- (void)SendRpc:(int)num_rpcs check_deadline:(bool)check_deadline deadline:(gpr_timespec)deadline {
167*cc02d7e2SAndroid Build Coastguard Worker  const std::string kMethodName("/grpc.cpp.test.util.EchoTestService/Echo");
168*cc02d7e2SAndroid Build Coastguard Worker  for (int i = 0; i < num_rpcs; i++) {
169*cc02d7e2SAndroid Build Coastguard Worker    Status recv_status;
170*cc02d7e2SAndroid Build Coastguard Worker
171*cc02d7e2SAndroid Build Coastguard Worker    ClientContext cli_ctx;
172*cc02d7e2SAndroid Build Coastguard Worker    GenericServerContext srv_ctx;
173*cc02d7e2SAndroid Build Coastguard Worker    GenericServerAsyncReaderWriter stream(&srv_ctx);
174*cc02d7e2SAndroid Build Coastguard Worker
175*cc02d7e2SAndroid Build Coastguard Worker    // The string needs to be long enough to test heap-based slice.
176*cc02d7e2SAndroid Build Coastguard Worker    /*send_request.set_message("Hello world. Hello world. Hello world.");*/
177*cc02d7e2SAndroid Build Coastguard Worker
178*cc02d7e2SAndroid Build Coastguard Worker    if (check_deadline) {
179*cc02d7e2SAndroid Build Coastguard Worker      cli_ctx.set_deadline(deadline);
180*cc02d7e2SAndroid Build Coastguard Worker    }
181*cc02d7e2SAndroid Build Coastguard Worker
182*cc02d7e2SAndroid Build Coastguard Worker    std::unique_ptr<GenericClientAsyncReaderWriter> call =
183*cc02d7e2SAndroid Build Coastguard Worker        generic_stub_->Call(&cli_ctx, kMethodName, &cli_cq_, tag(1));
184*cc02d7e2SAndroid Build Coastguard Worker    [self client_ok:1];
185*cc02d7e2SAndroid Build Coastguard Worker    Slice send_slice = Slice("hello world", 11);
186*cc02d7e2SAndroid Build Coastguard Worker    std::unique_ptr<ByteBuffer> send_buffer =
187*cc02d7e2SAndroid Build Coastguard Worker        std::unique_ptr<ByteBuffer>(new ByteBuffer(&send_slice, 1));
188*cc02d7e2SAndroid Build Coastguard Worker    call->Write(*send_buffer, tag(2));
189*cc02d7e2SAndroid Build Coastguard Worker    // Send ByteBuffer can be destroyed after calling Write.
190*cc02d7e2SAndroid Build Coastguard Worker    send_buffer.reset();
191*cc02d7e2SAndroid Build Coastguard Worker    [self client_ok:2];
192*cc02d7e2SAndroid Build Coastguard Worker    call->WritesDone(tag(3));
193*cc02d7e2SAndroid Build Coastguard Worker    [self client_ok:3];
194*cc02d7e2SAndroid Build Coastguard Worker
195*cc02d7e2SAndroid Build Coastguard Worker    generic_service_.RequestCall(&srv_ctx, &stream, srv_cq_.get(), srv_cq_.get(), tag(4));
196*cc02d7e2SAndroid Build Coastguard Worker
197*cc02d7e2SAndroid Build Coastguard Worker    [self verify_ok:srv_cq_.get() i:4 expect_ok:true];
198*cc02d7e2SAndroid Build Coastguard Worker    XCTAssertEqual(server_host_, srv_ctx.host().substr(0, server_host_.length()));
199*cc02d7e2SAndroid Build Coastguard Worker    XCTAssertEqual(kMethodName, srv_ctx.method());
200*cc02d7e2SAndroid Build Coastguard Worker
201*cc02d7e2SAndroid Build Coastguard Worker    if (check_deadline) {
202*cc02d7e2SAndroid Build Coastguard Worker      XCTAssertTrue(gpr_time_similar(deadline, srv_ctx.raw_deadline(),
203*cc02d7e2SAndroid Build Coastguard Worker                                     gpr_time_from_millis(1000, GPR_TIMESPAN)));
204*cc02d7e2SAndroid Build Coastguard Worker    }
205*cc02d7e2SAndroid Build Coastguard Worker
206*cc02d7e2SAndroid Build Coastguard Worker    ByteBuffer recv_buffer;
207*cc02d7e2SAndroid Build Coastguard Worker    stream.Read(&recv_buffer, tag(5));
208*cc02d7e2SAndroid Build Coastguard Worker    [self server_ok:5];
209*cc02d7e2SAndroid Build Coastguard Worker    XCTAssertTrue(byte_buffer_eq_string(&recv_buffer, "hello world"));
210*cc02d7e2SAndroid Build Coastguard Worker
211*cc02d7e2SAndroid Build Coastguard Worker    send_buffer = std::unique_ptr<ByteBuffer>(new ByteBuffer(recv_buffer));
212*cc02d7e2SAndroid Build Coastguard Worker    stream.Write(*send_buffer, tag(6));
213*cc02d7e2SAndroid Build Coastguard Worker    send_buffer.reset();
214*cc02d7e2SAndroid Build Coastguard Worker    [self server_ok:6];
215*cc02d7e2SAndroid Build Coastguard Worker
216*cc02d7e2SAndroid Build Coastguard Worker    stream.Finish(Status::OK, tag(7));
217*cc02d7e2SAndroid Build Coastguard Worker    [self server_ok:7];
218*cc02d7e2SAndroid Build Coastguard Worker
219*cc02d7e2SAndroid Build Coastguard Worker    recv_buffer.Clear();
220*cc02d7e2SAndroid Build Coastguard Worker    call->Read(&recv_buffer, tag(8));
221*cc02d7e2SAndroid Build Coastguard Worker    [self client_ok:8];
222*cc02d7e2SAndroid Build Coastguard Worker    XCTAssertTrue(byte_buffer_eq_string(&recv_buffer, "hello world"));
223*cc02d7e2SAndroid Build Coastguard Worker
224*cc02d7e2SAndroid Build Coastguard Worker    call->Finish(&recv_status, tag(9));
225*cc02d7e2SAndroid Build Coastguard Worker    [self client_ok:9];
226*cc02d7e2SAndroid Build Coastguard Worker
227*cc02d7e2SAndroid Build Coastguard Worker    XCTAssertTrue(recv_status.ok());
228*cc02d7e2SAndroid Build Coastguard Worker  }
229*cc02d7e2SAndroid Build Coastguard Worker}
230*cc02d7e2SAndroid Build Coastguard Worker
231*cc02d7e2SAndroid Build Coastguard Worker- (void)testSimpleRpc {
232*cc02d7e2SAndroid Build Coastguard Worker  [self ResetStub];
233*cc02d7e2SAndroid Build Coastguard Worker  [self SendRpc:1];
234*cc02d7e2SAndroid Build Coastguard Worker}
235*cc02d7e2SAndroid Build Coastguard Worker
236*cc02d7e2SAndroid Build Coastguard Worker- (void)testSequentialRpcs {
237*cc02d7e2SAndroid Build Coastguard Worker  [self ResetStub];
238*cc02d7e2SAndroid Build Coastguard Worker  [self SendRpc:10];
239*cc02d7e2SAndroid Build Coastguard Worker}
240*cc02d7e2SAndroid Build Coastguard Worker
241*cc02d7e2SAndroid Build Coastguard Worker+ (void)setUp {
242*cc02d7e2SAndroid Build Coastguard Worker  grpc_test_init(NULL, NULL);
243*cc02d7e2SAndroid Build Coastguard Worker}
244*cc02d7e2SAndroid Build Coastguard Worker
245*cc02d7e2SAndroid Build Coastguard Worker@end
246