From d461e009b19e525d003762586f3f7d30ed5f5f6f Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Mon, 19 Feb 2018 16:45:55 -0500 Subject: [PATCH] Add tests: CTF writer: `timestamp_begin`/`timestamp_end` autopopulation Those new tests validate that the automatic population of the `timestamp_begin` and `timestamp_end` fields in CTF writer work as expected. Signed-off-by: Philippe Proulx --- .gitignore | 1 + configure.ac | 2 + tests/Makefile.am | 1 + tests/lib/Makefile.am | 2 +- tests/lib/ctf-writer/Makefile.am | 5 + tests/lib/ctf-writer/test_auto_populate.py | 263 +++++++++++++++++++++ tests/lib/ctf-writer/test_ctf_writer.in | 36 +++ 7 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 tests/lib/ctf-writer/Makefile.am create mode 100644 tests/lib/ctf-writer/test_auto_populate.py create mode 100644 tests/lib/ctf-writer/test_ctf_writer.in diff --git a/.gitignore b/.gitignore index 50a47ad7..b2dcb450 100644 --- a/.gitignore +++ b/.gitignore @@ -34,6 +34,7 @@ /tests/lib/test_cc_prio_map /tests/lib/test_graph_topo /tests/lib/ctf-ir/test_ctf_ir +/tests/lib/ctf-writer/test_ctf_writer /tests/plugins/test-utils-muxer /tests/plugins/test-utils-muxer-complete /tests/plugins/test_lttng_utils_debug_info diff --git a/configure.ac b/configure.ac index 27ec6ee2..1ffe6962 100644 --- a/configure.ac +++ b/configure.ac @@ -740,6 +740,7 @@ AC_CONFIG_FILES([ tests/lib/Makefile tests/lib/test-plugin-plugins/Makefile tests/lib/ctf-ir/Makefile + tests/lib/ctf-writer/Makefile tests/utils/common.sh tests/utils/Makefile tests/utils/tap/Makefile @@ -785,6 +786,7 @@ AC_CONFIG_FILES([tests/cli/test_trimmer], [chmod +x tests/cli/test_trimmer]) AC_CONFIG_FILES([tests/lib/test_ctf_writer_complete], [chmod +x tests/lib/test_ctf_writer_complete]) AC_CONFIG_FILES([tests/lib/test_plugin_complete], [chmod +x tests/lib/test_plugin_complete]) AC_CONFIG_FILES([tests/lib/ctf-ir/test_ctf_ir], [chmod +x tests/lib/ctf-ir/test_ctf_ir]) +AC_CONFIG_FILES([tests/lib/ctf-writer/test_ctf_writer], [chmod +x tests/lib/ctf-writer/test_ctf_writer]) 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_complete], [chmod +x tests/plugins/test_dwarf_complete]) diff --git a/tests/Makefile.am b/tests/Makefile.am index a0d9dcc2..b137b01d 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -41,6 +41,7 @@ endif if ENABLE_PYTHON_BINDINGS TESTS_LIB += lib/ctf-ir/test_ctf_ir +TESTS_LIB += lib/ctf-writer/test_ctf_writer endif TESTS_PLUGINS = diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am index 1bfc7222..6b7030ee 100644 --- a/tests/lib/Makefile.am +++ b/tests/lib/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = ctf-ir +SUBDIRS = ctf-ir ctf-writer AM_CPPFLAGS += -I$(top_srcdir)/tests/utils diff --git a/tests/lib/ctf-writer/Makefile.am b/tests/lib/ctf-writer/Makefile.am new file mode 100644 index 00000000..8a64072c --- /dev/null +++ b/tests/lib/ctf-writer/Makefile.am @@ -0,0 +1,5 @@ +if ENABLE_PYTHON_BINDINGS +check_SCRIPTS = test_ctf_writer +endif + +EXTRA_DIST = test_auto_populate.py diff --git a/tests/lib/ctf-writer/test_auto_populate.py b/tests/lib/ctf-writer/test_auto_populate.py new file mode 100644 index 00000000..342b23aa --- /dev/null +++ b/tests/lib/ctf-writer/test_auto_populate.py @@ -0,0 +1,263 @@ +import tempfile +import unittest +import bt2 +import shutil + + +class AutoPopulatePacketContextTimestampsTestCase(unittest.TestCase): + def setUp(self): + self._trace_path = tempfile.mkdtemp() + self._writer = bt2.CtfWriter(self._trace_path) + self._cc = bt2.ClockClass('default', int(1e9)) + self._writer.trace.add_clock_class(self._cc) + self._sc = bt2.StreamClass() + pcft = bt2.StructureFieldType() + pcft.append_field('packet_size', bt2.IntegerFieldType(32)) + pcft.append_field('content_size', bt2.IntegerFieldType(32)) + pcft.append_field('timestamp_begin', bt2.IntegerFieldType(64, mapped_clock_class=self._cc)) + pcft.append_field('timestamp_end', bt2.IntegerFieldType(64, mapped_clock_class=self._cc)) + self._sc.packet_context_field_type = pcft + + def tearDown(self): + shutil.rmtree(self._trace_path) + + def _get_trace_notifs(self): + del self._cc + del self._sc + del self._ec + del self._stream + del self._writer + specs = [bt2.ComponentSpec('ctf', 'fs', self._trace_path)] + notif_iter = bt2.TraceCollectionNotificationIterator(specs) + return list(notif_iter) + + def _complete_sc(self): + self._sc.add_event_class(self._ec) + self._writer.trace.add_stream_class(self._sc) + self._stream = self._sc() + + def _complete_sc_event_simple_ts(self): + ehft = bt2.StructureFieldType() + ehft.append_field('id', bt2.IntegerFieldType(32)) + ehft.append_field('timestamp', bt2.IntegerFieldType(16, mapped_clock_class=self._cc)) + self._sc.event_header_field_type = ehft + self._ec = bt2.EventClass('evt') + payloadft = bt2.StructureFieldType() + payloadft.append_field('value', bt2.IntegerFieldType(32)) + self._ec.payload_field_type = payloadft + self._complete_sc() + + def _complete_sc_event_ts_in_payload(self): + ehft = bt2.StructureFieldType() + ehft.append_field('id', bt2.IntegerFieldType(32)) + ehft.append_field('timestamp', bt2.IntegerFieldType(16, mapped_clock_class=self._cc)) + self._sc.event_header_field_type = ehft + self._ec = bt2.EventClass('evt') + payloadft = bt2.StructureFieldType() + payloadft.append_field('value', bt2.IntegerFieldType(32)) + payloadft.append_field('a_ts', bt2.IntegerFieldType(8, mapped_clock_class=self._cc)) + self._ec.payload_field_type = payloadft + self._complete_sc() + + def _append_event_simple_ts(self, ts): + evt = self._ec() + evt.header_field['timestamp'] = ts + evt.payload_field['value'] = 23 + self._stream.append_event(evt) + + def _append_event_ts_in_payload(self, header_ts, payload_ts): + evt = self._ec() + evt.header_field['timestamp'] = header_ts + evt.payload_field['value'] = 23 + evt.payload_field['a_ts'] = payload_ts + self._stream.append_event(evt) + + def _set_ts_begin_end(self, ts_begin=None, ts_end=None): + if ts_begin is not None: + self._stream.packet_context_field['timestamp_begin'] = ts_begin + + if ts_end is not None: + self._stream.packet_context_field['timestamp_end'] = ts_end + + def _get_packet_ts_begin_end(self, notifs): + ts_begin_end_list = [] + + for notif in notifs: + if type(notif) is bt2.PacketBeginningNotification: + ts_begin_end_list.append(( + int(notif.packet.context_field['timestamp_begin']), + int(notif.packet.context_field['timestamp_end']), + )) + + return ts_begin_end_list + + def test_ts_inc(self): + self._complete_sc_event_simple_ts() + self._append_event_simple_ts(12) + self._append_event_simple_ts(144) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 0) + self.assertEqual(ts_begin_end_list[0][1], 144) + + def test_ts_equal(self): + self._complete_sc_event_simple_ts() + self._append_event_simple_ts(12) + self._append_event_simple_ts(144) + self._append_event_simple_ts(144) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 0) + self.assertEqual(ts_begin_end_list[0][1], 144) + + def test_ts_wraps(self): + self._complete_sc_event_simple_ts() + self._append_event_simple_ts(12) + self._append_event_simple_ts(144) + self._append_event_simple_ts(11) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 0) + self.assertEqual(ts_begin_end_list[0][1], 65547) + + def test_ts_begin_from_0(self): + self._complete_sc_event_simple_ts() + self._append_event_simple_ts(12) + self._append_event_simple_ts(144) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 0) + self.assertEqual(ts_begin_end_list[0][1], 144) + + def test_ts_begin_from_last_ts_end(self): + self._complete_sc_event_simple_ts() + self._append_event_simple_ts(12) + self._append_event_simple_ts(144) + self._stream.flush() + self._append_event_simple_ts(2001) + self._append_event_simple_ts(3500) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 0) + self.assertEqual(ts_begin_end_list[0][1], 144) + self.assertEqual(ts_begin_end_list[1][0], 144) + self.assertEqual(ts_begin_end_list[1][1], 3500) + + def test_ts_begin_from_provided(self): + self._complete_sc_event_simple_ts() + self._set_ts_begin_end(ts_begin=17) + self._append_event_simple_ts(11) + self._append_event_simple_ts(15) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 17) + self.assertEqual(ts_begin_end_list[0][1], 65551) + + def test_ts_end_from_provided(self): + self._complete_sc_event_simple_ts() + self._set_ts_begin_end(ts_end=1001) + self._append_event_simple_ts(11) + self._append_event_simple_ts(15) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 0) + self.assertEqual(ts_begin_end_list[0][1], 1001) + + def test_ts_end_from_provided_equal(self): + self._complete_sc_event_simple_ts() + self._set_ts_begin_end(ts_end=1001) + self._append_event_simple_ts(11) + self._append_event_simple_ts(1001) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 0) + self.assertEqual(ts_begin_end_list[0][1], 1001) + + def test_ts_end_from_provided_too_small(self): + self._complete_sc_event_simple_ts() + self._set_ts_begin_end(ts_end=1001) + self._append_event_simple_ts(11) + self._append_event_simple_ts(1002) + + with self.assertRaises(bt2.Error): + self._stream.flush() + + def test_ts_begin_provided_equal_last_ts_end_two_packets(self): + self._complete_sc_event_simple_ts() + self._append_event_simple_ts(12) + self._append_event_simple_ts(1001) + self._stream.flush() + self._set_ts_begin_end(ts_begin=1001) + self._append_event_simple_ts(2001) + self._append_event_simple_ts(3500) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 0) + self.assertEqual(ts_begin_end_list[0][1], 1001) + self.assertEqual(ts_begin_end_list[1][0], 1001) + self.assertEqual(ts_begin_end_list[1][1], 3500) + + def test_ts_begin_provided_less_than_last_ts_end_two_packets(self): + self._complete_sc_event_simple_ts() + self._append_event_simple_ts(12) + self._append_event_simple_ts(1001) + self._stream.flush() + self._set_ts_begin_end(ts_begin=1000) + self._append_event_simple_ts(2001) + self._append_event_simple_ts(3500) + + with self.assertRaises(bt2.Error): + self._stream.flush() + + def test_ts_end_from_value_event_payload(self): + self._complete_sc_event_ts_in_payload() + self._append_event_ts_in_payload(11, 15) + self._append_event_ts_in_payload(5, 10) + self._append_event_ts_in_payload(18, 10) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 0) + self.assertEqual(ts_begin_end_list[0][1], 65802) + + def test_empty_packet_auto_ts_begin_end(self): + self._complete_sc_event_simple_ts() + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 0) + self.assertEqual(ts_begin_end_list[0][1], 0) + + def test_empty_packet_provided_ts_begin(self): + self._complete_sc_event_simple_ts() + self._set_ts_begin_end(ts_begin=1001) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 1001) + self.assertEqual(ts_begin_end_list[0][1], 1001) + + def test_empty_packet_provided_ts_end(self): + self._complete_sc_event_simple_ts() + self._set_ts_begin_end(ts_end=1001) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 0) + self.assertEqual(ts_begin_end_list[0][1], 1001) + + def test_empty_packet_provided_ts_begin_end(self): + self._complete_sc_event_simple_ts() + self._set_ts_begin_end(1001, 3003) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 1001) + self.assertEqual(ts_begin_end_list[0][1], 3003) + + def test_empty_packet_ts_begin_from_last_ts_end(self): + self._complete_sc_event_simple_ts() + self._set_ts_begin_end(1001, 3003) + self._stream.flush() + self._set_ts_begin_end(ts_end=6000) + self._stream.flush() + ts_begin_end_list = self._get_packet_ts_begin_end(self._get_trace_notifs()) + self.assertEqual(ts_begin_end_list[0][0], 1001) + self.assertEqual(ts_begin_end_list[0][1], 3003) + self.assertEqual(ts_begin_end_list[1][0], 3003) + self.assertEqual(ts_begin_end_list[1][1], 6000) diff --git a/tests/lib/ctf-writer/test_ctf_writer.in b/tests/lib/ctf-writer/test_ctf_writer.in new file mode 100644 index 00000000..6cdb7c41 --- /dev/null +++ b/tests/lib/ctf-writer/test_ctf_writer.in @@ -0,0 +1,36 @@ +#!/bin/bash +# +# Copyright (C) 2017 - Philippe Proulx +# +# 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" + +PYTHON_BUILD_DIR="${BT_BUILD_PATH}/bindings/python/bt2/build/build_lib" +TESTS_UTILS_PYTHON_DIR="${BT_SRC_PATH}/tests/utils/python" +TESTRUNNER_PY="${BT_SRC_PATH}/tests/utils/python/testrunner.py" +THIS_DIR="${BT_SRC_PATH}/tests/lib/ctf-writer" + +if [ "x${MSYSTEM}" != "x" ]; then + export PATH="${BT_BUILD_PATH}/lib/.libs:${PATH}" +else + export LD_LIBRARY_PATH="${BT_BUILD_PATH}/lib/.libs:${LD_LIBRARY_PATH}" +fi + +PYTHONPATH="${PYTHON_BUILD_DIR}:${TESTS_UTILS_PYTHON_DIR}" \ + "@PYTHON@" "${TESTRUNNER_PY}" "${THIS_DIR}" +exit $? -- 2.34.1