[PATCH 2/2] lnst-ctl: add recipe validation

olichtne at redhat.com olichtne at redhat.com
Thu May 16 13:22:54 UTC 2013

From: Ondrej Lichtner <olichtne at redhat.com>

This commit adds recipe validation before the recipe is passed to the
NetTestController class. The validation uses the lxml library and will
catch syntactic errors as well as differences from the XML Schema.

Currently the recipes are validated only against the recipe.xsd schema
which has to be in the same directory as the lnst-ctl script. This will
be changed in the future when the format and validation is finalized,
the schema will be either in a standardized location or put on the

Signed-off-by: Ondrej Lichtner <olichtne at redhat.com>
 lnst-ctl | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/lnst-ctl b/lnst-ctl
index dcb4cd2..f9c828d 100755
--- a/lnst-ctl
+++ b/lnst-ctl
@@ -17,6 +17,7 @@ import logging
 import os
 import re
 import datetime
+from lxml import etree
 from lnst.Common.Logs import LoggingCtl, log_exc_traceback
 from lnst.Common.Config import Config
 from lnst.Controller.NetTestController import NetTestController, NetTestError
@@ -85,6 +86,11 @@ def get_recipe_result(args, file_path, cleanup, res_serializer, packet_capture,
     return ((file_path, res))
+def validate_recipe(recipe_path):
+    schema = etree.XMLSchema(file="recipe.xsd")
+    recipe = etree.parse(recipe_path)
+    schema.assertValid(recipe)
 def main():
     Main function
@@ -162,6 +168,15 @@ def main():
             for f in all_files:
                 recipe_file = os.path.join(recipe_path, f)
+                try:
+                    validate_recipe(recipe_file)
+                except (etree.DocumentInvalid, etree.XMLSyntaxError) as e:
+                    msg = "Recipe %s is invalid!" % recipe_file
+                    logging.error(msg)
+                    logging.error(e)
+                    continue
                 if re.match(r'^.*\.xml$', recipe_file):
                     logging.info("Processing recipe file \"%s\"" % recipe_file)
                     summary.append(get_recipe_result(action, recipe_file,
@@ -171,6 +186,13 @@ def main():
                                                      config, log_ctl,
+            try:
+                validate_recipe(recipe_path)
+            except (etree.DocumentInvalid, etree.XMLSyntaxError) as e:
+                msg = "Recipe %s is invalid!" % recipe_path
+                logging.error(msg)
+                logging.error(e)
+                break
             summary.append(get_recipe_result(action, recipe_path,
                                              cleanup, res_serializer,

More information about the LNST-developers mailing list