aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2013-09-06 16:52:00 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2013-09-08 10:49:52 +0200
commit0c987bd83b2b23f3f125c74f4a653c2fd2ae8c92 (patch)
tree0b87b424c5a44bc5f6d4655bc5987084270621fd
parent7eed0538ae79394a10ac9667a798237457ac2373 (diff)
vty: Add vty_install_default() and use for the vty nodes
This adds the vty_install_default() function that is basically the install_default() function plus the registration of the commands 'exit' and 'end'. The latter is only provided in subnodes of ENABLED_NODE and CONFIG_NONE. The VTY test program is extended to check these commands. Ticket: OW#952
-rw-r--r--include/osmocom/vty/command.h5
-rw-r--r--src/vty/command.c18
-rw-r--r--src/vty/logging_vty.c3
-rw-r--r--src/vty/vty.c2
-rw-r--r--tests/vty/vty_test.c124
-rw-r--r--tests/vty/vty_test.ok43
6 files changed, 188 insertions, 7 deletions
diff --git a/include/osmocom/vty/command.h b/include/osmocom/vty/command.h
index 8fbb482..b3b3029 100644
--- a/include/osmocom/vty/command.h
+++ b/include/osmocom/vty/command.h
@@ -340,6 +340,11 @@ void install_element(enum node_type, struct cmd_element *);
void install_element_ve(struct cmd_element *cmd);
void sort_node(void);
+/* This is similar to install_default() but it also creates
+ * 'exit' and 'end' commands.
+ */
+void vty_install_default(enum node_type);
+
/* Concatenates argv[shift] through argv[argc-1] into a single NUL-terminated
string with a space between each element (allocated using
XMALLOC(MTYPE_TMP)). Returns NULL if shift >= argc. */
diff --git a/src/vty/command.c b/src/vty/command.c
index 3892ddd..df2ffea 100644
--- a/src/vty/command.c
+++ b/src/vty/command.c
@@ -3302,6 +3302,18 @@ void install_default(enum node_type node)
install_element(node, &show_running_config_cmd);
}
+void vty_install_default(enum node_type node)
+{
+ install_default(node);
+
+ install_element(node, &config_exit_cmd);
+
+ if (node >= CONFIG_NODE) {
+ /* It's not a top node. */
+ install_element(node, &config_end_cmd);
+ }
+}
+
/**
* \brief Write the current running config to a given file
* \param[in] vty the vty of the code
@@ -3380,8 +3392,7 @@ void cmd_init(int terminal)
}
if (terminal) {
- install_element(ENABLE_NODE, &config_exit_cmd);
- install_default(ENABLE_NODE);
+ vty_install_default(ENABLE_NODE);
install_element(ENABLE_NODE, &config_disable_cmd);
install_element(ENABLE_NODE, &config_terminal_cmd);
install_element (ENABLE_NODE, &copy_runningconfig_startupconfig_cmd);
@@ -3395,8 +3406,7 @@ void cmd_init(int terminal)
install_element(ENABLE_NODE, &config_terminal_no_length_cmd);
install_element(ENABLE_NODE, &echo_cmd);
- install_default(CONFIG_NODE);
- install_element(CONFIG_NODE, &config_exit_cmd);
+ vty_install_default(CONFIG_NODE);
}
install_element(CONFIG_NODE, &hostname_cmd);
diff --git a/src/vty/logging_vty.c b/src/vty/logging_vty.c
index e17c7a8..64e49d7 100644
--- a/src/vty/logging_vty.c
+++ b/src/vty/logging_vty.c
@@ -677,8 +677,7 @@ void logging_vty_add_cmds(const struct log_info *cat)
install_element_ve(&show_alarms_cmd);
install_node(&cfg_log_node, config_write_log);
- install_default(CFG_LOG_NODE);
- install_element(CFG_LOG_NODE, &config_end_cmd);
+ vty_install_default(CFG_LOG_NODE);
install_element(CFG_LOG_NODE, &logging_fltr_all_cmd);
install_element(CFG_LOG_NODE, &logging_use_clr_cmd);
install_element(CFG_LOG_NODE, &logging_prnt_timestamp_cmd);
diff --git a/src/vty/vty.c b/src/vty/vty.c
index 696766a..8bfc35c 100644
--- a/src/vty/vty.c
+++ b/src/vty/vty.c
@@ -1753,7 +1753,7 @@ void vty_init(struct vty_app_info *app_info)
install_element(ENABLE_NODE, &terminal_monitor_cmd);
install_element(ENABLE_NODE, &terminal_no_monitor_cmd);
- install_default(VTY_NODE);
+ vty_install_default(VTY_NODE);
install_element(VTY_NODE, &vty_login_cmd);
install_element(VTY_NODE, &no_vty_login_cmd);
}
diff --git a/tests/vty/vty_test.c b/tests/vty/vty_test.c
index 2a9be84..e54a205 100644
--- a/tests/vty/vty_test.c
+++ b/tests/vty/vty_test.c
@@ -20,10 +20,19 @@
#include <stdio.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
#include <osmocom/core/talloc.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/utils.h>
#include <osmocom/vty/misc.h>
+#include <osmocom/vty/vty.h>
+#include <osmocom/vty/command.h>
+#include <osmocom/vty/buffer.h>
+
+static enum event last_vty_connection_event = -1;
static void test_cmd_string_from_valstr(void)
{
@@ -43,9 +52,124 @@ static void test_cmd_string_from_valstr(void)
talloc_free (cmd);
}
+static int do_vty_command(struct vty *vty, const char *cmd)
+{
+ vector vline;
+ int ret;
+
+ printf("Going to execute '%s'\n", cmd);
+ vline = cmd_make_strvec(cmd);
+ ret = cmd_execute_command(vline, vty, NULL, 0);
+ cmd_free_strvec(vline);
+ printf("Returned: %d, Current node: %d '%s'\n", ret, vty->node, cmd_prompt(vty->node));
+ return ret;
+}
+
+/* Override the implementation from telnet_interface.c */
+void vty_event(enum event event, int sock, struct vty *vty)
+{
+ last_vty_connection_event = event;
+
+ fprintf(stderr, "Got VTY event: %d\n", event);
+}
+
+static void test_node_tree_structure(void)
+{
+ struct vty_app_info vty_info = {
+ .name = "VtyTest",
+ .version = 0,
+ .go_parent_cb = NULL,
+ .is_config_node = NULL,
+ };
+
+ const struct log_info_cat default_categories[] = {};
+
+ const struct log_info log_info = {
+ .cat = default_categories,
+ .num_cat = ARRAY_SIZE(default_categories),
+ };
+
+ struct vty *vty;
+ vector vline;
+ int sock[2];
+
+ printf("Going to test VTY node tree structure\n");
+
+ /* Fake logging. */
+ osmo_init_logging(&log_info);
+
+ vty_init(&vty_info);
+
+ logging_vty_add_cmds(&log_info);
+
+ /* Fake connection. */
+ socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+
+ vty = vty_create(sock[0], NULL);
+
+ OSMO_ASSERT(vty != NULL);
+
+ OSMO_ASSERT(do_vty_command(vty, "enable") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == ENABLE_NODE);
+
+ OSMO_ASSERT(do_vty_command(vty, "configure terminal") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == CONFIG_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "exit") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == ENABLE_NODE);
+
+ OSMO_ASSERT(do_vty_command(vty, "configure terminal") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == CONFIG_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "end") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == ENABLE_NODE);
+
+ OSMO_ASSERT(do_vty_command(vty, "configure terminal") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == CONFIG_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "log stderr") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == CFG_LOG_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "exit") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == CONFIG_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "log stderr") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == CFG_LOG_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "end") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == ENABLE_NODE);
+
+ OSMO_ASSERT(do_vty_command(vty, "configure terminal") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == CONFIG_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "line vty") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == VTY_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "exit") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == CONFIG_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "line vty") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == VTY_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "end") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == ENABLE_NODE);
+
+
+ /* Check searching the parents nodes for matching commands. */
+ OSMO_ASSERT(do_vty_command(vty, "configure terminal") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == CONFIG_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "log stderr") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == CFG_LOG_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "line vty") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == VTY_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "log stderr") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == CFG_LOG_NODE);
+ OSMO_ASSERT(do_vty_command(vty, "end") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == ENABLE_NODE);
+
+ /* Check for final 'exit' (connection close). */
+ OSMO_ASSERT(do_vty_command(vty, "exit") == CMD_SUCCESS);
+ OSMO_ASSERT(vty->node == ENABLE_NODE);
+ OSMO_ASSERT(vty->status == VTY_CLOSE);
+
+ vty_close(vty);
+ OSMO_ASSERT(last_vty_connection_event == VTY_CLOSED);
+}
+
int main(int argc, char **argv)
{
test_cmd_string_from_valstr();
+ test_node_tree_structure();
printf("All tests passed\n");
return 0;
diff --git a/tests/vty/vty_test.ok b/tests/vty/vty_test.ok
index baec249..0ea2dab 100644
--- a/tests/vty/vty_test.ok
+++ b/tests/vty/vty_test.ok
@@ -1,3 +1,46 @@
Going to test vty_cmd_string_from_valstr()
Tested with %s-strings, resulting cmd = '[prefix%s%s%s%s%s][foo%s%s%s%s%s][sep%s%s%s%s%s][bar%s%s%s%s%s][end%s%s%s%s%s]'
+Going to test VTY node tree structure
+Going to execute 'enable'
+Returned: 0, Current node: 3 '%s# '
+Going to execute 'configure terminal'
+Returned: 0, Current node: 4 '%s(config)# '
+Going to execute 'exit'
+Returned: 0, Current node: 3 '%s# '
+Going to execute 'configure terminal'
+Returned: 0, Current node: 4 '%s(config)# '
+Going to execute 'end'
+Returned: 0, Current node: 3 '%s# '
+Going to execute 'configure terminal'
+Returned: 0, Current node: 4 '%s(config)# '
+Going to execute 'log stderr'
+Returned: 0, Current node: 7 '%s(config-log)# '
+Going to execute 'exit'
+Returned: 0, Current node: 4 '%s(config)# '
+Going to execute 'log stderr'
+Returned: 0, Current node: 7 '%s(config-log)# '
+Going to execute 'end'
+Returned: 0, Current node: 3 '%s# '
+Going to execute 'configure terminal'
+Returned: 0, Current node: 4 '%s(config)# '
+Going to execute 'line vty'
+Returned: 0, Current node: 8 '%s(config-line)# '
+Going to execute 'exit'
+Returned: 0, Current node: 4 '%s(config)# '
+Going to execute 'line vty'
+Returned: 0, Current node: 8 '%s(config-line)# '
+Going to execute 'end'
+Returned: 0, Current node: 3 '%s# '
+Going to execute 'configure terminal'
+Returned: 0, Current node: 4 '%s(config)# '
+Going to execute 'log stderr'
+Returned: 0, Current node: 7 '%s(config-log)# '
+Going to execute 'line vty'
+Returned: 0, Current node: 8 '%s(config-line)# '
+Going to execute 'log stderr'
+Returned: 0, Current node: 7 '%s(config-log)# '
+Going to execute 'end'
+Returned: 0, Current node: 3 '%s# '
+Going to execute 'exit'
+Returned: 0, Current node: 3 '%s# '
All tests passed