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>
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
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
-SUBDIRS = streaming filtering health tracefile-limits snapshots live exclusion save-load
+SUBDIRS = streaming filtering health tracefile-limits snapshots live exclusion save-load mi
--- /dev/null
+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
--- /dev/null
+/*
+ * 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
--- /dev/null
+#!/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
--- /dev/null
+/*
+ * 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;
+}
[ -z "$1" ] && echo "Error: No testlist. Please specify a testlist to run." && exit 1
-prove --merge --exec '' - < $1
+prove $2 --merge --exec '' - < $1