3 # The MIT License (MIT)
5 # Copyright (C) 2016 - Jérémie Galarneau <jeremie.galarneau@efficios.com>
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:
14 # The above copyright notice and this permission notice shall be included in
15 # all copies or substantial portions of the Software.
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
25 import bt_python_helper
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
40 def __init__(self
, timestamps
):
41 self
.timestamps
= timestamps
43 clock_uuid
= uuid
.uuid4()
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
)
53 integer_field_type
= babeltrace
.CTFWriter
.IntegerFieldDeclaration(32)
55 event_class
= babeltrace
.CTFWriter
.EventClass('simple_event')
56 event_class
.add_field(integer_field_type
, 'int_field')
58 stream_class
= babeltrace
.CTFWriter
.StreamClass('test_stream')
59 stream_class
.add_event_class(event_class
)
60 stream_class
.clock
= clock
64 for stream_id
, stream_packets
in enumerate(stream_descriptions
):
65 stream
= trace
.create_stream(stream_class
)
66 streams
.append(stream
)
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
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()
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
))
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
))
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
)
108 print('1..{}'.format(TEST_COUNT
))
110 trace_path_early
= tempfile
.mkdtemp()
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))]
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))]
131 expected_timestamps_early
= []
132 for ts
in range(11, 14):
133 for stream
in range(3):
134 expected_timestamps_early
.append(ts
)
136 expected_timestamps_late
= []
137 for ts
in range(100, 105):
138 for stream
in range(3):
139 expected_timestamps_late
.append(ts
)
141 expected_timestamps_union
= (expected_timestamps_early
+
142 expected_timestamps_late
)
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')
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')
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')
158 shutil
.rmtree(trace_path_early
)
159 shutil
.rmtree(trace_path_late
)