From: Jérémie Galarneau Date: Wed, 11 May 2016 19:45:46 +0000 (-0400) Subject: Tests: Multi-trace stream intersection test X-Git-Tag: v2.0.0-pre1~953 X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=5df9e303fa9d81b3a6d989612c7a98039ec76fd1 Tests: Multi-trace stream intersection test Signed-off-by: Jérémie Galarneau --- diff --git a/.gitignore b/.gitignore index 527d1955..c290479b 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/configure.ac b/configure.ac index a569108f..7a31bc7b 100644 --- a/configure.ac +++ b/configure.ac @@ -347,6 +347,7 @@ AC_CONFIG_FILES([ bindings/python/Makefile tests/Makefile tests/bin/Makefile + tests/bin/intersection/Makefile tests/lib/Makefile tests/utils/Makefile tests/utils/tap/Makefile @@ -363,8 +364,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 diff --git a/tests/Makefile.am b/tests/Makefile.am index 9b9adb66..467b191f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -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 \ @@ -23,3 +23,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 diff --git a/tests/bin/Makefile.am b/tests/bin/Makefile.am index 0d56c6d7..2d008ed4 100644 --- a/tests/bin/Makefile.am +++ b/tests/bin/Makefile.am @@ -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 index 00000000..664bc3a0 --- /dev/null +++ b/tests/bin/intersection/Makefile.am @@ -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 index 00000000..4b9fcaf7 --- /dev/null +++ b/tests/bin/intersection/bt_python_helper.py.in @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# +# The MIT License (MIT) +# +# Copyright (C) 2016 - Jérémie Galarneau +# +# 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' +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 index 00000000..689fbc1e --- /dev/null +++ b/tests/bin/intersection/test_intersection.in @@ -0,0 +1,55 @@ +#!/bin/bash +# +# Copyright (C) - 2015 Julien Desfossez +# +# 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 index 00000000..b4368a11 --- /dev/null +++ b/tests/bin/intersection/test_multi_trace_intersection.py @@ -0,0 +1,160 @@ +#!/usr/bin/env python3 +# +# The MIT License (MIT) +# +# Copyright (C) 2016 - Jérémie Galarneau +# +# 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.writer as btw +import babeltrace.reader as btr +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 = btw.Writer(path) + clock = btw.Clock('test_clock') + clock.uuid = clock_uuid + trace.add_clock(clock) + + integer_field_type = btw.IntegerFieldDeclaration(32) + + event_class = btw.EventClass('simple_event') + event_class.add_field(integer_field_type, 'int_field') + + stream_class = btw.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 = btw.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 = btr.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 index 82eac235..00000000 --- a/tests/bin/test_intersection.in +++ /dev/null @@ -1,56 +0,0 @@ -#!/bin/bash -# -# Copyright (C) - 2015 Julien Desfossez -# -# 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