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
* 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
* Implemented: "not-supported" and "add"
* Not yet: "replace" and "delete"
### 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
* @param[in] tag What to look for
* @param[in] ch New input character
* @param[in,out] state A state integer holding how far we have parsed.
* @retval 0 No, we havent detected end tag
* @retval 1 Yes, we have detected end tag!
* @param[in] tag What to look for
* @param[in] ch New input character
* @param[in,out] state A state integer holding how far we have parsed.
* @retval 0 No, we havent 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
detect_endtag(char *tag,

View file

@ -517,7 +517,8 @@ ys_prune(yang_stmt *yp,
* @param[in] ys Yang node to remove
* @retval 0 OK
* @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)
*/
static int
@ -1608,6 +1609,7 @@ yang_deviation(yang_stmt *ys,
yang_stmt *yd;
yang_stmt *yc;
yang_stmt *yc1;
yang_stmt *ytc;
char *devop;
clicon_handle h = (clicon_handle)arg;
enum rfc_6020 kw;
@ -1648,8 +1650,7 @@ yang_deviation(yang_stmt *ys,
else if (strcmp(devop, "add") == 0){
yc = NULL;
while ((yc = yn_each(yd, yc)) != NULL) {
/* If a property can only appear once, the property MUST NOT
exist in the target node. */
/* If a property can only appear once, the property MUST NOT exist in the target node. */
kw = yang_keyword_get(yc);
if (yang_find(ytarget, kw, NULL) != NULL){
if (yang_cardinality_interval(h,
@ -1674,8 +1675,48 @@ yang_deviation(yang_stmt *ys,
}
}
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){
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 */
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 -> "); }
;
/* 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
{ if (ysp_add_push(_yy, Y_DEVIATION, $2, NULL) == NULL) _YYERROR("deviation_stmt"); }
'{' deviation_substmts '}'
@ -1569,13 +1563,13 @@ deviate_add_substmt : units_stmt { _PARSE_DEBUG("deviate-add-substmt -> units
deviate_delete_stmt : K_DEVIATE D_DELETE ';'
{ if (ysp_add(_yy, Y_DEVIATE, strdup("add") /* D_NOT_SUPPORTED*/, NULL) == NULL) _YYERROR("notification_stmt");
_PARSE_DEBUG("deviate-delete-stmt -> DEVIATE add ;"); }
{ if (ysp_add(_yy, Y_DEVIATE, strdup("delete"), NULL) == NULL) _YYERROR("notification_stmt");
_PARSE_DEBUG("deviate-delete-stmt -> DEVIATE 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 '}'
{ 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
@ -1590,15 +1584,14 @@ deviate_delete_substmt : units_stmt { _PARSE_DEBUG("deviate-delete-substmt -> un
| { _PARSE_DEBUG("deviate-delete-substmt -> "); }
;
deviate_replace_stmt : K_DEVIATE D_REPLACE ';'
{ if (ysp_add(_yy, Y_DEVIATE, strdup("add") /* D_NOT_SUPPORTED*/, NULL) == NULL) _YYERROR("notification_stmt");
_PARSE_DEBUG("deviate-replace-stmt -> DEVIATE add ;"); }
{ if (ysp_add(_yy, Y_DEVIATE, strdup("replace"), NULL) == NULL) _YYERROR("notification_stmt");
_PARSE_DEBUG("deviate-replace-stmt -> DEVIATE 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 '}'
{ 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
@ -1688,40 +1681,40 @@ yang_stmt : action_stmt { _PARSE_DEBUG("yang-stmt -> action-stmt");
| leaf_stmt { _PARSE_DEBUG("yang-stmt -> leaf-stmt");}
| length_stmt { _PARSE_DEBUG("yang-stmt -> length-stmt");}
| list_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| mandatory_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| max_elements_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| min_elements_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| modifier_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| module_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| must_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| namespace_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| mandatory_stmt { _PARSE_DEBUG("yang-stmt -> mandatory-stmt");}
| max_elements_stmt { _PARSE_DEBUG("yang-stmt -> max-elements-stmt");}
| min_elements_stmt { _PARSE_DEBUG("yang-stmt -> min-elements-stmt");}
| modifier_stmt { _PARSE_DEBUG("yang-stmt -> modifier-stmt");}
| module_stmt { _PARSE_DEBUG("yang-stmt -> module-stmt");}
| must_stmt { _PARSE_DEBUG("yang-stmt -> must-stmt");}
| namespace_stmt { _PARSE_DEBUG("yang-stmt -> namespace-stmt");}
| notification_stmt { _PARSE_DEBUG("yang-stmt -> notification-stmt");}
| ordered_by_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| organization_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| output_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| path_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| pattern_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| position_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| prefix_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| presence_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| range_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| reference_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| refine_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| require_instance_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| revision_date_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| revision_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| ordered_by_stmt { _PARSE_DEBUG("yang-stmt -> ordered-by-stmt");}
| organization_stmt { _PARSE_DEBUG("yang-stmt -> organization-stmt");}
| output_stmt { _PARSE_DEBUG("yang-stmt -> output-stmt");}
| path_stmt { _PARSE_DEBUG("yang-stmt -> path-stmt");}
| pattern_stmt { _PARSE_DEBUG("yang-stmt -> pattern-stmt");}
| position_stmt { _PARSE_DEBUG("yang-stmt -> position-stmt");}
| prefix_stmt { _PARSE_DEBUG("yang-stmt -> prefix-stmt");}
| presence_stmt { _PARSE_DEBUG("yang-stmt -> presence-stmt");}
| range_stmt { _PARSE_DEBUG("yang-stmt -> range-stmt");}
| reference_stmt { _PARSE_DEBUG("yang-stmt -> reference-stmt");}
| refine_stmt { _PARSE_DEBUG("yang-stmt -> refine-stmt");}
| require_instance_stmt { _PARSE_DEBUG("yang-stmt -> require-instance-stmt");}
| revision_date_stmt { _PARSE_DEBUG("yang-stmt -> revision-date-stmt");}
| revision_stmt { _PARSE_DEBUG("yang-stmt -> revision-stmt");}
| rpc_stmt { _PARSE_DEBUG("yang-stmt -> rpc-stmt");}
| status_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| submodule_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| status_stmt { _PARSE_DEBUG("yang-stmt -> status-stmt");}
| submodule_stmt { _PARSE_DEBUG("yang-stmt -> submodule-stmt");}
| typedef_stmt { _PARSE_DEBUG("yang-stmt -> typedef-stmt");}
| type_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| unique_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| units_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| uses_augment_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| uses_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| value_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| when_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| yang_version_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");}
| type_stmt { _PARSE_DEBUG("yang-stmt -> type-stmt");}
| unique_stmt { _PARSE_DEBUG("yang-stmt -> unique-stmt");}
| units_stmt { _PARSE_DEBUG("yang-stmt -> units-stmt");}
| uses_augment_stmt { _PARSE_DEBUG("yang-stmt -> uses-augment-stmt");}
| uses_stmt { _PARSE_DEBUG("yang-stmt -> uses-stmt");}
| value_stmt { _PARSE_DEBUG("yang-stmt -> value-stmt");}
| when_stmt { _PARSE_DEBUG("yang-stmt -> when-stmt");}
| yang_version_stmt { _PARSE_DEBUG("yang-stmt -> yang-version-stmt");}
/* | yin_element_stmt { _PARSE_DEBUG("yang-stmt -> list-stmt");} */
;

View file

@ -35,11 +35,15 @@ module example-base{
prefix base;
namespace "urn:example:base";
container system {
must "daytime or time";
leaf daytime{ /* not supported removes this */
must "daytime or time"; /* deviate delete removes this */
leaf daytime{ /* deviate not-supported removes this */
type string;
}
leaf time{
type string;
}
list name-server {
max-elements 1; /* deviate replace replaces to "max.elements 3" here */
key name;
leaf name {
type string;
@ -52,7 +56,7 @@ module example-base{
}
leaf type {
type string;
/* add rule adds default here */
/* deviate add adds "default admin" here */
}
}
}
@ -60,12 +64,16 @@ module example-base{
EOF
# Args:
# 0: daytime implemented: true/false
# 1: admin type default: true/false
# 1: daytime implemented: 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()
{
daytime=$1
admindefault=$2
mustdate=$3
maxel1=$4
new "test params: -f $cfg"
@ -82,29 +90,55 @@ function testrun()
new "wait backend"
wait_backend
if ! $daytime; then # Not supported - dont continue
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\"><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>]]>]]"
new "Add user bob"
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>]]>]]"
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
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"
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"
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>]]>]]"
new "netconf commit"
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
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>]]>]]>$"
if $admindefault; then # add rule
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>]]>]]>$"
# 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
else
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>]]>]]>$"
fi
# 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
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>]]>]]>$"
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
new "Kill backend"
# Check if premature kill
@ -128,8 +162,8 @@ module example-deviations{
}
}
EOF
new "daytime supported"
testrun true false
new "1. daytime supported"
testrun true false true true
# Example from RFC 7950 Sec 7.20.3.3
cat <<EOF > $fyangdev
@ -145,10 +179,10 @@ module example-deviations{
}
}
EOF
new "daytime not supported"
testrun false false
new "2. daytime not supported"
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
module example-deviations{
yang-version 1.1;
@ -164,8 +198,47 @@ module example-deviations{
}
}
EOF
new "deviate add, check admin default"
testrun true true
new "3. deviate add, check admin default"
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"