• 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 "test/core/util/mock_endpoint.h"
26 
27 #include <inttypes.h>
28 
29 #include <grpc/support/alloc.h>
30 #include <grpc/support/string_util.h>
31 #include "src/core/lib/iomgr/sockaddr.h"
32 
33 typedef struct mock_endpoint {
34   grpc_endpoint base;
35   gpr_mu mu;
36   void (*on_write)(grpc_slice slice);
37   grpc_slice_buffer read_buffer;
38   grpc_slice_buffer* on_read_out;
39   grpc_closure* on_read;
40   grpc_resource_user* resource_user;
41 } mock_endpoint;
42 
me_read(grpc_endpoint * ep,grpc_slice_buffer * slices,grpc_closure * cb)43 static void me_read(grpc_endpoint* ep, grpc_slice_buffer* slices,
44                     grpc_closure* cb) {
45   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
46   gpr_mu_lock(&m->mu);
47   if (m->read_buffer.count > 0) {
48     grpc_slice_buffer_swap(&m->read_buffer, slices);
49     GRPC_CLOSURE_SCHED(cb, GRPC_ERROR_NONE);
50   } else {
51     m->on_read = cb;
52     m->on_read_out = slices;
53   }
54   gpr_mu_unlock(&m->mu);
55 }
56 
me_write(grpc_endpoint * ep,grpc_slice_buffer * slices,grpc_closure * cb,void * arg)57 static void me_write(grpc_endpoint* ep, grpc_slice_buffer* slices,
58                      grpc_closure* cb, void* arg) {
59   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
60   for (size_t i = 0; i < slices->count; i++) {
61     m->on_write(slices->slices[i]);
62   }
63   GRPC_CLOSURE_SCHED(cb, GRPC_ERROR_NONE);
64 }
65 
me_add_to_pollset(grpc_endpoint * ep,grpc_pollset * pollset)66 static void me_add_to_pollset(grpc_endpoint* ep, grpc_pollset* pollset) {}
67 
me_add_to_pollset_set(grpc_endpoint * ep,grpc_pollset_set * pollset)68 static void me_add_to_pollset_set(grpc_endpoint* ep,
69                                   grpc_pollset_set* pollset) {}
70 
me_delete_from_pollset_set(grpc_endpoint * ep,grpc_pollset_set * pollset)71 static void me_delete_from_pollset_set(grpc_endpoint* ep,
72                                        grpc_pollset_set* pollset) {}
73 
me_shutdown(grpc_endpoint * ep,grpc_error * why)74 static void me_shutdown(grpc_endpoint* ep, grpc_error* why) {
75   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
76   gpr_mu_lock(&m->mu);
77   if (m->on_read) {
78     GRPC_CLOSURE_SCHED(m->on_read,
79                        GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
80                            "Endpoint Shutdown", &why, 1));
81     m->on_read = nullptr;
82   }
83   gpr_mu_unlock(&m->mu);
84   grpc_resource_user_shutdown(m->resource_user);
85   GRPC_ERROR_UNREF(why);
86 }
87 
me_destroy(grpc_endpoint * ep)88 static void me_destroy(grpc_endpoint* ep) {
89   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
90   grpc_slice_buffer_destroy(&m->read_buffer);
91   grpc_resource_user_unref(m->resource_user);
92   gpr_free(m);
93 }
94 
me_get_peer(grpc_endpoint * ep)95 static char* me_get_peer(grpc_endpoint* ep) {
96   return gpr_strdup("fake:mock_endpoint");
97 }
98 
me_get_resource_user(grpc_endpoint * ep)99 static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) {
100   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
101   return m->resource_user;
102 }
103 
me_get_fd(grpc_endpoint * ep)104 static int me_get_fd(grpc_endpoint* ep) { return -1; }
105 
106 static const grpc_endpoint_vtable vtable = {
107     me_read,
108     me_write,
109     me_add_to_pollset,
110     me_add_to_pollset_set,
111     me_delete_from_pollset_set,
112     me_shutdown,
113     me_destroy,
114     me_get_resource_user,
115     me_get_peer,
116     me_get_fd,
117 };
118 
grpc_mock_endpoint_create(void (* on_write)(grpc_slice slice),grpc_resource_quota * resource_quota)119 grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice),
120                                          grpc_resource_quota* resource_quota) {
121   mock_endpoint* m = static_cast<mock_endpoint*>(gpr_malloc(sizeof(*m)));
122   m->base.vtable = &vtable;
123   char* name;
124   gpr_asprintf(&name, "mock_endpoint_%" PRIxPTR, (intptr_t)m);
125   m->resource_user = grpc_resource_user_create(resource_quota, name);
126   gpr_free(name);
127   grpc_slice_buffer_init(&m->read_buffer);
128   gpr_mu_init(&m->mu);
129   m->on_write = on_write;
130   m->on_read = nullptr;
131   return &m->base;
132 }
133 
grpc_mock_endpoint_put_read(grpc_endpoint * ep,grpc_slice slice)134 void grpc_mock_endpoint_put_read(grpc_endpoint* ep, grpc_slice slice) {
135   mock_endpoint* m = reinterpret_cast<mock_endpoint*>(ep);
136   gpr_mu_lock(&m->mu);
137   if (m->on_read != nullptr) {
138     grpc_slice_buffer_add(m->on_read_out, slice);
139     GRPC_CLOSURE_SCHED(m->on_read, GRPC_ERROR_NONE);
140     m->on_read = nullptr;
141   } else {
142     grpc_slice_buffer_add(&m->read_buffer, slice);
143   }
144   gpr_mu_unlock(&m->mu);
145 }
146