Skip to content

Commit 4f19905

Browse files
committed
test client BUGFIX more accurate error reply message
1 parent 3d79b5a commit 4f19905

File tree

3 files changed

+514
-4
lines changed

3 files changed

+514
-4
lines changed

src/main.c

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,64 @@ np2srv_err_nc(sr_error_info_err_t *err)
249249
return NULL;
250250
}
251251

252+
/**
253+
* @brief Find the nth substring delimited by quotes.
254+
*
255+
* For example: abcd"ef"ghij"kl"mn -> index 0 is "ef", index 1 is "kl".
256+
*
257+
* @param[in] msg Input string with quoted substring.
258+
* @param[in] index Number starting from 0 specifying the nth substring.
259+
* @return Copied nth substring without quotes.
260+
*/
261+
static char *
262+
np2srv_err_reply_get_quoted_string(const char *msg, uint32_t index)
263+
{
264+
char *ret;
265+
const char *start = NULL, *end = NULL, *iter, *tmp;
266+
uint32_t quote_cnt = 0, last_quote;
267+
268+
assert(msg);
269+
270+
last_quote = (index + 1) * 2;
271+
for (iter = msg; *iter; ++iter) {
272+
if (*iter != '\"') {
273+
continue;
274+
}
275+
/* updating the start and end pointers - swap */
276+
tmp = end;
277+
end = iter;
278+
start = tmp;
279+
if (++quote_cnt == last_quote) {
280+
/* nth substring found */
281+
break;
282+
}
283+
}
284+
285+
if (!start) {
286+
return NULL;
287+
}
288+
289+
/* Skip first quote */
290+
++start;
291+
/* Copy substring */
292+
ret = strndup(start, end - start);
293+
294+
return ret;
295+
}
296+
297+
/**
298+
* @brief Check that the @p str starts with the @p prefix.
299+
*
300+
* @param[in] prefix Required prefix.
301+
* @param[in] str Input string to check.
302+
* @return True if @p str start with @p prefix otherwise False.
303+
*/
304+
static ly_bool
305+
np2srv_strstarts(const char *prefix, const char *str)
306+
{
307+
return strncmp(str, prefix, strlen(prefix)) == 0;
308+
}
309+
252310
/**
253311
* @brief Create NC error reply based on SR error info.
254312
*
@@ -262,6 +320,9 @@ np2srv_err_reply_sr(const sr_error_info_t *err_info)
262320
struct lyd_node *e;
263321
const struct ly_ctx *ly_ctx;
264322
size_t i;
323+
char *str, *path;
324+
const struct lysc_node *cn;
325+
NC_ERR_TYPE errtype;
265326

266327
/* try to find a NETCONF error(s) */
267328
for (i = 0; i < err_info->err_count; ++i) {
@@ -284,16 +345,34 @@ np2srv_err_reply_sr(const sr_error_info_t *err_info)
284345

285346
ly_ctx = sr_acquire_context(np2srv.sr_conn);
286347
for (i = 0; i < err_info->err_count; ++i) {
287-
/* generic error */
288-
e = nc_err(ly_ctx, NC_ERR_OP_FAILED, NC_ERR_TYPE_APP);
289-
nc_err_set_msg(e, err_info->err[i].message, "en");
348+
if (np2srv_strstarts("Mandatory node", err_info->err[i].message) ||
349+
np2srv_strstarts("Mandatory choice", err_info->err[i].message)) {
350+
str = np2srv_err_reply_get_quoted_string(err_info->err[i].message, 0);
351+
path = np2srv_err_reply_get_quoted_string(err_info->err[i].message, 1);
352+
cn = lys_find_path(ly_ctx, NULL, path, 0);
353+
if (cn && ((cn->nodetype & LYS_RPC) || (cn->nodetype & LYS_INPUT))) {
354+
errtype = NC_ERR_TYPE_PROT;
355+
} else {
356+
errtype = NC_ERR_TYPE_APP;
357+
}
358+
e = nc_err(ly_ctx, NC_ERR_MISSING_ELEM, errtype, str);
359+
free(str);
360+
free(path);
361+
} else if (err_info->err->err_code == SR_ERR_NO_MEMORY) {
362+
e = nc_err(ly_ctx, NC_ERR_RES_DENIED, NC_ERR_TYPE_APP);
363+
} else {
364+
/* generic error */
365+
e = nc_err(ly_ctx, NC_ERR_OP_FAILED, NC_ERR_TYPE_APP);
366+
}
290367

368+
nc_err_set_msg(e, err_info->err[i].message, "en");
291369
if (reply) {
292370
nc_server_reply_add_err(reply, e);
293371
} else {
294372
reply = nc_server_reply_err(e);
295373
}
296374
}
375+
/* clear for other errors */
297376
sr_release_context(np2srv.sr_conn);
298377

299378
return reply;

tests/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ set(TEST_SRC "np2_test.c" "np2_other_client.c")
4242

4343
# list of all the tests
4444
set(TESTS test_rpc test_edit test_filter test_subscribe_filter test_subscribe_param test_parallel_sessions
45-
test_candidate test_with_defaults test_nacm test_sub_ntf test_sub_ntf_advanced test_sub_ntf_filter test_error)
45+
test_candidate test_with_defaults test_nacm test_sub_ntf test_sub_ntf_advanced test_sub_ntf_filter test_error test_other_client)
4646

4747
if(CMAKE_C_FLAGS MATCHES "-fsanitize=thread")
4848
message(WARNING "Features which use SIGEV_THREAD are known to be broken under TSAN, disabling tests for YANG-push and confirmed commit")

0 commit comments

Comments
 (0)