• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Copyright 2016 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 /* With the addition of a libuv endpoint, sockaddr.h now includes uv.h when
20    using that endpoint. Because of various transitive includes in uv.h,
21    including windows.h on Windows, uv.h must be included before other system
22    headers. Therefore, sockaddr.h must always be included first */
23 #include "src/core/lib/iomgr/sockaddr.h"
24 
25 #include <inttypes.h>
26 
27 #include <string>
28 
29 #include "absl/strings/str_format.h"
30 
31 #include "test/core/util/mock_endpoint.h"
32 
33 #include <grpc/support/alloc.h>
34 #include <grpc/support/string_util.h>
35 #include "src/core/lib/iomgr/sockaddr.h"
36 
37 typedef struct mock_endpoint {
38   grpc_endpoint base;
39   gpr_mu mu;
40   void (*on_write)(grpc_slice slice);
41   grpc_slice_buffer read_buffer;
42   grpc_slice_buffer* on_read_out;
43   grpc_closure* on_read;
44   grpc_resource_user* resource_user;
45 } mock_endpoint;
46 
me_read(grpc_endpoint * ep,grpc_slice_buffer * slices,grpc_closure * cb,bool)47 static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices,
48                     grpc_closure* cb, bool /*urgent*/) {
49   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
50   gpr_mu_lock(&m->mu);
51   if (m->read_buffer.count > 0) {
52     grpc_slice_buffer_swap(&m->read_buffer, slices);
53     grpc_core::ExecCtx::Run(DEBUG_LOCATION, cb, GRPC_ERROR_NONE);
54   } else {
55     m->on_read = cb;
56     m->on_read_out = slices;
57   }
58   gpr_mu_unlock(&m->mu);
59 }
60 
me_write(grpc_endpoint * ep,grpc_slice_buffer * slices,grpc_closure * cb,void *)61 static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices,
62                      grpc_closure* cb, void* /*arg*/) {
63   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
64   for (size_t i = 0; i < slices->count; i++) {
65     m->on_write(slices->slices[i]);
66   }
67   grpc_core::ExecCtx::Run(DEBUG_LOCATION, cb, GRPC_ERROR_NONE);
68 }
69 
me_add_to_pollset(grpc_endpoint *,grpc_pollset *)70 static void me_add_to_pollset(grpc_endpoint* /*ep*/,
71                               grpc_pollset* /*pollset*/) {}
72 
me_add_to_pollset_set(grpc_endpoint *,grpc_pollset_set *)73 static void me_add_to_pollset_set(grpc_endpoint* /*ep*/,
74                                   grpc_pollset_set* /*pollset*/) {}
75 
me_delete_from_pollset_set(grpc_endpoint *,grpc_pollset_set *)76 static void me_delete_from_pollset_set(grpc_endpoint* /*ep*/,
77                                        grpc_pollset_set* /*pollset*/) {}
78 
me_shutdown(grpc_endpoint * ep,grpc_error * why)79 static void me_shutdown(grpc_endpoint* ep, grpc_error* why) {
80   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
81   gpr_mu_lock(&m->mu);
82   if (m->on_read) {
83     grpc_core::ExecCtx::Run(DEBUG_LOCATION, m->on_read,
84                             GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
85                                 "Endpoint Shutdown", &why, 1));
86     m->on_read = nullptr;
87   }
88   gpr_mu_unlock(&m->mu);
89   grpc_resource_user_shutdown(m->resource_user);
90   GRPC_ERROR_UNREF(why);
91 }
92 
me_destroy(grpc_endpoint * ep)93 static void me_destroy(grpc_endpoint* ep) {
94   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
95   grpc_slice_buffer_destroy(&m->read_buffer);
96   grpc_resource_user_unref(m->resource_user);
97   gpr_mu_destroy(&m->mu);
98   gpr_free(m);
99 }
100 
me_get_peer(grpc_endpoint *)101 static char* me_get_peer(grpc_endpoint* /*ep*/) {
102   return gpr_strdup("fake:mock_endpoint");
103 }
104 
me_get_resource_user(grpc_endpoint * ep)105 static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) {
106   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
107   return m->resource_user;
108 }
109 
me_get_fd(grpc_endpoint *)110 static int me_get_fd(grpc_endpoint* /*ep*/) { return -1; }
111 
me_can_track_err(grpc_endpoint *)112 static bool me_can_track_err(grpc_endpoint* /*ep*/) { return false; }
113 
114 static const grpc_endpoint_vtable vtable = {me_read,
115                                             me_write,
116                                             me_add_to_pollset,
117                                             me_add_to_pollset_set,
118                                             me_delete_from_pollset_set,
119                                             me_shutdown,
120                                             me_destroy,
121                                             me_get_resource_user,
122                                             me_get_peer,
123                                             me_get_fd,
124                                             me_can_track_err};
125 
grpc_mock_endpoint_create(void (* on_write)(grpc_slice slice),grpc_resource_quota * resource_quota)126 grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice),
127                                          grpc_resource_quota* resource_quota) {
128   mock_endpoint* m = static_cast<mock_endpoint*>(gpr_malloc(sizeof(*m)));
129   m->base.vtable = &vtable;
130   std::string name = absl::StrFormat("mock_endpoint_%" PRIxPTR, (intptr_t)m);
131   m->resource_user = grpc_resource_user_create(resource_quota, name.c_str());
132   grpc_slice_buffer_init(&m->read_buffer);
133   gpr_mu_init(&m->mu);
134   m->on_write = on_write;
135   m->on_read = nullptr;
136   return &m->base;
137 }
138 
grpc_mock_endpoint_put_read(grpc_endpoint * ep,grpc_slice slice)139 void grpc_mock_endpoint_put_read(grpc_endpoint* ep, grpc_slice slice) {
140   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
141   gpr_mu_lock(&m->mu);
142   if (m->on_read != nullptr) {
143     grpc_slice_buffer_add(m->on_read_out, slice);
144     grpc_core::ExecCtx::Run(DEBUG_LOCATION, m->on_read, GRPC_ERROR_NONE);
145     m->on_read = nullptr;
146   } else {
147     grpc_slice_buffer_add(&m->read_buffer, slice);
148   }
149   gpr_mu_unlock(&m->mu);
150 }
151