Motr  M0
conn_pool.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2013-2020 Seagate Technology LLC and/or its Affiliates
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  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #include <unistd.h>
24 
25 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_RPC
26 #include "lib/trace.h"
27 
28 #include "ut/ut.h"
29 #include "rpc/conn_pool.h"
30 #include "rpc/conn_pool_internal.h"
31 #include "lib/finject.h"
32 
33 #include "rpc/rpclib.h"
34 #include "rpc/ut/clnt_srv_ctx.c" /* sctx, cctx. NOTE: This is .c file */
35 #include "ut/cs_service.h" /* m0_cs_default_stypes */
36 #include "ut/misc.h"
37 
38 /* ----------------------------------------------------------------
39  * Tests
40  * ---------------------------------------------------------------- */
41 
42 static void rpc_conn_pool(void)
43 {
44  struct m0_rpc_conn_pool pool = {};
45  struct m0_rpc_session *session = NULL;
46  struct m0_rpc_session *session2 = NULL;
47  int rc;
48  struct m0_rpc_conn_pool_item *pool_item;
49 
51 
54  M0_ASSERT(rc == 0);
55  M0_UT_ASSERT(rpc_conn_pool_items_tlist_is_empty(&pool.cp_items));
56 
57  /* new connection */
60  M0_UT_ASSERT(rc == 0);
61  pool_item = rpc_conn_pool_items_tlist_head(&pool.cp_items);
62  M0_UT_ASSERT(pool_item ==
63  rpc_conn_pool_items_tlist_tail(&pool.cp_items));
65  M0_UT_ASSERT(pool_item->cpi_users_nr == 1);
66 
68  /* Busy cycle to wait until session is established */
69  }
70 
71  /* reuse connection */
73  M0_UT_ASSERT(rc == 0);
74  M0_UT_ASSERT(session == session2);
75  pool_item = rpc_conn_pool_items_tlist_head(&pool.cp_items);
76  M0_UT_ASSERT(pool_item ==
77  rpc_conn_pool_items_tlist_tail(&pool.cp_items));
79  M0_UT_ASSERT(pool_item->cpi_users_nr == 2);
80 
81  /* put back #1 */
82  m0_rpc_conn_pool_put(&pool, session2);
83  pool_item = rpc_conn_pool_items_tlist_head(&pool.cp_items);
84  M0_UT_ASSERT(pool_item ==
85  rpc_conn_pool_items_tlist_tail(&pool.cp_items));
87  M0_UT_ASSERT(pool_item->cpi_users_nr == 1);
88 
89  /* put back #2 */
90  m0_rpc_conn_pool_put(&pool, session2);
91  pool_item = rpc_conn_pool_items_tlist_head(&pool.cp_items);
92  M0_UT_ASSERT(pool_item ==
93  rpc_conn_pool_items_tlist_tail(&pool.cp_items));
95  M0_UT_ASSERT(pool_item->cpi_users_nr == 0);
96 
99 }
100 
103  struct m0_clink clink;
104  bool cb_called;
105 };
106 
108 static struct m0_mutex cond_mutex;
109 
110 static bool pending_cp_clink_cb(struct m0_clink *clink)
111 {
112  struct cp_pending_item *cp_pending;
113 
115  cp_pending = container_of(clink, struct cp_pending_item, clink);
116  cp_pending->cb_called = true;
119 
120  return true;
121 }
122 
123 static void rpc_conn_pool_async(void) {
124  struct m0_rpc_conn_pool pool = {};
125  struct m0_rpc_session *session = NULL;
126  int rc;
127  struct cp_pending_item *cp_pending;
128  struct m0_rpc_conn_pool_item *pool_item;
129 
131 
134  M0_ASSERT(rc == 0);
135  M0_UT_ASSERT(rpc_conn_pool_items_tlist_is_empty(&pool.cp_items));
136 
137  /* Initiate new connection */
139  M0_UT_ASSERT(rc == -EBUSY);
140  pool_item = rpc_conn_pool_items_tlist_head(&pool.cp_items);
141  M0_UT_ASSERT(pool_item ==
142  rpc_conn_pool_items_tlist_tail(&pool.cp_items));
143 
144  /* Call connect once again */
146  M0_UT_ASSERT(rc == -EBUSY);
147 
148  /* Configure callback */
149  M0_ALLOC_PTR(cp_pending);
150 
153 
154  m0_clink_init(&cp_pending->clink, pending_cp_clink_cb);
155  cp_pending->clink.cl_is_oneshot = true;
156  cp_pending->session = session;
157  cp_pending->cb_called = false;
159  &cp_pending->clink);
160 
164 
165  M0_UT_ASSERT(cp_pending->cb_called);
167  cp_pending->session));
168 
171 
172  /* Connect once again */
174  M0_UT_ASSERT(rc == 0);
175 
176  m0_free(cp_pending);
179 }
180 
182  .ts_name = "rpc-conn-pool-ut",
183  .ts_tests = {
184  { "rpc-conn-pool", rpc_conn_pool},
185  { "rpc-conn-pool-async", rpc_conn_pool_async},
186  { NULL, NULL },
187  },
188 };
189 
190 #undef M0_TRACE_SUBSYSTEM
191 
192 /*
193  * Local variables:
194  * c-indentation-style: "K&R"
195  * c-basic-offset: 8
196  * tab-width: 8
197  * fill-column: 80
198  * scroll-step: 1
199  * End:
200  */
Definition: cond.h:99
M0_INTERNAL void m0_mutex_unlock(struct m0_mutex *mutex)
Definition: mutex.c:66
M0_INTERNAL void m0_rpc_conn_pool_fini(struct m0_rpc_conn_pool *pool)
Definition: conn_pool.c:345
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_clink_init(struct m0_clink *link, m0_chan_cb_t cb)
Definition: chan.c:201
const m0_time_t M0_TIME_NEVER
Definition: time.c:108
M0_INTERNAL int m0_rpc_conn_pool_init(struct m0_rpc_conn_pool *pool, struct m0_rpc_machine *rpc_mach, m0_time_t conn_timeout, uint64_t max_rpcs_in_flight)
Definition: conn_pool.c:325
static struct m0_rpc_client_ctx cctx
Definition: rconfc.c:69
#define container_of(ptr, type, member)
Definition: misc.h:33
static struct m0_rpc_session session
Definition: formation2.c:38
M0_INTERNAL void m0_mutex_lock(struct m0_mutex *mutex)
Definition: mutex.c:49
Definition: ut.h:77
M0_INTERNAL void m0_cond_init(struct m0_cond *cond, struct m0_mutex *mutex)
Definition: cond.c:40
#define M0_ASSERT(cond)
M0_INTERNAL void m0_cond_fini(struct m0_cond *cond)
Definition: cond.c:46
M0_INTERNAL void m0_cond_signal(struct m0_cond *cond)
Definition: cond.c:94
static void stop_rpc_client_and_server(void)
Definition: note.c:126
M0_INTERNAL struct m0_chan * m0_rpc_conn_pool_session_chan(struct m0_rpc_session *session)
Definition: conn_pool.c:304
M0_INTERNAL void m0_mutex_init(struct m0_mutex *mutex)
Definition: mutex.c:35
struct m0_clink clink
Definition: conn_pool.c:103
static struct m0_clink clink[RDWR_REQUEST_MAX]
M0_INTERNAL bool m0_rpc_conn_pool_session_established(struct m0_rpc_session *session)
Definition: conn_pool.c:310
static struct m0_pool pool
Definition: iter_ut.c:58
static struct m0_mutex cond_mutex
Definition: conn_pool.c:108
void m0_clink_add_lock(struct m0_chan *chan, struct m0_clink *link)
Definition: chan.c:255
const char * ts_name
Definition: ut.h:99
struct m0_ut_suite rpc_conn_pool_ut
Definition: conn_pool.c:181
M0_INTERNAL void m0_cond_wait(struct m0_cond *cond)
Definition: cond.c:52
M0_INTERNAL int m0_rpc_conn_pool_get_async(struct m0_rpc_conn_pool *pool, const char *remote_ep, struct m0_rpc_session **session)
Definition: conn_pool.c:230
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
static struct m0_cond connection_pending_cond
Definition: conn_pool.c:107
M0_INTERNAL void m0_mutex_fini(struct m0_mutex *mutex)
Definition: mutex.c:42
static void rpc_conn_pool(void)
Definition: conn_pool.c:42
static void rpc_conn_pool_async(void)
Definition: conn_pool.c:123
static bool pending_cp_clink_cb(struct m0_clink *clink)
Definition: conn_pool.c:110
struct m0_rpc_machine rcx_rpc_machine
Definition: rpclib.h:145
struct m0_rpc_session * session
Definition: conn_pool.c:102
#define SERVER_ENDPOINT_ADDR
Definition: common.h:30
M0_INTERNAL int m0_rpc_conn_pool_get_sync(struct m0_rpc_conn_pool *pool, const char *remote_ep, struct m0_rpc_session **session)
Definition: conn_pool.c:197
void m0_free(void *data)
Definition: memory.c:146
Definition: mutex.h:47
int32_t rc
Definition: trigger_fop.h:47
static void start_rpc_client_and_server(void)
Definition: note.c:111
#define M0_UT_ASSERT(a)
Definition: ut.h:46
M0_INTERNAL void m0_rpc_conn_pool_put(struct m0_rpc_conn_pool *pool, struct m0_rpc_session *session)
Definition: conn_pool.c:288