Fixed: [Missing/no namespace error in YANG augments with default values](https://github.com/clicon/clixon/issues/354)
Tests: ensure all netconf requests with identityref have declared namespaces. * This is part of fixing [Yang identityref XML encoding is not general](https://github.com/clicon/clixon/issues/90)
This commit is contained in:
parent
b748d68912
commit
74da966096
12 changed files with 177 additions and 104 deletions
|
|
@ -245,7 +245,7 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS>
|
|||
<name>e2</name>
|
||||
<type>mymod:some-new-iftype</type>
|
||||
<mymod:mandatory-leaf>true</mymod:mandatory-leaf>
|
||||
<mymod:other>if:fddi</mymod:other>
|
||||
<mymod:other xmlns:if=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\">if:fddi</mymod:other>
|
||||
</interface></interfaces></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "netconf validate ok"
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ cat <<EOF > $fstate
|
|||
EOF
|
||||
|
||||
EXPSTATE=$(cat <<EOF
|
||||
<global-state xmlns="urn:example:lib"><gbds>gbds</gbds><aug:gads xmlns:aug="urn:example:augment">gads</aug:gads></global-state>
|
||||
<global-state xmlns="urn:example:lib"><gbds>gbds</gbds><gads xmlns="urn:example:augment">gads</gads></global-state>
|
||||
EOF
|
||||
)
|
||||
|
||||
|
|
@ -184,13 +184,13 @@ new "4. Empty config + optional state, expect global default + optional state"
|
|||
cat <<EOF > $fstate
|
||||
<global-state xmlns="urn:example:lib">
|
||||
<gbos>gbos</gbos>
|
||||
<aug:gaos xmlns:aug="urn:example:augment">gaos</aug:gaos>
|
||||
<gaos xmlns="urn:example:augment">gaos</gaos>
|
||||
</global-state>
|
||||
EOF
|
||||
|
||||
# Note Expect gbds(default) + gbos(optional), the latter given by file above
|
||||
EXPSTATE=$(cat <<EOF
|
||||
<global-state xmlns="urn:example:lib"><gbds>gbds</gbds><gbos>gbos</gbos><aug:gads xmlns:aug="urn:example:augment">gads</aug:gads><aug:gaos xmlns:aug="urn:example:augment">gaos</aug:gaos></global-state>
|
||||
<global-state xmlns="urn:example:lib"><gbds>gbds</gbds><gbos>gbos</gbos><gads xmlns="urn:example:augment">gads</gads><gaos xmlns="urn:example:augment">gaos</gaos></global-state>
|
||||
EOF
|
||||
)
|
||||
|
||||
|
|
@ -209,7 +209,7 @@ cat <<EOF > $fstate
|
|||
EOF
|
||||
|
||||
EXPSTATE=$(cat <<EOF
|
||||
<global-state xmlns="urn:example:lib"><gbds>gbds</gbds><aug:gads xmlns:aug="urn:example:augment">gads</aug:gads></global-state><base-config xmlns="urn:example:lib"><parameter><name>a</name><param-state><lbds>lbds</lbds><aug:lads xmlns:aug="urn:example:augment">lads</aug:lads></param-state></parameter></base-config>
|
||||
<global-state xmlns="urn:example:lib"><gbds>gbds</gbds><gads xmlns="urn:example:augment">gads</gads></global-state><base-config xmlns="urn:example:lib"><parameter><name>a</name><param-state><lbds>lbds</lbds><lads xmlns="urn:example:augment">lads</lads></param-state></parameter></base-config>
|
||||
EOF
|
||||
)
|
||||
|
||||
|
|
@ -238,7 +238,7 @@ cat <<EOF > $fstate
|
|||
EOF
|
||||
|
||||
EXPSTATE=$(cat <<EOF
|
||||
<global-state xmlns="urn:example:lib"><gbds>gbds</gbds><aug:gads xmlns:aug="urn:example:augment">gads</aug:gads></global-state><base-config xmlns="urn:example:lib"><parameter><name>a</name><param-state><lbds>lbds</lbds><lbos>lbos</lbos><aug:lads xmlns:aug="urn:example:augment">lads</aug:lads><laos xmlns="urn:example:augment">laos</laos></param-state></parameter></base-config>
|
||||
<global-state xmlns="urn:example:lib"><gbds>gbds</gbds><gads xmlns="urn:example:augment">gads</gads></global-state><base-config xmlns="urn:example:lib"><parameter><name>a</name><param-state><lbds>lbds</lbds><lbos>lbos</lbos><lads xmlns="urn:example:augment">lads</lads><laos xmlns="urn:example:augment">laos</laos></param-state></parameter></base-config>
|
||||
EOF
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ new "wait restconf"
|
|||
wait_restconf
|
||||
|
||||
new "Add config to candidate"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"create\"><name>eth/0/0</name><type>if:fddi</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"create\"><name>eth/0/0</name><type xmlns:if=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\">if:fddi</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "netconf commit to running"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><commit/></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
|
@ -153,10 +153,10 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS>
|
|||
|
||||
# Here startup and candidate have content
|
||||
new "Check candidate content"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface xmlns:if=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><name>eth/0/0</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
|
||||
new "Check startup content"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><startup/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><startup/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface xmlns:if=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><name>eth/0/0</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
|
||||
new "Delete startup"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><delete-config><target><startup/></target></delete-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
|
@ -169,8 +169,8 @@ expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS>
|
|||
new "copy candidate->startup"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><copy-config><target><startup/></target><source><candidate/></source></copy-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "Check startup content"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><startup/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
new "Check startup content xxx"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><startup/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface xmlns:if=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><name>eth/0/0</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
|
||||
new "Delete candidate"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"delete\"><name>eth/0/0</name><type>if:fddi</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
|
@ -184,7 +184,7 @@ new "copy startup->candidate"
|
|||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><copy-config><target><candidate/></target><source><startup/></source></copy-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "Check candidate content"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface xmlns:if=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><name>eth/0/0</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
|
||||
# Negative test: check copying to running is not allowed
|
||||
new "Delete candidate"
|
||||
|
|
|
|||
|
|
@ -89,6 +89,9 @@ module example-my-crypto {
|
|||
namespace "urn:example:my-crypto";
|
||||
prefix mc;
|
||||
include "example-sub";
|
||||
import example-extra {
|
||||
prefix ee;
|
||||
}
|
||||
import "example-crypto-base" {
|
||||
prefix "crypto";
|
||||
}
|
||||
|
|
@ -215,19 +218,19 @@ new "netconf validate "
|
|||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "Set crypto to mc:aes"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><crypto xmlns=\"urn:example:my-crypto\">mc:aes</crypto></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><crypto xmlns=\"urn:example:my-crypto\" xmlns:mc=\"urn:example:my-crypto\">mc:aes</crypto></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "netconf validate"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "Set crypto to des:des3"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><crypto xmlns=\"urn:example:my-crypto\">des:des3</crypto></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><crypto xmlns=\"urn:example:my-crypto\" xmlns:des=\"urn:example:des\">des:des3</crypto></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "netconf validate"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "Set crypto to mc:foo"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><crypto xmlns=\"urn:example:my-crypto\">mc:foo</crypto></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><crypto xmlns=\"urn:example:my-crypto\" xmlns:mc=\"urn:example:my-crypto\">mc:foo</crypto></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "netconf validate"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
|
@ -247,11 +250,16 @@ new "netconf validate"
|
|||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
fi # not supported
|
||||
|
||||
new "Set crypto to foo:bar"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><crypto xmlns=\"urn:example:my-crypto\">foo:bar</crypto></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
if false; then
|
||||
# This should run if remove IDENTITYREF_KLUDGE
|
||||
new "Set crypto to foo:bar"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><crypto xmlns=\"urn:example:my-crypto\">foo:bar</crypto></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>invalid-value</error-tag><error-severity>error</error-severity><error-message>identityref: \"foo:bar\": prefix \"foo\" has no associated namespace</error-message></rpc-error></rpc-reply>"
|
||||
|
||||
new "netconf validate (expect fail)"
|
||||
expecteof_netconf "$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>Identityref validation failed, foo:bar not derived from crypto-alg in example-crypto-base.yang:[0-9]*</error-message></rpc-error></rpc-reply>" ""
|
||||
# Before foo:bar was accewpted but invalid here. Now it is catched in edit-config
|
||||
new "netconf validate (expect fail)"
|
||||
expecteof_netconf "$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>Identityref validation failed, foo:bar not derived from crypto-alg in example-crypto-base.yang:[0-9]*</error-message></rpc-error></rpc-reply>" ""
|
||||
|
||||
fi
|
||||
|
||||
new "cli set crypto to mc:aes"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -l o set crypto mc:aes)" 0 "^$"
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ module example{
|
|||
EOF
|
||||
|
||||
BASEXML=$(cat <<EOF
|
||||
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
|
||||
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces" xmlns:ex="urn:example:clixon">
|
||||
<interface xmlns:ip="urn:ietf:params:xml:ns:yang:ietf-ip">
|
||||
<name>eth0</name>
|
||||
<type>ex:eth</type>
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ new "Check nothing added"
|
|||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data/></rpc-reply>"
|
||||
|
||||
new "Add subtree eth/0/0 using none and create which should add eth/0/0"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"create\"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"create\"><name>eth/0/0</name><type xmlns:ex=\"urn:example:clixon\">ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
# Too many quotes, (single inside double inside single) need to fool bash
|
||||
rpc=$(chunked_framing "<rpc $DEFAULTNS><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/if:interfaces/if:interface[if:name='eth/0/0']\" xmlns:if=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"/></get-config></rpc>")
|
||||
|
|
@ -109,7 +109,7 @@ $DEFAULTHELLO$rpc
|
|||
EOF
|
||||
|
||||
new "Check eth/0/0 added using xpath"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "$rpc" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "$rpc" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface xmlns:ex=\"urn:example:clixon\"><name>eth/0/0</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
|
||||
new "Re-create same eth/0/0 which should generate error"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" xmlns:nc=\"urn:ietf:params:xml:ns:netconf:base:1.0\"><interface nc:operation=\"create\"><name>eth/0/0</name><type>ex:eth</type></interface></interfaces></config><default-operation>none</default-operation> </edit-config></rpc>" "<rpc-reply $DEFAULTNS><rpc-error>" ""
|
||||
|
|
@ -164,7 +164,7 @@ new "netconf discard-changes"
|
|||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><discard-changes/></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "netconf edit config eth1"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth1</name><type>ex:eth</type></interface></interfaces></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth1</name><type xmlns:ex=\"urn:example:clixon\">ex:eth</type></interface></interfaces></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "netconf validate"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><validate><source><candidate/></source></validate></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
|
@ -176,21 +176,21 @@ new "netconf commit using prefix xx"
|
|||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<xx:rpc xmlns:xx=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xx:message-id=\"42\"><xx:commit/></xx:rpc>" "" "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xmlns:xx=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xx:message-id=\"42\"><ok/></rpc-reply>"
|
||||
|
||||
new "netconf edit config merge eth2"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth2</name><type>ex:eth</type></interface></interfaces></config><default-operation>merge</default-operation></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth2</name><type xmlns:ex=\"urn:example:clixon\">ex:eth</type></interface></interfaces></config><default-operation>merge</default-operation></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
# Note, the type here is non-existant identityref, fails on validation
|
||||
new "netconf edit ampersand encoding(<&): name:'eth&' type:'t<>'"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth&</name><type>t<></type></interface></interfaces></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "netconf get replaced config"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth&</name><type>t<></type><enabled>true</enabled></interface><interface><name>eth1</name><type>ex:eth</type><enabled>true</enabled></interface><interface><name>eth2</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth&</name><type>t<></type><enabled>true</enabled></interface><interface xmlns:ex=\"urn:example:clixon\"><name>eth1</name><type>ex:eth</type><enabled>true</enabled></interface><interface xmlns:ex=\"urn:example:clixon\"><name>eth2</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
|
||||
new "cli show configuration eth& - encoding tests"
|
||||
expectpart "$($clixon_cli -1 -f $cfg show conf cli)" 0 "interfaces interface eth& type t<>
|
||||
interfaces interface eth& enabled true"
|
||||
|
||||
new "netconf edit CDATA"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type>ex:eth</type><description><![CDATA[myeth&]]></description></interface></interfaces></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth/0/0</name><type xmlns:ex=\"urn:example:clixon\">ex:eth</type><description><![CDATA[myeth&]]></description></interface></interfaces></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
#new "netconf get CDATA"
|
||||
#expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source><filter type=\"xpath\" select=\"/interfaces/interface[name='eth/0/0']/description\" /></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>eth/0/0</name><description><![CDATA[myeth&]]></description><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
|
|
@ -202,10 +202,10 @@ new "netconf edit state operation should fail"
|
|||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><edit-config><target><candidate/></target><config><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>e0</name><oper-status>up</oper-status></interface></interfaces></config></edit-config></rpc>" "" "<rpc-reply $DEFAULTNS><rpc-error><error-type>application</error-type><error-tag>bad-element</error-tag><error-info><bad-element>oper-status</bad-element></error-info><error-severity>error</error-severity><error-message>module ietf-interfaces: state data node unexpected</error-message></rpc-error></rpc-reply>"
|
||||
|
||||
new "netconf get state operation"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get><filter type=\"xpath\" select=\"/if:interfaces\" xmlns:if=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" /></get></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth1</name><type>ex:eth</type><enabled>true</enabled><oper-status>up</oper-status><ex:my-status xmlns:ex=\"urn:example:clixon\"><ex:int>42</ex:int><ex:str>foo</ex:str></ex:my-status></interface></interfaces></data></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get><filter type=\"xpath\" select=\"/if:interfaces\" xmlns:if=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" /></get></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface xmlns:ex=\"urn:example:clixon\"><name>eth1</name><type>ex:eth</type><enabled>true</enabled><oper-status>up</oper-status><ex:my-status><ex:int>42</ex:int><ex:str>foo</ex:str></ex:my-status></interface></interfaces></data></rpc-reply>"
|
||||
|
||||
new "netconf get state operation use prefix xx"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<xx:rpc xmlns:xx=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xx:message-id=\"42\"><xx:get><xx:filter xx:type=\"xpath\" xx:select=\"/if:interfaces\" xmlns:if=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" /></xx:get></xx:rpc>" "" "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xmlns:xx=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xx:message-id=\"42\"><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth1</name><type>ex:eth</type><enabled>true</enabled><oper-status>up</oper-status><ex:my-status xmlns:ex=\"urn:example:clixon\"><ex:int>42</ex:int><ex:str>foo</ex:str></ex:my-status></interface></interfaces></data></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<xx:rpc xmlns:xx=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xx:message-id=\"42\"><xx:get><xx:filter xx:type=\"xpath\" xx:select=\"/if:interfaces\" xmlns:if=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\" /></xx:get></xx:rpc>" "" "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xmlns:xx=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xx:message-id=\"42\"><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface xmlns:ex=\"urn:example:clixon\"><name>eth1</name><type>ex:eth</type><enabled>true</enabled><oper-status>up</oper-status><ex:my-status><ex:int>42</ex:int><ex:str>foo</ex:str></ex:my-status></interface></interfaces></data></rpc-reply>"
|
||||
|
||||
new "netconf lock"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><lock><target><candidate/></target></lock></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
|
@ -279,7 +279,7 @@ new "copy startup to candidate using prefix xx"
|
|||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<xx:rpc xmlns:xx=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xx:message-id=\"42\"><xx:copy-config><xx:target><xx:startup/></xx:target><xx:source><xx:candidate/></xx:source></xx:copy-config></xx:rpc>" "" "<rpc-reply xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xmlns:xx=\"urn:ietf:params:xml:ns:netconf:base:1.0\" xx:message-id=\"42\"><ok/></rpc-reply>"
|
||||
|
||||
new "netconf get startup"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><startup/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface><name>eth1</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><startup/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"urn:ietf:params:xml:ns:yang:ietf-interfaces\"><interface xmlns:ex=\"urn:example:clixon\"><name>eth1</name><type>ex:eth</type><enabled>true</enabled></interface></interfaces></data></rpc-reply>"
|
||||
|
||||
new "netconf delete startup"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><delete-config><target><startup/></target></delete-config></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ cat <<EOF > $dir/startup_db
|
|||
<name>e</name>
|
||||
<config>
|
||||
<name>e</name>
|
||||
<type>ex:eth</type>
|
||||
<type xmlns:ex="urn:example:clixon">ex:eth</type>
|
||||
<loopback-mode>false</loopback-mode>
|
||||
<enabled>true</enabled>
|
||||
</config>
|
||||
|
|
@ -103,7 +103,7 @@ new "$clixon_cli -D $DBG -1f $cfg show version"
|
|||
expectpart "$($clixon_cli -D $DBG -1f $cfg show version)" 0 "${CLIXON_VERSION}"
|
||||
|
||||
new "$clixon_netconf -qf $cfg"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"http://openconfig.net/yang/interfaces\"><interface><name>e</name><config><name>e</name><type>ex:eth</type><loopback-mode>false</loopback-mode><enabled>true</enabled></config><hold-time><config><up>0</up><down>0</down></config></hold-time></interface></interfaces></data></rpc-reply>"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><get-config><source><candidate/></source></get-config></rpc>" "" "<rpc-reply $DEFAULTNS><data><interfaces xmlns=\"http://openconfig.net/yang/interfaces\"><interface><name>e</name><config><name>e</name><type xmlns:ex=\"urn:example:clixon\">ex:eth</type><loopback-mode>false</loopback-mode><enabled>true</enabled></config><hold-time><config><up>0</up><down>0</down></config></hold-time></interface></interfaces></data></rpc-reply>"
|
||||
|
||||
new "cli show configuration"
|
||||
expectpart "$($clixon_cli -1 -f $cfg show conf xml)" 0 "^<interfaces xmlns=\"http://openconfig.net/yang/interfaces\">" --not-- "<oc-eth:ethernet xmlns:oc-eth=\"http://openconfig.net/yang/interfaces/ethernet\">"
|
||||
|
|
@ -153,10 +153,10 @@ cat <<EOF > $dir/startup_db
|
|||
<name>eth1</name>
|
||||
<config>
|
||||
<name>eth1</name>
|
||||
<type>ianaift:ethernetCsmacd</type>
|
||||
<type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd</type>
|
||||
<mtu>9206</mtu>
|
||||
<enabled>true</enabled>
|
||||
<oc-vlan:tpid xmlns:oc-vlan="http://openconfig.net/yang/vlan">oc-vlan-types:TPID_0X8100</oc-vlan:tpid>
|
||||
<oc-vlan:tpid xmlns:oc-vlan="http://openconfig.net/yang/vlan" xmlns:oc-vlan-types="http://openconfig.net/yang/vlan-types">oc-vlan-types:TPID_0X8100</oc-vlan:tpid>
|
||||
</config>
|
||||
<oc-eth:ethernet xmlns:oc-eth="http://openconfig.net/yang/interfaces/ethernet">
|
||||
<oc-eth:config>
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ cat <<EOF > $dir/startup_db
|
|||
</fdb>
|
||||
<config>
|
||||
<name>default</name>
|
||||
<type>oc-ni-types:DEFAULT_INSTANCE</type>
|
||||
<type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:DEFAULT_INSTANCE</type>
|
||||
<enabled>true</enabled>
|
||||
<router-id>1.2.3.4</router-id>
|
||||
</config>
|
||||
|
|
|
|||
|
|
@ -81,22 +81,22 @@ module ietf-interfaces {
|
|||
EOF
|
||||
|
||||
# Create running-db containin the interface "run" OK
|
||||
runvar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>run</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
runvar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>run</name><type xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces">if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
|
||||
# Create startup-db containing the interface "startup" OK
|
||||
startvar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>startup</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
startvar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces"><name>startup</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
|
||||
# extra OK
|
||||
extravar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>extra</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
extravar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces"><name>extra</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
|
||||
# invalid (contains <not-defined/>), but OK XML syntax
|
||||
invalidvar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><not-defined/><name>invalid</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
invalidvar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces"><not-defined/><name>invalid</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
|
||||
# Broken XML (contains </nmae>)
|
||||
brokenvar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>broken</nmae><type>if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
brokenvar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces"><name>broken</nmae><type>if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
|
||||
# Startup XML with state
|
||||
statevar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>startup</name><oper-status>up</oper-status><type>if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
statevar='<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>startup</name><oper-status>up</oper-status><type xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces">if:fddi</type><enabled>true</enabled></interface></interfaces>'
|
||||
|
||||
# Create a pre-set running, startup and (extra) config.
|
||||
# The configs are identified by an interface called run, startup, extra.
|
||||
|
|
@ -204,10 +204,10 @@ testrun init "$runvar" "$startvar" "$extravar" "<data>$extravar</data>"
|
|||
testrun none "$runvar" "$startvar" "$extravar" "<data>$runvar</data>"
|
||||
|
||||
# Running mode: keep running but load also extra
|
||||
testrun running "$runvar" "$startvar" "$extravar" '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>extra</name><type>if:fddi</type><enabled>true</enabled></interface><interface><name>run</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
testrun running "$runvar" "$startvar" "$extravar" '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces"><name>extra</name><type>if:fddi</type><enabled>true</enabled></interface><interface xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces"><name>run</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
|
||||
# Startup mode: scratch running, load startup with extra on top
|
||||
testrun startup "$runvar" "$startvar" "$extravar" '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface><name>extra</name><type>if:fddi</type><enabled>true</enabled></interface><interface><name>startup</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
testrun startup "$runvar" "$startvar" "$extravar" '<data><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"><interface xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces"><name>extra</name><type>if:fddi</type><enabled>true</enabled></interface><interface xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces"><name>startup</name><type>if:fddi</type><enabled>true</enabled></interface></interfaces></data>'
|
||||
|
||||
# 2. Try different modes on Invalid running/startup/extra WITHOUT failsafe
|
||||
# ensure all db:s are unchanged after failure.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue