/tests/plugins/test_dwarf_powerpc64le-linux-gnu
/tests/plugins/test_dwarf_x86_64-linux-gnu
/tests/plugins/test_dwarf
-/tests/plugins/ctf/test_ctf_plugin
+/tests/plugins/src.ctf.fs/query/test_query
+/tests/plugins/src.ctf.fs/succeed/test_succeed
+/tests/plugins/src.ctf.fs/succeed/gen-trace-*
/tests/utils/common.sh
+/tests/utils/diff.sh
*.o
*.a
*.la
tests/lib/test-plugin-plugins/Makefile
tests/Makefile
tests/plugins/Makefile
+ tests/plugins/src.ctf.fs/Makefile
+ tests/plugins/src.ctf.fs/succeed/Makefile
tests/utils/common.sh
+ tests/utils/diff.sh
tests/utils/Makefile
tests/utils/tap/Makefile
])
AC_CONFIG_FILES([tests/ctf-writer/test_ctf_writer], [chmod +x tests/ctf-writer/test_ctf_writer])
AC_CONFIG_FILES([tests/lib/test_plugin_complete], [chmod +x tests/lib/test_plugin_complete])
AC_CONFIG_FILES([tests/lib/trace-ir/test_trace_ir], [chmod +x tests/lib/trace-ir/test_trace_ir])
-AC_CONFIG_FILES([tests/plugins/ctf/test_ctf_plugin], [chmod +x tests/plugins/ctf/test_ctf_plugin])
+AC_CONFIG_FILES([tests/plugins/src.ctf.fs/query/test_query], [chmod +x tests/plugins/src.ctf.fs/query/test_query])
+AC_CONFIG_FILES([tests/plugins/src.ctf.fs/succeed/test_succeed], [chmod +x tests/plugins/src.ctf.fs/succeed/test_succeed])
AC_CONFIG_FILES([tests/plugins/test_utils_muxer_complete], [chmod +x tests/plugins/test_utils_muxer_complete])
AC_CONFIG_FILES([tests/plugins/test_lttng_utils_debug_info], [chmod +x tests/plugins/test_lttng_utils_debug_info])
AC_CONFIG_FILES([tests/plugins/test_dwarf_i386-linux-gnu], [chmod +x tests/plugins/test_dwarf_i386-linux-gnu])
TESTS_LIB += lib/trace-ir/test_trace_ir
endif
-TESTS_PLUGINS =
+TESTS_PLUGINS = \
+ plugins/src.ctf.fs/succeed/test_succeed
if !ENABLE_BUILT_IN_PLUGINS
if ENABLE_PYTHON_BINDINGS
-TESTS_PLUGINS += plugins/ctf/test_ctf_plugin
+TESTS_PLUGINS += plugins/src.ctf.fs/query/test_query
if ENABLE_DEBUG_INFO
TESTS_PLUGINS += plugins/test_lttng_utils_debug_info
+SUBDIRS = src.ctf.fs
AM_CPPFLAGS += -I$(top_srcdir)/tests/utils -I$(top_srcdir)/src/plugins
LIBTAP=$(top_builddir)/tests/utils/tap/libtap.la
dist_check_SCRIPTS = \
- test_lttng_utils_debug_info.py\
- ctf/test_query_trace_info.py
+ test_lttng_utils_debug_info.py
noinst_PROGRAMS =
+++ /dev/null
-#!/bin/bash
-#
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; only version 2
-# of the License.
-#
-# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-NO_SH_TAP=1
-. "@abs_top_builddir@/tests/utils/common.sh"
-
-TESTRUNNER_PY="$BT_SRC_PATH/tests/utils/python/testrunner.py"
-THIS_DIR="$BT_SRC_PATH/tests/plugins/ctf"
-
-exec "$BT_BUILD_PATH/tests/utils/test_python_bt2_env" python3 "$TESTRUNNER_PY" "$THIS_DIR"
+++ /dev/null
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; only version 2
-# of the License.
-#
-# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-import unittest
-import bt2
-import os
-import re
-
-
-test_ctf_traces_path = os.environ['TEST_CTF_TRACES_PATH']
-
-
-# Key to sort streams in a predictable order.
-def sort_predictably(stream):
- if 'range-ns' in stream:
- return stream['range-ns']['begin']
- else:
- return stream['paths'][0]
-
-
-class QueryTraceInfoClockOffsetTestCase(unittest.TestCase):
-
- def setUp(self):
- ctf = bt2.find_plugin('ctf')
- self._fs = ctf.source_component_classes['fs']
-
- self._paths = [os.path.join(test_ctf_traces_path, 'intersection', '3eventsintersect')]
- self._executor = bt2.QueryExecutor()
-
- def _check(self, trace, offset):
- self.assertEqual(trace['range-ns']['begin'], 13515309000000000 + offset)
- self.assertEqual(trace['range-ns']['end'], 13515309000000120 + offset)
- self.assertEqual(trace['intersection-range-ns']['begin'], 13515309000000070 + offset)
- self.assertEqual(trace['intersection-range-ns']['end'], 13515309000000100 + offset)
-
- streams = sorted(trace['streams'], key=sort_predictably)
- self.assertEqual(streams[0]['range-ns']['begin'], 13515309000000000 + offset)
- self.assertEqual(streams[0]['range-ns']['end'], 13515309000000100 + offset)
- self.assertEqual(streams[1]['range-ns']['begin'], 13515309000000070 + offset)
- self.assertEqual(streams[1]['range-ns']['end'], 13515309000000120 + offset)
-
- # Test various cominations of the clock-class-offset-s and
- # clock-class-offset-ns parameters to trace-info queries.
-
- # Without clock class offset
-
- def test_no_clock_class_offset(self):
- res = self._executor.query(self._fs, 'trace-info', {
- 'paths': self._paths,
- })
- trace = res[0]
- self._check(trace, 0)
-
- # With clock-class-offset-s
-
- def test_clock_class_offset_s(self):
- res = self._executor.query(self._fs, 'trace-info', {
- 'paths': self._paths,
- 'clock-class-offset-s': 2,
- })
- trace = res[0]
- self._check(trace, 2000000000)
-
- # With clock-class-offset-ns
-
- def test_clock_class_offset_ns(self):
- res = self._executor.query(self._fs, 'trace-info', {
- 'paths': self._paths,
- 'clock-class-offset-ns': 2,
- })
- trace = res[0]
- self._check(trace, 2)
-
- # With both, negative
-
- def test_clock_class_offset_both(self):
- res = self._executor.query(self._fs, 'trace-info', {
- 'paths': self._paths,
- 'clock-class-offset-s': -2,
- 'clock-class-offset-ns': -2,
- })
- trace = res[0]
- self._check(trace, -2000000002)
-
- def test_clock_class_offset_s_wrong_type(self):
- with self.assertRaises(bt2.InvalidQueryParams):
- self._executor.query(self._fs, 'trace-info', {
- 'paths': self._paths,
- 'clock-class-offset-s': "2",
- })
-
- def test_clock_class_offset_s_wrong_type_none(self):
- with self.assertRaises(bt2.InvalidQueryParams):
- self._executor.query(self._fs, 'trace-info', {
- 'paths': self._paths,
- 'clock-class-offset-s': None,
- })
-
- def test_clock_class_offset_ns_wrong_type(self):
- with self.assertRaises(bt2.InvalidQueryParams):
- self._executor.query(self._fs, 'trace-info', {
- 'paths': self._paths,
- 'clock-class-offset-ns': "2",
- })
-
- def test_clock_class_offset_ns_wrong_type_none(self):
- with self.assertRaises(bt2.InvalidQueryParams):
- self._executor.query(self._fs, 'trace-info', {
- 'paths': self._paths,
- 'clock-class-offset-ns': None,
- })
-
-
-class QueryTraceInfoPortNameTestCase(unittest.TestCase):
- def setUp(self):
- ctf = bt2.find_plugin("ctf")
- self._fs = ctf.source_component_classes["fs"]
-
- self._executor = bt2.QueryExecutor()
-
- def test_trace_uuid_stream_class_id_no_stream_id(self):
- res = self._executor.query(
- self._fs,
- "trace-info",
- {
- "paths": [
- os.path.join(
- test_ctf_traces_path, "intersection", "3eventsintersect"
- )
- ]
- },
- )
- self.assertEqual(len(res), 1)
- trace = res[0]
- streams = sorted(trace["streams"], key=sort_predictably)
- self.assertEqual(len(streams), 2)
- self.assertRegexpMatches(
- str(streams[0]["port-name"]),
- r"^7afe8fbe-79b8-4f6a-bbc7-d0c782e7ddaf \| 0 \| .*/tests/ctf-traces/intersection/3eventsintersect/test_stream_0$",
- )
- self.assertRegexpMatches(
- str(streams[1]["port-name"]),
- r"^7afe8fbe-79b8-4f6a-bbc7-d0c782e7ddaf \| 0 \| .*/tests/ctf-traces/intersection/3eventsintersect/test_stream_1$",
- )
-
- def test_trace_uuid_no_stream_class_id_no_stream_id(self):
- res = self._executor.query(
- self._fs,
- "trace-info",
- {"paths": [os.path.join(test_ctf_traces_path, "succeed", "succeed1")]},
- )
- self.assertEqual(len(res), 1)
- trace = res[0]
- streams = sorted(trace["streams"], key=sort_predictably)
- self.assertEqual(len(streams), 1)
- self.assertRegexpMatches(
- str(streams[0]["port-name"]),
- r"^2a6422d0-6cee-11e0-8c08-cb07d7b3a564 \| .*/tests/ctf-traces/succeed/succeed1/dummystream$",
- )
-
-
-class QueryTraceInfoRangeTestCase(unittest.TestCase):
- def setUp(self):
- ctf = bt2.find_plugin("ctf")
- self._fs = ctf.source_component_classes["fs"]
-
- self._executor = bt2.QueryExecutor()
-
- def test_trace_no_range(self):
- # This trace has no `timestamp_begin` and `timestamp_end` in its packet
- # context. The `trace-info` query should omit the `range-ns` fields in
- # the `trace` and `stream` data structures.
-
- res = self._executor.query(
- self._fs,
- "trace-info",
- {"paths": [os.path.join(test_ctf_traces_path, "succeed", "succeed1")]},
- )
-
- self.assertEqual(len(res), 1)
- trace = res[0]
- streams = trace["streams"]
- self.assertEqual(len(streams), 1)
-
- self.assertRaises(KeyError, lambda: trace['range-ns'])
- self.assertRaises(KeyError, lambda: streams[0]['range-ns'])
-
-
-if __name__ == '__main__':
- unittest.main()
--- /dev/null
+SUBDIRS = succeed
+dist_check_SCRIPTS = \
+ query/test_query_trace_info.py
--- /dev/null
+#!/bin/bash
+#
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; only version 2
+# of the License.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+NO_SH_TAP=1
+. "@abs_top_builddir@/tests/utils/common.sh"
+
+TESTRUNNER_PY="$BT_SRC_PATH/tests/utils/python/testrunner.py"
+THIS_DIR="$BT_SRC_PATH/tests/plugins/src.ctf.fs/query"
+
+exec "$BT_BUILD_PATH/tests/utils/test_python_bt2_env" python3 "$TESTRUNNER_PY" "$THIS_DIR"
--- /dev/null
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; only version 2
+# of the License.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+import unittest
+import bt2
+import os
+import re
+
+
+test_ctf_traces_path = os.environ['TEST_CTF_TRACES_PATH']
+
+
+# Key to sort streams in a predictable order.
+def sort_predictably(stream):
+ if 'range-ns' in stream:
+ return stream['range-ns']['begin']
+ else:
+ return stream['paths'][0]
+
+
+class QueryTraceInfoClockOffsetTestCase(unittest.TestCase):
+
+ def setUp(self):
+ ctf = bt2.find_plugin('ctf')
+ self._fs = ctf.source_component_classes['fs']
+
+ self._paths = [os.path.join(test_ctf_traces_path, 'intersection', '3eventsintersect')]
+ self._executor = bt2.QueryExecutor()
+
+ def _check(self, trace, offset):
+ self.assertEqual(trace['range-ns']['begin'], 13515309000000000 + offset)
+ self.assertEqual(trace['range-ns']['end'], 13515309000000120 + offset)
+ self.assertEqual(trace['intersection-range-ns']['begin'], 13515309000000070 + offset)
+ self.assertEqual(trace['intersection-range-ns']['end'], 13515309000000100 + offset)
+
+ streams = sorted(trace['streams'], key=sort_predictably)
+ self.assertEqual(streams[0]['range-ns']['begin'], 13515309000000000 + offset)
+ self.assertEqual(streams[0]['range-ns']['end'], 13515309000000100 + offset)
+ self.assertEqual(streams[1]['range-ns']['begin'], 13515309000000070 + offset)
+ self.assertEqual(streams[1]['range-ns']['end'], 13515309000000120 + offset)
+
+ # Test various cominations of the clock-class-offset-s and
+ # clock-class-offset-ns parameters to trace-info queries.
+
+ # Without clock class offset
+
+ def test_no_clock_class_offset(self):
+ res = self._executor.query(self._fs, 'trace-info', {
+ 'paths': self._paths,
+ })
+ trace = res[0]
+ self._check(trace, 0)
+
+ # With clock-class-offset-s
+
+ def test_clock_class_offset_s(self):
+ res = self._executor.query(self._fs, 'trace-info', {
+ 'paths': self._paths,
+ 'clock-class-offset-s': 2,
+ })
+ trace = res[0]
+ self._check(trace, 2000000000)
+
+ # With clock-class-offset-ns
+
+ def test_clock_class_offset_ns(self):
+ res = self._executor.query(self._fs, 'trace-info', {
+ 'paths': self._paths,
+ 'clock-class-offset-ns': 2,
+ })
+ trace = res[0]
+ self._check(trace, 2)
+
+ # With both, negative
+
+ def test_clock_class_offset_both(self):
+ res = self._executor.query(self._fs, 'trace-info', {
+ 'paths': self._paths,
+ 'clock-class-offset-s': -2,
+ 'clock-class-offset-ns': -2,
+ })
+ trace = res[0]
+ self._check(trace, -2000000002)
+
+ def test_clock_class_offset_s_wrong_type(self):
+ with self.assertRaises(bt2.InvalidQueryParams):
+ self._executor.query(self._fs, 'trace-info', {
+ 'paths': self._paths,
+ 'clock-class-offset-s': "2",
+ })
+
+ def test_clock_class_offset_s_wrong_type_none(self):
+ with self.assertRaises(bt2.InvalidQueryParams):
+ self._executor.query(self._fs, 'trace-info', {
+ 'paths': self._paths,
+ 'clock-class-offset-s': None,
+ })
+
+ def test_clock_class_offset_ns_wrong_type(self):
+ with self.assertRaises(bt2.InvalidQueryParams):
+ self._executor.query(self._fs, 'trace-info', {
+ 'paths': self._paths,
+ 'clock-class-offset-ns': "2",
+ })
+
+ def test_clock_class_offset_ns_wrong_type_none(self):
+ with self.assertRaises(bt2.InvalidQueryParams):
+ self._executor.query(self._fs, 'trace-info', {
+ 'paths': self._paths,
+ 'clock-class-offset-ns': None,
+ })
+
+
+class QueryTraceInfoPortNameTestCase(unittest.TestCase):
+ def setUp(self):
+ ctf = bt2.find_plugin("ctf")
+ self._fs = ctf.source_component_classes["fs"]
+
+ self._executor = bt2.QueryExecutor()
+
+ def test_trace_uuid_stream_class_id_no_stream_id(self):
+ res = self._executor.query(
+ self._fs,
+ "trace-info",
+ {
+ "paths": [
+ os.path.join(
+ test_ctf_traces_path, "intersection", "3eventsintersect"
+ )
+ ]
+ },
+ )
+ self.assertEqual(len(res), 1)
+ trace = res[0]
+ streams = sorted(trace["streams"], key=sort_predictably)
+ self.assertEqual(len(streams), 2)
+ self.assertRegexpMatches(
+ str(streams[0]["port-name"]),
+ r"^7afe8fbe-79b8-4f6a-bbc7-d0c782e7ddaf \| 0 \| .*/tests/ctf-traces/intersection/3eventsintersect/test_stream_0$",
+ )
+ self.assertRegexpMatches(
+ str(streams[1]["port-name"]),
+ r"^7afe8fbe-79b8-4f6a-bbc7-d0c782e7ddaf \| 0 \| .*/tests/ctf-traces/intersection/3eventsintersect/test_stream_1$",
+ )
+
+ def test_trace_uuid_no_stream_class_id_no_stream_id(self):
+ res = self._executor.query(
+ self._fs,
+ "trace-info",
+ {"paths": [os.path.join(test_ctf_traces_path, "succeed", "succeed1")]},
+ )
+ self.assertEqual(len(res), 1)
+ trace = res[0]
+ streams = sorted(trace["streams"], key=sort_predictably)
+ self.assertEqual(len(streams), 1)
+ self.assertRegexpMatches(
+ str(streams[0]["port-name"]),
+ r"^2a6422d0-6cee-11e0-8c08-cb07d7b3a564 \| .*/tests/ctf-traces/succeed/succeed1/dummystream$",
+ )
+
+
+class QueryTraceInfoRangeTestCase(unittest.TestCase):
+ def setUp(self):
+ ctf = bt2.find_plugin("ctf")
+ self._fs = ctf.source_component_classes["fs"]
+
+ self._executor = bt2.QueryExecutor()
+
+ def test_trace_no_range(self):
+ # This trace has no `timestamp_begin` and `timestamp_end` in its packet
+ # context. The `trace-info` query should omit the `range-ns` fields in
+ # the `trace` and `stream` data structures.
+
+ res = self._executor.query(
+ self._fs,
+ "trace-info",
+ {"paths": [os.path.join(test_ctf_traces_path, "succeed", "succeed1")]},
+ )
+
+ self.assertEqual(len(res), 1)
+ trace = res[0]
+ streams = trace["streams"]
+ self.assertEqual(len(streams), 1)
+
+ self.assertRaises(KeyError, lambda: trace['range-ns'])
+ self.assertRaises(KeyError, lambda: streams[0]['range-ns'])
+
+
+if __name__ == '__main__':
+ unittest.main()
--- /dev/null
+dist_check_SCRIPTS = test_succeed
+
+# Expectation files
+EXTRA_DIST = \
+ trace-smalltrace.expect \
+ trace-simple.expect
+
+# CTF trace generators
+GEN_TRACE_LDADD = $(top_builddir)/src/ctf-writer/libbabeltrace2-ctf-writer.la
+
+gen_trace_simple_SOURCES = gen-trace-simple.c
+gen_trace_simple_LDADD = $(GEN_TRACE_LDADD)
+
+noinst_PROGRAMS = \
+ gen-trace-simple
--- /dev/null
+/*
+ * Copyright 2019 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <stdint.h>
+#include <babeltrace2/ctf-writer/writer.h>
+#include <babeltrace2/ctf-writer/clock.h>
+#include <babeltrace2/ctf-writer/clock-class.h>
+#include <babeltrace2/ctf-writer/stream.h>
+#include <babeltrace2/ctf-writer/event.h>
+#include <babeltrace2/ctf-writer/event-types.h>
+#include <babeltrace2/ctf-writer/event-fields.h>
+#include <babeltrace2/ctf-writer/stream-class.h>
+#include <babeltrace2/ctf-writer/trace.h>
+
+#include "common/assert.h"
+
+struct config {
+ struct bt_ctf_writer *writer;
+ struct bt_ctf_trace *trace;
+ struct bt_ctf_clock *clock;
+ struct bt_ctf_stream_class *sc;
+ struct bt_ctf_stream *stream;
+ struct bt_ctf_event_class *ec;
+};
+
+static
+void fini_config(struct config *cfg)
+{
+ bt_ctf_object_put_ref(cfg->stream);
+ bt_ctf_object_put_ref(cfg->sc);
+ bt_ctf_object_put_ref(cfg->ec);
+ bt_ctf_object_put_ref(cfg->clock);
+ bt_ctf_object_put_ref(cfg->trace);
+ bt_ctf_object_put_ref(cfg->writer);
+}
+
+static
+void configure_writer(struct config *cfg, const char *path)
+{
+ struct bt_ctf_field_type *ft;
+ int ret;
+
+ cfg->writer = bt_ctf_writer_create(path);
+ BT_ASSERT(cfg->writer);
+ cfg->trace = bt_ctf_writer_get_trace(cfg->writer);
+ BT_ASSERT(cfg->trace);
+ cfg->clock = bt_ctf_clock_create("default");
+ BT_ASSERT(cfg->clock);
+ ret = bt_ctf_writer_add_clock(cfg->writer, cfg->clock);
+ BT_ASSERT(ret == 0);
+ ret = bt_ctf_writer_set_byte_order(cfg->writer,
+ BT_CTF_BYTE_ORDER_BIG_ENDIAN);
+ BT_ASSERT(ret == 0);
+ cfg->sc = bt_ctf_stream_class_create("hello");
+ BT_ASSERT(cfg->sc);
+ ret = bt_ctf_stream_class_set_clock(cfg->sc, cfg->clock);
+ BT_ASSERT(ret == 0);
+ cfg->ec = bt_ctf_event_class_create("ev");
+ BT_ASSERT(cfg->ec);
+ ft = bt_ctf_field_type_integer_create(8);
+ BT_ASSERT(ft);
+ ret = bt_ctf_field_type_integer_set_is_signed(ft, BT_TRUE);
+ BT_ASSERT(ret == 0);
+ ret = bt_ctf_event_class_add_field(cfg->ec, ft, "first");
+ BT_ASSERT(ret == 0);
+ bt_ctf_object_put_ref(ft);
+ ft = bt_ctf_field_type_string_create();
+ BT_ASSERT(ft);
+ ret = bt_ctf_event_class_add_field(cfg->ec, ft, "second");
+ BT_ASSERT(ret == 0);
+ bt_ctf_object_put_ref(ft);
+ ret = bt_ctf_stream_class_add_event_class(cfg->sc, cfg->ec);
+ BT_ASSERT(ret == 0);
+ cfg->stream = bt_ctf_writer_create_stream(cfg->writer, cfg->sc);
+ BT_ASSERT(cfg->stream);
+}
+
+static
+void write_stream(struct config *cfg)
+{
+ struct bt_ctf_event *ev;
+ struct bt_ctf_field *field;
+ uint64_t i;
+ int ret;
+
+ for (i = 0; i < 25; i++) {
+ ev = bt_ctf_event_create(cfg->ec);
+ BT_ASSERT(ev);
+ field = bt_ctf_event_get_payload(ev, "first");
+ BT_ASSERT(field);
+ ret = bt_ctf_field_integer_signed_set_value(field, -23 + i);
+ BT_ASSERT(ret == 0);
+ bt_ctf_object_put_ref(field);
+ field = bt_ctf_event_get_payload(ev, "second");
+ BT_ASSERT(field);
+ ret = bt_ctf_field_string_set_value(field, "saluuuut");
+ BT_ASSERT(ret == 0);
+ bt_ctf_object_put_ref(field);
+ ret = bt_ctf_clock_set_time(cfg->clock, 3600 + i * 5000);
+ BT_ASSERT(ret == 0);
+ ret = bt_ctf_stream_append_event(cfg->stream, ev);
+ BT_ASSERT(ret == 0);
+ bt_ctf_object_put_ref(ev);
+ }
+
+ ret = bt_ctf_stream_flush(cfg->stream);
+ BT_ASSERT(ret == 0);
+}
+
+int main(int argc, char **argv)
+{
+ struct config cfg = {0};
+
+ BT_ASSERT(argc >= 2);
+ configure_writer(&cfg, argv[1]);
+ write_stream(&cfg);
+ fini_config(&cfg);
+ return 0;
+}
--- /dev/null
+#!/bin/bash
+#
+# Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; only version 2
+# of the License.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# This test validates that a `src.ctf.fs` component successfully reads
+# specific CTF traces and creates the expected messages.
+#
+# Such CTF traces to open either exist (in `tests/ctf-traces/succeed`)
+# or are generated by this test using local trace generators.
+
+. "@abs_top_builddir@/tests/utils/diff.sh"
+
+this_dir_relative="tests/plugins/src.ctf.fs/succeed"
+this_dir_src="$BT_SRC_PATH/$this_dir_relative"
+this_dir_build="$BT_BUILD_PATH/$this_dir_relative"
+succeed_trace_dir="$BT_CTF_TRACES/succeed"
+
+test_ctf_common_details_args="-p with-trace-name=no,with-stream-name=no"
+
+test_ctf_gen_single() {
+ name="$1"
+
+ diag "Generating trace '$name'"
+ bt_diff_details_ctf_gen_single "$this_dir_build/gen-trace-$name" \
+ "$this_dir_src/trace-$name.expect" \
+ "$test_ctf_common_details_args -p with-uuid=no"
+ ok $? "Generated trace '$name' gives the expected output"
+}
+
+test_ctf_single() {
+ name="$1"
+
+ bt_diff_details_ctf_single "$succeed_trace_dir/$name" \
+ "$this_dir_src/trace-$name.expect" "$test_ctf_common_details_args"
+ ok $? "Trace '$name' gives the expected output"
+}
+
+plan_tests 2
+
+test_ctf_gen_single simple
+test_ctf_single smalltrace
--- /dev/null
+Trace class:
+ Stream class (ID 0):
+ Packets have beginning default clock snapshot: Yes
+ Packets have end default clock snapshot: Yes
+ Supports discarded events: Yes
+ Discarded events have default clock snapshots: Yes
+ Supports discarded packets: No
+ Discarded packets have default clock snapshots: No
+ Default clock class:
+ Name: default
+ Frequency (Hz): 1,000,000,000
+ Precision (cycles): 1
+ Offset (s): 0
+ Offset (cycles): 0
+ Origin is Unix epoch: No
+ Event class `ev` (ID 0):
+ Payload field class: Structure (2 members):
+ first: Signed integer (8-bit, Base 10)
+ second: String
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[Unknown]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream activity beginning
+
+[0 cycles, 0 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet beginning:
+
+[3600 cycles, 3600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -23
+ second: saluuuut
+
+[8600 cycles, 8600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -22
+ second: saluuuut
+
+[13,600 cycles, 13,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -21
+ second: saluuuut
+
+[18,600 cycles, 18,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -20
+ second: saluuuut
+
+[23,600 cycles, 23,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -19
+ second: saluuuut
+
+[28,600 cycles, 28,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -18
+ second: saluuuut
+
+[33,600 cycles, 33,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -17
+ second: saluuuut
+
+[38,600 cycles, 38,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -16
+ second: saluuuut
+
+[43,600 cycles, 43,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -15
+ second: saluuuut
+
+[48,600 cycles, 48,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -14
+ second: saluuuut
+
+[53,600 cycles, 53,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -13
+ second: saluuuut
+
+[58,600 cycles, 58,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -12
+ second: saluuuut
+
+[63,600 cycles, 63,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -11
+ second: saluuuut
+
+[68,600 cycles, 68,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -10
+ second: saluuuut
+
+[73,600 cycles, 73,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -9
+ second: saluuuut
+
+[78,600 cycles, 78,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -8
+ second: saluuuut
+
+[83,600 cycles, 83,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -7
+ second: saluuuut
+
+[88,600 cycles, 88,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -6
+ second: saluuuut
+
+[93,600 cycles, 93,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -5
+ second: saluuuut
+
+[98,600 cycles, 98,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -4
+ second: saluuuut
+
+[103,600 cycles, 103,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -3
+ second: saluuuut
+
+[108,600 cycles, 108,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -2
+ second: saluuuut
+
+[113,600 cycles, 113,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: -1
+ second: saluuuut
+
+[118,600 cycles, 118,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: 0
+ second: saluuuut
+
+[123,600 cycles, 123,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `ev` (Class ID 0):
+ Payload:
+ first: 1
+ second: saluuuut
+
+[123,600 cycles, 123,600 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet end
+
+[Unknown]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream activity end
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+Trace class:
+ UUID: 2a6422d0-6cee-11e0-8c08-cb07d7b3a564
+ Stream class (ID 0):
+ Packets have beginning default clock snapshot: No
+ Packets have end default clock snapshot: No
+ Supports discarded events: No
+ Discarded events have default clock snapshots: No
+ Supports discarded packets: No
+ Discarded packets have default clock snapshots: No
+ Event class `string` (ID 0):
+ Payload field class: Structure (1 member):
+ str: String
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Class UUID: 2a6422d0-6cee-11e0-8c08-cb07d7b3a564
+ Stream (ID 0, Class ID 0)
+
+[Unknown]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream activity beginning
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet beginning:
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `string` (Class ID 0):
+ Payload:
+ str: This is a test trace
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `string` (Class ID 0):
+ Payload:
+ str: with only two small events.
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet end
+
+[Unknown]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream activity end
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+#!/bin/sh
+
+# Copyright (C) 2019 - Philippe Proulx <pproulx@efficios.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; only version 2
+# of the License.
+#
+# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+. "@abs_top_builddir@/tests/utils/common.sh"
+
+# Checks the difference between:
+#
+# 1. What the CLI outputs when given the arguments "$1" (passed to
+# `xargs`, so they can include quoted arguments).
+# 2. The file with path "$2".
+#
+# Returns 0 if there's no difference, and 1 if there is, also printing
+# said difference to the standard error.
+bt_diff_cli() {
+ args="$1"
+ expected_file="$2"
+ temp_output_file="$(mktemp)"
+ temp_diff="$(mktemp)"
+
+ # Run the CLI to get a detailed file
+ echo "$args" | xargs "$BT_BIN" 2>/dev/null >"$temp_output_file"
+
+ # Compare output with expected output
+ if ! diff "$temp_output_file" "$expected_file" 2>/dev/null >"$temp_diff"; then
+ echo "ERROR: for '$args': actual and expected outputs differ:" >&2
+ cat "$temp_diff" >&2
+ rm -rf "$temp_output_file" "$temp_diff"
+ return 1
+ fi
+
+ rm -f "$temp_output_file" "$temp_diff"
+}
+
+# Checks the difference between:
+#
+# 1. What the CLI outputs when given the arguments:
+#
+# "$1" -c sink.text.details $3
+#
+# 2. The file with path "$2".
+#
+# Parameter 3 is optional.
+#
+# Returns 0 if there's no difference, and 1 if there is, also printing
+# said difference to the standard error.
+bt_diff_details_ctf_single() {
+ trace_dir="$1"
+ expected_file="$2"
+ extra_details_args=""
+
+ if [ $# -ge 3 ]; then
+ extra_details_args="$3"
+ fi
+
+ # Compare using the CLI with `sink.text.details`
+ bt_diff_cli "\"$trace_dir\" -c sink.text.details $extra_details_args" "$expected_file"
+}
+
+# Calls bt_diff_details_ctf_single(), except that "$1" is the path to a
+# program which generates the CTF trace to compare to. The program "$1"
+# receives the path to a temporary, empty directory where to write the
+# CTF trace as its first argument.
+bt_diff_details_ctf_gen_single() {
+ ctf_gen_prog_path="$1"
+ expected_file="$2"
+ extra_details_args=""
+
+ if [ $# -ge 3 ]; then
+ extra_details_args="$3"
+ fi
+
+ temp_trace_dir="$(mktemp -d)"
+
+ # Run the CTF trace generator program to get a CTF trace
+ if ! "$ctf_gen_prog_path" "$temp_trace_dir" 2>/dev/null; then
+ echo "ERROR: \"$ctf_gen_prog_path\" \"$temp_trace_dir\" failed" >&2
+ rm -rf "$temp_trace_dir"
+ return 1
+ fi
+
+ # Compare using the CLI with `sink.text.details`
+ bt_diff_details_ctf_single "$temp_trace_dir" "$expected_file" "$extra_details_args"
+ ret=$?
+ rm -rf "$temp_trace_dir"
+ return $ret
+}