summaryrefslogtreecommitdiffstats
path: root/tests/yanglint/non-interactive
diff options
context:
space:
mode:
Diffstat (limited to 'tests/yanglint/non-interactive')
-rw-r--r--tests/yanglint/non-interactive/all.tcl15
-rw-r--r--tests/yanglint/non-interactive/data_default.test31
-rw-r--r--tests/yanglint/non-interactive/data_in_format.test18
-rw-r--r--tests/yanglint/non-interactive/data_merge.test28
-rw-r--r--tests/yanglint/non-interactive/data_not_strict.test20
-rw-r--r--tests/yanglint/non-interactive/data_operational.test62
-rw-r--r--tests/yanglint/non-interactive/data_present.test25
-rw-r--r--tests/yanglint/non-interactive/data_type.test107
-rw-r--r--tests/yanglint/non-interactive/data_xpath.test42
-rw-r--r--tests/yanglint/non-interactive/disabled_searchdir.test18
-rw-r--r--tests/yanglint/non-interactive/ext_data.test29
-rw-r--r--tests/yanglint/non-interactive/extended_leafref.test13
-rw-r--r--tests/yanglint/non-interactive/format.test72
-rw-r--r--tests/yanglint/non-interactive/list.test26
-rw-r--r--tests/yanglint/non-interactive/ly.tcl8
-rw-r--r--tests/yanglint/non-interactive/make_implemented.test17
-rw-r--r--tests/yanglint/non-interactive/modcwd.yang4
-rw-r--r--tests/yanglint/non-interactive/path.test9
-rw-r--r--tests/yanglint/non-interactive/yang_library_file.test18
19 files changed, 562 insertions, 0 deletions
diff --git a/tests/yanglint/non-interactive/all.tcl b/tests/yanglint/non-interactive/all.tcl
new file mode 100644
index 0000000..998c03a
--- /dev/null
+++ b/tests/yanglint/non-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)/non-interactive"
+}
+
+tcltest::runAllTests
+exit $exitCode
diff --git a/tests/yanglint/non-interactive/data_default.test b/tests/yanglint/non-interactive/data_default.test
new file mode 100644
index 0000000..be19d72
--- /dev/null
+++ b/tests/yanglint/non-interactive/data_default.test
@@ -0,0 +1,31 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mods "$::env(YANG_MODULES_DIR)/ietf-netconf-with-defaults@2011-06-01.yang $::env(YANG_MODULES_DIR)/moddefault.yang"
+set data "$::env(TESTS_DIR)/data/moddefault.xml"
+
+test data_default_not_set {Print data without --default parameter} {
+ ly_cmd "-f xml $mods $data" "</lf>.*</di>\n</mdc>"
+ ly_cmd "-f json $mods $data" "lf\".*di\"\[^\"]*"
+} {}
+
+test data_default_all {data --default all} {
+ ly_cmd "-d all -f xml $mods $data" "</lf>.*</di>.*</ds>\n</mdc>"
+ ly_cmd "-d all -f json $mods $data" "lf\".*di\".*ds\"\[^\"]*"
+} {}
+
+test data_default_all_tagged {data --default all-tagged} {
+ ly_cmd "-d all-tagged -f xml $mods $data" "</lf>.*<di.*default.*</di>.*<ds.*default.*</ds>\n</mdc>"
+ ly_cmd "-d all-tagged -f json $mods $data" "lf\".*di\".*ds\".*@ds\".*default\"\[^\"]*"
+} {}
+
+test data_default_trim {data --default trim} {
+ ly_cmd "-d trim -f xml $mods $data" "</lf>\n</mdc>"
+ ly_cmd "-d trim -f json $mods $data" "lf\"\[^\"]*"
+} {}
+
+test data_default_implicit_tagged {data --default implicit-tagged} {
+ ly_cmd "-d implicit-tagged -f xml $mods $data" "</lf>.*<di>5</di>.*<ds.*default.*</ds>\n</mdc>"
+ ly_cmd "-d implicit-tagged -f json $mods $data" "lf\".*di\"\[^@]*ds\".*default\"\[^\"]*"
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/data_in_format.test b/tests/yanglint/non-interactive/data_in_format.test
new file mode 100644
index 0000000..f1336dd
--- /dev/null
+++ b/tests/yanglint/non-interactive/data_in_format.test
@@ -0,0 +1,18 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir $::env(YANG_MODULES_DIR)
+set ddir $::env(TESTS_DIR)/data
+
+test data_in_format_xml {--in-format xml} {
+ ly_cmd "-I xml $mdir/modleaf.yang $ddir/modleaf.dxml"
+ ly_cmd_err "-I json $mdir/modleaf.yang $ddir/modleaf.dxml" "Failed to parse"
+ ly_cmd_err "-I lyb $mdir/modleaf.yang $ddir/modleaf.dxml" "Failed to parse"
+} {}
+
+test data_in_format_json {--in-format json} {
+ ly_cmd "-I json $mdir/modleaf.yang $ddir/modleaf.djson"
+ ly_cmd_err "-I xml $mdir/modleaf.yang $ddir/modleaf.djson" "Failed to parse"
+ ly_cmd_err "-I lyb $mdir/modleaf.yang $ddir/modleaf.djson" "Failed to parse"
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/data_merge.test b/tests/yanglint/non-interactive/data_merge.test
new file mode 100644
index 0000000..4ecfcee
--- /dev/null
+++ b/tests/yanglint/non-interactive/data_merge.test
@@ -0,0 +1,28 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir $::env(YANG_MODULES_DIR)
+set ddir $::env(TESTS_DIR)/data
+
+test data_merge_basic {Data is merged and the node is added} {
+ ly_cmd "-m -f xml $mdir/modmerge.yang $ddir/modmerge.xml $ddir/modmerge3.xml" "<en>.*<lm>.*<lf>"
+} {}
+
+test data_merge_validation_failed {Data is merged but validation failed.} {
+ ly_cmd "$mdir/modmerge.yang $ddir/modmerge.xml"
+ ly_cmd "$mdir/modmerge.yang $ddir/modmerge2.xml"
+ ly_cmd "-m $mdir/modmerge.yang $ddir/modmerge2.xml $ddir/modmerge.xml"
+ ly_cmd_err "-m $mdir/modmerge.yang $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} {
+ set wrn1 "option has effect only for"
+ ly_cmd_wrn "-m -t rpc $mdir/modrpc.yang $ddir/modrpc.xml $ddir/modrpc.xml" $wrn1
+ ly_cmd_wrn "-m -t notif $mdir/modnotif.yang $ddir/modnotif2.xml $ddir/modnotif2.xml" $wrn1
+ ly_cmd_wrn "-m -t get $mdir/modconfig.yang $mdir/modleaf.yang $ddir/modleaf.xml $ddir/modconfig.xml" $wrn1
+ ly_cmd_wrn "-m -t getconfig $mdir/modconfig.yang $mdir/modleaf.yang $ddir/modleaf.xml $ddir/modconfig2.xml" $wrn1
+ ly_cmd_wrn "-m -t edit $mdir/modconfig.yang $mdir/modleaf.yang $ddir/modleaf.xml $ddir/modconfig2.xml" $wrn1
+ ly_cmd "-m -t config $mdir/modconfig.yang $mdir/modleaf.yang $ddir/modleaf.xml $ddir/modconfig2.xml"
+ ly_cmd "-m -t data $mdir/modconfig.yang $mdir/modleaf.yang $ddir/modleaf.xml $ddir/modconfig.xml"
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/data_not_strict.test b/tests/yanglint/non-interactive/data_not_strict.test
new file mode 100644
index 0000000..b91eed8
--- /dev/null
+++ b/tests/yanglint/non-interactive/data_not_strict.test
@@ -0,0 +1,20 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir $::env(YANG_MODULES_DIR)
+set ddir $::env(TESTS_DIR)/data
+
+test data_no_strict_basic {} {
+ ly_cmd_err "$ddir/modmandatory.xml $mdir/modleaf.yang" "No module with namespace \"urn:yanglint:modmandatory\" in the context."
+ ly_cmd "-n $ddir/modmandatory.xml $mdir/modleaf.yang"
+} {}
+
+test data_no_strict_invalid_data {validation with --no-strict but data are invalid} {
+ set errmsg "Mandatory node \"lft\" instance does not exist."
+ ly_cmd_err "-n $ddir/modmandatory_invalid.xml $mdir/modmandatory.yang" $errmsg
+} {}
+
+test data_no_strict_ignore_invalid_data {--no-strict ignore invalid data if no schema is provided} {
+ ly_cmd "-f xml -n $ddir/modmandatory_invalid.xml $ddir/modleaf.xml $mdir/modleaf.yang" "modleaf.*</lfl>$"
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/data_operational.test b/tests/yanglint/non-interactive/data_operational.test
new file mode 100644
index 0000000..82e861e
--- /dev/null
+++ b/tests/yanglint/non-interactive/data_operational.test
@@ -0,0 +1,62 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir "$::env(YANG_MODULES_DIR)"
+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} {
+ ly_cmd_err "-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} {
+ ly_cmd_err "-O $ddir/modconfig.xml $mdir/modoper-leafref.yang $ddir/modoper_leafref_notif.xml" $err1
+} {}
+
+test data_operational_missing {--operational is omitted and the datastore contents is in the data file} {
+ ly_cmd_err "$mdir/modoper-leafref.yang $ddir/modoper_leafref_notif_err.xml" "Failed to parse input data file"
+} {}
+
+test data_operational_wrong_type {data are not defined as an operation} {
+ ly_cmd_wrn "-t data -O $ddir/modconfig.xml $mdir/modleaf.yang $ddir/modleaf.xml" $err1
+} {}
+
+test data_operational_datastore_with_unknown_data {unknown data are ignored} {
+ ly_cmd "-t rpc -O $ddir/modmandatory_invalid.xml $mdir/modrpc.yang $ddir/modrpc.xml"
+} {}
+
+test data_operational_empty_datastore {datastore is considered empty because it contains unknown data} {
+ ly_cmd "-t rpc -O $ddir/modmandatory_invalid.xml $mdir/modrpc.yang $ddir/modrpc.xml"
+ set msg "parent \"/modnotif:con\" not found in the operational data"
+ ly_cmd_err "-t notif -O $ddir/modmandatory_invalid.xml $mdir/modnotif.yang $ddir/modnotif.xml" $msg
+} {}
+
+test data_operational_notif_leafref {--operational data is referenced from notification-leafref} {
+ ly_cmd "-t notif -O $ddir/modconfig.xml $mdir/modoper-leafref.yang $ddir/modoper_leafref_notif.xml"
+} {}
+
+test data_operational_nested_notif_leafref {--operational data is referenced from nested-notification-leafref} {
+ ly_cmd "-t notif -O $ddir/modoper_leafref_ds.xml $mdir/modoper-leafref.yang $ddir/modoper_leafref_notif2.xml"
+} {}
+
+test data_operational_nested_notif_parent_missing {--operational data are invalid due to missing parent node} {
+ set msg "klf='key_val']\" not found in the operational data"
+ ly_cmd_err "-t notif -O $ddir/modconfig.xml $mdir/modoper-leafref.yang $ddir/modoper_leafref_notif2.xml" $msg
+} {}
+
+test data_operational_action_leafref {--operational data is referenced from action-leafref} {
+ ly_cmd "-t rpc -O $ddir/modoper_leafref_ds.xml $mdir/modoper-leafref.yang $ddir/modoper_leafref_action.xml"
+} {}
+
+test data_operational_action_reply_leafref {--operational data is referenced from action-leafref output} {
+ ly_cmd "-t reply -O $ddir/modoper_leafref_ds.xml $mdir/modoper-leafref.yang $ddir/modoper_leafref_action_reply.xml"
+} {}
+
+test data_operational_rpc_leafref {--operational data is referenced from rpc-leafref} {
+ ly_cmd "-t rpc -O $ddir/modconfig.xml $mdir/modoper-leafref.yang $ddir/modoper_leafref_rpc.xml"
+} {}
+
+test data_operational_rpc_reply_leafref {--operational data is referenced from rpc-leafref output} {
+ ly_cmd "-t reply -O $ddir/modconfig.xml $mdir/modoper-leafref.yang $ddir/modoper_leafref_rpc_reply.xml"
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/data_present.test b/tests/yanglint/non-interactive/data_present.test
new file mode 100644
index 0000000..81aac14
--- /dev/null
+++ b/tests/yanglint/non-interactive/data_present.test
@@ -0,0 +1,25 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir $::env(YANG_MODULES_DIR)
+set ddir $::env(TESTS_DIR)/data
+
+test data_present_via_mandatory {validation of mandatory-stmt will pass only with the --present} {
+ set mods "$mdir/modleaf.yang $mdir/modmandatory.yang"
+ ly_cmd_err "$ddir/modleaf.xml $mods" "Mandatory node \"lft\" instance does not exist."
+ ly_cmd "-e $ddir/modleaf.xml $mods"
+} {}
+
+test data_present_merge {validation with --present and --merge} {
+ set mods "$mdir/modleaf.yang $mdir/modmandatory.yang $mdir/moddefault.yang"
+ set data "$ddir/modleaf.xml $ddir/moddefault.xml"
+ ly_cmd_err "-m $data $mods" "Mandatory node \"lft\" instance does not exist."
+ ly_cmd "-m -e $data $mods"
+} {}
+
+test data_present_merge_invalid {using --present and --merge but data are invalid} {
+ set mods "$mdir/modleaf.yang $mdir/modmandatory.yang"
+ set data "$ddir/modleaf.xml $ddir/modmandatory_invalid.xml"
+ ly_cmd_err "-e -m $data $mods" "Mandatory node \"lft\" instance does not exist."
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/data_type.test b/tests/yanglint/non-interactive/data_type.test
new file mode 100644
index 0000000..e3691d7
--- /dev/null
+++ b/tests/yanglint/non-interactive/data_type.test
@@ -0,0 +1,107 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir "$::env(YANG_MODULES_DIR)"
+set ddir "$::env(TESTS_DIR)/data"
+set modnc "$mdir/ietf-netconf@2011-06-01.yang"
+
+test data_type_data {data --type data} {
+ ly_cmd "-t data $mdir/modconfig.yang $ddir/modconfig.xml"
+} {}
+
+test data_type_config {data --type config} {
+ ly_cmd_err "-t config $mdir/modconfig.yang $ddir/modconfig.xml" "Unexpected data state node \"lff\""
+ ly_cmd "-t config $mdir/modconfig.yang $ddir/modconfig2.xml"
+} {}
+
+test data_type_get {data --type get} {
+ ly_cmd_err "-t data $mdir/modleafref.yang $ddir/modleafref2.xml" "Invalid leafref value"
+ ly_cmd "-t get $mdir/modleafref.yang $ddir/modleafref2.xml"
+} {}
+
+test data_type_getconfig_no_state {No state node for data --type getconfig} {
+ ly_cmd_err "-t getconfig $mdir/modconfig.yang $ddir/modconfig.xml" "Unexpected data state node \"lff\""
+ ly_cmd "-t getconfig $mdir/modconfig.yang $ddir/modconfig2.xml"
+} {}
+
+test data_type_getconfig_parse_only {No validation performed for data --type getconfig} {
+ ly_cmd_err "-t data $mdir/modleafref.yang $ddir/modleafref2.xml" "Invalid leafref value"
+ ly_cmd "-t getconfig $mdir/modleafref.yang $ddir/modleafref2.xml"
+} {}
+
+test data_type_edit_no_state {No state node for data --type edit} {
+ ly_cmd_err "-t edit $mdir/modconfig.yang $ddir/modconfig.xml" "Unexpected data state node \"lff\""
+ ly_cmd "-t edit $mdir/modconfig.yang $ddir/modconfig2.xml"
+} {}
+
+test data_type_edit_parse_only {No validation performed for data --type edit} {
+ ly_cmd_err "-t data $mdir/modleafref.yang $ddir/modleafref2.xml" "Invalid leafref value"
+ ly_cmd "-t edit $mdir/modleafref.yang $ddir/modleafref2.xml"
+} {}
+
+test data_type_rpc {Validation of rpc-statement by data --type rpc} {
+ ly_cmd_err "-t rpc $mdir/modleaf.yang $ddir/modleaf.xml" "Missing the operation node."
+ ly_cmd "-t rpc $mdir/modrpc.yang $ddir/modrpc.xml"
+} {}
+
+test data_type_rpc_nc {Validation of rpc-statement by data --type nc-rpc} {
+ ly_cmd_err "-t nc-rpc $modnc $mdir/modleaf.yang $ddir/modleaf.xml" "Missing NETCONF <rpc> envelope"
+ ly_cmd "-t nc-rpc $modnc $mdir/modrpc.yang $ddir/modrpc_nc.xml"
+} {}
+
+test data_type_rpc_reply {Validation of rpc-reply by data --type reply} {
+ ly_cmd_err "-t rpc $mdir/modleaf.yang $ddir/modleaf.xml" "Missing the operation node."
+ ly_cmd_wrn "-t reply -R $ddir/modrpc.xml $mdir/modrpc.yang $ddir/modrpc_reply.xml" "needed only for NETCONF"
+ ly_cmd "-t reply $mdir/modrpc.yang $ddir/modrpc_reply.xml"
+} {}
+
+test data_type_rpc_reply_nc {Validation of rpc-reply by data --type nc-reply} {
+ set err1 "Missing NETCONF <rpc-reply> envelope"
+ ly_cmd_err "-t nc-reply -R $ddir/modrpc_nc.xml $mdir/modrpc.yang $mdir/modleaf.yang $ddir/modleaf.xml" $err1
+ ly_cmd_err "-t nc-reply $mdir/modrpc.yang $ddir/modrpc_reply_nc.xml" "Missing source RPC"
+ ly_cmd "-t nc-reply -R $ddir/modrpc_nc.xml $mdir/modrpc.yang $ddir/modrpc_reply_nc.xml"
+} {}
+
+test data_type_rpc_action {Validation of action-statement by data --type rpc} {
+ ly_cmd_err "-t rpc $mdir/modleaf.yang $ddir/modleaf.xml" "Missing the operation node."
+ ly_cmd "-t rpc -O $ddir/modaction_ds.xml $mdir/modaction.yang $ddir/modaction.xml"
+} {}
+
+test data_type_rpc_action_nc {Validation of action-statement by data --type nc-rpc} {
+ ly_cmd_err "-t nc-rpc $mdir/modleaf.yang $ddir/modleaf.xml" "Missing NETCONF <rpc> envelope"
+ ly_cmd "-t nc-rpc -O $ddir/modaction_ds.xml $mdir/modaction.yang $ddir/modaction_nc.xml"
+} {}
+
+test data_type_rpc_action_reply {Validation of action-reply by data --type reply} {
+ ly_cmd_err "-t rpc $mdir/modleaf.yang $ddir/modleaf.xml" "Missing the operation node."
+ ly_cmd "-t reply -O $ddir/modaction_ds.xml $mdir/modaction.yang $ddir/modaction_reply.xml"
+} {}
+
+test data_type_rpc_action_reply_nc {Validation of action-reply by data --type nc-reply} {
+ set err1 "Missing NETCONF <rpc-reply> envelope"
+ set err2 "operational parameter needed"
+ ly_cmd_err "-t nc-reply -R $ddir/modaction_nc.xml $mdir/modaction.yang $mdir/modleaf.yang $ddir/modleaf.xml" $err1
+ ly_cmd_err "-t nc-reply $mdir/modaction.yang $ddir/modaction_reply_nc.xml" "Missing source RPC"
+ ly_cmd_err "-t nc-reply -R $ddir/modaction_nc.xml $mdir/modaction.yang $ddir/modaction_reply_nc.xml" $err2
+ ly_cmd "-t nc-reply -O $ddir/modaction_ds.xml -R $ddir/modaction_nc.xml $mdir/modaction.yang $ddir/modaction_reply_nc.xml"
+} {}
+
+test data_type_notif {Validation of notification-statement by data --type notif} {
+ ly_cmd_err "-t notif $mdir/modleaf.yang $ddir/modleaf.xml" "Missing the operation node."
+ ly_cmd "-t notif $mdir/modnotif.yang $ddir/modnotif2.xml"
+} {}
+
+test data_type_notif_nc {Validation of notification-statement by data --type nc-notif} {
+ ly_cmd_err "-t nc-notif $modnc $mdir/modleaf.yang $ddir/modleaf.xml" "Missing NETCONF <notification> envelope"
+ ly_cmd "-t nc-notif $modnc $mdir/modnotif.yang $ddir/modnotif2_nc.xml"
+} {}
+
+test data_type_notif_nested {Validation of nested-notification-statement by data --type notif} {
+ ly_cmd "-t notif -O $ddir/modnotif_ds.xml $mdir/modnotif.yang $ddir/modnotif.xml"
+} {}
+
+test data_type_notif_nested_nc {Validation of nested-notification-statement by data --type nc-notif} {
+ ly_cmd_err "-t nc-notif $modnc $mdir/modleaf.yang $ddir/modleaf.xml" "Missing NETCONF <notification> envelope"
+ ly_cmd "-t nc-notif -O $ddir/modnotif_ds.xml $modnc $mdir/modnotif.yang $ddir/modnotif_nc.xml"
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/data_xpath.test b/tests/yanglint/non-interactive/data_xpath.test
new file mode 100644
index 0000000..1d96106
--- /dev/null
+++ b/tests/yanglint/non-interactive/data_xpath.test
@@ -0,0 +1,42 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mod "$::env(YANG_MODULES_DIR)/moddatanodes.yang"
+set data "$::env(TESTS_DIR)/data/moddatanodes.xml"
+
+test data_xpath_empty {--data-path to missing node} {
+ ly_cmd "-E /moddatanodes:dnc/mis $mod $data" "Empty"
+} {}
+
+test data_xpath_leaf {--xpath to leaf node} {
+ ly_cmd "-E /moddatanodes:dnc/lf $mod $data" "leaf \"lf\" \\(value: \"x\"\\)"
+} {}
+
+test data_xpath_leaflist {--xpath to leaf-list node} {
+ set r1 "leaf-list \"lfl\" \\(value: \"1\"\\)"
+ set r2 "leaf-list \"lfl\" \\(value: \"2\"\\)"
+ ly_cmd "-E /moddatanodes:dnc/lfl $mod $data" "$r1\n $r2"
+} {}
+
+test data_xpath_list {--xpath to list} {
+ set r1 "list \"lt\" \\(\"kalf\": \"ka1\"; \"kblf\": \"kb1\";\\)"
+ set r2 "list \"lt\" \\(\"kalf\": \"ka2\"; \"kblf\": \"kb2\";\\)"
+ ly_cmd "-E /moddatanodes:dnc/con/lt $mod $data" "$r1\n $r2"
+} {}
+
+test data_xpath_container {--xpath to container} {
+ ly_cmd "-E /moddatanodes:dnc/con $mod $data" "container \"con\""
+} {}
+
+test data_xpath_wrong_path {--xpath to a non-existent node} {
+ ly_cmd_err "-E /moddatanodes:dnc/wrng $mod $data" "xpath failed"
+} {}
+
+test data_xpath_err_format {--xpath cannot be combined with --format} {
+ ly_cmd_err "-f xml -E /moddatanodes:dnc/lf $mod $data" "option cannot be combined"
+} {}
+
+test data_xpath_err_default {--xpath cannot be combined with --default} {
+ ly_cmd_err "-d all -E /moddatanodes:dnc/lf $mod $data" "option cannot be combined"
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/disabled_searchdir.test b/tests/yanglint/non-interactive/disabled_searchdir.test
new file mode 100644
index 0000000..49fe13e
--- /dev/null
+++ b/tests/yanglint/non-interactive/disabled_searchdir.test
@@ -0,0 +1,18 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir $env(YANG_MODULES_DIR)
+
+# Test should be skipped if called by ctest.
+test disable_searchdir_once {Unsuccessfully imports module due to disabled cwd searching} {
+-constraints {!ctest} -body {
+ ly_cmd "$mdir/modimp-cwd.yang"
+ ly_cmd_err "-D $mdir/modimp-cwd.yang" "not found in local searchdirs"
+}}
+
+test disable_searchdir_twice {Unsuccessfully imports module due to -D -D} {
+ ly_cmd "$mdir/ietf-ip.yang"
+ ly_cmd_err "-D -D $mdir/ietf-ip.yang" "Loading \"ietf-interfaces\" module failed."
+} {}
+
+cleanupTests
+
diff --git a/tests/yanglint/non-interactive/ext_data.test b/tests/yanglint/non-interactive/ext_data.test
new file mode 100644
index 0000000..d4e3c44
--- /dev/null
+++ b/tests/yanglint/non-interactive/ext_data.test
@@ -0,0 +1,29 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir "$::env(YANG_MODULES_DIR)"
+set ddir "$::env(TESTS_DIR)/data"
+
+test ext_data_schema_mount_tree {Print tree output of a model with Schema Mount} {
+ # mounting node lfl from modleaf.yang into modsm.yang
+ set out1 "--mp root.*--rw lfl/"
+ ly_cmd "-f tree -p $mdir -y -x $ddir/modsm_ctx_ext.xml $mdir/modsm.yang" $out1
+} {}
+
+test ext_data_schema_mount_tree_yanglibfile {Print tree output of a model with Schema Mount and --yang-library-file} {
+ # yang-library-file context contains an augment node 'alf' for modsm
+ set out1 "--mp root.*--rw lfl/.*--rw msa:alf?"
+ ly_cmd "-f tree -p $mdir -Y $ddir/modsm_ctx_main.xml -x $ddir/modsm_ctx_ext.xml $mdir/modsm.yang" $out1
+} {}
+
+test ext_data_schema_mount_xml {Validating and printing mounted data} {
+ ly_cmd "-f xml -t config -p $mdir -y -x $ddir/modsm_ctx_ext.xml $mdir/modsm.yang $ddir/modsm.xml" "</lfl>"
+} {}
+
+test ext_data_schema_mount_xml_yanglibfile {Validating and printing mounted data with --yang-library-file} {
+ set yanglibfile "$ddir/modsm_ctx_main.xml"
+ set extdata "$ddir/modsm_ctx_ext.xml"
+ set out1 "</lfl>.*</alf>"
+ ly_cmd "-f xml -t config -p $mdir -Y $yanglibfile -x $extdata $mdir/modsm.yang $ddir/modsm2.xml" $out1
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/extended_leafref.test b/tests/yanglint/non-interactive/extended_leafref.test
new file mode 100644
index 0000000..5e1a90e
--- /dev/null
+++ b/tests/yanglint/non-interactive/extended_leafref.test
@@ -0,0 +1,13 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir $::env(YANG_MODULES_DIR)
+
+test extended_leafref_enabled {Valid module with --extended-leafref option} {
+ ly_cmd "-X $mdir/modextleafref.yang"
+} {}
+
+test extended_leafref_disabled {Expected error if --extended-leafref is not set} {
+ ly_cmd_err "$mdir/modextleafref.yang" "Unexpected XPath token \"FunctionName\""
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/format.test b/tests/yanglint/non-interactive/format.test
new file mode 100644
index 0000000..8df5544
--- /dev/null
+++ b/tests/yanglint/non-interactive/format.test
@@ -0,0 +1,72 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir $::env(YANG_MODULES_DIR)
+set ddir $::env(TESTS_DIR)/data
+set ipv6_path "/ietf-interfaces:interfaces/interface/ietf-ip:ipv6/address"
+
+test format_yang {} {
+ ly_cmd "-f yang $mdir/modleaf.yang" "leaf lfl"
+} {}
+
+test format_yang_submodule {Print submodule in yang format} {
+ ly_cmd "-s modsub -f yang $mdir/modinclude.yang" "submodule modsub"
+} {}
+
+test format_yin {} {
+ ly_cmd "-f yin $mdir/modleaf.yang" "<leaf name=\"lfl\">"
+} {}
+
+test format_yin_submodule {Print submodule in yin format} {
+ ly_cmd "-s modsub -f yin $mdir/modinclude.yang" "<submodule name=\"modsub\""
+} {}
+
+test format_info {} {
+ ly_cmd "-f info $mdir/modleaf.yang" "status current"
+} {}
+
+test format_tree {} {
+ ly_cmd "-f tree $mdir/modleaf.yang" "\\+--rw lfl"
+} {}
+
+test format_data_xml {Print data in xml format} {
+ ly_cmd "-f xml $mdir/modleaf.yang $ddir/modleaf.xml" "<lfl xmlns=\"urn:yanglint:modleaf\">7</lfl>"
+} {}
+
+test format_data_json {Print data in json format} {
+ ly_cmd "-f json $mdir/modleaf.yang $ddir/modleaf.xml" "{\n \"modleaf:lfl\": 7\n}"
+} {}
+
+test format_data_lyb_err {Printing in LYB format: expect error due to missing parameter} {
+ ly_cmd_err "-f lyb $mdir/modleaf.yang $ddir/modleaf.xml" "The LYB format requires the -o"
+} {}
+
+test format_tree_submodule {Print submodule in tree format} {
+ ly_cmd "-s modsub -f tree $mdir/modinclude.yang" "submodule: modsub"
+} {}
+
+test format_tree_path {Print subtree in tree format} {
+ ly_cmd "-f tree -P $ipv6_path $mdir/ietf-ip.yang" "\\+--rw address.*\\+--rw prefix-length"
+} {}
+
+test format_tree_path_single_node {Print node in tree format} {
+ ly_cmd "-f tree -q -P $ipv6_path $mdir/ietf-ip.yang" "\\+--rw address\\* \\\[ip\\\]$"
+} {}
+
+test format_tree_path_single_node_line_length {Print node in the tree format and limit row size} {
+ ly_cmd "-f tree -L 20 -q -P $ipv6_path $mdir/ietf-ip.yang" "\\+--rw address\\*\n *\\\[ip\\\]$"
+} {}
+
+test format_feature_param_one_module {Show features for one module} {
+ ly_cmd "-f feature-param $mdir/ietf-ip.yang" " -F ietf-ip:ipv4-non-contiguous-netmasks,ipv6-privacy-autoconf" -ex
+} {}
+
+test format_feature_param_more_modules {Show a mix of modules with and without features} {
+
+ set features " -F modfeature:ftr1,ftr2\
+-F modleaf:\
+-F ietf-ip:ipv4-non-contiguous-netmasks,ipv6-privacy-autoconf"
+
+ ly_cmd "-f feature-param $mdir/modfeature.yang $mdir/modleaf.yang $mdir/ietf-ip.yang" $features -ex
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/list.test b/tests/yanglint/non-interactive/list.test
new file mode 100644
index 0000000..626d9a1
--- /dev/null
+++ b/tests/yanglint/non-interactive/list.test
@@ -0,0 +1,26 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-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 {} {
+ ly_cmd "-l" "ietf-yang-types"
+} {}
+
+test list_format_xml {list --format xml} {
+ ly_cmd "-y -f xml -l" [regex_xml_elements $modules "name"]
+} {}
+
+test list_format_json {list --format json} {
+ ly_cmd "-y -f json -l" [regex_json_pairs $modules "name"]
+} {}
+
+test list_ietf_yang_library {Error due to missing ietf-yang-library} {
+ ly_cmd_err "-f xml -l" "Module \"ietf-yang-library\" is not implemented."
+} {}
+
+test list_bad_format {Error due to bad format} {
+ ly_cmd_err "-f csv -l" "Unknown output format csv"
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/ly.tcl b/tests/yanglint/non-interactive/ly.tcl
new file mode 100644
index 0000000..f6bb2c7
--- /dev/null
+++ b/tests/yanglint/non-interactive/ly.tcl
@@ -0,0 +1,8 @@
+# @brief The main source of functions and variables for testing yanglint in the non-interactive mode.
+
+# For testing yanglint.
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/common.tcl" : "../common.tcl"}]
+# For testing any non-interactive tool.
+source "$::env(TESTS_DIR)/../tool_ni.tcl"
+
+# The script continues by defining variables and functions specific to the non-interactive yanglint tool.
diff --git a/tests/yanglint/non-interactive/make_implemented.test b/tests/yanglint/non-interactive/make_implemented.test
new file mode 100644
index 0000000..40cead9
--- /dev/null
+++ b/tests/yanglint/non-interactive/make_implemented.test
@@ -0,0 +1,17 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir $::env(YANG_MODULES_DIR)
+
+test make_impl_no_set {Import while --make-implemented is not set} {
+ ly_cmd "-l $mdir/modleafref.yang" "I modleafref\n.*I modleaf"
+} {}
+
+test make_impl_set_once {--make-implemented} {
+ ly_cmd "-l -i $mdir/modmust.yang" "I modmust\n.*I modleaf"
+} {}
+
+test make_impl_set_twice {-i -i} {
+ ly_cmd "-l -i -i $mdir/modimp-type.yang" "I modimp-type\n.*I modtypedef"
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/modcwd.yang b/tests/yanglint/non-interactive/modcwd.yang
new file mode 100644
index 0000000..db33e73
--- /dev/null
+++ b/tests/yanglint/non-interactive/modcwd.yang
@@ -0,0 +1,4 @@
+module modcwd {
+ namespace "urn:yanglint:modcwd";
+ prefix mc;
+}
diff --git a/tests/yanglint/non-interactive/path.test b/tests/yanglint/non-interactive/path.test
new file mode 100644
index 0000000..bf915ff
--- /dev/null
+++ b/tests/yanglint/non-interactive/path.test
@@ -0,0 +1,9 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir $env(YANG_MODULES_DIR)
+
+test path_basic {} {
+ ly_cmd "-p $::env(TESTS_DIR)/data $::env(YANG_MODULES_DIR)/modimp-path.yang"
+} {}
+
+cleanupTests
diff --git a/tests/yanglint/non-interactive/yang_library_file.test b/tests/yanglint/non-interactive/yang_library_file.test
new file mode 100644
index 0000000..bd95978
--- /dev/null
+++ b/tests/yanglint/non-interactive/yang_library_file.test
@@ -0,0 +1,18 @@
+source [expr {[info exists ::env(TESTS_DIR)] ? "$env(TESTS_DIR)/non-interactive/ly.tcl" : "ly.tcl"}]
+
+set mdir "$::env(YANG_MODULES_DIR)"
+set ddir "$::env(TESTS_DIR)/data"
+
+test ylf_list {apply --yang-library-file and check result by --list} {
+ ly_cmd "-Y $ddir/modimp_type_ctx.xml -p $mdir -l" "I modimp-type.*i modtypedef"
+} {}
+
+test ylf_make_implemented {apply --yang-library-file and --make-implemented} {
+ ly_cmd "-Y $ddir/modimp_type_ctx.xml -p $mdir -i -i -l" "I modimp-type.*I modtypedef"
+} {}
+
+test ylf_augment_ctx {Setup context by yang-library-file and augment module} {
+ ly_cmd "-Y $ddir/modconfig_ctx.xml -p $mdir -f tree $mdir/modconfig.yang $mdir/modconfig-augment.yang" "mca:alf"
+} {}
+
+cleanupTests