Changes to run_keyword:
- Allow multiple lib/resource paths separated by ":" for lib_file_path.
- Allow multiple keywords separated by " ; " for keyword_string.
- Add smarts to allow assignments (e.g. ${state}= Get State).
Change-Id: Idf38edb18b6b0bec0e6cd53ebc0b420439931306
Signed-off-by: Michael Walsh <micwalsh@us.ibm.com>
diff --git a/extended/run_keyword.py b/extended/run_keyword.py
old mode 100755
new mode 100644
index 3f1a10b..38033c7
--- a/extended/run_keyword.py
+++ b/extended/run_keyword.py
@@ -4,11 +4,10 @@
This module is the python counterpart to run_keyword.robot.
"""
-import gen_print as gp
import gen_robot_print as grp
import gen_robot_valid as grv
-
from robot.libraries.BuiltIn import BuiltIn
+import re
###############################################################################
@@ -20,12 +19,34 @@
setup()
- keyword_string = BuiltIn().get_variable_value("${keyword_string}")
- lib_file_path = BuiltIn().get_variable_value("${lib_file_path}")
+ # NOTE: During code review the following question was raised: Why support
+ # 1) variable assignments 2) multiple keywords? Couldn't a user simply
+ # call this program twice to get what they need. If necessary, the user
+ # could take the output of the first call and specify it as a literal on
+ # the second call.
+ #
+ # However, this approach would not work in all cases. The following case
+ # would be such an example:
+ # Let's say the first keyword string is as follows:
+ # Create Dictionary foo=bar
+ # You wish to take the output of that call and specify it as a literal
+ # value when running the following:
+ # Want Dictionary parm=<literal dictionary specification>
+ # The problem is that there is no way to specify a dictionary as a
+ # literal in Robot Framework.
+ # By having this program support variable assignments and multiple
+ # keywords, the user can invoke it with the following keyword string.
+ # ${my_dict}= Create Dictionary foo=bar ; Want Dictionary ${my_dict}
- cmd_buf = keyword_string.split(" ")
+ # The user can pass multiple lib/resource paths by separating them with a
+ # colon.
- if lib_file_path != "":
+ lib_file_path_list = \
+ BuiltIn().get_variable_value("${lib_file_path}").split(":")
+ # Get rid of empty entry if it exists.
+ if lib_file_path_list[0] == "":
+ del lib_file_path_list[0]
+ for lib_file_path in lib_file_path_list:
# We don't want global variable getting changed when an import is done
# so we'll save it and restore it.
quiet = int(BuiltIn().get_variable_value("${quiet}"))
@@ -37,22 +58,33 @@
BuiltIn().import_resource(lib_file_path)
BuiltIn().set_global_variable("${quiet}", quiet)
- error_message = grp.sprint_error_report("Keyword \"" + cmd_buf[0] +
- "\" does not exist.\n")
- BuiltIn().keyword_should_exist(cmd_buf[0], msg=error_message)
+ # The user can pass multiple keyword strings by separating them with " ; ".
+ keyword_list = \
+ BuiltIn().get_variable_value("${keyword_string}").split(" ; ")
+ for keyword_string in keyword_list:
+ cmd_buf = keyword_string.split(" ")
+ if re.match(r"\$\{", cmd_buf[0]):
+ # This looks like an assignment (e.g. ${var}= <keyword>).
+ # We'll extract the variable name, remove element 0 from
+ # cmd_buf and set the global variable with the results
+ # after running the keyword.
+ var_name = cmd_buf[0].strip("${}=")
+ del cmd_buf[0]
+ else:
+ var_name = ""
- grp.rqprint_issuing_keyword(cmd_buf)
- status, output = BuiltIn().run_keyword_and_ignore_error(*cmd_buf)
- if status != "PASS":
- error_message = grp.sprint_error_report("\"" + cmd_buf[0] +
- "\" failed with the" +
- " following error:\n" + output)
- if not quiet:
- grp.rprint(error_message, 'STDERR')
- BuiltIn().fail(error_message)
+ test_mode = int(BuiltIn().get_variable_value("${test_mode}"))
+ grp.rqprint_issuing_keyword(cmd_buf, test_mode)
+ if test_mode:
+ return
- if output is not None:
- grp.rprint(output)
+ output = BuiltIn().run_keyword(*cmd_buf)
+
+ if var_name != "":
+ BuiltIn().set_global_variable("${" + var_name + "}", output)
+ else:
+ if output is not None:
+ grp.rprint_var(output)
###############################################################################
diff --git a/extended/run_keyword.robot b/extended/run_keyword.robot
old mode 100755
new mode 100644
index 52924d1..cf45d29
--- a/extended/run_keyword.robot
+++ b/extended/run_keyword.robot
@@ -1,6 +1,31 @@
*** Settings ***
Documentation Run the caller's keyword string.
+# Description of parameters:
+# keyword_string The keyword string to be run by this program. If this
+# keyword string contains " ; " anywhere, it will be taken to
+# be multiple keyword strings (see example below). Each
+# keywrod may also include a variable assignment. Example:
+# ${my_var}= My Keyword
+# lib_file_path The path to a library or resource needed to run the keywords.
+# This may contain a colon-delimited list of library/resource
+# paths.
+# test_mode This means that this program should go through all the
+# motions but not actually do anything substantial.
+# debug If this parameter is set to "1", this program will print
+# additional debug information.
+# quiet If this parameter is set to "1", this program will print
+# only essential information, i.e. it will not echo parameters,
+# echo commands, print the total run time, etc.
+
+# Example calls:
+# cd $HOME/git/openbmc-test-automation
+# export PYTHONPATH=${HOME}/git/openbmc-test-automation/lib/
+
+# robot --outputdir=/tmp -v OPENBMC_HOST:barp01 -v 'keyword_string:Log To Console Hi.' extended/run_keyword.robot
+
+# robot --outputdir=/tmp -v OPENBMC_HOST:barp01 -v 'keyword_string:${state}= Get State quiet=${1} ; Rpvar state' -v lib_file_path:state.py extended/run_keyword.robot
+
# NOTE: Robot searches PYTHONPATH for libraries.
Library run_keyword.py