if ENABLE_PYTHON_BINDINGS
-#Disabled temporarily (work in progress)
-#SUBDIRS = python
+SUBDIRS = python
endif
# interface dependencies (without `native_bt` prefix and `.i` extension)
NATIVE_MODULE_DEPS = \
+ ccpriomap \
clockclass \
- eventclass \
+ component \
+ componentclass \
+ connection \
+ ctfwriter \
event \
+ eventclass \
fields \
ft \
+ graph \
+ logging \
+ notification \
+ notifiter \
packet \
+ plugin \
+ port \
ref \
- streamclass \
stream \
+ streamclass \
trace \
values \
- ctfwriter \
- componentclass \
- component \
- notification \
- notifiter \
- plugin
+ version
# Python modules (without `.py` extension)
-EXTRA_MODULES = \
- clock_class \
- event_class \
- event \
- fields \
- field_types \
- object \
- packet \
- stream_class \
- stream \
- trace \
- utils \
- values \
- ctf_writer \
- component \
- notification \
- notification_iterator \
- plugin \
- py_plugin
+EXTRA_MODULES = \
+ clock_class \
+ clock_class_priority_map \
+ component \
+ connection \
+ ctf_writer \
+ event \
+ event_class \
+ field_types \
+ fields \
+ graph \
+ logging \
+ notification \
+ notification_iterator \
+ object \
+ packet \
+ plugin \
+ port \
+ py_plugin \
+ stream \
+ stream_class \
+ trace \
+ utils \
+ values
# automatically generated file lists
EXTRA_MODULES_PY = $(addprefix $(srcdir)/,$(addsuffix .py,$(EXTRA_MODULES)))
$(SWIG) -python -Wall -I$(srcdir) -I$(top_srcdir)/include -module $(NATIVE_MODULE) -outcurrentdir $(NATIVE_MODULE_I)
# native_bt module
-_native_bt_la_SOURCES = native_bt_wrap.c
+_native_bt_la_SOURCES = logging.h logging.c
+nodist__native_bt_la_SOURCES = native_bt_wrap.c
_native_bt_la_LDFLAGS = -module
-_native_bt_la_CFLAGS = $(GLIB_CFLAGS) $(PYTHON_INCLUDE) -I$(srcdir) $(AM_CFLAGS)
-_native_bt_la_LIBS = $(GLIB_LIBS)
+_native_bt_la_CFLAGS = $(PYTHON_INCLUDE) -I$(srcdir) $(AM_CFLAGS)
_native_bt_la_LIBADD = \
$(top_builddir)/lib/libbabeltrace.la \
- $(top_builddir)/formats/ctf/libbabeltrace-ctf.la
+ $(top_builddir)/logging/libbabeltrace-logging.la \
+ $(top_builddir)/common/libbabeltrace-common.la
# extra module sources -> build directory
all-local:
@if [ x"$(srcdir)" != x"$(builddir)" ]; then \
for file in $(EXTRA_MODULES_PY); do \
- cp -f $(srcdir)/$$file $(builddir); \
+ cp -f "$(srcdir)/$$file" "$(builddir)"; \
done; \
fi
clean-local:
@if [ x"$(srcdir)" != x"$(builddir)" ]; then \
for file in $(EXTRA_MODULES_PY); do \
- rm -f $(srcdir)/$$file $(builddir); \
+ rm -f "$(srcdir)/$$file" "$(builddir)"; \
done; \
fi
# The MIT License (MIT)
#
-# Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
from bt2.clock_class import *
+from bt2.clock_class import _ClockValue
+from bt2.clock_class_priority_map import *
from bt2.component import *
+from bt2.component import _FilterComponent
+from bt2.component import _GenericFilterComponentClass
+from bt2.component import _GenericSinkComponentClass
+from bt2.component import _GenericSourceComponentClass
+from bt2.component import _SinkComponent
+from bt2.component import _SourceComponent
+from bt2.component import _UserFilterComponent
+from bt2.component import _UserSinkComponent
+from bt2.component import _UserSourceComponent
+from bt2.connection import *
+from bt2.connection import _Connection
+from bt2.connection import _PrivateConnection
from bt2.ctf_writer import *
+from bt2.ctf_writer import _CtfWriterStream
+from bt2.event import _Event
from bt2.event_class import *
from bt2.field_types import *
+from bt2.field_types import _FieldType
from bt2.fields import *
+from bt2.fields import _ArrayField
+from bt2.fields import _EnumerationField
+from bt2.fields import _Field
+from bt2.fields import _FloatingPointNumberField
+from bt2.fields import _IntegerField
+from bt2.fields import _SequenceField
+from bt2.fields import _StringField
+from bt2.fields import _StructureField
+from bt2.fields import _VariantField
+from bt2.graph import *
+from bt2.logging import *
from bt2.notification import *
+from bt2.notification import _DiscardedEventsNotification
+from bt2.notification import _DiscardedPacketsNotification
from bt2.notification_iterator import *
+from bt2.notification_iterator import _UserNotificationIterator
+from bt2.packet import _Packet
from bt2.plugin import *
+from bt2.port import *
+from bt2.port import _InputPort
+from bt2.port import _OutputPort
+from bt2.port import _Port
+from bt2.port import _PrivateInputPort
+from bt2.port import _PrivateOutputPort
+from bt2.port import _PrivatePort
from bt2.py_plugin import *
+from bt2.stream import _Stream
from bt2.stream_class import *
from bt2.trace import *
from bt2.values import *
+from bt2.values import _Value
class Error(Exception):
pass
-class FrozenError(Error):
+class Frozen(Error):
pass
-class NoSuchPluginError(Error):
+class NoSuchPlugin(Error):
pass
pass
+class NoSinkComponent(Exception):
+ pass
+
+
class TryAgain(Exception):
pass
pass
-class IncompleteUserClassError(Error):
+class PortConnectionRefused(Exception):
+ pass
+
+
+class IncompleteUserClass(Error):
pass
+class GraphCanceled(Exception):
+ pass
+
+
+class NotificationIteratorCanceled(Exception):
+ pass
+
+
+class ConnectionEnded(Exception):
+ pass
+
+
+class _ListenerHandle:
+ def __init__(self, listener_id, obj):
+ self._listener_id = listener_id
+ self._obj = obj
+
+
import bt2.native_bt as _native_bt
import atexit
atexit.register(_native_bt.py3_cc_exit_handler)
+version = (_native_bt.version_get_major(), _native_bt.version_get_minor(),
+ _native_bt.version_get_patch(), _native_bt.version_get_extra())
_native_bt.py3_cc_init_from_bt2()
+del _native_bt
+
+try:
+ del native_bt
+except:
+ pass
# The MIT License (MIT)
#
-# Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
from bt2 import native_bt, object, utils
import uuid as uuidp
+import numbers
import bt2
def cycles(self):
return self._cycles
+ def __hash__(self):
+ return hash((self.seconds, self.cycles))
+
def __eq__(self, other):
if not isinstance(other, self.__class__):
# not comparing apples to apples
class ClockClass(object._Object):
- def __init__(self, name, description=None, frequency=None, precision=None,
+ def __init__(self, name, frequency, description=None, precision=None,
offset=None, is_absolute=None, uuid=None):
utils._check_str(name)
- ptr = native_bt.ctf_clock_class_create(name)
+ utils._check_uint64(frequency)
+ ptr = native_bt.ctf_clock_class_create(name, frequency)
if ptr is None:
raise bt2.CreationError('cannot create clock class object')
memo[id(self)] = cpy
return cpy
+ def __hash__(self):
+ return hash((
+ self.name,
+ self.description,
+ self.frequency,
+ self.precision,
+ self.offset.seconds,
+ self.offset.cycles,
+ self.is_absolute,
+ self.uuid))
+
@property
def name(self):
name = native_bt.ctf_clock_class_get_name(self._ptr)
- utils._handle_ptr(name, "cannot get clock class object's name")
+ assert(name is not None)
return name
@name.setter
@property
def description(self):
- description = native_bt.ctf_clock_class_get_description(self._ptr)
- return description
+ return native_bt.ctf_clock_class_get_description(self._ptr)
@description.setter
def description(self, description):
@property
def frequency(self):
frequency = native_bt.ctf_clock_class_get_frequency(self._ptr)
-
- if utils._is_m1ull(frequency):
- raise bt2.Error("cannot get clock class object's frequency")
-
+ assert(frequency >= 1)
return frequency
@frequency.setter
@property
def precision(self):
precision = native_bt.ctf_clock_class_get_precision(self._ptr)
-
- if utils._is_m1ull(precision):
- raise bt2.Error("cannot get clock class object's precision")
-
+ assert(precision >= 0)
return precision
@precision.setter
@property
def offset(self):
ret, offset_s = native_bt.ctf_clock_class_get_offset_s(self._ptr)
- utils._handle_ret(ret, "cannot get clock class object's offset (seconds)")
+ assert(ret == 0)
ret, offset_cycles = native_bt.ctf_clock_class_get_offset_cycles(self._ptr)
- utils._handle_ret(ret, "cannot get clock class object's offset (cycles)")
+ assert(ret == 0)
return ClockClassOffset(offset_s, offset_cycles)
@offset.setter
@property
def is_absolute(self):
- is_absolute = native_bt.ctf_clock_class_get_is_absolute(self._ptr)
- utils._handle_ret(is_absolute, "cannot get clock class object's absoluteness")
+ is_absolute = native_bt.ctf_clock_class_is_absolute(self._ptr)
+ assert(is_absolute >= 0)
return is_absolute > 0
@is_absolute.setter
uuid_bytes = native_bt.ctf_clock_class_get_uuid(self._ptr)
if uuid_bytes is None:
- raise bt2.Error("cannot get clock class object's UUID")
+ return
return uuidp.UUID(bytes=uuid_bytes)
ret = native_bt.ctf_clock_class_set_uuid(self._ptr, uuid.bytes)
utils._handle_ret(ret, "cannot set clock class object's UUID")
- def create_clock_value(self, cycles):
+ def __call__(self, cycles):
return _ClockValue(self._ptr, cycles)
@property
def clock_class(self):
ptr = native_bt.ctf_clock_value_get_class(self._ptr)
- utils._handle_ptr(ptr, "cannot get clock value object's clock class object")
+ assert(ptr)
return ClockClass._create_from_ptr(ptr)
@property
def cycles(self):
ret, cycles = native_bt.ctf_clock_value_get_value(self._ptr)
- utils._handle_ret(ret, "cannot get clock value object's cycles")
+ assert(ret == 0)
return cycles
@property
return ns
def __eq__(self, other):
+ if isinstance(other, numbers.Integral):
+ return int(other) == self.cycles
+
if not isinstance(other, self.__class__):
# not comparing apples to apples
return False
if self.addr == other.addr:
return True
- self_props = self.clock_class.addr, self.cycles
- other_props = other.clock_class.addr, other.cycles
+ self_props = self.clock_class, self.cycles
+ other_props = other.clock_class, other.cycles
return self_props == other_props
def __copy__(self):
- return self.clock_class.create_clock_value(self.cycles)
+ return self.clock_class(self.cycles)
def __deepcopy__(self, memo):
cpy = self.__copy__()
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import collections.abc
+import bt2.clock_class
+import copy
+import bt2
+
+
+class _ClockClassIterator(collections.abc.Iterator):
+ def __init__(self, cc_prio_map):
+ self._cc_prio_map = cc_prio_map
+ self._at = 0
+
+ def __next__(self):
+ if self._at == len(self._cc_prio_map):
+ raise StopIteration
+
+ cc_ptr = native_bt.clock_class_priority_map_get_clock_class_by_index(self._cc_prio_map._ptr,
+ self._at)
+ assert(cc_ptr)
+ clock_class = bt2.ClockClass._create_from_ptr(cc_ptr)
+ self._at += 1
+ return clock_class
+
+
+class ClockClassPriorityMap(object._Object, collections.abc.MutableMapping):
+ def __init__(self, clock_class_priorities=None):
+ ptr = native_bt.clock_class_priority_map_create()
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create clock class priority map object')
+
+ super().__init__(ptr)
+
+ if clock_class_priorities is not None:
+ for clock_class, priority in clock_class_priorities.items():
+ self[clock_class] = priority
+
+ def __getitem__(self, key):
+ utils._check_type(key, bt2.ClockClass)
+ ret, prio = native_bt.clock_class_priority_map_get_clock_class_priority(self._ptr,
+ key._ptr)
+
+ if ret != 0:
+ raise KeyError(key)
+
+ return prio
+
+ def __len__(self):
+ count = native_bt.clock_class_priority_map_get_clock_class_count(self._ptr)
+ assert(count >= 0)
+ return count
+
+ def __delitem__(self):
+ raise NotImplementedError
+
+ def __setitem__(self, key, value):
+ utils._check_type(key, bt2.ClockClass)
+ utils._check_uint64(value)
+ ret = native_bt.clock_class_priority_map_add_clock_class(self._ptr,
+ key._ptr,
+ value)
+ utils._handle_ret(ret, "cannot set clock class's priority in clock class priority map object")
+
+ def __iter__(self):
+ return _ClockClassIterator(self)
+
+ @property
+ def highest_priority_clock_class(self):
+ cc_ptr = native_bt.clock_class_priority_map_get_highest_priority_clock_class(self._ptr)
+
+ if cc_ptr is None:
+ return
+
+ return bt2.ClockClass._create_from_ptr(cc_ptr)
+
+ def _get_prios(self):
+ prios = {}
+
+ for clock_class, prio in self.items():
+ prios[clock_class] = prio
+
+ return prios
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ return self._get_prios() == other._get_prios()
+
+ def _copy(self, cc_copy_func):
+ cpy = ClockClassPriorityMap()
+
+ for clock_class, prio in self.items():
+ cpy[cc_copy_func(clock_class)] = prio
+
+ return cpy
+
+ def __copy__(self):
+ return self._copy(lambda obj: obj)
+
+ def __deepcopy__(self, memo):
+ cpy = self._copy(copy.deepcopy)
+ memo[id(self)] = cpy
+ return cpy
import bt2.notification_iterator
import collections.abc
import bt2.values
+import traceback
+import bt2.port
import sys
import bt2
+import os
+
+
+_env_var = os.environ.get('BABELTRACE_PYTHON_BT2_NO_TRACEBACK')
+_NO_PRINT_TRACEBACK = _env_var == '1'
# This class wraps a component class pointer. This component class could
class _GenericComponentClass(object._Object):
@property
def name(self):
- return native_bt.component_class_get_name(self._ptr)
+ name = native_bt.component_class_get_name(self._ptr)
+ assert(name is not None)
+ return name
@property
def description(self):
def query(self, obj, params=None):
return _query(self._ptr, obj, params)
- def __call__(self, params=None, name=None):
- params = bt2.create_value(params)
- comp_ptr = native_bt.component_create_with_init_method_data(self._ptr,
- name,
- params._ptr,
- None)
-
- if comp_ptr is None:
- raise bt2.CreationError('cannot create component object')
+ def __eq__(self, other):
+ if not isinstance(other, _GenericComponentClass):
+ try:
+ if not issubclass(other, _UserComponent):
+ return False
+ except TypeError:
+ return False
- return _create_generic_component_from_ptr(comp_ptr)
+ return self.addr == other.addr
class _GenericSourceComponentClass(_GenericComponentClass):
pass
+def _handle_component_status(status, gen_error_msg):
+ if status == native_bt.COMPONENT_STATUS_END:
+ raise bt2.Stop
+ elif status == native_bt.COMPONENT_STATUS_AGAIN:
+ raise bt2.TryAgain
+ elif status == native_bt.COMPONENT_STATUS_UNSUPPORTED:
+ raise bt2.UnsupportedFeature
+ elif status == native_bt.COMPONENT_STATUS_REFUSE_PORT_CONNECTION:
+ raise bt2.PortConnectionRefused
+ elif status == native_bt.COMPONENT_STATUS_GRAPH_IS_CANCELED:
+ raise bt2.GraphCanceled
+ elif status < 0:
+ raise bt2.Error(gen_error_msg)
+
+
+class _PortIterator(collections.abc.Iterator):
+ def __init__(self, comp_ports):
+ self._comp_ports = comp_ports
+ self._at = 0
+
+ def __next__(self):
+ if self._at == len(self._comp_ports):
+ raise StopIteration
+
+ comp_ports = self._comp_ports
+ comp_ptr = comp_ports._component._ptr
+ port_ptr = comp_ports._get_port_at_index_fn(comp_ptr, self._at)
+ assert(port_ptr)
+
+ if comp_ports._is_private:
+ port_pub_ptr = native_bt.port_from_private_port(port_ptr)
+ name = native_bt.port_get_name(port_pub_ptr)
+ native_bt.put(port_pub_ptr)
+ else:
+ name = native_bt.port_get_name(port_ptr)
+
+ assert(name is not None)
+ native_bt.put(port_ptr)
+ self._at += 1
+ return name
+
+
+class _ComponentPorts(collections.abc.Mapping):
+ def __init__(self, is_private, component,
+ get_port_by_name_fn, get_port_at_index_fn,
+ get_port_count_fn):
+ self._is_private = is_private
+ self._component = component
+ self._get_port_by_name_fn = get_port_by_name_fn
+ self._get_port_at_index_fn = get_port_at_index_fn
+ self._get_port_count_fn = get_port_count_fn
+
+ def __getitem__(self, key):
+ utils._check_str(key)
+ port_ptr = self._get_port_by_name_fn(self._component._ptr, key)
+
+ if port_ptr is None:
+ raise KeyError(key)
+
+ if self._is_private:
+ return bt2.port._create_private_from_ptr(port_ptr)
+ else:
+ return bt2.port._create_from_ptr(port_ptr)
+
+ def __len__(self):
+ if self._is_private:
+ pub_ptr = native_bt.component_from_private_component(self._component._ptr)
+ count = self._get_port_count_fn(pub_ptr)
+ native_bt.put(pub_ptr)
+ else:
+ count = self._get_port_count_fn(self._component._ptr)
+
+ assert(count >= 0)
+ return count
+
+ def __iter__(self):
+ return _PortIterator(self)
+
+
# This class holds the methods which are common to both generic
# component objects and Python user component objects. They use the
# internal native _ptr, however it was set, to call native API
# functions.
-class _CommonComponentMethods:
+class _Component:
@property
def name(self):
- return native_bt.component_get_name(self._ptr)
+ name = native_bt.component_get_name(self._ptr)
+ assert(name is not None)
+ return name
+
+ @property
+ def graph(self):
+ ptr = native_bt.component_get_graph(self._ptr)
+ assert(ptr)
+ return bt2.Graph._create_from_ptr(ptr)
@property
def component_class(self):
cc_ptr = native_bt.component_get_class(self._ptr)
- utils._handle_ptr(cc_ptr, "cannot get component object's class object")
+ assert(cc_ptr)
return _create_generic_component_class_from_ptr(cc_ptr)
- def _handle_status(self, status, gen_error_msg):
- if status == native_bt.COMPONENT_STATUS_END:
- raise bt2.Stop
- elif status == native_bt.COMPONENT_STATUS_AGAIN:
- raise bt2.TryAgain
- elif status == native_bt.COMPONENT_STATUS_UNSUPPORTED:
- raise bt2.UnsupportedFeature
- elif status < 0:
- raise bt2.Error(gen_error_msg)
-
-
-class _CommonSourceComponentMethods(_CommonComponentMethods):
- def create_notification_iterator(self):
- iter_ptr = native_bt.component_source_create_notification_iterator_with_init_method_data(self._ptr, None)
-
- if iter_ptr is None:
- raise bt2.CreationError('cannot create notification iterator object')
-
- return bt2.notification_iterator._GenericNotificationIterator._create_from_ptr(iter_ptr)
+ def __eq__(self, other):
+ if not hasattr(other, 'addr'):
+ return False
+ return self.addr == other.addr
-class _CommonFilterComponentMethods(_CommonComponentMethods):
- def create_notification_iterator(self):
- iter_ptr = native_bt.component_filter_create_notification_iterator_with_init_method_data(self._ptr, None)
- if iter_ptr is None:
- raise bt2.CreationError('cannot create notification iterator object')
-
- return bt2.notification_iterator._GenericNotificationIterator._create_from_ptr(iter_ptr)
+class _SourceComponent(_Component):
+ pass
- def add_notification_iterator(self, notif_iter):
- utils._check_type(notif_iter, bt2.notification_iterator._GenericNotificationIteratorMethods)
- status = native_bt.component_filter_add_iterator(self._ptr, notif_iter._ptr)
- self._handle_status(status, 'unexpected error: cannot add notification iterator to filter component object')
+class _FilterComponent(_Component):
+ pass
-class _CommonSinkComponentMethods(_CommonComponentMethods):
- def add_notification_iterator(self, notif_iter):
- utils._check_type(notif_iter, bt2.notification_iterator._GenericNotificationIteratorMethods)
- status = native_bt.component_sink_add_iterator(self._ptr, notif_iter._ptr)
- self._handle_status(status, 'unexpected error: cannot add notification iterator to sink component object')
- def consume(self):
- status = native_bt.component_sink_consume(self._ptr)
- self._handle_status(status, 'unexpected error: cannot consume sink component object')
+class _SinkComponent(_Component):
+ pass
# This is analogous to _GenericSourceComponentClass, but for source
# component objects.
-class _GenericSourceComponent(object._Object, _CommonSourceComponentMethods):
- pass
+class _GenericSourceComponent(object._Object, _SourceComponent):
+ @property
+ def output_ports(self):
+ return _ComponentPorts(False, self,
+ native_bt.component_source_get_output_port_by_name,
+ native_bt.component_source_get_output_port_by_index,
+ native_bt.component_source_get_output_port_count)
# This is analogous to _GenericFilterComponentClass, but for filter
# component objects.
-class _GenericFilterComponent(object._Object, _CommonFilterComponentMethods):
- pass
+class _GenericFilterComponent(object._Object, _FilterComponent):
+ @property
+ def output_ports(self):
+ return _ComponentPorts(False, self,
+ native_bt.component_filter_get_output_port_by_name,
+ native_bt.component_filter_get_output_port_by_index,
+ native_bt.component_filter_get_output_port_count)
+
+ @property
+ def input_ports(self):
+ return _ComponentPorts(False, self,
+ native_bt.component_filter_get_input_port_by_name,
+ native_bt.component_filter_get_input_port_by_index,
+ native_bt.component_filter_get_input_port_count)
# This is analogous to _GenericSinkComponentClass, but for sink
# component objects.
-class _GenericSinkComponent(object._Object, _CommonSinkComponentMethods):
- pass
+class _GenericSinkComponent(object._Object, _SinkComponent):
+ @property
+ def input_ports(self):
+ return _ComponentPorts(False, self,
+ native_bt.component_sink_get_input_port_by_name,
+ native_bt.component_sink_get_input_port_by_index,
+ native_bt.component_sink_get_input_port_count)
-_COMP_CLS_TYPE_TO_GENERIC_COMP_CLS = {
+_COMP_CLS_TYPE_TO_GENERIC_COMP_PYCLS = {
native_bt.COMPONENT_CLASS_TYPE_SOURCE: _GenericSourceComponent,
native_bt.COMPONENT_CLASS_TYPE_FILTER: _GenericFilterComponent,
native_bt.COMPONENT_CLASS_TYPE_SINK: _GenericSinkComponent,
}
-_COMP_CLS_TYPE_TO_GENERIC_COMP_CLS_CLS = {
+_COMP_CLS_TYPE_TO_GENERIC_COMP_CLS_PYCLS = {
native_bt.COMPONENT_CLASS_TYPE_SOURCE: _GenericSourceComponentClass,
native_bt.COMPONENT_CLASS_TYPE_FILTER: _GenericFilterComponentClass,
native_bt.COMPONENT_CLASS_TYPE_SINK: _GenericSinkComponentClass,
def _create_generic_component_from_ptr(ptr):
comp_cls_type = native_bt.component_get_class_type(ptr)
- return _COMP_CLS_TYPE_TO_GENERIC_COMP_CLS[comp_cls_type]._create_from_ptr(ptr)
+ return _COMP_CLS_TYPE_TO_GENERIC_COMP_PYCLS[comp_cls_type]._create_from_ptr(ptr)
def _create_generic_component_class_from_ptr(ptr):
comp_cls_type = native_bt.component_class_get_type(ptr)
- return _COMP_CLS_TYPE_TO_GENERIC_COMP_CLS_CLS[comp_cls_type]._create_from_ptr(ptr)
+ return _COMP_CLS_TYPE_TO_GENERIC_COMP_CLS_PYCLS[comp_cls_type]._create_from_ptr(ptr)
def _trim_docstring(docstring):
params_ptr = params._ptr
results_ptr = native_bt.component_class_query(comp_cls_ptr, obj,
- params_ptr)
+ params_ptr)
if results_ptr is None:
raise bt2.Error('cannot query info with object "{}"'.format(obj))
- if results_ptr == native_bt.value_null:
- return
-
return bt2.values._create_from_ptr(results_ptr)
# Metaclass for component classes defined by Python code.
#
# The Python user can create a standard Python class which inherits one
-# of the three base classes (UserSourceComponent, UserFilterComponent,
-# or UserSinkComponent). Those base classes set this class
+# of the three base classes (_UserSourceComponent, _UserFilterComponent,
+# or _UserSinkComponent). Those base classes set this class
# (_UserComponentType) as their metaclass.
#
# Once the body of a user-defined component class is executed, this
# def __init__(self, params, name, something_else):
# ...
#
-# The user-defined component class can also have a _destroy() method
+# The user-defined component class can also have a _finalize() method
# (do NOT use __del__()) to be notified when the component object is
-# (really) destroyed.
+# finalized.
#
# User-defined source and filter component classes must use the
# `notification_iterator_class` class parameter to specify the
# notification iterator class to use for this component class:
#
-# class MyNotificationIterator(bt2.UserNotificationIterator):
+# class MyNotificationIterator(bt2._UserNotificationIterator):
# ...
#
-# class MySource(bt2.UserSourceComponent,
+# class MySource(bt2._UserSourceComponent,
# notification_iterator_class=MyNotificationIterator):
# ...
#
# This notification iterator class must inherit
-# bt2.UserNotificationIterator, and it must define the _get() and
+# bt2._UserNotificationIterator, and it must define the _get() and
# _next() methods. The notification iterator class can also define an
# __init__() method: this method has access to the original Python
# component object which was used to create it as the `component`
-# property. The notification iterator class can also define a _destroy()
-# method (again, do NOT use __del__()): this is called when the
-# notification iterator is (really) destroyed.
+# property. The notification iterator class can also define a
+# _finalize() method (again, do NOT use __del__()): this is called when
+# the notification iterator is (really) destroyed.
#
# When the user-defined class is destroyed, this metaclass's __del__()
# method is called: the native BT component class pointer is put (not
super().__init__(class_name, bases, namespace)
# skip our own bases; they are never directly instantiated by the user
- if class_name in ('_UserComponent', 'UserSourceComponent', 'UserFilterComponent', 'UserSinkComponent'):
+ own_bases = (
+ '_UserComponent',
+ '_UserFilterSinkComponent',
+ '_UserSourceComponent',
+ '_UserFilterComponent',
+ '_UserSinkComponent',
+ )
+
+ if class_name in own_bases:
return
comp_cls_name = kwargs.get('name', class_name)
+ utils._check_str(comp_cls_name)
comp_cls_descr = None
comp_cls_help = None
if hasattr(cls, '__doc__') and cls.__doc__ is not None:
+ utils._check_str(cls.__doc__)
docstring = _trim_docstring(cls.__doc__)
lines = docstring.splitlines()
iter_cls = kwargs.get('notification_iterator_class')
- if UserSourceComponent in bases:
+ if _UserSourceComponent in bases:
_UserComponentType._set_iterator_class(cls, iter_cls)
- has_seek_time = _UserComponentType._has_seek_to_time_method(cls._iter_cls)
cc_ptr = native_bt.py3_component_class_source_create(cls,
comp_cls_name,
comp_cls_descr,
- comp_cls_help,
- has_seek_time)
- elif UserFilterComponent in bases:
+ comp_cls_help)
+ elif _UserFilterComponent in bases:
_UserComponentType._set_iterator_class(cls, iter_cls)
- has_seek_time = _UserComponentType._has_seek_to_time_method(cls._iter_cls)
cc_ptr = native_bt.py3_component_class_filter_create(cls,
comp_cls_name,
comp_cls_descr,
- comp_cls_help,
- has_seek_time)
- elif UserSinkComponent in bases:
+ comp_cls_help)
+ elif _UserSinkComponent in bases:
if not hasattr(cls, '_consume'):
- raise bt2.IncompleteUserClassError("cannot create component class '{}': missing a _consume() method".format(class_name))
+ raise bt2.IncompleteUserClass("cannot create component class '{}': missing a _consume() method".format(class_name))
cc_ptr = native_bt.py3_component_class_sink_create(cls,
comp_cls_name,
comp_cls_descr,
comp_cls_help)
else:
- raise bt2.IncompleteUserClassError("cannot find a known component class base in the bases of '{}'".format(class_name))
+ raise bt2.IncompleteUserClass("cannot find a known component class base in the bases of '{}'".format(class_name))
if cc_ptr is None:
raise bt2.CreationError("cannot create component class '{}'".format(class_name))
cls._cc_ptr = cc_ptr
- def __call__(cls, *args, **kwargs):
- # create instance
+ def _init_from_native(cls, comp_ptr, params_ptr):
+ # create instance, not user-initialized yet
self = cls.__new__(cls)
- # assign native component pointer received from caller
- self._ptr = kwargs.get('__comp_ptr')
- name = kwargs.get('name')
-
- if self._ptr is None:
- # called from Python code
- self._belongs_to_native_component = False
-
- # py3_component_create() will call self.__init__() with the
- # desired arguments and keyword arguments. This is needed
- # because functions such as
- # bt_component_sink_set_minimum_input_count() can only be
- # called _during_ the bt_component_create() call (in
- # Python words: during self.__init__()).
- #
- # The arguments and keyword arguments to use for
- # self.__init__() are put in the object itself to find them
- # from the bt_component_create() function.
- self._init_args = args
- self._init_kwargs = kwargs
- native_bt.py3_component_create(cls._cc_ptr, self, name)
-
- # At this point, self._ptr should be set to non-None. If
- # it's not, an error occured during the
- # native_bt.py3_component_create() call. We consider this a
- # creation error.
- if self._ptr is None:
- raise bt2.CreationError("cannot create component object from component class '{}'".format(cls.__name__))
- else:
- # Called from non-Python code (within
- # bt_component_create()): call __init__() here, after
- # removing the __comp_ptr keyword argument which is just for
- # this __call__() method.
- self._belongs_to_native_component = True
- del kwargs['__comp_ptr']
+ # pointer to native private component object (weak/borrowed)
+ self._ptr = comp_ptr
- # inject `name` into the keyword arguments
- kwargs['name'] = self.name
- self.__init__(*args, **kwargs)
+ # call user's __init__() method
+ if params_ptr is not None:
+ native_bt.get(params_ptr)
+ params = bt2.values._create_from_ptr(params_ptr)
+ else:
+ params = None
+ self.__init__(params)
return self
- @staticmethod
- def _has_seek_to_time_method(iter_cls):
- return hasattr(iter_cls, '_seek_to_time')
+ def __call__(cls, *args, **kwargs):
+ raise bt2.Error('cannot directly instantiate a user component from a Python module')
@staticmethod
def _set_iterator_class(cls, iter_cls):
if iter_cls is None:
- raise bt2.IncompleteUserClassError("cannot create component class '{}': missing notification iterator class".format(cls.__name__))
+ raise bt2.IncompleteUserClass("cannot create component class '{}': missing notification iterator class".format(cls.__name__))
- if not issubclass(iter_cls, bt2.notification_iterator.UserNotificationIterator):
- raise bt2.IncompleteUserClassError("cannot create component class '{}': notification iterator class does not inherit bt2.UserNotificationIterator".format(cls.__name__))
+ if not issubclass(iter_cls, bt2.notification_iterator._UserNotificationIterator):
+ raise bt2.IncompleteUserClass("cannot create component class '{}': notification iterator class does not inherit bt2._UserNotificationIterator".format(cls.__name__))
- if not hasattr(iter_cls, '_get'):
- raise bt2.IncompleteUserClassError("cannot create component class '{}': notification iterator class is missing a _get() method".format(cls.__name__))
-
- if not hasattr(iter_cls, '_next'):
- raise bt2.IncompleteUserClassError("cannot create component class '{}': notification iterator class is missing a _next() method".format(cls.__name__))
+ if not hasattr(iter_cls, '__next__'):
+ raise bt2.IncompleteUserClass("cannot create component class '{}': notification iterator class is missing a __next__() method".format(cls.__name__))
cls._iter_cls = iter_cls
def addr(cls):
return int(cls._cc_ptr)
- def query(cls, action, params=None):
- return _query(cls._cc_ptr, action, params)
+ def query(cls, obj, params=None):
+ return _query(cls._cc_ptr, obj, params)
- def _query_from_bt(cls, action, params):
+ def _query_from_native(cls, obj, params_ptr):
# this can raise, in which case the native call to
# bt_component_class_query() returns NULL
- results = cls._query(action, params)
- results = bt2.create_value(results)
+ if params_ptr is not None:
+ native_bt.get(params_ptr)
+ params = bt2.values._create_from_ptr(params_ptr)
+ else:
+ params = None
+
+ try:
+ results = cls._query(obj, params)
+ except:
+ if not _NO_PRINT_TRACEBACK:
+ traceback.print_exc()
+
+ return
+
+ if results is NotImplemented:
+ return results
+
+ try:
+ results = bt2.create_value(results)
+ except:
+ if not _NO_PRINT_TRACEBACK:
+ traceback.print_exc()
+
+ return
if results is None:
results_addr = int(native_bt.value_null)
else:
- # steal the underlying native value object for the caller
+ # return new reference
+ results._get()
results_addr = int(results._ptr)
- results._ptr = None
return results_addr
- @staticmethod
- def _query(action, params):
+ @classmethod
+ def _query(cls, obj, params):
# BT catches this and returns NULL to the user
- raise NotImplementedError
+ return NotImplemented
+
+ def __eq__(self, other):
+ if not hasattr(other, 'addr'):
+ return False
+
+ return self.addr == other.addr
def __del__(cls):
if hasattr(cls, '_cc_ptr'):
native_bt.put(cls._cc_ptr)
-class _ComponentInputNotificationIterators(collections.abc.Sequence):
- def __init__(self, comp, count_func, get_func):
- self._comp = comp
- self._count_func = count_func
- self._get_func = get_func
-
- def __len__(self):
- status, count = self._count_func(self._comp._ptr)
- utils._handle_ret(status, "cannot get component object's input notification iterator count")
- return count
-
- def __getitem__(self, index):
- utils._check_uint64(index)
-
- if index >= len(self):
- raise IndexError
+class _UserComponent(metaclass=_UserComponentType):
+ @property
+ def name(self):
+ pub_ptr = native_bt.component_from_private_component(self._ptr)
+ name = native_bt.component_get_name(pub_ptr)
+ native_bt.put(pub_ptr)
+ assert(name is not None)
+ return name
- notif_iter_ptr = self._get_func(self._comp._ptr, index)
- utils._handle_ptr(notif_iter_ptr, "cannot get component object's input notification iterator")
- return bt2.notification_iterator._GenericNotificationIterator._create_from_ptr(notif_iter_ptr)
+ @property
+ def graph(self):
+ pub_ptr = native_bt.component_from_private_component(self._ptr)
+ ptr = native_bt.component_get_graph(pub_ptr)
+ native_bt.put(pub_ptr)
+ assert(ptr)
+ return bt2.Graph._create_from_ptr(ptr)
+ @property
+ def component_class(self):
+ pub_ptr = native_bt.component_from_private_component(self._ptr)
+ cc_ptr = native_bt.component_get_class(pub_ptr)
+ native_bt.put(pub_ptr)
+ assert(cc_ptr)
+ return _create_generic_component_class_from_ptr(cc_ptr)
-class _UserComponent(metaclass=_UserComponentType):
@property
def addr(self):
return int(self._ptr)
- def __init__(self, *args, **kwargs):
+ def __init__(self, params=None):
pass
- def _destroy(self):
+ def _finalize(self):
pass
- def __del__(self):
- if not self._belongs_to_native_component:
- self._belongs_to_native_component = True
- native_bt.py3_component_on_del(self)
- native_bt.put(self._ptr)
-
-
-class UserSourceComponent(_UserComponent, _CommonSourceComponentMethods):
- pass
-
+ def _accept_port_connection(self, port, other_port):
+ return True
-class UserFilterComponent(_UserComponent, _CommonFilterComponentMethods):
- def _set_minimum_input_notification_iterator_count(self, count):
- utils._check_uint64(count)
- status = native_bt.component_filter_set_minimum_input_count(self._ptr, count)
- self._handle_status(status, "unexpected error: cannot set filter component object's minimum input notification iterator count")
+ def _accept_port_connection_from_native(self, port_ptr, other_port_ptr):
+ native_bt.get(port_ptr)
+ native_bt.get(other_port_ptr)
+ port = bt2.port._create_private_from_ptr(port_ptr)
+ other_port = bt2.port._create_from_ptr(other_port_ptr)
+ res = self._accept_port_connection(port, other_port_ptr)
- _minimum_input_notification_iterator_count = property(fset=_set_minimum_input_notification_iterator_count)
+ if type(res) is not bool:
+ raise TypeError("'{}' is not a 'bool' object")
- def _set_maximum_input_notification_iterator_count(self, count):
- utils._check_uint64(count)
- status = native_bt.component_filter_set_maximum_input_count(self._ptr, count)
- self._handle_status(status, "unexpected error: cannot set filter component object's maximum input notification iterator count")
+ return res
- _maximum_input_notification_iterator_count = property(fset=_set_maximum_input_notification_iterator_count)
+ def _port_connected(self, port, other_port):
+ pass
- @property
- def _input_notification_iterators(self):
- return _ComponentInputNotificationIterators(self,
- native_bt.component_filter_get_input_count,
- native_bt.component_filter_get_input_iterator_private)
+ def _port_connected_from_native(self, port_ptr, other_port_ptr):
+ native_bt.get(port_ptr)
+ native_bt.get(other_port_ptr)
+ port = bt2.port._create_private_from_ptr(port_ptr)
+ other_port = bt2.port._create_from_ptr(other_port_ptr)
- def _add_iterator_from_bt(self, notif_iter_ptr):
- notif_iter = bt2.notification_iterator._GenericNotificationIterator._create_from_ptr(notif_iter_ptr)
- self._add_notification_iterator(notif_iter)
+ try:
+ self._port_connected(port, other_port_ptr)
+ except:
+ if not _NO_PRINT_TRACEBACK:
+ traceback.print_exc()
- def _add_notification_iterator(self, notif_iter):
+ def _port_disconnected(self, port):
pass
+ def _port_disconnected_from_native(self, port_ptr):
+ native_bt.get(port_ptr)
+ port = bt2.port._create_private_from_ptr(port_ptr)
-class UserSinkComponent(_UserComponent, _CommonSinkComponentMethods):
- def _set_minimum_input_notification_iterator_count(self, count):
- utils._check_uint64(count)
- status = native_bt.component_sink_set_minimum_input_count(self._ptr, count)
- self._handle_status(status, "unexpected error: cannot set sink component object's minimum input notification iterator count")
-
- _minimum_input_notification_iterator_count = property(fset=_set_minimum_input_notification_iterator_count)
-
- def _set_maximum_input_notification_iterator_count(self, count):
- utils._check_uint64(count)
- status = native_bt.component_sink_set_maximum_input_count(self._ptr, count)
- self._handle_status(status, "unexpected error: cannot set sink component object's maximum input notification iterator count")
+ try:
+ self._port_disconnected(port)
+ except:
+ if not _NO_PRINT_TRACEBACK:
+ traceback.print_exc()
- _maximum_input_notification_iterator_count = property(fset=_set_maximum_input_notification_iterator_count)
+class _UserSourceComponent(_UserComponent, _SourceComponent):
@property
- def _input_notification_iterators(self):
- return _ComponentInputNotificationIterators(self,
- native_bt.component_sink_get_input_count,
- native_bt.component_sink_get_input_iterator_private)
-
- def _add_iterator_from_bt(self, notif_iter_ptr):
- notif_iter = bt2.notification_iterator._GenericNotificationIterator._create_from_ptr(notif_iter_ptr)
- self._add_notification_iterator(notif_iter)
+ def _output_ports(self):
+ return _ComponentPorts(True, self,
+ native_bt.private_component_source_get_output_private_port_by_name,
+ native_bt.private_component_source_get_output_private_port_by_index,
+ native_bt.component_source_get_output_port_count)
+
+ def _add_output_port(self, name):
+ utils._check_str(name)
+ fn = native_bt.private_component_source_add_output_private_port
+ comp_status, priv_port_ptr = fn(self._ptr, name, None)
+ _handle_component_status(comp_status,
+ 'cannot add output port to source component object')
+ assert(priv_port_ptr)
+ return bt2.port._create_private_from_ptr(priv_port_ptr)
+
+
+class _UserFilterComponent(_UserComponent, _FilterComponent):
+ @property
+ def _output_ports(self):
+ return _ComponentPorts(True, self,
+ native_bt.private_component_filter_get_output_private_port_by_name,
+ native_bt.private_component_filter_get_output_private_port_by_index,
+ native_bt.component_filter_get_output_port_count)
- def _add_notification_iterator(self, notif_iter):
- pass
+ @property
+ def _input_ports(self):
+ return _ComponentPorts(True, self,
+ native_bt.private_component_filter_get_input_private_port_by_name,
+ native_bt.private_component_filter_get_input_private_port_by_index,
+ native_bt.component_filter_get_input_port_count)
+
+ def _add_output_port(self, name):
+ utils._check_str(name)
+ fn = native_bt.private_component_filter_add_output_private_port
+ comp_status, priv_port_ptr = fn(self._ptr, name, None)
+ _handle_component_status(comp_status,
+ 'cannot add output port to filter component object')
+ assert(priv_port_ptr)
+ return bt2.port._create_private_from_ptr(priv_port_ptr)
+
+ def _add_input_port(self, name):
+ utils._check_str(name)
+ fn = native_bt.private_component_filter_add_input_private_port
+ comp_status, priv_port_ptr = fn(self._ptr, name, None)
+ _handle_component_status(comp_status,
+ 'cannot add input port to filter component object')
+ assert(priv_port_ptr)
+ return bt2.port._create_private_from_ptr(priv_port_ptr)
+
+
+class _UserSinkComponent(_UserComponent, _SinkComponent):
+ @property
+ def _input_ports(self):
+ return _ComponentPorts(True, self,
+ native_bt.private_component_sink_get_input_private_port_by_name,
+ native_bt.private_component_sink_get_input_private_port_by_index,
+ native_bt.component_sink_get_input_port_count)
+
+ def _add_input_port(self, name):
+ utils._check_str(name)
+ fn = native_bt.private_component_sink_add_input_private_port
+ comp_status, priv_port_ptr = fn(self._ptr, name, None)
+ _handle_component_status(comp_status,
+ 'cannot add input port to sink component object')
+ assert(priv_port_ptr)
+ return bt2.port._create_private_from_ptr(priv_port_ptr)
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.notification_iterator
+import collections.abc
+import bt2.port
+import copy
+import bt2
+
+
+def _handle_status(status, gen_error_msg):
+ if status == native_bt.CONNECTION_STATUS_GRAPH_IS_CANCELED:
+ raise bt2.GraphCanceled
+ elif status == native_bt.CONNECTION_STATUS_IS_ENDED:
+ raise bt2.ConnectionEnded
+ elif status < 0:
+ raise bt2.Error(gen_error_msg)
+
+
+def _create_private_from_ptr(ptr):
+ obj = _PrivateConnection._create_from_ptr(ptr)
+ obj._pub_ptr = native_bt.connection_from_private_connection(ptr)
+ assert(obj._pub_ptr)
+ return obj
+
+
+class _Connection(object._Object):
+ @staticmethod
+ def _downstream_port(ptr):
+ port_ptr = native_bt.connection_get_downstream_port(ptr)
+ utils._handle_ptr(port_ptr, "cannot get connection object's downstream port object")
+ return bt2.port._create_from_ptr(port_ptr)
+
+ @staticmethod
+ def _upstream_port(ptr):
+ port_ptr = native_bt.connection_get_upstream_port(ptr)
+ utils._handle_ptr(port_ptr, "cannot get connection object's upstream port object")
+ return bt2.port._create_from_ptr(port_ptr)
+
+ @property
+ def downstream_port(self):
+ return self._downstream_port(self._ptr)
+
+ @property
+ def upstream_port(self):
+ return self._upstream_port(self._ptr)
+
+ @staticmethod
+ def _is_ended(ptr):
+ return native_bt.connection_is_ended(ptr) == 1
+
+ @property
+ def is_ended(self):
+ return self._is_ended(self._ptr)
+
+ def __eq__(self, other):
+ if type(other) not in (_Connection, _PrivateConnection):
+ return False
+
+ return self.addr == other.addr
+
+
+class _PrivateConnection(object._PrivateObject, _Connection):
+ def create_notification_iterator(self, notification_types=None):
+ if notification_types is None:
+ notif_types = None
+ else:
+ for notif_cls in notification_types:
+ if notif_cls not in bt2.notification._NOTIF_TYPE_TO_CLS.values():
+ raise ValueError("'{}' is not a notification class".format(notif_cls))
+
+ notif_types = [notif_cls._TYPE for notif_cls in notification_types]
+
+ status, notif_iter_ptr = native_bt.py3_create_notif_iter(int(self._ptr),
+ notif_types)
+ _handle_status(status, 'cannot create notification iterator object')
+ assert(notif_iter_ptr)
+ return bt2.notification_iterator._GenericNotificationIterator._create_from_ptr(notif_iter_ptr)
+
+ @property
+ def is_ended(self):
+ return self._is_ended(self._pub_ptr)
+
+ @property
+ def downstream_port(self):
+ return self._downstream_port(self._pub_ptr)
+
+ @property
+ def upstream_port(self):
+ return self._upstream_port(self._pub_ptr)
@property
def name(self):
name = native_bt.ctf_clock_get_name(self._ptr)
- utils._handle_ptr(name, "cannot get CTF writer clock object's name")
+ assert(name is not None)
return name
@property
@property
def frequency(self):
frequency = native_bt.ctf_clock_get_frequency(self._ptr)
-
- if utils._is_m1ull(frequency):
- raise bt2.Error("cannot get CTF writer clock object's frequency")
-
+ assert(frequency >= 1)
return frequency
@frequency.setter
@property
def precision(self):
precision = native_bt.ctf_clock_get_precision(self._ptr)
-
- if utils._is_m1ull(precision):
- raise bt2.Error("cannot get CTF writer clock object's precision")
-
+ assert(precision >= 0)
return precision
@precision.setter
@property
def offset(self):
ret, offset_s = native_bt.ctf_clock_get_offset_s(self._ptr)
- utils._handle_ret(ret, "cannot get CTF writer clock object's offset (seconds)")
+ assert(ret == 0)
ret, offset_cycles = native_bt.ctf_clock_get_offset(self._ptr)
- utils._handle_ret(ret, "cannot get CTF writer clock object's offset (cycles)")
+ assert(ret == 0)
return bt2.ClockClassOffset(offset_s, offset_cycles)
@offset.setter
@property
def is_absolute(self):
is_absolute = native_bt.ctf_clock_get_is_absolute(self._ptr)
- utils._handle_ret(is_absolute, "cannot get CTF writer clock object's absoluteness")
+ assert(is_absolute >= 0)
return is_absolute > 0
@is_absolute.setter
@property
def uuid(self):
uuid_bytes = native_bt.ctf_clock_get_uuid(self._ptr)
-
- if uuid_bytes is None:
- raise bt2.Error("cannot get CTF writer clock object's UUID")
-
+ assert(uuid_bytes is not None)
return uuidp.UUID(bytes=uuid_bytes)
@uuid.setter
@property
def trace(self):
trace_ptr = native_bt.ctf_writer_get_trace(self._ptr)
- utils._handle_ptr(name, "cannot get CTF writer object's trace class")
+ assert(trace_ptr)
return bt2.Trace._create_from_ptr(trace_ptr)
@property
def metadata_string(self):
metadata_string = native_bt.ctf_writer_get_metadata_string(self._ptr)
- utils._handle_ptr(metadata_string, "cannot get CTF writer object's metadata string")
+ assert(metadata_string is not None)
return metadata_string
def flush_metadata(self):
@property
def payload_field(self):
- field_ptr = native_bt.ctf_event_get_payload_field(self._ptr)
+ field_ptr = native_bt.ctf_event_get_event_payload(self._ptr)
if field_ptr is None:
return
utils._check_type(payload, bt2.fields._Field)
payload_ptr = payload._ptr
- ret = native_bt.ctf_event_set_payload_field(self._ptr, payload_ptr)
+ ret = native_bt.ctf_event_set_event_payload(self._ptr, payload_ptr)
utils._handle_ret(ret, "cannot set event object's payload field")
def _get_clock_value_cycles(self, clock_class_ptr):
utils._handle_ret(ret, "cannot get clock value object's cycles")
return cycles
- def get_clock_value(self, clock_class):
+ def clock_value(self, clock_class):
utils._check_type(clock_class, bt2.ClockClass)
clock_value_ptr = native_bt.ctf_event_get_clock_value(self._ptr,
clock_class._ptr)
clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
return clock_value
- def set_clock_value(self, clock_value):
+ def add_clock_value(self, clock_value):
utils._check_type(clock_value, bt2.clock_class._ClockValue)
ret = native_bt.ctf_event_set_clock_value(self._ptr,
clock_value._ptr)
cpy.context_field = copy_func(self.context_field)
cpy.payload_field = copy_func(self.payload_field)
- # copy known clock values
+ # Copy known clock value references. It's not necessary to copy
+ # clock class or clock value objects because once a clock value
+ # is created from a clock class, the clock class is frozen.
+ # Thus even if we copy the clock class, the user cannot modify
+ # it, therefore it's useless to copy it.
for clock_class in self._clock_classes:
- clock_value = self.get_clock_value(clock_class)
+ clock_value = self.clock_value(clock_class)
if clock_value is not None:
- cpy.set_clock_value(clock_value)
+ cpy.add_clock_value(clock_value)
return cpy
# The MIT License (MIT)
#
-# Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
import bt2
-class _EventClassAttributesIterator(collections.abc.Iterator):
- def __init__(self, attributes):
- self._attributes = attributes
- self._at = 0
-
- def __next__(self):
- if self._at == len(self._attributes):
- raise StopIteration
-
- name = native_bt.ctf_event_class_get_attribute_name(self._attributes._event_class_ptr,
- self._at)
- utils._handle_ptr("cannot get event class object's attribute name")
- self._at += 1
- return name
-
-
-class _EventClassAttributes(collections.abc.MutableMapping):
- def __init__(self, event_class_ptr):
- self._event_class_ptr = event_class_ptr
-
- def __getitem__(self, key):
- utils._check_str(key)
- value_ptr = native_bt.ctf_event_class_get_attribute_value_by_name(self._event_class_ptr,
- key)
-
- if value_ptr is None:
- raise KeyError(key)
-
- return bt2.values._create_from_ptr(value_ptr)
-
- def __setitem__(self, key, value):
- utils._check_str(key)
- value = bt2.create_value(value)
- ret = native_bt.ctf_event_class_set_attribute(self._event_class_ptr, key,
- value._ptr)
- utils._handle_ret(ret, "cannot set event class object's attribute")
-
- def __delitem__(self, key):
- raise NotImplementedError
-
- def __len__(self):
- count = native_bt.ctf_event_class_get_attribute_count(self._event_class_ptr)
- utils._handle_ret(count, "cannot get event class object's attribute count")
- return count
-
- def __iter__(self):
- return _EventClassAttributesIterator(self)
+class EventClassLogLevel:
+ UNKNOWN = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN
+ UNSPECIFIED = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED
+ EMERGENCY = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY
+ ALERT = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_ALERT
+ CRITICAL = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL
+ ERROR = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_ERROR
+ WARNING = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_WARNING
+ NOTICE = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_NOTICE
+ INFO = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_INFO
+ DEBUG_SYSTEM = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM
+ DEBUG_PROGRAM = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM
+ DEBUG_PROCESS = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS
+ DEBUG_MODULE = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE
+ DEBUG_UNIT = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT
+ DEBUG_FUNCTION = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION
+ DEBUG_LINE = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE
+ DEBUG = native_bt.CTF_EVENT_CLASS_LOG_LEVEL_DEBUG
class EventClass(object._Object):
- def __init__(self, name, id=None, context_field_type=None,
- payload_field_type=None, attributes=None):
+ def __init__(self, name, id=None, log_level=None, emf_uri=None,
+ context_field_type=None, payload_field_type=None):
utils._check_str(name)
ptr = native_bt.ctf_event_class_create(name)
if id is not None:
self.id = id
+ if log_level is not None:
+ self.log_level = log_level
+
+ if emf_uri is not None:
+ self.emf_uri = emf_uri
+
if context_field_type is not None:
self.context_field_type = context_field_type
if payload_field_type is not None:
self.payload_field_type = payload_field_type
- if attributes is not None:
- for name, value in attributes.items():
- self.attributes[name] = value
-
@property
def stream_class(self):
sc_ptr = native_bt.ctf_event_class_get_stream_class(self._ptr)
if sc_ptr is not None:
return bt2.StreamClass._create_from_ptr(sc_ptr)
- @property
- def attributes(self):
- return _EventClassAttributes(self._ptr)
-
@property
def name(self):
return native_bt.ctf_event_class_get_name(self._ptr)
@property
def id(self):
id = native_bt.ctf_event_class_get_id(self._ptr)
-
- if utils._is_m1ull(id):
- raise bt2.Error("cannot get event class object's ID")
-
- return id
+ return id if id >= 0 else None
@id.setter
def id(self, id):
ret = native_bt.ctf_event_class_set_id(self._ptr, id)
utils._handle_ret(ret, "cannot set event class object's ID")
+ @property
+ def log_level(self):
+ log_level = native_bt.ctf_event_class_get_log_level(self._ptr)
+ return log_level if log_level >= 0 else None
+
+ @log_level.setter
+ def log_level(self, log_level):
+ log_levels = (
+ EventClassLogLevel.UNSPECIFIED,
+ EventClassLogLevel.EMERGENCY,
+ EventClassLogLevel.ALERT,
+ EventClassLogLevel.CRITICAL,
+ EventClassLogLevel.ERROR,
+ EventClassLogLevel.WARNING,
+ EventClassLogLevel.NOTICE,
+ EventClassLogLevel.INFO,
+ EventClassLogLevel.DEBUG_SYSTEM,
+ EventClassLogLevel.DEBUG_PROGRAM,
+ EventClassLogLevel.DEBUG_PROCESS,
+ EventClassLogLevel.DEBUG_MODULE,
+ EventClassLogLevel.DEBUG_UNIT,
+ EventClassLogLevel.DEBUG_FUNCTION,
+ EventClassLogLevel.DEBUG_LINE,
+ EventClassLogLevel.DEBUG,
+ )
+
+ if log_level not in log_levels:
+ raise ValueError("'{}' is not a valid log level".format(log_level))
+
+ ret = native_bt.ctf_event_class_set_log_level(self._ptr, log_level)
+ utils._handle_ret(ret, "cannot set event class object's log level")
+
+ @property
+ def emf_uri(self):
+ return native_bt.ctf_event_class_get_emf_uri(self._ptr)
+
+ @emf_uri.setter
+ def emf_uri(self, emf_uri):
+ utils._check_str(emf_uri)
+ ret = native_bt.ctf_event_class_set_emf_uri(self._ptr, emf_uri)
+ utils._handle_ret(ret, "cannot set event class object's EMF URI")
+
@property
def context_field_type(self):
ft_ptr = native_bt.ctf_event_class_get_context_type(self._ptr)
if self.addr == other.addr:
return True
- self_attributes = {name: val for name, val in self.attributes.items()}
- other_attributes = {name: val for name, val in other.attributes.items()}
self_props = (
- self_attributes,
self.name,
self.id,
+ self.log_level,
+ self.emf_uri,
self.context_field_type,
self.payload_field_type
)
other_props = (
- other_attributes,
other.name,
other.id,
+ other.log_level,
+ other.emf_uri,
other.context_field_type,
other.payload_field_type
)
cpy = EventClass(self.name)
cpy.id = self.id
- for name, value in self.attributes.items():
- cpy.attributes[name] = value
+ if self.log_level is not None:
+ cpy.log_level = self.log_level
+
+ if self.emf_uri is not None:
+ cpy.emf_uri = self.emf_uri
cpy.context_field_type = ft_copy_func(self.context_field_type)
cpy.payload_field_type = ft_copy_func(self.payload_field_type)
# The MIT License (MIT)
#
-# Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@property
def alignment(self):
alignment = native_bt.ctf_field_type_get_alignment(self._ptr)
- utils._handle_ret(alignment, "cannot get field type object's alignment")
+ assert(alignment >= 0)
return alignment
@alignment.setter
@property
def byte_order(self):
bo = native_bt.ctf_field_type_get_byte_order(self._ptr)
- utils._handle_ret(bo, "cannot get field type object's byte order")
+ assert(bo >= 0)
return bo
@byte_order.setter
@property
def size(self):
size = native_bt.ctf_field_type_integer_get_size(self._ptr)
- utils._handle_ret(size, "cannot get integer field type object's size")
+ assert(size >= 1)
return size
@property
def is_signed(self):
- is_signed = native_bt.ctf_field_type_integer_get_signed(self._ptr)
- utils._handle_ret(is_signed,
- "cannot get integer field type object's signedness")
+ is_signed = native_bt.ctf_field_type_integer_is_signed(self._ptr)
+ assert(is_signed >= 0)
return is_signed > 0
@is_signed.setter
def is_signed(self, is_signed):
utils._check_bool(is_signed)
- ret = native_bt.ctf_field_type_integer_set_signed(self._ptr, int(is_signed))
+ ret = native_bt.ctf_field_type_integer_set_is_signed(self._ptr, int(is_signed))
utils._handle_ret(ret, "cannot set integer field type object's signedness")
@property
def base(self):
base = native_bt.ctf_field_type_integer_get_base(self._ptr)
- utils._handle_ret(base, "cannot get integer field type object's base")
+ assert(base >= 0)
return base
@base.setter
@property
def encoding(self):
encoding = native_bt.ctf_field_type_integer_get_encoding(self._ptr)
- utils._handle_ret(encoding, "cannot get integer field type object's encoding")
+ assert(encoding >= 0)
return encoding
@encoding.setter
@property
def mapped_clock_class(self):
ptr = native_bt.ctf_field_type_integer_get_mapped_clock_class(self._ptr)
- utils._handle_ptr(ptr, "cannot get integer field type object's mapped clock class")
+
+ if ptr is None:
+ return
+
return bt2.ClockClass._create_from_ptr(ptr)
@mapped_clock_class.setter
@property
def exponent_size(self):
exp_size = native_bt.ctf_field_type_floating_point_get_exponent_digits(self._ptr)
- utils._handle_ret(exp_size, "cannot get floating point number field type object's exponent size")
+ assert(exp_size >= 0)
return exp_size
@exponent_size.setter
@property
def mantissa_size(self):
- exp_size = native_bt.ctf_field_type_floating_point_get_mantissa_digits(self._ptr)
- utils._handle_ret(exp_size, "cannot get floating point number field type object's mantissa size")
- return exp_size
+ mant_size = native_bt.ctf_field_type_floating_point_get_mantissa_digits(self._ptr)
+ assert(mant_size >= 0)
+ return mant_size
@mantissa_size.setter
def mantissa_size(self, mantissa_size):
else:
ret, name, lower, upper = native_bt.ctf_field_type_enumeration_mapping_iterator_get_unsigned(self._ptr)
- utils._handle_ret(ret, "cannot get enumeration field type mapping iterator object's current mapping")
+ assert(ret == 0)
mapping = _EnumerationFieldTypeMapping(name, lower, upper)
ret = native_bt.ctf_field_type_enumeration_mapping_iterator_next(self._ptr)
@property
def integer_field_type(self):
ptr = native_bt.ctf_field_type_enumeration_get_container_type(self._ptr)
- utils._handle_ptr(ptr, "cannot get enumeration field type object's integer field type")
+ assert(ptr)
return _create_from_ptr(ptr)
@property
def __len__(self):
count = native_bt.ctf_field_type_enumeration_get_mapping_count(self._ptr)
- utils._handle_ret(count, "cannot get enumeration field type object's mapping count")
+ assert(count >= 0)
return count
def __getitem__(self, index):
get_fn = native_bt.ctf_field_type_enumeration_get_mapping_unsigned
ret, name, lower, upper = get_fn(self._ptr, index)
- utils._handle_ret(ret, "cannot get enumeration field type object's mapping")
+ assert(ret == 0)
return _EnumerationFieldTypeMapping(name, lower, upper)
def _get_mapping_iter(self, iter_ptr):
upper = lower
if self.is_signed:
- add_fn = native_bt.ctf_field_type_enumeration_add_mapping
+ add_fn = native_bt.ctf_field_type_enumeration_add_mapping_signed
utils._check_int64(lower)
utils._check_int64(upper)
else:
@property
def encoding(self):
encoding = native_bt.ctf_field_type_string_get_encoding(self._ptr)
- utils._handle_ret(encoding, "cannot get string field type object's encoding")
+ assert(encoding >= 0)
return encoding
@encoding.setter
class _FieldContainer(collections.abc.Mapping):
def __len__(self):
count = self._count()
- utils._handle_ret(count, "cannot get {} field type object's field count".format(self._NAME.lower()))
+ assert(count >= 0)
return count
def __getitem__(self, key):
if self._at == len(self._struct_field_type):
raise StopIteration
- ret, name, field_type_ptr = native_bt.ctf_field_type_structure_get_field(self._struct_field_type._ptr, self._at)
- utils._handle_ret(ret, "cannot get structure field type object's field")
+ get_ft_by_index = native_bt.ctf_field_type_structure_get_field_by_index
+ ret, name, field_type_ptr = get_ft_by_index(self._struct_field_type._ptr,
+ self._at)
+ assert(ret == 0)
native_bt.put(field_type_ptr)
self._at += 1
return name
name)
def _at(self, index):
- ret, name, field_type_ptr = native_bt.ctf_field_type_structure_get_field(self._ptr, index)
- utils._handle_ret(ret, "cannot get structure field type object's field")
+ if index < 0 or index >= len(self):
+ raise IndexError
+
+ ret, name, field_type_ptr = native_bt.ctf_field_type_structure_get_field_by_index(self._ptr, index)
+ assert(ret == 0)
return _create_from_ptr(field_type_ptr)
if self._at == len(self._variant_field_type):
raise StopIteration
- ret, name, field_type_ptr = native_bt.ctf_field_type_variant_get_field(self._variant_field_type._ptr, self._at)
- utils._handle_ret(ret, "cannot get variant field type object's field")
+ ret, name, field_type_ptr = native_bt.ctf_field_type_variant_get_field_by_index(self._variant_field_type._ptr,
+ self._at)
+ assert(ret == 0)
native_bt.put(field_type_ptr)
self._at += 1
return name
_NAME = 'Variant'
_ITER_CLS = _VariantFieldTypeFieldIterator
- def __init__(self, tag_name):
+ def __init__(self, tag_name, tag_field_type=None):
utils._check_str(tag_name)
- ptr = native_bt.ctf_field_type_variant_create(None, tag_name)
+
+ if tag_field_type is None:
+ tag_ft_ptr = None
+ else:
+ utils._check_type(tag_field_type, EnumerationFieldType)
+ tag_ft_ptr = tag_field_type._ptr
+
+ ptr = native_bt.ctf_field_type_variant_create(tag_ft_ptr,
+ tag_name)
self._check_create_status(ptr)
super().__init__(ptr)
@property
def tag_name(self):
tag_name = native_bt.ctf_field_type_variant_get_tag_name(self._ptr)
- utils._handle_ptr(tag_name, "cannot get variant field type object's tag name")
+ assert(tag_name is not None)
return tag_name
@tag_name.setter
ret = native_bt.ctf_field_type_variant_set_tag_name(self._ptr, tag_name)
utils._handle_ret(ret, "cannot set variant field type object's tag name")
+ @property
+ def tag_field_type(self):
+ ft_ptr = native_bt.ctf_field_type_variant_get_tag_type(self._ptr)
+
+ if ft_ptr is None:
+ return
+
+ return _create_from_ptr(ft_ptr)
+
def _count(self):
return native_bt.ctf_field_type_variant_get_field_count(self._ptr)
return native_bt.ctf_field_type_variant_add_field(self._ptr, ptr, name)
def _at(self, index):
- ret, name, field_type_ptr = native_bt.ctf_field_type_variant_get_field(self._ptr, index)
- utils._handle_ret(ret, "cannot get variant field type object's field")
+ if index < 0 or index >= len(self):
+ raise IndexError
+
+ ret, name, field_type_ptr = native_bt.ctf_field_type_variant_get_field_by_index(self._ptr, index)
+ assert(ret == 0)
return _create_from_ptr(field_type_ptr)
@property
def length(self):
length = native_bt.ctf_field_type_array_get_length(self._ptr)
- utils._handle_ret(length, "cannot get array field type object's length")
+ assert(length >= 0)
return length
@property
def element_field_type(self):
ptr = native_bt.ctf_field_type_array_get_element_type(self._ptr)
- utils._handle_ptr(ptr, "cannot get array field type object's element field type")
+ assert(ptr)
return _create_from_ptr(ptr)
@property
def length_name(self):
length_name = native_bt.ctf_field_type_sequence_get_length_field_name(self._ptr)
- utils._handle_ptr(length_name, "cannot get sequence field type object's length name")
+ assert(length_name is not None)
return length_name
@property
def element_field_type(self):
ptr = native_bt.ctf_field_type_sequence_get_element_type(self._ptr)
- utils._handle_ptr(ptr, "cannot get sequence field type object's element field type")
+ assert(ptr)
return _create_from_ptr(ptr)
_TYPE_ID_TO_OBJ = {
- native_bt.CTF_TYPE_ID_INTEGER: IntegerFieldType,
- native_bt.CTF_TYPE_ID_FLOAT: FloatingPointNumberFieldType,
- native_bt.CTF_TYPE_ID_ENUM: EnumerationFieldType,
- native_bt.CTF_TYPE_ID_STRING: StringFieldType,
- native_bt.CTF_TYPE_ID_STRUCT: StructureFieldType,
- native_bt.CTF_TYPE_ID_ARRAY: ArrayFieldType,
- native_bt.CTF_TYPE_ID_SEQUENCE: SequenceFieldType,
- native_bt.CTF_TYPE_ID_VARIANT: VariantFieldType,
- native_bt.CTF_TYPE_ID_UNTAGGED_VARIANT: VariantFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_INTEGER: IntegerFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_FLOAT: FloatingPointNumberFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_ENUM: EnumerationFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_STRING: StringFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_STRUCT: StructureFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_ARRAY: ArrayFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_SEQUENCE: SequenceFieldType,
+ native_bt.CTF_FIELD_TYPE_ID_VARIANT: VariantFieldType,
}
# The MIT License (MIT)
#
-# Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
else:
ret, value = native_bt.ctf_field_unsigned_integer_get_value(self._ptr)
- utils._handle_ret(ret, "cannot get integer field object's value")
+ if ret < 0:
+ # field is not set
+ return
+
return value
@value.setter
@property
def value(self):
ret, value = native_bt.ctf_field_floating_point_get_value(self._ptr)
- utils._handle_ret(ret, "cannot get floating point number field object's value")
+
+ if ret < 0:
+ # field is not set
+ return
+
return value
@value.setter
@property
def integer_field(self):
int_field_ptr = native_bt.ctf_field_enumeration_get_container(self._ptr)
- utils._handle_ptr(int_field_ptr,
- "cannot get enumeration field object's underlying integer field")
+ assert(int_field_ptr)
return _create_from_ptr(int_field_ptr)
@property
@property
def mappings(self):
- iter_ptr = bt_ctf_field_enumeration_get_mappings(self._ptr)
- return self.field_type._get_mapping_iter(iter_ptr)
+ iter_ptr = native_bt.ctf_field_enumeration_get_mappings(self._ptr)
+ assert(iter_ptr)
+ return bt2.field_types._EnumerationFieldTypeMappingIterator(iter_ptr,
+ self.field_type.is_signed)
@functools.total_ordering
@property
def value(self):
value = native_bt.ctf_field_string_get_value(self._ptr)
- utils._handle_ptr(value, "cannot get string field object's value")
+
+ if value is None:
+ # field is not set
+ return
+
return value
@value.setter
def __len__(self):
count = self._count()
- utils._handle_ret(count, "cannot get {} field object's field count".format(self._NAME.lower()))
+ assert(count >= 0)
return count
def __delitem__(self, index):
def __getitem__(self, key):
utils._check_str(key)
- ptr = native_bt.ctf_field_structure_get_field(self._ptr, key)
+ ptr = native_bt.ctf_field_structure_get_field_by_name(self._ptr, key)
if ptr is None:
raise KeyError(key)
def at_index(self, index):
utils._check_uint64(index)
+
+ if index >= len(self):
+ raise IndexError
+
field_ptr = native_bt.ctf_field_structure_get_field_by_index(self._ptr, index)
- utils._handle_ptr(field_ptr, "cannot get structure field object's field")
+ assert(field_ptr)
return _create_from_ptr(field_ptr)
def __iter__(self):
@property
def tag_field(self):
field_ptr = native_bt.ctf_field_variant_get_tag(self._ptr)
- utils._handle_ptr(field_ptr, "cannot get variant field object's tag field")
+
+ if field_ptr is None:
+ return
+
return _create_from_ptr(field_ptr)
@property
def field(self, tag_field=None):
if tag_field is None:
field_ptr = native_bt.ctf_field_variant_get_current_field(self._ptr)
- utils._handle_ptr(field_ptr, "cannot get variant field object's selected field")
+
+ if field_ptr is None:
+ return
else:
utils._check_type(tag_field, _EnumerationField)
field_ptr = native_bt.ctf_field_variant_get_field(self._ptr, tag_field._ptr)
return _create_from_ptr(field_ptr)
def __eq__(self, other):
- return self.field == other
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ return self.selected_field == other.selected_field
+
+ def __bool__(self):
+ return bool(self.selected_field)
class _ArraySequenceField(_ContainerField, collections.abc.MutableSequence):
raise IndexError('{} field object index is out of range'.format(self._NAME))
field_ptr = self._get_field_ptr_at_index(index)
- utils._handle_ptr(field_ptr, "cannot get {} field object's field".format(self._NAME))
+ assert(field_ptr)
return _create_from_ptr(field_ptr)
def __setitem__(self, index, value):
_TYPE_ID_TO_OBJ = {
- native_bt.CTF_TYPE_ID_INTEGER: _IntegerField,
- native_bt.CTF_TYPE_ID_FLOAT: _FloatingPointNumberField,
- native_bt.CTF_TYPE_ID_ENUM: _EnumerationField,
- native_bt.CTF_TYPE_ID_STRING: _StringField,
- native_bt.CTF_TYPE_ID_STRUCT: _StructureField,
- native_bt.CTF_TYPE_ID_ARRAY: _ArrayField,
- native_bt.CTF_TYPE_ID_SEQUENCE: _SequenceField,
- native_bt.CTF_TYPE_ID_VARIANT: _VariantField,
- native_bt.CTF_TYPE_ID_UNTAGGED_VARIANT: _VariantField,
+ native_bt.CTF_FIELD_TYPE_ID_INTEGER: _IntegerField,
+ native_bt.CTF_FIELD_TYPE_ID_FLOAT: _FloatingPointNumberField,
+ native_bt.CTF_FIELD_TYPE_ID_ENUM: _EnumerationField,
+ native_bt.CTF_FIELD_TYPE_ID_STRING: _StringField,
+ native_bt.CTF_FIELD_TYPE_ID_STRUCT: _StructureField,
+ native_bt.CTF_FIELD_TYPE_ID_ARRAY: _ArrayField,
+ native_bt.CTF_FIELD_TYPE_ID_SEQUENCE: _SequenceField,
+ native_bt.CTF_FIELD_TYPE_ID_VARIANT: _VariantField,
}
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2.connection
+import bt2.component
+import functools
+import bt2.port
+import bt2
+
+
+class GraphListenerType:
+ PORT_ADDED = 0
+ PORT_REMOVED = 1
+ PORTS_CONNECTED = 2
+ PORTS_DISCONNECTED = 3
+
+
+def _graph_port_added_listener_from_native(user_listener, port_ptr):
+ try:
+ port = bt2.port._create_from_ptr(port_ptr)
+ port._get()
+ user_listener(port)
+ except:
+ pass
+
+
+def _graph_port_removed_listener_from_native(user_listener, port_ptr):
+ try:
+ port = bt2.port._create_from_ptr(port_ptr)
+ port._get()
+ user_listener(port)
+ except:
+ pass
+
+
+def _graph_ports_connected_listener_from_native(user_listener,
+ upstream_port_ptr,
+ downstream_port_ptr):
+ try:
+ upstream_port = bt2.port._create_from_ptr(upstream_port_ptr)
+ upstream_port._get()
+ downstream_port = bt2.port._create_from_ptr(downstream_port_ptr)
+ downstream_port._get()
+ user_listener(upstream_port, downstream_port)
+ except:
+ pass
+
+
+def _graph_ports_disconnected_listener_from_native(user_listener,
+ upstream_comp_ptr,
+ downstream_comp_ptr,
+ upstream_port_ptr,
+ downstream_port_ptr):
+ try:
+ upstream_comp = bt2.component._create_generic_component_from_ptr(upstream_comp_ptr)
+ upstream_comp._get()
+ downstream_comp = bt2.component._create_generic_component_from_ptr(downstream_comp_ptr)
+ downstream_comp._get()
+ upstream_port = bt2.port._create_from_ptr(upstream_port_ptr)
+ upstream_port._get()
+ downstream_port = bt2.port._create_from_ptr(downstream_port_ptr)
+ downstream_port._get()
+ user_listener(upstream_comp, downstream_comp, upstream_port,
+ downstream_port)
+ except:
+ pass
+
+
+class Graph(object._Object):
+ def __init__(self):
+ ptr = native_bt.graph_create()
+
+ if ptr is None:
+ raise bt2.CreationError('cannot create graph object')
+
+ super().__init__(ptr)
+
+ def _handle_status(self, status, gen_error_msg):
+ if status == native_bt.GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION:
+ raise bt2.PortConnectionRefused
+ elif status == native_bt.GRAPH_STATUS_CANCELED:
+ raise bt2.GraphCanceled
+ elif status == native_bt.GRAPH_STATUS_END:
+ raise bt2.Stop
+ elif status == native_bt.GRAPH_STATUS_AGAIN:
+ raise bt2.TryAgain
+ elif status == native_bt.GRAPH_STATUS_NO_SINK:
+ raise bt2.NoSinkComponent
+ elif status < 0:
+ raise bt2.Error(gen_error_msg)
+
+ def add_component(self, component_class, name, params=None):
+ if isinstance(component_class, bt2.component._GenericComponentClass):
+ cc_ptr = component_class._ptr
+ elif issubclass(component_class, bt2.component._UserComponent):
+ cc_ptr = component_class._cc_ptr
+ else:
+ raise TypeError("'{}' is not a component class".format(component_class.__class__.__name__))
+
+ utils._check_str(name)
+ params = bt2.create_value(params)
+
+ if params is None:
+ params_ptr = None
+ else:
+ params_ptr = params._ptr
+
+ status, comp_ptr = native_bt.graph_add_component(self._ptr, cc_ptr,
+ name, params_ptr)
+ self._handle_status(status, 'cannot add component to graph')
+ assert(comp_ptr)
+ return bt2.component._create_generic_component_from_ptr(comp_ptr)
+
+ def connect_ports(self, upstream_port, downstream_port):
+ utils._check_type(upstream_port, bt2.port._OutputPort)
+ utils._check_type(downstream_port, bt2.port._InputPort)
+ status, conn_ptr = native_bt.graph_connect_ports(self._ptr,
+ upstream_port._ptr,
+ downstream_port._ptr)
+ self._handle_status(status, 'cannot connect component ports within graph')
+ assert(conn_ptr)
+ return bt2.connection._Connection._create_from_ptr(conn_ptr)
+
+ def add_listener(self, listener_type, listener):
+ if not hasattr(listener, '__call__'):
+ raise TypeError("'listener' parameter is not callable")
+
+ if listener_type == GraphListenerType.PORT_ADDED:
+ fn = native_bt.py3_graph_add_port_added_listener
+ listener_from_native = functools.partial(_graph_port_added_listener_from_native,
+ listener)
+ elif listener_type == GraphListenerType.PORT_REMOVED:
+ fn = native_bt.py3_graph_add_port_removed_listener
+ listener_from_native = functools.partial(_graph_port_removed_listener_from_native,
+ listener)
+ elif listener_type == GraphListenerType.PORTS_CONNECTED:
+ fn = native_bt.py3_graph_add_ports_connected_listener
+ listener_from_native = functools.partial(_graph_ports_connected_listener_from_native,
+ listener)
+ elif listener_type == GraphListenerType.PORTS_DISCONNECTED:
+ fn = native_bt.py3_graph_add_ports_disconnected_listener
+ listener_from_native = functools.partial(_graph_ports_disconnected_listener_from_native,
+ listener)
+ else:
+ raise TypeError
+
+ listener_id = fn(self._ptr, listener_from_native)
+ utils._handle_ret(listener_id, 'cannot add listener to graph object')
+ return bt2._ListenerHandle(listener_id, self)
+
+ def run(self):
+ status = native_bt.graph_run(self._ptr)
+
+ if status == native_bt.GRAPH_STATUS_END:
+ return
+
+ self._handle_status(status, 'graph object stopped running because of an unexpected error')
+
+ def cancel(self):
+ status = native_bt.graph_cancel(self._ptr)
+ self._handle_status(status, 'cannot cancel graph object')
+
+ @property
+ def is_canceled(self):
+ is_canceled = native_bt.graph_is_canceled(self._ptr)
+ assert(is_canceled >= 0)
+ return is_canceled > 0
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ return self.addr == other.addr
--- /dev/null
+/*
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_OUTPUT_LEVEL bt_cli_log_level
+#include <babeltrace/logging-internal.h>
+
+BT_LOG_INIT_LOG_LEVEL(bt_cli_log_level, "BABELTRACE_CLI_LOG_LEVEL");
--- /dev/null
+#ifndef CLI_LOGGING_H
+#define CLI_LOGGING_H
+
+/*
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#define BT_LOG_OUTPUT_LEVEL bt_cli_log_level
+#include <babeltrace/logging-internal.h>
+
+BT_LOG_LEVEL_EXTERN_SYMBOL(bt_cli_log_level);
+
+#endif /* CLI_LOGGING_H */
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import bt2
+
+
+class LoggingLevel:
+ VERBOSE = native_bt.LOGGING_LEVEL_VERBOSE
+ DEBUG = native_bt.LOGGING_LEVEL_DEBUG
+ INFO = native_bt.LOGGING_LEVEL_INFO
+ WARN = native_bt.LOGGING_LEVEL_WARN
+ ERROR = native_bt.LOGGING_LEVEL_ERROR
+ FATAL = native_bt.LOGGING_LEVEL_FATAL
+ NONE = native_bt.LOGGING_LEVEL_NONE
+
+
+def get_minimal_logging_level():
+ return native_bt.logging_get_minimal_level()
+
+
+def get_global_logging_level():
+ return native_bt.logging_get_global_level()
+
+
+def set_global_logging_level(level):
+ levels = (
+ LoggingLevel.VERBOSE,
+ LoggingLevel.DEBUG,
+ LoggingLevel.INFO,
+ LoggingLevel.WARN,
+ LoggingLevel.ERROR,
+ LoggingLevel.FATAL,
+ LoggingLevel.NONE,
+ )
+
+ if level not in levels:
+ raise TypeError("'{}' is not a valid logging level".format(level))
+
+ return native_bt.logging_set_global_level(level)
* THE SOFTWARE.
*/
+#ifndef SWIGPYTHON
+# error Unsupported output language
+#endif
+
%{
+#define BT_LOG_TAG "PY-NATIVE"
+#include "logging.h"
+
+#include <babeltrace/babeltrace.h>
+
typedef const unsigned char *BTUUID;
%}
-#ifndef SWIGPYTHON
-# error Unsupported output language
-#endif
+typedef int bt_bool;
/* For uint*_t/int*_t */
%include "stdint.i"
}
}
+/* Output argument typemap for component output (always appends) */
+%typemap(in, numinputs=0) struct bt_component **BTOUTCOMP (struct bt_component *temp_comp = NULL) {
+ $1 = &temp_comp;
+}
+
+%typemap(argout) struct bt_component **BTOUTCOMP {
+ if (*$1) {
+ /* SWIG_Python_AppendOutput() steals the created object */
+ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_bt_component, 0));
+ } else {
+ /* SWIG_Python_AppendOutput() steals Py_None */
+ Py_INCREF(Py_None);
+ $result = SWIG_Python_AppendOutput($result, Py_None);
+ }
+}
+
+/* Output argument typemap for connection output (always appends) */
+%typemap(in, numinputs=0) struct bt_connection **BTOUTCONN (struct bt_connection *temp_conn = NULL) {
+ $1 = &temp_conn;
+}
+
+%typemap(argout) struct bt_connection **BTOUTCONN {
+ if (*$1) {
+ /* SWIG_Python_AppendOutput() steals the created object */
+ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_bt_connection, 0));
+ } else {
+ /* SWIG_Python_AppendOutput() steals Py_None */
+ Py_INCREF(Py_None);
+ $result = SWIG_Python_AppendOutput($result, Py_None);
+ }
+}
+
+/* Output argument typemap for private port output (always appends) */
+%typemap(in, numinputs=0) struct bt_private_port **BTOUTPRIVPORT (struct bt_private_port *temp_priv_port = NULL) {
+ $1 = &temp_priv_port;
+}
+
+%typemap(argout) struct bt_private_port **BTOUTPRIVPORT {
+ if (*$1) {
+ /* SWIG_Python_AppendOutput() steals the created object */
+ $result = SWIG_Python_AppendOutput($result, SWIG_NewPointerObj(SWIG_as_voidptr(*$1), SWIGTYPE_p_bt_private_port, 0));
+ } else {
+ /* SWIG_Python_AppendOutput() steals Py_None */
+ Py_INCREF(Py_None);
+ $result = SWIG_Python_AppendOutput($result, Py_None);
+ }
+}
+
+/* Output argument typemap for initialized uint64_t output parameter (always appends) */
+%typemap(in, numinputs=0) uint64_t *OUTPUTINIT (uint64_t temp = -1ULL) {
+ $1 = &temp;
+}
+
+%typemap(argout) uint64_t *OUTPUTINIT {
+ $result = SWIG_Python_AppendOutput(resultobj, SWIG_From_unsigned_SS_long_SS_long((*$1)));
+}
+
+/* Output argument typemap for initialized unsigned int output parameter (always appends) */
+%typemap(in, numinputs=0) unsigned int *OUTPUTINIT (unsigned int temp = -1) {
+ $1 = &temp;
+}
+
+%typemap(argout) unsigned int *OUTPUTINIT {
+ $result = SWIG_Python_AppendOutput(resultobj, SWIG_From_unsigned_SS_long_SS_long((uint64_t) (*$1)));
+}
+
/* Input argument typemap for UUID bytes */
%typemap(in) BTUUID {
$1 = (unsigned char *) PyBytes_AsString($input);
}
/* Per-module interface files */
+%include "native_btccpriomap.i"
%include "native_btclockclass.i"
+%include "native_btcomponent.i"
+%include "native_btcomponentclass.i"
+%include "native_btconnection.i"
+%include "native_btctfwriter.i"
%include "native_btevent.i"
%include "native_bteventclass.i"
%include "native_btfields.i"
%include "native_btft.i"
+%include "native_btgraph.i"
+%include "native_btlogging.i"
+%include "native_btnotification.i"
+%include "native_btnotifiter.i"
%include "native_btpacket.i"
+%include "native_btplugin.i"
+%include "native_btport.i"
%include "native_btref.i"
%include "native_btstream.i"
%include "native_btstreamclass.i"
%include "native_bttrace.i"
%include "native_btvalues.i"
-%include "native_btctfwriter.i"
-%include "native_btcomponentclass.i"
-%include "native_btcomponent.i"
-%include "native_btnotifiter.i"
-%include "native_btnotification.i"
-%include "native_btplugin.i"
+%include "native_btversion.i"
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+%{
+#include <babeltrace/graph/clock-class-priority-map.h>
+%}
+
+/* Type */
+struct bt_clock_class_priority_map;
+
+/* Functions */
+struct bt_clock_class_priority_map *bt_clock_class_priority_map_create();
+int64_t bt_clock_class_priority_map_get_clock_class_count(
+ struct bt_clock_class_priority_map *clock_class_priority_map);
+struct bt_ctf_clock_class *
+bt_clock_class_priority_map_get_clock_class_by_index(
+ struct bt_clock_class_priority_map *clock_class_priority_map,
+ uint64_t index);
+struct bt_ctf_clock_class *
+bt_clock_class_priority_map_get_clock_class_by_name(
+ struct bt_clock_class_priority_map *clock_class_priority_map,
+ const char *name);
+struct bt_ctf_clock_class *
+bt_clock_class_priority_map_get_highest_priority_clock_class(
+ struct bt_clock_class_priority_map *clock_class_priority_map);
+int bt_clock_class_priority_map_get_clock_class_priority(
+ struct bt_clock_class_priority_map *clock_class_priority_map,
+ struct bt_ctf_clock_class *clock_class, uint64_t *OUTPUTINIT);
+int bt_clock_class_priority_map_add_clock_class(
+ struct bt_clock_class_priority_map *clock_class_priority_map,
+ struct bt_ctf_clock_class *clock_class, uint64_t priority);
+struct bt_clock_class_priority_map *bt_clock_class_priority_map_copy(
+ struct bt_clock_class_priority_map *clock_class_priority_map);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/ctf-ir/clock-class.h>
-%}
-
/* Types */
struct bt_ctf_clock_class;
struct bt_ctf_clock_value;
/* Clock class functions */
-struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name);
+struct bt_ctf_clock_class *bt_ctf_clock_class_create(const char *name,
+ uint64_t freq);
const char *bt_ctf_clock_class_get_name(struct bt_ctf_clock_class *clock_class);
int bt_ctf_clock_class_set_name(struct bt_ctf_clock_class *clock_class, const char *name);
const char *bt_ctf_clock_class_get_description(struct bt_ctf_clock_class *clock_class);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/component/component.h>
-#include <babeltrace/component/component-source.h>
-#include <babeltrace/component/component-sink.h>
-#include <babeltrace/component/component-filter.h>
-%}
-
/* Types */
struct bt_component;
/* Status */
enum bt_component_status {
- BT_COMPONENT_STATUS_OK = 0,
- BT_COMPONENT_STATUS_END = 1,
- BT_COMPONENT_STATUS_AGAIN = 2,
- BT_COMPONENT_STATUS_ERROR = -1,
- BT_COMPONENT_STATUS_UNSUPPORTED = -2,
- BT_COMPONENT_STATUS_INVALID = -3,
- BT_COMPONENT_STATUS_NOMEM = -4,
+ BT_COMPONENT_STATUS_OK = 0,
+ BT_COMPONENT_STATUS_END = 1,
+ BT_COMPONENT_STATUS_AGAIN = 11,
+ BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION = 111,
+ BT_COMPONENT_STATUS_ERROR = -1,
+ BT_COMPONENT_STATUS_UNSUPPORTED = -2,
+ BT_COMPONENT_STATUS_INVALID = -22,
+ BT_COMPONENT_STATUS_NOMEM = -12,
+ BT_COMPONENT_STATUS_NOT_FOUND = -19,
+ BT_COMPONENT_STATUS_GRAPH_IS_CANCELED = 125,
};
/* General functions */
-struct bt_component *bt_component_create_with_init_method_data(
- struct bt_component_class *component_class, const char *name,
- struct bt_value *params, void *init_method_data);
const char *bt_component_get_name(struct bt_component *component);
struct bt_component_class *bt_component_get_class(
struct bt_component *component);
enum bt_component_class_type bt_component_get_class_type(
struct bt_component *component);
+struct bt_graph *bt_component_get_graph(struct bt_component *component);
+struct bt_component *bt_component_from_private_component(
+ struct bt_private_component *private_component);
/* Source component functions */
-struct bt_notification_iterator *bt_component_source_create_notification_iterator_with_init_method_data(
- struct bt_component *component, void *init_method_data);
-
-/* Filter component functions */
-%{
-static struct bt_notification_iterator *bt_component_filter_get_input_iterator_private(
- struct bt_component *filter, unsigned int index)
-{
- struct bt_notification_iterator *iterator = NULL;
+int64_t bt_component_source_get_output_port_count(
+ struct bt_component *component);
+struct bt_port *bt_component_source_get_output_port_by_name(
+ struct bt_component *component, const char *name);
+struct bt_port *bt_component_source_get_output_port_by_index(
+ struct bt_component *component, uint64_t index);
- if (bt_component_filter_get_input_iterator(filter, index, &iterator)) {
- iterator = NULL;
- goto end;
- }
+/* Private source component functions */
+struct bt_private_port *
+bt_private_component_source_get_output_private_port_by_name(
+ struct bt_private_component *private_component,
+ const char *name);
+struct bt_private_port *
+bt_private_component_source_get_output_private_port_by_index(
+ struct bt_private_component *private_component,
+ uint64_t index);
+enum bt_component_status
+bt_private_component_source_add_output_private_port(
+ struct bt_private_component *private_component,
+ const char *name, void *user_data,
+ struct bt_private_port **BTOUTPRIVPORT);
-end:
- return iterator;
-}
-%}
+/* Filter component functions */
+int64_t bt_component_filter_get_input_port_count(
+ struct bt_component *component);
+struct bt_port *bt_component_filter_get_input_port_by_name(
+ struct bt_component *component, const char *name);
+struct bt_port *bt_component_filter_get_input_port_by_index(
+ struct bt_component *component, uint64_t index);
+int64_t bt_component_filter_get_output_port_count(
+ struct bt_component *component);
+struct bt_port *bt_component_filter_get_output_port_by_name(
+ struct bt_component *component, const char *name);
+struct bt_port *bt_component_filter_get_output_port_by_index(
+ struct bt_component *component, uint64_t index);
-struct bt_notification_iterator *bt_component_filter_create_notification_iterator_with_init_method_data(
- struct bt_component *component, void *init_method_data);
-enum bt_component_status bt_component_filter_add_iterator(
- struct bt_component *component,
- struct bt_notification_iterator *iterator);
-enum bt_component_status bt_component_filter_set_minimum_input_count(
- struct bt_component *filter, unsigned int minimum);
-enum bt_component_status bt_component_filter_set_maximum_input_count(
- struct bt_component *filter, unsigned int maximum);
-enum bt_component_status bt_component_filter_get_input_count(
- struct bt_component *filter, unsigned int *OUTPUT);
-struct bt_notification_iterator *bt_component_filter_get_input_iterator_private(
- struct bt_component *filter, unsigned int index);
+/* Private filter component functions */
+struct bt_private_port *
+bt_private_component_filter_get_output_private_port_by_name(
+ struct bt_private_component *private_component,
+ const char *name);
+struct bt_private_port *
+bt_private_component_filter_get_output_private_port_by_index(
+ struct bt_private_component *private_component, uint64_t index);
+enum bt_component_status
+bt_private_component_filter_add_output_private_port(
+ struct bt_private_component *private_component,
+ const char *name, void *user_data,
+ struct bt_private_port **BTOUTPRIVPORT);
+struct bt_private_port *
+bt_private_component_filter_get_input_private_port_by_name(
+ struct bt_private_component *private_component,
+ const char *name);
+struct bt_private_port *
+bt_private_component_filter_get_input_private_port_by_index(
+ struct bt_private_component *private_component, uint64_t index);
+enum bt_component_status
+bt_private_component_filter_add_input_private_port(
+ struct bt_private_component *private_component,
+ const char *name, void *user_data,
+ struct bt_private_port **BTOUTPRIVPORT);
/* Sink component functions */
-%{
-static struct bt_notification_iterator *bt_component_sink_get_input_iterator_private(
- struct bt_component *sink, unsigned int index)
-{
- struct bt_notification_iterator *iterator = NULL;
-
- if (bt_component_sink_get_input_iterator(sink, index, &iterator)) {
- iterator = NULL;
- goto end;
- }
-
-end:
- return iterator;
-}
-%}
-
-enum bt_component_status bt_component_sink_add_iterator(
- struct bt_component *component,
- struct bt_notification_iterator *iterator);
-enum bt_component_status bt_component_sink_consume(
+int64_t bt_component_sink_get_input_port_count(
struct bt_component *component);
-enum bt_component_status bt_component_sink_set_minimum_input_count(
- struct bt_component *sink, unsigned int minimum);
-enum bt_component_status bt_component_sink_set_maximum_input_count(
- struct bt_component *sink, unsigned int maximum);
-enum bt_component_status bt_component_sink_get_input_count(
- struct bt_component *sink, unsigned int *OUTPUT);
-struct bt_notification_iterator *bt_component_sink_get_input_iterator_private(
- struct bt_component *sink, unsigned int index);
+struct bt_port *bt_component_sink_get_input_port_by_name(
+ struct bt_component *component, const char *name);
+struct bt_port *bt_component_sink_get_input_port_by_index(
+ struct bt_component *component, uint64_t index);
+
+/* Private sink component functions */
+struct bt_private_port *
+bt_private_component_sink_get_input_private_port_by_name(
+ struct bt_private_component *private_component,
+ const char *name);
+struct bt_private_port *
+bt_private_component_sink_get_input_private_port_by_index(
+ struct bt_private_component *private_component, uint64_t index);
+enum bt_component_status
+bt_private_component_sink_add_input_private_port(
+ struct bt_private_component *private_component,
+ const char *name, void *user_data,
+ struct bt_private_port **BTOUTPRIVPORT);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/component/component-class.h>
-#include <babeltrace/component/component-class-source.h>
-#include <babeltrace/component/component-class-sink.h>
-#include <babeltrace/component/component-class-filter.h>
-#include <babeltrace/component/notification/iterator.h>
-#include <babeltrace/component/notification/notification.h>
-#include <assert.h>
-#include <glib.h>
-%}
-
/* Types */
struct bt_component_class;
/* Status */
enum bt_component_class_type {
- BT_COMPONENT_CLASS_TYPE_UNKNOWN = -1,
- BT_COMPONENT_CLASS_TYPE_SOURCE = 0,
- BT_COMPONENT_CLASS_TYPE_SINK = 1,
- BT_COMPONENT_CLASS_TYPE_FILTER = 2,
+ BT_COMPONENT_CLASS_TYPE_UNKNOWN = -1,
+ BT_COMPONENT_CLASS_TYPE_SOURCE = 0,
+ BT_COMPONENT_CLASS_TYPE_SINK = 1,
+ BT_COMPONENT_CLASS_TYPE_FILTER = 2,
};
/* General functions */
struct bt_component_class *component_class);
struct bt_value *bt_component_class_query(
struct bt_component_class *component_class,
- const char *action, struct bt_value *params);
+ const char *object, struct bt_value *params);
enum bt_component_class_type bt_component_class_get_type(
struct bt_component_class *component_class);
static void register_cc_ptr_to_py_cls(struct bt_component_class *bt_cc,
PyObject *py_cls)
{
+ if (!bt_cc_ptr_to_py_cls) {
+ /*
+ * Lazy-initializing this GHashTable because GLib
+ * might not be initialized yet and it needs to be
+ * before we call g_hash_table_new()
+ */
+ BT_LOGD_STR("Creating native component class to Python component class hash table.");
+ bt_cc_ptr_to_py_cls = g_hash_table_new(g_direct_hash, g_direct_equal);
+ assert(bt_cc_ptr_to_py_cls);
+ }
+
g_hash_table_insert(bt_cc_ptr_to_py_cls, (gpointer) bt_cc,
(gpointer) py_cls);
}
static PyObject *lookup_cc_ptr_to_py_cls(struct bt_component_class *bt_cc)
{
+ if (!bt_cc_ptr_to_py_cls) {
+ BT_LOGW("Cannot look up Python component class because hash table is NULL: "
+ "comp-cls-addr=%p", bt_cc);
+ return NULL;
+ }
+
return (PyObject *) g_hash_table_lookup(bt_cc_ptr_to_py_cls,
(gconstpointer) bt_cc);
}
static PyObject *py_mod_bt2_exc_unsupported_feature_type = NULL;
static PyObject *py_mod_bt2_exc_try_again_type = NULL;
static PyObject *py_mod_bt2_exc_stop_type = NULL;
-static PyObject *py_mod_bt2_values = NULL;
-static PyObject *py_mod_bt2_values_create_from_ptr_func = NULL;
+static PyObject *py_mod_bt2_exc_port_connection_refused_type = NULL;
+static PyObject *py_mod_bt2_exc_graph_canceled_type = NULL;
+static PyObject *py_mod_bt2_exc_notif_iter_canceled_type = NULL;
+static PyObject *py_mod_bt2_exc_connection_ended_type = NULL;
static void bt_py3_cc_init_from_bt2(void)
{
*/
py_mod_bt2 = PyImport_ImportModule("bt2");
assert(py_mod_bt2);
- py_mod_bt2_values = PyImport_ImportModule("bt2.values");
- assert(py_mod_bt2_values);
- py_mod_bt2_values_create_from_ptr_func =
- PyObject_GetAttrString(py_mod_bt2_values,
- "_create_from_ptr");
- assert(py_mod_bt2_values_create_from_ptr_func);
py_mod_bt2_exc_error_type =
PyObject_GetAttrString(py_mod_bt2, "Error");
assert(py_mod_bt2_exc_error_type);
PyObject_GetAttrString(py_mod_bt2, "TryAgain");
py_mod_bt2_exc_stop_type =
PyObject_GetAttrString(py_mod_bt2, "Stop");
+ py_mod_bt2_exc_port_connection_refused_type =
+ PyObject_GetAttrString(py_mod_bt2, "PortConnectionRefused");
+ py_mod_bt2_exc_graph_canceled_type =
+ PyObject_GetAttrString(py_mod_bt2, "GraphCanceled");
+ py_mod_bt2_exc_connection_ended_type =
+ PyObject_GetAttrString(py_mod_bt2, "ConnectionEnded");
assert(py_mod_bt2_exc_stop_type);
}
* bt_py3_cc_init_from_bt2() here. The global variables continue
* to exist for the code of this file, but they are now borrowed
* references. If this code is executed, it means that somehow
- * to modules are still loaded, so it should be safe to use them
- * even without a strong reference.
+ * the modules are still loaded, so it should be safe to use
+ * them even without a strong reference.
*
* We cannot do this in the library's destructor because it
* gets executed once Python is already finalized.
*/
- Py_XDECREF(py_mod_bt2_values_create_from_ptr_func);
- Py_XDECREF(py_mod_bt2_values);
Py_XDECREF(py_mod_bt2);
Py_XDECREF(py_mod_bt2_exc_error_type);
Py_XDECREF(py_mod_bt2_exc_unsupported_feature_type);
Py_XDECREF(py_mod_bt2_exc_try_again_type);
Py_XDECREF(py_mod_bt2_exc_stop_type);
+ Py_XDECREF(py_mod_bt2_exc_port_connection_refused_type);
+ Py_XDECREF(py_mod_bt2_exc_graph_canceled_type);
+ Py_XDECREF(py_mod_bt2_exc_notif_iter_canceled_type);
+ Py_XDECREF(py_mod_bt2_exc_connection_ended_type);
}
-/* Library constructor and destructor */
-
-__attribute__((constructor))
-static void bt_py3_native_comp_class_ctor(void) {
- /* Initialize component class association hash table */
- bt_cc_ptr_to_py_cls = g_hash_table_new(g_direct_hash, g_direct_equal);
- assert(bt_cc_ptr_to_py_cls);
-}
+/* Library destructor */
__attribute__((destructor))
static void bt_py3_native_comp_class_dtor(void) {
/* Destroy component class association hash table */
if (bt_cc_ptr_to_py_cls) {
+ BT_LOGD_STR("Destroying native component class to Python component class hash table.");
g_hash_table_destroy(bt_cc_ptr_to_py_cls);
}
}
-/* Converts a BT value object to a bt2.values object */
+/* Component class proxy methods (delegate to the attached Python object) */
-static PyObject *bt_py3_bt_value_from_ptr(struct bt_value *value)
+static enum bt_notification_iterator_status bt_py3_exc_to_notif_iter_status(void)
{
- PyObject *py_create_from_ptr_func = NULL;
- PyObject *py_value = NULL;
- PyObject *py_ptr = NULL;
+ enum bt_notification_iterator_status status =
+ BT_NOTIFICATION_ITERATOR_STATUS_OK;
+ PyObject *exc = PyErr_Occurred();
- py_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(value),
- SWIGTYPE_p_bt_value, 0);
- py_value = PyObject_CallFunctionObjArgs(
- py_mod_bt2_values_create_from_ptr_func, py_ptr, NULL);
- if (!py_value) {
+ if (!exc) {
goto end;
}
- /*
- * _create_from_ptr() only wraps an existing reference. `value`
- * is a borrowed reference here, so increment its reference
- * count for this new owner.
- */
- bt_get(value);
+ if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_unsupported_feature_type)) {
+ status = BT_NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED;
+ } else if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_stop_type)) {
+ status = BT_NOTIFICATION_ITERATOR_STATUS_END;
+ } else if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_try_again_type)) {
+ status = BT_NOTIFICATION_ITERATOR_STATUS_AGAIN;
+ } else {
+ status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
+ }
end:
- Py_XDECREF(py_ptr);
PyErr_Clear();
- return py_value;
+ return status;
}
-
-/* self.__init__(*args, **kwargs) */
-
-static int bt_py3_call_self_init(PyObject *py_self, PyObject *py_args,
- PyObject *py_kwargs)
+static enum bt_component_status bt_py3_exc_to_component_status(void)
{
- int ret = 0;
- size_t i;
- PyObject *py_init_method_result = NULL;
- PyObject *py_init_method = NULL;
- PyObject *py_init_method_args = NULL;
- PyObject *py_class = NULL;
+ enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+ PyObject *exc = PyErr_Occurred();
- py_class = PyObject_GetAttrString(py_self, "__class__");
- if (!py_class) {
- goto error;
+ if (!exc) {
+ goto end;
}
- py_init_method = PyObject_GetAttrString(py_class, "__init__");
- if (!py_init_method) {
- goto error;
+ if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_unsupported_feature_type)) {
+ status = BT_COMPONENT_STATUS_UNSUPPORTED;
+ } else if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_try_again_type)) {
+ status = BT_COMPONENT_STATUS_AGAIN;
+ } else if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_stop_type)) {
+ status = BT_COMPONENT_STATUS_END;
+ } else if (PyErr_GivenExceptionMatches(exc,
+ py_mod_bt2_exc_port_connection_refused_type)) {
+ status = BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION;
+ } else {
+ status = BT_COMPONENT_STATUS_ERROR;
}
- /* Prepend py_self to the arguments (copy them to new tuple) */
- py_init_method_args = PyTuple_New(PyTuple_Size(py_args) + 1);
- if (!py_init_method_args) {
+end:
+ PyErr_Clear();
+ return status;
+}
+
+static enum bt_component_status bt_py3_cc_init(
+ struct bt_private_component *priv_comp,
+ struct bt_value *params, void *init_method_data)
+{
+ struct bt_component *comp =
+ bt_component_from_private_component(priv_comp);
+ struct bt_component_class *comp_cls = bt_component_get_class(comp);
+ enum bt_component_status status = BT_COMPONENT_STATUS_OK;
+ PyObject *py_cls = NULL;
+ PyObject *py_comp = NULL;
+ PyObject *py_params_ptr = NULL;
+ PyObject *py_comp_ptr = NULL;
+
+ (void) init_method_data;
+ assert(comp);
+ assert(comp_cls);
+
+ /*
+ * Get the user-defined Python class which created this
+ * component's class in the first place (borrowed
+ * reference).
+ */
+ py_cls = lookup_cc_ptr_to_py_cls(comp_cls);
+ if (!py_cls) {
+ BT_LOGE("Cannot find Python class associated to native component class: "
+ "comp-cls-addr=%p", comp_cls);
goto error;
}
- Py_INCREF(py_self);
- ret = PyTuple_SetItem(py_init_method_args, 0, py_self);
- if (ret < 0) {
- Py_DECREF(py_self);
+ /* Parameters pointer -> SWIG pointer Python object */
+ py_params_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(params),
+ SWIGTYPE_p_bt_value, 0);
+ if (!py_params_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
goto error;
}
- for (i = 0; i < PyTuple_Size(py_args); i++) {
- PyObject *obj = PyTuple_GetItem(py_args, i);
- if (!obj) {
- goto error;
- }
-
- Py_INCREF(obj);
- ret = PyTuple_SetItem(py_init_method_args, i + 1, obj);
- if (ret < 0) {
- Py_DECREF(obj);
- goto error;
- }
+ /* Private component pointer -> SWIG pointer Python object */
+ py_comp_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(priv_comp),
+ SWIGTYPE_p_bt_private_component, 0);
+ if (!py_comp_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
+ goto error;
}
- py_init_method_result = PyObject_Call(py_init_method,
- py_init_method_args, py_kwargs);
- if (!py_init_method_result) {
+ /*
+ * Do the equivalent of this:
+ *
+ * py_comp = py_cls._init_from_native(py_comp_ptr, py_params_ptr)
+ *
+ * _UserComponentType._init_from_native() calls the Python
+ * component object's __init__() function.
+ */
+ py_comp = PyObject_CallMethod(py_cls,
+ "_init_from_native", "(OO)", py_comp_ptr, py_params_ptr);
+ if (!py_comp) {
+ BT_LOGE("Failed to call Python class's _init_from_native() method: "
+ "py-cls-addr=%p", py_cls);
goto error;
}
+ /*
+ * Our user Python component object is now fully created and
+ * initialized by the user. Since we just created it, this
+ * native component is its only (persistent) owner.
+ */
+ bt_private_component_set_user_data(priv_comp, py_comp);
+ py_comp = NULL;
goto end;
error:
- ret = -1;
-
-end:
- Py_XDECREF(py_init_method_args);
- Py_XDECREF(py_init_method_result);
- Py_XDECREF(py_init_method);
- Py_XDECREF(py_class);
- return ret;
-}
-
-
-/* Component class proxy methods (delegate to the attached Python object) */
-
-static enum bt_component_status bt_py3_cc_init(
- struct bt_component *component, struct bt_value *params,
- void *init_method_data)
-{
- enum bt_component_status status = BT_COMPONENT_STATUS_OK;
- int ret;
+ status = BT_COMPONENT_STATUS_ERROR;
/*
- * This function is either called from
- * _UserComponentType.__call__() (when init_method_data contains
- * the PyObject * currently creating this component) or from
- * other code (init_method_data is NULL).
+ * Clear any exception: we're returning a bad status anyway. If
+ * this call originated from Python (creation from a plugin's
+ * component class, for example), then the user gets an
+ * appropriate creation error.
*/
- if (init_method_data) {
- /*
- * Called from _UserComponentType.__call__().
- *
- * The `params` argument is completely ignored here,
- * because if the user creating the component object
- * from the component class object wants parameters,
- * they'll be in the keyword arguments anyway.
- */
- PyObject *py_comp = init_method_data;
- PyObject *py_comp_ptr = NULL;
- PyObject *py_init_args = NULL;
- PyObject *py_init_kwargs = NULL;
+ PyErr_Clear();
- /*
- * No need to take a Python reference on py_comp here:
- * we store it as a _borrowed_ reference. When all the
- * Python references are dropped, the object's __del__()
- * method is called. This method calls this side
- * (bt_py3_component_on_del()) to swap the ownership:
- * this BT component becomes the only owner of the
- * Python object.
- */
- bt_component_set_private_data(component, py_comp);
+end:
+ bt_put(comp_cls);
+ bt_put(comp);
+ Py_XDECREF(py_comp);
+ Py_XDECREF(py_params_ptr);
+ Py_XDECREF(py_comp_ptr);
+ return status;
+}
- /*
- * Set this BT component pointer as py_comp._ptr, and
- * take a reference on it (on success, at the end).
- *
- * This reference is put in the Python component
- * object's __del__() method.
- */
- py_comp_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(component),
- SWIGTYPE_p_bt_component, 0);
- if (!py_comp_ptr) {
- PyErr_Clear();
- goto with_init_method_data_error;
- }
+static void bt_py3_cc_finalize(struct bt_private_component *priv_comp)
+{
+ PyObject *py_comp = bt_private_component_get_user_data(priv_comp);
+ PyObject *py_method_result = NULL;
- ret = PyObject_SetAttrString(py_comp, "_ptr", py_comp_ptr);
- if (ret < 0) {
- PyErr_Clear();
- goto with_init_method_data_error;
- }
+ assert(py_comp);
- /*
- * _UserComponentType.__call__() puts the arguments and
- * keyword arguments to use for the py_comp.__init__()
- * call in py_comp._init_args and py_comp._init_kwargs.
- *
- * We need to get them and remove them from py_comp before
- * calling py_comp.__init__().
- */
- py_init_args = PyObject_GetAttrString(py_comp, "_init_args");
- if (!py_init_args) {
- PyErr_Clear();
- goto with_init_method_data_error;
- }
+ /* Call user's _finalize() method */
+ py_method_result = PyObject_CallMethod(py_comp,
+ "_finalize", NULL);
- py_init_kwargs = PyObject_GetAttrString(py_comp, "_init_kwargs");
- if (!py_init_kwargs) {
- PyErr_Clear();
- goto with_init_method_data_error;
- }
+ if (PyErr_Occurred()) {
+ BT_LOGW("User's _finalize() method raised an exception: ignoring.");
+ }
- ret = PyObject_DelAttrString(py_comp, "_init_args");
- if (ret < 0) {
- PyErr_Clear();
- goto with_init_method_data_error;
- }
+ /*
+ * Ignore any exception raised by the _finalize() method because
+ * it won't change anything at this point: the component is
+ * being destroyed anyway.
+ */
+ PyErr_Clear();
+ Py_XDECREF(py_method_result);
+ Py_DECREF(py_comp);
+}
- ret = PyObject_DelAttrString(py_comp, "_init_kwargs");
- if (ret < 0) {
- PyErr_Clear();
- goto with_init_method_data_error;
- }
+static enum bt_component_status bt_py3_cc_accept_port_connection(
+ struct bt_private_component *priv_comp,
+ struct bt_private_port *self_priv_port,
+ struct bt_port *other_port)
+{
+ enum bt_component_status status;
+ PyObject *py_comp = NULL;
+ PyObject *py_self_port_ptr = NULL;
+ PyObject *py_other_port_ptr = NULL;
+ PyObject *py_method_result = NULL;
- /* Ready to call py_comp.__init__() */
- ret = bt_py3_call_self_init(py_comp, py_init_args,
- py_init_kwargs);
- if (ret) {
- /*
- * We do not clear any raised exception here
- * so that the Python caller (the one who is
- * instantiating the class) gets the exception
- * from the __init__() method.
- */
- goto with_init_method_data_error;
- }
+ py_comp = bt_private_component_get_user_data(priv_comp);
+ assert(py_comp);
+ py_self_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(self_priv_port),
+ SWIGTYPE_p_bt_private_port, 0);
+ if (!py_self_port_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
+ goto error;
+ }
- /*
- * py_comp.__init__() went well: get the native BT
- * component object reference for the Python object.
- */
- bt_get(component);
- goto with_init_method_data_end;
+ py_other_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(other_port),
+ SWIGTYPE_p_bt_port, 0);
+ if (!py_other_port_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
+ goto error;
+ }
-with_init_method_data_error:
- status = BT_COMPONENT_STATUS_ERROR;
+ py_method_result = PyObject_CallMethod(py_comp,
+ "_accept_port_connection_from_native", "(OO)", py_self_port_ptr,
+ py_other_port_ptr);
+ status = bt_py3_exc_to_component_status();
+ if (!py_method_result && status == BT_COMPONENT_STATUS_OK) {
+ /* Pretty sure this should never happen, but just in case */
+ BT_LOGE("User's _accept_port_connection() method failed without raising an exception: "
+ "status=%d", status);
+ goto error;
+ }
+ if (status == BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION) {
/*
- * Reset py_comp._ptr to None to signal the error to
- * _UserComponentType.__call__(). For exceptions raised
- * from py_comp.__init__(), this is not important,
- * because __call__() will also raise before even
- * checking py_comp._ptr.
+ * Looks like the user method raised
+ * PortConnectionRefused: accept this like if it
+ * returned False.
*/
- if (PyObject_HasAttrString(py_comp, "_ptr")) {
- PyObject *py_err_type, *py_err_value, *py_err_traceback;
- PyErr_Fetch(&py_err_type, &py_err_value,
- &py_err_traceback);
- Py_INCREF(Py_None);
- PyObject_SetAttrString(py_comp, "_ptr", Py_None);
- PyErr_Restore(py_err_type, py_err_value,
- py_err_traceback);
- }
+ goto end;
+ } else if (status != BT_COMPONENT_STATUS_OK) {
+ BT_LOGE("User's _accept_port_connection() raised an unexpected exception: "
+ "status=%d", status);
+ goto error;
+ }
- /*
- * Important: remove py_comp from our the BT component's
- * private data. Since we're failing,
- * bt_py3_cc_destroy() is about to be called: it must
- * not consider py_comp. py_comp's __del__() method
- * will be called (because the instance exists), but
- * since py_comp._ptr is None, it won't do anything.
- */
- bt_component_set_private_data(component, NULL);
+ assert(PyBool_Check(py_method_result));
-with_init_method_data_end:
- Py_XDECREF(py_comp_ptr);
- Py_XDECREF(py_init_args);
- Py_XDECREF(py_init_kwargs);
+ if (py_method_result == Py_True) {
+ status = BT_COMPONENT_STATUS_OK;
} else {
- /*
- * Not called from _UserComponentType.__call__().
- *
- * In this case we need to instantiate the user-defined
- * Python class. To do this we call the user-defined
- * class manually with this already-created BT component
- * object pointer as the __comp_ptr keyword argument.
- *
- * We keep a reference, the only existing one, to the
- * created Python object. bt_py3_component_on_del() will
- * never be called by the object's __del__() method
- * because _UserComponentType.__call__() marks the
- * object as owned by the native BT component object.
- */
- PyObject *py_cls = NULL;
- PyObject *py_comp = NULL;
- PyObject *py_params = NULL;
- PyObject *py_comp_ptr = NULL;
- PyObject *py_cls_ctor_args = NULL;
- PyObject *py_cls_ctor_kwargs = NULL;
-
- /*
- * Get the user-defined Python class which created this
- * component's class in the first place (borrowed
- * reference).
- */
- py_cls = lookup_cc_ptr_to_py_cls(bt_component_get_class(component));
- if (!py_cls) {
- goto without_init_method_data_error;
- }
-
- /* BT value object -> Python bt2.values object */
- py_params = bt_py3_bt_value_from_ptr(params);
- if (!py_params) {
- goto without_init_method_data_error;
- }
-
- /* Component pointer -> SWIG pointer Python object */
- py_comp_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(component),
- SWIGTYPE_p_bt_component, 0);
- if (!py_comp_ptr) {
- goto without_init_method_data_error;
- }
-
- /*
- * Do the equivalent of this:
- *
- * py_comp = py_cls(__comp_ptr=py_comp_ptr, params=py_params)
- *
- * _UserComponentType.__call__() calls the Python
- * component object's __init__() function itself in this
- * case.
- */
- py_cls_ctor_args = PyTuple_New(0);
- if (!py_cls_ctor_args) {
- goto without_init_method_data_error;
- }
-
- py_cls_ctor_kwargs = PyDict_New();
- if (!py_cls_ctor_kwargs) {
- goto without_init_method_data_error;
- }
-
- ret = PyDict_SetItemString(py_cls_ctor_kwargs, "__comp_ptr",
- py_comp_ptr);
- if (ret < 0) {
- goto without_init_method_data_error;
- }
-
- ret = PyDict_SetItemString(py_cls_ctor_kwargs, "params",
- py_params);
- if (ret < 0) {
- goto without_init_method_data_error;
- }
-
- py_comp = PyObject_Call(py_cls, py_cls_ctor_args,
- py_cls_ctor_kwargs);
- if (!py_comp) {
- goto without_init_method_data_error;
- }
+ status = BT_COMPONENT_STATUS_REFUSE_PORT_CONNECTION;
+ }
- /*
- * Our user Python component object is now fully created
- * and initialized by the user. Since we just created
- * it, this BT component is its only (persistent) owner.
- */
- bt_component_set_private_data(component, py_comp);
- py_comp = NULL;
- goto without_init_method_data_end;
+ goto end;
-without_init_method_data_error:
- status = BT_COMPONENT_STATUS_ERROR;
+error:
+ status = BT_COMPONENT_STATUS_ERROR;
- /*
- * Clear any exception: we're returning a bad status
- * anyway. If this call originated from Python (creation
- * from a plugin's component class, for example), then
- * the user gets an appropriate creation error.
- */
- PyErr_Clear();
-
-without_init_method_data_end:
- Py_XDECREF(py_comp);
- Py_XDECREF(py_params);
- Py_XDECREF(py_comp_ptr);
- Py_XDECREF(py_cls_ctor_args);
- Py_XDECREF(py_cls_ctor_kwargs);
- }
+ /*
+ * Clear any exception: we're returning a bad status anyway. If
+ * this call originated from Python, then the user gets an
+ * appropriate error.
+ */
+ PyErr_Clear();
+end:
+ Py_XDECREF(py_self_port_ptr);
+ Py_XDECREF(py_other_port_ptr);
+ Py_XDECREF(py_method_result);
return status;
}
-static void bt_py3_cc_destroy(struct bt_component *component)
+static void bt_py3_cc_port_connected(
+ struct bt_private_component *priv_comp,
+ struct bt_private_port *self_priv_port,
+ struct bt_port *other_port)
{
- PyObject *py_comp = bt_component_get_private_data(component);
- PyObject *py_destroy_method_result = NULL;
+ PyObject *py_comp = NULL;
+ PyObject *py_self_port_ptr = NULL;
+ PyObject *py_other_port_ptr = NULL;
+ PyObject *py_method_result = NULL;
- if (py_comp) {
- /*
- * If we're here, this BT component is the only owner of
- * its private user Python object. It is safe to
- * decrement its reference count, and thus destroy it.
- *
- * We call its _destroy() method before doing so to notify
- * the Python user.
- */
- py_destroy_method_result = PyObject_CallMethod(py_comp,
- "_destroy", NULL);
+ py_comp = bt_private_component_get_user_data(priv_comp);
+ assert(py_comp);
+ py_self_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(self_priv_port),
+ SWIGTYPE_p_bt_private_port, 0);
+ if (!py_self_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_other_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(other_port),
+ SWIGTYPE_p_bt_port, 0);
+ if (!py_other_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_method_result = PyObject_CallMethod(py_comp,
+ "_port_connected_from_native", "(OO)", py_self_port_ptr,
+ py_other_port_ptr);
+ assert(py_method_result == Py_None);
+ Py_XDECREF(py_self_port_ptr);
+ Py_XDECREF(py_other_port_ptr);
+ Py_XDECREF(py_method_result);
+}
- /*
- * Ignore any exception raised by the _destroy() method
- * because it won't change anything at this point: the
- * component is being destroyed anyway.
- */
- PyErr_Clear();
- Py_XDECREF(py_destroy_method_result);
- Py_DECREF(py_comp);
- }
+static void bt_py3_cc_port_disconnected(
+ struct bt_private_component *priv_comp,
+ struct bt_private_port *priv_port)
+{
+ PyObject *py_comp = NULL;
+ PyObject *py_port_ptr = NULL;
+ PyObject *py_method_result = NULL;
+
+ py_comp = bt_private_component_get_user_data(priv_comp);
+ assert(py_comp);
+ py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(priv_port),
+ SWIGTYPE_p_bt_private_port, 0);
+ if (!py_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_method_result = PyObject_CallMethod(py_comp,
+ "_port_disconnected_from_native", "(O)", py_port_ptr);
+ assert(py_method_result == Py_None);
+ Py_XDECREF(py_port_ptr);
+ Py_XDECREF(py_method_result);
}
static struct bt_value *bt_py3_cc_query(
- struct bt_component_class *component_class,
+ struct bt_component_class *comp_cls,
const char *object, struct bt_value *params)
{
PyObject *py_cls = NULL;
- PyObject *py_params = NULL;
+ PyObject *py_params_ptr = NULL;
PyObject *py_query_func = NULL;
PyObject *py_object = NULL;
PyObject *py_results_addr = NULL;
struct bt_value *results = NULL;
- py_cls = lookup_cc_ptr_to_py_cls(component_class);
+ py_cls = lookup_cc_ptr_to_py_cls(comp_cls);
if (!py_cls) {
+ BT_LOGE("Cannot find Python class associated to native component class: "
+ "comp-cls-addr=%p", comp_cls);
goto error;
}
- py_params = bt_py3_bt_value_from_ptr(params);
- if (!py_params) {
+ py_params_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(params),
+ SWIGTYPE_p_bt_value, 0);
+ if (!py_params_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
goto error;
}
py_object = SWIG_FromCharPtr(object);
if (!py_object) {
+ BT_LOGE_STR("Failed to create a Python string.");
goto error;
}
py_results_addr = PyObject_CallMethod(py_cls,
- "_query_from_bt", "(OO)", py_object, py_params);
- if (!py_results_addr) {
+ "_query_from_native", "(OO)", py_object, py_params_ptr);
+ if (!py_results_addr || py_results_addr == Py_None) {
+ BT_LOGE_STR("User's _query() method failed.");
goto error;
}
- /*
- * The returned object, on success, is an integer object
- * (PyLong) containing the address of a BT value object
- * (which is now ours).
- */
- results = (struct bt_value *) PyLong_AsUnsignedLongLong(
- py_results_addr);
-
- /* Clear potential overflow error; should never happen */
- if (PyErr_Occurred()) {
- results = NULL;
- goto error;
- }
-
- if (!results) {
+ if (py_results_addr == Py_NotImplemented) {
+ BT_LOGE_STR("User's _query() method is not implemented.");
goto error;
}
+ /*
+ * The returned object, on success, is an integer object
+ * (PyLong) containing the address of a BT value object (new
+ * reference).
+ */
+ results = (void *) PyLong_AsUnsignedLongLong(py_results_addr);
+ assert(!PyErr_Occurred());
+ assert(results);
goto end;
error:
PyErr_Clear();
end:
- Py_XDECREF(py_params);
+ Py_XDECREF(py_params_ptr);
Py_XDECREF(py_query_func);
Py_XDECREF(py_object);
Py_XDECREF(py_results_addr);
return results;
}
-static enum bt_notification_iterator_status bt_py3_exc_to_notif_iter_status(void)
-{
- enum bt_notification_iterator_status status =
- BT_NOTIFICATION_ITERATOR_STATUS_OK;
- PyObject *exc = PyErr_Occurred();
-
- if (!exc) {
- goto end;
- }
-
- if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_unsupported_feature_type)) {
- status = BT_NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED;
- } else if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_stop_type)) {
- status = BT_NOTIFICATION_ITERATOR_STATUS_END;
- } else {
- status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
- }
-
-end:
- PyErr_Clear();
- return status;
-}
-
static enum bt_notification_iterator_status bt_py3_cc_notification_iterator_init(
- struct bt_component *component,
- struct bt_notification_iterator *iter, void *init_method_data)
+ struct bt_private_notification_iterator *priv_notif_iter,
+ struct bt_private_port *priv_port)
{
enum bt_notification_iterator_status status =
BT_NOTIFICATION_ITERATOR_STATUS_OK;
PyObject *py_iter_ptr = NULL;
PyObject *py_init_method_result = NULL;
PyObject *py_iter = NULL;
- PyObject *py_comp = bt_component_get_private_data(component);
+ struct bt_private_component *priv_comp =
+ bt_private_notification_iterator_get_private_component(
+ priv_notif_iter);
+ PyObject *py_comp;
+
+ assert(priv_comp);
+ py_comp = bt_private_component_get_user_data(priv_comp);
/* Find user's Python notification iterator class */
py_comp_cls = PyObject_GetAttrString(py_comp, "__class__");
if (!py_comp_cls) {
+ BT_LOGE_STR("Cannot get Python object's `__class__` attribute.");
goto error;
}
py_iter_cls = PyObject_GetAttrString(py_comp_cls, "_iter_cls");
if (!py_iter_cls) {
+ BT_LOGE_STR("Cannot get Python class's `_iter_cls` attribute.");
+ goto error;
+ }
+
+ py_iter_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(priv_notif_iter),
+ SWIGTYPE_p_bt_private_notification_iterator, 0);
+ if (!py_iter_ptr) {
+ BT_LOGE_STR("Failed to create a SWIG pointer object.");
goto error;
}
/*
- * Create object with borrowed BT notification iterator
+ * Create object with borrowed native notification iterator
* reference:
*
* py_iter = py_iter_cls.__new__(py_iter_cls, py_iter_ptr)
*/
- py_iter_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(iter),
- SWIGTYPE_p_bt_notification_iterator, 0);
- if (!py_iter_ptr) {
- goto error;
- }
-
py_iter = PyObject_CallMethod(py_iter_cls, "__new__",
"(OO)", py_iter_cls, py_iter_ptr);
if (!py_iter) {
+ BT_LOGE("Failed to call Python class's __new__() method: "
+ "py-cls-addr=%p", py_iter_cls);
goto error;
}
* py_iter.__init__()
*
* At this point, py_iter._ptr is set, so this initialization
- * function has access to the py_iter.component property (which
- * gives it the user Python component object from which the
- * iterator was created).
+ * function has access to self._component (which gives it the
+ * user Python component object from which the iterator was
+ * created).
*/
py_init_method_result = PyObject_CallMethod(py_iter, "__init__", NULL);
if (!py_init_method_result) {
+ BT_LOGE_STR("User's __init__() method failed.");
goto error;
}
/*
* Since the Python code can never instantiate a user-defined
- * notification iterator class, the BT notification iterator
+ * notification iterator class, the native notification iterator
* object does NOT belong to a user Python notification iterator
* object (borrowed reference). However this Python object is
- * owned by this BT notification iterator object.
+ * owned by this native notification iterator object.
*
- * In the Python world, the lifetime of the BT notification
+ * In the Python world, the lifetime of the native notification
* iterator is managed by a _GenericNotificationIterator
* instance:
*
* _GenericNotificationIterator instance:
* owns a native bt_notification_iterator object (iter)
- * owns a UserNotificationIterator instance (py_iter)
+ * owns a _UserNotificationIterator instance (py_iter)
* self._ptr is a borrowed reference to the
- * native bt_notification_iterator object (iter)
+ * native bt_private_notification_iterator
+ * object (iter)
*/
- bt_notification_iterator_set_private_data(iter, py_iter);
+ bt_private_notification_iterator_set_user_data(priv_notif_iter,
+ py_iter);
py_iter = NULL;
goto end;
PyErr_Clear();
end:
+ bt_put(priv_comp);
Py_XDECREF(py_comp_cls);
Py_XDECREF(py_iter_cls);
Py_XDECREF(py_iter_ptr);
return status;
}
-static void bt_py3_cc_notification_iterator_destroy(
- struct bt_notification_iterator *iter)
+static void bt_py3_cc_notification_iterator_finalize(
+ struct bt_private_notification_iterator *priv_notif_iter)
{
PyObject *py_notif_iter =
- bt_notification_iterator_get_private_data(iter);
- PyObject *py_destroy_method_result = NULL;
+ bt_private_notification_iterator_get_user_data(priv_notif_iter);
+ PyObject *py_method_result = NULL;
assert(py_notif_iter);
- py_destroy_method_result = PyObject_CallMethod(py_notif_iter,
- "_destroy", NULL);
+
+ /* Call user's _finalize() method */
+ py_method_result = PyObject_CallMethod(py_notif_iter,
+ "_finalize", NULL);
+
+ if (PyErr_Occurred()) {
+ BT_LOGW("User's _finalize() method raised an exception: ignoring.");
+ }
/*
- * Ignore any exception raised by the _destroy() method because
- * it won't change anything at this point. The notification
- * iterator is being destroyed anyway.
+ * Ignore any exception raised by the _finalize() method because
+ * it won't change anything at this point: the component is
+ * being destroyed anyway.
*/
PyErr_Clear();
- Py_XDECREF(py_destroy_method_result);
+ Py_XDECREF(py_method_result);
Py_DECREF(py_notif_iter);
}
-static struct bt_notification *bt_py3_cc_notification_iterator_get(
- struct bt_notification_iterator *iter)
+static struct bt_notification_iterator_next_return
+bt_py3_cc_notification_iterator_next(
+ struct bt_private_notification_iterator *priv_notif_iter)
{
+ struct bt_notification_iterator_next_return next_ret = {
+ .status = BT_NOTIFICATION_ITERATOR_STATUS_OK,
+ .notification = NULL,
+ };
PyObject *py_notif_iter =
- bt_notification_iterator_get_private_data(iter);
- PyObject *py_get_method_result = NULL;
- struct bt_notification *notif = NULL;
+ bt_private_notification_iterator_get_user_data(priv_notif_iter);
+ PyObject *py_method_result = NULL;
assert(py_notif_iter);
- py_get_method_result = PyObject_CallMethod(py_notif_iter,
- "_get_from_bt", NULL);
- if (!py_get_method_result) {
- goto error;
+ py_method_result = PyObject_CallMethod(py_notif_iter,
+ "_next_from_native", NULL);
+ if (!py_method_result) {
+ next_ret.status = bt_py3_exc_to_notif_iter_status();
+ assert(next_ret.status != BT_NOTIFICATION_ITERATOR_STATUS_OK);
+ goto end;
}
/*
* The returned object, on success, is an integer object
- * (PyLong) containing the address of a BT notification
+ * (PyLong) containing the address of a native notification
* object (which is now ours).
*/
- notif = (struct bt_notification *) PyLong_AsUnsignedLongLong(
- py_get_method_result);
+ next_ret.notification =
+ (struct bt_notification *) PyLong_AsUnsignedLongLong(
+ py_method_result);
/* Clear potential overflow error; should never happen */
- if (PyErr_Occurred()) {
- notif = NULL;
- goto error;
- }
-
- if (!notif) {
- goto error;
- }
-
+ assert(!PyErr_Occurred());
+ assert(next_ret.notification);
goto end;
-error:
- BT_PUT(notif);
-
- /*
- * Clear any exception: we're returning NULL anyway. If this
- * call originated from Python, then the user gets an
- * appropriate error.
- */
- PyErr_Clear();
-
end:
- Py_XDECREF(py_get_method_result);
- return notif;
-}
-
-static enum bt_notification_iterator_status bt_py3_cc_notification_iterator_next(
- struct bt_notification_iterator *iter)
-{
- enum bt_notification_iterator_status status;
- PyObject *py_notif_iter =
- bt_notification_iterator_get_private_data(iter);
- PyObject *py_next_method_result = NULL;
-
- assert(py_notif_iter);
- py_next_method_result = PyObject_CallMethod(py_notif_iter,
- "_next", NULL);
- status = bt_py3_exc_to_notif_iter_status();
- if (!py_next_method_result
- && status == BT_NOTIFICATION_ITERATOR_STATUS_OK) {
- /* Pretty sure this should never happen, but just in case */
- status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
- }
-
- Py_XDECREF(py_next_method_result);
- return status;
-}
-
-static enum bt_notification_iterator_status bt_py3_cc_notification_iterator_seek_time(
- struct bt_notification_iterator *iter, int64_t time)
-{
- enum bt_notification_iterator_status status;
- PyObject *py_notif_iter =
- bt_notification_iterator_get_private_data(iter);
- PyObject *py_seek_to_time_method_result = NULL;
-
- assert(py_notif_iter);
- py_seek_to_time_method_result = PyObject_CallMethod(py_notif_iter,
- "_seek_to_time", "(L)", time);
- status = bt_py3_exc_to_notif_iter_status();
- if (!py_seek_to_time_method_result
- && status == BT_NOTIFICATION_ITERATOR_STATUS_OK) {
- /* Pretty sure this should never happen, but just in case */
- status = BT_NOTIFICATION_ITERATOR_STATUS_ERROR;
- }
-
- Py_XDECREF(py_seek_to_time_method_result);
- return status;
-}
-
-static enum bt_component_status bt_py3_exc_to_component_status(void)
-{
- enum bt_component_status status = BT_COMPONENT_STATUS_OK;
- PyObject *exc = PyErr_Occurred();
-
- if (!exc) {
- goto end;
- }
-
- if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_unsupported_feature_type)) {
- status = BT_COMPONENT_STATUS_UNSUPPORTED;
- } else if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_try_again_type)) {
- status = BT_COMPONENT_STATUS_AGAIN;
- } else if (PyErr_GivenExceptionMatches(exc,
- py_mod_bt2_exc_stop_type)) {
- status = BT_COMPONENT_STATUS_END;
- } else {
- status = BT_COMPONENT_STATUS_ERROR;
- }
-
-end:
- PyErr_Clear();
- return status;
+ Py_XDECREF(py_method_result);
+ return next_ret;
}
static enum bt_component_status bt_py3_cc_sink_consume(
- struct bt_component *component)
+ struct bt_private_component *priv_comp)
{
- PyObject *py_comp = bt_component_get_private_data(component);
- PyObject *py_consume_method_result = NULL;
+ PyObject *py_comp = bt_private_component_get_user_data(priv_comp);
+ PyObject *py_method_result = NULL;
enum bt_component_status status;
- py_consume_method_result = PyObject_CallMethod(py_comp,
+ assert(py_comp);
+ py_method_result = PyObject_CallMethod(py_comp,
"_consume", NULL);
status = bt_py3_exc_to_component_status();
- if (!py_consume_method_result && status == BT_COMPONENT_STATUS_OK) {
- /* Pretty sure this should never happen, but just in case */
- status = BT_COMPONENT_STATUS_ERROR;
- }
-
- Py_XDECREF(py_consume_method_result);
- return status;
-}
-
-static enum bt_component_status bt_py3_cc_sink_filter_add_iterator(
- struct bt_component *component,
- struct bt_notification_iterator *iter)
-{
- PyObject *py_comp = bt_component_get_private_data(component);
- PyObject *py_add_iterator_method_result = NULL;
- PyObject *py_notif_iter_ptr = NULL;
- enum bt_component_status status;
-
- py_notif_iter_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(iter),
- SWIGTYPE_p_bt_notification_iterator, 0);
- if (!py_notif_iter_ptr) {
- PyErr_Clear();
- status = BT_COMPONENT_STATUS_ERROR;
- goto end;
- }
-
- bt_get(iter);
- py_add_iterator_method_result = PyObject_CallMethod(py_comp,
- "_add_iterator_from_bt", "(O)", py_notif_iter_ptr);
- status = bt_py3_exc_to_component_status();
- if (!py_add_iterator_method_result
- && status == BT_COMPONENT_STATUS_OK) {
+ if (!py_method_result && status == BT_COMPONENT_STATUS_OK) {
/* Pretty sure this should never happen, but just in case */
+ BT_LOGE("User's _consume() method failed without raising an exception: "
+ "status=%d", status);
status = BT_COMPONENT_STATUS_ERROR;
}
-end:
- Py_XDECREF(py_notif_iter_ptr);
- Py_XDECREF(py_add_iterator_method_result);
+ Py_XDECREF(py_method_result);
return status;
}
if (description) {
ret = bt_component_class_set_description(cc, description);
if (ret) {
+ BT_LOGE("Cannot set component class's description: "
+ "comp-cls-addr=%p", cc);
goto end;
}
}
if (help) {
ret = bt_component_class_set_help(cc, help);
if (ret) {
+ BT_LOGE("Cannot set component class's help text: "
+ "comp-cls-addr=%p", cc);
goto end;
}
}
ret = bt_component_class_set_init_method(cc, bt_py3_cc_init);
- if (ret) {
- goto end;
- }
-
- ret = bt_component_class_set_destroy_method(cc, bt_py3_cc_destroy);
- if (ret) {
- goto end;
- }
-
+ assert(ret == 0);
+ ret = bt_component_class_set_finalize_method(cc, bt_py3_cc_finalize);
+ assert(ret == 0);
+ ret = bt_component_class_set_accept_port_connection_method(cc,
+ bt_py3_cc_accept_port_connection);
+ assert(ret == 0);
+ ret = bt_component_class_set_port_connected_method(cc,
+ bt_py3_cc_port_connected);
+ assert(ret == 0);
+ ret = bt_component_class_set_port_disconnected_method(cc,
+ bt_py3_cc_port_disconnected);
+ assert(ret == 0);
ret = bt_component_class_set_query_method(cc, bt_py3_cc_query);
- if (ret) {
- goto end;
- }
+ assert(ret == 0);
end:
return ret;
}
-static int bt_py3_cc_set_optional_iter_methods(struct bt_component_class *cc,
- bool has_seek_time,
+static void bt_py3_cc_set_optional_iter_methods(struct bt_component_class *cc,
int (*set_notif_iter_init_method)(struct bt_component_class *, bt_component_class_notification_iterator_init_method),
- int (*set_notif_iter_destroy_method)(struct bt_component_class *, bt_component_class_notification_iterator_destroy_method),
- int (*set_notif_iter_seek_time_method)(struct bt_component_class *, bt_component_class_notification_iterator_seek_time_method))
+ int (*set_notif_iter_finalize_method)(struct bt_component_class *, bt_component_class_notification_iterator_finalize_method))
{
int ret;
ret = set_notif_iter_init_method(
cc, bt_py3_cc_notification_iterator_init);
- if (ret) {
- goto end;
- }
-
- ret = set_notif_iter_destroy_method(
- cc, bt_py3_cc_notification_iterator_destroy);
- if (ret) {
- goto end;
- }
-
- if (has_seek_time) {
- ret = set_notif_iter_seek_time_method(
- cc, bt_py3_cc_notification_iterator_seek_time);
- if (ret) {
- goto end;
- }
- }
-
-end:
- return ret;
+ assert(ret == 0);
+ ret = set_notif_iter_finalize_method(
+ cc, bt_py3_cc_notification_iterator_finalize);
+ assert(ret == 0);
}
static struct bt_component_class *bt_py3_component_class_source_create(
PyObject *py_cls, const char *name, const char *description,
- const char *help, bool has_seek_time)
+ const char *help)
{
struct bt_component_class *cc;
int ret;
assert(py_cls);
cc = bt_component_class_source_create(name,
- bt_py3_cc_notification_iterator_get,
bt_py3_cc_notification_iterator_next);
if (!cc) {
+ BT_LOGE_STR("Cannot create source component class.");
goto end;
}
ret = bt_py3_cc_set_optional_attrs_methods(cc, description, help);
if (ret) {
+ BT_LOGE_STR("Cannot set source component class's optional attributes and methods.");
BT_PUT(cc);
goto end;
}
- ret = bt_py3_cc_set_optional_iter_methods(cc, has_seek_time,
+ bt_py3_cc_set_optional_iter_methods(cc,
bt_component_class_source_set_notification_iterator_init_method,
- bt_component_class_source_set_notification_iterator_destroy_method,
- bt_component_class_source_set_notification_iterator_seek_time_method);
- if (ret) {
- BT_PUT(cc);
- goto end;
- }
-
+ bt_component_class_source_set_notification_iterator_finalize_method);
register_cc_ptr_to_py_cls(cc, py_cls);
bt_component_class_freeze(cc);
static struct bt_component_class *bt_py3_component_class_filter_create(
PyObject *py_cls, const char *name, const char *description,
- const char *help, bool has_seek_time)
+ const char *help)
{
struct bt_component_class *cc;
int ret;
assert(py_cls);
cc = bt_component_class_filter_create(name,
- bt_py3_cc_notification_iterator_get,
bt_py3_cc_notification_iterator_next);
if (!cc) {
+ BT_LOGE_STR("Cannot create filter component class.");
goto end;
}
ret = bt_py3_cc_set_optional_attrs_methods(cc, description, help);
if (ret) {
+ BT_LOGE_STR("Cannot set filter component class's optional attributes and methods.");
BT_PUT(cc);
goto end;
}
- ret = bt_py3_cc_set_optional_iter_methods(cc, has_seek_time,
+ bt_py3_cc_set_optional_iter_methods(cc,
bt_component_class_filter_set_notification_iterator_init_method,
- bt_component_class_filter_set_notification_iterator_destroy_method,
- bt_component_class_filter_set_notification_iterator_seek_time_method);
- if (ret) {
- BT_PUT(cc);
- goto end;
- }
-
- ret = bt_component_class_filter_set_add_iterator_method(cc,
- bt_py3_cc_sink_filter_add_iterator);
- if (ret) {
- BT_PUT(cc);
- goto end;
- }
-
+ bt_component_class_filter_set_notification_iterator_finalize_method);
register_cc_ptr_to_py_cls(cc, py_cls);
bt_component_class_freeze(cc);
assert(py_cls);
cc = bt_component_class_sink_create(name, bt_py3_cc_sink_consume);
if (!cc) {
+ BT_LOGE_STR("Cannot create sink component class.");
goto end;
}
ret = bt_py3_cc_set_optional_attrs_methods(cc, description, help);
if (ret) {
- BT_PUT(cc);
- goto end;
- }
-
- ret = bt_component_class_sink_set_add_iterator_method(cc,
- bt_py3_cc_sink_filter_add_iterator);
- if (ret) {
+ BT_LOGE_STR("Cannot set sink component class's optional attributes and methods.");
BT_PUT(cc);
goto end;
}
end:
return cc;
}
-
-
-/* Component creation function (called from Python module) */
-
-static void bt_py3_component_create(
- struct bt_component_class *comp_class, PyObject *py_self,
- const char *name)
-{
- struct bt_component *component =
- bt_component_create_with_init_method_data(comp_class,
- name, NULL, py_self);
-
- /*
- * Our component initialization function, bt_py3_cc_init(), sets
- * a new reference to the created component in the user's Python
- * object (py_self._ptr). This is where the reference is kept.
- * We don't need the returned component in this case (if any,
- * because it might be NULL if the creation failed, most
- * probably because py_self.__init__() raised something).
- */
- bt_put(component);
-}
-
-
-/* Component delete notification */
-
-static void bt_py3_component_on_del(PyObject *py_comp)
-{
- /*
- * The Python component's __del__() function calls this to
- * indicate that there's no more reference on it from the
- * Python world.
- *
- * Since the BT component can continue to live once the Python
- * component object is deleted, we increment the Python
- * component's reference count so that it now only belong to the
- * BT component. We will decrement this reference count once
- * the BT component is destroyed in bt_py3_cc_destroy().
- */
- assert(py_comp);
- Py_INCREF(py_comp);
-}
%}
-%exception bt_py3_component_create {
- $action
- if (PyErr_Occurred()) {
- /* Exception is already set by bt_py3_component_create() */
- SWIG_fail;
- }
-}
-
struct bt_component_class *bt_py3_component_class_source_create(
PyObject *py_cls, const char *name, const char *description,
- const char *help, bool has_seek_time);
+ const char *help);
struct bt_component_class *bt_py3_component_class_filter_create(
PyObject *py_cls, const char *name, const char *description,
- const char *help, bool has_seek_time);
+ const char *help);
struct bt_component_class *bt_py3_component_class_sink_create(
PyObject *py_cls, const char *name, const char *description,
const char *help);
-void bt_py3_component_create(
- struct bt_component_class *comp_class, PyObject *py_self,
- const char *name);
-void bt_py3_component_on_del(PyObject *py_comp);
void bt_py3_cc_init_from_bt2(void);
void bt_py3_cc_exit_handler(void);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_connection;
+struct bt_private_connection;
+
+/* Status */
+enum bt_connection_status {
+ BT_CONNECTION_STATUS_GRAPH_IS_CANCELED = 125,
+ BT_CONNECTION_STATUS_OK = 0,
+ BT_CONNECTION_STATUS_INVALID = -22,
+ BT_CONNECTION_STATUS_ERROR = -1,
+ BT_CONNECTION_STATUS_NOMEM = -12,
+ BT_CONNECTION_STATUS_IS_ENDED = 104,
+};
+
+/* Functions (public) */
+struct bt_port *bt_connection_get_downstream_port(
+ struct bt_connection *connection);
+struct bt_port *bt_connection_get_upstream_port(
+ struct bt_connection *connection);
+int bt_connection_is_ended(struct bt_connection *connection);
+
+/* Functions (private) */
+struct bt_connection *bt_connection_from_private_connection(
+ struct bt_private_connection *private_connection);
+
+/* Helper functions for Python */
+%typemap(out) struct bt_py3_create_notif_iter_ret {
+ $result = PyTuple_New(2);
+ PyObject *py_notif_iter_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr($1.notif_iter),
+ SWIGTYPE_p_bt_notification_iterator, 0);
+ PyObject *py_status = SWIG_From_long_SS_long($1.status);
+ PyTuple_SET_ITEM($result, 0, py_status);
+ PyTuple_SET_ITEM($result, 1, py_notif_iter_ptr);
+}
+
+%{
+struct bt_py3_create_notif_iter_ret {
+ enum bt_connection_status status;
+ struct bt_notification_iterator *notif_iter;
+};
+
+static struct bt_py3_create_notif_iter_ret bt_py3_create_notif_iter(
+ unsigned long long priv_conn_addr, PyObject *py_notif_types)
+{
+ struct bt_private_connection *priv_conn;
+ enum bt_notification_type *notification_types = NULL;
+ struct bt_py3_create_notif_iter_ret ret;
+
+ priv_conn = (void *) priv_conn_addr;
+ assert(!PyErr_Occurred());
+ assert(priv_conn);
+
+ if (py_notif_types != Py_None) {
+ size_t i;
+
+ assert(PyList_Check(py_notif_types));
+ notification_types = g_new0(enum bt_notification_type,
+ PyList_Size(py_notif_types) + 1);
+ assert(notification_types);
+ notification_types[PyList_Size(py_notif_types)] =
+ BT_NOTIFICATION_TYPE_SENTINEL;
+
+ for (i = 0; i < PyList_Size(py_notif_types); i++) {
+ PyObject *item = PyList_GetItem(py_notif_types, i);
+ long value;
+ int overflow;
+
+ assert(item);
+ assert(PyLong_Check(item));
+ value = PyLong_AsLongAndOverflow(item, &overflow);
+ assert(overflow == 0);
+ notification_types[i] = value;
+ }
+ }
+
+ ret.status = bt_private_connection_create_notification_iterator(
+ priv_conn, notification_types, &ret.notif_iter);
+
+ if (notification_types) {
+ g_free(notification_types);
+ }
+
+ return ret;
+}
+%}
+
+struct bt_py3_create_notif_iter_ret bt_py3_create_notif_iter(
+ unsigned long long priv_conn_addr, PyObject *notif_types);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/ctf-writer/clock.h>
-#include <babeltrace/ctf-writer/stream.h>
-#include <babeltrace/ctf-writer/stream-class.h>
-#include <babeltrace/ctf-writer/writer.h>
-%}
-
/* Types */
struct bt_ctf_clock;
struct bt_ctf_writer;
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/ctf-ir/event.h>
-%}
-
/* Type */
struct bt_ctf_event;
struct bt_ctf_event *event);
int bt_ctf_event_set_event_context(struct bt_ctf_event *event,
struct bt_ctf_field *context);
-struct bt_ctf_field *bt_ctf_event_get_payload_field(
+struct bt_ctf_field *bt_ctf_event_get_event_payload(
struct bt_ctf_event *event);
-int bt_ctf_event_set_payload_field(struct bt_ctf_event *event,
+int bt_ctf_event_set_event_payload(struct bt_ctf_event *event,
struct bt_ctf_field *payload);
struct bt_ctf_clock_value *bt_ctf_event_get_clock_value(
struct bt_ctf_event *event,
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/ctf-ir/event-class.h>
-%}
-
/* Type */
struct bt_ctf_event_class;
+/* Log levels */
+enum bt_ctf_event_class_log_level {
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN = -1,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED = 255,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_EMERGENCY = 0,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_ALERT = 1,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_CRITICAL = 2,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_ERROR = 3,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_WARNING = 4,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_NOTICE = 5,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO = 6,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_SYSTEM = 7,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROGRAM = 8,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_PROCESS = 9,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_MODULE = 10,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_UNIT = 11,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_FUNCTION = 12,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG_LINE = 13,
+ BT_CTF_EVENT_CLASS_LOG_LEVEL_DEBUG = 14,
+};
+
/* Functions */
struct bt_ctf_event_class *bt_ctf_event_class_create(const char *name);
struct bt_ctf_stream_class *bt_ctf_event_class_get_stream_class(
int64_t bt_ctf_event_class_get_id(
struct bt_ctf_event_class *event_class);
int bt_ctf_event_class_set_id(
- struct bt_ctf_event_class *event_class, uint32_t id);
-int bt_ctf_event_class_get_attribute_count(
+ struct bt_ctf_event_class *event_class, uint64_t id);
+enum bt_ctf_event_class_log_level bt_ctf_event_class_get_log_level(
struct bt_ctf_event_class *event_class);
-const char *bt_ctf_event_class_get_attribute_name(
- struct bt_ctf_event_class *event_class, int index);
-struct bt_value *
-bt_ctf_event_class_get_attribute_value_by_name(
- struct bt_ctf_event_class *event_class, const char *name);
-int bt_ctf_event_class_set_attribute(
- struct bt_ctf_event_class *event_class, const char *name,
- struct bt_value *value);
+int bt_ctf_event_class_set_log_level(
+ struct bt_ctf_event_class *event_class,
+ enum bt_ctf_event_class_log_level log_level);
+const char *bt_ctf_event_class_get_emf_uri(
+ struct bt_ctf_event_class *event_class);
+int bt_ctf_event_class_set_emf_uri(
+ struct bt_ctf_event_class *event_class,
+ const char *emf_uri);
struct bt_ctf_field_type *bt_ctf_event_class_get_context_type(
struct bt_ctf_event_class *event_class);
int bt_ctf_event_class_set_context_type(
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/ctf-ir/fields.h>
-%}
-
/* Type */
struct bt_ctf_field;
/* Structure field functions */
struct bt_ctf_field *bt_ctf_field_structure_get_field_by_index(
struct bt_ctf_field *structure, int index);
-struct bt_ctf_field *bt_ctf_field_structure_get_field(
- struct bt_ctf_field *structure, const char *name);
+struct bt_ctf_field *bt_ctf_field_structure_get_field_by_name(
+ struct bt_ctf_field *struct_field, const char *name);
+int bt_ctf_field_structure_set_field_by_name(struct bt_ctf_field *struct_field,
+ const char *name, struct bt_ctf_field *field);
/* Array field functions */
struct bt_ctf_field *bt_ctf_field_array_get_field(
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/ctf-ir/field-types.h>
-%}
-
/* Type */
struct bt_ctf_field_type;
BT_CTF_SCOPE_EVENT_FIELDS = 6,
};
-enum bt_ctf_type_id {
- BT_CTF_TYPE_ID_UNKNOWN = CTF_TYPE_UNKNOWN,
- BT_CTF_TYPE_ID_INTEGER = CTF_TYPE_INTEGER,
- BT_CTF_TYPE_ID_FLOAT = CTF_TYPE_FLOAT,
- BT_CTF_TYPE_ID_ENUM = CTF_TYPE_ENUM,
- BT_CTF_TYPE_ID_STRING = CTF_TYPE_STRING,
- BT_CTF_TYPE_ID_STRUCT = CTF_TYPE_STRUCT,
- BT_CTF_TYPE_ID_UNTAGGED_VARIANT = CTF_TYPE_UNTAGGED_VARIANT,
- BT_CTF_TYPE_ID_ARRAY = CTF_TYPE_ARRAY,
- BT_CTF_TYPE_ID_SEQUENCE = CTF_TYPE_SEQUENCE,
- BT_CTF_TYPE_ID_VARIANT = CTF_TYPE_VARIANT,
+enum bt_ctf_field_type_id {
+ BT_CTF_FIELD_TYPE_ID_UNKNOWN = CTF_TYPE_UNKNOWN,
+ BT_CTF_FIELD_TYPE_ID_INTEGER = CTF_TYPE_INTEGER,
+ BT_CTF_FIELD_TYPE_ID_FLOAT = CTF_TYPE_FLOAT,
+ BT_CTF_FIELD_TYPE_ID_ENUM = CTF_TYPE_ENUM,
+ BT_CTF_FIELD_TYPE_ID_STRING = CTF_TYPE_STRING,
+ BT_CTF_FIELD_TYPE_ID_STRUCT = CTF_TYPE_STRUCT,
+ BT_CTF_FIELD_TYPE_ID_ARRAY = CTF_TYPE_ARRAY,
+ BT_CTF_FIELD_TYPE_ID_SEQUENCE = CTF_TYPE_SEQUENCE,
+ BT_CTF_FIELD_TYPE_ID_VARIANT = CTF_TYPE_VARIANT,
BT_CTF_NR_TYPE_IDS = NR_CTF_TYPES,
};
enum bt_ctf_byte_order {
BT_CTF_BYTE_ORDER_UNKNOWN = -1,
BT_CTF_BYTE_ORDER_NATIVE = 0,
+ BT_CTF_BYTE_ORDER_UNSPECIFIED,
BT_CTF_BYTE_ORDER_LITTLE_ENDIAN,
BT_CTF_BYTE_ORDER_BIG_ENDIAN,
BT_CTF_BYTE_ORDER_NETWORK,
};
/* Common functions */
-enum bt_ctf_type_id bt_ctf_field_type_get_type_id(
+enum bt_ctf_field_type_id bt_ctf_field_type_get_type_id(
struct bt_ctf_field_type *field_type);
int bt_ctf_field_type_get_alignment(
struct bt_ctf_field_type *field_type);
unsigned int size);
int bt_ctf_field_type_integer_get_size(
struct bt_ctf_field_type *int_field_type);
-int bt_ctf_field_type_integer_get_signed(
+int bt_ctf_field_type_integer_set_size(
+ struct bt_ctf_field_type *int_field_type, unsigned int size);
+int bt_ctf_field_type_integer_is_signed(
struct bt_ctf_field_type *int_field_type);
-int bt_ctf_field_type_integer_set_signed(
+int bt_ctf_field_type_integer_set_is_signed(
struct bt_ctf_field_type *int_field_type, int is_signed);
enum bt_ctf_integer_base bt_ctf_field_type_integer_get_base(
struct bt_ctf_field_type *int_field_type);
struct bt_ctf_field_type *int_field_type);
struct bt_ctf_field_type *bt_ctf_field_type_enumeration_get_container_type(
struct bt_ctf_field_type *enum_field_type);
-int bt_ctf_field_type_enumeration_get_mapping_count(
+int64_t bt_ctf_field_type_enumeration_get_mapping_count(
struct bt_ctf_field_type *enum_field_type);
int bt_ctf_field_type_enumeration_get_mapping_signed(
struct bt_ctf_field_type *enum_field_type, int index,
struct bt_ctf_field_type *enum_field_type, int index,
const char **BTOUTSTR, uint64_t *OUTPUT,
uint64_t *OUTPUT);
-int bt_ctf_field_type_enumeration_add_mapping(
+int bt_ctf_field_type_enumeration_add_mapping_signed(
struct bt_ctf_field_type *enum_field_type, const char *name,
int64_t range_begin, int64_t range_end);
int bt_ctf_field_type_enumeration_add_mapping_unsigned(
const char **BTOUTSTR, int64_t *OUTPUT, int64_t *OUTPUT);
int bt_ctf_field_type_enumeration_mapping_iterator_get_unsigned(
struct bt_ctf_field_type_enumeration_mapping_iterator *iter,
- const char **BTOUTSTR, int64_t *OUTPUT, int64_t *OUTPUT);
+ const char **BTOUTSTR, uint64_t *OUTPUT, uint64_t *OUTPUT);
int bt_ctf_field_type_enumeration_mapping_iterator_next(
struct bt_ctf_field_type_enumeration_mapping_iterator *iter);
/* Structure field type functions */
struct bt_ctf_field_type *bt_ctf_field_type_structure_create(void);
-int bt_ctf_field_type_structure_get_field_count(
+int64_t bt_ctf_field_type_structure_get_field_count(
struct bt_ctf_field_type *struct_field_type);
-int bt_ctf_field_type_structure_get_field(
+int bt_ctf_field_type_structure_get_field_by_index(
struct bt_ctf_field_type *struct_field_type,
const char **BTOUTSTR, struct bt_ctf_field_type **BTOUTFT,
- int index);
+ uint64_t index);
struct bt_ctf_field_type *bt_ctf_field_type_structure_get_field_type_by_name(
struct bt_ctf_field_type *struct_field_type,
const char *field_name);
struct bt_ctf_field_type *array_field_type);
/* Sequence field type functions */
-extern struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
+struct bt_ctf_field_type *bt_ctf_field_type_sequence_create(
struct bt_ctf_field_type *element_field_type,
const char *length_name);
-extern struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
+struct bt_ctf_field_type *bt_ctf_field_type_sequence_get_element_type(
struct bt_ctf_field_type *sequence_field_type);
-extern const char *bt_ctf_field_type_sequence_get_length_field_name(
+const char *bt_ctf_field_type_sequence_get_length_field_name(
struct bt_ctf_field_type *sequence_field_type);
-extern struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
+struct bt_ctf_field_path *bt_ctf_field_type_sequence_get_length_field_path(
struct bt_ctf_field_type *sequence_field_type);
/* Variant field type functions */
const char *tag_name);
struct bt_ctf_field_path *bt_ctf_field_type_variant_get_tag_field_path(
struct bt_ctf_field_type *variant_field_type);
-int bt_ctf_field_type_variant_get_field_count(
+int64_t bt_ctf_field_type_variant_get_field_count(
struct bt_ctf_field_type *variant_field_type);
-int bt_ctf_field_type_variant_get_field(
+int bt_ctf_field_type_variant_get_field_by_index(
struct bt_ctf_field_type *variant_field_type,
const char **BTOUTSTR,
- struct bt_ctf_field_type **BTOUTFT, int index);
+ struct bt_ctf_field_type **BTOUTFT, uint64_t index);
struct bt_ctf_field_type *bt_ctf_field_type_variant_get_field_type_by_name(
struct bt_ctf_field_type *variant_field_type,
const char *field_name);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Types */
+struct bt_graph;
+
+/* Status */
+enum bt_graph_status {
+ BT_GRAPH_STATUS_COMPONENT_REFUSES_PORT_CONNECTION = 111,
+ BT_GRAPH_STATUS_CANCELED = 125,
+ BT_GRAPH_STATUS_AGAIN = 11,
+ BT_GRAPH_STATUS_END = 1,
+ BT_GRAPH_STATUS_OK = 0,
+ BT_GRAPH_STATUS_INVALID = -22,
+ BT_GRAPH_STATUS_NO_SINK = -6,
+ BT_GRAPH_STATUS_ERROR = -1,
+ BT_GRAPH_STATUS_NOMEM = -12,
+};
+
+/* Functions */
+struct bt_graph *bt_graph_create(void);
+enum bt_graph_status bt_graph_add_component(
+ struct bt_graph *graph,
+ struct bt_component_class *component_class,
+ const char *name, struct bt_value *params,
+ struct bt_component **BTOUTCOMP);
+enum bt_graph_status bt_graph_add_component_with_init_method_data(
+ struct bt_graph *graph,
+ struct bt_component_class *component_class,
+ const char *name, struct bt_value *params,
+ void *init_method_data,
+ struct bt_component **BTOUTCOMP);
+enum bt_graph_status bt_graph_connect_ports(struct bt_graph *graph,
+ struct bt_port *upstream, struct bt_port *downstream,
+ struct bt_connection **BTOUTCONN);
+enum bt_graph_status bt_graph_run(struct bt_graph *graph);
+enum bt_graph_status bt_graph_consume(struct bt_graph *graph);
+enum bt_graph_status bt_graph_cancel(struct bt_graph *graph);
+int bt_graph_is_canceled(struct bt_graph *graph);
+
+/* Helper functions for Python */
+%{
+static void port_added_listener(struct bt_port *port, void *py_callable)
+{
+ PyObject *py_port_ptr = NULL;
+ PyObject *py_res = NULL;
+
+ py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port),
+ SWIGTYPE_p_bt_port, 0);
+ if (!py_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_res = PyObject_CallFunction(py_callable, "(O)", py_port_ptr);
+ assert(py_res == Py_None);
+ Py_DECREF(py_port_ptr);
+ Py_DECREF(py_res);
+}
+
+static void port_removed_listener(struct bt_component *component,
+ struct bt_port *port, void *py_callable)
+{
+ PyObject *py_port_ptr = NULL;
+ PyObject *py_res = NULL;
+
+ py_port_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(port),
+ SWIGTYPE_p_bt_port, 0);
+ if (!py_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_res = PyObject_CallFunction(py_callable, "(O)", py_port_ptr);
+ assert(py_res == Py_None);
+ Py_DECREF(py_port_ptr);
+ Py_DECREF(py_res);
+}
+
+static void ports_connected_listener(struct bt_port *upstream_port,
+ struct bt_port *downstream_port, void *py_callable)
+{
+ PyObject *py_upstream_port_ptr = NULL;
+ PyObject *py_downstream_port_ptr = NULL;
+ PyObject *py_res = NULL;
+
+ py_upstream_port_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port, 0);
+ if (!py_upstream_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_downstream_port_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port, 0);
+ if (!py_downstream_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_res = PyObject_CallFunction(py_callable, "(OO)",
+ py_upstream_port_ptr, py_downstream_port_ptr);
+ assert(py_res == Py_None);
+ Py_DECREF(py_upstream_port_ptr);
+ Py_DECREF(py_downstream_port_ptr);
+ Py_DECREF(py_res);
+}
+
+static void ports_disconnected_listener(
+ struct bt_component *upstream_component,
+ struct bt_component *downstream_component,
+ struct bt_port *upstream_port, struct bt_port *downstream_port,
+ void *py_callable)
+{
+ PyObject *py_upstream_comp_ptr = NULL;
+ PyObject *py_downstream_comp_ptr = NULL;
+ PyObject *py_upstream_port_ptr = NULL;
+ PyObject *py_downstream_port_ptr = NULL;
+ PyObject *py_res = NULL;
+
+ py_upstream_comp_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(upstream_component),
+ SWIGTYPE_p_bt_component, 0);
+ if (!py_upstream_comp_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_downstream_comp_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(downstream_component),
+ SWIGTYPE_p_bt_component, 0);
+ if (!py_downstream_comp_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_upstream_port_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(upstream_port), SWIGTYPE_p_bt_port, 0);
+ if (!py_upstream_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_downstream_port_ptr = SWIG_NewPointerObj(
+ SWIG_as_voidptr(downstream_port), SWIGTYPE_p_bt_port, 0);
+ if (!py_downstream_port_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_res = PyObject_CallFunction(py_callable, "(OOOO)",
+ py_upstream_comp_ptr, py_downstream_comp_ptr,
+ py_upstream_port_ptr, py_downstream_port_ptr);
+ assert(py_res == Py_None);
+ Py_DECREF(py_upstream_comp_ptr);
+ Py_DECREF(py_downstream_comp_ptr);
+ Py_DECREF(py_upstream_port_ptr);
+ Py_DECREF(py_downstream_port_ptr);
+ Py_DECREF(py_res);
+}
+
+static void graph_listener_removed(void *py_callable)
+{
+ assert(py_callable);
+ Py_DECREF(py_callable);
+}
+
+static int bt_py3_graph_add_port_added_listener(struct bt_graph *graph,
+ PyObject *py_callable)
+{
+ int ret = 0;
+
+ assert(graph);
+ assert(py_callable);
+ ret = bt_graph_add_port_added_listener(graph, port_added_listener,
+ graph_listener_removed, py_callable);
+ if (ret >= 0) {
+ Py_INCREF(py_callable);
+ }
+
+ return ret;
+}
+
+static int bt_py3_graph_add_port_removed_listener(struct bt_graph *graph,
+ PyObject *py_callable)
+{
+ int ret = 0;
+
+ assert(graph);
+ assert(py_callable);
+ ret = bt_graph_add_port_removed_listener(graph, port_removed_listener,
+ graph_listener_removed, py_callable);
+ if (ret >= 0) {
+ Py_INCREF(py_callable);
+ }
+
+ return ret;
+}
+
+static int bt_py3_graph_add_ports_connected_listener(struct bt_graph *graph,
+ PyObject *py_callable)
+{
+ int ret = 0;
+
+ assert(graph);
+ assert(py_callable);
+ ret = bt_graph_add_ports_connected_listener(graph,
+ ports_connected_listener, graph_listener_removed, py_callable);
+ if (ret >= 0) {
+ Py_INCREF(py_callable);
+ }
+
+ return ret;
+}
+
+static int bt_py3_graph_add_ports_disconnected_listener(struct bt_graph *graph,
+ PyObject *py_callable)
+{
+ int ret = 0;
+
+ assert(graph);
+ assert(py_callable);
+ ret = bt_graph_add_ports_disconnected_listener(graph,
+ ports_disconnected_listener, graph_listener_removed,
+ py_callable);
+ if (ret >= 0) {
+ Py_INCREF(py_callable);
+ }
+
+ return ret;
+}
+%}
+
+int bt_py3_graph_add_port_added_listener(struct bt_graph *graph,
+ PyObject *py_callable);
+int bt_py3_graph_add_port_removed_listener(struct bt_graph *graph,
+ PyObject *py_callable);
+int bt_py3_graph_add_ports_connected_listener(struct bt_graph *graph,
+ PyObject *py_callable);
+int bt_py3_graph_add_ports_disconnected_listener(struct bt_graph *graph,
+ PyObject *py_callable);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+%{
+#include <babeltrace/logging.h>
+%}
+
+/* Log levels */
+enum bt_logging_level {
+ BT_LOGGING_LEVEL_VERBOSE = 1,
+ BT_LOGGING_LEVEL_DEBUG = 2,
+ BT_LOGGING_LEVEL_INFO = 3,
+ BT_LOGGING_LEVEL_WARN = 4,
+ BT_LOGGING_LEVEL_ERROR = 5,
+ BT_LOGGING_LEVEL_FATAL = 6,
+ BT_LOGGING_LEVEL_NONE = 0xff,
+};
+
+/* Logging functions */
+enum bt_logging_level bt_logging_get_minimal_level(void);
+enum bt_logging_level bt_logging_get_global_level(void);
+void bt_logging_set_global_level(enum bt_logging_level log_level);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/component/notification/event.h>
-#include <babeltrace/component/notification/packet.h>
-#include <babeltrace/component/notification/schema.h>
-#include <babeltrace/component/notification/stream.h>
-%}
-
/* Type */
-struct bt_notification;;
+struct bt_notification;
/* Notification type */
enum bt_notification_type {
+ BT_NOTIFICATION_TYPE_SENTINEL = -1000,
BT_NOTIFICATION_TYPE_UNKNOWN = -1,
- BT_NOTIFICATION_TYPE_ALL = 0,
- BT_NOTIFICATION_TYPE_EVENT = 1,
- BT_NOTIFICATION_TYPE_PACKET_BEGIN = 2,
- BT_NOTIFICATION_TYPE_PACKET_END = 3,
- BT_NOTIFICATION_TYPE_STREAM_END = 4,
- BT_NOTIFICATION_TYPE_NEW_TRACE = 5,
- BT_NOTIFICATION_TYPE_NEW_STREAM_CLASS = 6,
- BT_NOTIFICATION_TYPE_NEW_EVENT_CLASS = 7,
- BT_NOTIFICATION_TYPE_END_OF_TRACE = 8,
- BT_NOTIFICATION_TYPE_NR,
+ BT_NOTIFICATION_TYPE_ALL = -2,
+ BT_NOTIFICATION_TYPE_EVENT = 0,
+ BT_NOTIFICATION_TYPE_INACTIVITY = 1,
+ BT_NOTIFICATION_TYPE_STREAM_BEGIN = 2,
+ BT_NOTIFICATION_TYPE_STREAM_END = 3,
+ BT_NOTIFICATION_TYPE_PACKET_BEGIN = 4,
+ BT_NOTIFICATION_TYPE_PACKET_END = 5,
+ BT_NOTIFICATION_TYPE_DISCARDED_EVENTS = 6,
+ BT_NOTIFICATION_TYPE_DISCARDED_PACKETS = 7,
};
/* General functions */
/* Event notification functions */
struct bt_notification *bt_notification_event_create(
- struct bt_ctf_event *event);
+ struct bt_ctf_event *event,
+ struct bt_clock_class_priority_map *clock_class_priority_map);
struct bt_ctf_event *bt_notification_event_get_event(
struct bt_notification *notification);
+struct bt_clock_class_priority_map *
+bt_notification_event_get_clock_class_priority_map(
+ struct bt_notification *notification);
+
+/* Inactivity notification functions */
+struct bt_notification *bt_notification_inactivity_create(
+ struct bt_clock_class_priority_map *clock_class_priority_map);
+struct bt_clock_class_priority_map *
+bt_notification_inactivity_get_clock_class_priority_map(
+ struct bt_notification *notification);
+struct bt_ctf_clock_value *bt_notification_inactivity_get_clock_value(
+ struct bt_notification *notification,
+ struct bt_ctf_clock_class *clock_class);
+int bt_notification_inactivity_set_clock_value(
+ struct bt_notification *notification,
+ struct bt_ctf_clock_value *clock_value);
/* Packet notification functions */
struct bt_notification *bt_notification_packet_begin_create(
struct bt_ctf_packet *packet);
-struct bt_ctf_packet *bt_notification_packet_begin_get_packet(
- struct bt_notification *notification);
struct bt_notification *bt_notification_packet_end_create(
struct bt_ctf_packet *packet);
-struct bt_ctf_packet *bt_notification_packet_end_get_packet(
- struct bt_notification *notification);
-
-/* Schema notification functions */
-/*
-struct bt_notification *bt_notification_new_trace_create(
- struct bt_ctf_trace *trace);
-struct bt_ctf_trace *bt_notification_new_trace_get_trace(
+struct bt_ctf_packet *bt_notification_packet_begin_get_packet(
struct bt_notification *notification);
-struct bt_notification *bt_notification_new_stream_class_create(
- struct bt_ctf_stream_class *stream_class);
-struct bt_ctf_trace *bt_notification_new_stream_class_get_stream_class(
+struct bt_ctf_packet *bt_notification_packet_end_get_packet(
struct bt_notification *notification);
-*/
/* Stream notification functions */
+struct bt_notification *bt_notification_stream_begin_create(
+ struct bt_ctf_stream *stream);
struct bt_notification *bt_notification_stream_end_create(
struct bt_ctf_stream *stream);
+struct bt_ctf_stream *bt_notification_stream_begin_get_stream(
+ struct bt_notification *notification);
struct bt_ctf_stream *bt_notification_stream_end_get_stream(
struct bt_notification *notification);
+
+/* Discarded packets notification functions */
+struct bt_ctf_clock_value *
+bt_notification_discarded_packets_get_begin_clock_value(
+ struct bt_notification *notification);
+struct bt_ctf_clock_value *
+bt_notification_discarded_packets_get_end_clock_value(
+ struct bt_notification *notification);
+int64_t bt_notification_discarded_packets_get_count(
+ struct bt_notification *notification);
+struct bt_ctf_stream *bt_notification_discarded_packets_get_stream(
+ struct bt_notification *notification);
+
+/* Discarded events notification functions */
+struct bt_ctf_clock_value *
+bt_notification_discarded_events_get_begin_clock_value(
+ struct bt_notification *notification);
+struct bt_ctf_clock_value *
+bt_notification_discarded_events_get_end_clock_value(
+ struct bt_notification *notification);
+int64_t bt_notification_discarded_events_get_count(
+ struct bt_notification *notification);
+struct bt_ctf_stream *bt_notification_discarded_events_get_stream(
+ struct bt_notification *notification);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/component/notification/iterator.h>
-%}
-
/* Type */
struct bt_notification_iterator;
/* Status */
enum bt_notification_iterator_status {
+ BT_NOTIFICATION_ITERATOR_STATUS_CANCELED = 125,
+ BT_NOTIFICATION_ITERATOR_STATUS_AGAIN = 11,
BT_NOTIFICATION_ITERATOR_STATUS_END = 1,
BT_NOTIFICATION_ITERATOR_STATUS_OK = 0,
- BT_NOTIFICATION_ITERATOR_STATUS_INVAL = -1,
- BT_NOTIFICATION_ITERATOR_STATUS_ERROR = -2,
- BT_NOTIFICATION_ITERATOR_STATUS_NOMEM = -3,
- BT_NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED = -4,
-};
-
-/* Seek reference */
-enum bt_notification_iterator_seek_origin {
- BT_NOTIFICATION_ITERATOR_SEEK_ORIGIN_BEGIN = 0,
- BT_NOTIFICATION_ITERATOR_SEEK_ORIGIN_CURRENT = 1,
- BT_NOTIFICATION_ITERATOR_SEEK_ORIGIN_END = 2,
- BT_NOTIFICATION_ITERATOR_SEEK_ORIGIN_EPOCH = 3,
+ BT_NOTIFICATION_ITERATOR_STATUS_INVALID = -22,
+ BT_NOTIFICATION_ITERATOR_STATUS_ERROR = -1,
+ BT_NOTIFICATION_ITERATOR_STATUS_NOMEM = -12,
+ BT_NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED = -2,
};
/* Functions */
struct bt_notification_iterator *iterator);
enum bt_notification_iterator_status bt_notification_iterator_next(
struct bt_notification_iterator *iterator);
-enum bt_notification_iterator_status bt_notification_iterator_seek_time(
- struct bt_notification_iterator *iterator,
- enum bt_notification_iterator_seek_origin seek_origin,
- int64_t time);
struct bt_component *bt_notification_iterator_get_component(
struct bt_notification_iterator *iterator);
-enum bt_notification_iterator_status bt_notification_iterator_set_private_data(
- struct bt_notification_iterator *iterator, void *data);
-void *bt_notification_iterator_get_private_data(
- struct bt_notification_iterator *iterator);
/* Helper functions for Python */
%{
-static PyObject *bt_py3_get_component_from_notif_iter(
- struct bt_notification_iterator *iter)
+static PyObject *bt_py3_get_user_component_from_user_notif_iter(
+ struct bt_private_notification_iterator *priv_notif_iter)
{
- struct bt_component *component = bt_notification_iterator_get_component(iter);
+ struct bt_private_component *priv_comp =
+ bt_private_notification_iterator_get_private_component(
+ priv_notif_iter);
PyObject *py_comp;
- assert(component);
- py_comp = bt_component_get_private_data(component);
- BT_PUT(component);
+ assert(priv_comp);
+ py_comp = bt_private_component_get_user_data(priv_comp);
+ bt_put(priv_comp);
assert(py_comp);
/* Return new reference */
}
%}
-PyObject *bt_py3_get_component_from_notif_iter(
- struct bt_notification_iterator *iter);
+PyObject *bt_py3_get_user_component_from_user_notif_iter(
+ struct bt_private_notification_iterator *priv_notif_iter);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/ctf-ir/packet.h>
-%}
-
/* Type */
struct bt_ctf_packet;
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/plugin/plugin.h>
-#include <assert.h>
-%}
-
/* Types */
struct bt_plugin;
+struct bt_plugin_set;
/* Status */
enum bt_plugin_status {
- BT_PLUGIN_STATUS_OK = 0,
- BT_PLUGIN_STATUS_ERROR = -1,
- BT_PLUGIN_STATUS_NOMEM = -4,
+ BT_PLUGIN_STATUS_OK = 0,
+ BT_PLUGIN_STATUS_ERROR = -1,
+ BT_PLUGIN_STATUS_NOMEM = -4,
};
-/* Functions */
+/* Plugin functions */
+struct bt_plugin *bt_plugin_find(const char *plugin_name);
+struct bt_component_class *bt_plugin_find_component_class(
+ const char *plugin_name, const char *component_class_name,
+ enum bt_component_class_type component_class_type);
+struct bt_plugin_set *bt_plugin_create_all_from_file(const char *path);
+struct bt_plugin_set *bt_plugin_create_all_from_dir(const char *path,
+ int recurse);
+struct bt_plugin_set *bt_plugin_create_all_from_static(void);
const char *bt_plugin_get_name(struct bt_plugin *plugin);
const char *bt_plugin_get_author(struct bt_plugin *plugin);
const char *bt_plugin_get_license(struct bt_plugin *plugin);
const char *bt_plugin_get_description(struct bt_plugin *plugin);
const char *bt_plugin_get_path(struct bt_plugin *plugin);
enum bt_plugin_status bt_plugin_get_version(struct bt_plugin *plugin,
- unsigned int *OUTPUT, unsigned int *OUTPUT, unsigned int *OUTPUT,
- const char **BTOUTSTR);
-int bt_plugin_get_component_class_count(struct bt_plugin *plugin);
-struct bt_component_class *bt_plugin_get_component_class(
- struct bt_plugin *plugin, size_t index);
+ unsigned int *OUTPUTINIT, unsigned int *OUTPUTINIT,
+ unsigned int *OUTPUTINIT, const char **BTOUTSTR);
+int64_t bt_plugin_get_component_class_count(struct bt_plugin *plugin);
+struct bt_component_class *bt_plugin_get_component_class_by_index(
+ struct bt_plugin *plugin, uint64_t index);
struct bt_component_class *bt_plugin_get_component_class_by_name_and_type(
struct bt_plugin *plugin, const char *name,
enum bt_component_class_type type);
-struct bt_plugin *bt_plugin_create_from_name(const char *plugin_name);
-
-%{
-static PyObject *bt_py3_plugin_ptrs_list_from_bt_plugins(struct bt_plugin **plugins)
-{
- PyObject *py_plugin_ptrs = NULL;
- struct bt_plugin **plugin_at;
-
- if (!plugins) {
- goto error;
- }
-
- py_plugin_ptrs = PyList_New(0);
- if (!py_plugin_ptrs) {
- goto error;
- }
-
- plugin_at = plugins;
-
- while (*plugin_at) {
- struct bt_plugin *plugin = *plugin_at;
- PyObject *py_plugin_ptr;
- int ret;
-
- py_plugin_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(plugin),
- SWIGTYPE_p_bt_plugin, 0);
- if (!py_plugin_ptr) {
- goto error;
- }
-
- ret = PyList_Append(py_plugin_ptrs, py_plugin_ptr);
- Py_DECREF(py_plugin_ptr);
- if (ret < 0) {
- goto error;
- }
-
- plugin_at++;
- }
-
- goto end;
-
-error:
- Py_XDECREF(py_plugin_ptrs);
- py_plugin_ptrs = Py_None;
- Py_INCREF(py_plugin_ptrs);
-
- if (plugins) {
- /*
- * Put existing plugin references since they are not
- * moved to the caller.
- */
- plugin_at = plugins;
-
- while (*plugin_at) {
- bt_put(*plugin_at);
- plugin_at++;
- }
- }
-
-end:
- PyErr_Clear();
- free(plugins);
- return py_plugin_ptrs;
-}
-
-static PyObject *bt_py3_plugin_create_all_from_file(const char *path)
-{
- return bt_py3_plugin_ptrs_list_from_bt_plugins(
- bt_plugin_create_all_from_file(path));
-}
-
-static PyObject *bt_py3_plugin_create_all_from_dir(const char *path,
- bool recurse)
-{
- return bt_py3_plugin_ptrs_list_from_bt_plugins(
- bt_plugin_create_all_from_dir(path, recurse));
-}
-%}
-PyObject *bt_py3_plugin_create_all_from_file(const char *path);
-PyObject *bt_py3_plugin_create_all_from_dir(const char *path,
- bool recurse);
+/* Plugin set functions */
+int64_t bt_plugin_set_get_plugin_count(struct bt_plugin_set *plugin_set);
+struct bt_plugin *bt_plugin_set_get_plugin(struct bt_plugin_set *plugin_set,
+ uint64_t index);
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+/* Type */
+struct bt_port;
+struct bt_private_port;
+
+/* Status */
+enum bt_port_status {
+ BT_PORT_STATUS_OK = 0,
+ BT_PORT_STATUS_ERROR = -1,
+ BT_PORT_STATUS_INVALID = -2,
+};
+
+/* Port type */
+enum bt_port_type {
+ BT_PORT_TYPE_INPUT = 0,
+ BT_PORT_TYPE_OUTPUT = 1,
+ BT_PORT_TYPE_UNKOWN = -1,
+};
+
+/* Functions (public) */
+const char *bt_port_get_name(struct bt_port *port);
+enum bt_port_type bt_port_get_type(struct bt_port *port);
+struct bt_connection *bt_port_get_connection(struct bt_port *port);
+struct bt_component *bt_port_get_component(struct bt_port *port);
+enum bt_port_status bt_port_disconnect(struct bt_port *port);
+int bt_port_is_connected(struct bt_port *port);
+
+/* Functions (private) */
+struct bt_port *bt_port_from_private_port(struct bt_private_port *private_port);
+struct bt_private_connection *bt_private_port_get_private_connection(
+ struct bt_private_port *private_port);
+struct bt_private_component *bt_private_port_get_private_component(
+ struct bt_private_port *private_port);
+enum bt_port_status bt_private_port_remove_from_component(
+ struct bt_private_port *private_port);
+void *bt_private_port_get_user_data(
+ struct bt_private_port *private_port);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/ref.h>
-%}
-
/* Functions */
void *bt_get(void *obj);
void bt_put(void *obj);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/ctf-ir/stream.h>
-%}
-
/* Type */
struct bt_ctf_stream;
struct bt_ctf_stream *bt_ctf_stream_create(
struct bt_ctf_stream_class *stream_class,
const char *name);
+struct bt_ctf_stream *bt_ctf_stream_create_with_id(
+ struct bt_ctf_stream_class *stream_class,
+ const char *name, uint64_t id);
const char *bt_ctf_stream_get_name(struct bt_ctf_stream *stream);
+int64_t bt_ctf_stream_get_id(struct bt_ctf_stream *stream);
struct bt_ctf_stream_class *bt_ctf_stream_get_class(
struct bt_ctf_stream *stream);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/ctf-ir/stream-class.h>
-%}
-
/* Type */
struct bt_ctf_stream_class;
/* Functions */
+struct bt_ctf_stream_class *bt_ctf_stream_class_create_empty(
+ const char *name);
struct bt_ctf_stream_class *bt_ctf_stream_class_create(const char *name);
struct bt_ctf_trace *bt_ctf_stream_class_get_trace(
struct bt_ctf_stream_class *stream_class);
int64_t bt_ctf_stream_class_get_id(
struct bt_ctf_stream_class *stream_class);
int bt_ctf_stream_class_set_id(
- struct bt_ctf_stream_class *stream_class, uint32_t id);
+ struct bt_ctf_stream_class *stream_class, uint64_t id);
struct bt_ctf_field_type *bt_ctf_stream_class_get_packet_context_type(
struct bt_ctf_stream_class *stream_class);
int bt_ctf_stream_class_set_packet_context_type(
int bt_ctf_stream_class_set_event_context_type(
struct bt_ctf_stream_class *stream_class,
struct bt_ctf_field_type *event_context_type);
-int bt_ctf_stream_class_get_event_class_count(
+int64_t bt_ctf_stream_class_get_event_class_count(
struct bt_ctf_stream_class *stream_class);
-struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class(
- struct bt_ctf_stream_class *stream_class, int index);
-struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_name(
- struct bt_ctf_stream_class *stream_class, const char *name);
+struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_index(
+ struct bt_ctf_stream_class *stream_class, uint64_t index);
struct bt_ctf_event_class *bt_ctf_stream_class_get_event_class_by_id(
- struct bt_ctf_stream_class *stream_class, uint32_t id);
+ struct bt_ctf_stream_class *stream_class, uint64_t id);
int bt_ctf_stream_class_add_event_class(
struct bt_ctf_stream_class *stream_class,
struct bt_ctf_event_class *event_class);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/ctf-ir/trace.h>
-%}
-
/* Type */
struct bt_ctf_trace;
/* Functions */
struct bt_ctf_trace *bt_ctf_trace_create(void);
-const char *bt_ctf_trace_get_name(struct bt_ctf_trace *trace);
-int bt_ctf_trace_set_name(struct bt_ctf_trace *trace,
+const char *bt_ctf_trace_get_name(struct bt_ctf_trace *trace_class);
+int bt_ctf_trace_set_name(struct bt_ctf_trace *trace_class,
const char *name);
-enum bt_ctf_byte_order bt_ctf_trace_get_byte_order(
- struct bt_ctf_trace *trace);
-int bt_ctf_trace_set_byte_order(struct bt_ctf_trace *trace,
- enum bt_ctf_byte_order byte_order);
-int bt_ctf_trace_get_environment_field_count(
- struct bt_ctf_trace *trace);
+enum bt_ctf_byte_order bt_ctf_trace_get_native_byte_order(
+ struct bt_ctf_trace *trace_class);
+int bt_ctf_trace_set_native_byte_order(struct bt_ctf_trace *trace_class,
+ enum bt_ctf_byte_order native_byte_order);
+BTUUID bt_ctf_trace_get_uuid(
+ struct bt_ctf_trace *trace_class);
+int bt_ctf_trace_set_uuid(struct bt_ctf_trace *trace_class,
+ BTUUID uuid);
+int64_t bt_ctf_trace_get_environment_field_count(
+ struct bt_ctf_trace *trace_class);
const char *
-bt_ctf_trace_get_environment_field_name(struct bt_ctf_trace *trace,
- int index);
+bt_ctf_trace_get_environment_field_name_by_index(
+ struct bt_ctf_trace *trace_class, uint64_t index);
struct bt_value *
-bt_ctf_trace_get_environment_field_value(struct bt_ctf_trace *trace,
- int index);
+bt_ctf_trace_get_environment_field_value_by_index(struct bt_ctf_trace *trace_class,
+ uint64_t index);
struct bt_value *
bt_ctf_trace_get_environment_field_value_by_name(
- struct bt_ctf_trace *trace, const char *name);
+ struct bt_ctf_trace *trace_class, const char *name);
int bt_ctf_trace_set_environment_field(
- struct bt_ctf_trace *trace, const char *name,
+ struct bt_ctf_trace *trace_class, const char *name,
struct bt_value *value);
struct bt_ctf_field_type *bt_ctf_trace_get_packet_header_type(
- struct bt_ctf_trace *trace);
-int bt_ctf_trace_set_packet_header_type(struct bt_ctf_trace *trace,
+ struct bt_ctf_trace *trace_class);
+int bt_ctf_trace_set_packet_header_type(struct bt_ctf_trace *trace_class,
struct bt_ctf_field_type *packet_header_type);
-int bt_ctf_trace_get_clock_class_count(struct bt_ctf_trace *trace);
-struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class(
- struct bt_ctf_trace *trace, int index);
+int64_t bt_ctf_trace_get_clock_class_count(
+ struct bt_ctf_trace *trace_class);
+struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_index(
+ struct bt_ctf_trace *trace_class, uint64_t index);
struct bt_ctf_clock_class *bt_ctf_trace_get_clock_class_by_name(
- struct bt_ctf_trace *trace, const char *name);
-int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace,
+ struct bt_ctf_trace *trace_class, const char *name);
+int bt_ctf_trace_add_clock_class(struct bt_ctf_trace *trace_class,
struct bt_ctf_clock_class *clock_class);
-int bt_ctf_trace_get_stream_class_count(struct bt_ctf_trace *trace);
-struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class(
- struct bt_ctf_trace *trace, int index);
+int64_t bt_ctf_trace_get_stream_class_count(
+ struct bt_ctf_trace *trace_class);
+struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_index(
+ struct bt_ctf_trace *trace_class, uint64_t index);
struct bt_ctf_stream_class *bt_ctf_trace_get_stream_class_by_id(
- struct bt_ctf_trace *trace, uint32_t id);
-int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace,
+ struct bt_ctf_trace *trace_class, uint64_t id);
+int bt_ctf_trace_add_stream_class(struct bt_ctf_trace *trace_class,
struct bt_ctf_stream_class *stream_class);
+int64_t bt_ctf_trace_get_stream_count(struct bt_ctf_trace *trace_class);
+struct bt_ctf_stream *bt_ctf_trace_get_stream_by_index(
+ struct bt_ctf_trace *trace_class, uint64_t index);
+int bt_ctf_trace_is_static(struct bt_ctf_trace *trace_class);
+int bt_ctf_trace_set_is_static(struct bt_ctf_trace *trace_class);
+
+/* Helper functions for Python */
+%{
+void trace_is_static_listener(struct bt_ctf_trace *trace, void *py_callable)
+{
+ PyObject *py_trace_ptr = NULL;
+ PyObject *py_res = NULL;
+
+ py_trace_ptr = SWIG_NewPointerObj(SWIG_as_voidptr(trace),
+ SWIGTYPE_p_bt_ctf_trace, 0);
+ if (!py_trace_ptr) {
+ BT_LOGF_STR("Failed to create a SWIG pointer object.");
+ abort();
+ }
+
+ py_res = PyObject_CallFunction(py_callable, "(O)", py_trace_ptr);
+ assert(py_res == Py_None);
+ Py_DECREF(py_trace_ptr);
+ Py_DECREF(py_res);
+}
+
+void trace_listener_removed(struct bt_ctf_trace *trace, void *py_callable)
+{
+ assert(py_callable);
+ Py_DECREF(py_callable);
+}
+
+static int bt_py3_trace_add_is_staitc_listener(unsigned long long trace_addr,
+ PyObject *py_callable)
+{
+ struct bt_ctf_trace *trace = (void *) trace_addr;
+ int ret = 0;
+
+ assert(trace);
+ assert(py_callable);
+ ret = bt_ctf_trace_add_is_static_listener(trace,
+ trace_is_static_listener, trace_listener_removed, py_callable);
+ if (ret >= 0) {
+ Py_INCREF(py_callable);
+ }
+
+ return ret;
+}
+%}
+
+int bt_py3_trace_add_is_staitc_listener(unsigned long long trace_addr,
+ PyObject *py_callable);
* THE SOFTWARE.
*/
-%{
-#include <babeltrace/values.h>
-%}
-
-/* For uint*_t/int*_t */
-%include "stdint.i"
-
/* Remove prefix from `bt_value_null` */
%rename(value_null) bt_value_null;
/* Common functions */
enum bt_value_status bt_value_freeze(struct bt_value *object);
-bool bt_value_is_frozen(const struct bt_value *object);
+int bt_value_is_frozen(const struct bt_value *object);
struct bt_value *bt_value_copy(const struct bt_value *object);
-bool bt_value_compare(const struct bt_value *object_a,
+int bt_value_compare(const struct bt_value *object_a,
const struct bt_value *object_b);
/* Boolean value object functions */
struct bt_value *bt_value_bool_create(void);
-struct bt_value *bt_value_bool_create_init(bool val);
+struct bt_value *bt_value_bool_create_init(int val);
enum bt_value_status bt_value_bool_get(
- const struct bt_value *bool_obj, bool *OUTPUT);
+ const struct bt_value *bool_obj, int *OUTPUT);
enum bt_value_status bt_value_bool_set(struct bt_value *bool_obj,
- bool val);
+ int val);
/* Integer value object functions */
struct bt_value *bt_value_integer_create(void);
int bt_value_map_size(const struct bt_value *map_obj);
struct bt_value *bt_value_map_get(const struct bt_value *map_obj,
const char *key);
-bool bt_value_map_has_key(const struct bt_value *map_obj,
+int bt_value_map_has_key(const struct bt_value *map_obj,
const char *key);
enum bt_value_status bt_value_map_insert(
struct bt_value *map_obj, const char *key,
struct bt_value *element_obj);
+struct bt_value *bt_value_map_extend(struct bt_value *base_map_obj,
+ struct bt_value *extension_map_obj);
%{
struct bt_value_map_get_keys_private_data {
struct bt_value *keys;
};
-static bool bt_value_map_get_keys_private_cb(const char *key,
+static int bt_value_map_get_keys_private_cb(const char *key,
struct bt_value *object, void *data)
{
enum bt_value_status status;
status = bt_value_array_append_string(priv_data->keys, key);
if (status != BT_VALUE_STATUS_OK) {
- return false;
+ return BT_FALSE;
}
- return true;
+ return BT_TRUE;
}
static struct bt_value *bt_value_map_get_keys_private(
--- /dev/null
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+%{
+#include <babeltrace/version.h>
+%}
+
+/* Version functions */
+int bt_version_get_major(void);
+int bt_version_get_minor(void);
+int bt_version_get_patch(void);
+const char *bt_version_get_extra(void);
# THE SOFTWARE.
from bt2 import native_bt, object, utils
+import bt2.clock_class_priority_map
import bt2.packet
import bt2.stream
import bt2.event
+import copy
import bt2
pass
-class TraceEventNotification(_Notification):
- def __init__(self, event):
+class _CopyableNotification(_Notification):
+ def __copy__(self):
+ return self._copy(lambda obj: obj)
+
+ def __deepcopy__(self, memo):
+ cpy = self._copy(copy.deepcopy)
+ memo[id(self)] = cpy
+ return cpy
+
+
+class EventNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_EVENT
+
+ def __init__(self, event, cc_prio_map=None):
utils._check_type(event, bt2.event._Event)
- ptr = native_bt.notification_event_create(event._ptr)
+
+ if cc_prio_map is not None:
+ utils._check_type(cc_prio_map, bt2.clock_class_priority_map.ClockClassPriorityMap)
+ cc_prio_map_ptr = cc_prio_map._ptr
+ else:
+ cc_prio_map_ptr = None
+
+ ptr = native_bt.notification_event_create(event._ptr, cc_prio_map_ptr)
if ptr is None:
- raise bt2.CreationError('cannot create trace event notification object')
+ raise bt2.CreationError('cannot create event notification object')
super().__init__(ptr)
@property
def event(self):
event_ptr = native_bt.notification_event_get_event(self._ptr)
- utils._handle_ptr(event_ptr, "cannot get trace event notification object's event object")
+ assert(event_ptr)
return bt2.event._create_from_ptr(event_ptr)
+ @property
+ def clock_class_priority_map(self):
+ cc_prio_map_ptr = native_bt.notification_event_get_clock_class_priority_map(self._ptr)
+ assert(cc_prio_map_ptr)
+ return bt2.clock_class_priority_map.ClockClassPriorityMap._create_from_ptr(cc_prio_map_ptr)
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ self_props = (
+ self.event,
+ self.clock_class_priority_map,
+ )
+ other_props = (
+ other.event,
+ other.clock_class_priority_map,
+ )
+ return self_props == other_props
+
+ def _copy(self, copy_func):
+ # We can always use references here because those properties are
+ # frozen anyway if they are part of a notification. Since the
+ # user cannot modify them after copying the notification, it's
+ # useless to copy/deep-copy them.
+ return EventNotification(self.event, self.clock_class_priority_map)
+
+
+class PacketBeginningNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_PACKET_BEGIN
-class BeginningOfPacketNotification(_Notification):
def __init__(self, packet):
utils._check_type(packet, bt2.packet._Packet)
ptr = native_bt.notification_packet_begin_create(packet._ptr)
if ptr is None:
- raise bt2.CreationError('cannot create beginning of packet notification object')
+ raise bt2.CreationError('cannot create packet beginning notification object')
super().__init__(ptr)
@property
def packet(self):
packet_ptr = native_bt.notification_packet_begin_get_packet(self._ptr)
- utils._handle_ptr(packet_ptr, "cannot get beginning of packet notification object's packet object")
+ assert(packet_ptr)
return bt2.packet._Packet._create_from_ptr(packet_ptr)
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ return self.packet == other.packet
+
+ def _copy(self, copy_func):
+ # We can always use references here because those properties are
+ # frozen anyway if they are part of a notification. Since the
+ # user cannot modify them after copying the notification, it's
+ # useless to copy/deep-copy them.
+ return PacketBeginningNotification(self.packet)
+
+
+class PacketEndNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_PACKET_END
-class EndOfPacketNotification(_Notification):
def __init__(self, packet):
utils._check_type(packet, bt2.packet._Packet)
ptr = native_bt.notification_packet_end_create(packet._ptr)
if ptr is None:
- raise bt2.CreationError('cannot create end of packet notification object')
+ raise bt2.CreationError('cannot create packet end notification object')
super().__init__(ptr)
@property
def packet(self):
packet_ptr = native_bt.notification_packet_end_get_packet(self._ptr)
- utils._handle_ptr(packet_ptr, "cannot get end of packet notification object's packet object")
+ assert(packet_ptr)
return bt2.packet._Packet._create_from_ptr(packet_ptr)
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ return self.packet == other.packet
+
+ def _copy(self, copy_func):
+ # We can always use references here because those properties are
+ # frozen anyway if they are part of a notification. Since the
+ # user cannot modify them after copying the notification, it's
+ # useless to copy/deep-copy them.
+ return PacketEndNotification(self.packet)
+
+
+class StreamBeginningNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_STREAM_BEGIN
-class EndOfStreamNotification(_Notification):
def __init__(self, stream):
utils._check_type(stream, bt2.stream._Stream)
- ptr = native_bt.notification_stream_end_create(stream._ptr)
+ ptr = native_bt.notification_stream_begin_create(stream._ptr)
if ptr is None:
- raise bt2.CreationError('cannot create end of stream notification object')
+ raise bt2.CreationError('cannot create stream beginning notification object')
super().__init__(ptr)
@property
def stream(self):
- stream_ptr = native_bt.notification_stream_end_get_stream(self._ptr)
- utils._handle_ptr(stream_ptr, "cannot get end of stream notification object's stream object")
+ stream_ptr = native_bt.notification_stream_begin_get_stream(self._ptr)
+ assert(stream_ptr)
return bt2.stream._create_from_ptr(stream_ptr)
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ return self.stream == other.stream
+
+ def _copy(self, copy_func):
+ # We can always use references here because those properties are
+ # frozen anyway if they are part of a notification. Since the
+ # user cannot modify them after copying the notification, it's
+ # useless to copy/deep-copy them.
+ return StreamBeginningNotification(self.stream)
+
+
+class StreamEndNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_STREAM_END
-class NewTraceNotification(_Notification):
- def __init__(self, trace):
- utils._check_type(trace, bt2.Trace)
- ptr = native_bt.notification_new_trace_create(trace._ptr)
+ def __init__(self, stream):
+ utils._check_type(stream, bt2.stream._Stream)
+ ptr = native_bt.notification_stream_end_create(stream._ptr)
if ptr is None:
- raise bt2.CreationError('cannot create new trace notification object')
+ raise bt2.CreationError('cannot create stream end notification object')
super().__init__(ptr)
@property
- def trace(self):
- trace_ptr = native_bt.notification_new_trace_get_trace(self._ptr)
- utils._handle_ptr(trace_ptr, "cannot get new trace notification object's trace object")
- return bt2.trace._create_from_ptr(trace_ptr)
+ def stream(self):
+ stream_ptr = native_bt.notification_stream_end_get_stream(self._ptr)
+ assert(stream_ptr)
+ return bt2.stream._create_from_ptr(stream_ptr)
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ return self.stream == other.stream
+
+ def _copy(self, copy_func):
+ # We can always use references here because those properties are
+ # frozen anyway if they are part of a notification. Since the
+ # user cannot modify them after copying the notification, it's
+ # useless to copy/deep-copy them.
+ return StreamEndNotification(self.stream)
+
+
+class InactivityNotification(_CopyableNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_INACTIVITY
+ def __init__(self, cc_prio_map=None):
+ if cc_prio_map is not None:
+ utils._check_type(cc_prio_map, bt2.clock_class_priority_map.ClockClassPriorityMap)
+ cc_prio_map_ptr = cc_prio_map._ptr
+ else:
+ cc_prio_map_ptr = None
-class NewStreamClassNotification(_Notification):
- def __init__(self, stream_class):
- utils._check_type(stream_class, bt2.StreamClass)
- ptr = native_bt.notification_new_stream_class_create(stream_class._ptr)
+ ptr = native_bt.notification_inactivity_create(cc_prio_map_ptr)
if ptr is None:
- raise bt2.CreationError('cannot create new stream class notification object')
+ raise bt2.CreationError('cannot create inactivity notification object')
super().__init__(ptr)
@property
- def stream_class(self):
- stream_class_ptr = native_bt.notification_new_stream_class_get_stream_class(self._ptr)
- utils._handle_ptr(stream_class_ptr, "cannot get new stream class notification object's stream class object")
- return bt2.stream_class.StreamClass._create_from_ptr(stream_class_ptr)
+ def clock_class_priority_map(self):
+ cc_prio_map_ptr = native_bt.notification_inactivity_get_clock_class_priority_map(self._ptr)
+ assert(cc_prio_map_ptr)
+ return bt2.clock_class_priority_map.ClockClassPriorityMap._create_from_ptr(cc_prio_map_ptr)
+
+ def clock_value(self, clock_class):
+ utils._check_type(clock_class, bt2.ClockClass)
+ clock_value_ptr = native_bt.notification_inactivity_get_clock_value(self._ptr,
+ clock_class._ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
+ return clock_value
+
+ def add_clock_value(self, clock_value):
+ utils._check_type(clock_value, bt2.clock_class._ClockValue)
+ ret = native_bt.notification_inactivity_set_clock_value(self._ptr,
+ clock_value._ptr)
+ utils._handle_ret(ret, "cannot set inactivity notification object's clock value")
+
+ def _get_clock_values(self):
+ clock_values = {}
+
+ for clock_class in self.clock_class_priority_map:
+ clock_value = self.clock_value(clock_class)
+
+ if clock_value is None:
+ continue
+
+ clock_values[clock_class] = clock_value
+
+ return clock_values
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ self_props = (
+ self.clock_class_priority_map,
+ self._get_clock_values(),
+ )
+ other_props = (
+ other.clock_class_priority_map,
+ other._get_clock_values(),
+ )
+ return self_props == other_props
+
+ def __copy__(self):
+ cpy = InactivityNotification(self.clock_class_priority_map)
+
+ for clock_class in self.clock_class_priority_map:
+ clock_value = self.clock_value(clock_class)
+
+ if clock_value is None:
+ continue
+
+ cpy.add_clock_value(clock_value)
+
+ return cpy
+
+ def __deepcopy__(self, memo):
+ cc_prio_map_cpy = copy.deepcopy(self.clock_class_priority_map)
+ cpy = InactivityNotification(cc_prio_map_cpy)
+
+ # copy clock values
+ for orig_clock_class in self.clock_class_priority_map:
+ orig_clock_value = self.clock_value(orig_clock_class)
+
+ if orig_clock_value is None:
+ continue
+
+ # find equivalent, copied clock class in CC priority map copy
+ for cpy_clock_class in cc_prio_map_cpy:
+ if cpy_clock_class == orig_clock_class:
+ break
+
+ # create copy of clock value from copied clock class
+ clock_value_cpy = cpy_clock_class(orig_clock_value.cycles)
+
+ # set copied clock value in notification copy
+ cpy.add_clock_value(clock_value_cpy)
+
+ memo[id(self)] = cpy
+ return cpy
+
+
+class _DiscardedElementsNotification(_Notification):
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ if self.addr == other.addr:
+ return True
+
+ self_props = (
+ self.count,
+ self.stream,
+ self.beginning_clock_value,
+ self.end_clock_value,
+ )
+ other_props = (
+ other.count,
+ other.stream,
+ other.beginning_clock_value,
+ other.end_clock_value,
+ )
+ return self_props == other_props
+
+
+class _DiscardedPacketsNotification(_DiscardedElementsNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_DISCARDED_PACKETS
+
+ @property
+ def count(self):
+ count = native_bt.notification_discarded_packets_get_count(self._ptr)
+ assert(count >= 0)
+ return count
+
+ @property
+ def stream(self):
+ stream_ptr = native_bt.notification_discarded_packets_get_stream(self._ptr)
+ assert(stream_ptr)
+ return bt2.stream._create_from_ptr(stream_ptr)
+
+ @property
+ def beginning_clock_value(self):
+ clock_value_ptr = native_bt.notification_discarded_packets_get_begin_clock_value(self._ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
+ return clock_value
+
+ @property
+ def end_clock_value(self):
+ clock_value_ptr = native_bt.notification_discarded_packets_get_end_clock_value(self._ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
+ return clock_value
+
+
+class _DiscardedEventsNotification(_DiscardedElementsNotification):
+ _TYPE = native_bt.NOTIFICATION_TYPE_DISCARDED_EVENTS
+
+ @property
+ def count(self):
+ count = native_bt.notification_discarded_events_get_count(self._ptr)
+ assert(count >= 0)
+ return count
+
+ @property
+ def stream(self):
+ stream_ptr = native_bt.notification_discarded_events_get_stream(self._ptr)
+ assert(stream_ptr)
+ return bt2.stream._create_from_ptr(stream_ptr)
+
+ @property
+ def beginning_clock_value(self):
+ clock_value_ptr = native_bt.notification_discarded_events_get_begin_clock_value(self._ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
+ return clock_value
+
+ @property
+ def end_clock_value(self):
+ clock_value_ptr = native_bt.notification_discarded_events_get_end_clock_value(self._ptr)
+
+ if clock_value_ptr is None:
+ return
+
+ clock_value = bt2.clock_class._create_clock_value_from_ptr(clock_value_ptr)
+ return clock_value
_NOTIF_TYPE_TO_CLS = {
- native_bt.NOTIFICATION_TYPE_EVENT: TraceEventNotification,
- native_bt.NOTIFICATION_TYPE_PACKET_BEGIN: BeginningOfPacketNotification,
- native_bt.NOTIFICATION_TYPE_PACKET_END: EndOfPacketNotification,
- native_bt.NOTIFICATION_TYPE_STREAM_END: EndOfStreamNotification,
- native_bt.NOTIFICATION_TYPE_NEW_TRACE: NewTraceNotification,
- native_bt.NOTIFICATION_TYPE_NEW_STREAM_CLASS: NewStreamClassNotification,
+ native_bt.NOTIFICATION_TYPE_EVENT: EventNotification,
+ native_bt.NOTIFICATION_TYPE_PACKET_BEGIN: PacketBeginningNotification,
+ native_bt.NOTIFICATION_TYPE_PACKET_END: PacketEndNotification,
+ native_bt.NOTIFICATION_TYPE_STREAM_BEGIN: StreamBeginningNotification,
+ native_bt.NOTIFICATION_TYPE_STREAM_END: StreamEndNotification,
+ native_bt.NOTIFICATION_TYPE_INACTIVITY: InactivityNotification,
+ native_bt.NOTIFICATION_TYPE_DISCARDED_PACKETS: _DiscardedPacketsNotification,
+ native_bt.NOTIFICATION_TYPE_DISCARDED_EVENTS: _DiscardedEventsNotification,
}
import bt2
-class NotificationIteratorSeekOrigin:
- BEGIN = native_bt.NOTIFICATION_ITERATOR_SEEK_ORIGIN_BEGIN
- CURRENT = native_bt.NOTIFICATION_ITERATOR_SEEK_ORIGIN_CURRENT
- END = native_bt.NOTIFICATION_ITERATOR_SEEK_ORIGIN_END
-
-
-class _GenericNotificationIteratorMethods(collections.abc.Iterator):
- @property
- def notification(self):
- notif_ptr = native_bt.notification_iterator_get_notification(self._ptr)
- utils._handle_ptr(notif_ptr, "cannot get notification iterator object's current notification object")
- return bt2.notification._create_from_ptr(notif_ptr)
-
+class _NotificationIterator(collections.abc.Iterator):
def _handle_status(self, status, gen_error_msg):
- if status == native_bt.NOTIFICATION_ITERATOR_STATUS_END:
+ if status == native_bt.NOTIFICATION_ITERATOR_STATUS_CANCELED:
+ raise bt2.NotificationIteratorCanceled
+ elif status == native_bt.NOTIFICATION_ITERATOR_STATUS_AGAIN:
+ raise bt2.TryAgain
+ elif status == native_bt.NOTIFICATION_ITERATOR_STATUS_END:
raise bt2.Stop
elif status == native_bt.NOTIFICATION_ITERATOR_STATUS_UNSUPPORTED:
raise bt2.UnsupportedFeature
elif status < 0:
raise bt2.Error(gen_error_msg)
- def next(self):
- status = native_bt.notification_iterator_next(self._ptr)
- self._handle_status(status,
- 'unexpected error: cannot go to the next notification')
-
def __next__(self):
- self.next()
- return self.notification
-
- def seek_to_time(self, origin, time):
- utils._check_int64(origin)
- utils._check_int64(time)
- status = native_bt.notification_iterator_seek_time(self._ptr, origin,
- time)
- self._handle_status(status,
- 'unexpected error: cannot seek notification iterator to time')
+ raise NotImplementedError
-class _GenericNotificationIterator(object._Object, _GenericNotificationIteratorMethods):
+class _GenericNotificationIterator(object._Object, _NotificationIterator):
@property
def component(self):
comp_ptr = native_bt.notification_iterator_get_component(self._ptr)
- utils._handle_ptr(comp_ptr, "cannot get notification iterator object's component object")
+ assert(comp_ptr)
return bt2.component._create_generic_component_from_ptr(comp_ptr)
+ def _get_notif(self):
+ notif_ptr = native_bt.notification_iterator_get_notification(self._ptr)
+ utils._handle_ptr(notif_ptr, "cannot get notification iterator object's current notification object")
+ return bt2.notification._create_from_ptr(notif_ptr)
+
+ def _next(self):
+ status = native_bt.notification_iterator_next(self._ptr)
+ self._handle_status(status,
+ 'unexpected error: cannot advance the notification iterator')
+
+ def __next__(self):
+ self._next()
+ return self._get_notif()
-class UserNotificationIterator(_GenericNotificationIteratorMethods):
+
+class _UserNotificationIterator(_NotificationIterator):
def __new__(cls, ptr):
- # User iterator objects are always created by the BT system,
+ # User iterator objects are always created by the native side,
# that is, never instantiated directly by Python code.
#
- # The system calls this, then manually calls self.__init__()
- # without the `ptr` argument. The user has access to
- # self.component during this call, thanks to this self._ptr
- # argument being set.
+ # The native code calls this, then manually calls
+ # self.__init__() without the `ptr` argument. The user has
+ # access to self.component during this call, thanks to this
+ # self._ptr argument being set.
#
# self._ptr is NOT owned by this object here, so there's nothing
# to do in __del__().
pass
@property
- def component(self):
- return native_bt.py3_get_component_from_notif_iter(self._ptr)
+ def _component(self):
+ return native_bt.py3_get_user_component_from_user_notif_iter(self._ptr)
@property
def addr(self):
return int(self._ptr)
- def _destroy(self):
+ def _finalize(self):
pass
- def _get_from_bt(self):
- # this can raise anything: it's catched by the system
- notif = self._get()
+ def __next__(self):
+ raise bt2.Stop
+
+ def _next_from_native(self):
+ # this can raise anything: it's catched by the native part
+ try:
+ notif = next(self)
+ except StopIteration:
+ raise bt2.Stop
+ except:
+ raise
+
utils._check_type(notif, bt2.notification._Notification)
- # steal the underlying native notification object for the caller
- notif_ptr = notif._ptr
- notif._ptr = None
- return int(notif_ptr)
+ # take a new reference for the native part
+ notif._get()
+ return int(notif._ptr)
# The MIT License (MIT)
#
-# Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
def __del__(self):
ptr = getattr(self, '_ptr', None)
native_bt.put(ptr)
+ self._ptr = None
def __repr__(self):
return '<{}.{} object @ {}>'.format(self.__class__.__module__,
hex(self.addr))
+class _PrivateObject:
+ def __del__(self):
+ pub_ptr = getattr(self, '_pub_ptr', None)
+ native_bt.put(pub_ptr)
+ self._pub_ptr = None
+ super().__del__()
+
+
class _Freezable(metaclass=abc.ABCMeta):
@property
def is_frozen(self):
@property
def stream(self):
stream_ptr = native_bt.ctf_packet_get_stream(self._ptr)
- utils._handle_ptr(stream_ptr, "cannot get packet object's stream object")
+ assert(stream_ptr)
return bt2.stream._Stream._create_from_ptr(stream_ptr)
@property
from bt2 import native_bt, object, utils
import collections.abc
import bt2.component
+import os.path
import bt2
-def _plugin_ptrs_to_plugins(plugin_ptrs):
- plugins = []
-
- for plugin_ptr in plugin_ptrs:
- plugin = _Plugin._create_from_ptr(plugin_ptr)
- plugins.append(plugin)
+def find_plugins(path, recurse=True):
+ utils._check_str(path)
+ utils._check_bool(recurse)
+ plugin_set_ptr = None
- return plugins
+ if os.path.isfile(path):
+ plugin_set_ptr = native_bt.plugin_create_all_from_file(path)
+ elif os.path.isdir(path):
+ plugin_set_ptr = native_bt.plugin_create_all_from_dir(path, int(recurse))
+ if plugin_set_ptr is None:
+ return
-def create_plugins_from_file(path):
- utils._check_str(path)
- plugin_ptrs = native_bt.py3_plugin_create_all_from_file(path)
+ return _PluginSet._create_from_ptr(plugin_set_ptr)
- if plugin_ptrs is None:
- raise bt2.Error('cannot get plugin objects from file')
- return _plugin_ptrs_to_plugins(plugin_ptrs)
+def find_plugin(name):
+ utils._check_str(name)
+ ptr = native_bt.plugin_find(name)
+ if ptr is None:
+ return
-def create_plugins_from_dir(path, recurse=True):
- utils._check_str(path)
- plugin_ptrs = native_bt.py3_plugin_create_all_from_dir(path, recurse)
+ return _Plugin._create_from_ptr(ptr)
- if plugin_ptrs is None:
- raise bt2.Error('cannot get plugin objects from directory')
-
- return _plugin_ptrs_to_plugins(plugin_ptrs)
+class _PluginSet(object._Object, collections.abc.Sequence):
+ def __len__(self):
+ count = native_bt.plugin_set_get_plugin_count(self._ptr)
+ assert(count >= 0)
+ return count
-def create_plugin_from_name(name):
- utils._check_str(name)
- plugin_ptr = native_bt.plugin_create_from_name(name)
+ def __getitem__(self, index):
+ utils._check_uint64(index)
- if plugin_ptr is None:
- raise bt2.NoSuchPluginError(name)
+ if index >= len(self):
+ raise IndexError
- return _Plugin._create_from_ptr(plugin_ptr)
+ plugin_ptr = native_bt.plugin_set_get_plugin(self._ptr, index)
+ assert(plugin_ptr)
+ return _Plugin._create_from_ptr(plugin_ptr)
class _PluginVersion:
return '{}.{}.{}{}'.format(self._major, self._minor, self._patch, extra)
-class _Plugin(object._Object, collections.abc.Sequence):
+class _PluginComponentClassesIterator(collections.abc.Iterator):
+ def __init__(self, plugin_comp_cls):
+ self._plugin_comp_cls = plugin_comp_cls
+ self._at = 0
+
+ def __next__(self):
+ plugin_ptr = self._plugin_comp_cls._plugin._ptr
+ comp_cls_type = self._plugin_comp_cls._comp_cls_type
+ total = native_bt.plugin_get_component_class_count(plugin_ptr)
+
+ while True:
+ if self._at == total:
+ raise StopIteration
+
+ comp_cls_ptr = native_bt.plugin_get_component_class_by_index(plugin_ptr,
+ self._at)
+ assert(comp_cls_ptr)
+ cc_type = native_bt.component_class_get_type(comp_cls_ptr)
+ self._at += 1
+
+ if cc_type == comp_cls_type:
+ break
+
+ native_bt.put(comp_cls_ptr)
+
+ name = native_bt.component_class_get_name(comp_cls_ptr)
+ native_bt.put(comp_cls_ptr)
+ assert(name is not None)
+ return name
+
+
+class _PluginComponentClasses(collections.abc.Mapping):
+ def __init__(self, plugin, comp_cls_type):
+ self._plugin = plugin
+ self._comp_cls_type = comp_cls_type
+
+ def __getitem__(self, key):
+ utils._check_str(key)
+ cc_ptr = native_bt.plugin_get_component_class_by_name_and_type(self._plugin._ptr,
+ key,
+ self._comp_cls_type)
+
+ if cc_ptr is None:
+ raise KeyError(key)
+
+ return bt2.component._create_generic_component_class_from_ptr(cc_ptr)
+
+ def __len__(self):
+ count = 0
+ total = native_bt.plugin_get_component_class_count(self._plugin._ptr)
+
+ for at in range(total):
+ comp_cls_ptr = native_bt.plugin_get_component_class_by_index(self._plugin._ptr,
+ at)
+ assert(comp_cls_ptr)
+ cc_type = native_bt.component_class_get_type(comp_cls_ptr)
+
+ if cc_type == self._comp_cls_type:
+ count += 1
+
+ native_bt.put(comp_cls_ptr)
+
+ return count
+
+ def __iter__(self):
+ return _PluginComponentClassesIterator(self)
+
+
+class _Plugin(object._Object):
@property
def name(self):
name = native_bt.plugin_get_name(self._ptr)
- utils._handle_ptr(name, "cannot get plugin object's name")
+ assert(name is not None)
return name
@property
return _PluginVersion(major, minor, patch, extra)
- def source_component_class(self, name):
- utils._check_str(name)
- cc_ptr = native_bt.plugin_get_component_class_by_name_and_type(self._ptr,
- name,
- native_bt.COMPONENT_CLASS_TYPE_SOURCE)
-
- if cc_ptr is None:
- return
-
- return bt2.component._create_generic_component_class_from_ptr(cc_ptr)
-
- def filter_component_class(self, name):
- utils._check_str(name)
- cc_ptr = native_bt.plugin_get_component_class_by_name_and_type(self._ptr,
- name,
- native_bt.COMPONENT_CLASS_TYPE_FILTER)
-
- if cc_ptr is None:
- return
-
- return bt2.component._create_generic_component_class_from_ptr(cc_ptr)
-
- def sink_component_class(self, name):
- utils._check_str(name)
- cc_ptr = native_bt.plugin_get_component_class_by_name_and_type(self._ptr,
- name,
- native_bt.COMPONENT_CLASS_TYPE_SINK)
-
- if cc_ptr is None:
- return
-
- return bt2.component._create_generic_component_class_from_ptr(cc_ptr)
-
- def __len__(self):
- count = native_bt.plugin_get_component_class_count(self._ptr)
- utils._handle_ret(count, "cannot get plugin object's component class count")
- return count
-
- def __getitem__(self, index):
- utils._check_uint64(index)
+ @property
+ def source_component_classes(self):
+ return _PluginComponentClasses(self, native_bt.COMPONENT_CLASS_TYPE_SOURCE)
- if index >= len(self):
- raise IndexError
+ @property
+ def filter_component_classes(self):
+ return _PluginComponentClasses(self, native_bt.COMPONENT_CLASS_TYPE_FILTER)
- cc_ptr = native_bt.plugin_get_component_class(self._ptr, index)
- utils._handle_ptr(cc_ptr, "cannot get plugin object's component class object")
- return bt2.component._create_generic_component_class_from_ptr(cc_ptr)
+ @property
+ def sink_component_classes(self):
+ return _PluginComponentClasses(self, native_bt.COMPONENT_CLASS_TYPE_SINK)
--- /dev/null
+# The MIT License (MIT)
+#
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+from bt2 import native_bt, object, utils
+import collections.abc
+import bt2.component
+import bt2.connection
+import copy
+import bt2
+
+
+def _create_from_ptr(ptr):
+ port_type = native_bt.port_get_type(ptr)
+
+ if port_type == native_bt.PORT_TYPE_INPUT:
+ cls = _InputPort
+ elif port_type == native_bt.PORT_TYPE_OUTPUT:
+ cls = _OutputPort
+ else:
+ raise bt2.Error('unknown port type: {}'.format(port_type))
+
+ return cls._create_from_ptr(ptr)
+
+
+def _create_private_from_ptr(ptr):
+ pub_ptr = native_bt.port_from_private_port(ptr)
+ utils._handle_ptr(pub_ptr, 'cannot get port object from private port object')
+ port_type = native_bt.port_get_type(pub_ptr)
+ assert(port_type == native_bt.PORT_TYPE_INPUT or port_type == native_bt.PORT_TYPE_OUTPUT)
+
+ if port_type == native_bt.PORT_TYPE_INPUT:
+ cls = _PrivateInputPort
+ elif port_type == native_bt.PORT_TYPE_OUTPUT:
+ cls = _PrivateOutputPort
+
+ obj = cls._create_from_ptr(ptr)
+ obj._pub_ptr = pub_ptr
+ return obj
+
+
+class _Port(object._Object):
+ @staticmethod
+ def _name(ptr):
+ name = native_bt.port_get_name(ptr)
+ assert(name is not None)
+ return name
+
+ @staticmethod
+ def _disconnect(ptr):
+ status = native_bt.port_disconnect(ptr)
+
+ if status < 0:
+ raise bt2.Error('cannot disconnect port')
+
+ @property
+ def name(self):
+ return self._name(self._ptr)
+
+ @property
+ def component(self):
+ comp_ptr = native_bt.port_get_component(self._ptr)
+
+ if comp_ptr is None:
+ return
+
+ return bt2.component._create_generic_component_from_ptr(comp_ptr)
+
+ @property
+ def connection(self):
+ conn_ptr = native_bt.port_get_connection(self._ptr)
+
+ if conn_ptr is None:
+ return
+
+ return bt2.connection._Connection._create_from_ptr(conn_ptr)
+
+ @property
+ def is_connected(self):
+ return self.connection is not None
+
+ def disconnect(self):
+ self._disconnect(self._ptr)
+
+ def __eq__(self, other):
+ if type(other) is not type(self):
+ return False
+
+ return self.addr == other.addr
+
+
+class _InputPort(_Port):
+ pass
+
+
+class _OutputPort(_Port):
+ pass
+
+
+class _PrivatePort(object._PrivateObject, _Port):
+ @property
+ def name(self):
+ return self._name(self._pub_ptr)
+
+ @property
+ def component(self):
+ comp_ptr = native_bt.private_port_get_private_component(self._ptr)
+
+ if comp_ptr is None:
+ return
+
+ pub_comp_ptr = native_bt.component_from_private_component(comp_ptr)
+ assert(pub_comp_ptr)
+ comp = bt2.component._create_generic_component_from_ptr(pub_comp_ptr)
+ native_bt.put(comp_ptr)
+ return comp
+
+ @property
+ def connection(self):
+ conn_ptr = native_bt.private_port_get_private_connection(self._ptr)
+
+ if conn_ptr is None:
+ return
+
+ return bt2.connection._create_private_from_ptr(conn_ptr)
+
+ def remove_from_component(self):
+ status = native_bt.private_port_remove_from_component(self._ptr)
+
+ if status < 0:
+ raise bt2.Error("cannot remove port from component")
+
+ def disconnect(self):
+ self._disconnect(self._pub_ptr)
+
+
+class _PrivateInputPort(_PrivatePort, _InputPort):
+ pass
+
+
+class _PrivateOutputPort(_PrivatePort, _OutputPort):
+ pass
@property
def stream_class(self):
stream_class_ptr = native_bt.ctf_stream_get_class(self._ptr)
- utils._handle_ptr(stream_class_ptr, "cannot get stream object's stream class object")
+ assert(stream_class_ptr)
return bt2.StreamClass._create_from_ptr(stream_class_ptr)
@property
def name(self):
return native_bt.ctf_stream_get_name(self._ptr)
+ @property
+ def id(self):
+ id = native_bt.ctf_stream_get_id(self._ptr)
+ return id if id >= 0 else None
+
def __eq__(self, other):
if self.addr == other.addr:
return True
- return self.name == other.name
+ return (self.name, self.id) == (other.name, other.id)
class _Stream(_StreamBase):
return _StreamBase.__eq__(self, other)
def _copy(self):
- return self.stream_class(self.name)
+ return self.stream_class(self.name, self.id)
def __copy__(self):
return self._copy()
# The MIT License (MIT)
#
-# Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
if self._at == len(self._stream_class):
raise StopIteration
- ec_ptr = native_bt.ctf_stream_class_get_event_class(self._stream_class._ptr,
- self._at)
- utils._handle_ptr(ec_ptr, "cannot get stream class object's event class object")
- name = native_bt.ctf_event_class_get_name(ec_ptr)
+ ec_ptr = native_bt.ctf_stream_class_get_event_class_by_index(self._stream_class._ptr,
+ self._at)
+ assert(ec_ptr)
+ ev_id = native_bt.ctf_event_class_get_id(ec_ptr)
native_bt.put(ec_ptr)
- utils._handle_ptr(name, "cannot get event class object's name")
+ utils._handle_ret(ev_id, "cannot get event class object's ID")
self._at += 1
- return name
+ return ev_id
class StreamClass(object._Object, collections.abc.Mapping):
def __init__(self, name=None, id=None, packet_context_field_type=None,
event_header_field_type=None, event_context_field_type=None,
event_classes=None):
- ptr = native_bt.ctf_stream_class_create(None)
+ ptr = native_bt.ctf_stream_class_create_empty(None)
if ptr is None:
raise bt2.CreationError('cannot create stream class object')
self.add_event_class(event_class)
def __getitem__(self, key):
- utils._check_str(key)
- ec_ptr = native_bt.ctf_stream_class_get_event_class_by_name(self._ptr,
- key)
+ utils._check_int64(key)
+ ec_ptr = native_bt.ctf_stream_class_get_event_class_by_id(self._ptr,
+ key)
if ec_ptr is None:
raise KeyError(key)
def __len__(self):
count = native_bt.ctf_stream_class_get_event_class_count(self._ptr)
- utils._handle_ret(count, "cannot get stream class object's event class count")
+ assert(count >= 0)
return count
def __iter__(self):
return _EventClassIterator(self)
- def event_class_with_id(self, id):
- utils._check_int64(id)
- ec_ptr = native_bt.ctf_stream_class_get_event_class_by_id(self._ptr, id)
- utils._handle_ptr(ec_ptr, "cannot get stream class object's event class object")
- return bt2.EventClass._create_from_ptr(ec_ptr)
-
def add_event_class(self, event_class):
utils._check_type(event_class, bt2.EventClass)
ret = native_bt.ctf_stream_class_add_event_class(self._ptr, event_class._ptr)
def id(self):
id = native_bt.ctf_stream_class_get_id(self._ptr)
- if utils._is_m1ull(id):
- raise bt2.Error("cannot get stream class object's ID")
+ if id < 0:
+ return
return id
event_context_field_type_ptr)
utils._handle_ret(ret, "cannot set stream class object's event context field type")
- def __call__(self, name=None):
+ def __call__(self, name=None, id=None):
if name is not None:
utils._check_str(name)
- stream_ptr = native_bt.ctf_stream_create(self._ptr, name)
+ if id is None:
+ stream_ptr = native_bt.ctf_stream_create(self._ptr, name)
+ else:
+ stream_ptr = native_bt.ctf_stream_create_with_id(self._ptr, name, id)
if stream_ptr is None:
raise bt2.CreationError('cannot create stream object')
self_event_classes,
self.name,
self.id,
- self.clock,
self.packet_context_field_type,
self.event_header_field_type,
self.event_context_field_type,
+ self.clock,
)
other_props = (
other_event_classes,
other.name,
other.id,
- other.clock,
other.packet_context_field_type,
other.event_header_field_type,
other.event_context_field_type,
+ other.clock,
)
+
return self_props == other_props
def _copy(self, ft_copy_func, ev_copy_func):
cpy = StreamClass()
- cpy.id = self.id
- cpy.name = self.name
+
+ if self.id is not None:
+ cpy.id = self.id
+
+ if self.name is not None:
+ cpy.name = self.name
+
+ if self.clock is not None:
+ cpy.clock = self.clock
+
cpy.packet_context_field_type = ft_copy_func(self.packet_context_field_type)
cpy.event_header_field_type = ft_copy_func(self.event_header_field_type)
cpy.event_context_field_type = ft_copy_func(self.event_context_field_type)
# The MIT License (MIT)
#
-# Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
import bt2.field_types
import collections.abc
import bt2.values
+import bt2.stream
import copy
import bt2
if self._at == len(self._trace):
raise StopIteration
- sc_ptr = native_bt.ctf_trace_get_stream_class(self._trace._ptr,
- self._at)
- utils._handle_ptr(sc_ptr, "cannot get trace class object's stream class object")
+ sc_ptr = native_bt.ctf_trace_get_stream_class_by_index(self._trace._ptr,
+ self._at)
+ assert(sc_ptr)
id = native_bt.ctf_stream_class_get_id(sc_ptr)
native_bt.put(sc_ptr)
-
- if utils._is_m1ull(id):
- raise bt2.Error("cannot get stream class object's ID")
-
+ assert(id >= 0)
self._at += 1
return id
+class _TraceStreams(collections.abc.Sequence):
+ def __init__(self, trace):
+ self._trace = trace
+
+ def __len__(self):
+ count = native_bt.ctf_trace_get_stream_count(self._trace._ptr)
+ assert(count >= 0)
+ return count
+
+ def __getitem__(self, index):
+ utils._check_uint64(index)
+
+ if index >= len(self):
+ raise IndexError
+
+ stream_ptr = native_bt.ctf_trace_get_stream_by_index(self._trace._ptr,
+ index)
+ assert(stream_ptr)
+ return bt2.stream._create_from_ptr(stream_ptr)
+
+
class _TraceClockClassesIterator(collections.abc.Iterator):
def __init__(self, trace_clock_classes):
self._trace_clock_classes = trace_clock_classes
raise StopIteration
trace_ptr = self._trace_clock_classes._trace._ptr
- cc_ptr = native_bt.ctf_trace_get_clock_class(trace_ptr, self._at)
- utils._handle_ptr(cc_ptr, "cannot get trace class object's clock class")
+ cc_ptr = native_bt.ctf_trace_get_clock_class_by_index(trace_ptr, self._at)
+ assert(cc_ptr)
name = native_bt.ctf_clock_class_get_name(cc_ptr)
native_bt.put(cc_ptr)
- utils._handle_ptr(name, "cannot get clock class object's name")
+ assert(name is not None)
self._at += 1
return name
def __len__(self):
count = native_bt.ctf_trace_get_clock_class_count(self._trace._ptr)
- utils._handle_ret(count, "cannot get trace class object's clock class count")
+ assert(count >= 0)
return count
def __iter__(self):
raise StopIteration
trace_ptr = self._trace_env._trace._ptr
- entry_name = native_bt.ctf_trace_get_environment_field_name(trace_ptr,
- self._at)
- utils._handle_ptr(entry_name, "cannot get trace class object's environment entry name")
+ entry_name = native_bt.ctf_trace_get_environment_field_name_by_index(trace_ptr,
+ self._at)
+ assert(entry_name is not None)
self._at += 1
return entry_name
def __len__(self):
count = native_bt.ctf_trace_get_environment_field_count(self._trace._ptr)
- utils._handle_ret(count, "cannot get trace class object's environment entry count")
+ assert(count >= 0)
return count
def __iter__(self):
def __len__(self):
count = native_bt.ctf_trace_get_stream_class_count(self._ptr)
- utils._handle_ret(count, "cannot get trace class object's stream class count")
+ assert(count >= 0)
return count
def __iter__(self):
@property
def native_byte_order(self):
- bo = native_bt.ctf_trace_get_byte_order(self._ptr)
- utils._handle_ret(bo, "cannot get trace class object's native byte order")
+ bo = native_bt.ctf_trace_get_native_byte_order(self._ptr)
+ assert(bo >= 0)
return bo
@native_byte_order.setter
def native_byte_order(self, native_byte_order):
utils._check_int(native_byte_order)
- ret = native_bt.ctf_trace_set_byte_order(self._ptr, native_byte_order)
+ ret = native_bt.ctf_trace_set_native_byte_order(self._ptr, native_byte_order)
utils._handle_ret(ret, "cannot set trace class object's native byte order")
+ @property
+ def is_static(self):
+ is_static = native_bt.ctf_trace_is_static(self._ptr)
+ return is_static > 0
+
+ def set_is_static(self):
+ ret = native_bt.ctf_trace_set_is_static(self._ptr)
+ utils._handle_ret(ret, "cannot set trace object as static")
+
@property
def env(self):
return _TraceEnv(self)
ret = native_bt.ctf_trace_add_clock_class(self._ptr, clock_class._ptr)
utils._handle_ret(ret, "cannot add clock class object to trace class object")
+ @property
+ def streams(self):
+ return _TraceStreams(self)
+
@property
def packet_header_field_type(self):
ft_ptr = native_bt.ctf_trace_get_packet_header_type(self._ptr)
# The MIT License (MIT)
#
-# Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
def _check_alignment(a):
_check_uint64(a)
-
if not _is_pow2(a):
raise ValueError('{} is not a power of two'.format(a))
# The MIT License (MIT)
#
-# Copyright (c) 2016 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2017 Philippe Proulx <pproulx@efficios.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
return
if status == native_bt.VALUE_STATUS_FROZEN:
- raise bt2.FrozenError('{} value object is frozen'.format(obj_name))
+ raise bt2.Frozen('{} value object is frozen'.format(obj_name))
elif status == native_bt.VALUE_STATUS_INVAL:
# In practice, this should never happen, because arguments
# should always be validated in this Python module before
class _Value(object._Object, object._Freezable, metaclass=abc.ABCMeta):
- def __init__(self, ptr):
- super().__init__(ptr)
-
def __eq__(self, other):
if other is None:
# self is never the null value object
return self.value <= float(other)
def _spec_eq(self, other):
- return
+ pass
def __eq__(self, other):
if not isinstance(other, numbers.Number):
if not isinstance(value, bool):
raise TypeError("'{}' object is not a 'bool' or 'BoolValue' object".format(value.__class__))
- return value
+ return int(value)
@property
def value(self):
status, value = native_bt.value_bool_get(self._ptr)
- self._handle_status(status)
- return value
+ assert(status == native_bt.VALUE_STATUS_OK)
+ return value > 0
@value.setter
def value(self, value):
@property
def value(self):
status, value = native_bt.value_integer_get(self._ptr)
- self._handle_status(status)
+ assert(status == native_bt.VALUE_STATUS_OK)
return value
@value.setter
@property
def value(self):
status, value = native_bt.value_float_get(self._ptr)
- self._handle_status(status)
+ assert(status == native_bt.VALUE_STATUS_OK)
return value
@value.setter
@property
def value(self):
status, value = native_bt.value_string_get(self._ptr)
- self._handle_status(status)
+ assert(status == native_bt.VALUE_STATUS_OK)
return value
@value.setter
ptr = native_bt.value_copy(self._ptr)
if ptr is None:
- fmt = 'unexpected error: cannot deep-copy {} value object'
- raise RuntimeError(fmt.format(self._NAME))
+ raise RuntimeError('unexpected error: cannot deep-copy {} value object'.format(self._NAME))
copy = self.__class__._create_from_ptr(ptr)
memo[id(self)] = copy
def __len__(self):
size = native_bt.value_array_size(self._ptr)
- self._handle_status(size)
+ assert(size >= 0)
return size
def _check_index(self, index):
def __getitem__(self, index):
self._check_index(index)
ptr = native_bt.value_array_get(self._ptr, index)
-
- if ptr is None:
- raise RuntimeError('unexpected error: cannot get array value object element')
-
+ assert(ptr)
return _create_from_ptr(ptr)
def __setitem__(self, index, value):
def __len__(self):
size = native_bt.value_map_size(self._ptr)
- self._handle_status(size)
+ assert(size >= 0)
return size
def __contains__(self, key):
def __getitem__(self, key):
self._check_key(key)
ptr = native_bt.value_map_get(self._ptr, key)
-
- if ptr is None:
- raise RuntimeError('unexpected error: cannot get map value object element')
-
+ assert(ptr)
return _create_from_ptr(ptr)
def __iter__(self):
)
-# Check for conflicting optionnal features user choices
+# Check for conflicting optional features user choices
AS_IF([test "x$enable_python_bindings" = xno],
[
program_transform_name="s&babeltrace\.bin&babeltrace&;s&babeltrace-log\.bin&babeltrace-log&;$program_transform_name"
AC_SUBST(program_transform_name)
-
- #TODO: removed, work in progress
- #bindings/python/Makefile
- #bindings/python/babeltrace/Makefile
- #bindings/python/bt2/Makefile
- #bindings/python/bt2/__init__.py
AC_CONFIG_FILES([
Makefile
+ bindings/python/Makefile
+ bindings/python/bt2/Makefile
+ bindings/python/bt2/__init__.py
common/Makefile
compat/Makefile
cli/Makefile
AC_CONFIG_FILES([tests/plugins/test_dwarf_complete], [chmod +x tests/plugins/test_dwarf_complete])
AC_CONFIG_FILES([tests/plugins/test_bin_info_complete], [chmod +x tests/plugins/test_bin_info_complete])
-AS_IF([test "x$enable_python" = xyes],
+AS_IF([test "x$enable_python_bindings_tests" = xyes],
[AC_CONFIG_FILES([tests/bindings/python/bt2/testall.sh], [chmod +x tests/bindings/python/bt2/testall.sh])]
)
*native_*.py
*/object.py
*/utils.py
+ */logging.py
+ */py_plugin.py
[report]
exclude_lines =
def __repr__
raise bt2\.CreationError
raise NotImplementedError
+ return NotImplemented
pass
+ raise \w+Error\(['"][Uu]nexpected
+ if (self|other)\.addr == (self|other)\.addr
+ if not _NO_PRINT_TRACEBACK
+ class _PluginVersion:
check_SCRIPTS = testall.sh
-EXTRA_DIST = \
- $(check_SCRIPTS) \
- test_clock_class.py \
- test_ctf_writer_clock.py \
- test_event_class.py \
- test_event.py \
- test_fields.py \
- test_field_types.py \
- test_packet.py \
- test_stream_class.py \
- test_stream.py \
- test_trace.py \
- test_values.py \
+EXTRA_DIST = \
+ $(check_SCRIPTS) \
+ test_clock_class.py \
+ test_clock_class_priority_map.py \
+ test_component.py \
+ test_component_class.py \
+ test_connection.py \
+ test_ctf_writer_clock.py \
+ test_event.py \
+ test_event_class.py \
+ test_field_types.py \
+ test_fields.py \
+ test_graph.py \
+ test_notification.py \
+ test_notification_iterator.py \
+ test_packet.py \
+ test_plugin.py \
+ test_port.py \
+ test_stream.py \
+ test_stream_class.py \
+ test_trace.py \
+ test_values.py \
.coveragerc
LOG_DRIVER_FLAGS='--merge'
class ClockClassTestCase(unittest.TestCase):
def setUp(self):
- self._cc = bt2.ClockClass('salut')
+ self._cc = bt2.ClockClass('salut', 1000000)
+
+ def tearDown(self):
+ del self._cc
def test_create_default(self):
self.assertEqual(self._cc.name, 'salut')
self._cc.uuid = object()
def test_create_clock_value(self):
- cv = self._cc.create_clock_value(756)
+ cv = self._cc(756)
self.assertEqual(cv.clock_class.addr, self._cc.addr)
def _test_copy(self, cpy):
self.assertFalse(self._cc == 23)
-class ClockClassValueTestCase(unittest.TestCase):
+class ClockValueTestCase(unittest.TestCase):
def setUp(self):
- self._cc = bt2.ClockClass('salut')
- self._cv = self._cc.create_clock_value(123)
+ self._cc = bt2.ClockClass('salut', 1000,
+ offset=bt2.ClockClassOffset(45, 354))
+ self._cv = self._cc(123)
+
+ def tearDown(self):
+ del self._cc
+ del self._cv
def test_create_default(self):
self.assertEqual(self._cv.clock_class.addr, self._cc.addr)
def test_create_invalid_cycles_type(self):
with self.assertRaises(TypeError):
- self._cc.create_clock_value('yes')
+ self._cc('yes')
def test_ns_from_epoch(self):
- self._cv.clock_class.frequency = 1000
- self._cv.clock_class.offset = bt2.ClockClassOffset(45, 354)
s_from_epoch = 45 + ((354 + 123) / 1000)
ns_from_epoch = int(s_from_epoch * 1e9)
self.assertEqual(self._cv.ns_from_epoch, ns_from_epoch)
def test_eq(self):
- cv1 = self._cc.create_clock_value(123)
- cv2 = self._cc.create_clock_value(123)
+ cv1 = self._cc(123)
+ cv2 = self._cc(123)
self.assertEqual(cv1, cv2)
+ def test_eq_int(self):
+ cv1 = self._cc(123)
+ self.assertEqual(cv1, 123)
+
def test_ne_clock_class(self):
- cc1 = bt2.ClockClass('yes')
- cc2 = bt2.ClockClass('yes')
- cv1 = cc1.create_clock_value(123)
- cv2 = cc2.create_clock_value(123)
+ cc1 = bt2.ClockClass('yes', 1500)
+ cc2 = bt2.ClockClass('yes', 1501)
+ cv1 = cc1(123)
+ cv2 = cc2(123)
self.assertNotEqual(cv1, cv2)
def test_ne_cycles(self):
- cv1 = self._cc.create_clock_value(123)
- cv2 = self._cc.create_clock_value(125)
+ cv1 = self._cc(123)
+ cv2 = self._cc(125)
self.assertNotEqual(cv1, cv2)
def test_eq_invalid(self):
--- /dev/null
+import unittest
+import uuid
+import copy
+import bt2
+
+
+class ClockClassPriorityMapTestCase(unittest.TestCase):
+ def test_create_empty(self):
+ cc_prio_map = bt2.ClockClassPriorityMap()
+ self.assertEqual(len(cc_prio_map), 0)
+ self.assertIsNone(cc_prio_map.highest_priority_clock_class)
+
+ def test_create_full(self):
+ cc1 = bt2.ClockClass('meow', 1234)
+ cc2 = bt2.ClockClass('mix', 5678)
+ cc_prio_map = bt2.ClockClassPriorityMap({cc1: 17, cc2: 2})
+ self.assertEqual(len(cc_prio_map), 2)
+ self.assertEqual(cc_prio_map[cc1], 17)
+ self.assertEqual(cc_prio_map[cc2], 2)
+ self.assertEqual(cc_prio_map.highest_priority_clock_class, cc2)
+
+ def test_setitem(self):
+ cc_prio_map = bt2.ClockClassPriorityMap()
+ cc1 = bt2.ClockClass('mix', 5678)
+ cc_prio_map[cc1] = 184
+ self.assertEqual(len(cc_prio_map), 1)
+ self.assertEqual(cc_prio_map[cc1], 184)
+ self.assertEqual(cc_prio_map.highest_priority_clock_class, cc1)
+
+ def test_setitem_wrong_key_type(self):
+ cc_prio_map = bt2.ClockClassPriorityMap()
+
+ with self.assertRaises(TypeError):
+ cc_prio_map['the clock'] = 184
+
+ def test_setitem_wrong_value_type(self):
+ cc_prio_map = bt2.ClockClassPriorityMap()
+ cc1 = bt2.ClockClass('mix', 5678)
+
+ with self.assertRaises(TypeError):
+ cc_prio_map[cc1] = 'priority'
+
+ def test_getitem_wrong_key(self):
+ cc_prio_map = bt2.ClockClassPriorityMap()
+ cc1 = bt2.ClockClass('mix', 5678)
+ cc2 = bt2.ClockClass('mix', 5678)
+ cc_prio_map[cc1] = 2
+
+ with self.assertRaises(KeyError):
+ cc_prio_map[cc2]
+
+ def test_getitem_wrong_key_type(self):
+ cc_prio_map = bt2.ClockClassPriorityMap()
+
+ with self.assertRaises(TypeError):
+ cc_prio_map[23]
+
+ def test_iter(self):
+ cc1 = bt2.ClockClass('meow', 1234)
+ cc2 = bt2.ClockClass('mix', 5678)
+ cc3 = bt2.ClockClass('lel', 1548)
+ cc_prio_map = bt2.ClockClassPriorityMap({cc1: 17, cc2: 2, cc3: 25})
+ cc_prios = {}
+
+ for cc, prio in cc_prio_map.items():
+ cc_prios[cc] = prio
+
+ self.assertEqual(len(cc_prios), 3)
+ self.assertEqual(cc_prios[cc1], 17)
+ self.assertEqual(cc_prios[cc2], 2)
+ self.assertEqual(cc_prios[cc3], 25)
+
+ def test_eq(self):
+ cc1 = bt2.ClockClass('meow', 1234)
+ cc2 = bt2.ClockClass('mix', 5678)
+ cc3 = bt2.ClockClass('lel', 1548)
+ cc_prio_map = bt2.ClockClassPriorityMap({cc1: 17, cc2: 2, cc3: 25})
+ other_cc1 = bt2.ClockClass('meow', 1234)
+ other_cc2 = bt2.ClockClass('mix', 5678)
+ other_cc3 = bt2.ClockClass('lel', 1548)
+ other_cc_prio_map = bt2.ClockClassPriorityMap({other_cc1: 17, other_cc2: 2, other_cc3: 25})
+ self.assertEqual(cc_prio_map, other_cc_prio_map)
+
+ def test_ne_clock_class(self):
+ cc1 = bt2.ClockClass('meow', 1234)
+ cc2 = bt2.ClockClass('mix', 5678)
+ cc3 = bt2.ClockClass('lel', 1548)
+ cc_prio_map = bt2.ClockClassPriorityMap({cc1: 17, cc2: 2, cc3: 25})
+ other_cc1 = bt2.ClockClass('meow', 1234)
+ other_cc2 = bt2.ClockClass('coucou', 5678)
+ other_cc3 = bt2.ClockClass('lel', 1548)
+ other_cc_prio_map = bt2.ClockClassPriorityMap({other_cc1: 17, other_cc2: 2, other_cc3: 25})
+ self.assertNotEqual(cc_prio_map, other_cc_prio_map)
+
+ def test_ne_prio(self):
+ cc1 = bt2.ClockClass('meow', 1234)
+ cc2 = bt2.ClockClass('mix', 5678)
+ cc3 = bt2.ClockClass('lel', 1548)
+ cc_prio_map = bt2.ClockClassPriorityMap({cc1: 17, cc2: 2, cc3: 25})
+ other_cc1 = bt2.ClockClass('meow', 1234)
+ other_cc2 = bt2.ClockClass('mix', 5678)
+ other_cc3 = bt2.ClockClass('lel', 1548)
+ other_cc_prio_map = bt2.ClockClassPriorityMap({other_cc1: 17, other_cc2: 3, other_cc3: 25})
+ self.assertNotEqual(cc_prio_map, other_cc_prio_map)
+
+ def test_eq_invalid(self):
+ self.assertFalse(bt2.ClockClassPriorityMap() == 23)
+
+ def test_copy(self):
+ cc1 = bt2.ClockClass('meow', 1234)
+ cc2 = bt2.ClockClass('mix', 5678)
+ cc3 = bt2.ClockClass('lel', 1548)
+ cc_prio_map = bt2.ClockClassPriorityMap({cc1: 17, cc2: 2, cc3: 25})
+ cc_prio_map_cpy = copy.copy(cc_prio_map)
+ self.assertEqual(cc_prio_map, cc_prio_map_cpy)
+ self.assertEqual(list(cc_prio_map.keys())[0].addr, list(cc_prio_map_cpy.keys())[0].addr)
+ self.assertEqual(list(cc_prio_map.keys())[1].addr, list(cc_prio_map_cpy.keys())[1].addr)
+ self.assertEqual(list(cc_prio_map.keys())[2].addr, list(cc_prio_map_cpy.keys())[2].addr)
+ self.assertEqual(list(cc_prio_map.values())[0], list(cc_prio_map_cpy.values())[0])
+ self.assertEqual(list(cc_prio_map.values())[1], list(cc_prio_map_cpy.values())[1])
+ self.assertEqual(list(cc_prio_map.values())[2], list(cc_prio_map_cpy.values())[2])
+ self.assertEqual(cc_prio_map.highest_priority_clock_class.addr,
+ cc_prio_map_cpy.highest_priority_clock_class.addr)
+
+ def test_deep_copy(self):
+ cc1 = bt2.ClockClass('meow', 1234)
+ cc2 = bt2.ClockClass('mix', 5678)
+ cc3 = bt2.ClockClass('lel', 1548)
+ cc_prio_map = bt2.ClockClassPriorityMap({cc1: 17, cc2: 2, cc3: 25})
+ cc_prio_map_cpy = copy.deepcopy(cc_prio_map)
+ self.assertEqual(cc_prio_map, cc_prio_map_cpy)
+ self.assertNotEqual(list(cc_prio_map.keys())[0].addr, list(cc_prio_map_cpy.keys())[0].addr)
+ self.assertNotEqual(list(cc_prio_map.keys())[1].addr, list(cc_prio_map_cpy.keys())[1].addr)
+ self.assertNotEqual(list(cc_prio_map.keys())[2].addr, list(cc_prio_map_cpy.keys())[2].addr)
+ self.assertEqual(list(cc_prio_map.values())[0], list(cc_prio_map_cpy.values())[0])
+ self.assertEqual(list(cc_prio_map.values())[1], list(cc_prio_map_cpy.values())[1])
+ self.assertEqual(list(cc_prio_map.values())[2], list(cc_prio_map_cpy.values())[2])
+ self.assertNotEqual(cc_prio_map.highest_priority_clock_class.addr,
+ cc_prio_map_cpy.highest_priority_clock_class.addr)
+++ /dev/null
-from collections import OrderedDict
-import unittest
-import copy
-import bt2.notification_iterator
-import bt2
-
-
-def _create_ec():
- # clock class
- cc = bt2.ClockClass('salut_clock')
-
- # event header
- eh = bt2.StructureFieldType()
- eh += OrderedDict((
- ('id', bt2.IntegerFieldType(8)),
- ('ts', bt2.IntegerFieldType(32, mapped_clock_class=cc)),
- ))
-
- # packet context
- pc = bt2.StructureFieldType()
- pc += OrderedDict((
- ('something', bt2.IntegerFieldType(8)),
- ))
-
- # stream class
- sc = bt2.StreamClass()
- sc.packet_context_field_type = pc
- sc.event_header_field_type = eh
- sc.event_context_field_type = None
-
- # event payload
- ep = bt2.StructureFieldType()
- ep += OrderedDict((
- ('mosquito', bt2.StringFieldType()),
- ))
-
- # event class
- event_class = bt2.EventClass('ec', id=0)
- event_class.context_field_type = None
- event_class.payload_field_type = ep
- sc.add_event_class(event_class)
-
- # packet header
- ph = bt2.StructureFieldType()
- ph += OrderedDict((
- ('magic', bt2.IntegerFieldType(32)),
- ('stream_id', bt2.IntegerFieldType(16)),
- ))
-
- # trace
- trace = bt2.Trace()
- trace.packet_header_field_type = ph
- trace.add_clock_class(cc)
- trace.add_stream_class(sc)
- return event_class
-
-
-def _create_event(event_class, msg):
- ev = event_class()
- ev.header_field['id'] = 0
- ev.header_field['ts'] = 19487
- ev.payload_field['mosquito'] = msg
- return ev
-
-
-def _create_packet(stream):
- packet = stream.create_packet()
- packet.header_field['magic'] = 0xc1fc1fc1
- packet.header_field['stream_id'] = 0
- packet.context_field['something'] = 194
- return packet
-
-
-def _create_source():
- class MyIter(bt2.UserNotificationIterator):
- def __init__(self):
- self._event_class = self.component._event_class
- self._stream = self.component._stream
- self._packet = _create_packet(self._stream)
- self._at = 0
- self._cur_notif = None
-
- def _get(self):
- if self._cur_notif is None:
- raise bt2.Error('nothing here!')
-
- return self._cur_notif
-
- def _next(self):
- if self._at == 0:
- notif = bt2.BeginningOfPacketNotification(self._packet)
- elif self._at < 5:
- ev = _create_event(self._event_class, 'at {}'.format(self._at))
- ev.packet = self._packet
- notif = bt2.TraceEventNotification(ev)
- elif self._at == 5:
- notif = bt2.EndOfPacketNotification(self._packet)
- elif self._at == 6:
- notif = bt2.EndOfStreamNotification(self._stream)
- else:
- raise bt2.Stop
-
- self._at += 1
- self._cur_notif = notif
-
- class MySource(bt2.UserSourceComponent, notification_iterator_class=MyIter):
- def __init__(self):
- self._event_class = _create_ec()
- self._stream = self._event_class.stream_class(name='abcdef')
-
- return MySource()
-
-
-class GenCompClassTestCase(unittest.TestCase):
- def test_attr_name(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- sink = MySink()
- self.assertEqual(sink.component_class.name, 'MySink')
-
- def test_attr_description(self):
- class MySink(bt2.UserSinkComponent):
- '''This is the description.
-
- This is the help.
-
- This too:
-
- * And this.
- * And also that.
-
- Voilà.
- '''
-
- def _consume(self):
- pass
-
- sink = MySink()
- self.assertEqual(sink.component_class.description,
- 'This is the description.')
-
- def test_attr_help(self):
- class MySink(bt2.UserSinkComponent):
- '''This is the description.
-
- This is the help.
-
- This too:
-
- * And this.
- * And also that.
-
- Voilà.
- '''
-
- def _consume(self):
- pass
-
- sink = MySink()
- expected_help = '''This is the help.
-
-This too:
-
- * And this.
- * And also that.
-
-Voilà.'''
- self.assertEqual(sink.component_class.help, expected_help)
-
- def test_instantiate(self):
- class MySink(bt2.UserSinkComponent):
- 'hello'
-
- def __init__(self, params=None, name=None):
- if params is None or name is None:
- return
-
- nonlocal nl_params_a, nl_name
- nl_params_a = params['a']
- nl_name = name
-
- def _consume(self):
- pass
-
- nl_params_a = None
- nl_name = None
- sink = MySink()
- self.assertIsNone(nl_params_a)
- self.assertIsNone(nl_name)
- gen_comp_class = sink.component_class
- sink2 = gen_comp_class(params={'a': 23}, name='salut')
- self.assertEqual(nl_params_a, 23)
- self.assertEqual(nl_name, 'salut')
-
-
-class UserCompClassTestCase(unittest.TestCase):
- def test_attr_name(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- self.assertEqual(MySink.name, 'MySink')
-
- def test_attr_name_param(self):
- class MySink(bt2.UserSinkComponent, name='my custom name'):
- def _consume(self):
- pass
-
- self.assertEqual(MySink.name, 'my custom name')
-
- def test_attr_description(self):
- class MySink(bt2.UserSinkComponent):
- '''This is the description.
-
- This is the help.
-
- This too:
-
- * And this.
- * And also that.
-
- Voilà.
- '''
-
- def _consume(self):
- pass
-
- self.assertEqual(MySink.description, 'This is the description.')
-
- def test_attr_help(self):
- class MySink(bt2.UserSinkComponent):
- '''This is the description.
-
- This is the help.
-
- This too:
-
- * And this.
- * And also that.
-
- Voilà.
- '''
-
- def _consume(self):
- pass
-
- expected_help = '''This is the help.
-
-This too:
-
- * And this.
- * And also that.
-
-Voilà.'''
- self.assertEqual(MySink.help, expected_help)
-
- def test_query_missing(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- with self.assertRaises(bt2.Error):
- MySink.query('salut')
-
- def test_query_raises(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- @staticmethod
- def _query(obj, params):
- raise ValueError
-
- with self.assertRaises(bt2.Error):
- MySink.query('salut')
-
- def test_query_gets_none_params(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- @staticmethod
- def _query(obj, params):
- nonlocal recv_params
- recv_params = params
-
- recv_params = NotImplemented
- MySink.query('allo', None)
- self.assertIsNone(recv_params)
-
- def test_query_gets_same_params(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- @staticmethod
- def _query(obj, params):
- nonlocal recv_params
- recv_params = params
-
- recv_params = NotImplemented
- params = bt2.create_value(23)
- MySink.query('allo', params)
- self.assertEqual(recv_params.addr, params.addr)
-
- def test_query_obj(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- @staticmethod
- def _query(obj, params):
- nonlocal recv_obj
- recv_obj = obj
-
- recv_obj = None
- MySink.query('salut')
- self.assertEqual(recv_obj, 'salut')
-
- def test_query_returns_none(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- @staticmethod
- def _query(obj, params):
- pass
-
- self.assertIsNone(MySink.query('allo', 177))
-
- def test_query_returns_params(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- @staticmethod
- def _query(obj, params):
- return {'obj': obj, 'params': params}
-
- results = MySink.query('hello', (45, 'lol'))
- self.assertEqual(results['obj'], 'hello')
- self.assertEqual(results['params'], (45, 'lol'))
-
- def test_init(self):
- class MySink(bt2.UserSinkComponent):
- def __init__(self):
- nonlocal inited
- inited = True
-
- def _consume(self):
- pass
-
- inited = False
- sink = MySink()
- self.assertTrue(inited)
-
- def test_init_raises(self):
- class MySink(bt2.UserSinkComponent):
- def __init__(self):
- raise RuntimeError('oops')
-
- def _consume(self):
- pass
-
- with self.assertRaises(RuntimeError):
- sink = MySink()
-
- def test_destroy(self):
- class MySink(bt2.UserSinkComponent):
- def _destroy(self):
- nonlocal destroyed
- destroyed = True
-
- def _consume(self):
- pass
-
- destroyed = False
- sink = MySink()
- del sink
- self.assertTrue(destroyed)
-
- def test_destroy_raises(self):
- class MySink(bt2.UserSinkComponent):
- def _destroy(self):
- raise RuntimeError('oh oh')
- nonlocal destroyed
- destroyed = True
-
- def _consume(self):
- pass
-
- destroyed = False
- sink = MySink()
- del sink
- self.assertFalse(destroyed)
-
- def test_comp_attr_name(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- sink = MySink(name='salut')
- self.assertEqual(sink.name, 'salut')
-
- def test_comp_attr_no_name(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- sink = MySink()
- self.assertIsNone(sink.name)
-
- def test_comp_attr_class(self):
- class MySink(bt2.UserSinkComponent):
- def _consume(self):
- pass
-
- sink = MySink()
- self.assertEqual(sink.component_class.name, 'MySink')
-
-
-class UserSinkCompClassTestCase(unittest.TestCase):
- def test_missing_consume(self):
- with self.assertRaises(bt2.IncompleteUserClassError):
- class MySink(bt2.UserSinkComponent):
- pass
-
- def test_set_min_input(self):
- class MySink(bt2.UserSinkComponent):
- def __init__(self):
- self._maximum_input_notification_iterator_count = 10
- self._minimum_input_notification_iterator_count = 5
-
- def _consume(self):
- pass
-
- sink = MySink()
-
- def test_set_max_input(self):
- class MySink(bt2.UserSinkComponent):
- def __init__(self):
- self._maximum_input_notification_iterator_count = 5
-
- def _consume(self):
- pass
-
- sink = MySink()
-
- def test_consume(self):
- class MySink(bt2.UserSinkComponent):
- def __init__(self):
- pass
-
- def _consume(self):
- nonlocal consumed
- consumed = True
-
- sink = MySink()
- consumed = False
- source = _create_source()
- notif_iter = source.create_notification_iterator()
- sink.add_notification_iterator(notif_iter)
- sink.consume()
- self.assertTrue(consumed)
-
- def test_consume_raises(self):
- class MySink(bt2.UserSinkComponent):
- def __init__(self):
- pass
-
- def _consume(self):
- raise RuntimeError('hello')
-
- sink = MySink()
- source = _create_source()
- notif_iter = source.create_notification_iterator()
- sink.add_notification_iterator(notif_iter)
-
- with self.assertRaises(bt2.Error):
- sink.consume()
-
- def test_add_notification_iterator(self):
- class MySink(bt2.UserSinkComponent):
- def __init__(self):
- pass
-
- def _consume(self):
- pass
-
- def _add_notification_iterator(self, notif_iter):
- nonlocal added
- added = True
-
- sink = MySink()
- added = False
- source = _create_source()
- notif_iter = source.create_notification_iterator()
- sink.add_notification_iterator(notif_iter)
- self.assertTrue(added)
-
- def test_input_notif_iterators(self):
- class MySink(bt2.UserSinkComponent):
- def __init__(self):
- self._maximum_input_notification_iterator_count = 5
-
- def _consume(self):
- nonlocal count
- count = 0
-
- for notif_iter in self._input_notification_iterators:
- count += 1
-
- sink = MySink()
- count = 0
- source = _create_source()
- notif_iter1 = source.create_notification_iterator()
- notif_iter2 = source.create_notification_iterator()
- sink.add_notification_iterator(notif_iter1)
- sink.add_notification_iterator(notif_iter2)
- sink.consume()
- self.assertEqual(count, 2)
-
-
-class UserSourceCompClassTestCase(unittest.TestCase):
- def test_missing_notif_iterator_class(self):
- with self.assertRaises(bt2.IncompleteUserClassError):
- class MySource(bt2.UserSourceComponent):
- pass
-
- def test_invalid_notif_iterator_class(self):
- class Lel:
- pass
-
- with self.assertRaises(bt2.IncompleteUserClassError):
- class MySource(bt2.UserSourceComponent, notification_iterator_class=Lel):
- pass
-
- def test_notif_iterator_class_missing_get(self):
- class MyIter(bt2.UserNotificationIterator):
- def _next(self):
- pass
-
- with self.assertRaises(bt2.IncompleteUserClassError):
- class MySource(bt2.UserSourceComponent, notification_iterator_class=MyIter):
- pass
-
- def test_notif_iterator_class_missing_next(self):
- class MyIter(bt2.UserNotificationIterator):
- def _get(self):
- pass
-
- with self.assertRaises(bt2.IncompleteUserClassError):
- class MySource(bt2.UserSourceComponent, notification_iterator_class=MyIter):
- pass
-
- def test_create_notification_iterator(self):
- class MyIter(bt2.UserNotificationIterator):
- def __init__(self):
- nonlocal created
- created = True
-
- def _next(self):
- pass
-
- def _get(self):
- pass
-
- class MySource(bt2.UserSourceComponent, notification_iterator_class=MyIter):
- pass
-
- created = False
- source = MySource()
- notif_iter = source.create_notification_iterator()
- self.assertTrue(created)
-
-
-class UserSourceCompClassTestCase(unittest.TestCase):
- def test_missing_notif_iterator_class(self):
- with self.assertRaises(bt2.IncompleteUserClassError):
- class MyFilter(bt2.UserFilterComponent):
- pass
-
- def test_invalid_notif_iterator_class(self):
- class Lel:
- pass
-
- with self.assertRaises(bt2.IncompleteUserClassError):
- class MyFilter(bt2.UserFilterComponent, notification_iterator_class=Lel):
- pass
-
- def test_notif_iterator_class_missing_get(self):
- class MyIter(bt2.UserNotificationIterator):
- def _next(self):
- pass
-
- with self.assertRaises(bt2.IncompleteUserClassError):
- class MyFilter(bt2.UserFilterComponent, notification_iterator_class=MyIter):
- pass
-
- def test_notif_iterator_class_missing_next(self):
- class MyIter(bt2.UserNotificationIterator):
- def _get(self):
- pass
-
- with self.assertRaises(bt2.IncompleteUserClassError):
- class MyFilter(bt2.UserFilterComponent, notification_iterator_class=MyIter):
- pass
-
- def test_create_notification_iterator(self):
- class MyIter(bt2.UserNotificationIterator):
- def __init__(self):
- nonlocal created
- created = True
-
- def _next(self):
- pass
-
- def _get(self):
- pass
-
- class MyFilter(bt2.UserFilterComponent, notification_iterator_class=MyIter):
- pass
-
- created = False
- filter = MyFilter()
- notif_iter = filter.create_notification_iterator()
- self.assertTrue(created)
-
- def test_set_min_input(self):
- class MyIter(bt2.UserNotificationIterator):
- def _next(self):
- pass
-
- def _get(self):
- pass
-
- class MyFilter(bt2.UserFilterComponent, notification_iterator_class=MyIter):
- def __init__(self):
- self._maximum_input_notification_iterator_count = 10
- self._minimum_input_notification_iterator_count = 5
-
- filter = MyFilter()
-
- def test_set_max_input(self):
- class MyIter(bt2.UserNotificationIterator):
- def _next(self):
- pass
-
- def _get(self):
- pass
-
- class MyFilter(bt2.UserFilterComponent, notification_iterator_class=MyIter):
- def __init__(self):
- self._maximum_input_notification_iterator_count = 5
-
- filter = MyFilter()
-
- def test_add_notification_iterator(self):
- class MyIter(bt2.UserNotificationIterator):
- def _next(self):
- pass
-
- def _get(self):
- pass
-
- class MyFilter(bt2.UserFilterComponent, notification_iterator_class=MyIter):
- def __init__(self):
- pass
-
- def _add_notification_iterator(self, notif_iter):
- nonlocal added
- added = True
-
- filter = MyFilter()
- added = False
- source = _create_source()
- notif_iter = source.create_notification_iterator()
- filter.add_notification_iterator(notif_iter)
- self.assertTrue(added)
-
- def test_input_notif_iterators(self):
- class MyIter(bt2.UserNotificationIterator):
- def _next(self):
- pass
-
- def _get(self):
- pass
-
- class MyFilter(bt2.UserFilterComponent, notification_iterator_class=MyIter):
- def __init__(self):
- self._maximum_input_notification_iterator_count = 5
-
- def _test(self):
- nonlocal count
- count = 0
-
- for notif_iter in self._input_notification_iterators:
- count += 1
-
- filter = MyFilter()
- count = 0
- source = _create_source()
- notif_iter1 = source.create_notification_iterator()
- notif_iter2 = source.create_notification_iterator()
- filter.add_notification_iterator(notif_iter1)
- filter.add_notification_iterator(notif_iter2)
- filter._test()
- self.assertEqual(count, 2)
-
-
-class UserNotificationIteratorTestCase(unittest.TestCase):
- def test_init(self):
- class MyIter(bt2.UserNotificationIterator):
- def __init__(self):
- nonlocal inited
- inited = True
-
- def _next(self):
- pass
-
- def _get(self):
- pass
-
- class MySource(bt2.UserSourceComponent, notification_iterator_class=MyIter):
- pass
-
- inited = False
- source = MySource()
- notif_iter = source.create_notification_iterator()
- self.assertTrue(inited)
-
- def test_destroy(self):
- class MyIter(bt2.UserNotificationIterator):
- def _next(self):
- pass
-
- def _get(self):
- pass
-
- def _destroy(self):
- nonlocal destroyed
- destroyed = True
-
- class MySource(bt2.UserSourceComponent, notification_iterator_class=MyIter):
- pass
-
- source = MySource()
- notif_iter = source.create_notification_iterator()
- destroyed = False
- del notif_iter
- self.assertTrue(destroyed)
-
- def test_attr_component(self):
- class MyIter(bt2.UserNotificationIterator):
- def __init__(self):
- nonlocal source, is_same
- is_same = self.component is source
-
- def _next(self):
- pass
-
- def _get(self):
- pass
-
- class MySource(bt2.UserSourceComponent, notification_iterator_class=MyIter):
- pass
-
- source = MySource()
- is_same = False
- notif_iter = source.create_notification_iterator()
- self.assertTrue(is_same)
-
- def test_next_raises_stop(self):
- class MyIter(bt2.UserNotificationIterator):
- def _next(self):
- raise bt2.Stop
-
- def _get(self):
- pass
-
- class MySource(bt2.UserSourceComponent, notification_iterator_class=MyIter):
- pass
-
- source = MySource()
- is_same = False
- notif_iter = source.create_notification_iterator()
-
- with self.assertRaises(bt2.Stop):
- notif_iter.next()
-
- def test_next_raises_unsupported_feature(self):
- class MyIter(bt2.UserNotificationIterator):
- def _next(self):
- raise bt2.UnsupportedFeature
-
- def _get(self):
- pass
-
- class MySource(bt2.UserSourceComponent, notification_iterator_class=MyIter):
- pass
-
- source = MySource()
- is_same = False
- notif_iter = source.create_notification_iterator()
-
- with self.assertRaises(bt2.UnsupportedFeature):
- notif_iter.next()
-
- def test_next_raises_unknown(self):
- class MyIter(bt2.UserNotificationIterator):
- def _next(self):
- raise TypeError('lel')
-
- def _get(self):
- pass
-
- class MySource(bt2.UserSourceComponent, notification_iterator_class=MyIter):
- pass
-
- source = MySource()
- is_same = False
- notif_iter = source.create_notification_iterator()
-
- with self.assertRaises(bt2.Error):
- notif_iter.next()
-
- def test_iteration(self):
- source = _create_source()
- notif_iter = source.create_notification_iterator()
- pkt_addr = None
-
- for index, notif in enumerate(notif_iter):
- if index == 0:
- self.assertIsInstance(notif, bt2.BeginningOfPacketNotification)
- self.assertEqual(notif.packet.header_field['magic'], 0xc1fc1fc1)
- self.assertEqual(notif.packet.context_field['something'], 194)
- pkt_addr = notif.packet.addr
- elif index < 5:
- self.assertIsInstance(notif, bt2.TraceEventNotification)
- self.assertEqual(notif.event.header_field['ts'], 19487)
- self.assertEqual(notif.event.payload_field['mosquito'], 'at {}'.format(index))
- elif index == 5:
- self.assertIsInstance(notif, bt2.EndOfPacketNotification)
- self.assertEqual(notif.packet.header_field['magic'], 0xc1fc1fc1)
- self.assertEqual(notif.packet.context_field['something'], 194)
- self.assertEqual(notif.packet.addr, pkt_addr)
- elif index == 6:
- self.assertIsInstance(notif, bt2.EndOfStreamNotification)
- self.assertEqual(notif.stream.name, 'abcdef')
- else:
- raise RuntimeError('FAIL')
-
-
-class GenNotificationIteratorTestCase(unittest.TestCase):
- def test_attr_component(self):
- source = _create_source()
- notif_iter = source.create_notification_iterator()
- self.assertIsInstance(notif_iter, bt2.notification_iterator._GenericNotificationIterator)
- self.assertEqual(notif_iter.component.addr, source.addr)
--- /dev/null
+from bt2 import values
+import unittest
+import copy
+import bt2
+
+
+class UserComponentTestCase(unittest.TestCase):
+ @staticmethod
+ def _create_comp(comp_cls, name=None):
+ graph = bt2.Graph()
+
+ if name is None:
+ name = 'comp'
+
+ return graph.add_component(comp_cls, name)
+
+ def test_name(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ self.assertEqual(comp_self.name, 'yaes')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink, 'yaes')
+
+ def test_graph(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ nonlocal graph
+ self.assertEqual(comp_self.graph, graph)
+
+ def _consume(self):
+ pass
+
+ graph = bt2.Graph()
+ comp = graph.add_component(MySink, 'lel')
+ del graph
+
+ def test_class(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ self.assertEqual(comp_self.component_class, MySink)
+
+ def _consume(self):
+ pass
+
+ self._create_comp(MySink)
+
+ def test_addr(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ self.assertIsInstance(comp_self.addr, int)
+ self.assertNotEqual(comp_self.addr, 0)
+
+ def _consume(self):
+ pass
+
+ self._create_comp(MySink)
+
+ def test_finalize(self):
+ finalized = False
+
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ def _finalize(comp_self):
+ nonlocal finalized
+ finalized = True
+
+ graph = bt2.Graph()
+ comp = graph.add_component(MySink, 'lel')
+ del graph
+ del comp
+ self.assertTrue(finalized)
+
+
+class GenericComponentTestCase(unittest.TestCase):
+ @staticmethod
+ def _create_comp(comp_cls, name=None):
+ graph = bt2.Graph()
+
+ if name is None:
+ name = 'comp'
+
+ return graph.add_component(comp_cls, name)
+
+ def test_name(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink, 'yaes')
+ self.assertEqual(comp.name, 'yaes')
+
+ def test_graph(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ graph = bt2.Graph()
+ comp = graph.add_component(MySink, 'lel')
+ self.assertEqual(comp.graph, graph)
+
+ def test_class(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ self.assertEqual(comp.component_class, MySink)
+
+ def test_addr(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ self.assertIsInstance(comp.addr, int)
+ self.assertNotEqual(comp.addr, 0)
--- /dev/null
+from bt2 import values
+import unittest
+import copy
+import bt2
+
+
+class UserComponentClassTestCase(unittest.TestCase):
+ def _test_no_init(self, cls):
+ with self.assertRaises(bt2.Error):
+ cls()
+
+ def test_no_init_source(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ pass
+
+ self._test_no_init(MySource)
+
+ def test_no_init_filter(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ pass
+
+ self._test_no_init(MyFilter)
+
+ def test_no_init_sink(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ self._test_no_init(MySink)
+
+ def test_incomplete_source_no_notif_iter_cls(self):
+ class MyIter(bt2._UserNotificationIterator):
+ pass
+
+ with self.assertRaises(bt2.IncompleteUserClass):
+ class MySource(bt2._UserSourceComponent):
+ pass
+
+ def test_incomplete_source_wrong_notif_iter_cls_type(self):
+ class MyIter(bt2._UserNotificationIterator):
+ pass
+
+ with self.assertRaises(bt2.IncompleteUserClass):
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=int):
+ pass
+
+ def test_incomplete_filter_no_notif_iter_cls(self):
+ class MyIter(bt2._UserNotificationIterator):
+ pass
+
+ with self.assertRaises(bt2.IncompleteUserClass):
+ class MyFilter(bt2._UserFilterComponent):
+ pass
+
+ def test_incomplete_sink_no_consume_method(self):
+ class MyIter(bt2._UserNotificationIterator):
+ pass
+
+ with self.assertRaises(bt2.IncompleteUserClass):
+ class MySink(bt2._UserSinkComponent):
+ pass
+
+ def test_minimal_source(self):
+ class MyIter(bt2._UserNotificationIterator):
+ pass
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ pass
+
+ def test_minimal_filter(self):
+ class MyIter(bt2._UserNotificationIterator):
+ pass
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ pass
+
+ def test_minimal_sink(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ def test_default_name(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ self.assertEqual(MySink.name, 'MySink')
+
+ def test_custom_name(self):
+ class MySink(bt2._UserSinkComponent, name='salut'):
+ def _consume(self):
+ pass
+
+ self.assertEqual(MySink.name, 'salut')
+
+ def test_invalid_custom_name(self):
+ with self.assertRaises(TypeError):
+ class MySink(bt2._UserSinkComponent, name=23):
+ def _consume(self):
+ pass
+
+ def test_description(self):
+ class MySink(bt2._UserSinkComponent):
+ """
+ The description.
+
+ Bacon ipsum dolor amet ribeye t-bone corned beef, beef jerky
+ porchetta burgdoggen prosciutto chicken frankfurter boudin
+ hamburger doner bacon turducken. Sirloin shank sausage,
+ boudin meatloaf alcatra meatball t-bone tongue pastrami
+ cupim flank tenderloin.
+ """
+
+ def _consume(self):
+ pass
+
+ self.assertEqual(MySink.description, 'The description.')
+
+ def test_empty_description(self):
+ class MySink(bt2._UserSinkComponent):
+ """
+ """
+
+ def _consume(self):
+ pass
+
+ self.assertIsNone(MySink.description)
+
+ def test_help(self):
+ class MySink(bt2._UserSinkComponent):
+ """
+ The description.
+
+ The help
+ text is
+ here.
+ """
+
+ def _consume(self):
+ pass
+
+ self.assertEqual(MySink.help, 'The help\ntext is\nhere.')
+
+ def test_addr(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ self.assertIsInstance(MySink.addr, int)
+ self.assertNotEqual(MySink.addr, 0)
+
+ def test_query_not_implemented(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ with self.assertRaises(bt2.Error):
+ MySink.query('obj', 23)
+
+ def test_query_raises(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ @classmethod
+ def _query(cls, obj, params):
+ raise ValueError
+
+ with self.assertRaises(bt2.Error):
+ MySink.query('obj', 23)
+
+ def test_query_wrong_return_type(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ @classmethod
+ def _query(cls, obj, params):
+ return ...
+
+ with self.assertRaises(bt2.Error):
+ MySink.query('obj', 23)
+
+ def test_query_params_none(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ @classmethod
+ def _query(cls, obj, params):
+ nonlocal query_params
+ query_params = params
+ return None
+
+ query_params = None
+ params = None
+ res = MySink.query('obj', params)
+ self.assertEqual(query_params, params)
+ self.assertIsNone(res)
+ del query_params
+
+ def test_query_simple(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ @classmethod
+ def _query(cls, obj, params):
+ nonlocal query_params
+ query_params = params
+ return 17.5
+
+ query_params = None
+ params = ['coucou', 23, None]
+ res = MySink.query('obj', params)
+ self.assertEqual(query_params, params)
+ self.assertEqual(res, 17.5)
+ del query_params
+
+ def test_query_complex(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ @classmethod
+ def _query(cls, obj, params):
+ nonlocal query_params
+ query_params = params
+ return {
+ 'null': None,
+ 'bt2': 'BT2',
+ }
+
+ query_params = None
+ params = {
+ 'array': ['coucou', 23, None],
+ 'other_map': {
+ 'yes': 'yeah',
+ '19': 19,
+ 'minus 1.5': -1.5,
+ },
+ 'null': None,
+ }
+
+ res = MySink.query('obj', params)
+ self.assertEqual(query_params, params)
+ self.assertEqual(res, {
+ 'null': None,
+ 'bt2': 'BT2',
+ })
+ del query_params
+
+ def test_eq(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ self.assertEqual(MySink, MySink)
+
+
+class GenericComponentClassTestCase(unittest.TestCase):
+ def setUp(self):
+ class MySink(bt2._UserSinkComponent):
+ '''
+ The description.
+
+ The help.
+ '''
+ def _consume(self):
+ pass
+
+ @classmethod
+ def _query(cls, obj, params):
+ return [obj, params, 23]
+
+ self._py_comp_cls = MySink
+ graph = bt2.Graph()
+ comp = graph.add_component(MySink, 'salut')
+ self._comp_cls = comp.component_class
+ self.assertTrue(issubclass(type(self._comp_cls),
+ bt2.component._GenericComponentClass))
+
+ def tearDown(self):
+ del self._py_comp_cls
+ del self._comp_cls
+
+ def test_description(self):
+ self.assertEqual(self._comp_cls.description, 'The description.')
+
+ def test_help(self):
+ self.assertEqual(self._comp_cls.help, 'The help.')
+
+ def test_name(self):
+ self.assertEqual(self._comp_cls.name, 'MySink')
+
+ def test_addr(self):
+ self.assertIsInstance(self._comp_cls.addr, int)
+ self.assertNotEqual(self._comp_cls.addr, 0)
+
+ def test_eq_invalid(self):
+ self.assertFalse(self._comp_cls == 23)
+
+ def test_eq(self):
+ self.assertEqual(self._comp_cls, self._comp_cls)
+ self.assertEqual(self._py_comp_cls, self._comp_cls)
+
+ def test_query(self):
+ res = self._comp_cls.query('an object', {'yes': 'no', 'book': -17})
+ expected = ['an object', {'yes': 'no', 'book': -17}, 23]
+ self.assertEqual(res, expected)
--- /dev/null
+from bt2 import values
+import unittest
+import copy
+import bt2
+
+
+class ConnectionTestCase(unittest.TestCase):
+ def test_create(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertIsInstance(conn, bt2._Connection)
+ self.assertNotIsInstance(conn, bt2._PrivateConnection)
+
+ def test_is_ended_false(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertFalse(conn.is_ended)
+
+ def test_is_ended_true(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ src.output_ports['out'].disconnect()
+ self.assertTrue(conn.is_ended)
+
+ def test_downstream_port(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertEqual(conn.downstream_port.addr, sink.input_ports['in'].addr)
+
+ def test_upstream_port(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertEqual(conn.upstream_port.addr, src.output_ports['out'].addr)
+
+ def test_eq(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertEqual(conn, conn)
+
+ def test_eq_invalid(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertNotEqual(conn, 23)
+
+
+class PrivateConnectionTestCase(unittest.TestCase):
+ def test_create(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ def _port_connected(self, port, other_port):
+ nonlocal priv_conn
+ priv_conn = port.connection
+
+ priv_conn = None
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertIsInstance(priv_conn, bt2._PrivateConnection)
+ self.assertEqual(conn, priv_conn)
+ del priv_conn
+
+ def test_is_ended_false(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ def _port_connected(self, port, other_port):
+ nonlocal priv_conn
+ priv_conn = port.connection
+
+ priv_conn = None
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertFalse(priv_conn.is_ended)
+ del priv_conn
+
+ def test_is_ended_true(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ def _port_connected(self, port, other_port):
+ nonlocal priv_conn
+ priv_conn = port.connection
+
+ priv_conn = None
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ sink.input_ports['in'].disconnect()
+ self.assertTrue(priv_conn.is_ended)
+ del priv_conn
+
+ def test_downstream_port(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ def _port_connected(self, port, other_port):
+ nonlocal priv_port
+ priv_conn = port.connection
+ priv_port = priv_conn.downstream_port
+
+ priv_port = None
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertEqual(priv_port.addr, sink.input_ports['in'].addr)
+ del priv_port
+
+ def test_upstream_port(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ def _port_connected(self, port, other_port):
+ nonlocal priv_port
+ priv_conn = port.connection
+ priv_port = priv_conn.upstream_port
+
+ priv_port = None
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertEqual(priv_port.addr, src.output_ports['out'].addr)
+ del priv_port
+
+ def test_eq(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ def _port_connected(self, port, other_port):
+ nonlocal priv_conn
+ priv_conn = port.connection
+
+ priv_conn = None
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertEqual(priv_conn, conn)
+ del priv_conn
+
+ def test_eq_invalid(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ def _port_connected(self, port, other_port):
+ nonlocal priv_conn
+ priv_conn = port.connection
+
+ priv_conn = None
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertNotEqual(priv_conn, 23)
+ del priv_conn
def setUp(self):
self._clock = bt2.CtfWriterClock('salut')
+ def tearDown(self):
+ del self._clock
+
def test_create_default(self):
self.assertEqual(self._clock.name, 'salut')
def setUp(self):
self._ec = self._create_ec()
+ def tearDown(self):
+ del self._ec
+
def _create_ec(self, with_eh=True, with_sec=True, with_ec=True, with_ep=True):
# event header
if with_eh:
def test_clock_value(self):
tc = bt2.Trace()
tc.add_stream_class(self._ec.stream_class)
- cc = bt2.ClockClass('hi')
+ cc = bt2.ClockClass('hi', 1000)
tc.add_clock_class(cc)
ev = self._ec()
- ev.set_clock_value(cc.create_clock_value(177))
- self.assertEqual(ev.get_clock_value(cc).cycles, 177)
+ ev.add_clock_value(cc(177))
+ self.assertEqual(ev.clock_value(cc).cycles, 177)
def test_no_clock_value(self):
tc = bt2.Trace()
tc.add_stream_class(self._ec.stream_class)
- cc = bt2.ClockClass('hi')
+ cc = bt2.ClockClass('hi', 1000)
tc.add_clock_class(cc)
ev = self._ec()
- self.assertIsNone(ev.get_clock_value(cc))
+ self.assertIsNone(ev.clock_value(cc))
def test_no_packet(self):
ev = self._ec()
def _get_full_ev(self):
tc = bt2.Trace()
tc.add_stream_class(self._ec.stream_class)
- cc = bt2.ClockClass('hi')
+ cc = bt2.ClockClass('hi', 1000)
tc.add_clock_class(cc)
ev = self._ec()
self._fill_ev(ev)
def test_eq(self):
tc = bt2.Trace()
tc.add_stream_class(self._ec.stream_class)
- cc = bt2.ClockClass('hi')
+ cc = bt2.ClockClass('hi', 1000)
tc.add_clock_class(cc)
ev1 = self._ec()
self._fill_ev(ev1)
- ev1.set_clock_value(cc.create_clock_value(234))
+ ev1.add_clock_value(cc(234))
ev2 = self._ec()
self._fill_ev(ev2)
- ev2.set_clock_value(cc.create_clock_value(234))
+ ev2.add_clock_value(cc(234))
self.assertEqual(ev1, ev2)
def test_ne_header_field(self):
tc = bt2.Trace()
tc.add_stream_class(self._ec.stream_class)
- cc = bt2.ClockClass('hi')
+ cc = bt2.ClockClass('hi', 1000)
tc.add_clock_class(cc)
ev1 = self._ec()
self._fill_ev(ev1)
ev1.header_field['id'] = 19
- ev1.set_clock_value(cc.create_clock_value(234))
+ ev1.add_clock_value(cc(234))
ev2 = self._ec()
self._fill_ev(ev2)
- ev2.set_clock_value(cc.create_clock_value(234))
+ ev2.add_clock_value(cc(234))
self.assertNotEqual(ev1, ev2)
def test_ne_stream_event_context_field(self):
tc = bt2.Trace()
tc.add_stream_class(self._ec.stream_class)
- cc = bt2.ClockClass('hi')
+ cc = bt2.ClockClass('hi', 1000)
tc.add_clock_class(cc)
ev1 = self._ec()
self._fill_ev(ev1)
ev1.stream_event_context_field['cpu_id'] = 3
- ev1.set_clock_value(cc.create_clock_value(234))
+ ev1.add_clock_value(cc(234))
ev2 = self._ec()
self._fill_ev(ev2)
- ev2.set_clock_value(cc.create_clock_value(234))
+ ev2.add_clock_value(cc(234))
self.assertNotEqual(ev1, ev2)
def test_ne_context_field(self):
tc = bt2.Trace()
tc.add_stream_class(self._ec.stream_class)
- cc = bt2.ClockClass('hi')
+ cc = bt2.ClockClass('hi', 1000)
tc.add_clock_class(cc)
ev1 = self._ec()
self._fill_ev(ev1)
ev1.context_field['ant'] = -3
- ev1.set_clock_value(cc.create_clock_value(234))
+ ev1.add_clock_value(cc(234))
ev2 = self._ec()
self._fill_ev(ev2)
- ev2.set_clock_value(cc.create_clock_value(234))
+ ev2.add_clock_value(cc(234))
self.assertNotEqual(ev1, ev2)
def test_ne_payload_field(self):
tc = bt2.Trace()
tc.add_stream_class(self._ec.stream_class)
- cc = bt2.ClockClass('hi')
+ cc = bt2.ClockClass('hi', 1000)
tc.add_clock_class(cc)
ev1 = self._ec()
self._fill_ev(ev1)
ev1.payload_field['mosquito'] = 98
- ev1.set_clock_value(cc.create_clock_value(234))
+ ev1.add_clock_value(cc(234))
ev2 = self._ec()
self._fill_ev(ev2)
- ev2.set_clock_value(cc.create_clock_value(234))
+ ev2.add_clock_value(cc(234))
self.assertNotEqual(ev1, ev2)
def test_eq_invalid(self):
def _test_copy(self, func):
tc = bt2.Trace()
tc.add_stream_class(self._ec.stream_class)
- cc = bt2.ClockClass('hi')
+ cc = bt2.ClockClass('hi', 1000)
tc.add_clock_class(cc)
ev = self._ec()
self._fill_ev(ev)
- ev.set_clock_value(cc.create_clock_value(234))
+ ev.add_clock_value(cc(234))
cpy = func(ev)
self.assertIsNot(ev, cpy)
self.assertNotEqual(ev.addr, cpy.addr)
self._payload_ft.append_field('zoom', bt2.StringFieldType())
self._ec = bt2.EventClass('my_event')
self._ec.id = 18
+ self._ec.emf_uri = 'yes'
+ self._ec.log_level = bt2.EventClassLogLevel.INFO
self._ec.context_field_type = self._context_ft
self._ec.payload_field_type = self._payload_ft
+ def tearDown(self):
+ del self._context_ft
+ del self._payload_ft
+ del self._ec
+
def test_create(self):
self.assertEqual(self._ec.name, 'my_event')
self.assertEqual(self._ec.id, 18)
self.assertEqual(self._ec.context_field_type, self._context_ft)
self.assertEqual(self._ec.payload_field_type, self._payload_ft)
+ self.assertEqual(self._ec.emf_uri, 'yes')
+ self.assertEqual(self._ec.log_level, bt2.EventClassLogLevel.INFO)
def test_create_invalid_no_name(self):
with self.assertRaises(TypeError):
ec = bt2.EventClass(name='name', id=23,
context_field_type=self._context_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
self.assertEqual(ec.name, 'name')
self.assertEqual(ec.id, 23)
self.assertEqual(ec.context_field_type, self._context_ft)
self.assertEqual(ec.payload_field_type, self._payload_ft)
- self.assertEqual(ec.attributes['model.emf.uri'], 'my URI')
+ self.assertEqual(ec.emf_uri, 'my URI')
+ self.assertEqual(ec.log_level, bt2.EventClassLogLevel.WARNING)
def test_assign_id(self):
self._ec.id = 1717
self.assertNotEqual(self._ec.context_field_type.addr, cpy.context_field_type.addr)
self.assertNotEqual(self._ec.payload_field_type.addr, cpy.payload_field_type.addr)
- def test_attr_getitem(self):
- self.assertEqual(self._ec.attributes['id'], 18)
- self.assertEqual(self._ec.attributes['name'], 'my_event')
-
- def test_attr_setitem(self):
- self._ec.attributes['model.emf.uri'] = 'my url'
- self.assertEqual(self._ec.attributes['model.emf.uri'], 'my url')
+ def test_assign_emf_uri(self):
+ self._ec.emf_uri = 'salut'
+ self.assertEqual(self._ec.emf_uri, 'salut')
- def test_attr_len(self):
- self.assertTrue(len(self._ec.attributes) != 0)
+ def test_assign_invalid_emf_uri(self):
+ with self.assertRaises(TypeError):
+ self._ec.emf_uri = 23
- def test_attr_iter(self):
- for name, value in self._ec.attributes.items():
- self.assertIsInstance(value, values._Value)
+ def test_assign_log_level(self):
+ self._ec.log_level = bt2.EventClassLogLevel.EMERGENCY
+ self.assertEqual(self._ec.log_level, bt2.EventClassLogLevel.EMERGENCY)
- if name == 'name':
- self.assertEqual(value, 'my_event')
- elif name == 'id':
- self.assertEqual(value, 18)
+ def test_assign_invalid_log_level(self):
+ with self.assertRaises(ValueError):
+ self._ec.log_level = 'zoom'
def test_eq(self):
ec1 = bt2.EventClass(name='name', id=23,
context_field_type=self._context_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
ec2 = bt2.EventClass(name='name', id=23,
context_field_type=self._context_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
self.assertEqual(ec1, ec2)
def test_ne_name(self):
ec1 = bt2.EventClass(name='name1', id=23,
context_field_type=self._context_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
ec2 = bt2.EventClass(name='name', id=23,
context_field_type=self._context_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
self.assertNotEqual(ec1, ec2)
def test_ne_id(self):
ec1 = bt2.EventClass(name='name', id=24,
context_field_type=self._context_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
ec2 = bt2.EventClass(name='name', id=23,
context_field_type=self._context_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
self.assertNotEqual(ec1, ec2)
def test_ne_context_field_type(self):
ec1 = bt2.EventClass(name='name', id=23,
context_field_type=self._payload_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
ec2 = bt2.EventClass(name='name', id=23,
context_field_type=self._context_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
self.assertNotEqual(ec1, ec2)
def test_ne_payload_field_type(self):
ec1 = bt2.EventClass(name='name', id=23,
context_field_type=self._context_ft,
payload_field_type=self._context_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
+ ec2 = bt2.EventClass(name='name', id=23,
+ context_field_type=self._context_ft,
+ payload_field_type=self._payload_ft,
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
+ self.assertNotEqual(ec1, ec2)
+
+ def test_ne_emf_uri(self):
+ ec1 = bt2.EventClass(name='name', id=23,
+ context_field_type=self._context_ft,
+ payload_field_type=self._payload_ft,
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
ec2 = bt2.EventClass(name='name', id=23,
context_field_type=self._context_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my UR',
+ log_level=bt2.EventClassLogLevel.WARNING)
self.assertNotEqual(ec1, ec2)
- def test_ne_attribute(self):
+ def test_ne_log_level(self):
ec1 = bt2.EventClass(name='name', id=23,
context_field_type=self._context_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my URI'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.WARNING)
ec2 = bt2.EventClass(name='name', id=23,
context_field_type=self._context_ft,
payload_field_type=self._payload_ft,
- attributes={'model.emf.uri': 'my UR'})
+ emf_uri='my URI',
+ log_level=bt2.EventClassLogLevel.ERROR)
self.assertNotEqual(ec1, ec2)
def test_eq_invalid(self):
self._ft.encoding = 'hey'
def test_assign_mapped_clock_class(self):
- cc = bt2.ClockClass('name')
+ cc = bt2.ClockClass('name', 1000)
self._ft.mapped_clock_class = cc
self.assertEqual(self._ft.mapped_clock_class, cc)
def setUp(self):
self._ft = bt2.IntegerFieldType(35)
+ def tearDown(self):
+ del self._ft
+
def test_create_default(self):
self.assertEqual(self._ft.size, 35)
+ self.assertIsNone(self._ft.mapped_clock_class)
def test_create_invalid_size(self):
with self.assertRaises(TypeError):
ft = bt2.IntegerFieldType(0)
def test_create_full(self):
- cc = bt2.ClockClass('name')
+ cc = bt2.ClockClass('name', 1000)
ft = bt2.IntegerFieldType(24, alignment=16,
byte_order=bt2.ByteOrder.BIG_ENDIAN,
is_signed=True, base=bt2.Base.OCTAL,
def setUp(self):
self._ft = bt2.FloatingPointNumberFieldType()
+ def tearDown(self):
+ del self._ft
+
def test_create_default(self):
pass
def setUp(self):
self._ft = bt2.EnumerationFieldType(size=35)
+ def tearDown(self):
+ del self._ft
+
def test_create_from_int_ft(self):
int_ft = bt2.IntegerFieldType(23)
self._ft = bt2.EnumerationFieldType(int_ft)
def setUp(self):
self._ft = bt2.StringFieldType()
+ def tearDown(self):
+ del self._ft
+
def test_create_default(self):
pass
with self.assertRaises(TypeError):
self._ft.at_index('yes')
+ def test_at_index_out_of_bounds_after(self):
+ self._ft.append_field('c', bt2.IntegerFieldType(32))
+
+ with self.assertRaises(IndexError):
+ self._ft.at_index(len(self._ft))
+
class StructureFieldTypeTestCase(_TestFieldContainer, unittest.TestCase):
def setUp(self):
self._ft = bt2.StructureFieldType()
+ def tearDown(self):
+ del self._ft
+
def test_create_default(self):
self.assertEqual(self._ft.alignment, 1)
def setUp(self):
self._ft = bt2.VariantFieldType('path.to.tag')
+ def tearDown(self):
+ del self._ft
+
def test_create_default(self):
self.assertEqual(self._ft.tag_name, 'path.to.tag')
self._elem_ft = bt2.IntegerFieldType(23)
self._ft = bt2.ArrayFieldType(self._elem_ft, 45)
+ def tearDown(self):
+ del self._ft
+ del self._elem_ft
+
def test_create_default(self):
self.assertEqual(self._ft.element_field_type, self._elem_ft)
self.assertEqual(self._ft.length, 45)
self._elem_ft = bt2.IntegerFieldType(23)
self._ft = bt2.SequenceFieldType(self._elem_ft, 'the.length')
+ def tearDown(self):
+ del self._ft
+ del self._elem_ft
+
def test_create_default(self):
self.assertEqual(self._ft.element_field_type, self._elem_ft)
self.assertEqual(self._ft.length_name, 'the.length')
# inject testing methods for each binary operation
for name, binop in _BINOPS:
-
setattr(cls, test_binop_name('invalid_unknown'), partialmethod(_TestNumericField._test_binop_invalid_unknown, op=binop))
setattr(cls, test_binop_name('invalid_none'), partialmethod(_TestNumericField._test_binop_invalid_none, op=binop))
setattr(cls, test_binop_name('type_true'), partialmethod(_TestNumericField._test_binop_type_true, op=binop))
self._def_value = 17
self._def_new_value = -101
+ def tearDown(self):
+ del self._ft
+ del self._field
+ del self._def
+
class EnumerationFieldTestCase(_TestIntegerFieldCommon, unittest.TestCase):
def setUp(self):
self._ft = bt2.EnumerationFieldType(size=32, is_signed=True)
self._ft.append_mapping('whole range', -(2 ** 31), (2 ** 31) - 1)
+ self._ft.append_mapping('something', 17)
+ self._ft.append_mapping('speaker', 12, 16)
+ self._ft.append_mapping('can', 18, 2540)
+ self._ft.append_mapping('zip', -45, 1001)
self._def = self._ft()
self._def.value = 17
self._def_value = 17
self._def_new_value = -101
+ def tearDown(self):
+ del self._ft
+ del self._def
+
+ def test_mappings(self):
+ mappings = (
+ ('whole range', -(2 ** 31), (2 ** 31) - 1),
+ ('something', 17, 17),
+ ('zip', -45, 1001),
+ )
+
+ total = 0
+ index_set = set()
+
+ for fm in self._def.mappings:
+ total += 1
+ for index, mapping in enumerate(mappings):
+ if fm.name == mapping[0] and fm.lower == mapping[1] and fm.upper == mapping[2]:
+ index_set.add(index)
+
+ self.assertEqual(total, 3)
+ self.assertTrue(0 in index_set and 1 in index_set and 2 in index_set)
+
class FloatingPointNumberFieldTestCase(_TestNumericField, unittest.TestCase):
def setUp(self):
self._def_value = 52.7
self._def_new_value = -17.164857
+ def tearDown(self):
+ del self._ft
+ del self._field
+ del self._def
+
def _test_invalid_op(self, cb):
with self.assertRaises(TypeError):
cb()
self._def.value = self._def_value
self._def_new_value = 'Yes!'
+ def tearDown(self):
+ del self._ft
+ del self._def
+
def test_assign_int(self):
with self.assertRaises(TypeError):
self._def.value = 283
self._def[1] = 1847
self._def[2] = 1948754
+ def tearDown(self):
+ del self._elem_ft
+ del self._ft
+ del self._def
+
class SequenceFieldTestCase(_TestArraySequenceFieldCommon, unittest.TestCase):
def setUp(self):
self._def[1] = 1847
self._def[2] = 1948754
+ def tearDown(self):
+ del self._elem_ft
+ del self._ft
+ del self._def
+ del self._length_field
+
class StructureFieldTestCase(_TestCopySimple, unittest.TestCase):
def setUp(self):
self._def['C'] = 17.5
self._def['D'] = 16497
+ def tearDown(self):
+ del self._ft0
+ del self._ft1
+ del self._ft2
+ del self._ft3
+ del self._ft
+ del self._def
+
def _modify_def(self):
self._def['B'] = 'hola'
self.assertIs(type(field), bt2.fields._IntegerField)
self.assertEqual(field, -1872)
+ def test_at_index_out_of_bounds_after(self):
+ with self.assertRaises(IndexError):
+ self._def.at_index(len(self._ft))
+
def test_eq(self):
ft = bt2.StructureFieldType()
ft.append_field('A', self._ft0)
for vkey, vval in self._def.items():
val = orig_values[vkey]
self.assertEqual(vval, val)
+
+
+class VariantFieldTestCase(_TestCopySimple, unittest.TestCase):
+ def setUp(self):
+ self._tag_ft = bt2.EnumerationFieldType(size=32)
+ self._tag_ft.append_mapping('corner', 23)
+ self._tag_ft.append_mapping('zoom', 17, 20)
+ self._tag_ft.append_mapping('mellotron', 1001)
+ self._tag_ft.append_mapping('giorgio', 2000, 3000)
+ self._ft0 = bt2.IntegerFieldType(32, is_signed=True)
+ self._ft1 = bt2.StringFieldType()
+ self._ft2 = bt2.FloatingPointNumberFieldType()
+ self._ft3 = bt2.IntegerFieldType(17)
+ self._ft = bt2.VariantFieldType('salut', self._tag_ft)
+ self._ft.append_field('corner', self._ft0)
+ self._ft.append_field('zoom', self._ft1)
+ self._ft.append_field('mellotron', self._ft2)
+ self._ft.append_field('giorgio', self._ft3)
+ self._def = self._ft()
+
+ def tearDown(self):
+ del self._tag_ft
+ del self._ft0
+ del self._ft1
+ del self._ft2
+ del self._ft3
+ del self._ft
+ del self._def
+
+ def test_bool_op_true(self):
+ tag_field = self._tag_ft(1001)
+ self._def.field(tag_field).value = -17.34
+ self.assertTrue(self._def)
+
+ def test_bool_op_false(self):
+ self.assertFalse(self._def)
+
+ def test_tag_field_none(self):
+ self.assertIsNone(self._def.tag_field)
+
+ def test_tag_field(self):
+ tag_field = self._tag_ft(2800)
+ self._def.field(tag_field).value = 1847
+ self.assertEqual(self._def.tag_field, tag_field)
+ self.assertEqual(self._def.tag_field.addr, tag_field.addr)
+
+ def test_selected_field_none(self):
+ self.assertIsNone(self._def.selected_field)
+
+ def test_selected_field(self):
+ var_field1 = self._ft()
+ tag_field1 = self._tag_ft(1001)
+ var_field1.field(tag_field1).value = -17.34
+ self.assertEqual(var_field1.field(), -17.34)
+ self.assertEqual(var_field1.selected_field, -17.34)
+ var_field2 = self._ft()
+ tag_field2 = self._tag_ft(2500)
+ var_field2.field(tag_field2).value = 1921
+ self.assertEqual(var_field2.field(), 1921)
+ self.assertEqual(var_field2.selected_field, 1921)
+
+ def test_eq(self):
+ tag_ft = bt2.EnumerationFieldType(size=32)
+ tag_ft.append_mapping('corner', 23)
+ tag_ft.append_mapping('zoom', 17, 20)
+ tag_ft.append_mapping('mellotron', 1001)
+ tag_ft.append_mapping('giorgio', 2000, 3000)
+ ft0 = bt2.IntegerFieldType(32, is_signed=True)
+ ft1 = bt2.StringFieldType()
+ ft2 = bt2.FloatingPointNumberFieldType()
+ ft3 = bt2.IntegerFieldType(17)
+ ft = bt2.VariantFieldType('salut', tag_ft)
+ ft.append_field('corner', ft0)
+ ft.append_field('zoom', ft1)
+ ft.append_field('mellotron', ft2)
+ ft.append_field('giorgio', ft3)
+ field = ft()
+ field_tag = tag_ft(23)
+ def_tag = self._tag_ft(23)
+ field.field(field_tag).value = 1774
+ self._def.field(def_tag).value = 1774
+ self.assertEqual(self._def, field)
+
+ def test_eq_invalid_type(self):
+ self.assertNotEqual(self._def, 23)
--- /dev/null
+from bt2 import values
+import collections
+import unittest
+import copy
+import bt2
+
+
+class GraphTestCase(unittest.TestCase):
+ def setUp(self):
+ self._graph = bt2.Graph()
+
+ def tearDown(self):
+ del self._graph
+
+ def test_create_empty(self):
+ graph = bt2.Graph()
+
+ def test_add_component_user_cls(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ comp = self._graph.add_component(MySink, 'salut')
+ self.assertEqual(comp.name, 'salut')
+
+ def test_add_component_gen_cls(self):
+ class MySink(bt2._UserSinkComponent):
+ def _consume(self):
+ pass
+
+ comp = self._graph.add_component(MySink, 'salut')
+ assert(comp)
+ comp2 = self._graph.add_component(comp.component_class, 'salut2')
+ self.assertEqual(comp2.name, 'salut2')
+
+ def test_add_component_params(self):
+ comp_params = None
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ nonlocal comp_params
+ comp_params = params
+
+ def _consume(self):
+ pass
+
+ params = {'hello': 23, 'path': '/path/to/stuff'}
+ comp = self._graph.add_component(MySink, 'salut', params)
+ self.assertEqual(params, comp_params)
+ del comp_params
+
+ def test_add_component_invalid_cls_type(self):
+ with self.assertRaises(TypeError):
+ self._graph.add_component(int, 'salut')
+
+ def test_connect_ports(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ src = self._graph.add_component(MySource, 'src')
+ sink = self._graph.add_component(MySink, 'sink')
+ conn = self._graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self.assertTrue(src.output_ports['out'].is_connected)
+ self.assertTrue(sink.input_ports['in'].is_connected)
+ self.assertEqual(src.output_ports['out'].connection, conn)
+ self.assertEqual(sink.input_ports['in'].connection, conn)
+
+ def test_connect_ports_invalid_direction(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ src = self._graph.add_component(MySource, 'src')
+ sink = self._graph.add_component(MySink, 'sink')
+
+ with self.assertRaises(TypeError):
+ conn = self._graph.connect_ports(sink.input_ports['in'],
+ src.output_ports['out'])
+
+ def test_connect_ports_refused(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ def _accept_port_connection(self, port, other_port):
+ return False
+
+ src = self._graph.add_component(MySource, 'src')
+ sink = self._graph.add_component(MySink, 'sink')
+
+ with self.assertRaises(bt2.PortConnectionRefused):
+ conn = self._graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+
+ def test_connect_ports_canceled(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ src = self._graph.add_component(MySource, 'src')
+ sink = self._graph.add_component(MySink, 'sink')
+ self._graph.cancel()
+
+ with self.assertRaises(bt2.GraphCanceled):
+ conn = self._graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+
+ def test_cancel(self):
+ self.assertFalse(self._graph.is_canceled)
+ self._graph.cancel()
+ self.assertTrue(self._graph.is_canceled)
+
+ def test_run(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __init__(self):
+ self._build_meta()
+ self._at = 0
+
+ def _build_meta(self):
+ self._trace = bt2.Trace()
+ self._sc = bt2.StreamClass()
+ self._ec = bt2.EventClass('salut')
+ self._my_int_ft = bt2.IntegerFieldType(32)
+ self._ec.payload_field_type = bt2.StructureFieldType()
+ self._ec.payload_field_type += collections.OrderedDict([
+ ('my_int', self._my_int_ft),
+ ])
+ self._sc.add_event_class(self._ec)
+ self._trace.add_stream_class(self._sc)
+ self._stream = self._sc()
+ self._packet = self._stream.create_packet()
+
+ def _create_event(self, value):
+ ev = self._ec()
+ ev.payload_field['my_int'] = value
+ ev.packet = self._packet
+ return ev
+
+ def __next__(self):
+ if self._at == 5:
+ raise bt2.Stop
+
+ notif = bt2.EventNotification(self._create_event(self._at * 3))
+ self._at += 1
+ return notif
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+ self._at = 0
+
+ def _consume(comp_self):
+ notif = next(comp_self._notif_iter)
+
+ if comp_self._at == 0:
+ self.assertIsInstance(notif, bt2.StreamBeginningNotification)
+ elif comp_self._at == 1:
+ self.assertIsInstance(notif, bt2.PacketBeginningNotification)
+ elif comp_self._at >= 2 and comp_self._at <= 6:
+ self.assertIsInstance(notif, bt2.EventNotification)
+ self.assertEqual(notif.event.event_class.name, 'salut')
+ field = notif.event.payload_field['my_int']
+ self.assertEqual(field, (comp_self._at - 2) * 3)
+ elif comp_self._at == 7:
+ self.assertIsInstance(notif, bt2.PacketEndNotification)
+ elif comp_self._at == 8:
+ self.assertIsInstance(notif, bt2.StreamEndNotification)
+
+ comp_self._at += 1
+
+ def _port_connected(self, port, other_port):
+ self._notif_iter = port.connection.create_notification_iterator()
+
+ src = self._graph.add_component(MySource, 'src')
+ sink = self._graph.add_component(MySink, 'sink')
+ conn = self._graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ self._graph.run()
+
+ def test_run_again(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __init__(self):
+ self._build_meta()
+ self._at = 0
+
+ def _build_meta(self):
+ self._trace = bt2.Trace()
+ self._sc = bt2.StreamClass()
+ self._ec = bt2.EventClass('salut')
+ self._my_int_ft = bt2.IntegerFieldType(32)
+ self._ec.payload_field_type = bt2.StructureFieldType()
+ self._ec.payload_field_type += collections.OrderedDict([
+ ('my_int', self._my_int_ft),
+ ])
+ self._sc.add_event_class(self._ec)
+ self._trace.add_stream_class(self._sc)
+ self._stream = self._sc()
+ self._packet = self._stream.create_packet()
+
+ def _create_event(self, value):
+ ev = self._ec()
+ ev.payload_field['my_int'] = value
+ ev.packet = self._packet
+ return ev
+
+ def __next__(self):
+ if self._at == 1:
+ raise bt2.TryAgain
+
+ notif = bt2.EventNotification(self._create_event(self._at * 3))
+ self._at += 1
+ return notif
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+ self._at = 0
+
+ def _consume(comp_self):
+ if comp_self._at == 0:
+ notif = next(comp_self._notif_iter)
+ self.assertIsInstance(notif, bt2.EventNotification)
+ elif comp_self._at == 1:
+ with self.assertRaises(bt2.TryAgain):
+ notif = next(comp_self._notif_iter)
+
+ raise bt2.TryAgain
+
+ comp_self._at += 1
+
+ def _port_connected(self, port, other_port):
+ types = [bt2.EventNotification]
+ self._notif_iter = port.connection.create_notification_iterator(types)
+
+ src = self._graph.add_component(MySource, 'src')
+ sink = self._graph.add_component(MySink, 'sink')
+ conn = self._graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+
+ with self.assertRaises(bt2.TryAgain):
+ self._graph.run()
+
+ def test_run_no_sink(self):
+ class MyIter(bt2._UserNotificationIterator):
+ pass
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+ self._add_input_port('in')
+
+ src = self._graph.add_component(MySource, 'src')
+ flt = self._graph.add_component(MyFilter, 'flt')
+ conn = self._graph.connect_ports(src.output_ports['out'],
+ flt.input_ports['in'])
+
+ with self.assertRaises(bt2.NoSinkComponent):
+ self._graph.run()
+
+ def test_run_error(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __init__(self):
+ self._build_meta()
+ self._at = 0
+
+ def _build_meta(self):
+ self._trace = bt2.Trace()
+ self._sc = bt2.StreamClass()
+ self._ec = bt2.EventClass('salut')
+ self._my_int_ft = bt2.IntegerFieldType(32)
+ self._ec.payload_field_type = bt2.StructureFieldType()
+ self._ec.payload_field_type += collections.OrderedDict([
+ ('my_int', self._my_int_ft),
+ ])
+ self._sc.add_event_class(self._ec)
+ self._trace.add_stream_class(self._sc)
+ self._stream = self._sc()
+ self._packet = self._stream.create_packet()
+
+ def _create_event(self, value):
+ ev = self._ec()
+ ev.payload_field['my_int'] = value
+ ev.packet = self._packet
+ return ev
+
+ def __next__(self):
+ if self._at == 1:
+ raise bt2.TryAgain
+
+ notif = bt2.EventNotification(self._create_event(self._at * 3))
+ self._at += 1
+ return notif
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+ self._at = 0
+
+ def _consume(comp_self):
+ if comp_self._at == 0:
+ notif = next(comp_self._notif_iter)
+ self.assertIsInstance(notif, bt2.EventNotification)
+ elif comp_self._at == 1:
+ raise RuntimeError('error!')
+
+ comp_self._at += 1
+
+ def _port_connected(self, port, other_port):
+ types = [bt2.EventNotification]
+ self._notif_iter = port.connection.create_notification_iterator(types)
+
+ src = self._graph.add_component(MySource, 'src')
+ sink = self._graph.add_component(MySink, 'sink')
+ conn = self._graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+
+ with self.assertRaises(bt2.Error):
+ self._graph.run()
+
+ def test_listeners(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+ self._add_output_port('zero')
+
+ def _port_connected(self, port, other_port):
+ self._output_ports['zero'].remove_from_component()
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ raise bt2.Stop
+
+ def _port_connected(self, port, other_port):
+ self._add_input_port('taste')
+
+ def _port_disconnected(self, port):
+ port.remove_from_component()
+
+ def port_added_listener(port):
+ nonlocal calls
+ calls.append((port_added_listener, port))
+
+ def port_removed_listener(port):
+ nonlocal calls
+ calls.append((port_removed_listener, port))
+
+ def ports_connected_listener(upstream_port, downstream_port):
+ nonlocal calls
+ calls.append((ports_connected_listener, upstream_port,
+ downstream_port))
+
+ def ports_disconnected_listener(upstream_comp, downstream_comp,
+ upstream_port, downstream_port):
+ nonlocal calls
+ calls.append((ports_disconnected_listener, upstream_comp,
+ downstream_comp, upstream_port, downstream_port))
+
+ calls = []
+ self._graph.add_listener(bt2.GraphListenerType.PORT_ADDED,
+ port_added_listener)
+ self._graph.add_listener(bt2.GraphListenerType.PORT_REMOVED,
+ port_removed_listener)
+ self._graph.add_listener(bt2.GraphListenerType.PORTS_CONNECTED,
+ ports_connected_listener)
+ self._graph.add_listener(bt2.GraphListenerType.PORTS_DISCONNECTED,
+ ports_disconnected_listener)
+ src = self._graph.add_component(MySource, 'src')
+ sink = self._graph.add_component(MySink, 'sink')
+ self._graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ sink.input_ports['in'].disconnect()
+ self.assertIs(calls[0][0], port_added_listener)
+ self.assertEqual(calls[0][1].name, 'out')
+ self.assertIs(calls[1][0], port_added_listener)
+ self.assertEqual(calls[1][1].name, 'zero')
+ self.assertIs(calls[2][0], port_added_listener)
+ self.assertEqual(calls[2][1].name, 'in')
+ self.assertIs(calls[3][0], port_removed_listener)
+ self.assertEqual(calls[3][1].name, 'zero')
+ self.assertIs(calls[4][0], port_added_listener)
+ self.assertEqual(calls[4][1].name, 'taste')
+ self.assertIs(calls[5][0], ports_connected_listener)
+ self.assertEqual(calls[5][1].name, 'out')
+ self.assertEqual(calls[5][2].name, 'in')
+ self.assertIs(calls[6][0], port_removed_listener)
+ self.assertEqual(calls[6][1].name, 'in')
+ self.assertIs(calls[7][0], ports_disconnected_listener)
+ self.assertEqual(calls[7][1].name, 'src')
+ self.assertEqual(calls[7][2].name, 'sink')
+ self.assertEqual(calls[7][3].name, 'out')
+ self.assertEqual(calls[7][4].name, 'in')
+ del calls
--- /dev/null
+from bt2 import values
+import collections
+import unittest
+import copy
+import bt2
+
+
+class _NotificationTestCase(unittest.TestCase):
+ def setUp(self):
+ self._trace = bt2.Trace()
+ self._sc = bt2.StreamClass()
+ self._ec = bt2.EventClass('salut')
+ self._my_int_ft = bt2.IntegerFieldType(32)
+ self._ec.payload_field_type = bt2.StructureFieldType()
+ self._ec.payload_field_type += collections.OrderedDict([
+ ('my_int', self._my_int_ft),
+ ])
+ self._sc.add_event_class(self._ec)
+ self._clock_class = bt2.ClockClass('allo', 1000)
+ self._trace.add_clock_class(self._clock_class)
+ self._trace.packet_header_field_type = bt2.StructureFieldType()
+ self._trace.packet_header_field_type += collections.OrderedDict([
+ ('hello', self._my_int_ft),
+ ])
+ self._trace.add_stream_class(self._sc)
+ self._cc_prio_map = bt2.ClockClassPriorityMap()
+ self._cc_prio_map[self._clock_class] = 231
+ self._stream = self._sc()
+ self._packet = self._stream.create_packet()
+ self._packet.header_field['hello'] = 19487
+ self._event = self._ec()
+ self._event.add_clock_value(self._clock_class(1772))
+ self._event.payload_field['my_int'] = 23
+ self._event.packet = self._packet
+
+ def tearDown(self):
+ del self._trace
+ del self._sc
+ del self._ec
+ del self._my_int_ft
+ del self._clock_class
+ del self._cc_prio_map
+ del self._stream
+ del self._packet
+ del self._event
+
+
+class EventNotificationTestCase(_NotificationTestCase):
+ def test_create_no_cc_prio_map(self):
+ notif = bt2.EventNotification(self._event)
+ self.assertEqual(notif.event.addr, self._event.addr)
+ self.assertEqual(len(notif.clock_class_priority_map), 0)
+
+ def test_create_with_cc_prio_map(self):
+ notif = bt2.EventNotification(self._event, self._cc_prio_map)
+ self.assertEqual(notif.event.addr, self._event.addr)
+ self.assertEqual(len(notif.clock_class_priority_map), 1)
+ self.assertEqual(notif.clock_class_priority_map.highest_priority_clock_class.addr,
+ self._clock_class.addr)
+ self.assertEqual(notif.clock_class_priority_map[self._clock_class], 231)
+
+ def test_eq(self):
+ notif = bt2.EventNotification(self._event, self._cc_prio_map)
+ event_copy = copy.copy(self._event)
+ event_copy.packet = self._packet
+ cc_prio_map_copy = copy.copy(self._cc_prio_map)
+ notif2 = bt2.EventNotification(event_copy, cc_prio_map_copy)
+ self.assertEqual(notif, notif2)
+
+ def test_ne_event(self):
+ notif = bt2.EventNotification(self._event, self._cc_prio_map)
+ event_copy = copy.copy(self._event)
+ event_copy.payload_field['my_int'] = 17
+ event_copy.packet = self._packet
+ cc_prio_map_copy = copy.copy(self._cc_prio_map)
+ notif2 = bt2.EventNotification(event_copy, cc_prio_map_copy)
+ self.assertNotEqual(notif, notif2)
+
+ def test_ne_cc_prio_map(self):
+ notif = bt2.EventNotification(self._event)
+ event_copy = copy.copy(self._event)
+ event_copy.packet = self._packet
+ cc_prio_map_copy = copy.copy(self._cc_prio_map)
+ notif2 = bt2.EventNotification(event_copy, cc_prio_map_copy)
+ self.assertNotEqual(notif, notif2)
+
+ def test_eq_invalid(self):
+ notif = bt2.EventNotification(self._event)
+ self.assertNotEqual(notif, 23)
+
+ def test_copy(self):
+ notif = bt2.EventNotification(self._event, self._cc_prio_map)
+ notif2 = copy.copy(notif)
+ self.assertEqual(notif, notif2)
+
+ def test_deepcopy(self):
+ notif = bt2.EventNotification(self._event, self._cc_prio_map)
+ notif2 = copy.deepcopy(notif)
+ self.assertEqual(notif, notif2)
+
+
+class PacketBeginningNotificationTestCase(_NotificationTestCase):
+ def test_create(self):
+ notif = bt2.PacketBeginningNotification(self._packet)
+ self.assertEqual(notif.packet.addr, self._packet.addr)
+
+ def test_eq(self):
+ notif = bt2.PacketBeginningNotification(self._packet)
+ packet_copy = copy.copy(self._packet)
+ notif2 = bt2.PacketBeginningNotification(packet_copy)
+ self.assertEqual(notif, notif2)
+
+ def test_ne_packet(self):
+ notif = bt2.PacketBeginningNotification(self._packet)
+ packet_copy = copy.copy(self._packet)
+ packet_copy.header_field['hello'] = 1847
+ notif2 = bt2.PacketBeginningNotification(packet_copy)
+ self.assertNotEqual(notif, notif2)
+
+ def test_eq_invalid(self):
+ notif = bt2.PacketBeginningNotification(self._packet)
+ self.assertNotEqual(notif, 23)
+
+ def test_copy(self):
+ notif = bt2.PacketBeginningNotification(self._packet)
+ notif2 = copy.copy(notif)
+ self.assertEqual(notif, notif2)
+
+ def test_deepcopy(self):
+ notif = bt2.PacketBeginningNotification(self._packet)
+ notif2 = copy.deepcopy(notif)
+ self.assertEqual(notif, notif2)
+
+
+class PacketEndNotificationTestCase(_NotificationTestCase):
+ def test_create(self):
+ notif = bt2.PacketEndNotification(self._packet)
+ self.assertEqual(notif.packet.addr, self._packet.addr)
+
+ def test_eq(self):
+ notif = bt2.PacketEndNotification(self._packet)
+ packet_copy = copy.copy(self._packet)
+ notif2 = bt2.PacketEndNotification(packet_copy)
+ self.assertEqual(notif, notif2)
+
+ def test_ne_packet(self):
+ notif = bt2.PacketEndNotification(self._packet)
+ packet_copy = copy.copy(self._packet)
+ packet_copy.header_field['hello'] = 1847
+ notif2 = bt2.PacketEndNotification(packet_copy)
+ self.assertNotEqual(notif, notif2)
+
+ def test_eq_invalid(self):
+ notif = bt2.PacketEndNotification(self._packet)
+ self.assertNotEqual(notif, 23)
+
+ def test_copy(self):
+ notif = bt2.PacketEndNotification(self._packet)
+ notif2 = copy.copy(notif)
+ self.assertEqual(notif, notif2)
+
+ def test_deepcopy(self):
+ notif = bt2.PacketEndNotification(self._packet)
+ notif2 = copy.deepcopy(notif)
+ self.assertEqual(notif, notif2)
+
+
+class StreamBeginningNotificationTestCase(_NotificationTestCase):
+ def test_create(self):
+ notif = bt2.StreamBeginningNotification(self._stream)
+ self.assertEqual(notif.stream.addr, self._stream.addr)
+
+ def test_eq(self):
+ notif = bt2.StreamBeginningNotification(self._stream)
+ stream_copy = copy.copy(self._stream)
+ notif2 = bt2.StreamBeginningNotification(stream_copy)
+ self.assertEqual(notif, notif2)
+
+ def test_ne_stream(self):
+ notif = bt2.StreamBeginningNotification(self._stream)
+ stream_copy = self._sc(name='salut')
+ notif2 = bt2.StreamBeginningNotification(stream_copy)
+ self.assertNotEqual(notif, notif2)
+
+ def test_eq_invalid(self):
+ notif = bt2.StreamBeginningNotification(self._stream)
+ self.assertNotEqual(notif, 23)
+
+ def test_copy(self):
+ notif = bt2.StreamBeginningNotification(self._stream)
+ notif2 = copy.copy(notif)
+ self.assertEqual(notif, notif2)
+
+ def test_deepcopy(self):
+ notif = bt2.StreamBeginningNotification(self._stream)
+ notif2 = copy.deepcopy(notif)
+ self.assertEqual(notif, notif2)
+
+
+class StreamEndNotificationTestCase(_NotificationTestCase):
+ def test_create(self):
+ notif = bt2.StreamEndNotification(self._stream)
+ self.assertEqual(notif.stream.addr, self._stream.addr)
+
+ def test_eq(self):
+ notif = bt2.StreamEndNotification(self._stream)
+ stream_copy = copy.copy(self._stream)
+ notif2 = bt2.StreamEndNotification(stream_copy)
+ self.assertEqual(notif, notif2)
+
+ def test_ne_stream(self):
+ notif = bt2.StreamEndNotification(self._stream)
+ stream_copy = self._sc(name='salut')
+ notif2 = bt2.StreamEndNotification(stream_copy)
+ self.assertNotEqual(notif, notif2)
+
+ def test_eq_invalid(self):
+ notif = bt2.StreamEndNotification(self._stream)
+ self.assertNotEqual(notif, 23)
+
+ def test_copy(self):
+ notif = bt2.StreamEndNotification(self._stream)
+ notif2 = copy.copy(notif)
+ self.assertEqual(notif, notif2)
+
+ def test_deepcopy(self):
+ notif = bt2.StreamEndNotification(self._stream)
+ notif2 = copy.deepcopy(notif)
+ self.assertEqual(notif, notif2)
+
+
+class InactivityNotificationTestCase(unittest.TestCase):
+ def setUp(self):
+ self._cc1 = bt2.ClockClass('cc1', 1000)
+ self._cc2 = bt2.ClockClass('cc2', 2000)
+ self._cc_prio_map = bt2.ClockClassPriorityMap()
+ self._cc_prio_map[self._cc1] = 25
+ self._cc_prio_map[self._cc2] = 50
+
+ def tearDown(self):
+ del self._cc1
+ del self._cc2
+ del self._cc_prio_map
+
+ def test_create_no_cc_prio_map(self):
+ notif = bt2.InactivityNotification()
+ self.assertEqual(len(notif.clock_class_priority_map), 0)
+
+ def test_create_with_cc_prio_map(self):
+ notif = bt2.InactivityNotification(self._cc_prio_map)
+ notif.add_clock_value(self._cc1(123))
+ notif.add_clock_value(self._cc2(19487))
+ self.assertEqual(len(notif.clock_class_priority_map), 2)
+ self.assertEqual(notif.clock_class_priority_map, self._cc_prio_map)
+ self.assertEqual(notif.clock_value(self._cc1), 123)
+ self.assertEqual(notif.clock_value(self._cc2), 19487)
+
+ def test_eq(self):
+ notif = bt2.InactivityNotification(self._cc_prio_map)
+ notif.add_clock_value(self._cc1(123))
+ notif.add_clock_value(self._cc2(19487))
+ cc_prio_map_copy = copy.copy(self._cc_prio_map)
+ notif2 = bt2.InactivityNotification(cc_prio_map_copy)
+ notif2.add_clock_value(self._cc1(123))
+ notif2.add_clock_value(self._cc2(19487))
+ self.assertEqual(notif, notif2)
+
+ def test_ne_cc_prio_map(self):
+ notif = bt2.InactivityNotification(self._cc_prio_map)
+ notif.add_clock_value(self._cc1(123))
+ notif.add_clock_value(self._cc2(19487))
+ cc_prio_map_copy = copy.copy(self._cc_prio_map)
+ cc_prio_map_copy[self._cc2] = 23
+ notif2 = bt2.InactivityNotification(cc_prio_map_copy)
+ self.assertNotEqual(notif, notif2)
+
+ def test_ne_clock_value(self):
+ notif = bt2.InactivityNotification(self._cc_prio_map)
+ notif.add_clock_value(self._cc1(123))
+ notif.add_clock_value(self._cc2(19487))
+ notif2 = bt2.InactivityNotification(self._cc_prio_map)
+ notif.add_clock_value(self._cc1(123))
+ notif.add_clock_value(self._cc2(1847))
+ self.assertNotEqual(notif, notif2)
+
+ def test_eq_invalid(self):
+ notif = bt2.InactivityNotification(self._cc_prio_map)
+ self.assertNotEqual(notif, 23)
+
+ def test_copy(self):
+ notif = bt2.InactivityNotification(self._cc_prio_map)
+ notif.add_clock_value(self._cc1(123))
+ notif.add_clock_value(self._cc2(19487))
+ notif_copy = copy.copy(notif)
+ self.assertEqual(notif, notif_copy)
+ self.assertNotEqual(notif.addr, notif_copy.addr)
+ self.assertEqual(notif.clock_class_priority_map.addr,
+ notif_copy.clock_class_priority_map.addr)
+ self.assertEqual(notif_copy.clock_value(self._cc1), 123)
+ self.assertEqual(notif_copy.clock_value(self._cc2), 19487)
+
+ def test_deepcopy(self):
+ notif = bt2.InactivityNotification(self._cc_prio_map)
+ notif.add_clock_value(self._cc1(123))
+ notif.add_clock_value(self._cc2(19487))
+ notif_copy = copy.deepcopy(notif)
+ self.assertEqual(notif, notif_copy)
+ self.assertNotEqual(notif.addr, notif_copy.addr)
+ self.assertNotEqual(notif.clock_class_priority_map.addr,
+ notif_copy.clock_class_priority_map.addr)
+ self.assertEqual(notif.clock_class_priority_map,
+ notif_copy.clock_class_priority_map)
+ self.assertNotEqual(list(notif.clock_class_priority_map)[0].addr,
+ list(notif_copy.clock_class_priority_map)[0].addr)
+ self.assertIsNone(notif_copy.clock_value(self._cc1))
+ self.assertIsNone(notif_copy.clock_value(self._cc2))
+ self.assertEqual(notif_copy.clock_value(list(notif_copy.clock_class_priority_map)[0]), 123)
+ self.assertEqual(notif_copy.clock_value(list(notif_copy.clock_class_priority_map)[1]), 19487)
+
+
+class DiscardedPacketsNotificationTestCase(unittest.TestCase):
+ def setUp(self):
+ self._trace = bt2.Trace()
+ self._sc = bt2.StreamClass()
+ self._ec = bt2.EventClass('salut')
+ self._clock_class = bt2.ClockClass('yo', 1000)
+ self._uint64_int_ft = bt2.IntegerFieldType(64, mapped_clock_class=self._clock_class)
+ self._my_int_ft = bt2.IntegerFieldType(32)
+ self._ec.payload_field_type = bt2.StructureFieldType()
+ self._ec.payload_field_type += collections.OrderedDict([
+ ('my_int', self._my_int_ft),
+ ])
+ self._sc.add_event_class(self._ec)
+ self._sc.packet_context_field_type = bt2.StructureFieldType()
+ self._sc.packet_context_field_type += collections.OrderedDict([
+ ('packet_seq_num', self._my_int_ft),
+ ('timestamp_begin', self._uint64_int_ft),
+ ('timestamp_end', self._uint64_int_ft),
+ ])
+ self._trace.add_clock_class(self._clock_class)
+ self._trace.add_stream_class(self._sc)
+ self._stream = self._sc()
+
+ def tearDown(self):
+ del self._trace
+ del self._sc
+ del self._ec
+ del self._clock_class
+ del self._uint64_int_ft
+ del self._my_int_ft
+ del self._stream
+
+ def _create_event(self, packet):
+ event = self._ec()
+ event.payload_field['my_int'] = 23
+ event.packet = packet
+ return event
+
+ def _get_notif(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __init__(iter_self):
+ packet1 = self._stream.create_packet()
+ packet1.context_field['packet_seq_num'] = 0
+ packet1.context_field['timestamp_begin'] = 3
+ packet1.context_field['timestamp_end'] = 6
+ packet2 = self._stream.create_packet()
+ packet2.context_field['packet_seq_num'] = 5
+ packet2.context_field['timestamp_begin'] = 7
+ packet2.context_field['timestamp_end'] = 10
+ iter_self._ev1 = self._create_event(packet1)
+ iter_self._ev2 = self._create_event(packet2)
+ iter_self._at = 0
+
+ def __next__(self):
+ if self._at == 0:
+ notif = bt2.EventNotification(self._ev1)
+ elif self._at == 1:
+ notif = bt2.EventNotification(self._ev2)
+ else:
+ raise bt2.Stop
+
+ self._at += 1
+ return notif
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(comp_self):
+ nonlocal the_notif
+ notif = next(comp_self._notif_iter)
+
+ if type(notif) is bt2._DiscardedPacketsNotification:
+ the_notif = notif
+ raise bt2.Stop
+
+ def _port_connected(self, port, other_port):
+ self._notif_iter = port.connection.create_notification_iterator()
+
+ the_notif = None
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ graph.run()
+ return the_notif
+
+ def test_create(self):
+ self.assertIsInstance(self._get_notif(), bt2._DiscardedPacketsNotification)
+
+ def test_count(self):
+ self.assertEqual(self._get_notif().count, 4)
+
+ def test_stream(self):
+ self.assertEqual(self._get_notif().stream.addr, self._stream.addr)
+
+ def test_beginning_clock_value(self):
+ notif = self._get_notif()
+ beginning_clock_value = notif.beginning_clock_value
+ self.assertEqual(beginning_clock_value.clock_class, self._clock_class)
+ self.assertEqual(beginning_clock_value, 6)
+
+ def test_end_clock_value(self):
+ notif = self._get_notif()
+ end_clock_value = notif.end_clock_value
+ self.assertEqual(end_clock_value.clock_class, self._clock_class)
+ self.assertEqual(end_clock_value, 7)
+
+ def test_eq(self):
+ notif1 = self._get_notif()
+ notif2 = self._get_notif()
+ self.assertEqual(notif1, notif2)
+
+ def test_eq_invalid(self):
+ notif1 = self._get_notif()
+ self.assertNotEqual(notif1, 23)
+
+
+class DiscardedEventsNotificationTestCase(unittest.TestCase):
+ def setUp(self):
+ self._trace = bt2.Trace()
+ self._sc = bt2.StreamClass()
+ self._ec = bt2.EventClass('salut')
+ self._clock_class = bt2.ClockClass('yo', 1000)
+ self._uint64_int_ft = bt2.IntegerFieldType(64, mapped_clock_class=self._clock_class)
+ self._my_int_ft = bt2.IntegerFieldType(32)
+ self._ec.payload_field_type = bt2.StructureFieldType()
+ self._ec.payload_field_type += collections.OrderedDict([
+ ('my_int', self._my_int_ft),
+ ])
+ self._sc.add_event_class(self._ec)
+ self._sc.packet_context_field_type = bt2.StructureFieldType()
+ self._sc.packet_context_field_type += collections.OrderedDict([
+ ('events_discarded', self._my_int_ft),
+ ('timestamp_begin', self._uint64_int_ft),
+ ('timestamp_end', self._uint64_int_ft),
+ ])
+ self._trace.add_clock_class(self._clock_class)
+ self._trace.add_stream_class(self._sc)
+ self._stream = self._sc()
+
+ def tearDown(self):
+ del self._trace
+ del self._sc
+ del self._ec
+ del self._clock_class
+ del self._uint64_int_ft
+ del self._my_int_ft
+ del self._stream
+
+ def _create_event(self, packet):
+ event = self._ec()
+ event.payload_field['my_int'] = 23
+ event.packet = packet
+ return event
+
+ def _get_notif(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __init__(iter_self):
+ packet1 = self._stream.create_packet()
+ packet1.context_field['events_discarded'] = 0
+ packet1.context_field['timestamp_begin'] = 3
+ packet1.context_field['timestamp_end'] = 6
+ packet2 = self._stream.create_packet()
+ packet2.context_field['events_discarded'] = 10
+ packet2.context_field['timestamp_begin'] = 7
+ packet2.context_field['timestamp_end'] = 10
+ iter_self._ev1 = self._create_event(packet1)
+ iter_self._ev2 = self._create_event(packet2)
+ iter_self._at = 0
+
+ def __next__(self):
+ if self._at == 0:
+ notif = bt2.EventNotification(self._ev1)
+ elif self._at == 1:
+ notif = bt2.EventNotification(self._ev2)
+ else:
+ raise bt2.Stop
+
+ self._at += 1
+ return notif
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(comp_self):
+ nonlocal the_notif
+ notif = next(comp_self._notif_iter)
+
+ if type(notif) is bt2._DiscardedEventsNotification:
+ the_notif = notif
+ raise bt2.Stop
+
+ def _port_connected(self, port, other_port):
+ self._notif_iter = port.connection.create_notification_iterator()
+
+ the_notif = None
+ graph = bt2.Graph()
+ src = graph.add_component(MySource, 'src')
+ sink = graph.add_component(MySink, 'sink')
+ conn = graph.connect_ports(src.output_ports['out'],
+ sink.input_ports['in'])
+ graph.run()
+ return the_notif
+
+ def test_create(self):
+ self.assertIsInstance(self._get_notif(), bt2._DiscardedEventsNotification)
+
+ def test_count(self):
+ self.assertEqual(self._get_notif().count, 10)
+
+ def test_stream(self):
+ self.assertEqual(self._get_notif().stream.addr, self._stream.addr)
+
+ def test_beginning_clock_value(self):
+ notif = self._get_notif()
+ beginning_clock_value = notif.beginning_clock_value
+ self.assertEqual(beginning_clock_value.clock_class, self._clock_class)
+ self.assertEqual(beginning_clock_value, 6)
+
+ def test_end_clock_value(self):
+ notif = self._get_notif()
+ end_clock_value = notif.end_clock_value
+ self.assertEqual(end_clock_value.clock_class, self._clock_class)
+ self.assertEqual(end_clock_value, 10)
+
+ def test_eq(self):
+ notif1 = self._get_notif()
+ notif2 = self._get_notif()
+ self.assertEqual(notif1, notif2)
+
+ def test_eq_invalid(self):
+ notif1 = self._get_notif()
+ self.assertNotEqual(notif1, 23)
--- /dev/null
+from bt2 import values
+import unittest
+import copy
+import bt2
+
+
+class UserNotificationIteratorTestCase(unittest.TestCase):
+ @staticmethod
+ def _create_graph(src_comp_cls):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ next(self._notif_iter)
+
+ def _port_connected(self, port, other_port):
+ self._notif_iter = port.connection.create_notification_iterator()
+
+ graph = bt2.Graph()
+ src_comp = graph.add_component(src_comp_cls, 'src')
+ sink_comp = graph.add_component(MySink, 'sink')
+ graph.connect_ports(src_comp.output_ports['out'],
+ sink_comp.input_ports['in'])
+ return graph
+
+ def test_init(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __init__(self):
+ nonlocal initialized
+ initialized = True
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ initialized = False
+ graph = self._create_graph(MySource)
+ self.assertTrue(initialized)
+
+ def test_finalize(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def _finalize(self):
+ nonlocal finalized
+ finalized = True
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ finalized = False
+ graph = self._create_graph(MySource)
+ del graph
+ self.assertTrue(finalized)
+
+ def test_component(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __init__(self):
+ nonlocal salut
+ salut = self._component._salut
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+ self._salut = 23
+
+ salut = None
+ graph = self._create_graph(MySource)
+ self.assertEqual(salut, 23)
+
+ def test_addr(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __init__(self):
+ nonlocal addr
+ addr = self.addr
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ addr = None
+ graph = self._create_graph(MySource)
+ self.assertIsNotNone(addr)
+ self.assertNotEqual(addr, 0)
+
+
+class GenericNotificationIteratorTestCase(unittest.TestCase):
+ def test_component(self):
+ class MyIter(bt2._UserNotificationIterator):
+ pass
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(self, params):
+ self._add_output_port('out')
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(self, params):
+ self._add_input_port('in')
+
+ def _consume(self):
+ next(self._notif_iter)
+
+ def _port_connected(self, port, other_port):
+ nonlocal upstream_comp
+ self._notif_iter = port.connection.create_notification_iterator()
+ upstream_comp = self._notif_iter.component
+
+ upstream_comp = None
+ graph = bt2.Graph()
+ src_comp = graph.add_component(MySource, 'src')
+ sink_comp = graph.add_component(MySink, 'sink')
+ graph.connect_ports(src_comp.output_ports['out'],
+ sink_comp.input_ports['in'])
+ self.assertEqual(src_comp, upstream_comp)
+ del upstream_comp
def setUp(self):
self._packet = self._create_packet()
+ def tearDown(self):
+ del self._packet
+
def _create_packet(self, with_ph=True, with_pc=True):
# event header
eh = bt2.StructureFieldType()
--- /dev/null
+from bt2 import values
+import unittest
+import copy
+import bt2
+import bt2.plugin
+import os
+
+
+_TEST_PLUGIN_PLUGINS_PATH = os.environ['TEST_PLUGIN_PLUGINS_PATH']
+
+
+class PluginSetTestCase(unittest.TestCase):
+ def test_create(self):
+ pset = bt2.find_plugins(_TEST_PLUGIN_PLUGINS_PATH)
+ self.assertTrue(len(pset) >= 3)
+
+ def test_getitem(self):
+ pset = bt2.find_plugins(_TEST_PLUGIN_PLUGINS_PATH)
+ self.assertTrue(pset[0].path.startswith(_TEST_PLUGIN_PLUGINS_PATH))
+
+ def test_iter(self):
+ pset = bt2.find_plugins(_TEST_PLUGIN_PLUGINS_PATH)
+ names = set()
+
+ for plugin in pset:
+ names.add(plugin.name)
+
+ self.assertTrue('ctf' in names)
+ self.assertTrue('utils' in names)
+ self.assertTrue('text' in names)
+
+
+class FindPluginsTestCase(unittest.TestCase):
+ def test_find_none(self):
+ pset = bt2.find_plugins('/this/does/not/exist/246703df-cb85-46d5-8406-5e8dc4a88b41')
+ self.assertIsNone(pset)
+
+ def test_find_dir(self):
+ pset = bt2.find_plugins(_TEST_PLUGIN_PLUGINS_PATH)
+ self.assertTrue(len(pset) >= 3)
+
+
+class FindPluginTestCase(unittest.TestCase):
+ def test_find_none(self):
+ plugin = bt2.find_plugin('this-does-not-exist-246703df-cb85-46d5-8406-5e8dc4a88b41')
+ self.assertIsNone(plugin)
+
+ def test_find_existing(self):
+ plugin = bt2.find_plugin('ctf')
+ self.assertIsInstance(plugin, bt2.plugin._Plugin)
+
+
+class PluginTestCase(unittest.TestCase):
+ def setUp(self):
+ self._plugin = bt2.find_plugin('ctf')
+
+ def tearDown(self):
+ del self._plugin
+
+ def test_name(self):
+ self.assertEqual(self._plugin.name, 'ctf')
+
+ def test_path(self):
+ self.assertTrue(self._plugin.path.startswith(_TEST_PLUGIN_PLUGINS_PATH))
+
+ def test_author(self):
+ self.assertTrue('Philippe Proulx' in self._plugin.author)
+
+ def test_license(self):
+ self.assertTrue('MIT' in self._plugin.license)
+
+ def test_description(self):
+ self.assertTrue('CTF source and sink support' in self._plugin.description)
+
+ def test_version(self):
+ self.assertIsNone(self._plugin.version)
+
+ def test_source_comp_classes_len(self):
+ self.assertEqual(len(self._plugin.source_component_classes), 2)
+
+ def test_source_comp_classes_getitem(self):
+ self.assertEqual(self._plugin.source_component_classes['fs'].name, 'fs')
+
+ def test_source_comp_classes_getitem_invalid(self):
+ with self.assertRaises(KeyError):
+ self._plugin.source_component_classes['lol']
+
+ def test_source_comp_classes_iter(self):
+ plugins = {}
+
+ for cc_name, cc in self._plugin.source_component_classes.items():
+ plugins[cc_name] = cc
+
+ self.assertTrue('fs' in plugins)
+ self.assertTrue('lttng-live' in plugins)
+ self.assertEqual(plugins['fs'].name, 'fs')
+ self.assertEqual(plugins['lttng-live'].name, 'lttng-live')
+
+ def test_filter_comp_classes_len(self):
+ plugin = bt2.find_plugin('utils')
+ self.assertEqual(len(plugin.filter_component_classes), 2)
+
+ def test_sink_comp_classes_len(self):
+ self.assertEqual(len(self._plugin.sink_component_classes), 1)
--- /dev/null
+from bt2 import values
+import unittest
+import copy
+import bt2
+
+
+class PortTestCase(unittest.TestCase):
+ @staticmethod
+ def _create_comp(comp_cls, name=None):
+ graph = bt2.Graph()
+
+ if name is None:
+ name = 'comp'
+
+ return graph.add_component(comp_cls, name)
+
+ def test_src_add_output_port(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ port = comp_self._add_output_port('out')
+ self.assertEqual(port.name, 'out')
+
+ comp = self._create_comp(MySource)
+ self.assertEqual(len(comp.output_ports), 1)
+
+
+ def test_flt_add_output_port(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ port = comp_self._add_output_port('out')
+ self.assertEqual(port.name, 'out')
+
+ comp = self._create_comp(MyFilter)
+ self.assertEqual(len(comp.output_ports), 1)
+
+ def test_flt_add_input_port(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ port = comp_self._add_input_port('in')
+ self.assertEqual(port.name, 'in')
+
+ comp = self._create_comp(MyFilter)
+ self.assertEqual(len(comp.input_ports), 1)
+
+ def test_sink_add_input_port(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port = comp_self._add_input_port('in')
+ self.assertEqual(port.name, 'in')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ self.assertEqual(len(comp.input_ports), 1)
+
+ def test_user_src_output_ports_getitem(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ port1 = comp_self._add_output_port('clear')
+ port2 = comp_self._add_output_port('print')
+ port3 = comp_self._add_output_port('insert')
+ self.assertEqual(port3.addr, comp_self._output_ports['insert'].addr)
+ self.assertEqual(port2.addr, comp_self._output_ports['print'].addr)
+ self.assertEqual(port1.addr, comp_self._output_ports['clear'].addr)
+
+ comp = self._create_comp(MySource)
+
+ def test_user_flt_output_ports_getitem(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ port1 = comp_self._add_output_port('clear')
+ port2 = comp_self._add_output_port('print')
+ port3 = comp_self._add_output_port('insert')
+ self.assertEqual(port3.addr, comp_self._output_ports['insert'].addr)
+ self.assertEqual(port2.addr, comp_self._output_ports['print'].addr)
+ self.assertEqual(port1.addr, comp_self._output_ports['clear'].addr)
+
+ comp = self._create_comp(MyFilter)
+
+ def test_user_flt_input_ports_getitem(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ port1 = comp_self._add_input_port('clear')
+ port2 = comp_self._add_input_port('print')
+ port3 = comp_self._add_input_port('insert')
+ self.assertEqual(port3.addr, comp_self._input_ports['insert'].addr)
+ self.assertEqual(port2.addr, comp_self._input_ports['print'].addr)
+ self.assertEqual(port1.addr, comp_self._input_ports['clear'].addr)
+
+ comp = self._create_comp(MyFilter)
+
+ def test_user_sink_input_ports_getitem(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port1 = comp_self._add_input_port('clear')
+ port2 = comp_self._add_input_port('print')
+ port3 = comp_self._add_input_port('insert')
+ self.assertEqual(port3.addr, comp_self._input_ports['insert'].addr)
+ self.assertEqual(port2.addr, comp_self._input_ports['print'].addr)
+ self.assertEqual(port1.addr, comp_self._input_ports['clear'].addr)
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ def test_user_src_output_ports_getitem_invalid_key(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_output_port('clear')
+ comp_self._add_output_port('print')
+ comp_self._add_output_port('insert')
+
+ with self.assertRaises(KeyError):
+ comp_self._output_ports['hello']
+
+ comp = self._create_comp(MySource)
+
+ def test_user_flt_output_ports_getitem_invalid_key(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_output_port('clear')
+ comp_self._add_output_port('print')
+ comp_self._add_output_port('insert')
+
+ with self.assertRaises(KeyError):
+ comp_self._output_ports['hello']
+
+ comp = self._create_comp(MyFilter)
+
+ def test_user_flt_input_ports_getitem_invalid_key(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+ comp_self._add_input_port('print')
+ comp_self._add_input_port('insert')
+
+ with self.assertRaises(KeyError):
+ comp_self._input_ports['hello']
+
+ comp = self._create_comp(MyFilter)
+
+ def test_user_sink_input_ports_getitem_invalid_key(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+ comp_self._add_input_port('print')
+ comp_self._add_input_port('insert')
+
+ with self.assertRaises(KeyError):
+ comp_self._input_ports['hello']
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ def test_user_src_output_ports_len(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_output_port('clear')
+ comp_self._add_output_port('print')
+ comp_self._add_output_port('insert')
+ self.assertEqual(len(comp_self._output_ports), 3)
+
+ comp = self._create_comp(MySource)
+
+ def test_user_flt_output_ports_len(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_output_port('clear')
+ comp_self._add_output_port('print')
+ comp_self._add_output_port('insert')
+ self.assertEqual(len(comp_self._output_ports), 3)
+
+ comp = self._create_comp(MyFilter)
+
+ def test_user_flt_input_ports_len(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+ comp_self._add_input_port('print')
+ comp_self._add_input_port('insert')
+ self.assertEqual(len(comp_self._input_ports), 3)
+
+ comp = self._create_comp(MyFilter)
+
+ def test_user_sink_input_ports_len(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+ comp_self._add_input_port('print')
+ comp_self._add_input_port('insert')
+ self.assertEqual(len(comp_self._input_ports), 3)
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ def test_user_src_output_ports_iter(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ port1 = comp_self._add_output_port('clear')
+ port2 = comp_self._add_output_port('print')
+ port3 = comp_self._add_output_port('insert')
+ ports = []
+
+ for port_name, port in comp_self._output_ports.items():
+ ports.append((port_name, port))
+
+ self.assertEqual(ports[0][0], 'clear')
+ self.assertEqual(ports[0][1].addr, port1.addr)
+ self.assertEqual(ports[1][0], 'print')
+ self.assertEqual(ports[1][1].addr, port2.addr)
+ self.assertEqual(ports[2][0], 'insert')
+ self.assertEqual(ports[2][1].addr, port3.addr)
+
+ comp = self._create_comp(MySource)
+
+ def test_user_flt_output_ports_iter(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ port1 = comp_self._add_output_port('clear')
+ port2 = comp_self._add_output_port('print')
+ port3 = comp_self._add_output_port('insert')
+ ports = []
+
+ for port_name, port in comp_self._output_ports.items():
+ ports.append((port_name, port))
+
+ self.assertEqual(ports[0][0], 'clear')
+ self.assertEqual(ports[0][1].addr, port1.addr)
+ self.assertEqual(ports[1][0], 'print')
+ self.assertEqual(ports[1][1].addr, port2.addr)
+ self.assertEqual(ports[2][0], 'insert')
+ self.assertEqual(ports[2][1].addr, port3.addr)
+
+ comp = self._create_comp(MyFilter)
+
+ def test_user_flt_input_ports_iter(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ port1 = comp_self._add_input_port('clear')
+ port2 = comp_self._add_input_port('print')
+ port3 = comp_self._add_input_port('insert')
+ ports = []
+
+ for port_name, port in comp_self._input_ports.items():
+ ports.append((port_name, port))
+
+ self.assertEqual(ports[0][0], 'clear')
+ self.assertEqual(ports[0][1].addr, port1.addr)
+ self.assertEqual(ports[1][0], 'print')
+ self.assertEqual(ports[1][1].addr, port2.addr)
+ self.assertEqual(ports[2][0], 'insert')
+ self.assertEqual(ports[2][1].addr, port3.addr)
+
+ comp = self._create_comp(MyFilter)
+
+ def test_user_sink_input_ports_iter(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port1 = comp_self._add_input_port('clear')
+ port2 = comp_self._add_input_port('print')
+ port3 = comp_self._add_input_port('insert')
+ ports = []
+
+ for port_name, port in comp_self._input_ports.items():
+ ports.append((port_name, port))
+
+ self.assertEqual(ports[0][0], 'clear')
+ self.assertEqual(ports[0][1].addr, port1.addr)
+ self.assertEqual(ports[1][0], 'print')
+ self.assertEqual(ports[1][1].addr, port2.addr)
+ self.assertEqual(ports[2][0], 'insert')
+ self.assertEqual(ports[2][1].addr, port3.addr)
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ def test_gen_src_output_ports_getitem(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ port1 = None
+ port2 = None
+ port3 = None
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ nonlocal port1, port2, port3
+ port1 = comp_self._add_output_port('clear')
+ port2 = comp_self._add_output_port('print')
+ port3 = comp_self._add_output_port('insert')
+
+ comp = self._create_comp(MySource)
+ self.assertEqual(port3.addr, comp.output_ports['insert'].addr)
+ self.assertEqual(port2.addr, comp.output_ports['print'].addr)
+ self.assertEqual(port1.addr, comp.output_ports['clear'].addr)
+ del port1
+ del port2
+ del port3
+
+ def test_gen_flt_output_ports_getitem(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ port1 = None
+ port2 = None
+ port3 = None
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ nonlocal port1, port2, port3
+ port1 = comp_self._add_output_port('clear')
+ port2 = comp_self._add_output_port('print')
+ port3 = comp_self._add_output_port('insert')
+
+ comp = self._create_comp(MyFilter)
+ self.assertEqual(port3.addr, comp.output_ports['insert'].addr)
+ self.assertEqual(port2.addr, comp.output_ports['print'].addr)
+ self.assertEqual(port1.addr, comp.output_ports['clear'].addr)
+ del port1
+ del port2
+ del port3
+
+ def test_gen_flt_input_ports_getitem(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ port1 = None
+ port2 = None
+ port3 = None
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ nonlocal port1, port2, port3
+ port1 = comp_self._add_input_port('clear')
+ port2 = comp_self._add_input_port('print')
+ port3 = comp_self._add_input_port('insert')
+
+ comp = self._create_comp(MyFilter)
+ self.assertEqual(port3.addr, comp.input_ports['insert'].addr)
+ self.assertEqual(port2.addr, comp.input_ports['print'].addr)
+ self.assertEqual(port1.addr, comp.input_ports['clear'].addr)
+ del port1
+ del port2
+ del port3
+
+ def test_gen_sink_input_ports_getitem(self):
+ port1 = None
+ port2 = None
+ port3 = None
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ nonlocal port1, port2, port3
+ port1 = comp_self._add_input_port('clear')
+ port2 = comp_self._add_input_port('print')
+ port3 = comp_self._add_input_port('insert')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ self.assertEqual(port3.addr, comp.input_ports['insert'].addr)
+ self.assertEqual(port2.addr, comp.input_ports['print'].addr)
+ self.assertEqual(port1.addr, comp.input_ports['clear'].addr)
+ del port1
+ del port2
+ del port3
+
+ def test_gen_src_output_ports_getitem_invalid_key(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_output_port('clear')
+ comp_self._add_output_port('print')
+ comp_self._add_output_port('insert')
+
+ comp = self._create_comp(MySource)
+
+ with self.assertRaises(KeyError):
+ comp.output_ports['hello']
+
+ def test_gen_flt_output_ports_getitem_invalid_key(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_output_port('clear')
+ comp_self._add_output_port('print')
+ comp_self._add_output_port('insert')
+
+ comp = self._create_comp(MyFilter)
+
+ with self.assertRaises(KeyError):
+ comp.output_ports['hello']
+
+ def test_gen_flt_input_ports_getitem_invalid_key(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+ comp_self._add_input_port('print')
+ comp_self._add_input_port('insert')
+
+ comp = self._create_comp(MyFilter)
+
+ with self.assertRaises(KeyError):
+ comp.input_ports['hello']
+
+ def test_gen_sink_input_ports_getitem_invalid_key(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+ comp_self._add_input_port('print')
+ comp_self._add_input_port('insert')
+
+ with self.assertRaises(KeyError):
+ comp_self._input_ports['hello']
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ with self.assertRaises(KeyError):
+ comp.input_ports['hello']
+
+ def test_gen_src_output_ports_len(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_output_port('clear')
+ comp_self._add_output_port('print')
+ comp_self._add_output_port('insert')
+
+ comp = self._create_comp(MySource)
+ self.assertEqual(len(comp.output_ports), 3)
+
+ def test_gen_flt_output_ports_len(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_output_port('clear')
+ comp_self._add_output_port('print')
+ comp_self._add_output_port('insert')
+
+ comp = self._create_comp(MyFilter)
+ self.assertEqual(len(comp.output_ports), 3)
+
+ def test_gen_flt_input_ports_len(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+ comp_self._add_input_port('print')
+ comp_self._add_input_port('insert')
+
+ comp = self._create_comp(MyFilter)
+ self.assertEqual(len(comp.input_ports), 3)
+
+ def test_gen_sink_input_ports_len(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+ comp_self._add_input_port('print')
+ comp_self._add_input_port('insert')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ self.assertEqual(len(comp.input_ports), 3)
+
+ def test_gen_src_output_ports_iter(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ port1 = None
+ port2 = None
+ port3 = None
+
+ class MySource(bt2._UserSourceComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ nonlocal port1, port2, port3
+ port1 = comp_self._add_output_port('clear')
+ port2 = comp_self._add_output_port('print')
+ port3 = comp_self._add_output_port('insert')
+
+ comp = self._create_comp(MySource)
+ ports = []
+
+ for port_name, port in comp.output_ports.items():
+ ports.append((port_name, port))
+
+ self.assertEqual(ports[0][0], 'clear')
+ self.assertEqual(ports[0][1].addr, port1.addr)
+ self.assertEqual(ports[1][0], 'print')
+ self.assertEqual(ports[1][1].addr, port2.addr)
+ self.assertEqual(ports[2][0], 'insert')
+ self.assertEqual(ports[2][1].addr, port3.addr)
+ del port1
+ del port2
+ del port3
+
+ def test_gen_flt_output_ports_iter(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ port1 = None
+ port2 = None
+ port3 = None
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ nonlocal port1, port2, port3
+ port1 = comp_self._add_output_port('clear')
+ port2 = comp_self._add_output_port('print')
+ port3 = comp_self._add_output_port('insert')
+
+ comp = self._create_comp(MyFilter)
+ ports = []
+
+ for port_name, port in comp.output_ports.items():
+ ports.append((port_name, port))
+
+ self.assertEqual(ports[0][0], 'clear')
+ self.assertEqual(ports[0][1].addr, port1.addr)
+ self.assertEqual(ports[1][0], 'print')
+ self.assertEqual(ports[1][1].addr, port2.addr)
+ self.assertEqual(ports[2][0], 'insert')
+ self.assertEqual(ports[2][1].addr, port3.addr)
+ del port1
+ del port2
+ del port3
+
+ def test_gen_flt_input_ports_iter(self):
+ class MyIter(bt2._UserNotificationIterator):
+ def __next__(self):
+ raise bt2.Stop
+
+ port1 = None
+ port2 = None
+ port3 = None
+
+ class MyFilter(bt2._UserFilterComponent,
+ notification_iterator_class=MyIter):
+ def __init__(comp_self, params):
+ nonlocal port1, port2, port3
+ port1 = comp_self._add_input_port('clear')
+ port2 = comp_self._add_input_port('print')
+ port3 = comp_self._add_input_port('insert')
+
+ comp = self._create_comp(MyFilter)
+ ports = []
+
+ for port_name, port in comp.input_ports.items():
+ ports.append((port_name, port))
+
+ self.assertEqual(ports[0][0], 'clear')
+ self.assertEqual(ports[0][1].addr, port1.addr)
+ self.assertEqual(ports[1][0], 'print')
+ self.assertEqual(ports[1][1].addr, port2.addr)
+ self.assertEqual(ports[2][0], 'insert')
+ self.assertEqual(ports[2][1].addr, port3.addr)
+ del port1
+ del port2
+ del port3
+
+ def test_gen_sink_input_ports_iter(self):
+ port1 = None
+ port2 = None
+ port3 = None
+
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ nonlocal port1, port2, port3
+ port1 = comp_self._add_input_port('clear')
+ port2 = comp_self._add_input_port('print')
+ port3 = comp_self._add_input_port('insert')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ ports = []
+
+ for port_name, port in comp.input_ports.items():
+ ports.append((port_name, port))
+
+ self.assertEqual(ports[0][0], 'clear')
+ self.assertEqual(ports[0][1].addr, port1.addr)
+ self.assertEqual(ports[1][0], 'print')
+ self.assertEqual(ports[1][1].addr, port2.addr)
+ self.assertEqual(ports[2][0], 'insert')
+ self.assertEqual(ports[2][1].addr, port3.addr)
+ del port1
+ del port2
+ del port3
+
+ def test_name(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ self.assertEqual(comp.input_ports['clear'].name, 'clear')
+
+ def test_component(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ self.assertEqual(comp.input_ports['clear'].component.addr, comp.addr)
+
+ def test_connection_none(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ self.assertIsNone(comp.input_ports['clear'].connection)
+
+ def test_is_connected_false(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ self.assertFalse(comp.input_ports['clear'].is_connected)
+
+ def test_eq(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ self.assertEqual(comp.input_ports['clear'],
+ comp.input_ports['clear'])
+
+ def test_eq_invalid(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ comp_self._add_input_port('clear')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ self.assertNotEqual(comp.input_ports['clear'], 23)
+
+ def test_disconnect_no_connection(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port = comp_self._add_input_port('clear')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+ comp.input_ports['clear'].disconnect()
+
+ def test_priv_name(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port = comp_self._add_input_port('clear')
+ self.assertEqual(port.name, 'clear')
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ def test_priv_component(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port = comp_self._add_input_port('clear')
+ self.assertEqual(port.component, comp_self)
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ def test_priv_connection_none(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port = comp_self._add_input_port('clear')
+ self.assertIsNone(port.connection)
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ def test_priv_is_connected_false(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port = comp_self._add_input_port('clear')
+ self.assertFalse(port.is_connected)
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ def test_priv_eq(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port = comp_self._add_input_port('clear')
+ self.assertEqual(port, port)
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ def test_priv_eq_invalid(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port = comp_self._add_input_port('clear')
+ self.assertNotEqual(port, 23)
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ def test_priv_disconnect_no_connection(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port = comp_self._add_input_port('clear')
+ port.disconnect()
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
+
+ def test_priv_remove_from_component(self):
+ class MySink(bt2._UserSinkComponent):
+ def __init__(comp_self, params):
+ port = comp_self._add_input_port('clear')
+ self.assertEqual(len(comp_self._input_ports), 1)
+
+ try:
+ port.remove_from_component()
+ except:
+ import traceback
+ traceback.print_exc()
+
+ self.assertEqual(len(comp_self._input_ports), 0)
+ self.assertIsNone(port.component)
+
+ def _consume(self):
+ pass
+
+ comp = self._create_comp(MySink)
class StreamTestCase(unittest.TestCase):
def setUp(self):
- self._stream = self._create_stream()
+ self._stream = self._create_stream(stream_id=23)
- def _create_stream(self, name='my_stream'):
+ def tearDown(self):
+ del self._stream
+
+ def _create_stream(self, name='my_stream', stream_id=None):
# event header
eh = bt2.StructureFieldType()
eh += OrderedDict((
tc.add_stream_class(sc)
# stream
- return sc(name=name)
+ return sc(name=name, id=stream_id)
def test_attr_stream_class(self):
self.assertIsNotNone(self._stream.stream_class)
self.assertEqual(self._stream.name, 'my_stream')
def test_eq(self):
- stream1 = self._create_stream()
- stream2 = self._create_stream()
+ stream1 = self._create_stream(stream_id=17)
+ stream2 = self._create_stream(stream_id=17)
self.assertEqual(stream1, stream2)
def test_ne_name(self):
- stream1 = self._create_stream()
- stream2 = self._create_stream('lel')
+ stream1 = self._create_stream(stream_id=17)
+ stream2 = self._create_stream('lel', 17)
+ self.assertNotEqual(stream1, stream2)
+
+ def test_ne_id(self):
+ stream1 = self._create_stream(stream_id=17)
+ stream2 = self._create_stream(stream_id=23)
self.assertNotEqual(stream1, stream2)
def test_eq_invalid(self):
event_context_field_type=self._event_context_ft,
event_classes=(self._ec1, self._ec2))
+ def tearDown(self):
+ del self._packet_context_ft
+ del self._event_header_ft
+ del self._event_context_ft
+ del self._ec1
+ del self._sc
+
def _create_event_classes(self):
context_ft = bt2.StructureFieldType()
context_ft.append_field('allo', bt2.StringFieldType())
self.assertEqual(self._sc.packet_context_field_type, self._packet_context_ft)
self.assertEqual(self._sc.event_header_field_type, self._event_header_ft)
self.assertEqual(self._sc.event_context_field_type, self._event_context_ft)
- self.assertEqual(self._sc['event23'], self._ec1)
- self.assertEqual(self._sc['event17'], self._ec2)
+ self.assertEqual(self._sc[23], self._ec1)
+ self.assertEqual(self._sc[17], self._ec2)
+ self.assertEqual(len(self._sc), 2)
def test_assign_name(self):
self._sc.name = 'lel'
with self.assertRaises(TypeError):
self._sc.id = 'lel'
+ def test_no_id(self):
+ sc = bt2.StreamClass()
+ self.assertIsNone(sc.id)
+
def test_assign_packet_context_field_type(self):
self._sc.packet_context_field_type = self._event_context_ft
self.assertEqual(self._sc.packet_context_field_type, self._event_context_ft)
self.assertNotEqual(self._sc.event_context_field_type.addr, cpy.event_context_field_type.addr)
def test_getitem(self):
- self.assertEqual(self._sc['event23'], self._ec1)
- self.assertEqual(self._sc['event17'], self._ec2)
+ self.assertEqual(self._sc[23], self._ec1)
+ self.assertEqual(self._sc[17], self._ec2)
def test_getitem_wrong_key_type(self):
with self.assertRaises(TypeError):
- self._sc[23]
+ self._sc['event23']
def test_getitem_wrong_key(self):
with self.assertRaises(KeyError):
- self._sc['hello']
+ self._sc[19]
def test_len(self):
self.assertEqual(len(self._sc), 2)
def test_iter(self):
- for name, event_class in self._sc.items():
+ for ec_id, event_class in self._sc.items():
self.assertIsInstance(event_class, bt2.EventClass)
- if name == 'event23':
+ if ec_id == 23:
self.assertEqual(event_class, self._ec1)
- elif name == 'event17':
+ elif ec_id == 17:
self.assertEqual(event_class, self._ec2)
- def test_event_class_with_id(self):
- self.assertEqual(self._sc.event_class_with_id(23), self._ec1)
-
- def test_event_class_with_id_wrong_type(self):
- with self.assertRaises(TypeError):
- self._sc.event_class_with_id('yes')
-
def test_eq(self):
ec1, ec2 = self._create_event_classes()
sc1 = bt2.StreamClass(name='my_stream_class', id=12,
self._sc = self._create_stream_class('sc1', 3)
self._tc = bt2.Trace()
+ def tearDown(self):
+ del self._sc
+ del self._tc
+
def _create_stream_class(self, name, id):
ec1, ec2 = self._create_event_classes()
packet_context_ft = bt2.StructureFieldType()
def test_create_default(self):
self.assertEqual(len(self._tc), 0)
- def test_create_full(self):
+ def _get_std_header(self):
header_ft = bt2.StructureFieldType()
header_ft.append_field('magic', bt2.IntegerFieldType(32))
- clock_classes = bt2.ClockClass('cc1'), bt2.ClockClass('cc2')
+ header_ft.append_field('stream_id', bt2.IntegerFieldType(32))
+ return header_ft
+
+ def test_create_full(self):
+ clock_classes = bt2.ClockClass('cc1', 1000), bt2.ClockClass('cc2', 30)
sc = self._create_stream_class('sc1', 3)
tc = bt2.Trace(name='my name',
native_byte_order=bt2.ByteOrder.LITTLE_ENDIAN,
env={'the_string': 'value', 'the_int': 23},
- packet_header_field_type=header_ft,
+ packet_header_field_type=self._get_std_header(),
clock_classes=clock_classes,
stream_classes=(sc,))
self.assertEqual(tc.name, 'my name')
self.assertEqual(tc.native_byte_order, bt2.ByteOrder.LITTLE_ENDIAN)
self.assertEqual(tc.env['the_string'], 'value')
self.assertEqual(tc.env['the_int'], 23)
- self.assertEqual(tc.packet_header_field_type, header_ft)
+ self.assertEqual(tc.packet_header_field_type, self._get_std_header())
self.assertEqual(tc.clock_classes['cc1'], clock_classes[0])
self.assertEqual(tc.clock_classes['cc2'], clock_classes[1])
self.assertEqual(tc[3], sc)
with self.assertRaises(TypeError):
self._tc.name = 17
+ def test_assign_static(self):
+ self._tc.set_is_static()
+ self.assertTrue(self._tc.is_static)
+
def test_assign_native_byte_order(self):
self._tc.native_byte_order = bt2.ByteOrder.BIG_ENDIAN
self.assertEqual(self._tc.native_byte_order, bt2.ByteOrder.BIG_ENDIAN)
self.assertEqual(len(self._tc), len(cpy))
def _pre_copy(self):
+ self._tc.packet_header_field_type = self._get_std_header()
self._tc.name = 'the trace class'
sc1 = self._create_stream_class('sc1', 3)
sc2 = self._create_stream_class('sc2', 9)
sc3 = self._create_stream_class('sc3', 17)
- self._tc.add_clock_class(bt2.ClockClass('cc1'))
- self._tc.add_clock_class(bt2.ClockClass('cc2'))
+ self._tc.add_clock_class(bt2.ClockClass('cc1', 1000))
+ self._tc.add_clock_class(bt2.ClockClass('cc2', 30))
self._tc.env['allo'] = 'bateau'
self._tc.env['bateau'] = 'cart'
self._tc.add_stream_class(sc1)
self.assertEqual(len(self._tc), 1)
def test_iter(self):
+ self._tc.packet_header_field_type = self._get_std_header()
sc1 = self._create_stream_class('sc1', 3)
sc2 = self._create_stream_class('sc2', 9)
sc3 = self._create_stream_class('sc3', 17)
with self.assertRaises(KeyError):
self._tc.clock_classes['lel']
+ def test_streams_none(self):
+ self.assertEqual(len(self._tc.streams), 0)
+
+ def test_streams_len(self):
+ self._tc.add_stream_class(self._create_stream_class('sc1', 3))
+ stream0 = self._tc[3]()
+ stream1 = self._tc[3]()
+ stream2 = self._tc[3]()
+ self.assertEqual(len(self._tc.streams), 3)
+
+ def test_streams_iter(self):
+ self._tc.add_stream_class(self._create_stream_class('sc1', 3))
+ stream0 = self._tc[3](id=12)
+ stream1 = self._tc[3](id=15)
+ stream2 = self._tc[3](id=17)
+ sids = set()
+
+ for stream in self._tc.streams:
+ sids.add(stream.id)
+
+ self.assertEqual(len(sids), 3)
+ self.assertTrue(12 in sids and 15 in sids and 17 in sids)
+
def _test_eq_create_objects(self):
cc1_uuid = uuid.UUID('bc7f2f2d-2ee4-4e03-ab1f-2e0e1304e94f')
- cc1 = bt2.ClockClass('cc1', uuid=cc1_uuid)
+ cc1 = bt2.ClockClass('cc1', 1000, uuid=cc1_uuid)
cc2_uuid = uuid.UUID('da7d6b6f-3108-4706-89bd-ab554732611b')
- cc2 = bt2.ClockClass('cc2', uuid=cc2_uuid)
+ cc2 = bt2.ClockClass('cc2', 30, uuid=cc2_uuid)
sc1 = self._create_stream_class('sc1', 3)
sc2 = self._create_stream_class('sc2', 9)
- header_ft = bt2.StructureFieldType()
- header_ft.append_field('magic', bt2.IntegerFieldType(32))
- return cc1, cc2, sc1, sc2, header_ft
+ return cc1, cc2, sc1, sc2, self._get_std_header()
def test_eq(self):
cc1, cc2, sc1, sc2, header_ft = self._test_eq_create_objects()
def test_frozen_exc(self):
self._def.freeze()
- with self.assertRaisesRegex(bt2.FrozenError, r'.* value object is frozen$') as cm:
+ with self.assertRaisesRegex(bt2.Frozen, r'.* value object is frozen$') as cm:
self._modify_def()
self.assertEqual(self._def, self._def_value)
self._def_value = False
self._def_new_value = True
+ def tearDown(self):
+ del self._f
+ del self._t
+ del self._def
+
def _assert_expecting_bool(self):
return self.assertRaisesRegex(TypeError, r"expecting a 'bool' object")
self._def_value = self._pv
self._def_new_value = -101
+ def tearDown(self):
+ del self._ip
+ del self._in
+ del self._def
+ del self._def_value
+
def _assert_expecting_int(self):
return self.assertRaisesRegex(TypeError, r'expecting a number object')
self._def_value = self._pv
self._def_new_value = -101.88
+ def tearDown(self):
+ del self._fp
+ del self._fn
+ del self._def
+ del self._def_value
+
def _assert_expecting_float(self):
return self.assertRaisesRegex(TypeError, r"expecting a real number object")
self._def = bt2.StringValue(self._def_value)
self._def_new_value = 'Yes!'
+ def tearDown(self):
+ del self._def
+
def _assert_expecting_str(self):
return self.assertRaises(TypeError)
self._def_value = [None, False, True, -23, 0, 42, -42.4, 23.17, 'yes']
self._def = bt2.ArrayValue(copy.deepcopy(self._def_value))
+ def tearDown(self):
+ del self._def
+
def _modify_def(self):
self._def[2] = 'xyz'
}
self._def = bt2.MapValue(copy.deepcopy(self._def_value))
+ def tearDown(self):
+ del self._def
+
def _modify_def(self):
self._def['zero'] = 1
coverage run $@
}
+export BABELTRACE_PYTHON_BT2_NO_TRACEBACK=1
+export TEST_PLUGIN_PLUGINS_PATH="@abs_top_builddir@/plugins"
+export BABELTRACE_PLUGIN_PATH="@abs_top_builddir@/plugins/ctf:@abs_top_builddir@/plugins/utils:@abs_top_builddir@/plugins/text"
PYTHON_BUILD_DIR="@abs_top_builddir@/bindings/python"
BT2_NATIVE_LIBS_DIR="@abs_top_builddir@/bindings/python/bt2/.libs"
TESTS_UTILS_PYTHON_DIR="@abs_top_srcdir@/tests/utils/python"
SUBDIRS = tap
+EXTRA_DIST = python/testrunner.py