Motr  M0
xcode_fop_test.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-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 "lib/errno.h"
24 #include "lib/memory.h"
25 #include "lib/bitstring.h"
26 #include "lib/misc.h"
27 #include "lib/vec.h"
28 #include "ut/ut.h"
29 #include "motr/init.h"
30 #include "fop/fop.h"
31 #include "xcode/ut/xcode_fops_ff.h"
32 
33 #include "rpc/rpc_opcodes.h"
34 #include "rpc/rpc.h"
35 #include "net/net.h"
36 
38 enum {
41  TEST_OFFSET = 0xABCDEF,
42  TEST_COUNT = 0x123456,
43  TEST_INDEX = 0xDEAD,
44  TEST_VAL = 0x1111,
45  TEST_CNT_1 = 0x1234,
46  TEST_FLAG = 0x1,
50 };
51 
52 static char *fop_test_buf = "test fop encode/decode";
53 
55 };
56 
58 
59 static void fop_verify( struct m0_fop *fop)
60 {
61  void *fdata;
62  struct m0_fop_test *ftest;
63  int i;
64  int j;
65 
66  fdata = m0_fop_data(fop);
67  ftest = (struct m0_fop_test *)fdata;
68  M0_UT_ASSERT(ftest->ft_cnt == TEST_COUNT);
69  M0_UT_ASSERT(ftest->ft_offset == TEST_OFFSET);
70  M0_UT_ASSERT(ftest->ft_arr.fta_cnt == ARR_COUNT_1);
71  M0_UT_ASSERT(ftest->ft_arr.fta_data->da_cnt == ARR_COUNT_2);
72  for (i = 0; i < ftest->ft_arr.fta_cnt; ++i) {
73  int index = TEST_INDEX;
74  int test_val = TEST_VAL;
75  uint32_t test_cnt = TEST_CNT_1;
76 
77  for (j = 0; j < ftest->ft_arr.fta_data->da_cnt; ++j) {
78  int cnt;
79  uint64_t temp;
80  char *c;
81 
82  temp = ftest->ft_arr.fta_data[i].da_pair[j].p_offset;
83  M0_UT_ASSERT(temp == test_val);
84  test_val++;
85  temp = ftest->ft_arr.fta_data[i].da_pair[j].p_cnt;
86  M0_UT_ASSERT(temp == test_cnt);
87  test_cnt++;
88  temp =
89  ftest->ft_arr.fta_data[i].da_pair[j].p_key.tk_index;
90  M0_UT_ASSERT(temp == index);
91  index++;
92  temp =
93  ftest->ft_arr.fta_data[i].da_pair[j].p_key.tk_val;
94  M0_UT_ASSERT(temp == index);
95  index++;
96  temp =
97  ftest->ft_arr.fta_data[i].da_pair[j].p_key.tk_flag;
98  M0_UT_ASSERT(temp == TEST_FLAG);
99  cnt = ftest->ft_arr.fta_data[i].da_pair[j].p_buf.tb_cnt;
101  c = (char *)
102  ftest->ft_arr.fta_data[i].da_pair[j].p_buf.tb_buf;
103  temp = strcmp(c, fop_test_buf);
104  M0_UT_ASSERT(temp == 0);
105  }
106  }
107 }
108 
110 static void fop_free(struct m0_fop *fop)
111 {
112  struct m0_fop_test *ccf1;
113  unsigned int i;
114  unsigned int j;
115 
116  ccf1 = m0_fop_data(fop);
117  for (i = 0; i < ccf1->ft_arr.fta_cnt; ++i) {
118  for (j = 0; j < ccf1->ft_arr.fta_data->da_cnt; ++j) {
119  uint8_t *test_buf;
120 
121  test_buf =
122  ccf1->ft_arr.fta_data[i].da_pair[j].p_buf.tb_buf;
123  m0_free(test_buf);
124  }
125  }
126  for (i = 0; i < ccf1->ft_arr.fta_cnt; ++i)
127  m0_free(ccf1->ft_arr.fta_data[i].da_pair);
128 
129  m0_free(ccf1->ft_arr.fta_data);
131  m0_free(fop);
132 }
133 
134 /*
135  Manually calculate the size of the fop based on the .ff file.
136  For the current "test_fop" defined in xcode/ut/xcode_fops.ff, we have -
137 
138  struct m0_test_buf {
139  uint32_t tb_cnt(33); 4
140  uint8_t *tb_buf; + 33 (tb_cnt * uint8_t = 33 * 1)
141  }; = 37
142 
143  struct m0_test_key {
144  uint32_t tk_index; 4
145  uint64_t tk_val; + 8
146  uint8_t tk_flag; + 1
147  }; = 13
148 
149  struct m0_pair {
150  uint64_t p_offset; 8
151  uint32_t p_cnt; + 4
152  struct m0_test_key p_key; + 13
153  struct m0_test_buf p_buf; + 37
154  }; = 62
155 
156  struct m0_desc_arr {
157  uint32_t da_cnt(11); 4
158  struct m0_pair *da_pair; + 682 (da_cnt * da_pair = 11 * 62)
159  }; = 686
160 
161  struct m0_fop_test_arr {
162  uint32_t fta_cnt(10); 4
163  struct m0_desc_arr *fta_data; + 6860 (fta_cnt * fta_data = 10 * 686)
164  }; = 6864
165 
166  struct m0_fop_test {
167  uint32_t ft_cnt; 4
168  uint64_t ft_offset; + 8
169  struct m0_fop_test_arr ft_arr; + 6864
170  }; = 6876
171 
172  */
173 
175 static void test_fop_encdec(void)
176 {
177  int rc;
178  struct m0_bufvec_cursor cur;
179  void *cur_addr;
180  int i;
181  int j;
182  struct m0_fop *f1;
183  struct m0_fop *fd1;
184  struct m0_net_buffer *nb;
185  struct m0_fop_test *ccf1;
186  struct m0_xcode_ctx xctx;
187  struct m0_xcode_ctx xctx1;
188  size_t fop_size;
189  size_t act_fop_size = 6876;
190  struct m0_rpc_machine machine;
191 
192  m0_test_buf_xc->xct_flags = M0_XCODE_TYPE_FLAG_DOM_RPC;
193  m0_test_key_xc->xct_flags = M0_XCODE_TYPE_FLAG_DOM_RPC;
194  m0_pair_xc->xct_flags = M0_XCODE_TYPE_FLAG_DOM_RPC;
195  m0_desc_arr_xc->xct_flags = M0_XCODE_TYPE_FLAG_DOM_RPC;
196  m0_fop_test_arr_xc->xct_flags = M0_XCODE_TYPE_FLAG_DOM_RPC;
197  m0_fop_test_xc->xct_flags = M0_XCODE_TYPE_FLAG_DOM_RPC;
198 
200  .name = "xcode fop test",
202  .xt = m0_fop_test_xc,
203  .rpc_flags = 0,
204  .fop_ops = &test_ops);
205 
206  /* Allocate a fop and populate its fields with test values. */
208  M0_UT_ASSERT(f1 != NULL);
209 
210  ccf1 = m0_fop_data(f1);
211  M0_ASSERT(ccf1 != NULL);
212  ccf1->ft_arr.fta_cnt = ARR_COUNT_1;
213  ccf1->ft_cnt = TEST_COUNT;
214  ccf1->ft_offset = TEST_OFFSET;
215  M0_ALLOC_ARR(ccf1->ft_arr.fta_data, ccf1->ft_arr.fta_cnt);
216  M0_UT_ASSERT(ccf1->ft_arr.fta_data != NULL);
217 
218  for (i = 0; i < ccf1->ft_arr.fta_cnt; ++i) {
219  ccf1->ft_arr.fta_data[i].da_cnt=ARR_COUNT_2;
220  M0_ALLOC_ARR(ccf1->ft_arr.fta_data[i].da_pair,
221  ccf1->ft_arr.fta_data[i].da_cnt);
222  M0_UT_ASSERT(ccf1->ft_arr.fta_data[i].da_pair != NULL);
223  }
224 
225  for (i = 0; i < ccf1->ft_arr.fta_cnt; ++i) {
226  uint64_t ival = TEST_VAL;
227  int index = TEST_INDEX;
228  char flag = TEST_FLAG;
229  uint32_t cnt = TEST_CNT_1;
230 
231  for (j = 0; j < ccf1->ft_arr.fta_data->da_cnt; ++j) {
232  uint8_t *test_buf;
233 
234  ccf1->ft_arr.fta_data[i].da_pair[j].p_offset = ival++;
235  ccf1->ft_arr.fta_data[i].da_pair[j].p_cnt = cnt++;
236  ccf1->ft_arr.fta_data[i].da_pair[j].p_key.tk_index =
237  index++;
238  ccf1->ft_arr.fta_data[i].da_pair[j].p_key.tk_val =
239  index++;
240  ccf1->ft_arr.fta_data[i].da_pair[j].p_key.tk_flag =
241  flag;
242  M0_ALLOC_ARR(test_buf, TEST_BUF_SIZE);
243  M0_UT_ASSERT(test_buf != NULL);
244  ccf1->ft_arr.fta_data[i].da_pair[j].p_buf.tb_buf =
245  test_buf;
246  ccf1->ft_arr.fta_data[i].da_pair[j].p_buf.tb_cnt =
248  memcpy(ccf1->ft_arr.fta_data[i].da_pair[j].p_buf.tb_buf,
249  fop_test_buf, strlen(fop_test_buf));
250  }
251  }
252 
253  /* Check the size of the fop using the interfaces. */
254  m0_xcode_ctx_init(&xctx, &(struct m0_xcode_obj) {
255  f1->f_type->ft_xt, ccf1 });
256  fop_size = m0_xcode_length(&xctx);
257  M0_UT_ASSERT(fop_size == act_fop_size);
258 
259  /* Allocate a netbuf and a bufvec, check alignments. */
260  M0_ALLOC_PTR(nb);
263  cur_addr = m0_bufvec_cursor_addr(&cur);
264  M0_UT_ASSERT(M0_IS_8ALIGNED(cur_addr));
265 
266  m0_xcode_ctx_init(&xctx, &(struct m0_xcode_obj) {
267  f1->f_type->ft_xt, ccf1 });
269 
270  /* Encode the fop into the bufvec. */
271  rc = m0_xcode_encode(&xctx);
272  M0_UT_ASSERT(rc == 0);
273  cur_addr = m0_bufvec_cursor_addr(&cur);
274  M0_UT_ASSERT(M0_IS_8ALIGNED(cur_addr));
275  /*
276  Allocate a fop for decode. The payload from the bufvec will be
277  decoded into this fop.
278  Since this is a decode fop we do not allocate fop->f_data.fd_data
279  since this allocation is done by xcode.
280  For more, see comments in m0_fop_item_type_default_decode()
281  */
282  M0_ALLOC_PTR(fd1);
283  M0_UT_ASSERT(fd1 != NULL);
286  cur_addr = m0_bufvec_cursor_addr(&cur);
287  M0_UT_ASSERT(M0_IS_8ALIGNED(cur_addr));
288 
289  /* Decode the payload from bufvec into the fop. */
290  m0_xcode_ctx_init(&xctx1, &(struct m0_xcode_obj) {
291  fd1->f_type->ft_xt, NULL });
292  xctx1.xcx_alloc = m0_xcode_alloc;
293  xctx1.xcx_buf = cur;
294  rc = m0_xcode_decode(&xctx1);
295  M0_UT_ASSERT(rc == 0);
296  fd1->f_data.fd_data = m0_xcode_ctx_top(&xctx1);
297 
298  cur_addr = m0_bufvec_cursor_addr(&cur);
299  M0_UT_ASSERT(M0_IS_8ALIGNED(cur_addr));
300 
301  /* Verify the fop data. */
302  fop_verify(fd1);
303 
304  /* Clean up and free all the allocated memory. */
306  m0_free(nb);
307  fop_free(f1);
308  fop_free(fd1);
310 }
311 
312 static int xcode_bufvec_fop_init(void)
313 {
314  m0_xc_xcode_fops_init();
315  return 0;
316 }
317 
318 static int xcode_bufvec_fop_fini(void)
319 {
320  m0_xc_xcode_fops_fini();
321  return 0;
322 }
323 
325  .ts_name = "xcode_bufvec_fop-ut",
326  .ts_init = xcode_bufvec_fop_init,
327  .ts_fini = xcode_bufvec_fop_fini,
328  .ts_tests = {
329  { "xcode_bufvec_fop", test_fop_encdec },
330  { NULL, NULL }
331  }
332 };
333 
334 /*
335  * Local variables:
336  * c-indentation-style: "K&R"
337  * c-basic-offset: 8
338  * tab-width: 8
339  * fill-column: 80
340  * scroll-step: 1
341  * End:
342  */
static void fop_verify(struct m0_fop *fop)
void * fd_data
Definition: fop.h:75
M0_INTERNAL void * m0_xcode_ctx_top(const struct m0_xcode_ctx *ctx)
Definition: xcode.c:746
#define M0_ALLOC_ARR(arr, nr)
Definition: memory.h:84
#define NULL
Definition: misc.h:38
static struct buffer * cur(struct m0_addb2_mach *mach, m0_bcount_t space)
Definition: addb2.c:791
struct m0_bufvec nb_buffer
Definition: net.h:1322
#define M0_FOP_TYPE_INIT(ft,...)
Definition: fop.h:307
static char * fop_test_buf
M0_INTERNAL void m0_fop_init(struct m0_fop *fop, struct m0_fop_type *fopt, void *data, void(*fop_release)(struct m0_ref *))
Definition: fop.c:79
static void test_fop_encdec(void)
const struct m0_xcode_type * ft_xt
Definition: fop.h:230
static int xcode_bufvec_fop_fini(void)
void *(* xcx_alloc)(struct m0_xcode_cursor *, size_t)
Definition: xcode.h:600
void * m0_fop_data(const struct m0_fop *fop)
Definition: fop.c:220
void m0_fop_type_fini(struct m0_fop_type *fopt)
Definition: fop.c:232
struct m0_bufvec_cursor xcx_buf
Definition: xcode.h:591
M0_INTERNAL void * m0_bufvec_cursor_addr(struct m0_bufvec_cursor *cur)
Definition: vec.c:597
M0_INTERNAL int m0_xcode_decode(struct m0_xcode_ctx *ctx)
Definition: xcode.c:380
static struct m0_xcode_type ** xt[]
Definition: protocol.c:64
Definition: ut.h:77
static void fop_free(struct m0_fop *fop)
M0_INTERNAL int m0_bufvec_alloc(struct m0_bufvec *bufvec, uint32_t num_segs, m0_bcount_t seg_size)
Definition: vec.c:220
M0_INTERNAL int m0_xcode_length(struct m0_xcode_ctx *ctx)
Definition: xcode.c:390
M0_INTERNAL void m0_bufvec_free(struct m0_bufvec *bufvec)
Definition: vec.c:395
int opcode
Definition: crate.c:301
int i
Definition: dir.c:1033
struct m0_fop_type * f_type
Definition: fop.h:81
Definition: cnt.h:36
const char * name
Definition: trace.c:110
#define M0_ASSERT(cond)
static struct m0_addb2_callback c
Definition: consumer.c:41
static int xcode_bufvec_fop_init(void)
M0_INTERNAL void m0_bufvec_cursor_init(struct m0_bufvec_cursor *cur, const struct m0_bufvec *bvec)
Definition: vec.c:563
static struct m0_fop_type m0_fop_test_fopt
M0_INTERNAL void * m0_xcode_alloc(struct m0_xcode_cursor *it, size_t nob)
Definition: xcode.c:444
struct m0_rpc_machine machine
Definition: mdstore.c:58
struct m0_fop_type_ops test_ops
const char * ts_name
Definition: ut.h:99
struct m0_fop_data f_data
Definition: fop.h:82
M0_INTERNAL void m0_fop_release(struct m0_ref *ref)
Definition: fop.c:148
struct m0_ut_suite xcode_bufvec_fop_ut
#define M0_ALLOC_PTR(ptr)
Definition: memory.h:86
static bool flag
Definition: nucleus.c:266
M0_INTERNAL int m0_xcode_encode(struct m0_xcode_ctx *ctx)
Definition: xcode.c:385
static struct m0_fop * fop
Definition: item.c:57
M0_INTERNAL void m0_xcode_ctx_init(struct m0_xcode_ctx *ctx, const struct m0_xcode_obj *obj)
Definition: xcode.c:373
#define M0_IS_8ALIGNED(val)
Definition: arith.h:190
void m0_free(void *data)
Definition: memory.c:146
int32_t rc
Definition: trigger_fop.h:47
#define M0_UT_ASSERT(a)
Definition: ut.h:46
Definition: fop.h:79
struct m0_fop * m0_fop_alloc(struct m0_fop_type *fopt, void *data, struct m0_rpc_machine *mach)
Definition: fop.c:96