/tests/utils/testapp/gen-ust-events-ns/gen-ust-events-ns
/tests/regression/tools/health/health_check
/tests/regression/kernel/select_poll_epoll
-/tests/regression/tools/mi/extract_xml
-/tests/regression/tools/mi/validate_xml
/tests/regression/tools/notification/base_client
/tests/regression/tools/notification/notification
/tests/regression/tools/rotation/schedule_api
/tests/utils/testapp/gen-ust-tracef/gen-ust-tracef
/tests/utils/testapp/gen-syscall-events/gen-syscall-events
/tests/utils/testapp/gen-kernel-test-events/gen-kernel-test-events
+/tests/utils/xml-utils/extract_xml
+/tests/utils/xml-utils/validate_xml
/tests/regression/tools/live/live_test
/tests/unit/ini_config/ini_config
/tests/perf/find_event
tests/utils/testapp/userspace-probe-elf-binary/Makefile
tests/utils/testapp/userspace-probe-elf-cxx-binary/Makefile
tests/utils/testapp/userspace-probe-sdt-binary/Makefile
+ tests/utils/xml-utils/Makefile
])
# Inject variable into python test script.
# SPDX-License-Identifier: GPL-2.0-only
-noinst_PROGRAMS = validate_xml extract_xml
-validate_xml_SOURCES = validate_xml.c
-validate_xml_CPPFLAGS = $(libxml2_CFLAGS) $(AM_CPPFLAGS)
-validate_xml_LDADD = $(libxml2_LIBS)
-
-extract_xml_SOURCES = extract_xml.c
-extract_xml_CPPFLAGS = $(libxml2_CFLAGS) $(AM_CPPFLAGS)
-extract_xml_LDADD = $(libxml2_LIBS)
-
noinst_SCRIPTS = test_mi
EXTRA_DIST = test_mi
+++ /dev/null
-/*
- * Copyright (C) 2014 Jonathan Rajotte <jonathan.r.julien@gmail.com>
- *
- * SPDX-License-Identifier: GPL-2.0-only
- *
- */
-
-/*
- * Usage: extract_xml [-v|-e] 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 -e look if node exist return "true" else nothing
- * 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 <assert.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <libxml/tree.h>
-#include <libxml/parser.h>
-#include <libxml/xpath.h>
-#include <libxml/xpathInternals.h>
-#include <common/defaults.h>
-
-#if defined(LIBXML_XPATH_ENABLED)
-
-static int opt_verbose;
-static int node_exist;
-static bool result = false;
-
-/**
- * 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 = 0;
- 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 (node_exist) {
- result = true;
- } else 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 */
- if (node_exist) {
- result = true;
- } else {
- fprintf(stderr, "ERR:%s\n",
- "Xpath expression return non-final xml element");
- ret = -1;
- goto end;
- }
- }
- } else {
- if (node_exist) {
- result = true;
- } 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 (node_exist) {
- result = true;
- } else 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;
-}
-
-static int register_lttng_namespace(xmlXPathContextPtr xpathCtx)
-{
- int ret;
- xmlChar *prefix;
- xmlChar *ns = NULL;
-
- prefix = xmlCharStrdup("lttng");
- if (!prefix) {
- ret = -1;
- goto end;
- }
-
- ns = xmlCharStrdup(DEFAULT_LTTNG_MI_NAMESPACE);
- if (!ns) {
- ret = -1;
- goto end;
- }
-
- ret = xmlXPathRegisterNs(xpathCtx, prefix, ns);
-end:
- xmlFree(prefix);
- xmlFree(ns);
- 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)
-{
- int ret;
- 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;
- }
-
- /* Register the LTTng MI namespace */
- ret = register_lttng_namespace(xpathCtx);
- if (ret) {
- fprintf(stderr, "ERR: Could not register lttng namespace\n");
- xmlXPathFreeContext(xpathCtx);
- 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;
- }
- if (node_exist && result) {
- fprintf(stdout, "true\n");
- }
-
- /* 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, "ve")) != -1) {
- switch (opt) {
- case 'v':
- opt_verbose = 1;
- break;
- case 'e':
- node_exist = 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
OUTPUT_FILE="default.xml"
#Path to custom xml utilities
-XML_VALIDATE="$CURDIR/validate_xml $XSD_PATH"
-XML_EXTRACT="$CURDIR/extract_xml"
-XML_NODE_CHECK="$CURDIR/extract_xml -e"
+XML_UTILS_PATH="$TESTDIR/utils/xml-utils"
+XML_VALIDATE="$XML_UTILS_PATH/validate_xml $XSD_PATH"
+XML_EXTRACT="$XML_UTILS_PATH/extract_xml"
+XML_NODE_CHECK="$XML_UTILS_PATH/extract_xml -e"
XPATH_CMD_OUTPUT="//lttng:command/lttng:output"
XPATH_COMMAND_SUCCESS="/lttng:command/lttng:success/text()"
+++ /dev/null
-/*
- * Copyright (C) 2014 Jonathan Rajotte <jonathan.r.julien@gmail.com>
- *
- * SPDX-License-Identifier: LGPL-2.1-only
- *
- */
-
- /*
- * This script validate and xml from an xsd.
- * argv[1] Path of the xsd
- * argv[2] Path to the XML to be validated
- */
-
-#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 = { 0 };
-
- /* 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;
-}
XSD_PATH=$TESTDIR/../src/common/mi-lttng-4.0.xsd
-XML_VALIDATE="$TESTDIR/regression/tools/mi/validate_xml $XSD_PATH"
-XML_EXTRACT="$TESTDIR/regression/tools/mi/extract_xml"
+XML_VALIDATE="$TESTDIR/utils/xml-utils/validate_xml $XSD_PATH"
+XML_EXTRACT="$TESTDIR/utils/xml-utils/extract_xml"
XPATH_CMD_OUTPUT="//lttng:command/lttng:output"
XPATH_SESSION="$XPATH_CMD_OUTPUT/lttng:sessions/lttng:session"
XSD_PATH=$TESTDIR/../src/common/mi-lttng-4.0.xsd
-XML_VALIDATE="$TESTDIR/regression/tools/mi/validate_xml $XSD_PATH"
-XML_EXTRACT="$TESTDIR/regression/tools/mi/extract_xml"
+XML_VALIDATE="$TESTDIR/utils/xml-utils/validate_xml $XSD_PATH"
+XML_EXTRACT="$TESTDIR/utils/xml-utils/extract_xml"
XPATH_CMD_OUTPUT="//lttng:command/lttng:output"
XPATH_SESSION="$XPATH_CMD_OUTPUT/lttng:sessions/lttng:session"
NUM_TESTS=75
source $TESTDIR/utils/utils.sh
+XML_EXTRACT="$TESTDIR/utils/xml-utils/extract_xml"
# MUST set TESTDIR before calling those functions
plan_tests $NUM_TESTS
break;
fi
$TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list $sess -c chan2 > $mi_output_file
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain[lttng:type='UST']/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_disabled']/lttng:enabled/text()")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain[lttng:type='UST']/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_disabled']/lttng:enabled/text()")
if [[ $mi_result = "false" ]]; then
ok 0 "Disabled event is loaded in disabled state"
else
fail "Disabled event is loaded in disabled state"
fi
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_disabled']/lttng:enabled/text()")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_disabled']/lttng:enabled/text()")
test $mi_result = "false"
ok $? "Disabled event is loaded in disabled state"
# Check that uevent_same_name_diff_llevel with log level 6 (TRACE_INFO) is enabled
# This ensure that the state of events with similar name but not same
# descriptor tuple (exclusion,filter,loglevel) is restored correctly.
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_same_name_diff_llevel' and lttng:loglevel='TRACE_INFO']/lttng:enabled/text()")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:channels/lttng:channel[lttng:name='chan2']/lttng:events/lttng:event[lttng:name='uevent_same_name_diff_llevel' and lttng:loglevel='TRACE_INFO']/lttng:enabled/text()")
test $mi_result = "true"
ok $? "Enabled event with same name but different loglevel is in disabled state"
break;
fi
$TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list "$SESSION_NAME-trackers" > $mi_output_file
- mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vpid_process_attr_tracker/lttng:process_attr_values/lttng:vpid")
+ mi_result=$("$XML_EXTRACT" -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vpid_process_attr_tracker/lttng:process_attr_values/lttng:vpid")
if [[ $mi_result = "true" ]]; then
ok 0 "VPID target is present"
else
fail "VPID target missing"
fi
- mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vuid_process_attr_tracker/lttng:process_attr_values/lttng:vuid")
+ mi_result=$("$XML_EXTRACT" -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vuid_process_attr_tracker/lttng:process_attr_values/lttng:vuid")
if [[ $mi_result = "true" ]]; then
ok 0 "VUID target is present"
else
fail "VUID target missing"
fi
- mi_result=$($CURDIR/../mi/extract_xml -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vgid_process_attr_tracker/lttng:process_attr_values/lttng:vgid")
+ mi_result=$("$XML_EXTRACT" -e $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:domains/lttng:domain/lttng:process_attr_trackers/lttng:vgid_process_attr_tracker/lttng:process_attr_values/lttng:vgid")
if [[ $mi_result = "true" ]]; then
ok 0 "VGID target is present"
else
# Url of style file://
lttng_load_ok "-i $CURDIR/$SESSION_NAME.lttng --override-url=${local_url_override}"
$TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list "$SESSION_NAME" > $mi_output_file
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
test $mi_result = "${local_path_compare_value}"
ok $? "Path url file:// override [{$mi_result}, ${local_path_compare_value}]"
# Url of style /
lttng_load_ok "-i $CURDIR/$SESSION_NAME.lttng --override-url=${local_path_override}"
$TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list "$SESSION_NAME" > $mi_output_file
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
test $mi_result = "${local_path_compare_value}"
ok $? "Path url / override [{$mi_result}, ${local_path_compare_value}]"
# Url of style net://ip:port:port
lttng_load_ok "-i $CURDIR/$SESSION_NAME.lttng --override-url=${stream_url_override}"
$TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list "$SESSION_NAME" > $mi_output_file
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
test "$mi_result" = "${stream_url_compare}"
ok $? "Path url net://host:port:port override [${mi_result}, ${stream_url_compare}]"
# Url of style file://
lttng_load_ok "-i $CONFIG_DIR/$local_session_name.lttng --override-url=${url_override}"
$TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML snapshot list-output -s "$local_session_name" > $mi_output_file
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
test $mi_result = "${path_compare_value}"
ok $? "Path url file:// override [{$mi_result}, ${path_compare_value}]"
# Url of style /
lttng_load_ok "-i $CONFIG_DIR/$local_session_name.lttng --override-url=${path_override}"
$TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML snapshot list-output -s "$local_session_name" > $mi_output_file
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
test $mi_result = "${path_compare_value}"
ok $? "Path url / override [{$mi_result}, ${path_compare_value}]"
# Url of style net://ip:port:port
lttng_load_ok "-i $CONFIG_DIR/$local_session_name.lttng --override-url=${stream_url_override}"
$TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML snapshot list-output -s "$local_session_name" > $mi_output_file
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:ctrl_url")
test "$mi_result" = "${stream_url_compare_ctrl}"
ok $? "Path url ctrl net://host:port:port override [${mi_result}, ${stream_url_compare_ctrl}]"
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:data_url")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:snapshot_action/lttng:output/lttng:session/lttng:snapshots/lttng:snapshot/lttng:data_url")
test "$mi_result" = "${stream_url_compare_data}"
ok $? "Path url data net://host:port:port override [${mi_result}, ${stream_url_compare_data}]"
# Url of style net://ip:port:port
lttng_load_ok "-i $CONFIG_DIR/$local_session_name.lttng --override-url=${stream_url_override}"
$TESTDIR/../src/bin/lttng/$LTTNG_BIN --mi XML list "$local_session_name" > $mi_output_file
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
test "$mi_result" = "${stream_url_compare}"
ok $? "Path url net://host:port:port override [${mi_result}, ${stream_url_compare}]"
fi
${TESTDIR}/../src/bin/lttng/${LTTNG_BIN} --mi XML list "${override_name}" > $mi_output_file
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:name")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:name")
test "${mi_result}" = "${override_name}"
ok $? "Override name successful [${SESSION_NAME} to ${override_name}]"
# Make sure that the name override did not change something else
- mi_result=$($CURDIR/../mi/extract_xml $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
+ mi_result=$("$XML_EXTRACT" $mi_output_file "//lttng:command/lttng:output/lttng:sessions/lttng:session/lttng:path")
test "${mi_result}" = "${output_path}"
ok $? "Output path is not affected by name override"
# SPDX-License-Identifier: GPL-2.0-only
-SUBDIRS = . tap testapp
+SUBDIRS = . tap testapp xml-utils
EXTRA_DIST = utils.sh test_utils.py babelstats.pl warn_processes.sh \
parse-callstack.py
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+
+noinst_PROGRAMS = validate_xml extract_xml
+validate_xml_SOURCES = validate_xml.c
+validate_xml_CPPFLAGS = $(libxml2_CFLAGS) $(AM_CPPFLAGS)
+validate_xml_LDADD = $(libxml2_LIBS)
+
+extract_xml_SOURCES = extract_xml.c
+extract_xml_CPPFLAGS = $(libxml2_CFLAGS) $(AM_CPPFLAGS)
+extract_xml_LDADD = $(libxml2_LIBS)
+
+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>
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ */
+
+/*
+ * Usage: extract_xml [-v|-e] 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 -e look if node exist return "true" else nothing
+ * 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 <assert.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xpath.h>
+#include <libxml/xpathInternals.h>
+#include <common/defaults.h>
+
+#if defined(LIBXML_XPATH_ENABLED)
+
+static int opt_verbose;
+static int node_exist;
+static bool result = false;
+
+/**
+ * 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 = 0;
+ 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 (node_exist) {
+ result = true;
+ } else 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 */
+ if (node_exist) {
+ result = true;
+ } else {
+ fprintf(stderr, "ERR:%s\n",
+ "Xpath expression return non-final xml element");
+ ret = -1;
+ goto end;
+ }
+ }
+ } else {
+ if (node_exist) {
+ result = true;
+ } 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 (node_exist) {
+ result = true;
+ } else 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;
+}
+
+static int register_lttng_namespace(xmlXPathContextPtr xpathCtx)
+{
+ int ret;
+ xmlChar *prefix;
+ xmlChar *ns = NULL;
+
+ prefix = xmlCharStrdup("lttng");
+ if (!prefix) {
+ ret = -1;
+ goto end;
+ }
+
+ ns = xmlCharStrdup(DEFAULT_LTTNG_MI_NAMESPACE);
+ if (!ns) {
+ ret = -1;
+ goto end;
+ }
+
+ ret = xmlXPathRegisterNs(xpathCtx, prefix, ns);
+end:
+ xmlFree(prefix);
+ xmlFree(ns);
+ 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)
+{
+ int ret;
+ 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;
+ }
+
+ /* Register the LTTng MI namespace */
+ ret = register_lttng_namespace(xpathCtx);
+ if (ret) {
+ fprintf(stderr, "ERR: Could not register lttng namespace\n");
+ xmlXPathFreeContext(xpathCtx);
+ 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;
+ }
+ if (node_exist && result) {
+ fprintf(stdout, "true\n");
+ }
+
+ /* 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, "ve")) != -1) {
+ switch (opt) {
+ case 'v':
+ opt_verbose = 1;
+ break;
+ case 'e':
+ node_exist = 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
+/*
+ * Copyright (C) 2014 Jonathan Rajotte <jonathan.r.julien@gmail.com>
+ *
+ * SPDX-License-Identifier: LGPL-2.1-only
+ *
+ */
+
+ /*
+ * This script validate and xml from an xsd.
+ * argv[1] Path of the xsd
+ * argv[2] Path to the XML to be validated
+ */
+
+#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 = { 0 };
+
+ /* 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;
+}