From 17e3e74ad5e0cf111555b3f9ded23b7e555ebf63 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Tue, 18 Jun 2019 14:49:18 +0200 Subject: [PATCH 01/17] All hash_ functions have been prefixed with `clicon_` to avoid name collision with other packages (frr) --- CHANGELOG.md | 1 + apps/cli/cli_common.c | 6 ++--- lib/clixon/clixon_hash.h | 33 ++++++++++++------------ lib/src/clixon_data.c | 52 +++++++++++++++++++------------------- lib/src/clixon_datastore.c | 6 ++--- lib/src/clixon_handle.c | 12 ++++----- lib/src/clixon_hash.c | 46 ++++++++++++++++----------------- lib/src/clixon_options.c | 22 ++++++++-------- 8 files changed, 89 insertions(+), 89 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4ae6f50..4ab298e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -67,6 +67,7 @@ ### API changes on existing features (you may need to change your code) +* All hash_ functions have been prefixed with `clicon_` to avoid name collision with other packages (frr) * Added compiled regexp parameter as part of internal yang type resolution functions * `yang_type_resolve()`, `yang_type_get()` * All internal `ys_populate_*()` functions (except ys_populate()) have switched parameters: `clicon_handle, yang_stmt *)` diff --git a/apps/cli/cli_common.c b/apps/cli/cli_common.c index b871c7a3..0502fd7b 100644 --- a/apps/cli/cli_common.c +++ b/apps/cli/cli_common.c @@ -107,7 +107,7 @@ cli_notification_register(clicon_handle h, goto done; } snprintf(logname, len, "log_socket_%s", stream); - if ((p = hash_value(cdat, logname, &len)) != NULL) + if ((p = clicon_hash_value(cdat, logname, &len)) != NULL) s_exist = *(int*)p; if (status){ /* start */ @@ -119,14 +119,14 @@ cli_notification_register(clicon_handle h, goto done; if (cligen_regfd(s, fn, arg) < 0) goto done; - if (hash_add(cdat, logname, &s, sizeof(s)) == NULL) + if (clicon_hash_add(cdat, logname, &s, sizeof(s)) == NULL) goto done; } else{ /* stop */ if (s_exist != -1){ cligen_unregfd(s_exist); } - hash_del(cdat, logname); + clicon_hash_del(cdat, logname); #if 0 /* cant turn off */ if (clicon_rpc_create_subscription(h, status, stream, format, filter, NULL) < 0) goto done; diff --git a/lib/clixon/clixon_hash.h b/lib/clixon/clixon_hash.h index 090af542..6fcca465 100644 --- a/lib/clixon/clixon_hash.h +++ b/lib/clixon/clixon_hash.h @@ -44,14 +44,14 @@ struct clicon_hash { }; typedef struct clicon_hash *clicon_hash_t; -clicon_hash_t *hash_init (void); -void hash_free (clicon_hash_t *); -clicon_hash_t hash_lookup (clicon_hash_t *head, const char *key); -void *hash_value (clicon_hash_t *head, const char *key, size_t *vlen); -clicon_hash_t hash_add (clicon_hash_t *head, const char *key, void *val, size_t vlen); -int hash_del (clicon_hash_t *head, const char *key); -int hash_dump(clicon_hash_t *head, FILE *f); -int hash_keys(clicon_hash_t *hash, char ***vector, size_t *nkeys); +clicon_hash_t *clicon_hash_init (void); +void clicon_hash_free (clicon_hash_t *); +clicon_hash_t clicon_hash_lookup (clicon_hash_t *head, const char *key); +void *clicon_hash_value (clicon_hash_t *head, const char *key, size_t *vlen); +clicon_hash_t clicon_hash_add (clicon_hash_t *head, const char *key, void *val, size_t vlen); +int clicon_hash_del (clicon_hash_t *head, const char *key); +int clicon_hash_dump(clicon_hash_t *head, FILE *f); +int clicon_hash_keys(clicon_hash_t *hash, char ***vector, size_t *nkeys); /* * Macros to iterate over hash contents. @@ -59,24 +59,23 @@ int hash_keys(clicon_hash_t *hash, char ***vector, size_t *nkeys); * * Example: * char *k; - * clicon_hash_t *h = hash_init(); + * clicon_hash_t *h = clicon_hash_init(); * - * hash_add(h, "colour", "red", 6); - * hash_add(h, "name", "rudolf" 7); - * hash_add(h, "species", "reindeer" 9); + * clicon_hash_add(h, "colour", "red", 6); + * clicon_hash_add(h, "name", "rudolf" 7); + * clicon_hash_add(h, "species", "reindeer" 9); * - * hash_each(h, k) { - * printf ("%s = %s\n", k, (char *)hash_value(h, k, NULL)); + * clicon_hash_each(h, k) { + * printf ("%s = %s\n", k, (char *)clicon_hash_value(h, k, NULL)); * } hash_each_end(); */ -#define hash_each(__hash__, __key__) \ +#define clicon_hash_each(__hash__, __key__) \ { \ int __i__; \ size_t __n__; \ char **__k__ = hash_keys((__hash__),&__n__); \ if (__k__) { \ for(__i__ = 0; __i__ < __n__ && ((__key__) = __k__[__i__]); __i__++) -#define hash_each_end(__hash__) if (__k__) free(__k__); } } - +#define clicon_hash_each_end(__hash__) if (__k__) free(__k__); } } #endif /* _CLIXON_HASH_H_ */ diff --git a/lib/src/clixon_data.c b/lib/src/clixon_data.c index 56871268..cb38c34d 100644 --- a/lib/src/clixon_data.c +++ b/lib/src/clixon_data.c @@ -83,7 +83,7 @@ clicon_dbspec_yang(clicon_handle h) size_t len; void *p; - if ((p = hash_value(cdat, "dbspec_yang", &len)) != NULL) + if ((p = clicon_hash_value(cdat, "dbspec_yang", &len)) != NULL) return *(yang_stmt **)p; return NULL; } @@ -100,7 +100,7 @@ clicon_dbspec_yang_set(clicon_handle h, /* It is the pointer to ys that should be copied by hash, so we send a ptr to the ptr to indicate what to copy. */ - if (hash_add(cdat, "dbspec_yang", &ys, sizeof(ys)) == NULL) + if (clicon_hash_add(cdat, "dbspec_yang", &ys, sizeof(ys)) == NULL) return -1; return 0; } @@ -118,7 +118,7 @@ clicon_nacm_ext(clicon_handle h) size_t len; void *p; - if ((p = hash_value(cdat, "nacm_xml", &len)) != NULL) + if ((p = clicon_hash_value(cdat, "nacm_xml", &len)) != NULL) return *(cxobj **)p; return NULL; } @@ -141,7 +141,7 @@ clicon_nacm_ext_set(clicon_handle h, /* It is the pointer to xn that should be copied by hash, so we send a ptr to the ptr to indicate what to copy. */ - if (hash_add(cdat, "nacm_xml", &xn, sizeof(xn)) == NULL) + if (clicon_hash_add(cdat, "nacm_xml", &xn, sizeof(xn)) == NULL) return -1; return 0; } @@ -158,7 +158,7 @@ clicon_config_yang(clicon_handle h) size_t len; void *p; - if ((p = hash_value(cdat, "control_yang", &len)) != NULL) + if ((p = clicon_hash_value(cdat, "control_yang", &len)) != NULL) return *(yang_stmt **)p; return NULL; } @@ -175,7 +175,7 @@ clicon_config_yang_set(clicon_handle h, /* It is the pointer to ys that should be copied by hash, so we send a ptr to the ptr to indicate what to copy. */ - if (hash_add(cdat, "control_yang", &ys, sizeof(ys)) == NULL) + if (clicon_hash_add(cdat, "control_yang", &ys, sizeof(ys)) == NULL) return -1; return 0; } @@ -192,7 +192,7 @@ clicon_conf_xml(clicon_handle h) size_t len; void *p; - if ((p = hash_value(cdat, "clixon_conf", &len)) != NULL) + if ((p = clicon_hash_value(cdat, "clixon_conf", &len)) != NULL) return *(cxobj **)p; return NULL; } @@ -209,7 +209,7 @@ clicon_conf_xml_set(clicon_handle h, /* It is the pointer to x that should be copied by hash, * so we send a ptr to the ptr to indicate what to copy. */ - if (hash_add(cdat, "clixon_conf", &x, sizeof(x)) == NULL) + if (clicon_hash_add(cdat, "clixon_conf", &x, sizeof(x)) == NULL) return -1; return 0; } @@ -223,7 +223,7 @@ clicon_username_get(clicon_handle h) { clicon_hash_t *cdat = clicon_data(h); - return (char*)hash_value(cdat, "username", NULL); + return (char*)clicon_hash_value(cdat, "username", NULL); } /*! Set authorized user name @@ -238,8 +238,8 @@ clicon_username_set(clicon_handle h, clicon_hash_t *cdat = clicon_data(h); if (username == NULL) - return hash_del(cdat, "username"); - return hash_add(cdat, "username", username, strlen(username)+1)==NULL?-1:0; + return clicon_hash_del(cdat, "username"); + return clicon_hash_add(cdat, "username", username, strlen(username)+1)==NULL?-1:0; } /*! Get backend daemon startup status @@ -252,7 +252,7 @@ clicon_startup_status_get(clicon_handle h) clicon_hash_t *cdat = clicon_data(h); void *p; - if ((p = hash_value(cdat, "startup_status", NULL)) != NULL) + if ((p = clicon_hash_value(cdat, "startup_status", NULL)) != NULL) return *(enum startup_status *)p; return STARTUP_ERR; } @@ -268,7 +268,7 @@ clicon_startup_status_set(clicon_handle h, enum startup_status status) { clicon_hash_t *cdat = clicon_data(h); - if (hash_add(cdat, "startup_status", &status, sizeof(status))==NULL) + if (clicon_hash_add(cdat, "startup_status", &status, sizeof(status))==NULL) return -1; return 0; } @@ -284,7 +284,7 @@ clicon_socket_get(clicon_handle h) clicon_hash_t *cdat = clicon_data(h); void *p; - if ((p = hash_value(cdat, "socket", NULL)) == NULL) + if ((p = clicon_hash_value(cdat, "socket", NULL)) == NULL) return -1; return *(int*)p; } @@ -302,8 +302,8 @@ clicon_socket_set(clicon_handle h, clicon_hash_t *cdat = clicon_data(h); if (s == -1) - return hash_del(cdat, "socket"); - return hash_add(cdat, "socket", &s, sizeof(int))==NULL?-1:0; + return clicon_hash_del(cdat, "socket"); + return clicon_hash_add(cdat, "socket", &s, sizeof(int))==NULL?-1:0; } /*! Get module state cache @@ -319,7 +319,7 @@ clicon_modst_cache_get(clicon_handle h, clicon_hash_t *cdat = clicon_data(h); void *p; - if ((p = hash_value(cdat, brief?"modst_brief":"modst_full", NULL)) != NULL) + if ((p = clicon_hash_value(cdat, brief?"modst_brief":"modst_full", NULL)) != NULL) return *(cxobj **)p; return NULL; } @@ -346,7 +346,7 @@ clicon_modst_cache_set(clicon_handle h, assert(strcmp(xml_name(xms),"modules-state")==0); if ((x = xml_dup(xms)) == NULL) return -1; - if (hash_add(cdat, brief?"modst_brief":"modst_full", &x, sizeof(x))==NULL) + if (clicon_hash_add(cdat, brief?"modst_brief":"modst_full", &x, sizeof(x))==NULL) return -1; ok: return 0; @@ -363,7 +363,7 @@ clicon_xml_changelog_get(clicon_handle h) clicon_hash_t *cdat = clicon_data(h); void *p; - if ((p = hash_value(cdat, "xml-changelog", NULL)) != NULL) + if ((p = clicon_hash_value(cdat, "xml-changelog", NULL)) != NULL) return *(cxobj **)p; return NULL; } @@ -381,7 +381,7 @@ clicon_xml_changelog_set(clicon_handle h, { clicon_hash_t *cdat = clicon_data(h); - if (hash_add(cdat, "xml-changelog", &xchlog, sizeof(xchlog))==NULL) + if (clicon_hash_add(cdat, "xml-changelog", &xchlog, sizeof(xchlog))==NULL) return -1; return 0; } @@ -403,12 +403,12 @@ clicon_argv_get(clicon_handle h, void *p; if (argc){ - if ((p = hash_value(cdat, "argc", NULL)) == NULL) + if ((p = clicon_hash_value(cdat, "argc", NULL)) == NULL) return -1; *argc = *(int*)p; } if (argv){ - if ((p = hash_value(cdat, "argv", NULL)) == NULL) + if ((p = clicon_hash_value(cdat, "argv", NULL)) == NULL) return -1; *argv = (char**)p; } @@ -444,10 +444,10 @@ clicon_argv_set(clicon_handle h, memcpy(argvv+1, argv, argc*sizeof(char*)); argvv[0] = prgm; /* Note the value is the argv vector (which is copied) */ - if (hash_add(cdat, "argv", argvv, len*sizeof(char*))==NULL) + if (clicon_hash_add(cdat, "argv", argvv, len*sizeof(char*))==NULL) goto done; argc += 1; - if (hash_add(cdat, "argc", &argc, sizeof(argc))==NULL) + if (clicon_hash_add(cdat, "argc", &argc, sizeof(argc))==NULL) goto done; retval = 0; done: @@ -470,7 +470,7 @@ clicon_db_elmnt_get(clicon_handle h, clicon_hash_t *cdat = clicon_db_elmnt(h); void *p; - if ((p = hash_value(cdat, db, NULL)) != NULL) + if ((p = clicon_hash_value(cdat, db, NULL)) != NULL) return (db_elmnt *)p; return NULL; } @@ -491,7 +491,7 @@ clicon_db_elmnt_set(clicon_handle h, { clicon_hash_t *cdat = clicon_db_elmnt(h); - if (hash_add(cdat, db, de, sizeof(*de))==NULL) + if (clicon_hash_add(cdat, db, de, sizeof(*de))==NULL) return -1; return 0; } diff --git a/lib/src/clixon_datastore.c b/lib/src/clixon_datastore.c index b27ce1b4..78e5c300 100644 --- a/lib/src/clixon_datastore.c +++ b/lib/src/clixon_datastore.c @@ -160,10 +160,10 @@ xmldb_disconnect(clicon_handle h) int i; db_elmnt *de; - if (hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0) + if (clicon_hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0) goto done; for(i = 0; i < klen; i++) - if ((de = hash_value(clicon_db_elmnt(h), keys[i], NULL)) != NULL){ + if ((de = clicon_hash_value(clicon_db_elmnt(h), keys[i], NULL)) != NULL){ if (de->de_xml){ xml_free(de->de_xml); de->de_xml = NULL; @@ -310,7 +310,7 @@ xmldb_unlock_all(clicon_handle h, int i; db_elmnt *de; - if (hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0) + if (clicon_hash_keys(clicon_db_elmnt(h), &keys, &klen) < 0) goto done; for (i = 0; i < klen; i++) if ((de = clicon_db_elmnt_get(h, keys[i])) != NULL && diff --git a/lib/src/clixon_handle.c b/lib/src/clixon_handle.c index 5d91c7c8..b4b5a303 100644 --- a/lib/src/clixon_handle.c +++ b/lib/src/clixon_handle.c @@ -111,15 +111,15 @@ clicon_handle_init0(int size) } memset(ch, 0, size); ch->ch_magic = CLICON_MAGIC; - if ((ch->ch_copt = hash_init()) == NULL){ + if ((ch->ch_copt = clicon_hash_init()) == NULL){ clicon_handle_exit((clicon_handle)ch); goto done; } - if ((ch->ch_data = hash_init()) == NULL){ + if ((ch->ch_data = clicon_hash_init()) == NULL){ clicon_handle_exit((clicon_handle)ch); goto done; } - if ((ch->ch_db_elmnt = hash_init()) == NULL){ + if ((ch->ch_db_elmnt = clicon_hash_init()) == NULL){ clicon_handle_exit((clicon_handle)ch); goto done; } @@ -154,12 +154,12 @@ clicon_handle_exit(clicon_handle h) clicon_hash_t *ha; if ((ha = clicon_options(h)) != NULL) - hash_free(ha); + clicon_hash_free(ha); if ((ha = clicon_data(h)) != NULL) - hash_free(ha); + clicon_hash_free(ha); if ((ha = clicon_db_elmnt(h)) != NULL) - hash_free(ha); + clicon_hash_free(ha); stream_delete_all(h, 1); free(ch); retval = 0; diff --git a/lib/src/clixon_hash.c b/lib/src/clixon_hash.c index b14e10ad..f757743b 100644 --- a/lib/src/clixon_hash.c +++ b/lib/src/clixon_hash.c @@ -115,7 +115,7 @@ hash_bucket(const char *str) * @see hash_free For freeing the hash-table */ clicon_hash_t * -hash_init(void) +clicon_hash_init(void) { clicon_hash_t *hash; @@ -133,7 +133,7 @@ hash_init(void) * @retval void */ void -hash_free(clicon_hash_t *hash) +clicon_hash_free(clicon_hash_t *hash) { int i; clicon_hash_t tmp; @@ -157,8 +157,8 @@ hash_free(clicon_hash_t *hash) * @retval NULL Not found */ clicon_hash_t -hash_lookup(clicon_hash_t *hash, - const char *key) +clicon_hash_lookup(clicon_hash_t *hash, + const char *key) { uint32_t bkt; clicon_hash_t h; @@ -183,13 +183,13 @@ hash_lookup(clicon_hash_t *hash, * @retval NULL Key not found or value NULL */ void * -hash_value(clicon_hash_t *hash, - const char *key, - size_t *vlen) +clicon_hash_value(clicon_hash_t *hash, + const char *key, + size_t *vlen) { clicon_hash_t h; - h = hash_lookup(hash, key); + h = clicon_hash_lookup(hash, key); if (h == NULL) return NULL; /* OK, key not found */ @@ -209,10 +209,10 @@ hash_value(clicon_hash_t *hash, * @note special case val is NULL and vlen==0 */ clicon_hash_t -hash_add(clicon_hash_t *hash, - const char *key, - void *val, - size_t vlen) +clicon_hash_add(clicon_hash_t *hash, + const char *key, + void *val, + size_t vlen) { void *newval = NULL; clicon_hash_t h; @@ -225,7 +225,7 @@ hash_add(clicon_hash_t *hash, goto catch; } /* If variable exist, don't allocate a new. just replace value */ - h = hash_lookup(hash, key); + h = clicon_hash_lookup(hash, key); if (h == NULL) { if ((new = (clicon_hash_t)malloc(sizeof(*new))) == NULL){ clicon_err(OE_UNIX, errno, "malloc: %s", strerror(errno)); @@ -283,12 +283,12 @@ catch: * @retval -1 Key not found */ int -hash_del(clicon_hash_t *hash, - const char *key) +clicon_hash_del(clicon_hash_t *hash, + const char *key) { clicon_hash_t h; - h = hash_lookup(hash, key); + h = clicon_hash_lookup(hash, key); if (h == NULL) return -1; @@ -311,9 +311,9 @@ hash_del(clicon_hash_t *hash, * @note: vector needs to be deallocated with free */ int -hash_keys(clicon_hash_t *hash, - char ***vector, - size_t *nkeys) +clicon_hash_keys(clicon_hash_t *hash, + char ***vector, + size_t *nkeys) { int retval = -1; int bkt; @@ -357,8 +357,8 @@ catch: * @retval -1 Error */ int -hash_dump(clicon_hash_t *hash, - FILE *f) +clicon_hash_dump(clicon_hash_t *hash, + FILE *f) { int retval = -1; int i; @@ -369,10 +369,10 @@ hash_dump(clicon_hash_t *hash, if (hash == NULL) goto ok; - if (hash_keys(hash, &keys, &klen) < 0) + if (clicon_hash_keys(hash, &keys, &klen) < 0) goto done; for(i = 0; i < klen; i++) { - val = hash_value(hash, keys[i], &vlen); + val = clicon_hash_value(hash, keys[i], &vlen); printf("%s =\t 0x%p , length %zu\n", keys[i], val, vlen); } diff --git a/lib/src/clixon_options.c b/lib/src/clixon_options.c index d91dc9ee..a3fbbdf1 100644 --- a/lib/src/clixon_options.c +++ b/lib/src/clixon_options.c @@ -102,10 +102,10 @@ clicon_option_dump(clicon_handle h, size_t klen; size_t vlen; - if (hash_keys(hash, &keys, &klen) < 0) + if (clicon_hash_keys(hash, &keys, &klen) < 0) goto done; for(i = 0; i < klen; i++) { - val = hash_value(hash, keys[i], &vlen); + val = clicon_hash_value(hash, keys[i], &vlen); if (vlen){ if (((char*)val)[vlen-1]=='\0') /* assume string */ clicon_debug(dbglevel, "%s =\t \"%s\"", keys[i], (char*)val); @@ -222,7 +222,7 @@ parse_configfile(clicon_handle h, /* Used as an arg to this fn */ if (strcmp(name,"CLICON_CONFIGFILE")==0) continue; - if (hash_add(copt, + if (clicon_hash_add(copt, name, body, strlen(body)+1) == NULL) @@ -267,7 +267,7 @@ clicon_option_add(clicon_handle h, name, value, name) < 0) goto done; } - if (hash_add(copt, + if (clicon_hash_add(copt, name, value, strlen(value)+1) == NULL) @@ -302,10 +302,10 @@ clicon_options_main(clicon_handle h, /* * Set configure file if not set by command-line above */ - if (!hash_lookup(copt, "CLICON_CONFIGFILE")){ + if (!clicon_hash_lookup(copt, "CLICON_CONFIGFILE")){ clicon_option_str_set(h, "CLICON_CONFIGFILE", CLIXON_DEFAULT_CONFIG); } - configfile = hash_value(copt, "CLICON_CONFIGFILE", NULL); + configfile = clicon_hash_value(copt, "CLICON_CONFIGFILE", NULL); clicon_debug(1, "CLICON_CONFIGFILE=%s", configfile); /* File must end with .xml */ if ((suffix = rindex(configfile, '.')) != NULL){ @@ -368,7 +368,7 @@ clicon_option_exists(clicon_handle h, { clicon_hash_t *copt = clicon_options(h); - return (hash_lookup(copt, (char*)name) != NULL); + return (clicon_hash_lookup(copt, (char*)name) != NULL); } /*! Get a single string option string via handle @@ -387,9 +387,9 @@ clicon_option_str(clicon_handle h, { clicon_hash_t *copt = clicon_options(h); - if (hash_lookup(copt, (char*)name) == NULL) + if (clicon_hash_lookup(copt, (char*)name) == NULL) return NULL; - return hash_value(copt, (char*)name, NULL); + return clicon_hash_value(copt, (char*)name, NULL); } /*! Set a single string option via handle @@ -406,7 +406,7 @@ clicon_option_str_set(clicon_handle h, { clicon_hash_t *copt = clicon_options(h); - return hash_add(copt, (char*)name, val, strlen(val)+1)==NULL?-1:0; + return clicon_hash_add(copt, (char*)name, val, strlen(val)+1)==NULL?-1:0; } /*! Get options as integer but stored as string @@ -501,7 +501,7 @@ clicon_option_del(clicon_handle h, { clicon_hash_t *copt = clicon_options(h); - return hash_del(copt, (char*)name); + return clicon_hash_del(copt, (char*)name); } /*----------------------------------------------------------------- From 9ad343d6b4d72d0705ebaa54668e7d2535974257 Mon Sep 17 00:00:00 2001 From: Dave Cornejo Date: Tue, 18 Jun 2019 22:15:38 -1000 Subject: [PATCH 02/17] add instructions for FreeBSD --- doc/INSTALL.md | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/doc/INSTALL.md b/doc/INSTALL.md index 6efca64f..4afd8173 100644 --- a/doc/INSTALL.md +++ b/doc/INSTALL.md @@ -42,6 +42,51 @@ Docker is used to build Alpine Linux ### Build docker image ## FreeBSD -### Package install + +FreeBSD has ports for both cligen and clixon available. +You can install them as binary packages, or you can build +them in a ports source tree locally. + +If you install using binary packages or build from the +ports collection, the installation locations comply +with FreeBSD standards and you have some assurance +that the installed package is correct and functional. + +The nginx setup for RESTCONF is altered - the system user +www is used, and the restconf daemon is placed in +/usr/local/sbin. + +### Binary package install + +To install the pre-built binary package, use the FreeBSD +pkg command. + +``` +% pkg install clixon +``` + +This will install clixon and all the dependencies needed. + ### Build from source +If you prefer you can also build clixon from the +[FreeBSD ports collection](https://www.freebsd.org/doc/handbook/ports-using.html) + +Once you have the Ports Collection installed, you build +clixon like this: + +``` +% cd /usr/ports/devel/clixon +% make && make install +``` + +One issue with using the Ports Collection is that it may +not install the latest version from GitHub. The port is +generally updated soon after an official release, but there +is still a lag between it and the master branch. The maintainer +for the port tries to assure that the master branch will +compile always, but no FreeBSD specific functional testing +is done. + + + From 631b1d4558abed37ef0784a8988a751324474cfd Mon Sep 17 00:00:00 2001 From: Vladimir Ratnikov Date: Wed, 19 Jun 2019 15:52:20 -0400 Subject: [PATCH 03/17] api_path2xml_vec strict mode check on list key length mismatch --- CHANGELOG.md | 1 + lib/src/clixon_xml_map.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9769c04a..20071bd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -192,6 +192,7 @@ ### Minor changes +* `api_path2xml_vec` strict mode check added if list key length mismatch * `startup_extraxml` triggers unnecessary validation * Renamed startup_db_reset -> xmldb_db_reset (its a general function) * In startup_extraxml(), check if reset callbacks or extraxml file actually makes and changes to the tmp db. diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 973c8698..be24a155 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -2494,7 +2494,7 @@ api_path2xml_vec(char **vec, else{ if ((valvec = clicon_strsep(restval, ",", &nvalvec)) == NULL) goto done; - if (nvalvec != cvec_len(cvk)){ + if (nvalvec != cvec_len(cvk)) && strict){ clicon_err(OE_XML, EINVAL, "List key %s length mismatch", name); goto fail; } From c3245f0600602756ffba4a918d680c3a69adc9dd Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Wed, 19 Jun 2019 21:54:59 +0200 Subject: [PATCH 04/17] On validation callbacks, XML_FLAG_ADD is added to all nodes at startup validation, not just the top-level. This is the same behaviour as for steady-state validation. --- CHANGELOG.md | 2 ++ apps/backend/backend_commit.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9769c04a..8a86f5a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,7 +69,9 @@ ### API changes on existing features (you may need to change your code) +* On validation callbacks, XML_FLAG_ADD is added to all nodes at startup validation, not just the top-level. This is the same behaviour as for steady-state validation. * All hash_ functions have been prefixed with `clicon_` to avoid name collision with other packages (frr) + * All calls to the following functions must be changed: `hash_init`, `hash_free`, `hash_lookup`, `hash_value`, `hash_add`, `hash_del`, `hash_dump`, and `hash_keys`. * RESTCONF strict namespace validation of data in POST and PUT. * Accepted: ``` diff --git a/apps/backend/backend_commit.c b/apps/backend/backend_commit.c index 61e7193f..1371d673 100644 --- a/apps/backend/backend_commit.c +++ b/apps/backend/backend_commit.c @@ -214,7 +214,8 @@ startup_common(clicon_handle h, xt = NULL; x = NULL; while ((x = xml_child_each(td->td_target, x, CX_ELMNT)) != NULL){ - xml_flag_set(x, XML_FLAG_ADD); + xml_flag_set(x, XML_FLAG_ADD); /* Also down */ + xml_apply(x, CX_ELMNT, (xml_applyfn_t*)xml_flag_set, (void*)XML_FLAG_ADD); if (cxvec_append(x, &td->td_avec, &td->td_alen) < 0) goto done; } From bf2a9bfdfcd895295fb98cef15416a702d45331b Mon Sep 17 00:00:00 2001 From: 008agent <008agent@mail.ru> Date: Wed, 19 Jun 2019 23:00:30 +0300 Subject: [PATCH 05/17] Update clixon_xml_map.c --- lib/src/clixon_xml_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index be24a155..a536e679 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -2494,7 +2494,7 @@ api_path2xml_vec(char **vec, else{ if ((valvec = clicon_strsep(restval, ",", &nvalvec)) == NULL) goto done; - if (nvalvec != cvec_len(cvk)) && strict){ + if ((nvalvec != cvec_len(cvk)) && strict){ clicon_err(OE_XML, EINVAL, "List key %s length mismatch", name); goto fail; } From 97529a20a49b005cf8a022525ee0bf53003b9e6e Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 20 Jun 2019 13:59:55 +0200 Subject: [PATCH 06/17] * Error messages for invalid number ranges and string lengths have been uniformed and changed. * Error messages for invalid ranges are now on the form: ``` Number 23 out of range: 1-10 String length 23 out of range: 1-10 ``` --- CHANGELOG.md | 6 + lib/src/clixon_datastore_read.c | 4 - lib/src/clixon_yang_type.c | 113 +++++++++++++- test/all.sh | 3 +- test/test_insert.sh | 2 - test/test_transaction.sh | 2 +- test/test_type.sh | 39 ++--- test/test_type_range.sh | 252 ++++++++++++++++++++++++++++++++ 8 files changed, 388 insertions(+), 33 deletions(-) create mode 100755 test/test_type_range.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index a343903b..988fd9f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,12 @@ ### API changes on existing features (you may need to change your code) +* Error messages for invalid number ranges and string lengths have been uniformed and changed. + * Error messages for invalid ranges are now on the form: + ``` + Number 23 out of range: 1-10 + String length 23 out of range: 1-10 + ``` * On validation callbacks, XML_FLAG_ADD is added to all nodes at startup validation, not just the top-level. This is the same behaviour as for steady-state validation. * All hash_ functions have been prefixed with `clicon_` to avoid name collision with other packages (frr) * All calls to the following functions must be changed: `hash_init`, `hash_free`, `hash_lookup`, `hash_value`, `hash_add`, `hash_del`, `hash_dump`, and `hash_keys`. diff --git a/lib/src/clixon_datastore_read.c b/lib/src/clixon_datastore_read.c index b4358ae7..aed5e82d 100644 --- a/lib/src/clixon_datastore_read.c +++ b/lib/src/clixon_datastore_read.c @@ -589,10 +589,6 @@ xmldb_get_zerocopy(clicon_handle h, db_elmnt *de = NULL; db_elmnt de0 = {0,}; - if (!clicon_option_bool(h, "CLICON_XMLDB_CACHE")){ - clicon_err(OE_CFG, 0, "CLICON_XMLDB_CACHE must be set"); - goto done; - } if ((yspec = clicon_dbspec_yang(h)) == NULL){ clicon_err(OE_YANG, ENOENT, "No yang spec"); goto done; diff --git a/lib/src/clixon_yang_type.c b/lib/src/clixon_yang_type.c index cc1de405..3e00f7e8 100644 --- a/lib/src/clixon_yang_type.c +++ b/lib/src/clixon_yang_type.c @@ -588,6 +588,105 @@ cv_validate_pattern(clicon_handle h, (rmax && (i) > cv_##type##_get(rmax))) +/*! Error messsage for int violating ranges + * @note contains kludge - duplicate loop + */ +static int +outofrange(cg_var *cv0, + cvec *cvv, + char **reason) +{ + int retval = -1; + cbuf *cb = NULL; + cg_var *cv1; + cg_var *cv2; + int i; + + if ((cb = cbuf_new()) == NULL) + goto done; + cprintf(cb, "Number "); + cv2cbuf(cv0, cb); + cprintf(cb, " out of range: "); + /* Kludge: need to repeat the same loop as in the main function in + cv_validate1 */ + i = 0; + while (i2) + cprintf(cb, ", "); + cv2cbuf(cv1, cb); + cprintf(cb, "-"); + cv2cbuf(cv2, cb); + } + if (reason && (*reason = strdup(cbuf_get(cb))) == NULL) + goto done; + if (cb) + cbuf_free(cb); + retval = 0; + done: + return retval; +} + +/*! Error messsage for string violating string limits + * @note contains kludge - duplicate loop + */ +static int +outoflength(uint64_t u64, + cvec *cvv, + char **reason) +{ + int retval = -1; + cbuf *cb = NULL; + cg_var *cv1; + cg_var *cv2; + int i; + + if ((cb = cbuf_new()) == NULL) + goto done; + cprintf(cb, "String length %" PRIu64 " out of range: ", u64); + + /* Kludge: need to repeat the same loop as in the main function in + cv_validate1 */ + i = 0; + while (i2) + cprintf(cb, ", "); + cv2cbuf(cv1, cb); + cprintf(cb, "-"); + cv2cbuf(cv2, cb); + } + if (reason && (*reason = strdup(cbuf_get(cb))) == NULL) + goto done; + if (cb) + cbuf_free(cb); + retval = 0; + done: + return retval; +} + /*! Validate CLIgen variable * @param[in] h Clicon handle * @param[in] cv A cligen variable to validate. This is a correctly parsed cv. @@ -600,6 +699,7 @@ cv_validate_pattern(clicon_handle h, * @retval 0 Validation not OK, malloced reason is returned. Free reason with free() * @retval 1 Validation OK * @note reason if given must be freed by caller + * @see cv_validate Corresponding type check in cligen */ static int cv_validate1(clicon_handle h, @@ -705,14 +805,13 @@ cv_validate1(clicon_handle h, /* Check fails */ if (i==cvec_len(cvv)){ /* And it is last */ if (reason){ - if (reti) - *reason = cligen_reason("Number out of range: %" - PRId64, ii); - else if (retu) - *reason = cligen_reason("Number out of range: %" - PRIu64, uu); + if (reti || retu){ + if (outofrange(cv, cvv, reason) < 0) + goto done; + } else - *reason = cligen_reason("string length out of range: %" PRIu64, uu); + if (outoflength(uu, cvv, reason) < 0) + goto done; } goto fail; } diff --git a/test/all.sh b/test/all.sh index 6711558f..18ebde01 100755 --- a/test/all.sh +++ b/test/all.sh @@ -6,7 +6,8 @@ : ${pattern:=test_*.sh} if [ $# -gt 0 ]; then - echo "usage: $0 # detailed logs and stopon first error" + echo "usage: $0 # detailed logs and stop on first error. Use pattern=\"\" $0 to" + echo " Use pattern= $0 to narrow down test cases" exit -1 fi diff --git a/test/test_insert.sh b/test/test_insert.sh index dccdfae3..eea94e1d 100755 --- a/test/test_insert.sh +++ b/test/test_insert.sh @@ -3,7 +3,6 @@ # First a list with 0-5 base elements, insert in different places # Second varying yangs: container, leaf, list, leaf-list, choice, user-order list - # Magic line must be first in script (see README.md) s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi @@ -27,7 +26,6 @@ cat < $cfg /usr/local/var/$APPNAME/$APPNAME.sock /usr/local/var/$APPNAME/$APPNAME.pidfile $dir - true EOF diff --git a/test/test_transaction.sh b/test/test_transaction.sh index 69bddea0..eec920dd 100755 --- a/test/test_transaction.sh +++ b/test/test_transaction.sh @@ -177,7 +177,7 @@ new "3. Validate system-error config (9999 not in range)" expecteof "$clixon_netconf -qf $cfg" 0 "$nr9999]]>]]>" '^]]>]]>$' new "Validate system-error validate (should fail)" -expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^applicationbad-elementberrorNumber out of range: 9999]]>]]>$' +expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^applicationbad-elementberrorNumber 9999 out of range: 0-100]]>]]>$' new "Validate system-error discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" diff --git a/test/test_type.sh b/test/test_type.sh index 52265bd3..ac52f8b0 100755 --- a/test/test_type.sh +++ b/test/test_type.sh @@ -197,7 +197,7 @@ EOF # Type tests. # Parameters: -# 1: dbcache true/false +# 1: dbcache: cache, nocache, cache-zerocopy testrun(){ dbcache=$1 new "test params: -f $cfg # dbcache: $dbcache" @@ -216,7 +216,7 @@ testrun(){ /usr/local/var/$APPNAME/$APPNAME.pidfile 1 /usr/local/var/$APPNAME - $dbcache + $dbcache $format EOF @@ -231,7 +231,7 @@ EOF start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "cli set transitive string. type is alpha followed by number and is defined in three levels of modules" @@ -360,7 +360,7 @@ EOF expecteof "$clixon_netconf -qf $cfg" 0 '-1]]>]]>' "^]]>]]>$" new "netconf validate num1 -1 wrong" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum1errorNumber out of range: -1]]>]]>$' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum1errorNumber -1 out of range: 1-1]]>]]>$' new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" @@ -368,7 +368,7 @@ EOF #-------- num2 range and blanks new "cli range test num2 3 error" - expectfn "$clixon_cli -1f $cfg -l o set num2 3" 255 '^CLI syntax error: "set num2 3": Number out of range: 3$' + expectfn "$clixon_cli -1f $cfg -l o set num2 3" 255 '^CLI syntax error: "set num2 3": Number 3 out of range: 4-4000$' new "cli range test num2 1000 ok" expectfn "$clixon_cli -1f $cfg -l o set num2 1000" 0 '^$' @@ -380,7 +380,7 @@ EOF expecteof "$clixon_netconf -qf $cfg" 0 '3]]>]]>' "^]]>]]>$" new "netconf validate num2 3 fail" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum2errorNumber out of range: 3]]>]]>$' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum2errorNumber 3 out of range: 4-4000]]>]]>$' new "netconf range set num2 1000 ok" expecteof "$clixon_netconf -qf $cfg" 0 '1000]]>]]>' "^]]>]]>$" @@ -392,7 +392,7 @@ EOF expecteof "$clixon_netconf -qf $cfg" 0 '5000]]>]]>' "^]]>]]>$" new "netconf validate num2 5000 fail" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum2errorNumber out of range: 5000]]>]]>$' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum2errorNumber 5000 out of range: 4-4000]]>]]>$' new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" @@ -420,7 +420,7 @@ EOF #-------- num4 multiple ranges 1..2 | 42..50 new "cli range test num4 multiple 0 fail" - expectfn "$clixon_cli -1f $cfg -l o set num4 0" 255 '^CLI syntax error: "set num4 0": Number out of range: 0$' + expectfn "$clixon_cli -1f $cfg -l o set num4 0" 255 '^CLI syntax error: "set num4 0": Number 0 out of range: 1-2, 42-50$' new "cli range test num4 multiple 2 ok" expectfn "$clixon_cli -1f $cfg -l e set num4 2" 0 '^$' @@ -477,7 +477,7 @@ EOF expecteof "$clixon_netconf -qf $cfg" 0 '-3.59]]>]]>' "^]]>]]>$" new "netconf range dec64 -3.59 validate fail" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber out of range' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber -3.590 out of range' new "netconf range dec64 -3.5" expecteof "$clixon_netconf -qf $cfg" 0 '-3.500]]>]]>' "^]]>]]>$" @@ -489,13 +489,13 @@ EOF expecteof "$clixon_netconf -qf $cfg" 0 '-2]]>]]>' "^]]>]]>$" new "netconf range dec64 -2 validate fail" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber out of range' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber -2.000 out of range' new "netconf range dec64 -0.001" expecteof "$clixon_netconf -qf $cfg" 0 '-0.001]]>]]>' "^]]>]]>$" new "netconf range dec64 -0.001 validate fail" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber out of range' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber -0.001 out of range' new "netconf range dec64 0.0" expecteof "$clixon_netconf -qf $cfg" 0 '0.0]]>]]>' "^]]>]]>$" @@ -507,12 +507,12 @@ EOF expecteof "$clixon_netconf -qf $cfg" 0 '+0.001]]>]]>' "^]]>]]>$" new "netconf range dec64 +0.001 validate fail" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber out of range' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementdecerrorNumber 0.001 out of range' #----------------string ranges--------------------- #-------- len1 single range (2) new "cli length test len1 1 fail" - expectfn "$clixon_cli -1f $cfg -l o set len1 x" 255 '^CLI syntax error: "set len1 x": String length not within limits: 1$' + expectfn "$clixon_cli -1f $cfg -l o set len1 x" 255 '^CLI syntax error: "set len1 x": String length 1 out of range: 2-2$' new "cli length test len1 2 OK" expectfn "$clixon_cli -1f $cfg -l o set len1 xy" 0 '^$' @@ -527,12 +527,12 @@ EOF expecteof "$clixon_netconf -qf $cfg" 0 'x]]>]]>' "^]]>]]>$" new "netconf validate len1 1 wrong" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementlen1errorstring length out of range: 1]]>]]>$' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementlen1errorString length 1 out of range: 2-2]]>]]>$' #-------- len2 range and blanks new "cli length test len2 3 error" - expectfn "$clixon_cli -1f $cfg -l o set len2 ab" 255 '^CLI syntax error: "set len2 ab": String length not within limits: 2$' + expectfn "$clixon_cli -1f $cfg -l o set len2 ab" 255 '^CLI syntax error: "set len2 ab": String length 2 out of range: 4-4000$' new "cli length test len2 42 ok" expectfn "$clixon_cli -1f $cfg -l o set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 '^$' @@ -547,7 +547,7 @@ EOF #-------- len4 multiple ranges 2..3 | 20-29 new "cli length test len4 1 error" - expectfn "$clixon_cli -1f $cfg -l o set len4 a" 255 '^CLI syntax error: "set len4 a": String length not within limits: 1$' + expectfn "$clixon_cli -1f $cfg -l o set len4 a" 255 '^CLI syntax error: "set len4 a": String length 1 out of range: 2-3, 20-29$' new "cli length test len4 2 ok" expectfn "$clixon_cli -1f $cfg -l o set len4 ab" 0 '^$' @@ -614,9 +614,12 @@ EOF } # Run without db cache -testrun false +testrun nocache # Run with db cache -testrun true +testrun cache + +# Run with zero-copy XXX does not work +#testrun cache-zerocopy rm -rf $dir diff --git a/test/test_type_range.sh b/test/test_type_range.sh new file mode 100755 index 00000000..35db73c5 --- /dev/null +++ b/test/test_type_range.sh @@ -0,0 +1,252 @@ +#!/bin/bash +# Range type tests. +# Mainly error messages and multiple ranges +# Tests all int types including decimal64 and string length ranges +# See also test_type.sh + +# Magic line must be first in script (see README.md) +s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi + +APPNAME=example + +# Which format to use as datastore format internally +: ${format:=xml} + +cfg=$dir/conf_yang.xml +fyang=$dir/type.yang +dclispec=$dir/clispec/ + +# XXX: add more types, now only uint8 and int8 +cat < $fyang +module example{ + yang-version 1.1; + namespace "urn:example:clixon"; + prefix ex; + typedef tint8{ + type int8{ + range "1..10 | 14..20"; + } + } + typedef tint16{ + type int16{ + range "1..10 | 14..20"; + } + } + typedef tint32{ + type int32{ + range "1..10 | 14..20"; + } + } + typedef tint64{ + type int64{ + range "1..10 | 14..20"; + } + } + typedef tuint8{ + type uint8{ + range "1..10 | 14..20"; + } + } + typedef tuint16{ + type uint16{ + range "1..10 | 14..20"; + } + } + typedef tuint32{ + type uint32{ + range "1..10 | 14..20"; + } + } + typedef tuint64{ + type uint64{ + range "1..10 | 14..20"; + } + } + typedef tdecimal64{ + type decimal64{ + fraction-digits 3; + range "1..10 | 14..20"; + } + } + typedef tstring{ + type string{ + length "1..10 | 14..20"; + } + } + leaf lint8 { + type tint8; + } + leaf lint16 { + type tint16; + } + leaf lint32 { + type tint32; + } + leaf lint64 { + type tint64; + } + leaf luint8 { + type tuint8; + } + leaf luint16 { + type tuint16; + } + leaf luint32 { + type tuint32; + } + leaf luint64 { + type tuint64; + } + leaf ldecimal64 { + type tdecimal64; + } + leaf lstring { + type tstring; + } +} +EOF + +mkdir $dclispec + +# clispec for both generated cli and a hardcoded range check +cat < $dclispec/clispec.cli + CLICON_MODE="example"; + CLICON_PROMPT="%U@%H> "; + CLICON_PLUGIN="example_cli"; + + # Manually added (not generated) + manual hint8 ; + manual hint16 ; + manual hint32 ; + manual hint64 ; + + manual huint8 ; + manual huint16 ; + manual huint32 ; + manual huint64 ; + + manual hdecimal64 ; + + manual hstring ; + + # Generated cli + set @datamodel, cli_set(); + merge @datamodel, cli_merge(); + create @datamodel, cli_create(); + show, cli_show_config("candidate", "text", "/"); + quit("Quit"), cli_quit(); +EOF + +cat < $cfg + + $cfg + $dir + /usr/local/share/clixon + $IETFRFC + $fyang + $dclispec + /usr/local/lib/$APPNAME/cli + $APPNAME + /usr/local/var/$APPNAME/$APPNAME.sock + /usr/local/var/$APPNAME/$APPNAME.pidfile + 1 + /usr/local/var/$APPNAME + $format + +EOF + +# Type range tests. +# Parameters: 1: type (eg uint8) +# 2: val OK +# 3: eval Invalid value +# 4: post (eg .000 - special for decimal64, others should have "") +testrange(){ + t=$1 + val=$2 + eval=$3 + post=$4 + + if [ $t = "string" ]; then # special case for string type error msg + len=$(echo -n "$eval" | wc -c) + errmsg="String length $len out of range: 1$post-10$post, 14$post-20$post" + else + errmsg="Number $eval$post out of range: 1$post-10$post, 14$post-20$post" + fi + + new "generated cli set $t leaf invalid" + expectfn "$clixon_cli -1f $cfg -l o set l$t $eval" 255 "$errmsg"; + + new "generated cli set $t leaf OK" + expectfn "$clixon_cli -1f $cfg -l o set l$t $val" 0 '^$' + + # XXX Error in cligen order: Unknown command vs Number out of range + # olof@vandal> set luint8 0 + # CLI syntax error: "set luint8 0": Number 0 is out of range: 14 - 20 + # olof@vandal> set luint8 1 + # olof@vandal> set luint8 0 + # CLI syntax error: "set luint8 0": Unknown command +# (SAME AS FIRST ^) +# new "generated cli set $t leaf invalid" +# expectfn "$clixon_cli -1f $cfg -l o set l$t $eval" 255 "\"set l$t $eval\": Number $eval out of range: 1-10, 14-20"; + + new "manual cli set $t leaf OK" + expectfn "$clixon_cli -1f $cfg -l o man h$t $val" 0 '^$' + + new "manual cli set $t leaf invalid" + echo "$clixon_cli -1f $cfg -l o set h$t $eval" + expectfn "$clixon_cli -1f $cfg -l o set l$t $eval" 255 'Unknown command' + + new "discard" + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" + + new "Netconf set invalid $t leaf" + expecteof "$clixon_netconf -qf $cfg" 0 "$eval]]>]]>" "^]]>]]>$" + + new "netconf get config" + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^$eval]]>]]>$" + + new "netconf validate invalid range" + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^applicationbad-elementl$terror$errmsg]]>]]>$" + + new "discard" + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" +} + +if [ $BE -ne 0 ]; then + new "kill old backend" + sudo clixon_backend -zf $cfg + if [ $? -ne 0 ]; then + err + fi + new "start backend -s init -f $cfg" + start_backend -s init -f $cfg + + new "waiting" + wait_backend +fi + +new "test params: -f $cfg" + +# Test all int types +for t in int8 int16 int32 int64 uint8 uint16 uint32 uint64; do + testrange $t 1 0 "" +done + +# decimal64 requires 3 decimals as postfix +testrange decimal64 1 0 ".000" + +# test string with lengthlimit +testrange string "012" "01234567890" "" + +if [ $BE -ne 0 ]; then + new "Kill backend" + # Check if premature kill + pid=`pgrep -u root -f clixon_backend` + if [ -z "$pid" ]; then + err "backend already dead" + fi + # kill backend + stop_backend -f $cfg +fi + +rm -rf $dir From c90aa8371c9c8cdb75f79e056ae88709e8c3fe98 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 20 Jun 2019 15:35:57 +0200 Subject: [PATCH 07/17] * Fixed [identityref validation fails when using typedef #87](https://github.com/clicon/clixon/issues/87) --- CHANGELOG.md | 1 + lib/src/clixon_xml_map.c | 25 +++++++++-------- lib/src/clixon_yang_type.c | 3 +- test/test_identity.sh | 56 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 70 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 988fd9f9..870710bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -251,6 +251,7 @@ ### Corrected Bugs +* Fixed [identityref validation fails when using typedef #87](https://github.com/clicon/clixon/issues/87) * Fixed a problem with some netconf error messages caused restconf daemon to exit due to no XML encoding * Check cligen tab mode, dont start if CLICON_CLI_TAB_MODE is undefined * Startup transactions did not mark added tree with XML_FLAG_ADD as it should. diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index a536e679..3abfcb3a 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -1206,19 +1206,20 @@ xml_yang_validate_all(clicon_handle h, /* Special case if leaf is leafref, then first check against current xml tree */ - if ((yc = yang_find(ys, Y_TYPE, NULL)) != NULL){ - if (strcmp(yc->ys_argument, "leafref") == 0){ - if ((ret = validate_leafref(xt, yc, xret)) < 0) - goto done; - if (ret == 0) - goto fail; - } - else if (strcmp(yc->ys_argument, "identityref") == 0){ - if ((ret = validate_identityref(xt, ys, yc, xret)) < 0) - goto done; - if (ret == 0) - goto fail; + /* Get base type yc */ + if (yang_type_get(ys, NULL, &yc, NULL, NULL, NULL, NULL, NULL) < 0) + goto done; + if (strcmp(yang_argument_get(yc), "leafref") == 0){ + if ((ret = validate_leafref(xt, yc, xret)) < 0) + goto done; + if (ret == 0) + goto fail; } + else if (strcmp(yang_argument_get(yc), "identityref") == 0){ + if ((ret = validate_identityref(xt, ys, yc, xret)) < 0) + goto done; + if (ret == 0) + goto fail; } break; default: diff --git a/lib/src/clixon_yang_type.c b/lib/src/clixon_yang_type.c index 3e00f7e8..61c63d43 100644 --- a/lib/src/clixon_yang_type.c +++ b/lib/src/clixon_yang_type.c @@ -1416,13 +1416,14 @@ yang_type_resolve(yang_stmt *yorig, * * @code * yang_stmt *yrestype; + * char *origtype = NULL; * int options; * cvec *cvv = NULL; * cvec *patterns = cvec_new(0); * cvec *regexps = cvec_new(0); * uint8_t fraction; * - * if (yang_type_get(ys, &type, &yrestype, &options, &cvv, + * if (yang_type_get(ys, &origtype, &yrestype, &options, &cvv, * patterns, regexps, &fraction) < 0) * goto err; * if (yrestype == NULL) # unresolved diff --git a/test/test_identity.sh b/test/test_identity.sh index a31b1bbb..782e8fa6 100755 --- a/test/test_identity.sh +++ b/test/test_identity.sh @@ -106,7 +106,31 @@ cat < $fyang container aes-parameters { when "../crypto = 'mc:aes'"; } - } + identity acl-base; + typedef acl-type { + description "problem detected in ietf-access-control-list.yang"; + type identityref { + base acl-base; + } + } + identity ipv4-acl-type { + base mc:acl-base; + } + identity ipv6-acl-type { + base mc:acl-base; + } + container acls { + list acl { + key name; + leaf name { + type string; + } + leaf type { + type acl-type; + } + } + } + } EOF new "test params: -f $cfg" @@ -120,7 +144,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "Set crypto to aes" @@ -186,6 +210,34 @@ expectfn "$clixon_cli -1 -f $cfg -l o set crypto des:des3" 0 "^$" new "cli validate" expectfn "$clixon_cli -1 -f $cfg -l o validate" 0 "^$" +new "Netconf set acl-type" +expecteof "$clixon_netconf -qf $cfg" 0 'xmc:ipv4-acl-type]]>]]>' '^]]>]]>$' + +new "netconf validate " +expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" + +new "Netconf set undefined acl-type" +expecteof "$clixon_netconf -qf $cfg" 0 'xundefined]]>]]>' '^]]>]]>$' + +new "netconf validate fail" +expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationoperation-failederrorIdentityref validation failed, Identityref validation failed, not derived from acl-base]]>]]>$' + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" + +new "CLI set acl-type" +expectfn "$clixon_cli -1 -f $cfg -l o set acls acl x type mc:ipv4-acl-type" 0 "^$" + +new "cli validate" +expectfn "$clixon_cli -1 -f $cfg -l o validate" 0 "^$" + +new "CLI set wrong acl-type" +expectfn "$clixon_cli -1 -f $cfg -l o set acls acl x type undefined" 0 "^$" + +new "cli validate" +expectfn "$clixon_cli -1 -f $cfg -l o validate" 255 "Identityref validation failed" + + if [ $BE -eq 0 ]; then exit # BE fi From d703c274b6d95a079568bca4d8b671348031316f Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 20 Jun 2019 15:43:11 +0200 Subject: [PATCH 08/17] test string problem --- test/test_identity.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_identity.sh b/test/test_identity.sh index 782e8fa6..0c23f331 100755 --- a/test/test_identity.sh +++ b/test/test_identity.sh @@ -220,7 +220,7 @@ new "Netconf set undefined acl-type" expecteof "$clixon_netconf -qf $cfg" 0 'xundefined]]>]]>' '^]]>]]>$' new "netconf validate fail" -expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationoperation-failederrorIdentityref validation failed, Identityref validation failed, not derived from acl-base]]>]]>$' +expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationoperation-failederrorIdentityref validation failed, Identityref validation failed' new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" From fe35e181fd8b8a8860a791107c086d2a8023885e Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 20 Jun 2019 15:56:02 +0200 Subject: [PATCH 09/17] identityref errmsg memory error --- lib/src/clixon_xml_map.c | 14 ++++++++++---- test/test_identity.sh | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/src/clixon_xml_map.c b/lib/src/clixon_xml_map.c index 3abfcb3a..e3e0f1ae 100644 --- a/lib/src/clixon_xml_map.c +++ b/lib/src/clixon_xml_map.c @@ -328,11 +328,12 @@ validate_identityref(cxobj *xt, { int retval = -1; - char *node; + char *node = NULL; yang_stmt *ybaseref; /* This is the type's base reference */ yang_stmt *ybaseid; char *prefix = NULL; cbuf *cb = NULL; + cbuf *cb2 = NULL; /* Get idref value. Then see if this value is derived from ytype. * Always add default prefix because derived identifiers are stored with @@ -365,10 +366,13 @@ validate_identityref(cxobj *xt, * The derived node list is a cvec computed XXX */ if (cvec_find(yang_cvec_get(ybaseid), node) == NULL){ - cbuf_reset(cb); - cprintf(cb, "Identityref validation failed, %s not derived from %s", + if ((cb2 = cbuf_new()) == NULL){ + clicon_err(OE_UNIX, errno, "cbuf_new"); + goto done; + } + cprintf(cb2, "Identityref validation failed, %s not derived from %s", node, yang_argument_get(ybaseid)); - if (netconf_operation_failed_xml(xret, "application", cbuf_get(cb)) < 0) + if (netconf_operation_failed_xml(xret, "application", cbuf_get(cb2)) < 0) goto done; goto fail; } @@ -376,6 +380,8 @@ validate_identityref(cxobj *xt, done: if (cb) cbuf_free(cb); + if (cb2) + cbuf_free(cb2); return retval; fail: retval = 0; diff --git a/test/test_identity.sh b/test/test_identity.sh index 0c23f331..7a8f3214 100755 --- a/test/test_identity.sh +++ b/test/test_identity.sh @@ -220,7 +220,7 @@ new "Netconf set undefined acl-type" expecteof "$clixon_netconf -qf $cfg" 0 'xundefined]]>]]>' '^]]>]]>$' new "netconf validate fail" -expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationoperation-failederrorIdentityref validation failed, Identityref validation failed' +expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationoperation-failederrorIdentityref validation failed, mc:undefined not derived from acl-base]]>]]>' new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" From d12644a5ef2d164fab582832dcbc70d8aad48c5d Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 20 Jun 2019 19:00:22 +0200 Subject: [PATCH 10/17] Fixed [Wrong yang-generated cli code for typeref identityref combination #88](https://github.com/clicon/clixon/issues/88) --- CHANGELOG.md | 1 + apps/cli/cli_generate.c | 9 +++++---- test/test_identity.sh | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 870710bc..f93f16b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -251,6 +251,7 @@ ### Corrected Bugs +* Fixed [Wrong yang-generated cli code for typeref identityref combination #88](https://github.com/clicon/clixon/issues/88) * Fixed [identityref validation fails when using typedef #87](https://github.com/clicon/clixon/issues/87) * Fixed a problem with some netconf error messages caused restconf daemon to exit due to no XML encoding * Check cligen tab mode, dont start if CLICON_CLI_TAB_MODE is undefined diff --git a/apps/cli/cli_generate.c b/apps/cli/cli_generate.c index c5d26013..d0fc91d7 100644 --- a/apps/cli/cli_generate.c +++ b/apps/cli/cli_generate.c @@ -185,14 +185,15 @@ yang2cli_var_identityref(yang_stmt *ys, char *name; char *id; int i; + int len; - /* Add a wildchar string first -let validate take it for default prefix */ - cprintf(cb, ">"); - if (helptext) - cprintf(cb, "(\"%s\")", helptext); if ((ybaseref = yang_find(ytype, Y_BASE, NULL)) != NULL && (ybaseid = yang_find_identity(ys, yang_argument_get(ybaseref))) != NULL){ if (cvec_len(yang_cvec_get(ybaseid)) > 0){ + /* Add a wildchar string first -let validate take it for default prefix */ + cprintf(cb, ">"); + if (helptext) + cprintf(cb, "(\"%s\")", helptext); cprintf(cb, "|<%s:%s choice:", yang_argument_get(ys), cvtypestr); i = 0; while ((cv = cvec_each(yang_cvec_get(ybaseid), cv)) != NULL){ diff --git a/test/test_identity.sh b/test/test_identity.sh index 7a8f3214..81f956e5 100755 --- a/test/test_identity.sh +++ b/test/test_identity.sh @@ -130,6 +130,12 @@ cat < $fyang } } } + identity empty; /* some errors with an empty identity set */ + leaf e { + type identityref { + base mc:empty; + } + } } EOF @@ -237,6 +243,15 @@ expectfn "$clixon_cli -1 -f $cfg -l o set acls acl x type undefined" 0 "^$" new "cli validate" expectfn "$clixon_cli -1 -f $cfg -l o validate" 255 "Identityref validation failed" +# test empty identityref list +new "cli set empty" +expectfn "$clixon_cli -1 -f $cfg -l o set e undefined" 0 "^$" + +new "cli validate" +expectfn "$clixon_cli -1 -f $cfg -l o validate" 255 "Identityref validation failed" + +new "netconf discard-changes" +expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" if [ $BE -eq 0 ]; then exit # BE From b64dd678dc0a7fb9ee3d8b55ea0f1ea3828d0904 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Fri, 21 Jun 2019 17:44:52 +0200 Subject: [PATCH 11/17] CLI ranges error shown instead of "Unknown command" --- apps/cli/cli_generate.c | 2 -- test/test_type.sh | 28 ++++++++++++++-------------- test/test_type_range.sh | 6 +++--- test/test_union.sh | 2 +- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/apps/cli/cli_generate.c b/apps/cli/cli_generate.c index d0fc91d7..a205eec0 100644 --- a/apps/cli/cli_generate.c +++ b/apps/cli/cli_generate.c @@ -163,7 +163,6 @@ cli_callback_generate(clicon_handle h, return retval; } - /*! Generate identityref statements for CLI variables * @param[in] ys Yang statement * @param[in] ytype Yang union type being resolved @@ -185,7 +184,6 @@ yang2cli_var_identityref(yang_stmt *ys, char *name; char *id; int i; - int len; if ((ybaseref = yang_find(ytype, Y_BASE, NULL)) != NULL && (ybaseid = yang_find_identity(ys, yang_argument_get(ybaseref))) != NULL){ diff --git a/test/test_type.sh b/test/test_type.sh index ac52f8b0..f305113f 100755 --- a/test/test_type.sh +++ b/test/test_type.sh @@ -238,7 +238,7 @@ EOF expectfn "$clixon_cli -1f $cfg -l o set c talle x99" 0 '^$' new "cli set transitive string error. Wrong type" - expectfn "$clixon_cli -1f $cfg -l o set c talle 9xx" 255 '^CLI syntax error: "set c talle 9xx": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set c talle 9xx" 255 '^CLI syntax error: "set c talle 9xx": regexp match fail: 9xx does not match \[a-z\]\[0-9\]\*$' new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" @@ -266,10 +266,10 @@ EOF expectfn "$clixon_cli -1f $cfg -l o -l o validate" 0 '^$' new "cli set transitive union error. should fail" - expectfn "$clixon_cli -1f $cfg -l o set c ulle kalle" 255 '^CLI syntax error: "set c ulle kalle": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set c ulle kalle" 255 "^CLI syntax error: \"set c ulle kalle\": 'kalle' is not a number$" new "cli set transitive union error int" - expectfn "$clixon_cli -1f $cfg -l o set c ulle 55" 255 '^CLI syntax error: "set c ulle 55": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set c ulle 55" 255 '^CLI syntax error: "set c ulle 55": Number 55 out of range: 4-44$' new "netconf set transitive union error int" expecteof "$clixon_netconf -qf $cfg" 0 '55]]>]]>' "^]]>]]>" @@ -354,7 +354,7 @@ EOF #expectfn "$clixon_cli -1f $cfg -l o set num1 \-100" 0 '^$' new "cli range test num1 2 error" - expectfn "$clixon_cli -1f $cfg -l o set num1 2" 255 '^CLI syntax error: "set num1 2": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set num1 2" 255 '^CLI syntax error: "set num1 2": Number 2 out of range: 1-1$' new "netconf range set num1 -1" expecteof "$clixon_netconf -qf $cfg" 0 '-1]]>]]>' "^]]>]]>$" @@ -374,7 +374,7 @@ EOF expectfn "$clixon_cli -1f $cfg -l o set num2 1000" 0 '^$' new "cli range test num2 5000 error" - expectfn "$clixon_cli -1f $cfg -l o set num2 5000" 255 '^CLI syntax error: "set num2 5000": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set num2 5000" 255 '^CLI syntax error: "set num2 5000": Number 5000 out of range: 4-4000$' new "netconf range set num2 3 fail" expecteof "$clixon_netconf -qf $cfg" 0 '3]]>]]>' "^]]>]]>$" @@ -403,7 +403,7 @@ EOF expectfn "$clixon_cli -1f $cfg -l o set num3 42" 0 '^$' new "cli range test num3 260 fail" - expectfn "$clixon_cli -1f $cfg -l o set num3 260" 255 '^CLI syntax error: "set num3 260": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set num3 260" 255 '^CLI syntax error: "set num3 260": 260 is out of range\(type is uint8\)$' new "cli range test num3 -1 fail" expectfn "$clixon_cli -1f $cfg -l o set num3 -1" 255 "CLI syntax error:" @@ -426,13 +426,13 @@ EOF expectfn "$clixon_cli -1f $cfg -l e set num4 2" 0 '^$' new "cli range test num4 multiple 20 fail" - expectfn "$clixon_cli -1f $cfg -l o set num4 20" 255 '^CLI syntax error: "set num4 20": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set num4 20" 255 '^CLI syntax error: "set num4 20": Number 20 out of range: 1-2, 42-50$' new "cli range test num4 multiple 42 ok" expectfn "$clixon_cli -1f $cfg -l o set num4 42" 0 '^$' new "cli range test num4 multiple 99 fail" - expectfn "$clixon_cli -1f $cfg -l o set num4 99" 255 '^CLI syntax error: "set num4 99": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set num4 99" 255 '^CLI syntax error: "set num4 99": Number 99 out of range: 1-2, 42-50$' new "netconf range set num4 multiple 2" expecteof "$clixon_netconf -qf $cfg" 0 '42]]>]]>' "^]]>]]>$" @@ -467,7 +467,7 @@ EOF expectfn "$clixon_cli -1f $cfg -l o set dec 15.0" 0 '^$' new "cli range dec64 multiple 30.0 fail" - expectfn "$clixon_cli -1f $cfg -l o set dec 30.0" 255 '^CLI syntax error: "set dec 30.0": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set dec 30.0" 255 '^CLI syntax error: "set dec 30.0": Number 30.000 out of range: -3.500--2.500, 0.000-0.000, 10.000-20.000$' new "dec64 discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" @@ -518,7 +518,7 @@ EOF expectfn "$clixon_cli -1f $cfg -l o set len1 xy" 0 '^$' new "cli length test len1 3 error" - expectfn "$clixon_cli -1f $cfg -l o set len1 hej" 255 '^CLI syntax error: "set len1 hej": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set len1 hej" 255 '^CLI syntax error: "set len1 hej": String length 3 out of range: 2-2$' new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" @@ -553,26 +553,26 @@ EOF expectfn "$clixon_cli -1f $cfg -l o set len4 ab" 0 '^$' new "cli length test len4 10 error" - expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghij" 255 '^CLI syntax error: "set len4 abcdefghij": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghij" 255 '^CLI syntax error: "set len4 abcdefghij": String length 10 out of range: 2-3, 20-29$' new "cli length test len4 20 ok" expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghijabcdefghija" 0 '^$' new "cli length test len4 30 error" - expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghijabcdefghijabcdefghij" 255 '^CLI syntax error: "set len4 abcdefghijabcdefghijabcdefghij": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghijabcdefghijabcdefghij" 255 '^CLI syntax error: "set len4 abcdefghijabcdefghijabcdefghij": String length 30 out of range: 2-3, 20-29$' # XSD schema -> POSIX ECE translation new "cli yang pattern \d ok" expectfn "$clixon_cli -1f $cfg -l o set digit4 0123" 0 '^$' new "cli yang pattern \d error" - expectfn "$clixon_cli -1f $cfg -l o set digit4 01b2" 255 '^CLI syntax error: "set digit4 01b2": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set digit4 01b2" 255 '^CLI syntax error: "set digit4 01b2": regexp match fail: 01b2 does not match' new "cli yang pattern \w ok" expectfn "$clixon_cli -1f $cfg -l o set word4 abc9" 0 '^$' new "cli yang pattern \w error" - expectfn "$clixon_cli -1f $cfg -l o set word4 ab%3" 255 '^CLI syntax error: "set word4 ab%3": Unknown command$' + expectfn "$clixon_cli -1f $cfg -l o set word4 ab%3" 255 '^CLI syntax error: "set word4 ab%3": regexp match fail: ab%3 does not match' new "netconf pattern \w" expecteof "$clixon_netconf -qf $cfg" 0 'aXG9]]>]]>' "^]]>]]>$" diff --git a/test/test_type_range.sh b/test/test_type_range.sh index 35db73c5..a6c030d0 100755 --- a/test/test_type_range.sh +++ b/test/test_type_range.sh @@ -186,15 +186,15 @@ testrange(){ # olof@vandal> set luint8 0 # CLI syntax error: "set luint8 0": Unknown command # (SAME AS FIRST ^) -# new "generated cli set $t leaf invalid" -# expectfn "$clixon_cli -1f $cfg -l o set l$t $eval" 255 "\"set l$t $eval\": Number $eval out of range: 1-10, 14-20"; + new "generated cli set $t leaf invalid" + expectfn "$clixon_cli -1f $cfg -l o set l$t $eval" 255 "$errmsg" new "manual cli set $t leaf OK" expectfn "$clixon_cli -1f $cfg -l o man h$t $val" 0 '^$' new "manual cli set $t leaf invalid" echo "$clixon_cli -1f $cfg -l o set h$t $eval" - expectfn "$clixon_cli -1f $cfg -l o set l$t $eval" 255 'Unknown command' + expectfn "$clixon_cli -1f $cfg -l o set l$t $eval" 255 "$errmsg" new "discard" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" diff --git a/test/test_union.sh b/test/test_union.sh index 8fa52a7b..b6862ff3 100755 --- a/test/test_union.sh +++ b/test/test_union.sh @@ -99,7 +99,7 @@ new "cli set transitive union" expectfn "$clixon_cli -1f $cfg -l o set c ulle 33" 0 "^$" new "cli set transitive union error" -expectfn "$clixon_cli -1f $cfg -l o set c ulle kalle" 255 '^CLI syntax error: "set c ulle kalle": Unknown command$' +expectfn "$clixon_cli -1f $cfg -l o set c ulle kalle" 255 "^CLI syntax error: \"set c ulle kalle\": 'kalle' is not a number$" if [ $BE -eq 0 ]; then exit # BE From 4cd63f6b55f210f4e33d7566c78954583471b031 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Sat, 22 Jun 2019 12:22:41 +0200 Subject: [PATCH 12/17] dded enable/disable as alternative boolean truth values on input (in CLIgen) --- test/test_type.sh | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/test/test_type.sh b/test/test_type.sh index f305113f..c2a37119 100755 --- a/test/test_type.sh +++ b/test/test_type.sh @@ -192,6 +192,10 @@ module example{ pattern '[a-zA-Z_][a-zA-Z0-9_\-.]*'; } } + leaf bool { + description "For testing different truth values in CLI"; + type boolean; + } } EOF @@ -589,7 +593,6 @@ EOF new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" - #------ minus new "type with minus" @@ -601,6 +604,27 @@ EOF #new "cli type with minus" #expectfn "$clixon_cli -1f $cfg -l o set name my-name" 0 '^$' + #------ cli truth-values: true/on/enable false/off/disable + + new "cli truth: true" + expectfn "$clixon_cli -1f $cfg -l o set bool true" 0 '^$' + new "cli truth: false" + expectfn "$clixon_cli -1f $cfg -l o set bool false" 0 '^$' + new "cli truth: on" + expectfn "$clixon_cli -1f $cfg -l o set bool on" 0 '^$' + new "cli verify on translates to true" + expectfn "$clixon_cli -1f $cfg -l o show conf" 0 'bool true;' + new "cli truth: off" + expectfn "$clixon_cli -1f $cfg -l o set bool off" 0 '^$' + new "cli verify off translates to false" + expectfn "$clixon_cli -1f $cfg -l o show conf" 0 'bool false;' + new "cli truth: enable" + expectfn "$clixon_cli -1f $cfg -l o set bool enable" 0 '^$' + new "cli truth: disable" + expectfn "$clixon_cli -1f $cfg -l o set bool disable" 0 '^$' + new "cli truth: wrong" + expectfn "$clixon_cli -1f $cfg -l o set bool wrong" 255 "'wrong' is not a boolean value" + if [ $BE -ne 0 ]; then new "Kill backend" # Check if premature kill From 6dec522af1e8dfb158e400c6aa7afd2d8abb3580 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Tue, 25 Jun 2019 16:40:04 +0200 Subject: [PATCH 13/17] Changed invalid number ranges outside type scope. --- CHANGELOG.md | 4 +-- lib/src/clixon_yang_type.c | 4 +-- test/test_type.sh | 4 +-- test/test_type_range.sh | 69 ++++++++++++++++++++++++++++++++++++-- 4 files changed, 73 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f93f16b3..eb2fe361 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,8 +72,8 @@ * Error messages for invalid number ranges and string lengths have been uniformed and changed. * Error messages for invalid ranges are now on the form: ``` - Number 23 out of range: 1-10 - String length 23 out of range: 1-10 + Number 23 out of range: 1 - 10 + String length 23 out of range: 1 - 10 ``` * On validation callbacks, XML_FLAG_ADD is added to all nodes at startup validation, not just the top-level. This is the same behaviour as for steady-state validation. * All hash_ functions have been prefixed with `clicon_` to avoid name collision with other packages (frr) diff --git a/lib/src/clixon_yang_type.c b/lib/src/clixon_yang_type.c index 61c63d43..d548c75b 100644 --- a/lib/src/clixon_yang_type.c +++ b/lib/src/clixon_yang_type.c @@ -626,7 +626,7 @@ outofrange(cg_var *cv0, if (i>2) cprintf(cb, ", "); cv2cbuf(cv1, cb); - cprintf(cb, "-"); + cprintf(cb, " - "); cv2cbuf(cv2, cb); } if (reason && (*reason = strdup(cbuf_get(cb))) == NULL) @@ -675,7 +675,7 @@ outoflength(uint64_t u64, if (i>2) cprintf(cb, ", "); cv2cbuf(cv1, cb); - cprintf(cb, "-"); + cprintf(cb, " - "); cv2cbuf(cv2, cb); } if (reason && (*reason = strdup(cbuf_get(cb))) == NULL) diff --git a/test/test_type.sh b/test/test_type.sh index c2a37119..978cba77 100755 --- a/test/test_type.sh +++ b/test/test_type.sh @@ -407,7 +407,7 @@ EOF expectfn "$clixon_cli -1f $cfg -l o set num3 42" 0 '^$' new "cli range test num3 260 fail" - expectfn "$clixon_cli -1f $cfg -l o set num3 260" 255 '^CLI syntax error: "set num3 260": 260 is out of range\(type is uint8\)$' + expectfn "$clixon_cli -1f $cfg -l o set num3 260" 255 '^CLI syntax error: "set num3 260": Number 260 out of range: 0-255$' new "cli range test num3 -1 fail" expectfn "$clixon_cli -1f $cfg -l o set num3 -1" 255 "CLI syntax error:" @@ -416,7 +416,7 @@ EOF expecteof "$clixon_netconf -qf $cfg" 0 '260]]>]]>' "^]]>]]>$" new "netconf validate num3 260 fail" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum3error260 is out of range(type is uint8)]]>]]>$' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum3errorNumber 260 out of range: 0-255]]>]]>$' new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" diff --git a/test/test_type_range.sh b/test/test_type_range.sh index a6c030d0..efd55a60 100755 --- a/test/test_type_range.sh +++ b/test/test_type_range.sh @@ -73,6 +73,7 @@ module example{ length "1..10 | 14..20"; } } + /* here follows constrained ints */ leaf lint8 { type tint8; } @@ -103,6 +104,36 @@ module example{ leaf lstring { type tstring; } + /* here follows unlimited ints */ + leaf rint8 { + type int8; + } + leaf rint16 { + type int16; + } + leaf rint32 { + type int32; + } + leaf rint64 { + type int64; + } + leaf ruint8 { + type uint8; + } + leaf ruint16 { + type uint16; + } + leaf ruint32 { + type uint32; + } + leaf ruint64 { + type uint64; + } + leaf rdecimal64 { + type decimal64{ + fraction-digits 3; + } + } } EOF @@ -168,9 +199,9 @@ testrange(){ if [ $t = "string" ]; then # special case for string type error msg len=$(echo -n "$eval" | wc -c) - errmsg="String length $len out of range: 1$post-10$post, 14$post-20$post" + errmsg="String length $len out of range: 1$post - 10$post, 14$post - 20$post" else - errmsg="Number $eval$post out of range: 1$post-10$post, 14$post-20$post" + errmsg="Number $eval$post out of range: 1$post - 10$post, 14$post - 20$post" fi new "generated cli set $t leaf invalid" @@ -212,6 +243,29 @@ testrange(){ expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" } +# Type unlimited value range test. Only test invalid number out of range of type +# Parameters: 1: type (eg uint8) +# 2: val +# 3: post (eg .000 - special for decimal64, others should have "") +testunlimit(){ + t=$1 + val=$2 + rmin=$3 + rmax=$4 + post=$5 + + errmsg="Number $val$post out of range: $rmin$post - $rmax$post" + + new "Netconf set invalid $t leaf" + expecteof "$clixon_netconf -qf $cfg" 0 "$val]]>]]>" "^]]>]]>$" + + new "netconf validate invalid range" + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^applicationbad-elementl$terror$errmsg]]>]]>$" + + new "discard" + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" +} + if [ $BE -ne 0 ]; then new "kill old backend" sudo clixon_backend -zf $cfg @@ -227,6 +281,17 @@ fi new "test params: -f $cfg" +# Test all int types +testunlimit int8 300 -128 127 "" +testunlimit int16 73000 -32768 32767 "" +testunlimit int32 4900000000 -2147483648 2147483647 "" +testunlimit int64 49739274983274983274983274 -9223372036854775808 9223372036854775807 "" +testunlimit uint8 300 0 255 "" +testunlimit uint16 73000 0 65535 "" +testunlimit uint32 4900000000 0 4294967295 "" +testunlimit uint64 49739274983274983274983274 0 18446744073709551615 "" +#testunlimit decimal64 49739274983274983274983274 -9223372036854775808 9223372036854775807 ".000" + # Test all int types for t in int8 int16 int32 int64 uint8 uint16 uint32 uint64; do testrange $t 1 0 "" From 91d01f8c28e1cca23f58be2eb397ef7720e7b8ad Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Tue, 25 Jun 2019 16:55:32 +0200 Subject: [PATCH 14/17] range test --- test/test_type_range.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test_type_range.sh b/test/test_type_range.sh index efd55a60..0760d485 100755 --- a/test/test_type_range.sh +++ b/test/test_type_range.sh @@ -257,10 +257,10 @@ testunlimit(){ errmsg="Number $val$post out of range: $rmin$post - $rmax$post" new "Netconf set invalid $t leaf" - expecteof "$clixon_netconf -qf $cfg" 0 "$val]]>]]>" "^]]>]]>$" + expecteof "$clixon_netconf -qf $cfg" 0 "$val]]>]]>" "^]]>]]>$" new "netconf validate invalid range" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^applicationbad-elementl$terror$errmsg]]>]]>$" + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^applicationbad-elementr$terror$errmsg]]>]]>$" new "discard" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" From 1134b084c3d9af2ccd363711bb0ecb92e8669f33 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Sun, 30 Jun 2019 15:14:51 +0200 Subject: [PATCH 15/17] error range test error x - y --- .gitignore | 1 + test/test_transaction.sh | 2 +- test/test_type.sh | 40 ++++++++++++++++++++-------------------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/.gitignore b/.gitignore index 4927378c..6826005a 100644 --- a/.gitignore +++ b/.gitignore @@ -49,6 +49,7 @@ build-root/*.rpm build-root/rpmbuild util/clixon_util_datastore +util/clixon_util_insert util/clixon_util_json util/clixon_util_stream util/clixon_util_xml diff --git a/test/test_transaction.sh b/test/test_transaction.sh index eec920dd..4055cc7d 100755 --- a/test/test_transaction.sh +++ b/test/test_transaction.sh @@ -177,7 +177,7 @@ new "3. Validate system-error config (9999 not in range)" expecteof "$clixon_netconf -qf $cfg" 0 "$nr9999]]>]]>" '^]]>]]>$' new "Validate system-error validate (should fail)" -expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^applicationbad-elementberrorNumber 9999 out of range: 0-100]]>]]>$' +expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' '^applicationbad-elementberrorNumber 9999 out of range: 0 - 100]]>]]>$' new "Validate system-error discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" diff --git a/test/test_type.sh b/test/test_type.sh index 978cba77..96ac57da 100755 --- a/test/test_type.sh +++ b/test/test_type.sh @@ -273,7 +273,7 @@ EOF expectfn "$clixon_cli -1f $cfg -l o set c ulle kalle" 255 "^CLI syntax error: \"set c ulle kalle\": 'kalle' is not a number$" new "cli set transitive union error int" - expectfn "$clixon_cli -1f $cfg -l o set c ulle 55" 255 '^CLI syntax error: "set c ulle 55": Number 55 out of range: 4-44$' + expectfn "$clixon_cli -1f $cfg -l o set c ulle 55" 255 '^CLI syntax error: "set c ulle 55": Number 55 out of range: 4 - 44$' new "netconf set transitive union error int" expecteof "$clixon_netconf -qf $cfg" 0 '55]]>]]>' "^]]>]]>" @@ -358,13 +358,13 @@ EOF #expectfn "$clixon_cli -1f $cfg -l o set num1 \-100" 0 '^$' new "cli range test num1 2 error" - expectfn "$clixon_cli -1f $cfg -l o set num1 2" 255 '^CLI syntax error: "set num1 2": Number 2 out of range: 1-1$' + expectfn "$clixon_cli -1f $cfg -l o set num1 2" 255 '^CLI syntax error: "set num1 2": Number 2 out of range: 1 - 1$' new "netconf range set num1 -1" expecteof "$clixon_netconf -qf $cfg" 0 '-1]]>]]>' "^]]>]]>$" new "netconf validate num1 -1 wrong" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum1errorNumber -1 out of range: 1-1]]>]]>$' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum1errorNumber -1 out of range: 1 - 1]]>]]>$' new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" @@ -372,19 +372,19 @@ EOF #-------- num2 range and blanks new "cli range test num2 3 error" - expectfn "$clixon_cli -1f $cfg -l o set num2 3" 255 '^CLI syntax error: "set num2 3": Number 3 out of range: 4-4000$' + expectfn "$clixon_cli -1f $cfg -l o set num2 3" 255 '^CLI syntax error: "set num2 3": Number 3 out of range: 4 - 4000$' new "cli range test num2 1000 ok" expectfn "$clixon_cli -1f $cfg -l o set num2 1000" 0 '^$' new "cli range test num2 5000 error" - expectfn "$clixon_cli -1f $cfg -l o set num2 5000" 255 '^CLI syntax error: "set num2 5000": Number 5000 out of range: 4-4000$' + expectfn "$clixon_cli -1f $cfg -l o set num2 5000" 255 '^CLI syntax error: "set num2 5000": Number 5000 out of range: 4 - 4000$' new "netconf range set num2 3 fail" expecteof "$clixon_netconf -qf $cfg" 0 '3]]>]]>' "^]]>]]>$" new "netconf validate num2 3 fail" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum2errorNumber 3 out of range: 4-4000]]>]]>$' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum2errorNumber 3 out of range: 4 - 4000]]>]]>$' new "netconf range set num2 1000 ok" expecteof "$clixon_netconf -qf $cfg" 0 '1000]]>]]>' "^]]>]]>$" @@ -396,7 +396,7 @@ EOF expecteof "$clixon_netconf -qf $cfg" 0 '5000]]>]]>' "^]]>]]>$" new "netconf validate num2 5000 fail" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum2errorNumber 5000 out of range: 4-4000]]>]]>$' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum2errorNumber 5000 out of range: 4 - 4000]]>]]>$' new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" @@ -407,7 +407,7 @@ EOF expectfn "$clixon_cli -1f $cfg -l o set num3 42" 0 '^$' new "cli range test num3 260 fail" - expectfn "$clixon_cli -1f $cfg -l o set num3 260" 255 '^CLI syntax error: "set num3 260": Number 260 out of range: 0-255$' + expectfn "$clixon_cli -1f $cfg -l o set num3 260" 255 '^CLI syntax error: "set num3 260": Number 260 out of range: 0 - 255$' new "cli range test num3 -1 fail" expectfn "$clixon_cli -1f $cfg -l o set num3 -1" 255 "CLI syntax error:" @@ -416,7 +416,7 @@ EOF expecteof "$clixon_netconf -qf $cfg" 0 '260]]>]]>' "^]]>]]>$" new "netconf validate num3 260 fail" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum3errorNumber 260 out of range: 0-255]]>]]>$' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementnum3errorNumber 260 out of range: 0 - 255]]>]]>$' new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" @@ -424,19 +424,19 @@ EOF #-------- num4 multiple ranges 1..2 | 42..50 new "cli range test num4 multiple 0 fail" - expectfn "$clixon_cli -1f $cfg -l o set num4 0" 255 '^CLI syntax error: "set num4 0": Number 0 out of range: 1-2, 42-50$' + expectfn "$clixon_cli -1f $cfg -l o set num4 0" 255 '^CLI syntax error: "set num4 0": Number 0 out of range: 1 - 2, 42 - 50$' new "cli range test num4 multiple 2 ok" expectfn "$clixon_cli -1f $cfg -l e set num4 2" 0 '^$' new "cli range test num4 multiple 20 fail" - expectfn "$clixon_cli -1f $cfg -l o set num4 20" 255 '^CLI syntax error: "set num4 20": Number 20 out of range: 1-2, 42-50$' + expectfn "$clixon_cli -1f $cfg -l o set num4 20" 255 '^CLI syntax error: "set num4 20": Number 20 out of range: 1 - 2, 42 - 50$' new "cli range test num4 multiple 42 ok" expectfn "$clixon_cli -1f $cfg -l o set num4 42" 0 '^$' new "cli range test num4 multiple 99 fail" - expectfn "$clixon_cli -1f $cfg -l o set num4 99" 255 '^CLI syntax error: "set num4 99": Number 99 out of range: 1-2, 42-50$' + expectfn "$clixon_cli -1f $cfg -l o set num4 99" 255 '^CLI syntax error: "set num4 99": Number 99 out of range: 1 - 2, 42 - 50$' new "netconf range set num4 multiple 2" expecteof "$clixon_netconf -qf $cfg" 0 '42]]>]]>' "^]]>]]>$" @@ -471,7 +471,7 @@ EOF expectfn "$clixon_cli -1f $cfg -l o set dec 15.0" 0 '^$' new "cli range dec64 multiple 30.0 fail" - expectfn "$clixon_cli -1f $cfg -l o set dec 30.0" 255 '^CLI syntax error: "set dec 30.0": Number 30.000 out of range: -3.500--2.500, 0.000-0.000, 10.000-20.000$' + expectfn "$clixon_cli -1f $cfg -l o set dec 30.0" 255 '^CLI syntax error: "set dec 30.0": Number 30.000 out of range: -3.500 - -2.500, 0.000 - 0.000, 10.000 - 20.000$' new "dec64 discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" @@ -516,13 +516,13 @@ EOF #----------------string ranges--------------------- #-------- len1 single range (2) new "cli length test len1 1 fail" - expectfn "$clixon_cli -1f $cfg -l o set len1 x" 255 '^CLI syntax error: "set len1 x": String length 1 out of range: 2-2$' + expectfn "$clixon_cli -1f $cfg -l o set len1 x" 255 '^CLI syntax error: "set len1 x": String length 1 out of range: 2 - 2$' new "cli length test len1 2 OK" expectfn "$clixon_cli -1f $cfg -l o set len1 xy" 0 '^$' new "cli length test len1 3 error" - expectfn "$clixon_cli -1f $cfg -l o set len1 hej" 255 '^CLI syntax error: "set len1 hej": String length 3 out of range: 2-2$' + expectfn "$clixon_cli -1f $cfg -l o set len1 hej" 255 '^CLI syntax error: "set len1 hej": String length 3 out of range: 2 - 2$' new "netconf discard-changes" expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" "^]]>]]>$" @@ -531,12 +531,12 @@ EOF expecteof "$clixon_netconf -qf $cfg" 0 'x]]>]]>' "^]]>]]>$" new "netconf validate len1 1 wrong" - expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementlen1errorString length 1 out of range: 2-2]]>]]>$' + expecteof "$clixon_netconf -qf $cfg" 0 "]]>]]>" '^applicationbad-elementlen1errorString length 1 out of range: 2 - 2]]>]]>$' #-------- len2 range and blanks new "cli length test len2 3 error" - expectfn "$clixon_cli -1f $cfg -l o set len2 ab" 255 '^CLI syntax error: "set len2 ab": String length 2 out of range: 4-4000$' + expectfn "$clixon_cli -1f $cfg -l o set len2 ab" 255 '^CLI syntax error: "set len2 ab": String length 2 out of range: 4 - 4000$' new "cli length test len2 42 ok" expectfn "$clixon_cli -1f $cfg -l o set len2 hejhophdsakjhkjsadhkjsahdkjsad" 0 '^$' @@ -551,19 +551,19 @@ EOF #-------- len4 multiple ranges 2..3 | 20-29 new "cli length test len4 1 error" - expectfn "$clixon_cli -1f $cfg -l o set len4 a" 255 '^CLI syntax error: "set len4 a": String length 1 out of range: 2-3, 20-29$' + expectfn "$clixon_cli -1f $cfg -l o set len4 a" 255 '^CLI syntax error: "set len4 a": String length 1 out of range: 2 - 3, 20 - 29$' new "cli length test len4 2 ok" expectfn "$clixon_cli -1f $cfg -l o set len4 ab" 0 '^$' new "cli length test len4 10 error" - expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghij" 255 '^CLI syntax error: "set len4 abcdefghij": String length 10 out of range: 2-3, 20-29$' + expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghij" 255 '^CLI syntax error: "set len4 abcdefghij": String length 10 out of range: 2 - 3, 20 - 29$' new "cli length test len4 20 ok" expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghijabcdefghija" 0 '^$' new "cli length test len4 30 error" - expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghijabcdefghijabcdefghij" 255 '^CLI syntax error: "set len4 abcdefghijabcdefghijabcdefghij": String length 30 out of range: 2-3, 20-29$' + expectfn "$clixon_cli -1f $cfg -l o set len4 abcdefghijabcdefghijabcdefghij" 255 '^CLI syntax error: "set len4 abcdefghijabcdefghijabcdefghij": String length 30 out of range: 2 - 3, 20 - 29$' # XSD schema -> POSIX ECE translation new "cli yang pattern \d ok" From a2340c265c60e1f9b679705893c1bf113891c379 Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Mon, 1 Jul 2019 10:32:48 +0200 Subject: [PATCH 16/17] test scripts: replaced sleeps with wait functions --- test/mem.sh | 17 +++++++++++++++-- test/test_augment.sh | 2 +- test/test_choice.sh | 4 +++- test/test_cli_history.sh | 2 +- test/test_feature.sh | 2 +- test/test_leafref.sh | 2 +- test/test_minmax.sh | 2 +- test/test_nacm.sh | 4 ++-- test/test_nacm_default.sh | 2 -- test/test_nacm_module_read.sh | 4 ++-- test/test_nacm_module_write.sh | 4 ++-- test/test_nacm_protocol.sh | 4 ++-- test/test_order.sh | 2 +- test/test_restconf_startup.sh | 3 ++- test/test_rpc.sh | 4 +++- test/test_startup.sh | 2 +- test/test_transaction.sh | 3 ++- test/test_union.sh | 2 +- test/test_unique.sh | 2 +- test/test_upgrade.sh | 2 +- test/test_upgrade_auto.sh | 5 ++--- test/test_upgrade_interfaces.sh | 5 ++--- test/test_upgrade_repair.sh | 5 ++--- test/test_when_must.sh | 2 +- test/test_yang_load.sh | 16 ++++++++-------- test/test_yang_namespace.sh | 3 ++- 26 files changed, 60 insertions(+), 45 deletions(-) diff --git a/test/mem.sh b/test/mem.sh index d9c0e1dd..f40f52cd 100755 --- a/test/mem.sh +++ b/test/mem.sh @@ -86,7 +86,20 @@ done testnr=0 for c in $cmds; do if [ $testnr != 0 ]; then echo; fi - echo "Mem test for $c" - echo "=================" + echo "Mem test $c begin" + length=$(echo "Mem test $c begin" | wc -c) + let i=1 + while [ $i -lt $length ]; do + echo -n "=" + let i++ + done + echo memonce $c + echo "Mem test $c done" + let i=1 + while [ $i -lt $length ]; do + echo -n "=" + let i++ + done + echo done diff --git a/test/test_augment.sh b/test/test_augment.sh index a3a9d7ef..a5a61153 100755 --- a/test/test_augment.sh +++ b/test/test_augment.sh @@ -154,7 +154,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi # mandatory-leaf See RFC7950 Sec 7.17 diff --git a/test/test_choice.sh b/test/test_choice.sh index 145f0dac..2e352993 100755 --- a/test/test_choice.sh +++ b/test/test_choice.sh @@ -124,7 +124,9 @@ new "start restconf daemon" start_restconf -f $cfg new "waiting" -sleep $RCWAIT +wait_backend +wait_restconf + # First vanilla (protocol) case new "netconf validate empty" diff --git a/test/test_cli_history.sh b/test/test_cli_history.sh index f6c50382..034daf1d 100755 --- a/test/test_cli_history.sh +++ b/test/test_cli_history.sh @@ -48,7 +48,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "cli read and add entry to existing history" diff --git a/test/test_feature.sh b/test/test_feature.sh index 6db7c439..72ad5c71 100755 --- a/test/test_feature.sh +++ b/test/test_feature.sh @@ -85,7 +85,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "cli enabled feature" diff --git a/test/test_leafref.sh b/test/test_leafref.sh index 1c8f7eae..8179766f 100755 --- a/test/test_leafref.sh +++ b/test/test_leafref.sh @@ -87,7 +87,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "leafref base config" diff --git a/test/test_minmax.sh b/test/test_minmax.sh index 5c7faf5d..fd6da008 100755 --- a/test/test_minmax.sh +++ b/test/test_minmax.sh @@ -115,7 +115,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "minmax: minimal" diff --git a/test/test_nacm.sh b/test/test_nacm.sh index b7b914ae..042b6d75 100755 --- a/test/test_nacm.sh +++ b/test/test_nacm.sh @@ -124,12 +124,12 @@ fi new "kill old restconf daemon" sudo pkill -u www-data -f "/www-data/clixon_restconf" -sleep 1 new "start restconf daemon (-a is enable basic authentication)" start_restconf -f $cfg -- -a new "waiting" -sleep $RCWAIT +wait_backend +wait_restconf new "auth get" expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 'null diff --git a/test/test_nacm_default.sh b/test/test_nacm_default.sh index 6645ef11..7bceadbf 100755 --- a/test/test_nacm_default.sh +++ b/test/test_nacm_default.sh @@ -101,14 +101,12 @@ EOF new "kill old restconf daemon" sudo pkill -u www-data -f "/www-data/clixon_restconf" - sleep 1 new "start restconf daemon (-a is enable basic authentication)" start_restconf -f $cfg -- -a new "waiting" wait_backend wait_restconf - #----------- First get case "$ret1" in diff --git a/test/test_nacm_module_read.sh b/test/test_nacm_module_read.sh index 16755175..365d6dcf 100755 --- a/test/test_nacm_module_read.sh +++ b/test/test_nacm_module_read.sh @@ -139,12 +139,12 @@ fi new "kill old restconf daemon" sudo pkill -u www-data -f "/www-data/clixon_restconf" -sleep 1 new "start restconf daemon (-a is enable basic authentication)" start_restconf -f $cfg -- -a new "waiting" -sleep $RCWAIT +wait_backend +wait_restconf new "auth set authentication config" expecteof "$clixon_netconf -qf $cfg" 0 "$RULES]]>]]>" "^]]>]]>$" diff --git a/test/test_nacm_module_write.sh b/test/test_nacm_module_write.sh index d1bbe6d0..a88951e8 100755 --- a/test/test_nacm_module_write.sh +++ b/test/test_nacm_module_write.sh @@ -148,12 +148,12 @@ fi new "kill old restconf daemon" sudo pkill -u www-data -f "/www-data/clixon_restconf" -sleep 1 new "start restconf daemon (-a is enable basic authentication)" start_restconf -f $cfg -- -a new "waiting" -sleep $RCWAIT +wait_backend +wait_restconf # Set nacm from scratch nacm(){ diff --git a/test/test_nacm_protocol.sh b/test/test_nacm_protocol.sh index c9092ac9..4aa851cd 100755 --- a/test/test_nacm_protocol.sh +++ b/test/test_nacm_protocol.sh @@ -148,12 +148,12 @@ fi new "kill old restconf daemon" sudo pkill -u www-data -f "/www-data/clixon_restconf" -sleep 1 new "start restconf daemon (-a is enable basic authentication)" start_restconf -f $cfg -- -a new "waiting" -sleep $RCWAIT +wait_backend +wait_restconf new "auth set authentication config" expecteof "$clixon_netconf -qf $cfg" 0 "$RULES]]>]]>" "^]]>]]>$" diff --git a/test/test_order.sh b/test/test_order.sh index 20393f18..79a93f62 100755 --- a/test/test_order.sh +++ b/test/test_order.sh @@ -162,7 +162,7 @@ if [ $BE -ne 0 ]; then start_backend -s running -f $cfg -- -s new "waiting" - sleep $RCWAIT + wait_backend fi # STATE (should not be ordered) diff --git a/test/test_restconf_startup.sh b/test/test_restconf_startup.sh index 36037af8..2513c7a8 100755 --- a/test/test_restconf_startup.sh +++ b/test/test_restconf_startup.sh @@ -68,7 +68,8 @@ testrun(){ start_restconf -f $cfg -y $fyang $option new "waiting" - sleep $RCWAIT + wait_backend + wait_restconf new "restconf put 42" expecteq "$(curl -s -X PUT http://localhost/restconf/data/example:x/y=42 -d '{"example:y":{"a":"42","b":"42"}}')" 0 "" diff --git a/test/test_rpc.sh b/test/test_rpc.sh index 64ed55c3..8190608a 100755 --- a/test/test_rpc.sh +++ b/test/test_rpc.sh @@ -50,7 +50,9 @@ new "start restconf daemon" start_restconf -f $cfg new "waiting" -sleep $RCWAIT +wait_backend +wait_restconf + new "rpc tests" diff --git a/test/test_startup.sh b/test/test_startup.sh index 691c7df7..afb35ed8 100755 --- a/test/test_startup.sh +++ b/test/test_startup.sh @@ -86,7 +86,7 @@ testrun(){ start_backend -s $mode -f $cfg -c $dir/extra_db new "waiting" - sleep $RCWAIT + wait_backend else new "Restart backend as eg follows: -Ff $cfg -s $mode -c $dir/extra_db # $BETIMEOUT s" sleep $BETIMEOUT diff --git a/test/test_transaction.sh b/test/test_transaction.sh index 4055cc7d..fefe6122 100755 --- a/test/test_transaction.sh +++ b/test/test_transaction.sh @@ -121,8 +121,9 @@ if [ $BE -ne 0 ]; then fi new "start backend -s init -f $cfg -l f$flog -- -t /x/y[a=$errnr]" start_backend -s init -f $cfg -l f$flog -- -t /x/y[a=$errnr] # -t means transaction logging + new "waiting" - sleep $RCWAIT + wait_backend fi let nr=0 diff --git a/test/test_union.sh b/test/test_union.sh index b6862ff3..7931ede3 100755 --- a/test/test_union.sh +++ b/test/test_union.sh @@ -89,7 +89,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "cli set transitive string" diff --git a/test/test_unique.sh b/test/test_unique.sh index 799a51bb..a921ff53 100755 --- a/test/test_unique.sh +++ b/test/test_unique.sh @@ -92,7 +92,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi # RFC test two-field caes diff --git a/test/test_upgrade.sh b/test/test_upgrade.sh index 03b59f7b..a3885f28 100755 --- a/test/test_upgrade.sh +++ b/test/test_upgrade.sh @@ -265,7 +265,7 @@ runtest(){ start_backend -s $mode -f $cfg -o "CLICON_XMLDB_MODSTATE=$modstate" new "waiting" - sleep $RCWAIT + wait_backend else new "Restart backend as eg follows: -Ff $cfg -s $mode -o \"CLICON_XMLDB_MODSTATE=$modstate\" ($BETIMEOUT s)" sleep $BETIMEOUT diff --git a/test/test_upgrade_auto.sh b/test/test_upgrade_auto.sh index 7991864c..11c8fd52 100755 --- a/test/test_upgrade_auto.sh +++ b/test/test_upgrade_auto.sh @@ -254,8 +254,6 @@ if [ $BE -ne 0 ]; then new "start backend -s $mode -f $cfg" start_backend -s $mode -f $cfg fi -new "waiting" -sleep $RCWAIT new "kill old restconf daemon" sudo pkill -u www-data clixon_restconf @@ -264,7 +262,8 @@ new "start restconf daemon" start_restconf -f $cfg new "waiting" -sleep $RCWAIT +wait_backend +wait_restconf new "Check running db content" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^$XML]]>]]>$" diff --git a/test/test_upgrade_interfaces.sh b/test/test_upgrade_interfaces.sh index c72e7b2c..5bba6688 100755 --- a/test/test_upgrade_interfaces.sh +++ b/test/test_upgrade_interfaces.sh @@ -265,8 +265,6 @@ testrun(){ new "start backend -s startup -f $cfg -- -u" start_backend -s startup -f $cfg -- -u fi - new "waiting" - sleep $RCWAIT new "kill old restconf daemon" sudo pkill -u www-data clixon_restconf @@ -275,7 +273,8 @@ testrun(){ start_restconf -f $cfg new "waiting" - sleep $RCWAIT + wait_backend + wait_restconf new "Check running db content" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^$runxml]]>]]>$" diff --git a/test/test_upgrade_repair.sh b/test/test_upgrade_repair.sh index e752d1d5..a9c9bb80 100755 --- a/test/test_upgrade_repair.sh +++ b/test/test_upgrade_repair.sh @@ -112,8 +112,6 @@ if [ $BE -ne 0 ]; then new "start backend -s $mode -f $cfg" start_backend -s $mode -f $cfg fi -new "waiting" -sleep $RCWAIT new "kill old restconf daemon" sudo pkill -u www-data clixon_restconf @@ -122,7 +120,8 @@ new "start restconf daemon" start_restconf -f $cfg new "waiting" -sleep $RCWAIT +wait_backend +wait_restconf new "Check running db content is failsafe" expecteof "$clixon_netconf -qf $cfg" 0 ']]>]]>' "^$SAMEXML]]>]]>$" diff --git a/test/test_when_must.sh b/test/test_when_must.sh index a57c4fe4..2fc4dcf7 100755 --- a/test/test_when_must.sh +++ b/test/test_when_must.sh @@ -102,7 +102,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "when: add static route" diff --git a/test/test_yang_load.sh b/test/test_yang_load.sh index 19c826d5..df5e7195 100755 --- a/test/test_yang_load.sh +++ b/test/test_yang_load.sh @@ -85,7 +85,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "1. Set newex" @@ -134,7 +134,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "Set oldex" @@ -178,7 +178,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "Set newex" @@ -222,7 +222,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "Set oldex" @@ -266,7 +266,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "Set newex" @@ -312,7 +312,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "Set oldex" expecteof "$clixon_netconf -qf $cfg" 0 'str]]>]]>' '^]]>]]>$' @@ -357,7 +357,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "Set oldex" @@ -403,7 +403,7 @@ if [ $BE -ne 0 ]; then start_backend -s init -f $cfg new "waiting" - sleep $RCWAIT + wait_backend fi new "Set oldex" diff --git a/test/test_yang_namespace.sh b/test/test_yang_namespace.sh index d5c925eb..113d0426 100755 --- a/test/test_yang_namespace.sh +++ b/test/test_yang_namespace.sh @@ -83,7 +83,8 @@ new "start restconf daemon" start_restconf -f $cfg new "waiting" -sleep $RCWAIT +wait_backend +wait_restconf new "netconf set x in example1" expecteof "$clixon_netconf -qf $cfg" 0 '42]]>]]>' '^]]>]]>$' From 41f7e44dec182fb8d81a2c27e5c25bb630b4584f Mon Sep 17 00:00:00 2001 From: Olof hagsand Date: Thu, 4 Jul 2019 20:21:07 +0200 Subject: [PATCH 17/17] Return 404 Not found error if restconf GET does not return requested instance --- CHANGELOG.md | 1 + apps/restconf/clixon_restconf.h | 2 +- apps/restconf/restconf_lib.c | 13 +++- apps/restconf/restconf_lib.h | 2 +- apps/restconf/restconf_main.c | 2 +- apps/restconf/restconf_methods.c | 106 +++++++++++++++------------ apps/restconf/restconf_stream.c | 4 +- lib/clixon/clixon_netconf_lib.h | 1 + lib/src/clixon_netconf_lib.c | 57 +++++++++++++++ test/test_nacm.sh | 3 +- test/test_nacm_default.sh | 6 +- test/test_nacm_module_read.sh | 3 +- test/test_nacm_protocol.sh | 5 +- test/test_restconf2.sh | 4 +- test/test_restconf_err.sh | 120 +++++++++++++++++++++++++++++++ 15 files changed, 262 insertions(+), 67 deletions(-) create mode 100755 test/test_restconf_err.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index eb2fe361..a20c959b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -251,6 +251,7 @@ ### Corrected Bugs +* Return 404 Not found error if restconf GET does not return requested instance * Fixed [Wrong yang-generated cli code for typeref identityref combination #88](https://github.com/clicon/clixon/issues/88) * Fixed [identityref validation fails when using typedef #87](https://github.com/clicon/clixon/issues/87) * Fixed a problem with some netconf error messages caused restconf daemon to exit due to no XML encoding diff --git a/apps/restconf/clixon_restconf.h b/apps/restconf/clixon_restconf.h index 4c93c104..06c6ed86 100644 --- a/apps/restconf/clixon_restconf.h +++ b/apps/restconf/clixon_restconf.h @@ -55,7 +55,7 @@ int test(FCGX_Request *r, int dbg); cbuf *readdata(FCGX_Request *r); int get_user_cookie(char *cookiestr, char *attribute, char **val); int api_return_err(clicon_handle h, FCGX_Request *r, cxobj *xerr, - int pretty, int use_xml); + int pretty, int use_xml, int code); #endif /* _CLIXON_RESTCONF_H_ */ diff --git a/apps/restconf/restconf_lib.c b/apps/restconf/restconf_lib.c index 8bcb7c38..e7613f87 100644 --- a/apps/restconf/restconf_lib.c +++ b/apps/restconf/restconf_lib.c @@ -394,13 +394,16 @@ get_user_cookie(char *cookiestr, * @param[in] xerr XML error message from backend * @param[in] pretty Set to 1 for pretty-printed xml/json output * @param[in] use_xml Set to 0 for JSON and 1 for XML + * @param[in] code If 0 use rfc8040 sec 7 netconf2restconf error-tag mapping + * otherwise use this code */ int api_return_err(clicon_handle h, FCGX_Request *r, cxobj *xerr, int pretty, - int use_xml) + int use_xml, + int code0) { int retval = -1; cbuf *cb = NULL; @@ -417,8 +420,12 @@ api_return_err(clicon_handle h, goto ok; } tagstr = xml_body(xtag); - if ((code = restconf_err2code(tagstr)) < 0) - code = 500; /* internal server error */ + if (code0 != 0) + code = code0; + else{ + if ((code = restconf_err2code(tagstr)) < 0) + code = 500; /* internal server error */ + } if ((reason_phrase = restconf_code2reason(code)) == NULL) reason_phrase=""; if (xml_name_set(xerr, "error") < 0) diff --git a/apps/restconf/restconf_lib.h b/apps/restconf/restconf_lib.h index 57839bc8..1b90ef30 100644 --- a/apps/restconf/restconf_lib.h +++ b/apps/restconf/restconf_lib.h @@ -60,7 +60,7 @@ int test(FCGX_Request *r, int dbg); cbuf *readdata(FCGX_Request *r); int get_user_cookie(char *cookiestr, char *attribute, char **val); int api_return_err(clicon_handle h, FCGX_Request *r, cxobj *xerr, - int pretty, int use_xml); + int pretty, int use_xml, int code); int restconf_terminate(clicon_handle h); #endif /* _RESTCONF_LIB_H_ */ diff --git a/apps/restconf/restconf_main.c b/apps/restconf/restconf_main.c index 92822e80..cc6dabef 100644 --- a/apps/restconf/restconf_main.c +++ b/apps/restconf/restconf_main.c @@ -397,7 +397,7 @@ api_restconf(clicon_handle h, if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0) goto done; if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ - if (api_return_err(h, r, xerr, pretty, use_xml) < 0) + if (api_return_err(h, r, xerr, pretty, use_xml, 0) < 0) goto done; goto ok; } diff --git a/apps/restconf/restconf_methods.c b/apps/restconf/restconf_methods.c index 79571982..9a288f5b 100644 --- a/apps/restconf/restconf_methods.c +++ b/apps/restconf/restconf_methods.c @@ -214,7 +214,7 @@ api_data_get2(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -227,7 +227,7 @@ api_data_get2(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -246,7 +246,7 @@ api_data_get2(clicon_handle h, #endif /* Check if error return */ if ((xe = xpath_first(xret, "//rpc-error")) != NULL){ - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -277,7 +277,20 @@ api_data_get2(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) + goto done; + goto ok; + } + /* Check if not exists */ + if (xlen == 0){ + /* 4.3: If a retrieval request for a data resource represents an + instance that does not exist, then an error response containing + a "404 Not Found" status-line MUST be returned by the server. + The error-tag value "invalid-value" is used in this case. */ + if (netconf_invalid_value_xml(&xe, "application", "Instance does not exist") < 0) + goto done; + /* override invalid-value default 400 with 404 */ + if (api_return_err(h, r, xe, pretty, use_xml, 404) < 0) goto done; goto ok; } @@ -487,7 +500,7 @@ api_data_post(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -501,7 +514,7 @@ api_data_post(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -514,7 +527,7 @@ api_data_post(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -523,7 +536,7 @@ api_data_post(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -538,7 +551,7 @@ api_data_post(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -560,14 +573,15 @@ api_data_post(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (debug){ - cbuf *ccc=cbuf_new(); - if (clicon_xml2cbuf(ccc, xe, 0, 0) < 0) - goto done; - clicon_debug(1, "%s XE:%s", __FUNCTION__, cbuf_get(ccc)); - } - - if (api_return_err(h, r, xe, pretty, use_xml) < 0) +#if 0 + if (debug){ + cbuf *ccc=cbuf_new(); + if (clicon_xml2cbuf(ccc, xe, 0, 0) < 0) + goto done; + clicon_debug(1, "%s XE:%s", __FUNCTION__, cbuf_get(ccc)); + } +#endif + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -599,7 +613,7 @@ api_data_post(clicon_handle h, if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0) goto done; if ((xe = xpath_first(xret, "//rpc-error")) != NULL){ - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -621,7 +635,7 @@ api_data_post(clicon_handle h, /* log errors from discard, but ignore */ if ((xpath_first(xretdis, "//rpc-error")) != NULL) clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__); - if (api_return_err(h, r, xe, pretty, use_xml) < 0) /* Use original xe */ + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) /* Use original xe */ goto done; goto ok; } @@ -835,7 +849,7 @@ api_data_put(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -850,7 +864,7 @@ api_data_put(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -863,7 +877,7 @@ api_data_put(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -872,7 +886,7 @@ api_data_put(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -887,7 +901,7 @@ api_data_put(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -907,7 +921,7 @@ api_data_put(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -947,7 +961,7 @@ api_data_put(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -972,7 +986,7 @@ api_data_put(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -996,7 +1010,7 @@ api_data_put(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1033,7 +1047,7 @@ api_data_put(clicon_handle h, goto done; if ((xe = xpath_first(xret, "//rpc-error")) != NULL){ - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1054,7 +1068,7 @@ api_data_put(clicon_handle h, /* log errors from discard, but ignore */ if ((xpath_first(xretdis, "//rpc-error")) != NULL) clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__); - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1187,7 +1201,7 @@ api_data_delete(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1211,7 +1225,7 @@ api_data_delete(clicon_handle h, if (clicon_rpc_netconf(h, cbuf_get(cbx), &xret, NULL) < 0) goto done; if ((xe = xpath_first(xret, "//rpc-error")) != NULL){ - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1233,7 +1247,7 @@ api_data_delete(clicon_handle h, /* log errors from discard, but ignore */ if ((xpath_first(xretdis, "//rpc-error")) != NULL) clicon_log(LOG_WARNING, "%s: discard-changes failed which may lead candidate in an inconsistent state", __FUNCTION__); - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1425,7 +1439,7 @@ api_operations_post_input(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto fail; } @@ -1438,7 +1452,7 @@ api_operations_post_input(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto fail; } @@ -1447,7 +1461,7 @@ api_operations_post_input(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto fail; } @@ -1480,7 +1494,7 @@ api_operations_post_input(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto fail; } @@ -1554,7 +1568,7 @@ api_operations_post_output(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto fail; } @@ -1591,7 +1605,7 @@ api_operations_post_output(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto fail; } @@ -1724,7 +1738,7 @@ api_operations_post(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1743,7 +1757,7 @@ api_operations_post(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1754,7 +1768,7 @@ api_operations_post(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1783,7 +1797,7 @@ api_operations_post(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto done; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1823,7 +1837,7 @@ api_operations_post(clicon_handle h, clicon_err(OE_XML, EINVAL, "rpc-error not found (internal error)"); goto ok; } - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1852,7 +1866,7 @@ api_operations_post(clicon_handle h, goto done; /* Local error: return it and quit */ if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){ - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -1861,7 +1875,7 @@ api_operations_post(clicon_handle h, if (clicon_rpc_netconf_xml(h, xtop, &xret, NULL) < 0) goto done; if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){ - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } diff --git a/apps/restconf/restconf_stream.c b/apps/restconf/restconf_stream.c index 3d34c798..5c633347 100644 --- a/apps/restconf/restconf_stream.c +++ b/apps/restconf/restconf_stream.c @@ -269,7 +269,7 @@ restconf_stream(clicon_handle h, if (clicon_rpc_netconf(h, cbuf_get(cb), &xret, &s) < 0) goto done; if ((xe = xpath_first(xret, "rpc-reply/rpc-error")) != NULL){ - if (api_return_err(h, r, xe, pretty, use_xml) < 0) + if (api_return_err(h, r, xe, pretty, use_xml, 0) < 0) goto done; goto ok; } @@ -417,7 +417,7 @@ api_stream(clicon_handle h, if (netconf_access_denied_xml(&xret, "protocol", "The requested URL was unauthorized") < 0) goto done; if ((xerr = xpath_first(xret, "//rpc-error")) != NULL){ - if (api_return_err(h, r, xerr, pretty, use_xml) < 0) + if (api_return_err(h, r, xerr, pretty, use_xml, 0) < 0) goto done; goto ok; } diff --git a/lib/clixon/clixon_netconf_lib.h b/lib/clixon/clixon_netconf_lib.h index f3651da5..83fc2117 100644 --- a/lib/clixon/clixon_netconf_lib.h +++ b/lib/clixon/clixon_netconf_lib.h @@ -43,6 +43,7 @@ */ int netconf_in_use(cbuf *cb, char *type, char *message); int netconf_invalid_value(cbuf *cb, char *type, char *message); +int netconf_invalid_value_xml(cxobj **xret, char *type, char *message); int netconf_too_big(cbuf *cb, char *type, char *message); int netconf_missing_attribute(cbuf *cb, char *type, char *info, char *message); int netconf_bad_attribute(cbuf *cb, char *type, char *info, char *message); diff --git a/lib/src/clixon_netconf_lib.c b/lib/src/clixon_netconf_lib.c index bf59a9bb..56bceacd 100644 --- a/lib/src/clixon_netconf_lib.c +++ b/lib/src/clixon_netconf_lib.c @@ -108,6 +108,48 @@ netconf_in_use(cbuf *cb, goto done; } +/*! Create Netconf invalid-value error XML tree according to RFC 6241 Appendix A + * + * The request specifies an unacceptable value for one or more parameters. + * @param[out] xret Error XML tree. Free with xml_free after use + * @param[in] type Error type: "application" or "protocol" + * @param[in] message Error message (will be XML encoded) + */ +int +netconf_invalid_value_xml(cxobj **xret, + char *type, + char *message) +{ + int retval =-1; + cxobj *xerr; + char *encstr = NULL; + + if (*xret == NULL){ + if ((*xret = xml_new("rpc-reply", NULL, NULL)) == NULL) + goto done; + } + else if (xml_name_set(*xret, "rpc-reply") < 0) + goto done; + if ((xerr = xml_new("rpc-error", *xret, NULL)) == NULL) + goto done; + if (xml_parse_va(&xerr, NULL, "%s" + "invalid-value" + "error", type) < 0) + goto done; + if (message){ + if (xml_chardata_encode(&encstr, "%s", message) < 0) + goto done; + if (xml_parse_va(&xerr, NULL, "%s", + encstr) < 0) + goto done; + } + retval = 0; + done: + if (encstr) + free(encstr); + return retval; +} + /*! Create Netconf invalid-value error XML tree according to RFC 6241 Appendix A * * The request specifies an unacceptable value for one or more parameters. @@ -120,6 +162,20 @@ netconf_invalid_value(cbuf *cb, char *type, char *message) { +#if 1 + int retval = -1; + cxobj *xret = NULL; + + if (netconf_invalid_value_xml(&xret, type, message) < 0) + goto done; + if (clicon_xml2cbuf(cb, xret, 0, 0) < 0) + goto done; + retval = 0; + done: + if (xret) + xml_free(xret); + return retval; +#else int retval = -1; char *encstr = NULL; @@ -145,6 +201,7 @@ netconf_invalid_value(cbuf *cb, err: clicon_err(OE_XML, errno, "cprintf"); goto done; +#endif } /*! Create Netconf too-big error XML tree according to RFC 6241 Appendix A diff --git a/test/test_nacm.sh b/test/test_nacm.sh index 042b6d75..c50308ab 100755 --- a/test/test_nacm.sh +++ b/test/test_nacm.sh @@ -132,8 +132,7 @@ wait_backend wait_restconf new "auth get" -expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 'null - ' +expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}} ' # explicitly disable nacm (regression on netgate bug) new "disable nacm" diff --git a/test/test_nacm_default.sh b/test/test_nacm_default.sh index 7bceadbf..224c8b78 100755 --- a/test/test_nacm_default.sh +++ b/test/test_nacm_default.sh @@ -115,8 +115,7 @@ EOF ;; 1) ret='{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "default deny"}}} ' ;; - 2) ret='null - ' + 2) ret='{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}} ' ;; esac @@ -140,8 +139,7 @@ EOF ;; 1) ret='{"ietf-restconf:errors" : {"error": {"error-type": "application","error-tag": "access-denied","error-severity": "error","error-message": "default deny"}}} ' ;; - 2) ret='null - ' + 2) ret='{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}} ' ;; 3) ret='{"nacm-example:x": 42} ' diff --git a/test/test_nacm_module_read.sh b/test/test_nacm_module_read.sh index 365d6dcf..6b64ab90 100755 --- a/test/test_nacm_module_read.sh +++ b/test/test_nacm_module_read.sh @@ -200,8 +200,7 @@ expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/clixon-e ' new "limit read other module fail" -expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 'null - ' +expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}} ' new "limit read state OK" expecteq "$(curl -u wilma:bar -sS -X GET http://localhost/restconf/data/clixon-example:state)" 0 '{"clixon-example:state": {"op": ["42","41","43"]}} diff --git a/test/test_nacm_protocol.sh b/test/test_nacm_protocol.sh index 4aa851cd..59ce33c7 100755 --- a/test/test_nacm_protocol.sh +++ b/test/test_nacm_protocol.sh @@ -191,9 +191,8 @@ expecteq "$(curl -u guest:bar -sS -X DELETE http://localhost/restconf/data)" 0 ' new "deny-delete-config: limited fail (restconf) ok" expecteq "$(curl -u wilma:bar -sS -X DELETE http://localhost/restconf/data)" 0 '' -new "admin get nacm (should be null)" -expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 'null - ' +new "admin get nacm (should fail)" +expecteq "$(curl -u andy:bar -sS -X GET http://localhost/restconf/data/nacm-example:x)" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}} ' new "deny-delete-config: admin ok (restconf)" expecteq "$(curl -u andy:bar -sS -X DELETE http://localhost/restconf/data)" 0 '' diff --git a/test/test_restconf2.sh b/test/test_restconf2.sh index 84aba720..ec1486d7 100755 --- a/test/test_restconf2.sh +++ b/test/test_restconf2.sh @@ -137,7 +137,7 @@ new "restconf DELETE" expectfn 'curl -s -X DELETE http://localhost/restconf/data/example:cont1' 0 "" new "restconf GET null datastore" -expectfn "curl -s -X GET http://localhost/restconf/data/example:cont1" 0 'null' +expectfn "curl -s -X GET http://localhost/restconf/data/example:cont1" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}}' new "restconf POST initial tree" expectfn 'curl -s -X POST -d {"example:cont1":{"interface":{"name":"local0","type":"regular"}}} http://localhost/restconf/data' 0 "" @@ -149,7 +149,7 @@ new "restconf DELETE whole datastore" expectfn 'curl -s -X DELETE http://localhost/restconf/data' 0 "" new "restconf GET null datastore" -expectfn "curl -s -X GET http://localhost/restconf/data/example:cont1" 0 'null' +expectfn "curl -s -X GET http://localhost/restconf/data/example:cont1" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}}' new "restconf PUT initial datastore" expectfn 'curl -s -X PUT -d {"data":{"example:cont1":{"interface":{"name":"local0","type":"regular"}}}} http://localhost/restconf/data' 0 "" diff --git a/test/test_restconf_err.sh b/test/test_restconf_err.sh new file mode 100755 index 00000000..fb5e27da --- /dev/null +++ b/test/test_restconf_err.sh @@ -0,0 +1,120 @@ +#!/bin/bash +# Restconf error-code functionality +# See RFC8040 +# Testcases: +# Sec 4.3 (GET): If a retrieval request for a data resource represents an +# instance that does not exist, then an error response containing a "404 Not +# Found" status-line MUST be returned by the server. The error-tag +# value "invalid-value" is used in this case. + +# Magic line must be first in script (see README.md) +s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi + +APPNAME=example + +cfg=$dir/conf.xml +fyang=$dir/restconf.yang +fxml=$dir/initial.xml + +# example +cat < $cfg + + $cfg + /usr/local/share/clixon + $IETFRFC + $fyang + false + /usr/local/var/$APPNAME/$APPNAME.sock + $dir/restconf.pidfile + /usr/local/var/$APPNAME + +EOF + +cat < $fyang +module example{ + yang-version 1.1; + namespace "urn:example:clixon"; + prefix ex; + list a { + key k; + leaf k { + type int32; + } + leaf description{ + type string; + } + leaf b{ + type string; + } + container c{ + presence "for test"; + } + list d{ + key k; + leaf k { + type string; + } + } + } +} +EOF + +# Initial tree +XML=$(cat <0No leaf b, No container c, No leaf d +EOF + ) + +new "test params: -f $cfg" + +if [ $BE -ne 0 ]; then + new "kill old backend" + sudo clixon_backend -zf $cfg + if [ $? -ne 0 ]; then + err + fi + sudo pkill clixon_backend # to be sure + new "start backend -s init -f $cfg" + start_backend -s init -f $cfg +fi + +new "kill old restconf daemon" +sudo pkill -u www-data -f "/www-data/clixon_restconf" + +new "start restconf daemon" +start_restconf -f $cfg + +new "waiting" +wait_backend +wait_restconf + +new "restconf POST initial tree" +expecteq "$(curl -s -X POST -H 'Content-Type: application/yang-data+xml' -d "$XML" http://localhost/restconf/data)" 0 '' + +new "restconf GET initial datastore" +expecteq "$(curl -s -X GET -H 'Accept: application/yang-data+xml' http://localhost/restconf/data/example:a)" 0 "$XML + " + +new "restconf GET non-existent container header" +expectfn "curl -s -I -X GET http://localhost/restconf/data/example:a/c" 0 "HTTP/1.1 404 Not Found" + +new "restconf GET non-existent container body" +expectfn "curl -s -X GET http://localhost/restconf/data/example:a/c" 0 '{"ietf-restconf:errors" : {"error": {"rpc-error": {"error-type": "application","error-tag": "invalid-value","error-severity": "error","error-message": "Instance does not exist"}}}}' + +new "Kill restconf daemon" +stop_restconf + +if [ $BE -eq 0 ]; then + exit # BE +fi + +new "Kill backend" +# Check if premature kill +pid=`pgrep -u root -f clixon_backend` +if [ -z "$pid" ]; then + err "backend already dead" +fi +# kill backend +stop_backend -f $cfg + +rm -rf $dir