lib: make discarded events/packets support and clock snapshots optional
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Mon, 3 Jun 2019 16:16:11 +0000 (12:16 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Thu, 6 Jun 2019 21:19:12 +0000 (17:19 -0400)
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 <eeppeliteloop@gmail.com>
Change-Id: I18b0bc65ef61e8bbd01521fb20c223d401d2adc9
Reviewed-on: https://review.lttng.org/c/babeltrace/+/1365
Reviewed-by: Simon Marchi <simon.marchi@efficios.com>
Tested-by: jenkins
22 files changed:
bindings/python/bt2/bt2/__init__.py.in
bindings/python/bt2/bt2/message.py
bindings/python/bt2/bt2/message_iterator.py
bindings/python/bt2/bt2/native_bt_stream_class.i
bindings/python/bt2/bt2/stream_class.py
bindings/python/bt2/bt2/trace_class.py
include/babeltrace/trace-ir/stream-class-const.h
include/babeltrace/trace-ir/stream-class-internal.h
include/babeltrace/trace-ir/stream-class.h
lib/graph/message/discarded-items.c
lib/lib-logging.c
lib/trace-ir/stream-class.c
plugins/ctf/common/metadata/ctf-meta-translate.c
plugins/ctf/fs-sink/fs-sink.c
plugins/lttng-utils/debug-info/debug-info.c
plugins/lttng-utils/debug-info/trace-ir-metadata-copy.c
plugins/text/pretty/print.c
plugins/utils/muxer/muxer.c
plugins/utils/trimmer/trimmer.c
tests/bindings/python/bt2/test_event.py
tests/bindings/python/bt2/test_message.py
tests/bindings/python/bt2/test_stream_class.py

index f0e4e4b2886cc712bab8217e783ed13268d8f5d0..bb970ac6f0c6ac3af9508fbf10c9646db671eb8c 100644 (file)
@@ -106,7 +106,7 @@ class QueryExecutorCanceled(Exception):
     pass
 
 
-class NoDefaultClockClass(Error):
+class NonexistentClockSnapshot(Error):
     pass
 
 
index bc666529043fc4994f3e75e4793d514e2c02df7f..fdce1f894e8c21ac871d64a072c4e0cf5a53f187 100644 (file)
@@ -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,
index 7ac98f3dfcf64c35792972ae675c9a7695c757c6..fad4c4d608f8a00853dcdc9b1f2aaff2b74901ea 100644 (file)
@@ -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')
index aba139bf3d951a2578ba77c7bb63defaeb9b7d8f..7538ae3532735c13a90f0281a591cb3024c754bb 100644 (file)
@@ -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,
index fa13cb3b83c9b715fc5dc401068a4dac9c984838..20dd006c9880327098a8eec4d82ecd81c7d590c3 100644 (file)
@@ -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)
index b8eeb30f22ef7a1d5059df15bf5e1787141ecad1..a28a20ea91c0e1a34061c081869a27d9e0bd7794 100644 (file)
@@ -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
index 2b3da093e91912d738946d8a6a8c70cd242a24a0..6b84ead529d3306a368b778cdbf2a143b1242ebb 100644 (file)
@@ -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);
 
index d24b5d6ab71432a71550449784cb4a117f4270e7..b996d96906a92443ba087a39f97a701878f92305 100644 (file)
@@ -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;
index ac7ca66408e348463b99fc5b75ca88fc7e533eac..c7e1fb7f150c181cc6eab145fb9bd364f27162df 100644 (file)
@@ -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,
index 82f0039244c2bacb89e0da28b6fc8c9db5ace4a5..a6924aae3bdb9bd1c7ad129f05eeaaaad1fa3ef7 100644 (file)
@@ -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,
index 683df22eb2d009d1b968f611e18bde28fa85dc61..c966648f73e153356064488703961fe40b249b48 100644 (file)
@@ -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);
index 89470b5badc7594008a2467abb621ec58ec29bd0..0f3338697fb44aab270343804783f6f56669df4e 100644 (file)
@@ -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)
index e8486f96108d40147fe657cb5c581d43695f7fbf..f65ab64ab05df4a4362f6744a3ec30ca07d97442 100644 (file)
@@ -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;
 
index da3307feac63dc59225ab7ffee4c6065aafc2312..5316d30cb0cb1b30540175489ac2e077dd69e35a 100644 (file)
@@ -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);
index 1859d27360bc1e1cf10d1ea347bb13baffbce49a..e26e360bda8ddaf99452694a448d8cd03b9b6c8f 100644 (file)
@@ -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);
index c07b7bdde79c014eaabc1385224dc58e41a5a702..e651dce9b99118f7a7a97bbfa87b1cd4f7475043 100644 (file)
@@ -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) {
index a3f94b96fd140ffbcd9cfb8045f3c00d32c83986..bdc1eb9801b5c0e8d1341d7f173ee721d2ebd618 100644 (file)
@@ -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,
index de9178066f1c0af7b495301ecca027fd8d98bcb0..8fa4ebadab6e2831e4af2d526f4df9cff7911f34 100644 (file)
@@ -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(
index db5b65b3215518ecf8de9920f1be21a48c51bdb0..0a5557e4002837ac47f5ff1bbb186ac619e7d4b9 100644 (file)
@@ -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) {
index 4c21ee7fe144dd204a963ff9da93f057fd8a4d34..d420b33f67fccc01c0e0a27018e4515f20093676 100644 (file)
@@ -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):
index 3cc55042ad9e6f73a7130236a4bd93d679ad0b66..986c708c890852616d1a80464742fffb419f3929 100644 (file)
@@ -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)
index 243563f5bd7e16eda466f67f7f19136a32a04ddc..9c52801b8500bc3112a679021440e44c09275d67 100644 (file)
@@ -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)
This page took 0.040331 seconds and 4 git commands to generate.