Completed: Yang deviation [deviation statement not yet support #211](https://github.com/clicon/clixon/issues/211)

This commit is contained in:
Olof hagsand 2021-05-04 11:38:39 +02:00
parent 5a72626aa4
commit af04ec9e9d
5 changed files with 201 additions and 86 deletions

View file

@ -34,10 +34,8 @@ Expected: June 2021
### New features ### New features
* Yang Deviation/deviate [deviation statement not yet support #211](https://github.com/clicon/clixon/issues/211) * Yang deviation [deviation statement not yet support #211](https://github.com/clicon/clixon/issues/211)
* See RFC7950 Sec 5.6.3 * See RFC7950 Sec 5.6.3
* Implemented: "not-supported" and "add"
* Not yet: "replace" and "delete"
### Minor features ### Minor features

View file

@ -770,11 +770,21 @@ send_msg_notify_xml(clicon_handle h,
} }
/*! Look for a text pattern in an input string, one char at a time /*! Look for a text pattern in an input string, one char at a time
* @param[in] tag What to look for * @param[in] tag What to look for
* @param[in] ch New input character * @param[in] ch New input character
* @param[in,out] state A state integer holding how far we have parsed. * @param[in,out] state A state integer holding how far we have parsed.
* @retval 0 No, we havent detected end tag * @retval 0 No, we havent detected end tag
* @retval 1 Yes, we have detected end tag! * @retval 1 Yes, we have detected end tag!
* @code
* int state = 0;
* char ch;
* while (1) {
* // read ch
* if (detect_endtag("mypattern", ch, &state)) {
* // mypattern is matched
* }
* }
* @endcode
*/ */
int int
detect_endtag(char *tag, detect_endtag(char *tag,

View file

@ -517,7 +517,8 @@ ys_prune(yang_stmt *yp,
* @param[in] ys Yang node to remove * @param[in] ys Yang node to remove
* @retval 0 OK * @retval 0 OK
* @retval -1 Error * @retval -1 Error
* @see ys_prune if parent and position is known * @see ys_prune if parent and position is know
* @see ys_free Deallocate yang node
* @note Do not call this in a loop of yang children (unless you know what you are doing) * @note Do not call this in a loop of yang children (unless you know what you are doing)
*/ */
static int static int
@ -1608,6 +1609,7 @@ yang_deviation(yang_stmt *ys,
yang_stmt *yd; yang_stmt *yd;
yang_stmt *yc; yang_stmt *yc;
yang_stmt *yc1; yang_stmt *yc1;
yang_stmt *ytc;
char *devop; char *devop;
clicon_handle h = (clicon_handle)arg; clicon_handle h = (clicon_handle)arg;
enum rfc_6020 kw; enum rfc_6020 kw;
@ -1648,8 +1650,7 @@ yang_deviation(yang_stmt *ys,
else if (strcmp(devop, "add") == 0){ else if (strcmp(devop, "add") == 0){
yc = NULL; yc = NULL;
while ((yc = yn_each(yd, yc)) != NULL) { while ((yc = yn_each(yd, yc)) != NULL) {
/* If a property can only appear once, the property MUST NOT /* If a property can only appear once, the property MUST NOT exist in the target node. */
exist in the target node. */
kw = yang_keyword_get(yc); kw = yang_keyword_get(yc);
if (yang_find(ytarget, kw, NULL) != NULL){ if (yang_find(ytarget, kw, NULL) != NULL){
if (yang_cardinality_interval(h, if (yang_cardinality_interval(h,
@ -1674,8 +1675,48 @@ yang_deviation(yang_stmt *ys,
} }
} }
else if (strcmp(devop, "replace") == 0){ else if (strcmp(devop, "replace") == 0){
yc = NULL;
while ((yc = yn_each(yd, yc)) != NULL) {
/* The properties to replace MUST exist in the target node.*/
kw = yang_keyword_get(yc);
if ((ytc = yang_find(ytarget, kw, NULL)) == NULL){
clicon_err(OE_YANG, 0, "deviation %s: \"%s %s\" replaced but node does not exist in target %s",
nodeid,
yang_key2str(kw), yang_argument_get(yc),
yang_argument_get(ytarget));
goto done;
}
/* Remove old */
if (ys_prune_self(ytc) < 0)
goto done;
if (ys_free(ytc) < 0)
goto done;
/* Make a copy of deviate child and insert. */
if ((yc1 = ys_dup(yc)) == NULL)
goto done;
if (yn_insert(ytarget, yc1) < 0)
goto done;
}
} }
else if (strcmp(devop, "delete") == 0){ else if (strcmp(devop, "delete") == 0){
yc = NULL;
while ((yc = yn_each(yd, yc)) != NULL) {
/* The substatement's keyword MUST match a corresponding keyword in the target node, and the
* argument's string MUST be equal to the corresponding keyword's argument string in the
* target node. */
kw = yang_keyword_get(yc);
if ((ytc = yang_find(ytarget, kw, NULL)) == NULL){
clicon_err(OE_YANG, 0, "deviation %s: \"%s %s\" replaced but node does not exist in target %s",
nodeid,
yang_key2str(kw), yang_argument_get(yc),
yang_argument_get(ytarget));
goto done;
}
if (ys_prune_self(ytc) < 0)
goto done;
if (ys_free(ytc) < 0)
goto done;
}
} }
else{ /* Shouldnt happen, lex/yacc takes it */ else{ /* Shouldnt happen, lex/yacc takes it */
clicon_err(OE_YANG, EINVAL, "%s: invalid deviate operator", devop); clicon_err(OE_YANG, EINVAL, "%s: invalid deviate operator", devop);

View file

@ -1508,12 +1508,6 @@ notification_substmt : if_feature_stmt { _PARSE_DEBUG("notification-substmt ->
| { _PARSE_DEBUG("notification-substmt -> "); } | { _PARSE_DEBUG("notification-substmt -> "); }
; ;
/* deviation /oc-sys:system/oc-sys:config/oc-sys:hostname {
deviate not-supported;
}
* XXX abs-schema-nodeid-str is too difficult, it needs the + semantics
*/
deviation_stmt : K_DEVIATION string deviation_stmt : K_DEVIATION string
{ if (ysp_add_push(_yy, Y_DEVIATION, $2, NULL) == NULL) _YYERROR("deviation_stmt"); } { if (ysp_add_push(_yy, Y_DEVIATION, $2, NULL) == NULL) _YYERROR("deviation_stmt"); }
'{' deviation_substmts '}' '{' deviation_substmts '}'
@ -1569,13 +1563,13 @@ deviate_add_substmt : units_stmt { _PARSE_DEBUG("deviate-add-substmt -> units
deviate_delete_stmt : K_DEVIATE D_DELETE ';' deviate_delete_stmt : K_DEVIATE D_DELETE ';'
{ if (ysp_add(_yy, Y_DEVIATE, strdup("add") /* D_NOT_SUPPORTED*/, NULL) == NULL) _YYERROR("notification_stmt"); { if (ysp_add(_yy, Y_DEVIATE, strdup("delete"), NULL) == NULL) _YYERROR("notification_stmt");
_PARSE_DEBUG("deviate-delete-stmt -> DEVIATE add ;"); } _PARSE_DEBUG("deviate-delete-stmt -> DEVIATE delete ;"); }
| K_DEVIATE D_DELETE | K_DEVIATE D_DELETE
{ if (ysp_add_push(_yy, Y_DEVIATE, strdup("add"), NULL) == NULL) _YYERROR("deviate_stmt"); } { if (ysp_add_push(_yy, Y_DEVIATE, strdup("delete"), NULL) == NULL) _YYERROR("deviate_stmt"); }
'{' deviate_delete_substmts '}' '{' deviate_delete_substmts '}'
{ if (ystack_pop(_yy) < 0) _YYERROR("deviate_stmt"); { if (ystack_pop(_yy) < 0) _YYERROR("deviate_stmt");
_PARSE_DEBUG("deviate-delete-stmt -> DEVIATE add { deviate-substmts }"); } _PARSE_DEBUG("deviate-delete-stmt -> DEVIATE delete { deviate-delete-substmts }"); }
; ;
deviate_delete_substmts : deviate_delete_substmts deviate_delete_substmt deviate_delete_substmts : deviate_delete_substmts deviate_delete_substmt
@ -1590,15 +1584,14 @@ deviate_delete_substmt : units_stmt { _PARSE_DEBUG("deviate-delete-substmt -> un
| { _PARSE_DEBUG("deviate-delete-substmt -> "); } | { _PARSE_DEBUG("deviate-delete-substmt -> "); }
; ;
deviate_replace_stmt : K_DEVIATE D_REPLACE ';' deviate_replace_stmt : K_DEVIATE D_REPLACE ';'
{ if (ysp_add(_yy, Y_DEVIATE, strdup("add") /* D_NOT_SUPPORTED*/, NULL) == NULL) _YYERROR("notification_stmt"); { if (ysp_add(_yy, Y_DEVIATE, strdup("replace"), NULL) == NULL) _YYERROR("notification_stmt");
_PARSE_DEBUG("deviate-replace-stmt -> DEVIATE add ;"); } _PARSE_DEBUG("deviate-replace-stmt -> DEVIATE replace ;"); }
| K_DEVIATE D_REPLACE | K_DEVIATE D_REPLACE
{ if (ysp_add_push(_yy, Y_DEVIATE, strdup("add"), NULL) == NULL) _YYERROR("deviate_stmt"); } { if (ysp_add_push(_yy, Y_DEVIATE, strdup("replace"), NULL) == NULL) _YYERROR("deviate_stmt"); }
'{' deviate_replace_substmts '}' '{' deviate_replace_substmts '}'
{ if (ystack_pop(_yy) < 0) _YYERROR("deviate_stmt"); { if (ystack_pop(_yy) < 0) _YYERROR("deviate_stmt");
_PARSE_DEBUG("deviate-replace-stmt -> DEVIATE add { deviate-substmts }"); } _PARSE_DEBUG("deviate-replace-stmt -> DEVIATE replace { deviate-replace-substmts }"); }
; ;
deviate_replace_substmts : deviate_replace_substmts deviate_replace_substmt deviate_replace_substmts : deviate_replace_substmts deviate_replace_substmt
@ -1688,40 +1681,40 @@ yang_stmt : action_stmt { _PARSE_DEBUG("yang-stmt -> action-stmt");
| leaf_stmt { _PARSE_DEBUG("yang-stmt -> leaf-stmt");} | leaf_stmt { _PARSE_DEBUG("yang-stmt -> leaf-stmt");}
| length_stmt { _PARSE_DEBUG("yang-stmt -> length-stmt");} | length_stmt { _PARSE_DEBUG("yang-stmt -> length-stmt");}
| list_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | list_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| mandatory_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | mandatory_stmt { _PARSE_DEBUG("yang-stmt -> mandatory-stmt");}
| max_elements_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | max_elements_stmt { _PARSE_DEBUG("yang-stmt -> max-elements-stmt");}
| min_elements_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | min_elements_stmt { _PARSE_DEBUG("yang-stmt -> min-elements-stmt");}
| modifier_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | modifier_stmt { _PARSE_DEBUG("yang-stmt -> modifier-stmt");}
| module_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | module_stmt { _PARSE_DEBUG("yang-stmt -> module-stmt");}
| must_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | must_stmt { _PARSE_DEBUG("yang-stmt -> must-stmt");}
| namespace_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | namespace_stmt { _PARSE_DEBUG("yang-stmt -> namespace-stmt");}
| notification_stmt { _PARSE_DEBUG("yang-stmt -> notification-stmt");} | notification_stmt { _PARSE_DEBUG("yang-stmt -> notification-stmt");}
| ordered_by_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | ordered_by_stmt { _PARSE_DEBUG("yang-stmt -> ordered-by-stmt");}
| organization_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | organization_stmt { _PARSE_DEBUG("yang-stmt -> organization-stmt");}
| output_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | output_stmt { _PARSE_DEBUG("yang-stmt -> output-stmt");}
| path_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | path_stmt { _PARSE_DEBUG("yang-stmt -> path-stmt");}
| pattern_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | pattern_stmt { _PARSE_DEBUG("yang-stmt -> pattern-stmt");}
| position_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | position_stmt { _PARSE_DEBUG("yang-stmt -> position-stmt");}
| prefix_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | prefix_stmt { _PARSE_DEBUG("yang-stmt -> prefix-stmt");}
| presence_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | presence_stmt { _PARSE_DEBUG("yang-stmt -> presence-stmt");}
| range_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | range_stmt { _PARSE_DEBUG("yang-stmt -> range-stmt");}
| reference_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | reference_stmt { _PARSE_DEBUG("yang-stmt -> reference-stmt");}
| refine_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | refine_stmt { _PARSE_DEBUG("yang-stmt -> refine-stmt");}
| require_instance_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | require_instance_stmt { _PARSE_DEBUG("yang-stmt -> require-instance-stmt");}
| revision_date_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | revision_date_stmt { _PARSE_DEBUG("yang-stmt -> revision-date-stmt");}
| revision_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | revision_stmt { _PARSE_DEBUG("yang-stmt -> revision-stmt");}
| rpc_stmt { _PARSE_DEBUG("yang-stmt -> rpc-stmt");} | rpc_stmt { _PARSE_DEBUG("yang-stmt -> rpc-stmt");}
| status_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | status_stmt { _PARSE_DEBUG("yang-stmt -> status-stmt");}
| submodule_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | submodule_stmt { _PARSE_DEBUG("yang-stmt -> submodule-stmt");}
| typedef_stmt { _PARSE_DEBUG("yang-stmt -> typedef-stmt");} | typedef_stmt { _PARSE_DEBUG("yang-stmt -> typedef-stmt");}
| type_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | type_stmt { _PARSE_DEBUG("yang-stmt -> type-stmt");}
| unique_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | unique_stmt { _PARSE_DEBUG("yang-stmt -> unique-stmt");}
| units_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | units_stmt { _PARSE_DEBUG("yang-stmt -> units-stmt");}
| uses_augment_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | uses_augment_stmt { _PARSE_DEBUG("yang-stmt -> uses-augment-stmt");}
| uses_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | uses_stmt { _PARSE_DEBUG("yang-stmt -> uses-stmt");}
| value_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | value_stmt { _PARSE_DEBUG("yang-stmt -> value-stmt");}
| when_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | when_stmt { _PARSE_DEBUG("yang-stmt -> when-stmt");}
| yang_version_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} | yang_version_stmt { _PARSE_DEBUG("yang-stmt -> yang-version-stmt");}
/* | yin_element_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} */ /* | yin_element_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} */
; ;

View file

@ -35,11 +35,15 @@ module example-base{
prefix base; prefix base;
namespace "urn:example:base"; namespace "urn:example:base";
container system { container system {
must "daytime or time"; must "daytime or time"; /* deviate delete removes this */
leaf daytime{ /* not supported removes this */ leaf daytime{ /* deviate not-supported removes this */
type string;
}
leaf time{
type string; type string;
} }
list name-server { list name-server {
max-elements 1; /* deviate replace replaces to "max.elements 3" here */
key name; key name;
leaf name { leaf name {
type string; type string;
@ -52,7 +56,7 @@ module example-base{
} }
leaf type { leaf type {
type string; type string;
/* add rule adds default here */ /* deviate add adds "default admin" here */
} }
} }
} }
@ -60,13 +64,17 @@ module example-base{
EOF EOF
# Args: # Args:
# 0: daytime implemented: true/false # 1: daytime implemented: true/false
# 1: admin type default: true/false # 2: admin type default: true/false
# 3: mustdate default: true/false
# 4: maxelement of name-server is 1: true/false (if false the # is 3)
function testrun() function testrun()
{ {
daytime=$1 daytime=$1
admindefault=$2 admindefault=$2
mustdate=$3
maxel1=$4
new "test params: -f $cfg" new "test params: -f $cfg"
if [ "$BE" -ne 0 ]; then if [ "$BE" -ne 0 ]; then
@ -82,29 +90,55 @@ function testrun()
new "wait backend" new "wait backend"
wait_backend wait_backend
if ! $daytime; then # Not supported - dont continue new "Add user bob"
new "Add example-base daytime - should not be supported" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:base\"><user><name>bob</name></user></system></config></edit-config></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:base\"><daytime>Sept17</daytime></system></config></edit-config></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>daytime</bad-element></error-info><error-severity>error</error-severity><error-message>Failed to find YANG spec of XML node: daytime with parent: system in namespace: urn:example:base</error-message></rpc-error></rpc-reply>]]>]]"
if $mustdate; then # fail since there is neither date or daytime (delete rule)
new "netconf validate expect error"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>operation-failed</error-tag><error-severity>error</error-severity><error-message>must xpath validation failed</error-message></rpc-error></rpc-reply>]]>]]>$"
else else
new "netconf validate ok"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]"
fi
new "Add time"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:base\"><time>yes</time></system></config></edit-config></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]"
new "netconf validate ok"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]"
if $daytime; then # not-supported rule
new "Add example-base daytime - supported" new "Add example-base daytime - supported"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:base\"><daytime>Sept17</daytime></system></config></edit-config></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:base\"><daytime>Sept17</daytime></system></config></edit-config></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]"
else # Not supported
new "Add example-base daytime - expect error not supported"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:base\"><daytime>Sept17</daytime></system></config></edit-config></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>unknown-element</error-tag><error-info><bad-element>daytime</bad-element></error-info><error-severity>error</error-severity><error-message>Failed to find YANG spec of XML node: daytime with parent: system in namespace: urn:example:base</error-message></rpc-error></rpc-reply>]]>]]"
fi # daytime supported
new "Add user bob" new "netconf commit"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:base\"><user><name>bob</name></user></system></config></edit-config></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
new "netconf commit"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><commit/></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]>$"
if $admindefault; then if $admindefault; then # add rule
new "Get type admin expected" new "Get type admin expected"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/base:system/base:user[base:name='bob']\" xmlns:base=\"urn:example:base\"/></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><system xmlns=\"urn:example:base\"><user><name>bob</name><type>admin</type></user></system></data></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/base:system/base:user[base:name='bob']\" xmlns:base=\"urn:example:base\"/></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data><system xmlns=\"urn:example:base\"><user><name>bob</name><type>admin</type></user></system></data></rpc-reply>]]>]]>$"
# XXX Cannot select a default value?? # XXX Cannot select a default value??
# expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/base:system/base:user[base:name='bob']/base:type\" xmlns:base=\"urn:example:base\"/></get-config></rpc>]]>]]>" foo # expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/base:system/base:user[base:name='bob']/base:type\" xmlns:base=\"urn:example:base\"/></get-config></rpc>]]>]]>" foo
else else
new "Get type none expected" new "Get type none expected"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/base:system/base:user[base:name='bob']/base:type\" xmlns:base=\"urn:example:base\"/></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$" expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><get-config><source><running/></source><filter type=\"xpath\" select=\"/base:system/base:user[base:name='bob']/base:type\" xmlns:base=\"urn:example:base\"/></get-config></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><data/></rpc-reply>]]>]]>$"
fi
fi fi
# Add 2 name-servers
new "Add two name-servers"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><system xmlns=\"urn:example:base\"><name-server><name>aa</name></name-server><name-server><name>bb</name></name-server></system></config></edit-config></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]"
if $maxel1; then # add two and check if it fails
new "netconf validate 2 element fail"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>]]>]]>" "^<rpc-reply $DEFAULTNS><rpc-error><error-type>protocol</error-type><error-tag>operation-failed</error-tag><error-app-tag>too-many-elements</error-app-tag><error-severity>error</error-severity><error-path>/system/name-server</error-path></rpc-error></rpc-reply>]]>]]>$"
else
new "netconf validate 2 elements ok"
expecteof "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>]]>]]>" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>]]>]]"
fi
if [ "$BE" -ne 0 ]; then if [ "$BE" -ne 0 ]; then
new "Kill backend" new "Kill backend"
# Check if premature kill # Check if premature kill
@ -128,8 +162,8 @@ module example-deviations{
} }
} }
EOF EOF
new "daytime supported" new "1. daytime supported"
testrun true false testrun true false true true
# Example from RFC 7950 Sec 7.20.3.3 # Example from RFC 7950 Sec 7.20.3.3
cat <<EOF > $fyangdev cat <<EOF > $fyangdev
@ -145,10 +179,10 @@ module example-deviations{
} }
} }
EOF EOF
new "daytime not supported" new "2. daytime not supported"
testrun false false testrun false false true true
# Example from RFC 7950 Sec 7.20.3.3 # Add example from RFC 7950 Sec 7.20.3.3
cat <<EOF > $fyangdev cat <<EOF > $fyangdev
module example-deviations{ module example-deviations{
yang-version 1.1; yang-version 1.1;
@ -164,8 +198,47 @@ module example-deviations{
} }
} }
EOF EOF
new "deviate add, check admin default" new "3. deviate add, check admin default"
testrun true true testrun true true true true
# Delete example from RFC 7950 Sec 7.20.3.3
cat <<EOF > $fyangdev
module example-deviations{
yang-version 1.1;
prefix md;
namespace "urn:example:deviations";
import example-base {
prefix base;
}
deviation /base:system/base:name-server {
deviate replace {
max-elements 3;
}
}
}
EOF
new "4. deviate replace"
testrun true false true false
# Replace example from RFC 7950 Sec 7.20.3.3
cat <<EOF > $fyangdev
module example-deviations{
yang-version 1.1;
prefix md;
namespace "urn:example:deviations";
import example-base {
prefix base;
}
deviation /base:system {
deviate delete {
must "daytime or time";
}
}
}
EOF
new "5. deviate delete"
testrun true false false true
rm -rf "$dir" rm -rf "$dir"