Tests: Multi-trace stream intersection test
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Wed, 11 May 2016 19:45:46 +0000 (15:45 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 13 May 2016 20:06:00 +0000 (16:06 -0400)
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
.gitignore
configure.ac
tests/Makefile.am
tests/bin/Makefile.am
tests/bin/intersection/Makefile.am [new file with mode: 0644]
tests/bin/intersection/bt_python_helper.py.in [new file with mode: 0644]
tests/bin/intersection/test_intersection.in [new file with mode: 0644]
tests/bin/intersection/test_multi_trace_intersection.py [new file with mode: 0755]
tests/bin/test_intersection.in [deleted file]

index a1f883e21c751f7d4556c4bb7b5d5e5d5348f3db..a7c9e3ca4cd67bfbcbb8cdd4252e4de63e26c8d0 100644 (file)
@@ -1,6 +1,7 @@
 *~
 /tests/bin/test_trace_read
-/tests/bin/test_intersection
+/tests/bin/intersection/test_intersection
+/tests/bin/intersection/bt_python_helper.py
 /tests/bin/test_packet_seq_num
 /tests/lib/test_bitfield
 /tests/lib/test_seek
index 0157ec836dba9e0ff9020316209959dbcc683eb2..38b8a75f69088796f58ff78ad97765e83f0606b2 100644 (file)
@@ -313,6 +313,7 @@ AC_CONFIG_FILES([
        bindings/python/babeltrace/Makefile
        tests/Makefile
        tests/bin/Makefile
+       tests/bin/intersection/Makefile
        tests/lib/Makefile
        tests/utils/Makefile
        tests/utils/tap/Makefile
@@ -329,8 +330,10 @@ AC_CONFIG_FILES([tests/lib/test_dwarf_complete], [chmod +x tests/lib/test_dwarf_
 AC_CONFIG_FILES([tests/lib/test_bin_info_complete], [chmod +x tests/lib/test_bin_info_complete])
 
 AC_CONFIG_FILES([tests/bin/test_trace_read], [chmod +x tests/bin/test_trace_read])
-AC_CONFIG_FILES([tests/bin/test_intersection], [chmod +x tests/bin/test_intersection])
+AC_CONFIG_FILES([tests/bin/intersection/test_intersection], [chmod +x tests/bin/intersection/test_intersection])
+AC_CONFIG_FILES([tests/bin/intersection/bt_python_helper.py])
 AC_CONFIG_FILES([tests/bin/test_packet_seq_num], [chmod +x tests/bin/test_packet_seq_num])
+AC_CONFIG_FILES([tests/bin/intersection/test_multi_trace_intersection.py:tests/bin/intersection/test_multi_trace_intersection.py], [chmod +x tests/bin/intersection/test_multi_trace_intersection.py])
 
 AC_OUTPUT
 
index 7045aef90d8821b597a6b5839fc7e131fd15fbf2..98e0b85fd6730da73313166cb2a54b4ae8d64c62 100644 (file)
@@ -6,7 +6,7 @@ LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) \
 TESTS = bin/test_trace_read \
        bin/test_trace_read \
        bin/test_packet_seq_num \
-       bin/test_intersection \
+       bin/intersection/test_intersection \
        lib/test_bitfield \
        lib/test_seek_empty_packet \
        lib/test_seek_big_trace \
@@ -20,3 +20,7 @@ if ENABLE_DEBUGINFO
 TESTS += lib/test_dwarf_complete \
        lib/test_bin_info_complete
 endif
+
+if USE_PYTHON
+TESTS += bin/intersection/test_multi_trace_intersection.py
+endif
index 0d56c6d7762fab295f176fbfaab5bea690d948cf..2d008ed460ec243fc8dbb722f852c33fb5d828b5 100644 (file)
@@ -1 +1,2 @@
-check_SCRIPTS = test_trace_read test_intersection test_packet_seq_num
+SUBDIRS = intersection
+check_SCRIPTS = test_trace_read test_packet_seq_num
diff --git a/tests/bin/intersection/Makefile.am b/tests/bin/intersection/Makefile.am
new file mode 100644 (file)
index 0000000..664bc3a
--- /dev/null
@@ -0,0 +1,6 @@
+check_SCRIPTS = test_intersection \
+               bt_python_helper.py \
+               test_multi_trace_intersection.py
+
+SCRIPT_LIST = test_multi_trace_intersection.py
+dist_noinst_SCRIPTS = test_multi_trace_intersection.py
diff --git a/tests/bin/intersection/bt_python_helper.py.in b/tests/bin/intersection/bt_python_helper.py.in
new file mode 100644 (file)
index 0000000..11b4ab1
--- /dev/null
@@ -0,0 +1,37 @@
+#!/usr/bin/env python3
+#
+# The MIT License (MIT)
+#
+# Copyright (C) 2016 - Jérémie Galarneau <jeremie.galarneau@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.
+
+import sys
+
+# Point the Python interpreter to the builddir's library and Babeltrace
+# bindings
+bt_module_path = '@abs_top_builddir@/bindings/python/babeltrace'
+bt_lib_py_path = '@abs_top_builddir@/bindings/python/babeltrace/.libs'
+bt_lib_bt_path = '@abs_top_builddir@/lib/.libs'
+bt_lib_ctf_path = '@abs_top_builddir@/format/ctf/.libs'
+
+sys.path.insert(0, bt_module_path)
+sys.path.insert(1, bt_lib_py_path)
+sys.path.insert(2, bt_lib_bt_path)
+sys.path.insert(3, bt_lib_ctf_path)
diff --git a/tests/bin/intersection/test_intersection.in b/tests/bin/intersection/test_intersection.in
new file mode 100644 (file)
index 0000000..689fbc1
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/bash
+#
+# Copyright (C) - 2015 Julien Desfossez <jdesfossez@efficios.com>
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License, version 2 only, as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+# more details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+TESTDIR=@abs_top_srcdir@/tests
+
+BABELTRACE_BIN=@abs_top_builddir@/converter/babeltrace
+CTF_TRACES=@abs_top_srcdir@/tests/ctf-traces
+
+source $TESTDIR/utils/tap/tap.sh
+
+NUM_TESTS=10
+
+plan_tests $NUM_TESTS
+
+test_intersect() {
+       trace=$1
+       totalevents=$2
+       intersect=$3
+
+       test $($BABELTRACE_BIN $trace | wc -l) = $totalevents
+       ok $? "$totalevents events in the whole trace"
+       test $($BABELTRACE_BIN --stream-intersection $trace 2>/dev/null| wc -l) = $intersect
+       ok $? "$intersect events in packets intersecting"
+}
+
+diag "Test the stream intersection feature"
+
+diag "2 streams offsetted with 3 packets intersecting"
+test_intersect ${CTF_TRACES}/intersection/3eventsintersect 8 3
+
+diag "2 streams offsetted with 3 packets intersecting (exchanged file names)"
+test_intersect ${CTF_TRACES}/intersection/3eventsintersectreverse 8 3
+
+diag "No intersection between 2 streams"
+test_intersect ${CTF_TRACES}/intersection/nointersect 6 0
+
+diag "Only 1 stream"
+test_intersect ${CTF_TRACES}/intersection/onestream 3 3
+
+diag "No stream at all"
+test_intersect ${CTF_TRACES}/intersection/nostream 0 0
diff --git a/tests/bin/intersection/test_multi_trace_intersection.py b/tests/bin/intersection/test_multi_trace_intersection.py
new file mode 100755 (executable)
index 0000000..907b501
--- /dev/null
@@ -0,0 +1,159 @@
+#!/usr/bin/env python3
+#
+# The MIT License (MIT)
+#
+# Copyright (C) 2016 - Jérémie Galarneau <jeremie.galarneau@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.
+
+import bt_python_helper
+import tempfile
+import babeltrace
+import uuid
+import shutil
+
+
+class Entry(object):
+    def __init__(self, stream_id, timestamp=None, end_of_packet=False):
+        self.stream_id = stream_id
+        self.timestamp = timestamp
+        self.end_of_packet = end_of_packet
+
+
+class Packet(object):
+    def __init__(self, timestamps):
+        self.timestamps = timestamps
+
+clock_uuid = uuid.uuid4()
+
+# stream_descriptions is a list of lists of Packets.
+# Each stream description list is mapped to a single stream instance.
+def create_trace(path, clock_uuid, stream_descriptions):
+    trace = babeltrace.CTFWriter.Writer(path)
+    clock = babeltrace.CTFWriter.Clock('test_clock')
+    clock.uuid = clock_uuid
+    trace.add_clock(clock)
+
+    integer_field_type = babeltrace.CTFWriter.IntegerFieldDeclaration(32)
+
+    event_class = babeltrace.CTFWriter.EventClass('simple_event')
+    event_class.add_field(integer_field_type, 'int_field')
+
+    stream_class = babeltrace.CTFWriter.StreamClass('test_stream')
+    stream_class.add_event_class(event_class)
+    stream_class.clock = clock
+
+    streams = []
+    stream_entries = []
+    for stream_id, stream_packets in enumerate(stream_descriptions):
+        stream = trace.create_stream(stream_class)
+        streams.append(stream)
+
+        for packet in stream_packets:
+            for timestamp in packet.timestamps:
+                stream_entries.append(Entry(stream_id, timestamp))
+            # Mark the last inserted entry as the end of packet
+            stream_entries[len(stream_entries) - 1].end_of_packet = True
+
+    # Sort stream entries which will provide us with a time-ordered list of
+    # events to insert in the streams.
+    for entry in sorted(stream_entries, key=lambda entry: entry.timestamp):
+        clock.time = entry.timestamp
+        event = babeltrace.CTFWriter.Event(event_class)
+        event.payload('int_field').value = entry.stream_id
+        streams[entry.stream_id].append_event(event)
+        if entry.end_of_packet is True:
+            streams[entry.stream_id].flush()
+
+
+def check_trace_expected_timestamps(trace_paths, expected_timestamps):
+    traces = babeltrace.TraceCollection(intersect_mode=True)
+    for trace_path in trace_paths:
+        trace_handle = traces.add_trace(trace_path, 'ctf')
+        if trace_handle is None:
+            print('Failed to open trace at {}'.format(trace_path))
+            return False
+    for event in traces.events:
+        expected_timestamp = expected_timestamps.pop(0)
+        if event.timestamp != expected_timestamp:
+            print('# Unexpected timestamp ({}), expected {}'.format(
+                event.timestamp, expected_timestamp))
+            return False
+    return True
+
+
+def print_test_result(test_number, result, description):
+    result_string = 'ok' if result else 'not ok'
+    result_string += ' {} - {}'.format(test_number, description)
+    print(result_string)
+
+TEST_COUNT = 3
+# TAP plan
+print('1..{}'.format(TEST_COUNT))
+
+trace_path_early = tempfile.mkdtemp()
+
+# The stream intersection of this trace is event timestamps 11, 12 and 13,
+# accounting for 9 events in stream-intersection mode
+print('# Creating early trace at {}'.format(trace_path_early))
+create_trace(trace_path_early, clock_uuid, [
+    [Packet(range(1, 7)), Packet(range(11, 18))],
+    [Packet(range(8, 15)), Packet(range(22, 24)), Packet(range(30, 60))],
+    [Packet(range(11, 14))]
+    ])
+
+trace_path_late = tempfile.mkdtemp()
+print('# Creating late trace at {}'.format(trace_path_late))
+# The stream intersection of this trace is event timestamps 100, 101, 102, 103
+# and 104 accounting for 15 events in stream-intersection mode
+create_trace(trace_path_late, clock_uuid, [
+    [Packet(range(100, 105)), Packet(range(109, 120))],
+    [Packet(range(88, 95)), Packet(range(96, 110)), Packet(range(112, 140))],
+    [Packet(range(99, 105))]
+    ])
+
+expected_timestamps_early = []
+for ts in range(11, 14):
+    for stream in range(3):
+        expected_timestamps_early.append(ts)
+
+expected_timestamps_late = []
+for ts in range(100, 105):
+    for stream in range(3):
+        expected_timestamps_late.append(ts)
+
+expected_timestamps_union = (expected_timestamps_early +
+                            expected_timestamps_late)
+
+# Validate that the stream-intersection mode on a single trace returns only
+# the events that are in overlapping packets across all of the trace's streams.
+result = check_trace_expected_timestamps([trace_path_early],
+                                            expected_timestamps_early)
+print_test_result(1, result, 'Validating expected event timestamps of "early" trace')
+
+result = check_trace_expected_timestamps([trace_path_late],
+                                            expected_timestamps_late)
+print_test_result(2, result, 'Validating expected event timestamps of "late" trace')
+
+result = check_trace_expected_timestamps([trace_path_early, trace_path_late],
+                                            expected_timestamps_union)
+print_test_result(3, result, 'Validating expected event timestamps of the union of "early" and "late" traces')
+
+shutil.rmtree(trace_path_early)
+shutil.rmtree(trace_path_late)
diff --git a/tests/bin/test_intersection.in b/tests/bin/test_intersection.in
deleted file mode 100644 (file)
index 82eac23..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) - 2015 Julien Desfossez <jdesfossez@efficios.com>
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License, version 2 only, as
-# published by the Free Software Foundation.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-CURDIR=$(dirname $0)
-TESTDIR=$CURDIR/..
-
-BABELTRACE_BIN=$CURDIR/../../converter/babeltrace
-CTF_TRACES=@abs_top_srcdir@/tests/ctf-traces
-
-source $TESTDIR/utils/tap/tap.sh
-
-NUM_TESTS=10
-
-plan_tests $NUM_TESTS
-
-test_intersect() {
-       trace=$1
-       totalevents=$2
-       intersect=$3
-
-       test $($BABELTRACE_BIN $trace | wc -l) = $totalevents
-       ok $? "$totalevents events in the whole trace"
-       test $($BABELTRACE_BIN --stream-intersection $trace 2>/dev/null| wc -l) = $intersect
-       ok $? "$intersect events in packets intersecting"
-}
-
-diag "Test the stream intersection feature"
-
-diag "2 streams offsetted with 3 packets intersecting"
-test_intersect ${CTF_TRACES}/intersection/3eventsintersect 8 3
-
-diag "2 streams offsetted with 3 packets intersecting (exchanged file names)"
-test_intersect ${CTF_TRACES}/intersection/3eventsintersectreverse 8 3
-
-diag "No intersection between 2 streams"
-test_intersect ${CTF_TRACES}/intersection/nointersect 6 0
-
-diag "Only 1 stream"
-test_intersect ${CTF_TRACES}/intersection/onestream 3 3
-
-diag "No stream at all"
-test_intersect ${CTF_TRACES}/intersection/nostream 0 0
This page took 0.031428 seconds and 4 git commands to generate.