From 2e90378a2b94006e2743b06e7fe7a1f0e691a56e Mon Sep 17 00:00:00 2001 From: Philippe Proulx Date: Mon, 3 Jun 2019 12:16:11 -0400 Subject: [PATCH] lib: make discarded events/packets support and clock snapshots optional This patch adds functions to the stream class API to make it explicit that discarded events and/or discarded packets are supported for stream instances. The same functions are used to specify whether or not discarded events and discarded packets have time ranges, that is, default beginning and end clock snapshots. The basic use cases to support are: 1. CTF 1.8: packet context has `timestamp_begin`, `timestamp_end` packet context members, as well as `events_discarded` and/or `packet_seq_num` members. This is legit: LTTng produces this. 2. CTF 1.8: packet context has `events_discarded` and/or `packet_seq_num` packet context members, but no `timestamp_begin` and `timestamp_end` members. This is possible (barectf, other tracers). 3. Source has no concept of discarded events and/or packets. My initial approach was to have only the "discarded events have default clock snapshots" and "discarded packets have default clock snapshots" stream class properties, but they would need to be false by default (because there's no default clock class by default), and then `sink.ctf.fs` would, at least temporarily, require those default clock snapshots to exist for those messages when there's a default clock class, so simple sources without the discarded events/packets concept would always need to set both stream class properties. I found this weird, so the default is: * No discarded events support. * No discarded packets support. When you set that the streams of a given stream class support discarded events and packets, you specify at the same time if they have default clock snapshots: void bt_stream_class_set_supports_discarded_events( bt_stream_class *stream_class, bt_bool supports_discarded_events, bt_bool with_default_clock_snapshots); void bt_stream_class_set_supports_discarded_packets( bt_stream_class *stream_class, bt_bool supports_discarded_packets, bt_bool with_default_clock_snapshots); This means that a simple source can keep the default properties as is and not create any discarded events/packets messages; `sink.ctf.fs` will work fine. It is a precondition that the stream class has a default clock class when you call bt_stream_class_set_supports_discarded_events() or bt_stream_class_set_supports_discarded_packets() with the `with_default_clock_snapshots` parameter set. This patch satisfies the three use cases above with those configurations: 1. Discarded events and/or packets supported with default clock snapshots. 2. Discarded events and/or packets supported without default clock snapshots. 3. Discarded events and/or packets are not supported. The component classes are not modified to support custom configurations yet: * `src.ctf.fs` always supports discarded events/packets, and always with default clock snapshots when the stream class has a default clock class. * `sink.ctf.fs` and `flt.utils.trimmer` expect that, if discarded events/packets are supported (and those messages are not intentionally ignored for `sink.ctf.fs`) and the stream class has a default clock class, discarded events/packets have default clock snapshots. Support for other configurations will be added in future patches. This change will also make it possible for `sink.ctf.fs` to not write any `events_discarded` packet context member when discarded events are known to be not supported. Python bindings are updated to support this feature. The four new flags are added as parameters to the TraceClass.create_stream_class(). The corresponding (private) property setters in `StreamClass` check that you cannot make the stream class _not_ support discarded events/packets, but have discarded events/packets have default clock snapshots. The new tests in `test_stream_class.py` verify this too. In `message.py`, I changed how we check, for each type of message, if the message object has a default clock snapshot or not. It used to rely on its stream class having a default clock class or not, but it's not the only condition for packet beginning, packet end, and now discarded events and discarded packets messages. Now, in any default clock snapshot property, the function checks its own, custom condition. Because having the stream class have a default clock class is still a typical condition, there's the helper _Message._check_has_default_clock_class(). I renamed `NoDefaultClockClass` to `NonexistentClockSnapshot` to make the exception more generic, considering what's written in this paragraph. I also removed the `_DiscardedMessage.default_clock_class` property because it could not be found in other types of messages, which is weird, and you can always access it with mein_msg.stream.stream_class.default_clock_class Signed-off-by: Philippe Proulx Change-Id: I18b0bc65ef61e8bbd01521fb20c223d401d2adc9 Reviewed-on: https://review.lttng.org/c/babeltrace/+/1365 Reviewed-by: Simon Marchi Tested-by: jenkins --- bindings/python/bt2/bt2/__init__.py.in | 2 +- bindings/python/bt2/bt2/message.py | 52 +++++++------- bindings/python/bt2/bt2/message_iterator.py | 32 ++++++--- .../python/bt2/bt2/native_bt_stream_class.i | 22 ++++++ bindings/python/bt2/bt2/stream_class.py | 34 +++++++++ bindings/python/bt2/bt2/trace_class.py | 11 ++- .../babeltrace/trace-ir/stream-class-const.h | 12 ++++ .../trace-ir/stream-class-internal.h | 4 ++ include/babeltrace/trace-ir/stream-class.h | 10 +++ lib/graph/message/discarded-items.c | 26 +++++-- lib/lib-logging.c | 12 +++- lib/trace-ir/stream-class.c | 72 +++++++++++++++++++ .../ctf/common/metadata/ctf-meta-translate.c | 4 ++ plugins/ctf/fs-sink/fs-sink.c | 28 ++++++++ plugins/lttng-utils/debug-info/debug-info.c | 14 ++-- .../debug-info/trace-ir-metadata-copy.c | 10 +++ plugins/text/pretty/print.c | 22 +++--- plugins/utils/muxer/muxer.c | 30 +++++--- plugins/utils/trimmer/trimmer.c | 29 +++++++- tests/bindings/python/bt2/test_event.py | 2 +- tests/bindings/python/bt2/test_message.py | 34 ++++----- .../bindings/python/bt2/test_stream_class.py | 60 ++++++++++++++++ 22 files changed, 436 insertions(+), 86 deletions(-) diff --git a/bindings/python/bt2/bt2/__init__.py.in b/bindings/python/bt2/bt2/__init__.py.in index f0e4e4b2..bb970ac6 100644 --- a/bindings/python/bt2/bt2/__init__.py.in +++ b/bindings/python/bt2/bt2/__init__.py.in @@ -106,7 +106,7 @@ class QueryExecutorCanceled(Exception): pass -class NoDefaultClockClass(Error): +class NonexistentClockSnapshot(Error): pass diff --git a/bindings/python/bt2/bt2/message.py b/bindings/python/bt2/bt2/message.py index bc666529..fdce1f89 100644 --- a/bindings/python/bt2/bt2/message.py +++ b/bindings/python/bt2/bt2/message.py @@ -41,12 +41,14 @@ class _Message(object._SharedObject): _get_ref = staticmethod(native_bt.message_get_ref) _put_ref = staticmethod(native_bt.message_put_ref) + @staticmethod + def _check_has_default_clock_class(clock_class): + if clock_class is None: + raise bt2.NonexistentClockSnapshot('cannot get default clock snapshot: stream class has no default clock class') + class _MessageWithDefaultClockSnapshot: def _get_default_clock_snapshot(self, borrow_clock_snapshot_ptr): - if not self._has_default_clock_class: - raise bt2.NoDefaultClockClass('cannot get default clock snapshot, stream class has no default clock class') - snapshot_ptr = borrow_clock_snapshot_ptr(self._ptr) return bt2.clock_snapshot._ClockSnapshot._create_from_ptr_and_get_ref( @@ -56,12 +58,9 @@ class _MessageWithDefaultClockSnapshot: class _EventMessage(_Message, _MessageWithDefaultClockSnapshot): _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_event_borrow_default_clock_snapshot_const) - @property - def _has_default_clock_class(self): - return self.event.packet.stream.stream_class.default_clock_class is not None - @property def default_clock_snapshot(self): + self._check_has_default_clock_class(self.event.packet.stream.stream_class.default_clock_class) return self._get_default_clock_snapshot(self._borrow_default_clock_snapshot_ptr) @property @@ -73,12 +72,9 @@ class _EventMessage(_Message, _MessageWithDefaultClockSnapshot): class _PacketMessage(_Message, _MessageWithDefaultClockSnapshot): - @property - def _has_default_clock_class(self): - return self.packet.stream.stream_class.default_clock_class is not None - @property def default_clock_snapshot(self): + self._check_has_default_clock_class(self.packet.stream.stream_class.default_clock_class) return self._get_default_clock_snapshot(self._borrow_default_clock_snapshot_ptr) @property @@ -117,9 +113,7 @@ class _StreamEndMessage(_StreamMessage): class _StreamActivityMessage(_Message): @property def default_clock_snapshot(self): - if self.stream.stream_class.default_clock_class is None: - raise bt2.NoDefaultClockClass('cannot get default clock snapshot, stream class has no default clock class') - + self._check_has_default_clock_class(self.stream.stream_class.default_clock_class) status, snapshot_ptr = self._borrow_default_clock_snapshot_ptr(self._ptr) if status == native_bt.MESSAGE_STREAM_ACTIVITY_CLOCK_SNAPSHOT_STATE_KNOWN: @@ -161,12 +155,12 @@ class _StreamActivityEndMessage(_StreamActivityMessage): class _MessageIteratorInactivityMessage(_Message, _MessageWithDefaultClockSnapshot): - # This kind of message always has a default clock class. - _has_default_clock_class = True _borrow_default_clock_snapshot_ptr = staticmethod(native_bt.message_message_iterator_inactivity_borrow_default_clock_snapshot_const) @property def default_clock_snapshot(self): + # This kind of message always has a default clock class: no + # need to call self._check_has_default_clock_class() here. return self._get_default_clock_snapshot(self._borrow_default_clock_snapshot_ptr) @@ -177,16 +171,6 @@ class _DiscardedMessage(_Message, _MessageWithDefaultClockSnapshot): assert stream_ptr return bt2.stream._Stream._create_from_ptr_and_get_ref(stream_ptr) - @property - def _has_default_clock_class(self): - return self.default_clock_class is not None - - @property - def default_clock_class(self): - cc_ptr = self._borrow_clock_class_ptr(self._ptr) - if cc_ptr is not None: - return bt2.clock_class._ClockClass._create_from_ptr_and_get_ref(cc_ptr) - @property def count(self): avail, count = self._get_count(self._ptr) @@ -199,12 +183,18 @@ class _DiscardedMessage(_Message, _MessageWithDefaultClockSnapshot): _count = property(fset=_set_count) + def _check_has_default_clock_snapshots(self): + if not self._has_default_clock_snapshots: + raise bt2.NonexistentClockSnapshot('cannot get default clock snapshot: such a message has no clock snapshots for this stream class') + @property def beginning_default_clock_snapshot(self): + self._check_has_default_clock_snapshots() return self._get_default_clock_snapshot(self._borrow_beginning_clock_snapshot_ptr) @property def end_default_clock_snapshot(self): + self._check_has_default_clock_snapshots() return self._get_default_clock_snapshot(self._borrow_end_clock_snapshot_ptr) @@ -212,19 +202,25 @@ class _DiscardedEventsMessage(_DiscardedMessage): _borrow_stream_ptr = staticmethod(native_bt.message_discarded_events_borrow_stream_const) _get_count = staticmethod(native_bt.message_discarded_events_get_count) _set_count = staticmethod(native_bt.message_discarded_events_set_count) - _borrow_clock_class_ptr = staticmethod(native_bt.message_discarded_events_borrow_stream_class_default_clock_class_const) _borrow_beginning_clock_snapshot_ptr = staticmethod(native_bt.message_discarded_events_borrow_default_beginning_clock_snapshot_const) _borrow_end_clock_snapshot_ptr = staticmethod(native_bt.message_discarded_events_borrow_default_end_clock_snapshot_const) + @property + def _has_default_clock_snapshots(self): + return self.stream.stream_class.discarded_events_have_default_clock_snapshots + class _DiscardedPacketsMessage(_DiscardedMessage): _borrow_stream_ptr = staticmethod(native_bt.message_discarded_packets_borrow_stream_const) _get_count = staticmethod(native_bt.message_discarded_packets_get_count) _set_count = staticmethod(native_bt.message_discarded_packets_set_count) - _borrow_clock_class_ptr = staticmethod(native_bt.message_discarded_packets_borrow_stream_class_default_clock_class_const) _borrow_beginning_clock_snapshot_ptr = staticmethod(native_bt.message_discarded_packets_borrow_default_beginning_clock_snapshot_const) _borrow_end_clock_snapshot_ptr = staticmethod(native_bt.message_discarded_packets_borrow_default_end_clock_snapshot_const) + @property + def _has_default_clock_snapshots(self): + return self.stream.stream_class.discarded_packets_have_default_clock_snapshots + _MESSAGE_TYPE_TO_CLS = { native_bt.MESSAGE_TYPE_EVENT: _EventMessage, diff --git a/bindings/python/bt2/bt2/message_iterator.py b/bindings/python/bt2/bt2/message_iterator.py index 7ac98f3d..fad4c4d6 100644 --- a/bindings/python/bt2/bt2/message_iterator.py +++ b/bindings/python/bt2/bt2/message_iterator.py @@ -276,15 +276,23 @@ class _UserMessageIterator(_MessageIterator): end_clock_snapshot=None): utils._check_type(stream, bt2.stream._Stream) - if beg_clock_snapshot is None and end_clock_snapshot is None: - ptr = native_bt.message_discarded_events_create(self._ptr, stream._ptr) - elif beg_clock_snapshot is not None and end_clock_snapshot is not None: + if not stream.stream_class.supports_discarded_events: + raise ValueError('stream class does not support discarded events') + + if stream.stream_class.discarded_events_have_default_clock_snapshots: + if beg_clock_snapshot is None or end_clock_snapshot is None: + raise ValueError('discarded events have default clock snapshots for this stream class') + utils._check_uint64(beg_clock_snapshot) utils._check_uint64(end_clock_snapshot) ptr = native_bt.message_discarded_events_create_with_default_clock_snapshots( self._ptr, stream._ptr, beg_clock_snapshot, end_clock_snapshot) else: - raise ValueError('begin and end clock snapshots must be both provided or both omitted') + if beg_clock_snapshot is not None or end_clock_snapshot is not None: + raise ValueError('discarded events have no default clock snapshots for this stream class') + + ptr = native_bt.message_discarded_events_create( + self._ptr, stream._ptr) if ptr is None: raise bt2.CreationError('cannot discarded events message object') @@ -299,15 +307,23 @@ class _UserMessageIterator(_MessageIterator): def _create_discarded_packets_message(self, stream, count=None, beg_clock_snapshot=None, end_clock_snapshot=None): utils._check_type(stream, bt2.stream._Stream) - if beg_clock_snapshot is None and end_clock_snapshot is None: - ptr = native_bt.message_discarded_packets_create(self._ptr, stream._ptr) - elif beg_clock_snapshot is not None and end_clock_snapshot is not None: + if not stream.stream_class.supports_discarded_packets: + raise ValueError('stream class does not support discarded packets') + + if stream.stream_class.discarded_packets_have_default_clock_snapshots: + if beg_clock_snapshot is None or end_clock_snapshot is None: + raise ValueError('discarded packets have default clock snapshots for this stream class') + utils._check_uint64(beg_clock_snapshot) utils._check_uint64(end_clock_snapshot) ptr = native_bt.message_discarded_packets_create_with_default_clock_snapshots( self._ptr, stream._ptr, beg_clock_snapshot, end_clock_snapshot) else: - raise ValueError('begin and end clock snapshots must be both provided or both omitted') + if beg_clock_snapshot is not None or end_clock_snapshot is not None: + raise ValueError('discarded packets have no default clock snapshots for this stream class') + + ptr = native_bt.message_discarded_packets_create( + self._ptr, stream._ptr) if ptr is None: raise bt2.CreationError('cannot discarded packets message object') diff --git a/bindings/python/bt2/bt2/native_bt_stream_class.i b/bindings/python/bt2/bt2/native_bt_stream_class.i index aba139bf..7538ae35 100644 --- a/bindings/python/bt2/bt2/native_bt_stream_class.i +++ b/bindings/python/bt2/bt2/native_bt_stream_class.i @@ -47,6 +47,18 @@ extern bt_bool bt_stream_class_packets_have_default_beginning_clock_snapshot( extern bt_bool bt_stream_class_packets_have_default_end_clock_snapshot( const bt_stream_class *stream_class); +extern bt_bool bt_stream_class_supports_discarded_events( + const bt_stream_class *stream_class); + +extern bt_bool bt_stream_class_supports_discarded_packets( + const bt_stream_class *stream_class); + +extern bt_bool bt_stream_class_discarded_events_have_default_clock_snapshots( + const bt_stream_class *stream_class); + +extern bt_bool bt_stream_class_discarded_packets_have_default_clock_snapshots( + const bt_stream_class *stream_class); + extern uint64_t bt_stream_class_get_id( const bt_stream_class *stream_class); @@ -103,6 +115,16 @@ extern void bt_stream_class_set_packets_have_default_beginning_clock_snapshot( extern void bt_stream_class_set_packets_have_default_end_clock_snapshot( bt_stream_class *stream_class, bt_bool value); +extern void bt_stream_class_set_supports_discarded_events( + bt_stream_class *stream_class, + bt_bool supports_discarded_events, + bt_bool with_default_clock_snapshots); + +extern void bt_stream_class_set_supports_discarded_packets( + bt_stream_class *stream_class, + bt_bool supports_discarded_packets, + bt_bool with_default_clock_snapshots); + extern bt_stream_class_status bt_stream_class_set_packet_context_field_class( bt_stream_class *stream_class, diff --git a/bindings/python/bt2/bt2/stream_class.py b/bindings/python/bt2/bt2/stream_class.py index fa13cb3b..20dd006c 100644 --- a/bindings/python/bt2/bt2/stream_class.py +++ b/bindings/python/bt2/bt2/stream_class.py @@ -148,6 +148,40 @@ class StreamClass(object._SharedObject, collections.abc.Mapping): _packets_have_default_end_clock_snapshot = property(fset=_packets_have_default_end_clock_snapshot) + @property + def supports_discarded_events(self): + return native_bt.stream_class_supports_discarded_events(self._ptr) + + def _set_supports_discarded_events(self, supports, with_cs=False): + utils._check_bool(supports) + utils._check_bool(with_cs) + + if not supports and with_cs: + raise ValueError('cannot not support discarded events, but have default clock snapshots') + + native_bt.stream_class_set_supports_discarded_events(self._ptr, supports, with_cs) + + @property + def discarded_events_have_default_clock_snapshots(self): + return native_bt.stream_class_discarded_events_have_default_clock_snapshots(self._ptr) + + @property + def supports_discarded_packets(self): + return native_bt.stream_class_supports_discarded_packets(self._ptr) + + def _set_supports_discarded_packets(self, supports, with_cs): + utils._check_bool(supports) + utils._check_bool(with_cs) + + if not supports and with_cs: + raise ValueError('cannot not support discarded packets, but have default clock snapshots') + + native_bt.stream_class_set_supports_discarded_packets(self._ptr, supports, with_cs) + + @property + def discarded_packets_have_default_clock_snapshots(self): + return native_bt.stream_class_discarded_packets_have_default_clock_snapshots(self._ptr) + @property def id(self): id = native_bt.stream_class_get_id(self._ptr) diff --git a/bindings/python/bt2/bt2/trace_class.py b/bindings/python/bt2/bt2/trace_class.py index b8eeb30f..a28a20ea 100644 --- a/bindings/python/bt2/bt2/trace_class.py +++ b/bindings/python/bt2/bt2/trace_class.py @@ -172,7 +172,11 @@ class TraceClass(object._SharedObject, collections.abc.Mapping): assigns_automatic_event_class_id=True, assigns_automatic_stream_id=True, packets_have_default_beginning_clock_snapshot=False, - packets_have_default_end_clock_snapshot=False): + packets_have_default_end_clock_snapshot=False, + supports_discarded_events=False, + discarded_events_have_default_clock_snapshots=False, + supports_discarded_packets=False, + discarded_packets_have_default_clock_snapshots=False): if self.assigns_automatic_stream_class_id: if id is not None: @@ -204,7 +208,10 @@ class TraceClass(object._SharedObject, collections.abc.Mapping): sc._assigns_automatic_stream_id = assigns_automatic_stream_id sc._packets_have_default_beginning_clock_snapshot = packets_have_default_beginning_clock_snapshot sc._packets_have_default_end_clock_snapshot = packets_have_default_end_clock_snapshot - + sc._set_supports_discarded_events(supports_discarded_events, + discarded_events_have_default_clock_snapshots) + sc._set_supports_discarded_packets(supports_discarded_packets, + discarded_packets_have_default_clock_snapshots) return sc @property diff --git a/include/babeltrace/trace-ir/stream-class-const.h b/include/babeltrace/trace-ir/stream-class-const.h index 2b3da093..6b84ead5 100644 --- a/include/babeltrace/trace-ir/stream-class-const.h +++ b/include/babeltrace/trace-ir/stream-class-const.h @@ -62,6 +62,18 @@ extern bt_bool bt_stream_class_packets_have_default_beginning_clock_snapshot( extern bt_bool bt_stream_class_packets_have_default_end_clock_snapshot( const bt_stream_class *stream_class); +extern bt_bool bt_stream_class_supports_discarded_events( + const bt_stream_class *stream_class); + +extern bt_bool bt_stream_class_supports_discarded_packets( + const bt_stream_class *stream_class); + +extern bt_bool bt_stream_class_discarded_events_have_default_clock_snapshots( + const bt_stream_class *stream_class); + +extern bt_bool bt_stream_class_discarded_packets_have_default_clock_snapshots( + const bt_stream_class *stream_class); + extern uint64_t bt_stream_class_get_id( const bt_stream_class *stream_class); diff --git a/include/babeltrace/trace-ir/stream-class-internal.h b/include/babeltrace/trace-ir/stream-class-internal.h index d24b5d6a..b996d969 100644 --- a/include/babeltrace/trace-ir/stream-class-internal.h +++ b/include/babeltrace/trace-ir/stream-class-internal.h @@ -50,6 +50,10 @@ struct bt_stream_class { bool assigns_automatic_stream_id; bool packets_have_default_beginning_clock_snapshot; bool packets_have_default_end_clock_snapshot; + bool supports_discarded_events; + bool supports_discarded_packets; + bool discarded_events_have_default_clock_snapshots; + bool discarded_packets_have_default_clock_snapshots; struct bt_field_class *packet_context_fc; struct bt_field_class *event_common_context_fc; struct bt_clock_class *default_clock_class; diff --git a/include/babeltrace/trace-ir/stream-class.h b/include/babeltrace/trace-ir/stream-class.h index ac7ca664..c7e1fb7f 100644 --- a/include/babeltrace/trace-ir/stream-class.h +++ b/include/babeltrace/trace-ir/stream-class.h @@ -66,6 +66,16 @@ extern void bt_stream_class_set_packets_have_default_beginning_clock_snapshot( extern void bt_stream_class_set_packets_have_default_end_clock_snapshot( bt_stream_class *stream_class, bt_bool value); +extern void bt_stream_class_set_supports_discarded_events( + bt_stream_class *stream_class, + bt_bool supports_discarded_events, + bt_bool with_default_clock_snapshots); + +extern void bt_stream_class_set_supports_discarded_packets( + bt_stream_class *stream_class, + bt_bool supports_discarded_packets, + bt_bool with_default_clock_snapshots); + extern bt_stream_class_status bt_stream_class_set_packet_context_field_class( bt_stream_class *stream_class, diff --git a/lib/graph/message/discarded-items.c b/lib/graph/message/discarded-items.c index 82f00392..a6924aae 100644 --- a/lib/graph/message/discarded-items.c +++ b/lib/graph/message/discarded-items.c @@ -69,16 +69,32 @@ struct bt_message *create_discarded_items_message( { struct bt_message_discarded_items *message; struct bt_stream_class *stream_class; + bool has_support; + bool has_default_clock_snapshots; BT_ASSERT_PRE_NON_NULL(self_msg_iter, "Message iterator"); BT_ASSERT_PRE_NON_NULL(stream, "Stream"); stream_class = bt_stream_borrow_class(stream); BT_ASSERT(stream_class); - BT_ASSERT_PRE((with_cs && stream_class->default_clock_class) || - (!with_cs && !stream_class->default_clock_class), - "Creating a message with a default clock snapshot, but without " - "a default clock class, or without a default clock snapshot, " - "but with a default clock class: ", + + if (type == BT_MESSAGE_TYPE_DISCARDED_EVENTS) { + has_support = stream_class->supports_discarded_events; + has_default_clock_snapshots = + stream_class->discarded_events_have_default_clock_snapshots; + } else { + has_support = stream_class->supports_discarded_packets; + has_default_clock_snapshots = + stream_class->discarded_packets_have_default_clock_snapshots; + } + + BT_ASSERT_PRE(has_support, + "Stream class does not support discarded events or packets: " + "type=%s, %![stream-]+s, %![sc-]+S", + bt_message_type_string(type), stream, stream_class); + BT_ASSERT_PRE((with_cs && has_default_clock_snapshots) || + (!with_cs && !has_default_clock_snapshots), + "Unexpected stream class configuration when creating " + "a discarded events or packets message: " "type=%s, %![stream-]+s, %![sc-]+S, with-cs=%d, " "cs-begin-val=%" PRIu64 ", cs-end-val=%" PRIu64, bt_message_type_string(type), stream, stream_class, diff --git a/lib/lib-logging.c b/lib/lib-logging.c index 683df22e..c966648f 100644 --- a/lib/lib-logging.c +++ b/lib/lib-logging.c @@ -536,11 +536,19 @@ static inline void format_stream_class(char **buf_ch, bool extended, BUF_APPEND(", %sassigns-auto-ec-id=%d, %sassigns-auto-stream-id=%d, " "%spackets-have-default-beginning-cs=%d, " - "%spackets-have-default-end-cs=%d, ", + "%spackets-have-default-end-cs=%d, " + "%ssupports-discarded-events=%d, " + "%sdiscarded-events-have-default-cs=%d, " + "%ssupports-discarded-packets=%d, " + "%sdiscarded-packets-have-default-cs=%d", PRFIELD(stream_class->assigns_automatic_event_class_id), PRFIELD(stream_class->assigns_automatic_stream_id), PRFIELD(stream_class->packets_have_default_beginning_clock_snapshot), - PRFIELD(stream_class->packets_have_default_end_clock_snapshot)); + PRFIELD(stream_class->packets_have_default_end_clock_snapshot), + PRFIELD(stream_class->supports_discarded_events), + PRFIELD(stream_class->discarded_events_have_default_clock_snapshots), + PRFIELD(stream_class->supports_discarded_packets), + PRFIELD(stream_class->discarded_packets_have_default_clock_snapshots)); BUF_APPEND(", %strace-class-addr=%p", PRFIELD(trace_class)); SET_TMP_PREFIX("trace-class-"); format_trace_class(buf_ch, false, tmp_prefix, trace_class); diff --git a/lib/trace-ir/stream-class.c b/lib/trace-ir/stream-class.c index 89470b5b..0f333869 100644 --- a/lib/trace-ir/stream-class.c +++ b/lib/trace-ir/stream-class.c @@ -498,6 +498,78 @@ bt_bool bt_stream_class_assigns_automatic_stream_id( return (bt_bool) stream_class->assigns_automatic_stream_id; } +void bt_stream_class_set_supports_discarded_events( + struct bt_stream_class *stream_class, + bt_bool supports_discarded_events, + bt_bool with_default_clock_snapshots) +{ + BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class"); + BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class); + BT_ASSERT_PRE(supports_discarded_events || + !with_default_clock_snapshots, + "Discarded events cannot have default clock snapshots when " + "not supported: %!+S", stream_class); + BT_ASSERT_PRE(!with_default_clock_snapshots || + stream_class->default_clock_class, + "Stream class has no default clock class: %!+S", stream_class); + stream_class->supports_discarded_events = + (bool) supports_discarded_events; + stream_class->discarded_events_have_default_clock_snapshots = + (bool) with_default_clock_snapshots; + BT_LIB_LOGV("Set stream class's discarded events support property: " + "%!+S", stream_class); +} + +bt_bool bt_stream_class_supports_discarded_events( + const struct bt_stream_class *stream_class) +{ + BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class"); + return (bt_bool) stream_class->supports_discarded_events; +} + +bt_bool bt_stream_class_discarded_events_have_default_clock_snapshots( + const struct bt_stream_class *stream_class) +{ + BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class"); + return (bt_bool) stream_class->discarded_events_have_default_clock_snapshots; +} + +void bt_stream_class_set_supports_discarded_packets( + struct bt_stream_class *stream_class, + bt_bool supports_discarded_packets, + bt_bool with_default_clock_snapshots) +{ + BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class"); + BT_ASSERT_PRE_STREAM_CLASS_HOT(stream_class); + BT_ASSERT_PRE(supports_discarded_packets || + !with_default_clock_snapshots, + "Discarded packets cannot have default clock snapshots when " + "not supported: %!+S", stream_class); + BT_ASSERT_PRE(!with_default_clock_snapshots || + stream_class->default_clock_class, + "Stream class has no default clock class: %!+S", stream_class); + stream_class->supports_discarded_packets = + (bool) supports_discarded_packets; + stream_class->discarded_packets_have_default_clock_snapshots = + (bool) with_default_clock_snapshots; + BT_LIB_LOGV("Set stream class's discarded packets support property: " + "%!+S", stream_class); +} + +bt_bool bt_stream_class_supports_discarded_packets( + const struct bt_stream_class *stream_class) +{ + BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class"); + return (bt_bool) stream_class->supports_discarded_packets; +} + +bt_bool bt_stream_class_discarded_packets_have_default_clock_snapshots( + const struct bt_stream_class *stream_class) +{ + BT_ASSERT_PRE_NON_NULL(stream_class, "Stream class"); + return (bt_bool) stream_class->discarded_packets_have_default_clock_snapshots; +} + void bt_stream_class_set_assigns_automatic_stream_id( struct bt_stream_class *stream_class, bt_bool value) diff --git a/plugins/ctf/common/metadata/ctf-meta-translate.c b/plugins/ctf/common/metadata/ctf-meta-translate.c index e8486f96..f65ab64a 100644 --- a/plugins/ctf/common/metadata/ctf-meta-translate.c +++ b/plugins/ctf/common/metadata/ctf-meta-translate.c @@ -491,6 +491,10 @@ void ctf_stream_class_to_ir(struct ctx *ctx) ctx->ir_sc, BT_TRUE); } + bt_stream_class_set_supports_discarded_events(ctx->ir_sc, BT_TRUE, + ctx->sc->default_clock_class != NULL); + bt_stream_class_set_supports_discarded_packets(ctx->ir_sc, BT_TRUE, + ctx->sc->default_clock_class != NULL); ctx->sc->is_translated = true; ctx->sc->ir_sc = ctx->ir_sc; diff --git a/plugins/ctf/fs-sink/fs-sink.c b/plugins/ctf/fs-sink/fs-sink.c index da3307fe..5316d30c 100644 --- a/plugins/ctf/fs-sink/fs-sink.c +++ b/plugins/ctf/fs-sink/fs-sink.c @@ -552,6 +552,34 @@ bt_self_component_status handle_stream_beginning_msg( status = BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR; goto end; } + + if (!fs_sink->ignore_discarded_events && + bt_stream_class_supports_discarded_events(ir_sc) && + !bt_stream_class_discarded_events_have_default_clock_snapshots(ir_sc)) { + BT_LOGE("Unsupported stream: discarded events " + "have no clock snapshots: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + ir_stream, bt_stream_get_id(ir_stream), + bt_stream_get_name(ir_stream)); + status = BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR; + goto end; + } + + if (!fs_sink->ignore_discarded_packets && + bt_stream_class_supports_discarded_packets(ir_sc) && + !bt_stream_class_discarded_packets_have_default_clock_snapshots(ir_sc)) { + BT_LOGE("Unsupported stream: discarded packets " + "have no clock snapshots: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + ir_stream, bt_stream_get_id(ir_stream), + bt_stream_get_name(ir_stream)); + status = BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR; + goto end; + } } stream = borrow_stream(fs_sink, ir_stream); diff --git a/plugins/lttng-utils/debug-info/debug-info.c b/plugins/lttng-utils/debug-info/debug-info.c index 1859d273..e26e360b 100644 --- a/plugins/lttng-utils/debug-info/debug-info.c +++ b/plugins/lttng-utils/debug-info/debug-info.c @@ -1540,7 +1540,7 @@ bt_message *handle_discarded_events_message(struct debug_info_msg_iter *debug_it { const bt_clock_snapshot *begin_cs, *end_cs; const bt_stream *in_stream; - const bt_clock_class *default_cc; + bool has_default_clock_snapshots; uint64_t discarded_events, begin_cs_value, end_cs_value; bt_property_availability prop_avail; bt_message *out_message = NULL; @@ -1554,9 +1554,10 @@ bt_message *handle_discarded_events_message(struct debug_info_msg_iter *debug_it debug_it->ir_maps, in_stream); BT_ASSERT(out_stream); - default_cc = bt_stream_class_borrow_default_clock_class_const( + has_default_clock_snapshots = + bt_stream_class_discarded_events_have_default_clock_snapshots( bt_stream_borrow_class_const(in_stream)); - if (default_cc) { + if (has_default_clock_snapshots) { begin_cs = bt_message_discarded_events_borrow_default_beginning_clock_snapshot_const( in_message); @@ -1598,7 +1599,7 @@ bt_message *handle_discarded_packets_message(struct debug_info_msg_iter *debug_i const bt_message *in_message) { const bt_clock_snapshot *begin_cs, *end_cs; - const bt_clock_class *default_cc; + bool has_default_clock_snapshots; const bt_stream *in_stream; uint64_t discarded_packets, begin_cs_value, end_cs_value; bt_property_availability prop_avail; @@ -1613,9 +1614,10 @@ bt_message *handle_discarded_packets_message(struct debug_info_msg_iter *debug_i debug_it->ir_maps, in_stream); BT_ASSERT(out_stream); - default_cc = bt_stream_class_borrow_default_clock_class_const( + has_default_clock_snapshots = + bt_stream_class_discarded_packets_have_default_clock_snapshots( bt_stream_borrow_class_const(in_stream)); - if (default_cc) { + if (has_default_clock_snapshots) { begin_cs = bt_message_discarded_packets_borrow_default_beginning_clock_snapshot_const( in_message); diff --git a/plugins/lttng-utils/debug-info/trace-ir-metadata-copy.c b/plugins/lttng-utils/debug-info/trace-ir-metadata-copy.c index c07b7bdd..e651dce9 100644 --- a/plugins/lttng-utils/debug-info/trace-ir-metadata-copy.c +++ b/plugins/lttng-utils/debug-info/trace-ir-metadata-copy.c @@ -263,6 +263,16 @@ int copy_stream_class_content(struct trace_ir_maps *ir_maps, out_stream_class, bt_stream_class_packets_have_default_end_clock_snapshot( in_stream_class)); + bt_stream_class_set_supports_discarded_events( + out_stream_class, + bt_stream_class_supports_discarded_events(in_stream_class), + bt_stream_class_discarded_events_have_default_clock_snapshots( + in_stream_class)); + bt_stream_class_set_supports_discarded_packets( + out_stream_class, + bt_stream_class_supports_discarded_packets(in_stream_class), + bt_stream_class_discarded_packets_have_default_clock_snapshots( + in_stream_class)); in_name = bt_stream_class_get_name(in_stream_class); if (in_name) { diff --git a/plugins/text/pretty/print.c b/plugins/text/pretty/print.c index a3f94b96..bdc1eb98 100644 --- a/plugins/text/pretty/print.c +++ b/plugins/text/pretty/print.c @@ -1357,23 +1357,29 @@ int pretty_print_discarded_items(struct pretty_component *pretty, BT_ASSERT(stream); stream_class = bt_stream_borrow_class_const(stream); - if (bt_stream_class_borrow_default_clock_class_const(stream_class)) { - switch (bt_message_get_type(msg)) { - case BT_MESSAGE_TYPE_DISCARDED_EVENTS: + switch (bt_message_get_type(msg)) { + case BT_MESSAGE_TYPE_DISCARDED_EVENTS: + if (bt_stream_class_discarded_events_have_default_clock_snapshots( + stream_class)) { begin = bt_message_discarded_events_borrow_default_beginning_clock_snapshot_const( msg); end = bt_message_discarded_events_borrow_default_end_clock_snapshot_const( msg); - break; - case BT_MESSAGE_TYPE_DISCARDED_PACKETS: + } + + break; + case BT_MESSAGE_TYPE_DISCARDED_PACKETS: + if (bt_stream_class_discarded_packets_have_default_clock_snapshots( + stream_class)) { begin = bt_message_discarded_packets_borrow_default_beginning_clock_snapshot_const( msg); end = bt_message_discarded_packets_borrow_default_end_clock_snapshot_const( msg); - break; - default: - abort(); } + + break; + default: + abort(); } print_discarded_elements_msg(pretty, stream, begin, end, diff --git a/plugins/utils/muxer/muxer.c b/plugins/utils/muxer/muxer.c index de917806..8fa4ebad 100644 --- a/plugins/utils/muxer/muxer.c +++ b/plugins/utils/muxer/muxer.c @@ -534,6 +534,12 @@ int get_msg_ts_ns(struct muxer_comp *muxer_comp, bt_packet_borrow_stream_const( bt_message_packet_end_borrow_packet_const( msg))); + } else if (unlikely(msg_type == BT_MESSAGE_TYPE_DISCARDED_EVENTS)) { + stream_class = bt_stream_borrow_class_const( + bt_message_discarded_events_borrow_stream_const(msg)); + } else if (unlikely(msg_type == BT_MESSAGE_TYPE_DISCARDED_PACKETS)) { + stream_class = bt_stream_borrow_class_const( + bt_message_discarded_packets_borrow_stream_const(msg)); } switch (msg_type) { @@ -564,16 +570,24 @@ int get_msg_ts_ns(struct muxer_comp *muxer_comp, break; case BT_MESSAGE_TYPE_DISCARDED_EVENTS: - BT_ASSERT(bt_message_discarded_events_borrow_stream_class_default_clock_class_const( - msg)); - clock_snapshot = bt_message_discarded_events_borrow_default_beginning_clock_snapshot_const( - msg); + if (bt_stream_class_discarded_events_have_default_clock_snapshots( + stream_class)) { + clock_snapshot = bt_message_discarded_events_borrow_default_beginning_clock_snapshot_const( + msg); + } else { + goto no_clock_snapshot; + } + break; case BT_MESSAGE_TYPE_DISCARDED_PACKETS: - BT_ASSERT(bt_message_discarded_packets_borrow_stream_class_default_clock_class_const( - msg)); - clock_snapshot = bt_message_discarded_packets_borrow_default_beginning_clock_snapshot_const( - msg); + if (bt_stream_class_discarded_packets_have_default_clock_snapshots( + stream_class)) { + clock_snapshot = bt_message_discarded_packets_borrow_default_beginning_clock_snapshot_const( + msg); + } else { + goto no_clock_snapshot; + } + break; case BT_MESSAGE_TYPE_STREAM_ACTIVITY_BEGINNING: BT_ASSERT(bt_message_stream_activity_beginning_borrow_stream_class_default_clock_class_const( diff --git a/plugins/utils/trimmer/trimmer.c b/plugins/utils/trimmer/trimmer.c index db5b65b3..0a5557e4 100644 --- a/plugins/utils/trimmer/trimmer.c +++ b/plugins/utils/trimmer/trimmer.c @@ -1734,7 +1734,8 @@ bt_self_message_iterator_status handle_message( } /* - * Temporary: make sure packet beginning and end + * Temporary: make sure packet beginning, packet + * end, discarded events, and discarded packets * messages have default clock snapshots until * the support for not having them is * implemented. @@ -1765,6 +1766,32 @@ bt_self_message_iterator_status handle_message( goto end; } + if (bt_stream_class_supports_discarded_events(sc) && + !bt_stream_class_discarded_events_have_default_clock_snapshots(sc)) { + BT_LOGE("Unsupported stream: discarded events " + "have no clock snapshots: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + stream, bt_stream_get_id(stream), + bt_stream_get_name(stream)); + status = BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR; + goto end; + } + + if (bt_stream_class_supports_discarded_packets(sc) && + !bt_stream_class_discarded_packets_have_default_clock_snapshots(sc)) { + BT_LOGE("Unsupported stream: discarded packets " + "have no clock snapshots: " + "stream-addr=%p, " + "stream-id=%" PRIu64 ", " + "stream-name=\"%s\"", + stream, bt_stream_get_id(stream), + bt_stream_get_name(stream)); + status = BT_SELF_MESSAGE_ITERATOR_STATUS_ERROR; + goto end; + } + sstate = g_new0(struct trimmer_iterator_stream_state, 1); if (!sstate) { diff --git a/tests/bindings/python/bt2/test_event.py b/tests/bindings/python/bt2/test_event.py index 4c21ee7f..d420b33f 100644 --- a/tests/bindings/python/bt2/test_event.py +++ b/tests/bindings/python/bt2/test_event.py @@ -170,7 +170,7 @@ class EventTestCase(unittest.TestCase): def test_no_clock_value(self): msg = self._create_test_event_message(with_clockclass=False) - with self.assertRaises(bt2.NoDefaultClockClass): + with self.assertRaises(bt2.NonexistentClockSnapshot): msg.default_clock_snapshot def test_stream(self): diff --git a/tests/bindings/python/bt2/test_message.py b/tests/bindings/python/bt2/test_message.py index 3cc55042..986c708c 100644 --- a/tests/bindings/python/bt2/test_message.py +++ b/tests/bindings/python/bt2/test_message.py @@ -63,18 +63,20 @@ class AllMessagesTestCase(unittest.TestCase): def __init__(self, params): self._add_output_port('out') - with_cc = params['with_cc'] + with_cc = bool(params['with_cc']) tc = self._create_trace_class() if with_cc: cc = self._create_clock_class() - packets_have_clock_snapshots = True else: cc = None - packets_have_clock_snapshots = False sc = tc.create_stream_class(default_clock_class=cc, - packets_have_default_beginning_clock_snapshot=packets_have_clock_snapshots, - packets_have_default_end_clock_snapshot=packets_have_clock_snapshots) + packets_have_default_beginning_clock_snapshot=with_cc, + packets_have_default_end_clock_snapshot=with_cc, + supports_discarded_events=True, + discarded_events_have_default_clock_snapshots=with_cc, + supports_discarded_packets=True, + discarded_packets_have_default_clock_snapshots=with_cc) # Create payload field class my_int_fc = tc.create_signed_integer_field_class(32) @@ -127,7 +129,7 @@ class AllMessagesTestCase(unittest.TestCase): self.assertIsInstance(msg, bt2.message._DiscardedEventsMessage) self.assertEqual(msg.stream.addr, self._stream.addr) self.assertEqual(msg.count, 890) - self.assertEqual(msg.default_clock_class.addr, self._clock_class.addr) + self.assertEqual(msg.stream.stream_class.default_clock_class.addr, self._clock_class.addr) self.assertEqual(msg.beginning_default_clock_snapshot.value, i) self.assertEqual(msg.end_default_clock_snapshot.value, i) elif i == 6: @@ -138,7 +140,7 @@ class AllMessagesTestCase(unittest.TestCase): self.assertIsInstance(msg, bt2.message._DiscardedPacketsMessage) self.assertEqual(msg.stream.addr, self._stream.addr) self.assertEqual(msg.count, 678) - self.assertEqual(msg.default_clock_class.addr, self._clock_class.addr) + self.assertEqual(msg.stream.stream_class.default_clock_class.addr, self._clock_class.addr) self.assertEqual(msg.beginning_default_clock_snapshot.value, i) self.assertEqual(msg.end_default_clock_snapshot.value, i) elif i == 8: @@ -162,7 +164,7 @@ class AllMessagesTestCase(unittest.TestCase): self.assertEqual(msg.stream.addr, self._stream.addr) elif i == 1: self.assertIsInstance(msg, bt2.message._StreamActivityBeginningMessage) - with self.assertRaises(bt2.NoDefaultClockClass): + with self.assertRaises(bt2.NonexistentClockSnapshot): msg.default_clock_snapshot elif i == 2: self.assertIsInstance(msg, bt2.message._PacketBeginningMessage) @@ -170,16 +172,16 @@ class AllMessagesTestCase(unittest.TestCase): elif i == 3: self.assertIsInstance(msg, bt2.message._EventMessage) self.assertEqual(msg.event.event_class.addr, self._event_class.addr) - with self.assertRaises(bt2.NoDefaultClockClass): + with self.assertRaises(bt2.NonexistentClockSnapshot): msg.default_clock_snapshot elif i == 4: self.assertIsInstance(msg, bt2.message._DiscardedEventsMessage) self.assertEqual(msg.stream.addr, self._stream.addr) self.assertEqual(msg.count, 890) - self.assertIsNone(msg.default_clock_class) - with self.assertRaises(bt2.NoDefaultClockClass): + self.assertIsNone(msg.stream.stream_class.default_clock_class) + with self.assertRaises(bt2.NonexistentClockSnapshot): msg.beginning_default_clock_snapshot - with self.assertRaises(bt2.NoDefaultClockClass): + with self.assertRaises(bt2.NonexistentClockSnapshot): msg.end_default_clock_snapshot elif i == 5: self.assertIsInstance(msg, bt2.message._PacketEndMessage) @@ -188,15 +190,15 @@ class AllMessagesTestCase(unittest.TestCase): self.assertIsInstance(msg, bt2.message._DiscardedPacketsMessage) self.assertEqual(msg.stream.addr, self._stream.addr) self.assertEqual(msg.count, 678) - self.assertIsNone(msg.default_clock_class) - with self.assertRaises(bt2.NoDefaultClockClass): + self.assertIsNone(msg.stream.stream_class.default_clock_class) + with self.assertRaises(bt2.NonexistentClockSnapshot): msg.beginning_default_clock_snapshot - with self.assertRaises(bt2.NoDefaultClockClass): + with self.assertRaises(bt2.NonexistentClockSnapshot): msg.end_default_clock_snapshot elif i == 7: self.assertIsInstance(msg, bt2.message._StreamActivityEndMessage) self.assertEqual(msg.stream.addr, self._stream.addr) - with self.assertRaises(bt2.NoDefaultClockClass): + with self.assertRaises(bt2.NonexistentClockSnapshot): msg.default_clock_snapshot elif i == 8: self.assertIsInstance(msg, bt2.message._StreamEndMessage) diff --git a/tests/bindings/python/bt2/test_stream_class.py b/tests/bindings/python/bt2/test_stream_class.py index 243563f5..9c52801b 100644 --- a/tests/bindings/python/bt2/test_stream_class.py +++ b/tests/bindings/python/bt2/test_stream_class.py @@ -24,6 +24,10 @@ class StreamClassTestCase(unittest.TestCase): self.assertTrue(sc.assigns_automatic_stream_id) self.assertFalse(sc.packets_have_default_beginning_clock_snapshot) self.assertFalse(sc.packets_have_default_end_clock_snapshot) + self.assertFalse(sc.supports_discarded_events) + self.assertFalse(sc.discarded_events_have_default_clock_snapshots) + self.assertFalse(sc.supports_discarded_packets) + self.assertFalse(sc.discarded_packets_have_default_clock_snapshots) def test_create_name(self): sc = self._tc.create_stream_class(name='bozo') @@ -131,6 +135,62 @@ class StreamClassTestCase(unittest.TestCase): with self.assertRaises(TypeError): sc = self._tc.create_stream_class(packets_have_default_end_clock_snapshot="something") + def test_supports_discarded_events_without_cs(self): + sc = self._tc.create_stream_class(default_clock_class=self._cc, + supports_discarded_events=True) + self.assertTrue(sc.supports_discarded_events) + self.assertFalse(sc.discarded_events_have_default_clock_snapshots) + + def test_supports_discarded_events_with_cs(self): + sc = self._tc.create_stream_class(default_clock_class=self._cc, + supports_discarded_events=True, + discarded_events_have_default_clock_snapshots=True) + self.assertTrue(sc.supports_discarded_events) + self.assertTrue(sc.discarded_events_have_default_clock_snapshots) + + def test_supports_discarded_events_raises_type_error(self): + with self.assertRaises(TypeError): + sc = self._tc.create_stream_class(default_clock_class=self._cc, + supports_discarded_events=23) + + def test_discarded_events_have_default_cs_raises_type_error(self): + with self.assertRaises(TypeError): + sc = self._tc.create_stream_class(default_clock_class=self._cc, + discarded_events_have_default_clock_snapshots=23) + + def test_does_not_support_discarded_events_raises_with_cs(self): + with self.assertRaises(ValueError): + sc = self._tc.create_stream_class(default_clock_class=self._cc, + discarded_events_have_default_clock_snapshots=True) + + def test_supports_discarded_packets_without_cs(self): + sc = self._tc.create_stream_class(default_clock_class=self._cc, + supports_discarded_packets=True) + self.assertTrue(sc.supports_discarded_packets) + self.assertFalse(sc.discarded_packets_have_default_clock_snapshots) + + def test_supports_discarded_packets_with_cs(self): + sc = self._tc.create_stream_class(default_clock_class=self._cc, + supports_discarded_packets=True, + discarded_packets_have_default_clock_snapshots=True) + self.assertTrue(sc.supports_discarded_packets) + self.assertTrue(sc.discarded_packets_have_default_clock_snapshots) + + def test_supports_discarded_packets_raises_type_error(self): + with self.assertRaises(TypeError): + sc = self._tc.create_stream_class(default_clock_class=self._cc, + supports_discarded_packets=23) + + def test_discarded_packets_have_default_cs_raises_type_error(self): + with self.assertRaises(TypeError): + sc = self._tc.create_stream_class(default_clock_class=self._cc, + discarded_packets_have_default_clock_snapshots=23) + + def test_does_not_support_discarded_packets_raises_with_cs(self): + with self.assertRaises(ValueError): + sc = self._tc.create_stream_class(default_clock_class=self._cc, + discarded_packets_have_default_clock_snapshots=True) + def test_trace_class(self): sc = self._tc.create_stream_class() self.assertEqual(sc.trace_class.addr, self._tc.addr) -- 2.34.1