diff options
Diffstat (limited to 'tests/yanglint/interactive')
22 files changed, 1045 insertions, 0 deletions
diff --git a/tests/yanglint/interactive/add.test b/tests/yanglint/interactive/add.test new file mode 100644 index 0000000..d1cacc1 --- /dev/null +++ b/tests/yanglint/interactive/add.test @@ -0,0 +1,59 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set mdir $::env(YANG_MODULES_DIR) + +test add_basic {} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "add $mdir/modleafref.yang" + ly_cmd "list" "I modleafref\r.*I modleaf" +}} + +test add_disable_searchdir_once {add --disable-searchdir} { +-setup $ly_setup -cleanup $ly_cleanup -constraints {!ctest} -body { + ly_cmd "add $mdir/modimp-cwd.yang" + ly_cmd "clear" + ly_cmd_err "add -D $mdir/modimp-cwd.yang" "not found in local searchdirs" +}} + +test add_disable_searchdir_twice {add -D -D} { +-setup $ly_setup -cleanup $ly_cleanup -constraints {!ctest} -body { + ly_cmd "add $mdir/ietf-ip.yang" + ly_cmd "clear" + ly_cmd_err "add -D -D $mdir/ietf-ip.yang" "Loading \"ietf-interfaces\" module failed." +}} + +test add_with_feature {Add module with feature} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "add --feature modfeature:ftr2 $mdir/modfeature.yang" + ly_cmd "feature -a" "modfeature:\r\n\tftr1 \\(off\\)\r\n\tftr2 \\(on\\)" +}} + +test add_make_implemented_once {add --make-implemented} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_ignore "add $mdir/modmust.yang" + ly_cmd "list" "I modmust\r.*i modleaf" + ly_cmd "clear" + ly_ignore "add -i $mdir/modmust.yang" + ly_cmd "list" "I modmust\r.*I modleaf" +}} + +test add_make_implemented_twice {add -i -i} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "add $mdir/modimp-type.yang" + ly_cmd "list" "I modimp-type\r.*i modtypedef" + ly_cmd "clear" + ly_cmd "add -i -i $mdir/modimp-type.yang" + ly_cmd "list" "I modimp-type\r.*I modtypedef" +}} + +test add_extended_leafref_enabled {Valid module with --extended-leafref option} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "add -X $mdir/modextleafref.yang" +}} + +test add_extended_leafref_disabled {Expected error if --extended-leafref is not set} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd_err "add $mdir/modextleafref.yang" "Unexpected XPath token \"FunctionName\"" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/all.tcl b/tests/yanglint/interactive/all.tcl new file mode 100644 index 0000000..b22a5ab --- /dev/null +++ b/tests/yanglint/interactive/all.tcl @@ -0,0 +1,15 @@ +package require tcltest + +# Hook to determine if any of the tests failed. +# Sets a global variable exitCode to 1 if any test fails otherwise it is set to 0. +proc tcltest::cleanupTestsHook {} { + variable numTests + set ::exitCode [expr {$numTests(Failed) > 0}] +} + +if {[info exists ::env(TESTS_DIR)]} { + tcltest::configure -testdir "$env(TESTS_DIR)/interactive" +} + +tcltest::runAllTests +exit $exitCode diff --git a/tests/yanglint/interactive/clear.test b/tests/yanglint/interactive/clear.test new file mode 100644 index 0000000..cac0810 --- /dev/null +++ b/tests/yanglint/interactive/clear.test @@ -0,0 +1,53 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set mdir $::env(YANG_MODULES_DIR) +set ddir $::env(TESTS_DIR)/data + +test clear_searchpath {searchpath is also deleted} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "searchpath ./" + ly_cmd "clear" + ly_cmd "searchpath" "List of the searchpaths:" -ex +}} + +test clear_make_implemented_once {clear --make-implemented} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -i" + ly_cmd "add $mdir/modmust.yang" + ly_cmd "list" "I modmust\r.*I modleaf" +}} + +test clear_make_implemented_twice {clear -i -i} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -i -i" + ly_cmd "add $mdir/modmust.yang" + ly_cmd "list" "I modmust\r.*I modleaf" +}} + +test clear_ietf_yang_library {clear --yang-library} { +-setup $ly_setup -cleanup $ly_cleanup -body { + # add models + ly_cmd "clear -y" + ly_cmd "list" "I ietf-yang-library" +}} + +test clear_ylf_list {apply --yang-library-file and check result by --list} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -Y $ddir/modimp_type_ctx.xml" + ly_cmd "list" "I modimp-type.*i modtypedef" +}} + +test clear_ylf_make_implemented {apply --yang-library-file and --make-implemented} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -Y $ddir/modimp_type_ctx.xml -i -i" + ly_cmd "list" "I modimp-type.*I modtypedef" +}} + +test clear_ylf_augment_ctx {Setup context by yang-library-file and augment module} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -Y $ddir/modconfig_ctx.xml" + ly_cmd "add $mdir/modconfig-augment.yang" + ly_cmd "print -f tree modconfig" "mca:alf" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/completion.test b/tests/yanglint/interactive/completion.test new file mode 100644 index 0000000..86ded1f --- /dev/null +++ b/tests/yanglint/interactive/completion.test @@ -0,0 +1,69 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set mdir "$::env(YANG_MODULES_DIR)" + +variable ly_cleanup { + ly_ignore + ly_exit +} + +test completion_hints_ietf_ip {Completion and hints for ietf-ip.yang} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "add $mdir/ietf-ip.yang" + + # completion and hint + ly_completion "print -f info -P " "print -f info -P /ietf-" + + set hints {"/ietf-yang-schema-mount:schema-mounts" "/ietf-interfaces:interfaces" "/ietf-interfaces:interfaces-state"} + ly_hint "" "print -f info -P /ietf-" $hints + + # double completion + ly_completion "i" "print -f info -P /ietf-interfaces:interfaces" + ly_completion "/" "print -f info -P /ietf-interfaces:interfaces/interface" + + # a lot of hints + set hints {"/ietf-interfaces:interfaces/interface" + "/ietf-interfaces:interfaces/interface/name" "/ietf-interfaces:interfaces/interface/description" + "/ietf-interfaces:interfaces/interface/type" "/ietf-interfaces:interfaces/interface/enabled" + "/ietf-interfaces:interfaces/interface/link-up-down-trap-enable" + "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6" + } + ly_hint "" "print -f info -P /ietf-interfaces:interfaces/interface" $hints + + # double tab + ly_completion "/i" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv" + ly_completion "4" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv4" + set hints { "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/enabled" + "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/forwarding" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/mtu" + "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/address" "/ietf-interfaces:interfaces/interface/ietf-ip:ipv4/neighbor" + } + ly_hint "\t" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv" $hints + + # no more completion + ly_completion "/e" "print -f info -P /ietf-interfaces:interfaces/interface/ietf-ip:ipv4/enabled " +}} + +# Note that somehow a command is automatically sent again (\t\t replaced by \r) after the hints. +# But that doesn't affect the test because the tests only focus on the word in the hint. + +test hint_data_file {Show file hints for command data} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_hint "data $mdir\t\t" "data $mdir" "modleaf.yang.*" +}} + +test hint_data_format {Show print hints for command data --format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_hint "data -f \t\t" "data -f " "xml.*" +}} + +test hint_data_file_after_opt {Show file hints after option with argument} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_hint "data -f xml $mdir\t\t" "data -f xml $mdir" "modleaf.yang.*" +}} + +test hint_data_file_after_opt2 {Show file hints after option without argument} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_hint "data -m $mdir\t\t" "data -m $mdir" "modleaf.yang.*" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/data_default.test b/tests/yanglint/interactive/data_default.test new file mode 100644 index 0000000..1953acc --- /dev/null +++ b/tests/yanglint/interactive/data_default.test @@ -0,0 +1,41 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set mods "ietf-netconf-with-defaults moddefault" +set data "$::env(TESTS_DIR)/data/moddefault.xml" + +test data_default_not_set {Print data without --default parameter} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load $mods" + ly_cmd "data -f xml $data" "</lf>.*</di>\r\n</mdc>" + ly_cmd "data -f json $data" "lf\".*di\"\[^\"]*" +}} + +test data_default_all {data --default all} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load $mods" + ly_cmd "data -d all -f xml $data" "</lf>.*</di>.*</ds>\r\n</mdc>" + ly_cmd "data -d all -f json $data" "lf\".*di\".*ds\"\[^\"]*" +}} + +test data_default_all_tagged {data --default all-tagged} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load $mods" + ly_cmd "data -d all-tagged -f xml $data" "</lf>.*<di.*default.*</di>.*<ds.*default.*</ds>\r\n</mdc>" + ly_cmd "data -d all-tagged -f json $data" "lf\".*di\".*ds\".*@ds\".*default\"\[^\"]*" +}} + +test data_default_trim {data --default trim} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load $mods" + ly_cmd "data -d trim -f xml $data" "</lf>\r\n</mdc>" + ly_cmd "data -d trim -f json $data" "lf\"\[^\"]*" +}} + +test data_default_implicit_tagged {data --default implicit-tagged} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load $mods" + ly_cmd "data -d implicit-tagged -f xml $data" "</lf>.*<di>5</di>.*<ds.*default.*</ds>\r\n</mdc>" + ly_cmd "data -d implicit-tagged -f json $data" "lf\".*di\"\[^@]*ds\".*default\"\[^\"]*" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/data_format.test b/tests/yanglint/interactive/data_format.test new file mode 100644 index 0000000..dc4b7e0 --- /dev/null +++ b/tests/yanglint/interactive/data_format.test @@ -0,0 +1,23 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set ddir "$::env(TESTS_DIR)/data" + +test data_format_xml {Print data in xml format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf" + ly_cmd "data -f xml $ddir/modleaf.xml" "<lfl xmlns=\"urn:yanglint:modleaf\">7</lfl>" +}} + +test data_format_json {Print data in json format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf" + ly_cmd "data -f json $ddir/modleaf.xml" "{\r\n \"modleaf:lfl\": 7\r\n}" +}} + +test data_format_lyb_err {Print data in lyb format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf" + ly_cmd_err "data -f lyb $ddir/modleaf.xml" "The LYB format requires the -o" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/data_in_format.test b/tests/yanglint/interactive/data_in_format.test new file mode 100644 index 0000000..cc5f37e --- /dev/null +++ b/tests/yanglint/interactive/data_in_format.test @@ -0,0 +1,21 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set ddir "$::env(TESTS_DIR)/data" + +test data_in_format_xml {--in-format xml} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf" + ly_cmd "data -F xml $ddir/modleaf.dxml" + ly_cmd_err "data -F json $ddir/modleaf.dxml" "Failed to parse" + ly_cmd_err "data -F lyb $ddir/modleaf.dxml" "Failed to parse" +}} + +test data_in_format_json {--in-format json} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf" + ly_cmd "data -F json $ddir/modleaf.djson" + ly_cmd_err "data -F xml $ddir/modleaf.djson" "Failed to parse" + ly_cmd_err "data -F lyb $ddir/modleaf.djson" "Failed to parse" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/data_merge.test b/tests/yanglint/interactive/data_merge.test new file mode 100644 index 0000000..38754c7 --- /dev/null +++ b/tests/yanglint/interactive/data_merge.test @@ -0,0 +1,33 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set ddir "$::env(TESTS_DIR)/data" + +test data_merge_basic {Data is merged and the node is added} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modmerge" + ly_cmd "data -m -f xml $ddir/modmerge.xml $ddir/modmerge3.xml" "<en>.*<lm>.*<lf>" +}} + +test data_merge_validation_failed {Data is merged but validation failed.} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modmerge" + ly_cmd "data $ddir/modmerge.xml" + ly_cmd "data $ddir/modmerge2.xml" + ly_cmd "data -m $ddir/modmerge2.xml $ddir/modmerge.xml" + ly_cmd_err "data -m $ddir/modmerge.xml $ddir/modmerge2.xml" "Merged data are not valid" +}} + +test data_merge_dataconfig {The merge option has effect only for 'data' and 'config' TYPEs} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modrpc modnotif modconfig modleaf" + set wrn1 "option has effect only for" + ly_cmd_wrn "data -m -t rpc $ddir/modrpc.xml $ddir/modrpc.xml" $wrn1 + ly_cmd_wrn "data -m -t notif $ddir/modnotif2.xml $ddir/modnotif2.xml" $wrn1 + ly_cmd_wrn "data -m -t get $ddir/modleaf.xml $ddir/modconfig.xml" $wrn1 + ly_cmd_wrn "data -m -t getconfig $ddir/modleaf.xml $ddir/modconfig2.xml" $wrn1 + ly_cmd_wrn "data -m -t edit $ddir/modleaf.xml $ddir/modconfig2.xml" $wrn1 + ly_cmd "data -m -t config $ddir/modleaf.xml $ddir/modconfig2.xml" + ly_cmd "data -m -t data $ddir/modleaf.xml $ddir/modconfig.xml" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/data_not_strict.test b/tests/yanglint/interactive/data_not_strict.test new file mode 100644 index 0000000..201a5a9 --- /dev/null +++ b/tests/yanglint/interactive/data_not_strict.test @@ -0,0 +1,25 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set ddir $::env(TESTS_DIR)/data + +test data_no_strict_basic {} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf" + ly_cmd_err "data $ddir/modmandatory.xml" "No module with namespace \"urn:yanglint:modmandatory\" in the context." + ly_cmd "data -n $ddir/modmandatory.xml" +}} + +test data_no_strict_invalid_data {validation with --no-strict but data are invalid} { +-setup $ly_setup -cleanup $ly_cleanup -body { + set errmsg "Mandatory node \"lft\" instance does not exist." + ly_cmd "load modmandatory" + ly_cmd_err "data -n $ddir/modmandatory_invalid.xml" $errmsg +}} + +test data_no_strict_ignore_invalid_data {--no-strict ignore invalid data if no schema is provided} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf" + ly_cmd "data -f xml -n $ddir/modmandatory_invalid.xml $ddir/modleaf.xml" "modleaf.*</lfl>$" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/data_operational.test b/tests/yanglint/interactive/data_operational.test new file mode 100644 index 0000000..c0c7b1c --- /dev/null +++ b/tests/yanglint/interactive/data_operational.test @@ -0,0 +1,86 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set ddir "$::env(TESTS_DIR)/data" +set err1 "Operational datastore takes effect only with RPCs/Actions/Replies/Notification input data types" + +test data_operational_twice {it is not allowed to specify more than one --operational parameter} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modoper-leafref" + ly_cmd "data -t notif -O $ddir/modconfig.xml -O $ddir/modleaf.xml" "cannot be set multiple times" +}} + +test data_operational_no_type {--operational should be with parameter --type} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modoper-leafref" + ly_cmd_wrn "data -O $ddir/modconfig.xml $ddir/modoper_leafref_notif.xml" $err1 +}} + +test data_operational_missing {--operational is omitted and the datastore contents is in the data file} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modoper-leafref" + ly_cmd_err "data $ddir/modoper_leafref_notif_err.xml" "Failed to parse input data file" +}} + +test data_operational_wrong_type {data are not defined as an operation} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd_wrn "data -t data -O $ddir/modconfig.xml $ddir/modleaf.xml" $err1 +}} + +test data_operational_datastore_with_unknown_data {unknown data are ignored} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modrpc" + ly_cmd "data -t rpc -O $ddir/modmandatory_invalid.xml $ddir/modrpc.xml" +}} + +test data_operational_empty_datastore {datastore is considered empty because it contains unknown data} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modrpc modnotif" + ly_cmd "data -t rpc -O $ddir/modmandatory_invalid.xml $ddir/modrpc.xml" + set msg "parent \"/modnotif:con\" not found in the operational data" + ly_cmd_err "data -t notif -O $ddir/modmandatory_invalid.xml $ddir/modnotif.xml" $msg +}} + +test data_operational_notif_leafref {--operational data is referenced from notification-leafref} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modoper-leafref" + ly_cmd "data -t notif -O $ddir/modconfig.xml $ddir/modoper_leafref_notif.xml" +}} + +test data_operational_nested_notif_leafref {--operational data is referenced from nested-notification-leafref} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modoper-leafref" + ly_cmd "data -t notif -O $ddir/modoper_leafref_ds.xml $ddir/modoper_leafref_notif2.xml" +}} + +test data_operational_nested_notif_parent_missing {--operational data are invalid due to missing parent node} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modoper-leafref" + set msg "klf='key_val']\" not found in the operational data" + ly_cmd_err "data -t notif -O $ddir/modconfig.xml $ddir/modoper_leafref_notif2.xml" $msg +}} + +test data_operational_action_leafref {--operational data is referenced from action-leafref} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modoper-leafref" + ly_cmd "data -t rpc -O $ddir/modoper_leafref_ds.xml $ddir/modoper_leafref_action.xml" +}} + +test data_operational_action_reply_leafref {--operational data is referenced from action-leafref output} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modoper-leafref" + ly_cmd "data -t reply -O $ddir/modoper_leafref_ds.xml $ddir/modoper_leafref_action_reply.xml" +}} + +test data_operational_rpc_leafref {--operational data is referenced from rpc-leafref} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modoper-leafref" + ly_cmd "data -t rpc -O $ddir/modconfig.xml $ddir/modoper_leafref_rpc.xml" +}} + +test data_operational_rpc_reply_leafref {--operational data is referenced from rpc-leafref output} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modoper-leafref" + ly_cmd "data -t reply -O $ddir/modconfig.xml $ddir/modoper_leafref_rpc_reply.xml" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/data_present.test b/tests/yanglint/interactive/data_present.test new file mode 100644 index 0000000..4bba596 --- /dev/null +++ b/tests/yanglint/interactive/data_present.test @@ -0,0 +1,25 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set ddir "$::env(TESTS_DIR)/data" + +test data_present_via_mandatory {validation of mandatory-stmt will pass only with the --present} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf modmandatory" + ly_cmd_err "data $ddir/modleaf.xml" "Mandatory node \"lft\" instance does not exist." + ly_cmd "data -e $ddir/modleaf.xml" +}} + +test data_present_merge {validation with --present and --merge} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf modmandatory moddefault" + ly_cmd_err "data -m $ddir/modleaf.xml $ddir/moddefault.xml" "Mandatory node \"lft\" instance does not exist." + ly_cmd "data -e -m $ddir/modleaf.xml $ddir/moddefault.xml" +}} + +test data_present_merge_invalid {using --present and --merge but data are invalid} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf modmandatory" + ly_cmd_err "data -e -m $ddir/modleaf.xml $ddir/modmandatory_invalid.xml" "Mandatory node \"lft\" instance does not exist." +}} + +cleanupTests diff --git a/tests/yanglint/interactive/data_type.test b/tests/yanglint/interactive/data_type.test new file mode 100644 index 0000000..a442813 --- /dev/null +++ b/tests/yanglint/interactive/data_type.test @@ -0,0 +1,140 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set ddir "$::env(TESTS_DIR)/data" + +test data_type_data {data --type data} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modconfig" + ly_cmd "data -t data $ddir/modconfig.xml" +}} + +test data_type_config {data --type config} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modconfig" + ly_cmd_err "data -t config $ddir/modconfig.xml" "Unexpected data state node \"lff\"" + ly_cmd "data -t config $ddir/modconfig2.xml" +}} + +test data_type_get {data --type get} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleafref" + ly_cmd_err "data -t data $ddir/modleafref2.xml" "Invalid leafref value" + ly_cmd "data -t get $ddir/modleafref2.xml" +}} + +test data_type_getconfig_no_state {No state node for data --type getconfig} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modconfig" + ly_cmd_err "data -t getconfig $ddir/modconfig.xml" "Unexpected data state node \"lff\"" + ly_cmd "data -t getconfig $ddir/modconfig2.xml" +}} + +test data_type_getconfig_parse_only {No validation performed for data --type getconfig} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleafref" + ly_cmd_err "data -t data $ddir/modleafref2.xml" "Invalid leafref value" + ly_cmd "data -t getconfig $ddir/modleafref2.xml" +}} + +test data_type_edit_no_state {No state node for data --type edit} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modconfig" + ly_cmd_err "data -t edit $ddir/modconfig.xml" "Unexpected data state node \"lff\"" + ly_cmd "data -t edit $ddir/modconfig2.xml" +}} + +test data_type_edit_parse_only {No validation performed for data --type edit} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleafref" + ly_cmd_err "data -t data $ddir/modleafref2.xml" "Invalid leafref value" + ly_cmd "data -t edit $ddir/modleafref2.xml" +}} + +test data_type_rpc {Validation of rpc-statement by data --type rpc} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modrpc modleaf" + ly_cmd_err "data -t rpc $ddir/modleaf.xml" "Missing the operation node." + ly_cmd "data -t rpc $ddir/modrpc.xml" +}} + +test data_type_rpc_nc {Validation of rpc-statement by data --type nc-rpc} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modrpc modleaf ietf-netconf" + ly_cmd_err "data -t nc-rpc $ddir/modleaf.xml" "Missing NETCONF <rpc> envelope" + ly_cmd "data -t nc-rpc $ddir/modrpc_nc.xml" +}} + +test data_type_rpc_reply {Validation of rpc-reply by data --type reply} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modrpc modleaf" + ly_cmd_err "data -t rpc $ddir/modleaf.xml" "Missing the operation node." + ly_cmd_wrn "data -t reply -R $ddir/modrpc.xml $ddir/modrpc_reply.xml" "needed only for NETCONF" + ly_cmd "data -t reply $ddir/modrpc_reply.xml" +}} + +test data_type_rpc_reply_nc {Validation of rpc-reply by data --type nc-reply} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modrpc modleaf" + ly_cmd_err "data -t nc-reply -R $ddir/modrpc_nc.xml $ddir/modleaf.xml" "Missing NETCONF <rpc-reply> envelope" + ly_cmd_err "data -t nc-reply $ddir/modrpc_reply_nc.xml" "Missing source RPC" + ly_cmd "data -t nc-reply -R $ddir/modrpc_nc.xml $ddir/modrpc_reply_nc.xml" +}} + +test data_type_rpc_action {Validation of action-statement by data --type rpc} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modaction modleaf" + ly_cmd_err "data -t rpc $ddir/modleaf.xml" "Missing the operation node." + ly_cmd "data -t rpc -O $ddir/modaction_ds.xml $ddir/modaction.xml" +}} + +test data_type_rpc_action_nc {Validation of action-statement by data --type nc-rpc} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modaction modleaf" + ly_cmd_err "data -t nc-rpc $ddir/modleaf.xml" "Missing NETCONF <rpc> envelope" + ly_cmd "data -t nc-rpc -O $ddir/modaction_ds.xml $ddir/modaction_nc.xml" +}} + +test data_type_rpc_action_reply {Validation of action-reply by data --type reply} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modaction modleaf" + ly_cmd_err "data -t rpc $ddir/modleaf.xml" "Missing the operation node." + ly_cmd "data -t reply -O $ddir/modaction_ds.xml $ddir/modaction_reply.xml" +}} + +test data_type_rpc_action_reply_nc {Validation of action-reply by data --type nc-reply} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modaction modleaf" + ly_cmd_err "data -t nc-reply -R $ddir/modaction_nc.xml $ddir/modleaf.xml" "Missing NETCONF <rpc-reply> envelope" + ly_cmd_err "data -t nc-reply $ddir/modaction_reply_nc.xml" "Missing source RPC" + ly_cmd_err "data -t nc-reply -R $ddir/modaction_nc.xml $ddir/modaction_reply_nc.xml" "operational parameter needed" + ly_cmd "data -t nc-reply -O $ddir/modaction_ds.xml -R $ddir/modaction_nc.xml $ddir/modaction_reply_nc.xml" +}} + +test data_type_notif {Validation of notification-statement by data --type notif} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modnotif modleaf" + ly_cmd_err "data -t notif $ddir/modleaf.xml" "Missing the operation node." + ly_cmd "data -t notif $ddir/modnotif2.xml" +}} + +test data_type_notif_nc {Validation of notification-statement by data --type nc-notif} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modnotif modleaf ietf-netconf" + ly_cmd_err "data -t nc-notif $ddir/modleaf.xml" "Missing NETCONF <notification> envelope" + ly_cmd "data -t nc-notif $ddir/modnotif2_nc.xml" +}} + +test data_type_notif_nested {Validation of nested-notification-statement by data --type notif} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modnotif modleaf" + ly_cmd "data -t notif -O $ddir/modnotif_ds.xml $ddir/modnotif.xml" +}} + +test data_type_notif_nested_nc {Validation of nested-notification-statement by data --type nc-notif} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modnotif modleaf ietf-netconf" + ly_cmd_err "data -t nc-notif $ddir/modleaf.xml" "Missing NETCONF <notification> envelope" + ly_cmd "data -t nc-notif -O $ddir/modnotif_ds.xml $ddir/modnotif_nc.xml" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/data_xpath.test b/tests/yanglint/interactive/data_xpath.test new file mode 100644 index 0000000..398cb9f --- /dev/null +++ b/tests/yanglint/interactive/data_xpath.test @@ -0,0 +1,57 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set data "$::env(TESTS_DIR)/data/moddatanodes.xml" + +test data_xpath_empty {--xpath to missing node} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load moddatanodes" + ly_cmd "data -x /moddatanodes:dnc/mis $data" "Empty" +}} + +test data_xpath_leaf {--xpath to leaf node} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load moddatanodes" + ly_cmd "data -x /moddatanodes:dnc/lf $data" "leaf \"lf\" \\(value: \"x\"\\)" +}} + +test data_xpath_leaflist {--xpath to leaf-list node} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load moddatanodes" + set r1 "leaf-list \"lfl\" \\(value: \"1\"\\)" + set r2 "leaf-list \"lfl\" \\(value: \"2\"\\)" + ly_cmd "data -x /moddatanodes:dnc/lfl $data" "$r1\r\n $r2" +}} + +test data_xpath_list {--xpath to list} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load moddatanodes" + set r1 "list \"lt\" \\(\"kalf\": \"ka1\"; \"kblf\": \"kb1\";\\)" + set r2 "list \"lt\" \\(\"kalf\": \"ka2\"; \"kblf\": \"kb2\";\\)" + ly_cmd "data -x /moddatanodes:dnc/con/lt $data" "$r1\r\n $r2" +}} + +test data_xpath_container {--xpath to container} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load moddatanodes" + ly_cmd "data -x /moddatanodes:dnc/con $data" "container \"con\"" +}} + +test data_xpath_wrong_path {--xpath to a non-existent node} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load moddatanodes" + ly_cmd_err "data -x /moddatanodes:dnc/wrng $data" "xpath failed" +}} + +test data_xpath_err_format {--xpath cannot be combined with --format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load moddatanodes" + ly_cmd_err "data -f xml -x /moddatanodes:dnc/lf $data" "option cannot be combined" +}} + +test data_xpath_err_default {--xpath cannot be combined with --default} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load moddatanodes ietf-netconf-with-defaults" + ly_cmd_err "data -d all -x /moddatanodes:dnc/lf $data" "option cannot be combined" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/debug.test b/tests/yanglint/interactive/debug.test new file mode 100644 index 0000000..8a64c92 --- /dev/null +++ b/tests/yanglint/interactive/debug.test @@ -0,0 +1,33 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set mdir $::env(YANG_MODULES_DIR) + +test debug_dict {Check debug message DICT} { +-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body { + ly_cmd "verb debug" + ly_cmd "debug dict" + ly_cmd "load modleaf" "DICT" +}} + +test debug_xpath {Check debug message XPATH} { +-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body { + ly_cmd "verb debug" + ly_cmd "debug xpath" + ly_cmd "load modmust" "XPATH" +}} + +test debug_dep_sets {Check debug message DEPSETS} { +-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body { + ly_cmd "verb debug" + ly_cmd "debug dep-sets" + ly_cmd "load modleaf" "DEPSETS" +}} + +test debug_depsets_xpath {Check debug message DEPSETS and XPATH} { +-setup $ly_setup -cleanup $ly_cleanup -constraints {[yanglint_debug]} -body { + ly_cmd "verb debug" + ly_cmd "debug dep-sets xpath" + ly_cmd "load modmust" "DEPSETS.*XPATH" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/extdata.test b/tests/yanglint/interactive/extdata.test new file mode 100644 index 0000000..e253d1a --- /dev/null +++ b/tests/yanglint/interactive/extdata.test @@ -0,0 +1,63 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set mdir "$::env(YANG_MODULES_DIR)" +set ddir "$::env(TESTS_DIR)/data" + +test extdata_set_clear {Set and clear extdata file} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "extdata" "No file set" + ly_cmd "extdata $ddir/modsm_ctx_ext.xml" + ly_cmd "extdata" "$ddir/modsm_ctx_ext.xml" + ly_cmd "extdata -c" + ly_cmd "extdata" "No file set" +}} + +test extdata_clear_cmd {Clear extdata file by 'clear' command} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "extdata $ddir/modsm_ctx_ext.xml" + ly_cmd "clear" + ly_cmd "extdata" "No file set" +}} + +test extdata_one_only {Only one file for extdata} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd_err "extdata $ddir/modsm_ctx_ext.xml $ddir/modsm_ctx_ext.xml" "Only one file must be entered" +}} + +test extdata_schema_mount_tree {Print tree output of a model with Schema Mount} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -y" + ly_cmd "searchpath $mdir" + ly_cmd "load modsm" + ly_cmd "extdata $ddir/modsm_ctx_ext.xml" + ly_cmd "print -f tree modsm" "--mp root.*--rw lfl/" +}} + +test ext_data_schema_mount_tree_yanglibfile {Print tree output of a model with Schema Mount and --yang-library-file} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -Y $ddir/modsm_ctx_main.xml" + ly_cmd "searchpath $mdir" + ly_cmd "load modsm" + ly_cmd "extdata $ddir/modsm_ctx_ext.xml" + ly_cmd "print -f tree modsm" "--mp root.*--rw lfl/.*--rw msa:alf?" +}} + +test ext_data_schema_mount_xml {Validating and printing mounted data} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -y" + ly_cmd "searchpath $mdir" + ly_cmd "load modsm" + ly_cmd "extdata $ddir/modsm_ctx_ext.xml" + ly_cmd "data -f xml -t config $ddir/modsm.xml" "</lfl>" +}} + +test ext_data_schema_mount_xml_yanglibfile {Validating and printing mounted data with --yang-library-file} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -Y $ddir/modsm_ctx_main.xml" + ly_cmd "searchpath $mdir" + ly_cmd "load modsm" + ly_cmd "extdata $ddir/modsm_ctx_ext.xml" + ly_cmd "data -f xml -t config $ddir/modsm2.xml" "</lfl>.*</alf>" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/feature.test b/tests/yanglint/interactive/feature.test new file mode 100644 index 0000000..84bfa8e --- /dev/null +++ b/tests/yanglint/interactive/feature.test @@ -0,0 +1,37 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +test feature_all_default {Default output of feature --all} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "feature -a" "yang:\r\n\t(none)\r\n\r\nietf-yang-schema-mount:\r\n\t(none)\r\n" -ex +}} + +test feature_all_add_module {Add module with only one feature and call feature --all} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load --feature modfeature:ftr1 modfeature" + ly_cmd "feature -a" "modfeature:\r\n\tftr1 \\(on\\)\r\n\tftr2 \\(off\\)" +}} + +test feature_all_on {Add module with all enabled features and call feature --all} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load --feature modfeature:* modfeature" + ly_cmd "feature -a" "modfeature:\r\n\tftr1 \\(on\\)\r\n\tftr2 \\(on\\)" +}} + +test feature_one_module {Show features for one module} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load ietf-ip" + ly_cmd "feature -f ietf-ip" " -F ietf-ip:ipv4-non-contiguous-netmasks,ipv6-privacy-autoconf" -ex +}} + +test feature_more_modules {Show a mix of modules with and without features} { +-setup $ly_setup -cleanup $ly_cleanup -body { + + set features " -F modfeature:ftr1,ftr2\ +-F modleaf:\ +-F ietf-ip:ipv4-non-contiguous-netmasks,ipv6-privacy-autoconf" + + ly_cmd "load ietf-ip modleaf modfeature" + ly_cmd "feature -f modfeature modleaf ietf-ip" $features -ex +}} + +cleanupTests diff --git a/tests/yanglint/interactive/list.test b/tests/yanglint/interactive/list.test new file mode 100644 index 0000000..ab59a32 --- /dev/null +++ b/tests/yanglint/interactive/list.test @@ -0,0 +1,34 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] +namespace import uti::regex_xml_elements uti::regex_json_pairs + +set modules {ietf-yang-library ietf-inet-types} + +test list_basic {basic test} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "list" "ietf-yang-types" +}} + +test list_format_xml {list --format xml} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -y" + ly_cmd "list -f xml" [regex_xml_elements $modules "name"] +}} + +test list_format_json {list --format json} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -y" + ly_cmd "list -f json" [regex_json_pairs $modules "name"] +}} + +test list_ietf_yang_library {Error due to missing ietf-yang-library} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd_err "list -f xml" "Module \"ietf-yang-library\" is not implemented." +}} + +test list_bad_format {Error due to bad format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "clear -y" + ly_cmd_err "list -f csv" "Unknown output format csv" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/load.test b/tests/yanglint/interactive/load.test new file mode 100644 index 0000000..a95d044 --- /dev/null +++ b/tests/yanglint/interactive/load.test @@ -0,0 +1,45 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +test load_basic {} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleafref" + ly_cmd "list" "I modleafref\r.*I modleaf" +}} + +test load_with_feature {Load module with feature} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load --feature modfeature:ftr2 modfeature" + ly_cmd "feature -a" "modfeature:\r\n\tftr1 \\(off\\)\r\n\tftr2 \\(on\\)" +}} + +test load_make_implemented_once {load --make-implemented} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_ignore "load modmust" + ly_cmd "list" "I modmust\r.*i modleaf" + ly_cmd "clear" + ly_cmd "searchpath $::env(YANG_MODULES_DIR)" + ly_cmd "load -i modmust" + ly_cmd "list" "I modmust\r.*I modleaf" +}} + +test load_make_implemented_twice {load -i -i} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modimp-type" + ly_cmd "list" "I modimp-type\r.*i modtypedef" + ly_cmd "clear" + ly_cmd "searchpath $::env(YANG_MODULES_DIR)" + ly_cmd "load -i -i modimp-type" + ly_cmd "list" "I modimp-type\r.*I modtypedef" +}} + +test load_extended_leafref_enabled {Valid module with --extended-leafref option} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load -X modextleafref" +}} + +test load_extended_leafref_disabled {Expected error if --extended-leafref is not set} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd_err "load modextleafref" "Unexpected XPath token \"FunctionName\"" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/ly.tcl b/tests/yanglint/interactive/ly.tcl new file mode 100644 index 0000000..4c56be4 --- /dev/null +++ b/tests/yanglint/interactive/ly.tcl @@ -0,0 +1,81 @@ +# @brief The main source of functions and variables for testing yanglint in the interactive mode. + +# For testing yanglint. +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/common.tcl" : "../common.tcl"}] +# For testing any interactive tool. +source "$::env(TESTS_DIR)/../tool_i.tcl" + +# The script continues by defining variables and functions specific to the interactive yanglint tool. + +# set the timeout to 5 seconds +set timeout 5 +# prompt of yanglint +set prompt "> " +# turn off dialog between expect and yanglint +log_user 0 +# setting some large terminal width +stty columns 720 + +# default setup for every unit test +variable ly_setup { + spawn $TUT + ly_skip_warnings + # Searchpath is set, so modules can be loaded via the 'load' command. + ly_cmd "searchpath $::env(YANG_MODULES_DIR)" +} + +# default cleanup for every unit test +variable ly_cleanup { + ly_exit +} + +# Skip no dir and/or no history warnings and prompt. +proc ly_skip_warnings {} { + global prompt + expect -re "(YANGLINT.*)*$prompt" {} +} + +# Send command 'cmd' to the process, expect error header and then check output string by 'pattern'. +# Parameter cmd is a string of arguments. +# Parameter pattern is a regex. It must not contain a prompt. +proc ly_cmd_err {cmd pattern} { + global prompt + + send -- "${cmd}\r" + expect -- "${cmd}\r\n" + + expect { + -re "YANGLINT\\\[E\\\]: .*${pattern}.*\r\n${prompt}$" {} + -re "libyang\\\[\[0-9]+\\\]: .*${pattern}.*\r\n${prompt}$" {} + -re "\r\n${prompt}$" { + error "unexpected output:\n$expect_out(buffer)" + } + } +} + +# Send command 'cmd' to the process, expect warning header and then check output string by 'pattern'. +# Parameter cmd is a string of arguments. +# Parameter pattern is a regex. It must not contain a prompt. +proc ly_cmd_wrn {cmd pattern} { + ly_cmd_header $cmd "YANGLINT\\\[W\\\]:" $pattern +} + +# Send 'exit' and wait for eof. +proc ly_exit {} { + send "exit\r" + expect eof +} + +# Check if yanglint is configured as DEBUG. +# Return 1 on success. +proc yanglint_debug {} { + global TUT + # Call non-interactive yanglint with --help. + set output [exec -- $TUT "-h"] + # Find option --debug. + if { [regexp -- "--debug=GROUPS" $output] } { + return 1 + } else { + return 0 + } +} diff --git a/tests/yanglint/interactive/modcwd.yang b/tests/yanglint/interactive/modcwd.yang new file mode 100644 index 0000000..db33e73 --- /dev/null +++ b/tests/yanglint/interactive/modcwd.yang @@ -0,0 +1,4 @@ +module modcwd { + namespace "urn:yanglint:modcwd"; + prefix mc; +} diff --git a/tests/yanglint/interactive/print.test b/tests/yanglint/interactive/print.test new file mode 100644 index 0000000..8b9d740 --- /dev/null +++ b/tests/yanglint/interactive/print.test @@ -0,0 +1,77 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set ipv6_path "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address" + +test print_yang {} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf" + ly_cmd "print -f yang modleaf" "leaf lfl" +}} + +test print_yang_submodule {Print submodule in yang format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modinclude" + ly_cmd "print -f yang modsub" "submodule modsub" +}} + +test print_yin {} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf" + ly_cmd "print -f yin modleaf" "<leaf name=\"lfl\">" +}} + +test print_yin_submodule {Print submodule in yin format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modinclude" + ly_cmd "print -f yin modsub" "<submodule name=\"modsub\"" +}} + +test print_info {} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf" + ly_cmd "print -f info modleaf" "status current" +}} + +test print_info_path {Print subtree in info format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load ietf-ip" + ly_cmd "print -f info -P $ipv6_path" "^list address .* leaf prefix-length" +}} + +test print_info_path_single_node {Print node in info format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load ietf-ip" + ly_cmd "print -f info -q -P $ipv6_path" "^list address .* IPv6 addresses on the interface.\";\r\n\}$" +}} + +test print_tree {} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modleaf" + ly_cmd "print -f tree modleaf" "\\+--rw lfl" +}} + +test print_tree_submodule {Print submodule in tree format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load modinclude" + ly_cmd "print -f tree modsub" "submodule: modsub" +}} + +test print_tree_path {Print subtree in tree format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load ietf-ip" + ly_cmd "print -f tree -P $ipv6_path" "\\+--rw address.*\\+--rw prefix-length" +}} + +test print_tree_path_single_node {Print node in tree format} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load ietf-ip" + ly_cmd "print -f tree -q -P $ipv6_path" "\\+--rw address\\* \\\[ip\\\]$" +}} + +test print_tree_path_single_node_line_length {Print node in the tree format and limit row size} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "load ietf-ip" + ly_cmd "print -f tree -L 20 -q -P $ipv6_path" "\\+--rw address\\*\r\n *\\\[ip\\\]$" +}} + +cleanupTests diff --git a/tests/yanglint/interactive/searchpath.test b/tests/yanglint/interactive/searchpath.test new file mode 100644 index 0000000..3bd6796 --- /dev/null +++ b/tests/yanglint/interactive/searchpath.test @@ -0,0 +1,24 @@ +source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/interactive/ly.tcl" : "ly.tcl"}] + +set mdir $::env(YANG_MODULES_DIR) + +variable ly_setup { + spawn $TUT + ly_skip_warnings +} + +test searchpath_basic {} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "searchpath $mdir" + ly_cmd "searchpath" "$mdir" + ly_cmd "load modleaf" +}} + +test searchpath_clear {searchpath --clear} { +-setup $ly_setup -cleanup $ly_cleanup -body { + ly_cmd "searchpath $mdir" + ly_cmd "searchpath --clear" + ly_cmd_err "load modleaf" "Data model \"modleaf\" not found in local searchdirs" +}} + +cleanupTests |