Mi test: Basic test structure
authorJonathan Rajotte Julien <jonathan.r.julien@gmail.com>
Thu, 17 Jul 2014 18:34:08 +0000 (14:34 -0400)
committerJonathan Rajotte Julien <jonathan.r.julien@gmail.com>
Tue, 22 Jul 2014 20:14:58 +0000 (16:14 -0400)
Added two utils: an xml xpath extractor and xml xsd validator.

Test for session command

Signed-off-by: Jonathan Rajotte Julien <jonathan.r.julien@gmail.com>
configure.ac
tests/fast_regression
tests/regression/tools/Makefile.am
tests/regression/tools/mi/Makefile.am [new file with mode: 0644]
tests/regression/tools/mi/extract_xml.c [new file with mode: 0644]
tests/regression/tools/mi/test_mi_version [new file with mode: 0755]
tests/regression/tools/mi/validate_xml.c [new file with mode: 0644]
tests/regression/tools/mi/validate_xml.h [new file with mode: 0644]
tests/run.sh

index a6f5b0be9d022e45db308ab7072216a1467372a2..7d8839543eb03f42b3d3061472b17b4e0c7314a7 100644 (file)
@@ -420,6 +420,7 @@ AC_CONFIG_FILES([
        tests/regression/tools/live/Makefile
        tests/regression/tools/exclusion/Makefile
        tests/regression/tools/save-load/Makefile
+       tests/regression/tools/mi/Makefile
        tests/regression/ust/Makefile
        tests/regression/ust/nprocesses/Makefile
        tests/regression/ust/high-throughput/Makefile
index a3c2fe9947e99dcf26800b021d5f6aad530bb69e..6fae89d039f003c4adb80f315d3292dc6f64d151 100644 (file)
@@ -13,6 +13,7 @@ regression/tools/snapshots/test_ust_fast
 regression/tools/snapshots/test_ust_streaming
 regression/tools/save-load/test_save
 regression/tools/save-load/test_load
+regression/tools/mi/test_mi_version
 regression/ust/before-after/test_before_after
 regression/ust/buffers-pid/test_buffers_pid
 regression/ust/multi-session/test_multi_session
index 84df800758b8f3487f1026f6a6d0c240621dbeb8..09f55b33ac81f5d1d085a04f17697a18c83ad8ee 100644 (file)
@@ -1 +1 @@
-SUBDIRS = streaming filtering health tracefile-limits snapshots live exclusion save-load
+SUBDIRS = streaming filtering health tracefile-limits snapshots live exclusion save-load mi
diff --git a/tests/regression/tools/mi/Makefile.am b/tests/regression/tools/mi/Makefile.am
new file mode 100644 (file)
index 0000000..7a54c34
--- /dev/null
@@ -0,0 +1,27 @@
+AM_CPPFLAGS = -I$(srcdir)/include
+
+noinst_PROGRAMS = validate_xml extract_xml
+validate_xml_SOURCES = validate_xml.c
+validate_xml_CPPFLAGS = $(XML_CPPFLAGS) $(AM_CPPFLAGS)
+validate_xml_LDADD = $(XML_LIBS)
+
+extract_xml_SOURCES = extract_xml.c
+extract_xml_CPPFLAGS = $(XML_CPPFLAGS) $(AM_CPPFLAGS)
+extract_xml_LDADD = $(XML_LIBS)
+
+noinst_SCRIPTS = test_mi_version
+EXTRA_DIST =
+
+all-local:
+       @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
+               for script in $(EXTRA_DIST); do \
+                       cp -f $(srcdir)/$$script $(builddir); \
+               done; \
+       fi
+
+clean-local:
+       @if [ x"$(srcdir)" != x"$(builddir)" ]; then \
+               for script in $(EXTRA_DIST); do \
+                       rm -f $(builddir)/$$script; \
+               done; \
+       fi
diff --git a/tests/regression/tools/mi/extract_xml.c b/tests/regression/tools/mi/extract_xml.c
new file mode 100644 (file)
index 0000000..724e005
--- /dev/null
@@ -0,0 +1,227 @@
+/*
+ * Copyright (C) 2014 - Jonathan Rajotte <jonathan.r.julien@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License, version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ */
+
+/*
+ * Usage: extract_xml [-v] xml_path xpath_expression
+ * Evaluate XPath expression and prints result node set.
+ * args[1] path to the xml file
+ * args[2] xpath expression to extract
+ * If -v is set the name of the node will appear with his value delimited by
+ * a semicolon(;)
+ * Ex:
+ * Command:extract_xml ../file.xml /test/node/text()
+ * Output:
+ *     a
+ *     b
+ *     c
+ * With -v
+ *     node;a;
+ *     node;b;
+ *     node;c;
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <unistd.h>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+
+#if defined(LIBXML_XPATH_ENABLED)
+
+
+int opt_verbose;
+/**
+ * print_xpath_nodes:
+ * nodes:  the nodes set.
+ * output: the output file handle.
+ *
+ * Print the node content to the file
+ */
+static int print_xpath_nodes(xmlDocPtr doc, xmlNodeSetPtr nodes, FILE *output)
+{
+       int ret;
+       int size;
+       int i;
+
+       xmlNodePtr cur;
+       xmlChar *node_child_value_string = NULL;
+
+       assert(output);
+       size = (nodes) ? nodes->nodeNr : 0;
+
+       for (i = 0; i < size; ++i) {
+               assert(nodes->nodeTab[i]);
+
+               if (nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) {
+                       fprintf(stderr, "ERR:%s\n",
+                                       "This executable does not support xml namespacing\n");
+                       ret = -1;
+                       goto end;
+               } else if (nodes->nodeTab[i]->type == XML_ELEMENT_NODE) {
+                       cur = nodes->nodeTab[i];
+
+                       if (xmlChildElementCount(cur) == 0) {
+                               if (xmlNodeIsText(cur->children)) {
+                                       node_child_value_string = xmlNodeListGetString(doc,
+                                                       cur->children, 1);
+                                       if (opt_verbose) {
+                                               fprintf(output, "%s;%s;\n", cur->name,
+                                                               node_child_value_string);
+                                       } else {
+                                               fprintf(output, "%s\n",
+                                                               node_child_value_string);
+                                       }
+                                       xmlFree(node_child_value_string);
+                               } else {
+                                       /* We don't want to print non-final element */
+                                       fprintf(stderr, "ERR:%s\n",
+                                                       "Xpath expression return non-final xml element");
+                                       ret = -1;
+                                       goto end;
+                               }
+                       } else {
+                               /* We don't want to print non-final element */
+                               fprintf(stderr, "ERR:%s\n",
+                                               "Xpath expression return non-final xml element");
+                               ret = -1;
+                               goto end;
+                       }
+
+               } else {
+                       cur = nodes->nodeTab[i];
+                       if (opt_verbose) {
+                               fprintf(output, "%s;%s;\n", cur->parent->name, cur->content);
+                       } else {
+                               fprintf(output, "%s\n", cur->content);
+
+                       }
+               }
+       }
+       /* Command Success */
+       ret = 0;
+
+end:
+       return ret;
+}
+
+/*
+ * Extract element corresponding to xpath
+ * xml_path     The path to the xml file
+ * xpath:       The xpath to evaluate.
+ *
+ * Evaluate an xpath expression onto an xml file.
+ * and print the result one by line.
+ *
+ * Returns 0 on success and a negative value otherwise.
+ */
+static int extract_xpath(const char *xml_path, const xmlChar *xpath)
+{
+       xmlDocPtr doc = NULL;
+       xmlXPathContextPtr xpathCtx = NULL;
+       xmlXPathObjectPtr xpathObj = NULL;
+
+       assert(xml_path);
+       assert(xpath);
+
+       /* Parse the xml file */
+       doc = xmlParseFile(xml_path);
+       if (!doc) {
+               fprintf(stderr, "ERR parsing: xml file invalid \"%s\"\n", xml_path);
+               return -1;
+       }
+
+       /* Initialize a xpath context */
+       xpathCtx = xmlXPathNewContext(doc);
+       if (!xpathCtx) {
+               fprintf(stderr, "ERR: XPath context invalid\n");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       /* Evaluate xpath expression */
+       xpathObj = xmlXPathEvalExpression(xpath, xpathCtx);
+       if (!xpathObj) {
+               fprintf(stderr, "ERR: invalid xpath expression \"%s\"\n", xpath);
+               xmlXPathFreeContext(xpathCtx);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       /* Print results */
+       if (print_xpath_nodes(doc, xpathObj->nodesetval, stdout)) {
+               xmlXPathFreeObject(xpathObj);
+               xmlXPathFreeContext(xpathCtx);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       /* Cleanup */
+       xmlXPathFreeObject(xpathObj);
+       xmlXPathFreeContext(xpathCtx);
+       xmlFreeDoc(doc);
+
+       return 0;
+}
+
+int main(int argc, char **argv)
+{
+       int opt;
+
+       /* Parse command line and process file */
+       while ((opt = getopt(argc, argv, "v")) != -1) {
+               switch (opt) {
+               case 'v':
+                       opt_verbose = 1;
+                       break;
+               default:
+                       abort();
+               }
+       }
+
+       if (!(optind + 1 < argc)) {
+               fprintf(stderr, "ERR:%s\n", "Arguments missing");
+               return -1;
+       }
+
+       /* Init libxml */
+       xmlInitParser();
+       xmlKeepBlanksDefault(0);
+       if (access(argv[optind], F_OK)) {
+               fprintf(stderr, "ERR:%s\n", "Xml path not valid");
+               return -1;
+       }
+       /* Do the main job */
+       if (extract_xpath(argv[optind], (xmlChar *)argv[optind+1])) {
+               return -1;
+       }
+
+       /* Shutdown libxml */
+       xmlCleanupParser();
+
+       return 0;
+}
+
+#else
+int main(void)
+{
+       fprintf(stderr, "XPath support not compiled in\n");
+       return -1;
+}
+#endif
diff --git a/tests/regression/tools/mi/test_mi_version b/tests/regression/tools/mi/test_mi_version
new file mode 100755 (executable)
index 0000000..1d89453
--- /dev/null
@@ -0,0 +1,78 @@
+#!/bin/bash
+#
+# Copyright (C) - 2014 Jonathan Rajotte <jonathan.r.julien@gmail.com>
+#
+# This library is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+# details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this library; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+
+TEST_DESC="Mi test command version"
+
+CURDIR=$(dirname $0)/
+TESTDIR=$CURDIR/../../../
+XSD_PATH=$TESTDIR/../src/common/mi_lttng.xsd
+SESSIOND_BIN="lttng-sessiond"
+RELAYD_BIN="lttng-relayd"
+LTTNG_BIN="lttng --mi xml"
+
+XML_VALIDATE="$CURDIR/validate_xml $XSD_PATH"
+
+LTTNG=$TESTDIR/../src/bin/lttng/$LTTNG_BIN
+
+
+DIR=$(readlink -f $TESTDIR)
+
+NUM_TESTS=4
+
+source $TESTDIR/utils/utils.sh
+
+# MUST set TESTDIR before calling those functions
+plan_tests $NUM_TESTS
+
+print_test_banner "$TEST_DESC"
+
+function mi_print_version()
+{
+       local opt=$2
+       local output_path=$1
+
+       $LTTNG version $opt > $output_path
+       ok $? "Machine Interface Lttng version"
+
+}
+
+function test_version_validation()
+{
+       mi_print_version version.xml
+       $XML_VALIDATE version.xml
+       ok $? "Machine Interface Version xsd validation"
+}
+
+start_lttng_sessiond
+
+TESTS=(
+       test_version_validation
+)
+
+for fct_test in ${TESTS[@]};
+do
+       TRACE_PATH=$(mktemp -d)
+
+       ${fct_test}
+       if [ $? -ne 0 ]; then
+               break;
+       fi
+       # Only delete if successful
+       rm -rf $TRACE_PATH
+done
+
+stop_lttng_sessiond
diff --git a/tests/regression/tools/mi/validate_xml.c b/tests/regression/tools/mi/validate_xml.c
new file mode 100644 (file)
index 0000000..e3c6350
--- /dev/null
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2014  Jonathan Rajotte <jonathan.r.julien@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1 of
+ * the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+ /*
+  * This script validate and xml from an xsd.
+  * argv[1] Path of the xsd
+  * argv[2] Path to the XML to be validated
+  */
+
+#define _GNU_SOURCE
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <libxml/xmlschemas.h>
+#include <libxml/parser.h>
+
+#include <lttng/lttng-error.h>
+
+struct validation_ctx {
+       xmlSchemaParserCtxtPtr parser_ctx;
+       xmlSchemaPtr schema;
+       xmlSchemaValidCtxtPtr schema_validation_ctx;
+};
+
+enum command_err_code {
+       CMD_SUCCESS = 0,
+       CMD_ERROR
+};
+
+static
+void xml_error_handler(void *ctx, const char *format, ...)
+{
+       char *err_msg;
+       va_list args;
+       int ret;
+
+       va_start(args, format);
+       ret = vasprintf(&err_msg, format, args);
+       va_end(args);
+       if (ret == -1) {
+               fprintf(stderr, "ERR: %s\n",
+                               "String allocation failed in xml error handle");
+               return;
+       }
+
+       fprintf(stderr, "XML Error: %s\n", err_msg);
+       free(err_msg);
+}
+
+static
+void fini_validation_ctx(
+       struct validation_ctx *ctx)
+{
+       if (ctx->parser_ctx) {
+               xmlSchemaFreeParserCtxt(ctx->parser_ctx);
+       }
+
+       if (ctx->schema) {
+               xmlSchemaFree(ctx->schema);
+       }
+
+       if (ctx->schema_validation_ctx) {
+               xmlSchemaFreeValidCtxt(ctx->schema_validation_ctx);
+       }
+
+       memset(ctx, 0, sizeof(struct validation_ctx));
+}
+
+static
+int init_validation_ctx(
+       struct validation_ctx *ctx, char *xsd_path)
+{
+       int ret;
+
+       if (!xsd_path) {
+               ret = -LTTNG_ERR_NOMEM;
+               goto end;
+       }
+
+       ctx->parser_ctx = xmlSchemaNewParserCtxt(xsd_path);
+       if (!ctx->parser_ctx) {
+               ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+               goto end;
+       }
+       xmlSchemaSetParserErrors(ctx->parser_ctx, xml_error_handler,
+               xml_error_handler, NULL);
+
+       ctx->schema = xmlSchemaParse(ctx->parser_ctx);
+       if (!ctx->schema) {
+               ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+               goto end;
+       }
+
+       ctx->schema_validation_ctx = xmlSchemaNewValidCtxt(ctx->schema);
+       if (!ctx->schema_validation_ctx) {
+               ret = -LTTNG_ERR_LOAD_INVALID_CONFIG;
+               goto end;
+       }
+
+       xmlSchemaSetValidErrors(ctx->schema_validation_ctx, xml_error_handler,
+                       xml_error_handler, NULL);
+       ret = 0;
+
+end:
+       if (ret) {
+               fini_validation_ctx(ctx);
+       }
+       return ret;
+}
+
+static int validate_xml(const char *xml_file_path, struct validation_ctx *ctx)
+{
+       int ret;
+       xmlDocPtr doc = NULL;
+
+       assert(xml_file_path);
+       assert(ctx);
+
+       /* Open the document */
+       doc = xmlParseFile(xml_file_path);
+       if (!doc) {
+               ret = LTTNG_ERR_MI_IO_FAIL;
+               goto end;
+       }
+
+       /* Validate against the validation ctx (xsd) */
+       ret = xmlSchemaValidateDoc(ctx->schema_validation_ctx, doc);
+       if (ret) {
+               fprintf(stderr, "ERR: %s\n", "XML is not valid againt provided XSD");
+               ret = CMD_ERROR;
+               goto end;
+       }
+
+       ret = CMD_SUCCESS;
+end:
+       return ret;
+
+
+}
+int main(int argc, char **argv, char *env[])
+{
+       int ret;
+       struct validation_ctx ctx;
+
+       /* Check if we have all argument */
+       if (argc < 3) {
+               fprintf(stderr, "ERR: %s\n", "Missing arguments");
+               ret = CMD_ERROR;
+               goto end;
+       }
+
+       /* Check if xsd file exist */
+       ret = access(argv[1], F_OK);
+       if (ret < 0) {
+               fprintf(stderr, "ERR: %s\n", "Xsd path not valid");
+               goto end;
+       }
+
+       /* Check if xml to validate exist */
+       ret = access(argv[2], F_OK);
+       if (ret < 0) {
+               fprintf(stderr, "ERR: %s\n", "XML path not valid");
+               goto end;
+       }
+
+       /* initialize the validation ctx */
+       ret = init_validation_ctx(&ctx, argv[1]);
+       if (ret) {
+               goto end;
+       }
+
+       ret = validate_xml(argv[2], &ctx);
+
+       fini_validation_ctx(&ctx);
+
+end:
+       return ret;
+}
diff --git a/tests/regression/tools/mi/validate_xml.h b/tests/regression/tools/mi/validate_xml.h
new file mode 100644 (file)
index 0000000..e69de29
index c6c50fd9cff94ecb02ef1e9b3eab2e98180043c6..ce51639f762684cd705d8e7e8ef54742fc1cdd7a 100755 (executable)
@@ -19,4 +19,4 @@
 
 [ -z "$1" ] && echo "Error: No testlist. Please specify a testlist to run." && exit 1
 
-prove --merge --exec '' - < $1
+prove $2 --merge --exec '' - < $1
This page took 0.032655 seconds and 4 git commands to generate.