Add tests: CTF writer: `timestamp_begin`/`timestamp_end` autopopulation
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Mon, 19 Feb 2018 21:45:55 +0000 (16:45 -0500)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 2 May 2019 03:32:03 +0000 (23:32 -0400)
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 <eeppeliteloop@gmail.com>
.gitignore
configure.ac
tests/Makefile.am
tests/lib/Makefile.am
tests/lib/ctf-writer/Makefile.am [new file with mode: 0644]
tests/lib/ctf-writer/test_auto_populate.py [new file with mode: 0644]
tests/lib/ctf-writer/test_ctf_writer.in [new file with mode: 0644]

index 50a47ad708a74d0e29be3534afc346a42008fa7e..b2dcb450c74326241ca2fe2b352c22ac6075fe05 100644 (file)
@@ -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
index 27ec6ee2d379a12d1936721119c86360ee63f293..1ffe69623fe418cf8c580abb1015abb46da29729 100644 (file)
@@ -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])
index a0d9dcc28fc9f48922da8ea68a07aa55a8edac5f..b137b01dacdf1b4ece7e314a0b6961a509f8b788 100644 (file)
@@ -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 =
index 1bfc722232a50e51200f3be2e364a664615053c8..6b7030ee4480aa0466629fdba85fec41cdfa4b44 100644 (file)
@@ -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 (file)
index 0000000..8a64072
--- /dev/null
@@ -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 (file)
index 0000000..342b23a
--- /dev/null
@@ -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 (file)
index 0000000..6cdb7c4
--- /dev/null
@@ -0,0 +1,36 @@
+#!/bin/bash
+#
+# Copyright (C) 2017 - 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.
+#
+
+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 $?
This page took 0.029744 seconds and 4 git commands to generate.