bt2/clock_class.py \
bt2/clock_snapshot.py \
bt2/component.py \
+ bt2/component_descriptor.py \
bt2/connection.py \
bt2/error.py \
bt2/event.py \
from bt2.component import _UserSourceComponent
from bt2.component import _UserFilterComponent
from bt2.component import _UserSinkComponent
+from bt2.component_descriptor import ComponentDescriptor
from bt2.error import ComponentClassType
from bt2.error import _ErrorCause
from bt2.error import _ComponentErrorCause
--- /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
+from bt2 import component as bt2_component
+import bt2
+
+
+def _is_source_comp_cls(comp_cls):
+ if isinstance(comp_cls, bt2_component._SourceComponentClass):
+ return True
+
+ try:
+ return issubclass(comp_cls, bt2_component._UserSourceComponent)
+ except:
+ return False
+
+
+def _is_filter_comp_cls(comp_cls):
+ if isinstance(comp_cls, bt2_component._FilterComponentClass):
+ return True
+
+ try:
+ return issubclass(comp_cls, bt2_component._UserFilterComponent)
+ except:
+ return False
+
+
+def _is_sink_comp_cls(comp_cls):
+ if isinstance(comp_cls, bt2_component._SinkComponentClass):
+ return True
+
+ try:
+ return issubclass(comp_cls, bt2_component._UserSinkComponent)
+ except:
+ return False
+
+
+class ComponentDescriptor:
+ def __init__(self, component_class, params=None, obj=None):
+ if (
+ not _is_source_comp_cls(component_class)
+ and not _is_filter_comp_cls(component_class)
+ and not _is_sink_comp_cls(component_class)
+ ):
+ raise TypeError(
+ "'{}' is not a component class".format(
+ component_class.__class__.__name__
+ )
+ )
+
+ base_cc_ptr = component_class._bt_component_class_ptr()
+
+ if obj is not None and not native_bt.bt2_is_python_component_class(base_cc_ptr):
+ raise ValueError('cannot pass a Python object to a non-Python component')
+
+ self._comp_cls = component_class
+ self._params = bt2.create_value(params)
+ self._obj = obj
+
+ @property
+ def component_class(self):
+ return self._comp_cls
+
+ @property
+ def params(self):
+ return self._params
+
+ @property
+ def obj(self):
+ return self._obj
--- /dev/null
+#
+# Copyright (C) 2019 EfficiOS Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; only version 2
+# of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+
+import unittest
+import bt2
+
+
+class _DummySink(bt2._UserSinkComponent):
+ def _user_consume(self):
+ pass
+
+
+class ComponentDescriptorTestCase(unittest.TestCase):
+ def setUp(self):
+ self._obj = object()
+ self._comp_descr = bt2.ComponentDescriptor(_DummySink, {'zoom': -23}, self._obj)
+
+ def _get_comp_cls_from_plugin(self):
+ plugin = bt2.find_plugin('text', find_in_user_dir=False, find_in_sys_dir=False)
+ assert plugin is not None
+ cc = plugin.source_component_classes['dmesg']
+ assert cc is not None
+ return cc
+
+ def test_init_invalid_cls_type(self):
+ with self.assertRaises(TypeError):
+ bt2.ComponentDescriptor(int)
+
+ def test_init_invalid_params_type(self):
+ with self.assertRaises(TypeError):
+ bt2.ComponentDescriptor(_DummySink, object())
+
+ def test_init_invalid_obj_non_python_comp_cls(self):
+ cc = self._get_comp_cls_from_plugin()
+
+ with self.assertRaises(ValueError):
+ bt2.ComponentDescriptor(cc, obj=57)
+
+ def test_init_with_user_comp_cls(self):
+ bt2.ComponentDescriptor(_DummySink)
+
+ def test_init_with_gen_comp_cls(self):
+ cc = self._get_comp_cls_from_plugin()
+ bt2.ComponentDescriptor(cc)
+
+ def test_attr_component_class(self):
+ self.assertIs(self._comp_descr.component_class, _DummySink)
+
+ def test_attr_params(self):
+ self.assertEqual(self._comp_descr.params, {'zoom': -23})
+
+ def test_attr_obj(self):
+ self.assertIs(self._comp_descr.obj, self._obj)
def test_has__CurrentArrayElementFieldPathItem(self):
self._assert_in_bt2('_CurrentArrayElementFieldPathItem')
+ def test_has_ComponentDescriptor(self):
+ self._assert_in_bt2('ComponentDescriptor')
+
def test_has_Graph(self):
self._assert_in_bt2('Graph')