Motr  M0
glob.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016-2020 Seagate Technology LLC and/or its Affiliates
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * For any questions about this software or licensing,
17  * please email opensource@seagate.com or cortx-questions@seagate.com.
18  *
19  */
20 
21 
22 #include "conf/glob.h"
23 #include "conf/cache.h" /* m0_conf_cache_from_string */
24 #include "conf/obj.h" /* m0_conf_service */
25 #include "conf/ut/common.h"
26 #include "lib/memory.h" /* m0_free */
27 #include "lib/errno.h" /* ENOENT */
28 #include "lib/string.h" /* m0_streq */
29 #include "ut/misc.h" /* M0_UT_PATH */
30 #include "ut/ut.h"
31 
32 static struct err_entry {
33  int ee_errno;
34  const struct m0_fid *ee_objid;
35  const struct m0_fid *ee_elem;
36 } g_err_accum[8];
37 
38 static int errfunc(int errcode, const struct m0_conf_obj *obj,
39  const struct m0_fid *path);
40 
41 static void test_conf_glob(void)
42 {
43  struct m0_conf_glob glob;
44  const struct m0_conf_obj *objv[16];
45  int rc;
47 
49  /*
50  * origin == NULL
51  */
53  M0_CONF_ROOT_NODES_FID, M0_CONF_ANY_FID,
54  M0_CONF_NODE_PROCESSES_FID, M0_CONF_ANY_FID,
55  M0_CONF_PROCESS_SERVICES_FID, M0_CONF_ANY_FID);
56  rc = m0_conf_glob(&glob, ARRAY_SIZE(objv), objv);
57  M0_UT_ASSERT(rc == 11);
58  /* check the types of returned objects */
60 
61  /*
62  * origin != NULL
63  */
65  /* `cache' may be omitted if `origin' is provided */
66  NULL,
67  m0_conf_cache_lookup(cache, /* pool-4 */
68  &M0_FID_TINIT('o', 1, 4)),
69  M0_CONF_POOL_PVERS_FID, M0_CONF_ANY_FID,
70  M0_CONF_PVER_SITEVS_FID, M0_CONF_ANY_FID,
71  M0_CONF_SITEV_RACKVS_FID, M0_CONF_ANY_FID,
72  M0_CONF_RACKV_ENCLVS_FID, M0_CONF_ANY_FID,
73  M0_CONF_ENCLV_CTRLVS_FID, M0_CONF_ANY_FID,
74  M0_CONF_CTRLV_DRIVEVS_FID, M0_CONF_ANY_FID);
75  while ((rc = m0_conf_glob(&glob, 1, objv)) > 0)
76  (void)M0_CONF_CAST(objv[0], m0_conf_objv);
77  M0_UT_ASSERT(rc == 0);
78 
79  /*
80  * the longest path possible
81  */
83  M0_CONF_ROOT_POOLS_FID, M0_CONF_ANY_FID,
84  M0_CONF_POOL_PVERS_FID, M0_CONF_ANY_FID,
85  M0_CONF_PVER_SITEVS_FID, M0_CONF_ANY_FID,
86  M0_CONF_SITEV_RACKVS_FID, M0_CONF_ANY_FID,
87  M0_CONF_RACKV_ENCLVS_FID, M0_CONF_ANY_FID,
88  M0_CONF_ENCLV_CTRLVS_FID, M0_CONF_ANY_FID,
89  M0_CONF_CTRLV_DRIVEVS_FID, M0_CONF_ANY_FID);
90  rc = m0_conf_glob(&glob, ARRAY_SIZE(objv), objv);
91  M0_UT_ASSERT(rc == 16);
92  /* check the types of returned objects */
94 
95  /*
96  * specific objects in the middle of the path, case #1
97  */
99  M0_CONF_ROOT_POOLS_FID, M0_FID_TINIT('o', 1, 4),
100  M0_CONF_POOL_PVERS_FID, M0_CONF_ANY_FID);
101  rc = m0_conf_glob(&glob, ARRAY_SIZE(objv), objv);
102  M0_UT_ASSERT(rc == 3);
103  /* check the types of returned objects */
105 
106  /*
107  * specific objects in the middle of the path, case #2
108  */
110  M0_CONF_ROOT_NODES_FID, M0_CONF_ANY_FID,
111  M0_CONF_NODE_PROCESSES_FID, M0_FID_TINIT('r', 1, 5),
112  M0_CONF_PROCESS_SERVICES_FID, M0_CONF_ANY_FID);
113  rc = m0_conf_glob(&glob, ARRAY_SIZE(objv), objv);
114  M0_UT_ASSERT(rc == 10);
115  /* check the types of returned objects */
117 
119 }
120 
121 static void test_conf_glob_errors(void)
122 {
123  struct m0_conf_glob glob;
124  const struct m0_conf_obj *objv[16];
125  struct err_entry *e;
126  char errbuf[64];
127  const char *err;
128  uint32_t i;
129  int rc;
131  const struct m0_fid profile = M0_FID_TINIT('p', 1, 0);
132  const struct m0_fid missing[] = {
133  /* service-9; first item of a conf_dir */
134  M0_FID_TINIT('s', 1, 9),
135  /* service-22; intermediate item of a conf_dir */
136  M0_FID_TINIT('s', 1, 22),
137  /* node-48; last item of a conf_dir */
138  M0_FID_TINIT('n', 1, 48)
139  };
140 
142  /*
143  * -ENOENT
144  */
146  M0_CONF_ROOT_PROFILES_FID, M0_FID_TINIT('p', 1, 7));
147  rc = m0_conf_glob(&glob, ARRAY_SIZE(objv), objv);
148  M0_UT_ASSERT(rc == -ENOENT);
149  err = m0_conf_glob_error(&glob, errbuf, sizeof errbuf);
150  M0_UT_ASSERT(m0_streq(err, "Unreachable path:"
151  " <4474700000000001:0>/<7000000000000001:7>"));
152  M0_SET0(&g_err_accum[0]);
153 
154  /*
155  * -EPERM, ->coo_lookup()
156  */
159  M0_CONF_ROOT_PROFILES_FID, profile);
160  rc = m0_conf_glob(&glob, ARRAY_SIZE(objv), objv);
161  M0_UT_ASSERT(rc == -EPERM);
162  err = m0_conf_glob_error(&glob, errbuf, sizeof errbuf);
163  M0_UT_ASSERT(m0_streq(err, "Conf object is not ready:"
164  " <7000000000000001:0>"));
166  M0_SET0(&g_err_accum[0]);
167 
168  /*
169  * -EPERM, conf_dir items
170  */
171  for (i = 0; i < ARRAY_SIZE(missing); ++i)
172  m0_conf_cache_lookup(cache, &missing[i])->co_status =
174  m0_conf_glob_init(&glob, 0, errfunc, cache, NULL,
175  M0_CONF_ROOT_NODES_FID, M0_CONF_ANY_FID,
176  M0_CONF_NODE_PROCESSES_FID, M0_CONF_ANY_FID,
177  M0_CONF_PROCESS_SERVICES_FID, M0_CONF_ANY_FID,
178  M0_CONF_SERVICE_SDEVS_FID, M0_CONF_ANY_FID);
179  rc = m0_conf_glob(&glob, ARRAY_SIZE(objv), objv);
180  M0_UT_ASSERT(rc == 4);
181  /* check the types of returned objects */
183  for (i = 0; i < ARRAY_SIZE(missing); ++i) {
184  /* check error */
185  e = &g_err_accum[i];
186  M0_UT_ASSERT(e->ee_errno == -EPERM);
187  M0_UT_ASSERT(m0_fid_eq(e->ee_objid, &missing[i]));
188  M0_UT_ASSERT(e->ee_elem == NULL);
189  M0_SET0(e); /* clear g_err_accum[] slot */
190  /* restore status */
191  m0_conf_cache_lookup(cache, &missing[i])->co_status =
192  M0_CS_READY;
193  }
194  M0_UT_ASSERT(g_err_accum[i].ee_errno == 0);
195 
197 }
198 
199 static int
200 errfunc(int errcode, const struct m0_conf_obj *obj, const struct m0_fid *path)
201 {
202  struct err_entry *x;
203 
204  M0_PRE(M0_IN(errcode, (-EPERM, -ENOENT)));
205 
207  (x = &g_err_accum[i])->ee_errno == 0));
208  /* An empty slot found. Fill it with data. */
209  *x = (struct err_entry){
210  .ee_errno = errcode,
211  .ee_objid = &obj->co_id,
212  .ee_elem = errcode == -ENOENT ? path : NULL
213  };
214  return 0; /* do not abort the execution */
215 }
216 
217 static int conf_glob_ut_init(void)
218 {
219  int rc;
220 
222  if (rc == 0)
224  M0_UT_PATH("conf.xc"));
225  return rc;
226 }
227 
228 static int conf_glob_ut_fini(void)
229 {
230  return m0_conf_ut_cache_fini();
231 }
232 
234  .ts_name = "conf-glob-ut",
235  .ts_init = conf_glob_ut_init,
236  .ts_fini = conf_glob_ut_fini,
237  .ts_tests = {
238  { "glob", test_conf_glob },
239  { "glob-errors", test_conf_glob_errors },
240  { NULL, NULL }
241  }
242 };
Definition: beck.c:235
M0_INTERNAL int m0_conf_ut_cache_init(void)
Definition: common.c:107
#define M0_PRE(cond)
#define m0_conf_glob_init(glob, flags, errfunc, cache, origin,...)
Definition: glob.h:142
int ee_errno
Definition: glob.c:33
#define NULL
Definition: misc.h:38
static bool x
Definition: sm.c:168
M0_INTERNAL struct m0_conf_obj * m0_conf_cache_lookup(const struct m0_conf_cache *cache, const struct m0_fid *id)
Definition: cache.c:106
#define m0_exists(var, nr,...)
Definition: misc.h:134
static int conf_glob_ut_fini(void)
Definition: glob.c:228
#define M0_SET0(obj)
Definition: misc.h:64
Definition: ut.h:77
static struct foo * obj
Definition: tlist.c:302
static void test_conf_glob(void)
Definition: glob.c:41
static void test_conf_glob_errors(void)
Definition: glob.c:121
int i
Definition: dir.c:1033
struct m0_conf_cache m0_conf_ut_cache
Definition: common.c:31
#define M0_FID_TINIT(type, container, key)
Definition: fid.h:90
struct m0_ut_suite conf_glob_ut
Definition: glob.c:233
M0_INTERNAL char * m0_conf_glob_error(const struct m0_conf_glob *glob, char *buf, size_t buflen)
Definition: glob.c:115
static int errfunc(int errcode, const struct m0_conf_obj *obj, const struct m0_fid *path)
Definition: glob.c:200
#define m0_streq(a, b)
Definition: string.h:34
M0_INTERNAL int m0_conf_ut_cache_fini(void)
Definition: common.c:114
static int conf_glob_ut_init(void)
Definition: glob.c:217
#define M0_CONF_CAST(ptr, type)
Definition: obj.h:780
M0_INTERNAL bool m0_fid_eq(const struct m0_fid *fid0, const struct m0_fid *fid1)
Definition: fid.c:164
#define m0_forall(var, nr,...)
Definition: misc.h:112
const char * ts_name
Definition: ut.h:99
static struct m0_fid profile
Definition: rconfc.c:49
const struct m0_fid * ee_objid
Definition: glob.c:34
static struct err_entry g_err_accum[8]
Definition: fid.h:38
const struct m0_fid * ee_elem
Definition: glob.c:35
M0_INTERNAL void m0_conf_ut_cache_from_file(struct m0_conf_cache *cache, const char *path)
Definition: common.c:123
Definition: glob.c:32
enum m0_conf_status co_status
Definition: obj.h:210
M0_INTERNAL int m0_conf_glob(struct m0_conf_glob *glob, uint32_t nr, const struct m0_conf_obj **objv)
Definition: glob.c:92
#define M0_UT_PATH(name)
Definition: misc.h:41
M0_INTERNAL void m0_conf_cache_lock(struct m0_conf_cache *cache)
Definition: cache.c:50
int32_t rc
Definition: trigger_fop.h:47
#define ARRAY_SIZE(a)
Definition: misc.h:45
#define M0_UT_ASSERT(a)
Definition: ut.h:46
M0_INTERNAL void m0_conf_cache_unlock(struct m0_conf_cache *cache)
Definition: cache.c:55