Tests: Multi-trace stream intersection test
[babeltrace.git] / tests / bin / intersection / test_multi_trace_intersection.py
1 #!/usr/bin/env python3
2 #
3 # The MIT License (MIT)
4 #
5 # Copyright (C) 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
6 #
7 # Permission is hereby granted, free of charge, to any person obtaining a copy
8 # of this software and associated documentation files (the "Software"), to deal
9 # in the Software without restriction, including without limitation the rights
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 # copies of the Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice shall be included in
15 # all copies or substantial portions of the Software.
16 #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 # SOFTWARE.
24
25 import bt_python_helper
26 import tempfile
27 import babeltrace
28 import uuid
29 import shutil
30
31
32 class Entry(object):
33 def __init__(self, stream_id, timestamp=None, end_of_packet=False):
34 self.stream_id = stream_id
35 self.timestamp = timestamp
36 self.end_of_packet = end_of_packet
37
38
39 class Packet(object):
40 def __init__(self, timestamps):
41 self.timestamps = timestamps
42
43 clock_uuid = uuid.uuid4()
44
45 # stream_descriptions is a list of lists of Packets.
46 # Each stream description list is mapped to a single stream instance.
47 def create_trace(path, clock_uuid, stream_descriptions):
48 trace = babeltrace.CTFWriter.Writer(path)
49 clock = babeltrace.CTFWriter.Clock('test_clock')
50 clock.uuid = clock_uuid
51 trace.add_clock(clock)
52
53 integer_field_type = babeltrace.CTFWriter.IntegerFieldDeclaration(32)
54
55 event_class = babeltrace.CTFWriter.EventClass('simple_event')
56 event_class.add_field(integer_field_type, 'int_field')
57
58 stream_class = babeltrace.CTFWriter.StreamClass('test_stream')
59 stream_class.add_event_class(event_class)
60 stream_class.clock = clock
61
62 streams = []
63 stream_entries = []
64 for stream_id, stream_packets in enumerate(stream_descriptions):
65 stream = trace.create_stream(stream_class)
66 streams.append(stream)
67
68 for packet in stream_packets:
69 for timestamp in packet.timestamps:
70 stream_entries.append(Entry(stream_id, timestamp))
71 # Mark the last inserted entry as the end of packet
72 stream_entries[len(stream_entries) - 1].end_of_packet = True
73
74 # Sort stream entries which will provide us with a time-ordered list of
75 # events to insert in the streams.
76 for entry in sorted(stream_entries, key=lambda entry: entry.timestamp):
77 clock.time = entry.timestamp
78 event = babeltrace.CTFWriter.Event(event_class)
79 event.payload('int_field').value = entry.stream_id
80 streams[entry.stream_id].append_event(event)
81 if entry.end_of_packet is True:
82 streams[entry.stream_id].flush()
83
84
85 def check_trace_expected_timestamps(trace_paths, expected_timestamps):
86 traces = babeltrace.TraceCollection(intersect_mode=True)
87 for trace_path in trace_paths:
88 trace_handle = traces.add_trace(trace_path, 'ctf')
89 if trace_handle is None:
90 print('Failed to open trace at {}'.format(trace_path))
91 return False
92 for event in traces.events:
93 expected_timestamp = expected_timestamps.pop(0)
94 if event.timestamp != expected_timestamp:
95 print('# Unexpected timestamp ({}), expected {}'.format(
96 event.timestamp, expected_timestamp))
97 return False
98 return True
99
100
101 def print_test_result(test_number, result, description):
102 result_string = 'ok' if result else 'not ok'
103 result_string += ' {} - {}'.format(test_number, description)
104 print(result_string)
105
106 TEST_COUNT = 3
107 # TAP plan
108 print('1..{}'.format(TEST_COUNT))
109
110 trace_path_early = tempfile.mkdtemp()
111
112 # The stream intersection of this trace is event timestamps 11, 12 and 13,
113 # accounting for 9 events in stream-intersection mode
114 print('# Creating early trace at {}'.format(trace_path_early))
115 create_trace(trace_path_early, clock_uuid, [
116 [Packet(range(1, 7)), Packet(range(11, 18))],
117 [Packet(range(8, 15)), Packet(range(22, 24)), Packet(range(30, 60))],
118 [Packet(range(11, 14))]
119 ])
120
121 trace_path_late = tempfile.mkdtemp()
122 print('# Creating late trace at {}'.format(trace_path_late))
123 # The stream intersection of this trace is event timestamps 100, 101, 102, 103
124 # and 104 accounting for 15 events in stream-intersection mode
125 create_trace(trace_path_late, clock_uuid, [
126 [Packet(range(100, 105)), Packet(range(109, 120))],
127 [Packet(range(88, 95)), Packet(range(96, 110)), Packet(range(112, 140))],
128 [Packet(range(99, 105))]
129 ])
130
131 expected_timestamps_early = []
132 for ts in range(11, 14):
133 for stream in range(3):
134 expected_timestamps_early.append(ts)
135
136 expected_timestamps_late = []
137 for ts in range(100, 105):
138 for stream in range(3):
139 expected_timestamps_late.append(ts)
140
141 expected_timestamps_union = (expected_timestamps_early +
142 expected_timestamps_late)
143
144 # Validate that the stream-intersection mode on a single trace returns only
145 # the events that are in overlapping packets across all of the trace's streams.
146 result = check_trace_expected_timestamps([trace_path_early],
147 expected_timestamps_early)
148 print_test_result(1, result, 'Validating expected event timestamps of "early" trace')
149
150 result = check_trace_expected_timestamps([trace_path_late],
151 expected_timestamps_late)
152 print_test_result(2, result, 'Validating expected event timestamps of "late" trace')
153
154 result = check_trace_expected_timestamps([trace_path_early, trace_path_late],
155 expected_timestamps_union)
156 print_test_result(3, result, 'Validating expected event timestamps of the union of "early" and "late" traces')
157
158 shutil.rmtree(trace_path_early)
159 shutil.rmtree(trace_path_late)
This page took 0.032309 seconds and 4 git commands to generate.