From ccd35bbd6fff549df8db6a7b7ff0adc38843cc4b Mon Sep 17 00:00:00 2001 From: Simon Marchi Date: Fri, 29 Mar 2019 18:18:21 -0400 Subject: [PATCH] Remove babeltrace 1 Python bindings and tests We previously had the goal of providing the Babeltrace 1 Python API (the babeltrace module) on top of the Babeltrace 2 Python API (the bt2 module). It was decided that this is no longer required, those who have scripts working against the Babeltrace 1 API will have to keep using Babeltrace 1. A factor that influenced this decision is that it would be difficult to keep the exact same behavior as Babeltrace 1 had, and therefore guarantee that scripts will keep working. For example, CTF headers (event headers or packet headers) are not accessible in trace-ir. So if a script relied on reading some header fields, the best we could do would be to simulate the value of some well-known header fields. For example, it would be possible to simulate the timestamp field of an event header. However, things like a packet's content_size and packet_size would be more difficult. So instead of putting efforts doing something that works halfway, it was decided that such scripts would have to keep using Babeltrace 1. Signed-off-by: Simon Marchi --- bindings/python/Makefile.am | 2 +- bindings/python/babeltrace/.gitignore | 4 - bindings/python/babeltrace/Makefile.am | 68 ---- .../babeltrace/babeltrace/__init__.py.in | 33 -- .../python/babeltrace/babeltrace/common.py | 164 -------- .../babeltrace/babeltrace/reader_event.py | 353 ------------------ .../babeltrace/reader_trace_handle.py | 137 ------- .../examples/babeltrace_and_lttng.py | 130 ------- .../python/babeltrace/examples/ctf_writer.py | 152 -------- .../babeltrace/examples/example-api-test.py | 69 ---- .../babeltrace/examples/sched_switch.py | 79 ---- .../babeltrace/examples/sequence_test.py | 67 ---- bindings/python/babeltrace/setup.py.in | 75 ---- configure.ac | 4 - tests/bindings/python/Makefile.am | 2 +- tests/bindings/python/babeltrace/Makefile.am | 7 - .../python/babeltrace/test_reader_event.py | 195 ---------- .../test_reader_field_declaration.py | 172 --------- .../test_reader_trace_intersection.py | 147 -------- 19 files changed, 2 insertions(+), 1858 deletions(-) delete mode 100644 bindings/python/babeltrace/.gitignore delete mode 100644 bindings/python/babeltrace/Makefile.am delete mode 100644 bindings/python/babeltrace/babeltrace/__init__.py.in delete mode 100644 bindings/python/babeltrace/babeltrace/common.py delete mode 100644 bindings/python/babeltrace/babeltrace/reader_event.py delete mode 100644 bindings/python/babeltrace/babeltrace/reader_trace_handle.py delete mode 100644 bindings/python/babeltrace/examples/babeltrace_and_lttng.py delete mode 100644 bindings/python/babeltrace/examples/ctf_writer.py delete mode 100644 bindings/python/babeltrace/examples/example-api-test.py delete mode 100644 bindings/python/babeltrace/examples/sched_switch.py delete mode 100644 bindings/python/babeltrace/examples/sequence_test.py delete mode 100644 bindings/python/babeltrace/setup.py.in delete mode 100644 tests/bindings/python/babeltrace/Makefile.am delete mode 100644 tests/bindings/python/babeltrace/test_reader_event.py delete mode 100644 tests/bindings/python/babeltrace/test_reader_field_declaration.py delete mode 100644 tests/bindings/python/babeltrace/test_reader_trace_intersection.py diff --git a/bindings/python/Makefile.am b/bindings/python/Makefile.am index fbc28130..f3cec072 100644 --- a/bindings/python/Makefile.am +++ b/bindings/python/Makefile.am @@ -1 +1 @@ -SUBDIRS = bt2 babeltrace +SUBDIRS = bt2 diff --git a/bindings/python/babeltrace/.gitignore b/bindings/python/babeltrace/.gitignore deleted file mode 100644 index 6d5c3f0f..00000000 --- a/bindings/python/babeltrace/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -build/ -installed_files.txt -babeltrace/__init__.py -setup.py diff --git a/bindings/python/babeltrace/Makefile.am b/bindings/python/babeltrace/Makefile.am deleted file mode 100644 index a331b389..00000000 --- a/bindings/python/babeltrace/Makefile.am +++ /dev/null @@ -1,68 +0,0 @@ -# Since the shared object used by the python bindings is not built with -# libtool, we need to add the directory containing libbabeltrace to the -# linker path. -AM_LDFLAGS=-L$(top_builddir)/lib/.libs - -INSTALLED_FILES=$(builddir)/installed_files.txt - -STATIC_BINDINGS_DEPS = \ - babeltrace/common.py \ - babeltrace/reader.py \ - babeltrace/reader_event_declaration.py \ - babeltrace/reader_event.py \ - babeltrace/reader_field_declaration.py \ - babeltrace/reader_field_definition.py \ - babeltrace/reader_trace_collection.py \ - babeltrace/reader_trace_handle.py \ - babeltrace/writer.py - -GENERATED_BINDINGS_DEPS = \ - babeltrace/__init__.py \ - setup.py - - -all-local: build-python-bindings.stamp - -copy-static-deps.stamp: $(STATIC_BINDINGS_DEPS) - @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ - for file in $(STATIC_BINDINGS_DEPS); do \ - cp -f $(srcdir)/$$file $(builddir)/$$file; \ - done; \ - fi - touch $@ - -build-python-bindings.stamp: copy-static-deps.stamp $(GENERATED_BINDINGS_DEPS) - $(BUILD_FLAGS) $(PYTHON) $(builddir)/setup.py build - touch $@ - -install-exec-local: build-python-bindings.stamp - @opts="--prefix=$(prefix) --record $(INSTALLED_FILES) --verbose --no-compile $(DISTSETUPOPTS)"; \ - if [ "$(DESTDIR)" != "" ]; then \ - opts="$$opts --root=$(DESTDIR)"; \ - fi; \ - $(PYTHON) $(builddir)/setup.py install $$opts; - -clean-local: - rm -rf $(builddir)/build - @if [ x"$(srcdir)" != x"$(builddir)" ]; then \ - for file in $(STATIC_BINDINGS_DEPS); do \ - rm -f $(builddir)/$$file; \ - done; \ - fi - -# Distutils' setup.py does not include an uninstall target, we thus need to do -# it manually. We save the path of the files that were installed during the install target -# and delete them during the uninstallation. -uninstall-local: - if [ "$(DESTDIR)" != "" ]; then \ - $(SED) -i "s|^|$(DESTDIR)/|g" $(INSTALLED_FILES); \ - fi - cat $(INSTALLED_FILES) | xargs rm -rf || true - $(GREP) "__init__.py" $(INSTALLED_FILES) | xargs dirname | xargs rm -rf || true - rm -f $(INSTALLED_FILES) - -# distribute: extra Python modules and SWIG interface files -EXTRA_DIST = $(STATIC_BINDINGS_DEPS) - -# clean: generated Python files and stamps -CLEANFILES = build-python-bindings.stamp copy-static-deps.stamp diff --git a/bindings/python/babeltrace/babeltrace/__init__.py.in b/bindings/python/babeltrace/babeltrace/__init__.py.in deleted file mode 100644 index d58185e2..00000000 --- a/bindings/python/babeltrace/babeltrace/__init__.py.in +++ /dev/null @@ -1,33 +0,0 @@ -# backward compatibility with old `babeltrace` module: import common members -from .common import \ - CTFStringEncoding, \ - ByteOrder, \ - CTFTypeId, \ - CTFScope - - -# backward compatibility with old `babeltrace` module: import reader API members -from .reader import \ - TraceCollection, \ - TraceHandle, \ - Event, \ - FieldError, \ - EventDeclaration, \ - FieldDeclaration, \ - IntegerFieldDeclaration, \ - EnumerationFieldDeclaration, \ - ArrayFieldDeclaration, \ - SequenceFieldDeclaration, \ - FloatFieldDeclaration, \ - StructureFieldDeclaration, \ - StringFieldDeclaration, \ - VariantFieldDeclaration - - -# backward compatibility with old `babeltrace` module: import CTF writer API -# module as `CTFWriter`, since `CTFWriter` used to be a class in the -# `babeltrace` module -import babeltrace.writer as CTFWriter - - -__version__ = '@PACKAGE_VERSION@' diff --git a/bindings/python/babeltrace/babeltrace/common.py b/bindings/python/babeltrace/babeltrace/common.py deleted file mode 100644 index 1dffa1bb..00000000 --- a/bindings/python/babeltrace/babeltrace/common.py +++ /dev/null @@ -1,164 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2013-2017 Jérémie Galarneau -# -# 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. - - -class CTFStringEncoding: - """ - CTF string encodings. - """ - - #: None - NONE = 0 - - #: UTF-8 - UTF8 = 1 - - #: ASCII - ASCII = 2 - - #: Unknown - UNKNOWN = 3 - - -# Based on the enum in ctf-writer/writer.h -class ByteOrder: - """ - Byte orders. - """ - - #: Native byte order - BYTE_ORDER_NATIVE = 0 - - #: Little-endian - BYTE_ORDER_LITTLE_ENDIAN = 1 - - #: Big-endian - BYTE_ORDER_BIG_ENDIAN = 2 - - #: Network byte order (big-endian) - BYTE_ORDER_NETWORK = 3 - - #: Unknown byte order - BYTE_ORDER_UNKNOWN = 4 # Python-specific entry - - -# enum equivalent, accessible constants -# These are taken directly from ctf/events.h -# All changes to enums must also be made here -class CTFTypeId: - """ - CTF numeric type identifiers. - """ - - #: Unknown type - UNKNOWN = 0 - - #: Integer - INTEGER = 1 - - #: Floating point number - FLOAT = 2 - - #: Enumeration - ENUM = 3 - - #: String - STRING = 4 - - #: Structure - STRUCT = 5 - - #: Untagged variant - UNTAGGED_VARIANT = 6 - - #: Variant - VARIANT = 7 - - #: Array - ARRAY = 8 - - #: Sequence - SEQUENCE = 9 - - NR_CTF_TYPES = 10 - - def type_name(id): - """ - Returns the name of the CTF numeric type identifier *id*. - """ - - name = "UNKNOWN_TYPE" - constants = [ - attr for attr in dir(CTFTypeId) if not callable( - getattr( - CTFTypeId, - attr)) and not attr.startswith("__")] - - for attr in constants: - if getattr(CTFTypeId, attr) == id: - name = attr - break - - return name - - -class CTFScope: - """ - CTF scopes. - """ - - #: Packet header - TRACE_PACKET_HEADER = 0 - - #: Packet context - STREAM_PACKET_CONTEXT = 1 - - #: Event header - STREAM_EVENT_HEADER = 2 - - #: Stream event context - STREAM_EVENT_CONTEXT = 3 - - #: Event context - EVENT_CONTEXT = 4 - - #: Event fields - EVENT_FIELDS = 5 - - def scope_name(scope): - """ - Returns the name of the CTF scope *scope*. - """ - - name = "UNKNOWN_SCOPE" - constants = [ - attr for attr in dir(CTFScope) if not callable( - getattr( - CTFScope, - attr)) and not attr.startswith("__")] - - for attr in constants: - if getattr(CTFScope, attr) == scope: - name = attr - break - - return name diff --git a/bindings/python/babeltrace/babeltrace/reader_event.py b/bindings/python/babeltrace/babeltrace/reader_event.py deleted file mode 100644 index 4ed4de3d..00000000 --- a/bindings/python/babeltrace/babeltrace/reader_event.py +++ /dev/null @@ -1,353 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2013-2017 Jérémie Galarneau -# -# 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. - -import bt2 -import babeltrace.common as common -import babeltrace.reader_field_definition as field_definition -import datetime -import collections - - -def _create_event(event_notification, trace_handle=None, trace_collection=None): - event = Event.__new__(Event) - event._event_notification = event_notification - event._trace_handle = trace_handle - event._trace_collection = trace_collection - return event - - -class Event(collections.Mapping): - """ - An :class:`Event` object represents a trace event. :class:`Event` - objects are returned by :attr:`TraceCollection.events` and are - not meant to be instantiated by the user. - - :class:`Event` has a :class:`dict`-like interface for accessing - an event's field value by field name: - - .. code-block:: python - - event['my_field'] - - If a field name exists in multiple scopes, the value of the first - field found is returned. The scopes are searched in the following - order: - - 1. Event fields (:attr:`babeltrace.common.CTFScope.EVENT_FIELDS`) - 2. Event context (:attr:`babeltrace.common.CTFScope.EVENT_CONTEXT`) - 3. Stream event context (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_CONTEXT`) - 4. Event header (:attr:`babeltrace.common.CTFScope.STREAM_EVENT_HEADER`) - 5. Packet context (:attr:`babeltrace.common.CTFScope.STREAM_PACKET_CONTEXT`) - 6. Packet header (:attr:`babeltrace.common.CTFScope.TRACE_PACKET_HEADER`) - - It is still possible to obtain a field's value from a specific - scope using :meth:`field_with_scope`. - - Field values are returned as native Python types, that is: - - +-----------------------+----------------------------------+ - | Field type | Python type | - +=======================+==================================+ - | Integer | :class:`int` | - +-----------------------+----------------------------------+ - | Floating point number | :class:`float` | - +-----------------------+----------------------------------+ - | Enumeration | :class:`str` (enumeration label) | - +-----------------------+----------------------------------+ - | String | :class:`str` | - +-----------------------+----------------------------------+ - | Array | :class:`list` of native Python | - | | objects | - +-----------------------+----------------------------------+ - | Sequence | :class:`list` of native Python | - | | objects | - +-----------------------+----------------------------------+ - | Structure | :class:`dict` mapping field | - | | names to native Python objects | - +-----------------------+----------------------------------+ - - For example, printing the third element of a sequence named ``seq`` - in a structure named ``my_struct`` of the ``event``'s field named - ``my_field`` is done this way: - - .. code-block:: python - - print(event['my_field']['my_struct']['seq'][2]) - """ - - def __init__(self): - raise NotImplementedError("Event cannot be instantiated") - - @property - def name(self): - """ - Event name or ``None`` on error. - """ - - try: - return self._event_notification.event.name - except bt2.Error: - pass - - def _clock_value(self): - cc_prio_map = self._event_notification.clock_class_priority_map - clock_class = cc_prio_map.highest_priority_clock_class - if not clock_class: - return - - return self._event_notification.event.clock_value(clock_class) - - @property - def cycles(self): - """ - Event timestamp in cycles or -1 on error. - """ - - try: - clock_value = self._clock_value() - except bt2.Error: - return -1 - - if clock_value is not None: - return clock_value.cycles - else: - return -1 - - @property - def timestamp(self): - """ - Event timestamp (nanoseconds since Epoch). - """ - - try: - clock_value = self._clock_value() - except bt2.Error: - raise RuntimeError("Failed to get event timestamp") - - if clock_value is not None: - return clock_value.ns_from_epoch - else: - raise RuntimeError("Failed to get event timestamp") - - @property - def datetime(self): - """ - Event timestamp as a standard :class:`datetime.datetime` - object. - - Note that the :class:`datetime.datetime` class' precision - is limited to microseconds, whereas :attr:`timestamp` provides - the event's timestamp with a nanosecond resolution. - """ - - return datetime.date.fromtimestamp(self.timestamp / 1E9) - - def field_with_scope(self, field_name, scope): - """ - Returns the value of a field named *field_name* within the - scope *scope*, or ``None`` if the field cannot be found. - - *scope* must be one of :class:`babeltrace.common.CTFScope` - constants. - """ - - if scope not in _SCOPES: - raise ValueError("Invalid scope provided") - - field = self._field_with_scope(field_name, scope) - - if field is not None: - return field.value - - def field_list_with_scope(self, scope): - """ - Returns a list of field names in the scope *scope*. - """ - - if scope not in _SCOPES: - raise ValueError("Invalid scope provided") - - field_names = [] - - for field in self._field_list_with_scope(scope): - field_names.append(field.name) - - return field_names - - @property - def handle(self): - """ - :class:`TraceHandle` object containing this event, or ``None`` - on error. - """ - - try: - return self._trace_handle - except AttributeError: - return None - - @property - def trace_collection(self): - """ - :class:`TraceCollection` object containing this event, or - ``None`` on error. - """ - - try: - return self._trace_collection - except AttributeError: - return - - def __getitem__(self, field_name): - field = self._field(field_name) - if field is None: - raise KeyError(field_name) - return field.value - - def __iter__(self): - for key in self.keys(): - yield key - - def __len__(self): - count = 0 - for scope in _SCOPES: - scope_field = self._get_scope_field(scope) - if scope_field is not None and isinstance(scope_field, - bt2._StructureField): - count += len(scope_field) - return count - - def __contains__(self, field_name): - return self._field(field_name) is not None - - def keys(self): - """ - Returns the list of field names. - - Note: field names are unique within the returned list, although - a field name could exist in multiple scopes. Use - :meth:`field_list_with_scope` to obtain the list of field names - of a given scope. - """ - - field_names = set() - - for scope in _SCOPES: - for name in self.field_list_with_scope(scope): - field_names.add(name) - - return list(field_names) - - def get(self, field_name, default=None): - """ - Returns the value of the field named *field_name*, or *default* - when not found. - - See :class:`Event` note about how fields are retrieved by - name when multiple fields share the same name in different - scopes. - """ - - field = self._field(field_name) - - if field is None: - return default - - return field.value - - def items(self): - """ - Generates pairs of (field name, field value). - - This method iterates :meth:`keys` to find field names, which - means some fields could be unavailable if other fields share - their names in scopes with higher priorities. - """ - - for field in self.keys(): - yield (field, self[field]) - - def _get_scope_field(self, scope): - try: - event = self._event_notification.event - if scope is common.CTFScope.EVENT_FIELDS: - return event.payload_field - - if scope is common.CTFScope.EVENT_CONTEXT: - return event.context_field - - if scope is common.CTFScope.STREAM_EVENT_CONTEXT: - return event.stream_event_context_field - - if scope is common.CTFScope.STREAM_EVENT_HEADER: - return event.header_field - - if scope is common.CTFScope.STREAM_PACKET_CONTEXT: - return event.packet.context_field - - if scope is common.CTFScope.TRACE_PACKET_HEADER: - return event.packet.header_field - except bt2.Error: - return - - raise ValueError("Invalid scope provided") - - def _field_with_scope(self, field_name, scope): - scope_field = self._get_scope_field(scope) - if scope_field is not None: - try: - bt2_field = scope_field[field_name] - if bt2_field is not None: - return field_definition._Definition(scope, bt2_field, - field_name) - except (KeyError, bt2.Error): - return None - - def _field(self, field_name): - for scope in _SCOPES: - field = self._field_with_scope(field_name, scope) - if field is not None: - return field - - def _field_list_with_scope(self, scope): - fields = [] - scope_field = self._get_scope_field(scope) - - if scope_field is None or not isinstance(scope_field, - bt2._StructureField): - return fields - - for name, field in scope_field.items(): - fields.append(field_definition._Definition(scope, field, name)) - - return fields - - -# Priority of the scopes when searching for event fields -_SCOPES = [ - common.CTFScope.EVENT_FIELDS, - common.CTFScope.EVENT_CONTEXT, - common.CTFScope.STREAM_EVENT_CONTEXT, - common.CTFScope.STREAM_EVENT_HEADER, - common.CTFScope.STREAM_PACKET_CONTEXT, - common.CTFScope.TRACE_PACKET_HEADER -] diff --git a/bindings/python/babeltrace/babeltrace/reader_trace_handle.py b/bindings/python/babeltrace/babeltrace/reader_trace_handle.py deleted file mode 100644 index 4d682300..00000000 --- a/bindings/python/babeltrace/babeltrace/reader_trace_handle.py +++ /dev/null @@ -1,137 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2013-2017 Jérémie Galarneau -# -# 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. - -import bt2 -import itertools -from babeltrace import reader_event_declaration - - -class TraceHandle: - """ - A :class:`TraceHandle` is a handle allowing the user to manipulate - a specific trace directly. It is a unique identifier representing a - trace, and is not meant to be instantiated by the user. - """ - - def __init__(self): - raise NotImplementedError("TraceHandle cannot be instantiated") - - def __repr__(self): - # TODO print an id or some information about component / query result? - return "Babeltrace TraceHandle: trace_id('{0}')".format(self._id) - - def __hash__(self): - return hash((self.path, self.id)) - - def __eq__(self, other): - if type(other) is not type(self): - return False - - return (self.path, self.id) == (other.path, other.id) - - @property - def id(self): - """ - Numeric ID of this trace handle. - """ - - return self._id - - @property - def path(self): - """ - Path of the underlying trace. - """ - - return self._path - - def _query_trace_info(self): - try: - result = bt2.QueryExecutor().query(self._trace_collection._fs_comp_cls, - 'trace-info', {'path': self._path}) - except: - raise ValueError - - assert(len(result) == 1) - return result - - @property - def timestamp_begin(self): - """ - Buffers creation timestamp (nanoseconds since Epoch) of the - underlying trace. - """ - - result = self._query_trace_info() - - try: - return int(result[0]['range-ns']['begin']) - except: - raise ValueError - - @property - def timestamp_end(self): - """ - Buffers destruction timestamp (nanoseconds since Epoch) of the - underlying trace. - """ - - result = self._query_trace_info() - - try: - return int(result[0]['range-ns']['end']) - except: - raise ValueError - - @property - def _has_intersection(self): - result = self._query_trace_info() - - try: - return 'intersection-range-ns' in result[0] - except: - raise ValueError - - def _get_event_declarations(self): - notif_iter = bt2.TraceCollectionNotificationIterator([ - bt2.ComponentSpec('ctf', 'fs', self._path) - ]) - - # raises if the trace contains no streams - first_notif = next(notif_iter) - assert(type(first_notif) is bt2.StreamBeginningNotification) - trace = first_notif.stream.stream_class.trace - ec_iters = [sc.values() for sc in trace.values()] - return map(reader_event_declaration._create_event_declaration, - itertools.chain(*ec_iters)) - - @property - def events(self): - """ - Generates all the :class:`EventDeclaration` objects of the - underlying trace. - """ - - try: - return self._get_event_declarations() - except: - return diff --git a/bindings/python/babeltrace/examples/babeltrace_and_lttng.py b/bindings/python/babeltrace/examples/babeltrace_and_lttng.py deleted file mode 100644 index 651fa2da..00000000 --- a/bindings/python/babeltrace/examples/babeltrace_and_lttng.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 -# babeltrace_and_lttng.py -# -# Babeltrace and LTTng example script -# -# Copyright 2012 EfficiOS Inc. -# -# Author: Danny Serres -# -# 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. - - -# This script uses both lttng-tools and babeltrace -# python modules. It creates a session, enables -# events, starts tracing for 2 seconds, stops tracing, -# destroys the session and outputs the trace in the -# specified output file. -# -# WARNING: will destroy any existing trace having -# the same name as ses_name - - -# ------------------------------------------------------ -ses_name = "babeltrace-lttng-test" -trace_path = "/lttng-traces/babeltrace-lttng-trace/" -out_file = "babeltrace-lttng-trace-text-output.txt" -# ------------------------------------------------------ - - -import time -try: - import babeltrace.reader - import lttng -except ImportError: - raise ImportError( "both babeltrace and lttng-tools " - "python modules must be installed") - - -# Errors to raise if something goes wrong -class LTTngError(Exception): - pass - - -class BabeltraceError(Exception): - pass - - -# LTTNG-TOOLS - -# Making sure session does not already exist -lttng.destroy(ses_name) - -# Creating a new session and handle -ret = lttng.create(ses_name, trace_path) -if ret < 0: - raise LTTngError(lttng.strerror(ret)) - -domain = lttng.Domain() -domain.type = lttng.DOMAIN_KERNEL - -han = None -han = lttng.Handle(ses_name, domain) -if han is None: - raise LTTngError("Handle not created") - - -# Enabling all events -event = lttng.Event() -event.type = lttng.EVENT_ALL -event.loglevel_type = lttng.EVENT_LOGLEVEL_ALL -ret = lttng.enable_event(han, event, None) -if ret < 0: - raise LTTngError(lttng.strerror(ret)) - -# Start, wait, stop -ret = lttng.start(ses_name) -if ret < 0: - raise LTTngError(lttng.strerror(ret)) -print("Tracing...") -time.sleep(2) -print("Stopped.") -ret = lttng.stop(ses_name) -if ret < 0: - raise LTTngError(lttng.strerror(ret)) - - -# Destroying tracing session -ret = lttng.destroy(ses_name) -if ret < 0: - raise LTTngError(lttng.strerror(ret)) - - -# BABELTRACE - -# Create TraceCollecion and add trace: -traces = babeltrace.reader.TraceCollection() -ret = traces.add_trace(trace_path + "/kernel", "ctf") -if ret is None: - raise BabeltraceError("Error adding trace") - -# Reading events from trace -# and outputting timestamps and event names -# in out_file -print("Writing trace file...") -output = open(out_file, "wt") - -for event in traces.events: - output.write("TS: {}, {} : {}\n".format( - event.timestamp, event.cycles, event.name)) - -# Closing file -output.close() - -print("Done.") diff --git a/bindings/python/babeltrace/examples/ctf_writer.py b/bindings/python/babeltrace/examples/ctf_writer.py deleted file mode 100644 index 03e01ea9..00000000 --- a/bindings/python/babeltrace/examples/ctf_writer.py +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env python3 -# ctf_writer.py -# -# Babeltrace CTF Writer example script. -# -# Copyright 2013 EfficiOS Inc. -# -# Author: Jérémie Galarneau -# -# 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. - -import sys -import tempfile -import babeltrace.writer as btw - - -trace_path = tempfile.mkdtemp() - -print("Writing trace at {}".format(trace_path)) -writer = btw.Writer(trace_path) - -clock = btw.Clock("A_clock") -print("Clock name is \"{}\"".format(clock.name)) -clock.description = "Simple clock" -print("Clock description is \"{}\"".format(clock.description)) -print("Clock frequency is {}".format(clock.frequency)) -print("Clock precision is {}".format(clock.precision)) -print("Clock offset_seconds is {}".format(clock.offset_seconds)) -print("Clock offset is {}".format(clock.offset)) -print("Clock is absolute: {}".format(clock.absolute)) -print("Clock time is {}".format(clock.time)) -print("Clock UUID is {}".format(clock.uuid)) - -writer.add_clock(clock) -writer.add_environment_field("Python_version", str(sys.version_info)) - -stream_class = btw.StreamClass("test_stream") -stream_class.clock = clock - -event_class = btw.EventClass("SimpleEvent") - -# Create a int32_t equivalent type -int32_type = btw.IntegerFieldDeclaration(32) -int32_type.signed = True - -# Create a uint16_t equivalent type -uint16_type = btw.IntegerFieldDeclaration(16) -uint16_type.signed = False - -# Add a custom uint16_t field in the stream's packet context -packet_context_type = stream_class.packet_context_type -print("\nFields in default packet context:") -for field in packet_context_type.fields: - print(str(type(field[1])) + " " + field[0]) -packet_context_type.add_field(uint16_type, "a_custom_packet_context_field") -stream_class.packet_context_type = packet_context_type - -# Set a stream event context -stream_event_context_type = btw.StructureFieldDeclaration() -stream_event_context_type.add_field(int32_type, "field_in_stream_event_context") -stream_class.event_context_type = stream_event_context_type - -# Create a string type -string_type = btw.StringFieldDeclaration() - -# Create a structure type containing both an integer and a string -structure_type = btw.StructureFieldDeclaration() -structure_type.add_field(int32_type, "an_integer") -structure_type.add_field(string_type, "a_string_field") -event_class.add_field(structure_type, "structure_field") - -# Create a floating point type -floating_point_type = btw.FloatFieldDeclaration() -floating_point_type.exponent_digits = btw.FloatFieldDeclaration.FLT_EXP_DIG -floating_point_type.mantissa_digits = btw.FloatFieldDeclaration.FLT_MANT_DIG -event_class.add_field(floating_point_type, "float_field") - -# Create an enumeration type -int10_type = btw.IntegerFieldDeclaration(10) -enumeration_type = btw.EnumerationFieldDeclaration(int10_type) -enumeration_type.add_mapping("FIRST_ENTRY", 0, 4) -enumeration_type.add_mapping("SECOND_ENTRY", 5, 5) -enumeration_type.add_mapping("THIRD_ENTRY", 6, 10) -event_class.add_field(enumeration_type, "enum_field") - -# Create an array type -array_type = btw.ArrayFieldDeclaration(int10_type, 5) -event_class.add_field(array_type, "array_field") - -# Create a sequence type -sequence_type = btw.SequenceFieldDeclaration(int32_type, "sequence_len") -event_class.add_field(uint16_type, "sequence_len") -event_class.add_field(sequence_type, "sequence_field") - -stream_class.add_event_class(event_class) -stream = writer.create_stream(stream_class) - -for i in range(100): - event = btw.Event(event_class) - - clock.time = i * 1000 - structure_field = event.payload("structure_field") - integer_field = structure_field.field("an_integer") - integer_field.value = i - - string_field = structure_field.field("a_string_field") - string_field.value = "Test string." - - float_field = event.payload("float_field") - float_field.value = float(i) + (float(i) / 100.0) - - array_field = event.payload("array_field") - for j in range(5): - element = array_field.field(j) - element.value = i + j - - event.payload("sequence_len").value = i % 10 - sequence_field = event.payload("sequence_field") - sequence_field.length = event.payload("sequence_len") - for j in range(event.payload("sequence_len").value): - sequence_field.field(j).value = i + j - - enumeration_field = event.payload("enum_field") - integer_field = enumeration_field.container - enumeration_field.value = i % 10 - - event.stream_context.field("field_in_stream_event_context").value = i * 10 - - stream.append_event(event) - -# Populate custom packet context field before flushing -packet_context = stream.packet_context -field = packet_context.field("a_custom_packet_context_field") -field.value = 42 - -stream.flush() diff --git a/bindings/python/babeltrace/examples/example-api-test.py b/bindings/python/babeltrace/examples/example-api-test.py deleted file mode 100644 index 1bdea6cc..00000000 --- a/bindings/python/babeltrace/examples/example-api-test.py +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env python3 -# example_api_test.py -# -# Babeltrace example script based on the Babeltrace API test script -# -# Copyright 2012 EfficiOS Inc. -# -# Author: Danny Serres -# -# 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. - -# This example uses the babeltrace python module -# to partially test the api. - -import sys -import babeltrace.reader - - -# Check for path arg: -if len(sys.argv) < 2: - raise TypeError("Usage: python example-api-test.py path/to/file") - -# Create TraceCollection and add trace: -traces = babeltrace.reader.TraceCollection() -trace_handle = traces.add_trace(sys.argv[1], "ctf") -if trace_handle is None: - raise IOError("Error adding trace") - -# Listing events -print("--- Event list ---") -for event_declaration in trace_handle.events: - print("event : {}".format(event_declaration.name)) - if event_declaration.name == "sched_switch": - for field_declaration in event_declaration.fields: - print(field_declaration) -print("--- Done ---") - -for event in traces.events: - print("TS: {}, {} : {}".format(event.timestamp, event.cycles, event.name)) - - if event.name == "sched_switch": - prev_comm = event["prev_comm"] - if prev_comm is None: - print("ERROR: Missing prev_comm context info") - else: - print("sched_switch prev_comm: {}".format(prev_comm)) - - if event.name == "exit_syscall": - ret_code = event["ret"] - if ret_code is None: - print("ERROR: Unable to extract ret") - else: - print("exit_syscall ret: {}".format(ret_code)) diff --git a/bindings/python/babeltrace/examples/sched_switch.py b/bindings/python/babeltrace/examples/sched_switch.py deleted file mode 100644 index 0deb4a53..00000000 --- a/bindings/python/babeltrace/examples/sched_switch.py +++ /dev/null @@ -1,79 +0,0 @@ -#!/usr/bin/env python3 -# sched_switch.py -# -# Babeltrace example script with sched_switch events -# -# Copyright 2012 EfficiOS Inc. -# -# Author: Danny Serres -# -# 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. - -# The script takes one optional argument (pid) -# The script will read events based on pid and -# print the scheduler switches happening with the process. -# If no arguments are passed, it displays all the scheduler switches. -# This can be used to understand which tasks schedule out the current -# process being traced, and when it gets scheduled in again. -# The trace needs PID context (lttng add-context -k -t pid) - -import sys -import babeltrace.reader -import babeltrace.common - - -if len(sys.argv) < 2 or len(sys.argv) > 3: - raise TypeError("Usage: python sched_switch.py [pid] path/to/trace") -elif len(sys.argv) == 3: - filterPID = True -else: - filterPID = False - -traces = babeltrace.reader.TraceCollection() -ret = traces.add_trace(sys.argv[len(sys.argv) - 1], "ctf") -if ret is None: - raise IOError("Error adding trace") - -for event in traces.events: - if event.name != "sched_switch": - continue - - # Getting PID - pid = event.field_with_scope("pid", babeltrace.common.CTFScope.STREAM_EVENT_CONTEXT) - if pid is None: - print("ERROR: Missing PID info for sched_switch") - continue # Next event - - if filterPID and (pid != long(sys.argv[1])): - continue # Next event - - prev_comm = event["prev_comm"] - prev_tid = event["prev_tid"] - prev_prio = event["prev_prio"] - prev_state = event["prev_state"] - next_comm = event["next_comm"] - next_tid = event["next_tid"] - next_prio = event["next_prio"] - - # Output - print("sched_switch, pid = {}, TS = {}, prev_comm = {},\n\t" - "prev_tid = {}, prev_prio = {}, prev_state = {},\n\t" - "next_comm = {}, next_tid = {}, next_prio = {}".format( - pid, event.timestamp, prev_comm, prev_tid, - prev_prio, prev_state, next_comm, next_tid, next_prio)) diff --git a/bindings/python/babeltrace/examples/sequence_test.py b/bindings/python/babeltrace/examples/sequence_test.py deleted file mode 100644 index e9116ced..00000000 --- a/bindings/python/babeltrace/examples/sequence_test.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python3 -# sequence_test.py -# -# Babeltrace example script based on the Babeltrace API test script -# -# Copyright 2013 Xiaona Han -# Copyright 2012 EfficiOS Inc. -# -# Author: Danny Serres -# Author: Xiaona Han -# -# 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. - -# This example uses the babeltrace python module -# to partially test the sequence API - -import sys -import babeltrace.reader - - -# Check for path arg: -if len(sys.argv) < 2: - raise TypeError("Usage: sequence_test.py path/to/file") - -# Create TraceCollection and add trace: -traces = babeltrace.reader.TraceCollection() -trace_handle = traces.add_trace(sys.argv[1], "ctf") -if trace_handle is None: - raise IOError("Error adding trace") - -# Listing events -print("--- Event list ---") -for event_declaration in trace_handle.events: - print("event : {}".format(event_declaration.name)) -print("--- Done ---") - -for event in traces.events: - print("TS: {}, {} : {}".format(event.timestamp, - event.cycles, event.name)) - - try: - sequence = event["seq_int_field"] - print("int sequence values: {}". format(sequence)) - except KeyError: - pass - - try: - sequence = event["seq_long_field"] - print("long sequence values: {}". format(sequence)) - except KeyError: - pass diff --git a/bindings/python/babeltrace/setup.py.in b/bindings/python/babeltrace/setup.py.in deleted file mode 100644 index 59052d74..00000000 --- a/bindings/python/babeltrace/setup.py.in +++ /dev/null @@ -1,75 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (C) 2017 - Francis Deslauriers -# -# 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. - -import sys - -from distutils.core import setup, Extension - -PY_PATH_WARN_MSG = """ --------------------------------------WARNING------------------------------------ -The install directory used:\n ({})\nis not included in your PYTHONPATH. - -To add this directory to your Python search path permanently you can add the -following command to your .bashrc/.zshrc: - export PYTHONPATH="${{PYTHONPATH}}:{}" --------------------------------------------------------------------------------- -""" - -def main(): - dist = setup(name='babeltrace', - version='@PACKAGE_VERSION@', - description='Babeltrace Python Bindings', - packages=['babeltrace'], - package_dir={'babeltrace': 'babeltrace'}, - options={'build': - { - 'build_base': 'build', - 'build_lib': 'build/build_lib' - }, - }, - url='http://diamon.org/babeltrace', - license='MIT', - classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: The MIT License', - 'Programming Language :: Python :: 3' - 'Topic :: System :: Logging', - ]) - -# After the installation, we check that the install directory is included in -# the Python search path and we print a warning message when it's not. -# We need to do this because Python search path differs depending on the distro -# and some distros don't include any /usr/local/ in the search path. This is -# also useful for out-of-tree installs and tests. -# It's only relevant to make this check on the `install` command. - - if 'install' in dist.command_obj: - install_dir = dist.command_obj['install'].install_libbase - if install_dir not in sys.path: - # We can't consider this an error because if affects every - # distro differently. We only warn the user that some - # extra configuration is needed to use the bindings - print(PY_PATH_WARN_MSG.format(install_dir, install_dir)) - -if __name__ == "__main__": - main() diff --git a/configure.ac b/configure.ac index 723386db..eba84ee5 100644 --- a/configure.ac +++ b/configure.ac @@ -722,9 +722,6 @@ AC_SUBST(program_transform_name) AC_CONFIG_FILES([ Makefile bindings/python/Makefile - bindings/python/babeltrace/Makefile - bindings/python/babeltrace/setup.py - bindings/python/babeltrace/babeltrace/__init__.py bindings/python/bt2/Makefile bindings/python/bt2/setup.py bindings/python/bt2/bt2/__init__.py @@ -763,7 +760,6 @@ AC_CONFIG_FILES([ tests/bindings/Makefile tests/bindings/python/Makefile tests/bindings/python/bt2/Makefile - tests/bindings/python/babeltrace/Makefile tests/plugins/Makefile tests/python-plugin-provider/Makefile extras/Makefile diff --git a/tests/bindings/python/Makefile.am b/tests/bindings/python/Makefile.am index fbc28130..f3cec072 100644 --- a/tests/bindings/python/Makefile.am +++ b/tests/bindings/python/Makefile.am @@ -1 +1 @@ -SUBDIRS = bt2 babeltrace +SUBDIRS = bt2 diff --git a/tests/bindings/python/babeltrace/Makefile.am b/tests/bindings/python/babeltrace/Makefile.am deleted file mode 100644 index 7303d1ca..00000000 --- a/tests/bindings/python/babeltrace/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ -EXTRA_DIST = \ - test_reader_event.py \ - test_reader_event_declaration.py \ - test_reader_field_declaration.py \ - test_ctf_writer_empty_packet.py \ - test_ctf_writer_no_packet_context.py \ - test_reader_trace_intersection.py diff --git a/tests/bindings/python/babeltrace/test_reader_event.py b/tests/bindings/python/babeltrace/test_reader_event.py deleted file mode 100644 index 32dc3884..00000000 --- a/tests/bindings/python/babeltrace/test_reader_event.py +++ /dev/null @@ -1,195 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2017 Jérémie Galarneau -# Copyright (c) 2017 Philippe Proulx -# -# 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. - -import collections -import unittest -import bt2 -import babeltrace -import datetime - - -class EventTestCase(unittest.TestCase): - def setUp(self): - self._values = { - 'ph_field_1' : 42, - 'ph_field_2' : 'bla bla', - 'spc_field' : 'some string', - 'seh_field' : 'another string', - 'sec_field' : 68752, - 'ec_field' : 89, - 'ef_field' : 8476, - } - - self._int_ft = bt2.IntegerFieldType(32) - self._str_ft = bt2.StringFieldType() - - self._trace = bt2.Trace() - self._trace.packet_header_field_type = bt2.StructureFieldType() - self._trace.packet_header_field_type += collections.OrderedDict([ - ('ph_field_1', self._int_ft), - ('ph_field_2', self._str_ft), - ]) - - self._sc = bt2.StreamClass() - self._sc.packet_context_field_type = bt2.StructureFieldType() - self._sc.packet_context_field_type += collections.OrderedDict([ - ('spc_field', self._str_ft), - ]) - - self._sc.event_header_field_type = bt2.StructureFieldType() - self._sc.event_header_field_type += collections.OrderedDict([ - ('seh_field', self._str_ft), - ]) - - self._sc.event_context_field_type = bt2.StructureFieldType() - self._sc.event_context_field_type += collections.OrderedDict([ - ('sec_field', self._int_ft), - ]) - - self._clock_class = bt2.ClockClass('allo', 1000) - self._trace.add_clock_class(self._clock_class) - - self._ec = bt2.EventClass('event_class_name') - self._ec.context_field_type = bt2.StructureFieldType() - self._ec.context_field_type += collections.OrderedDict([ - ('ec_field', self._int_ft), - ]) - self._ec.payload_field_type = bt2.StructureFieldType() - self._ec.payload_field_type += collections.OrderedDict([ - ('ef_field', self._int_ft), - ]) - - self._sc.add_event_class(self._ec) - - 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['ph_field_1'] = self._values['ph_field_1'] - self._packet.header_field['ph_field_2'] = self._values['ph_field_2'] - self._packet.context_field['spc_field'] = self._values['spc_field'] - - self._event = self._ec() - self._event.clock_values.add(self._clock_class(1772)) - self._event.header_field['seh_field'] = self._values['seh_field'] - self._event.stream_event_context_field['sec_field'] = self._values[ - 'sec_field'] - self._event.context_field['ec_field'] = self._values['ec_field'] - self._event.payload_field['ef_field'] = self._values['ef_field'] - self._event.packet = self._packet - - def tearDown(self): - del self._trace - del self._sc - del self._ec - del self._int_ft - del self._str_ft - del self._clock_class - del self._cc_prio_map - del self._stream - del self._packet - del self._event - - def _get_event(self): - notif = bt2.EventNotification(self._event, self._cc_prio_map) - return babeltrace.reader_event._create_event(notif) - - def test_attr_name(self): - event = self._get_event() - self.assertEqual(event.name, 'event_class_name') - - def test_attr_cycles(self): - event = self._get_event() - self.assertEqual(event.cycles, 1772) - - def test_attr_timestamp(self): - event = self._get_event() - clock_class = self._cc_prio_map.highest_priority_clock_class - self.assertEqual(event.timestamp, 1772 * (1E9 / clock_class.frequency)) - - def test_attr_datetime(self): - event = self._get_event() - clock_class = self._cc_prio_map.highest_priority_clock_class - ns = self._event.clock_values[clock_class].ns_from_epoch - self.assertEqual(datetime.date.fromtimestamp(ns / 1E9), event.datetime) - - def test_getitem(self): - event = self._get_event() - for name, value in self._values.items(): - self.assertEqual(event[name], value) - - with self.assertRaises(KeyError): - field = event['non-existant-key'] - - def test_field_list_with_scope(self): - event = self._get_event() - self.assertEqual( - set(event.field_list_with_scope( - babeltrace.CTFScope.TRACE_PACKET_HEADER)), - set(['ph_field_1', 'ph_field_2'])) - - self.assertEqual( - set(event.field_list_with_scope( - babeltrace.CTFScope.STREAM_PACKET_CONTEXT)), - set(['spc_field'])) - - self.assertEqual( - set(event.field_list_with_scope( - babeltrace.CTFScope.STREAM_EVENT_HEADER)), - set(['seh_field'])) - - self.assertEqual( - set(event.field_list_with_scope( - babeltrace.CTFScope.STREAM_EVENT_CONTEXT)), - set(['sec_field'])) - - self.assertEqual( - set(event.field_list_with_scope( - babeltrace.CTFScope.EVENT_CONTEXT)), - set(['ec_field'])) - - self.assertEqual( - set(event.field_list_with_scope( - babeltrace.CTFScope.EVENT_FIELDS)), - set(['ef_field'])) - - def test_field_with_scope(self): - event = self._get_event() - self.assertEqual(event.field_with_scope( - 'seh_field', babeltrace.CTFScope.STREAM_EVENT_HEADER), - self._values['seh_field']) - - def test_get(self): - event = self._get_event() - self.assertEqual(event.get('spc_field'), self._values['spc_field']) - self.assertEqual(event.get('non-existant field', 'No field'), - 'No field') - - def test_keys(self): - event = self._get_event() - self.assertEqual(set(self._values.keys()), set(event.keys())) - - def test_len(self): - event = self._get_event() - self.assertEqual(len(self._values), len(event)) diff --git a/tests/bindings/python/babeltrace/test_reader_field_declaration.py b/tests/bindings/python/babeltrace/test_reader_field_declaration.py deleted file mode 100644 index b552cab6..00000000 --- a/tests/bindings/python/babeltrace/test_reader_field_declaration.py +++ /dev/null @@ -1,172 +0,0 @@ -# The MIT License (MIT) -# -# Copyright (c) 2017 Jérémie Galarneau -# Copyright (c) 2017 Philippe Proulx -# -# 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. - -import collections -import unittest -import copy -import bt2 -import babeltrace -import babeltrace.reader_field_declaration as field_declaration -import datetime -import random - - -class FieldDeclarationTestCase(unittest.TestCase): - def setUp(self): - pass - - def tearDown(self): - pass - - @staticmethod - def _get_declaration(field_type): - return field_declaration._create_field_declaration( - field_type, 'a_name', babeltrace.CTFScope.TRACE_PACKET_HEADER) - - def test_type(self): - int_ft = bt2.IntegerFieldType(32) - - enum_ft = bt2.EnumerationFieldType(int_ft) - enum_ft.add_mapping('corner', 23) - enum_ft.add_mapping('zoom', 17, 20) - enum_ft.add_mapping('mellotron', 1001) - enum_ft.add_mapping('giorgio', 2000, 3000) - - array_ft = bt2.ArrayFieldType(int_ft, 5) - seq_ft = bt2.SequenceFieldType(int_ft, 'the_len_field') - float_ft = bt2.FloatingPointNumberFieldType() - - struct_ft = bt2.StructureFieldType() - struct_ft.append_field('a', int_ft) - struct_ft.append_field('b', int_ft) - struct_ft.append_field('c', int_ft) - - _string_ft = bt2.StringFieldType() - - variant_ft = bt2.VariantFieldType('tag', enum_ft) - variant_ft.append_field('corner', int_ft) - variant_ft.append_field('zoom', array_ft) - variant_ft.append_field('mellotron', float_ft) - variant_ft.append_field('giorgio', struct_ft) - - expected_types = { - babeltrace.CTFTypeId.INTEGER: int_ft, - babeltrace.CTFTypeId.FLOAT: float_ft, - babeltrace.CTFTypeId.ENUM: enum_ft, - babeltrace.CTFTypeId.STRING: _string_ft, - babeltrace.CTFTypeId.STRUCT: struct_ft, - babeltrace.CTFTypeId.VARIANT: variant_ft, - babeltrace.CTFTypeId.ARRAY: array_ft, - babeltrace.CTFTypeId.SEQUENCE: seq_ft, - } - - for type_id, ft in expected_types.items(): - declaration = self._get_declaration(ft) - self.assertIsNotNone(declaration) - self.assertEqual(declaration.type, type_id) - - def test_int_signedness(self): - int_ft = bt2.IntegerFieldType(size=32, is_signed=True) - declaration = self._get_declaration(int_ft) - self.assertEqual(declaration.signedness, 1) - - uint_ft = bt2.IntegerFieldType(size=32, is_signed=False) - declaration = self._get_declaration(uint_ft) - self.assertEqual(declaration.signedness, 0) - - def test_int_base(self): - int_ft = bt2.IntegerFieldType(size=32, base=8) - declaration = self._get_declaration(int_ft) - self.assertEqual(declaration.base, 8) - - int_ft = bt2.IntegerFieldType(size=32, base=16) - declaration = self._get_declaration(int_ft) - self.assertEqual(declaration.base, 16) - - int_ft = bt2.IntegerFieldType(size=32, base=10) - declaration = self._get_declaration(int_ft) - self.assertEqual(declaration.base, 10) - - int_ft = bt2.IntegerFieldType(size=32, base=2) - declaration = self._get_declaration(int_ft) - self.assertEqual(declaration.base, 2) - - def test_int_byte_order(self): - expected_byte_orders = { - bt2.ByteOrder.NATIVE: babeltrace.ByteOrder.BYTE_ORDER_NATIVE, - bt2.ByteOrder.LITTLE_ENDIAN: babeltrace.ByteOrder.BYTE_ORDER_LITTLE_ENDIAN, - bt2.ByteOrder.BIG_ENDIAN: babeltrace.ByteOrder.BYTE_ORDER_BIG_ENDIAN, - bt2.ByteOrder.NETWORK: babeltrace.ByteOrder.BYTE_ORDER_NETWORK, - } - - for bt2_bo, bt_bo in expected_byte_orders.items(): - int_ft = bt2.IntegerFieldType(size=32, byte_order=bt2_bo) - declaration = self._get_declaration(int_ft) - self.assertEqual(declaration.byte_order, bt_bo) - - def test_int_size(self): - int_ft = bt2.IntegerFieldType(size=32, base=8) - declaration = self._get_declaration(int_ft) - self.assertEqual(declaration.size, 32) - self.assertEqual(declaration.length, 32) - - int_ft = bt2.IntegerFieldType(size=12, base=8) - declaration = self._get_declaration(int_ft) - self.assertEqual(declaration.size, 12) - self.assertEqual(declaration.length, 12) - - def test_int_encoding(self): - expected_encodings = { - bt2.Encoding.NONE: babeltrace.CTFStringEncoding.NONE, - bt2.Encoding.ASCII: babeltrace.CTFStringEncoding.ASCII, - bt2.Encoding.UTF8: babeltrace.CTFStringEncoding.UTF8, - } - - for bt2_encoding, bt_encoding in expected_encodings.items(): - int_ft = bt2.IntegerFieldType(size=32, encoding=bt2_encoding) - declaration = self._get_declaration(int_ft) - self.assertEqual(declaration.encoding, bt_encoding) - - def test_array_length(self): - int_ft = bt2.IntegerFieldType(32) - array_ft = bt2.ArrayFieldType(int_ft, 5) - declaration = self._get_declaration(array_ft) - self.assertEqual(declaration.length, 5) - - def test_array_element_declaration(self): - int_ft = bt2.IntegerFieldType(size=32, is_signed=True, base=8) - array_ft = bt2.ArrayFieldType(int_ft, 5) - declaration = self._get_declaration(array_ft) - element_declaration = declaration.element_declaration - self.assertEqual(element_declaration.type, babeltrace.CTFTypeId.INTEGER) - self.assertEqual(element_declaration.size, 32) - self.assertEqual(element_declaration.base, 8) - - def test_sequence_element_declaration(self): - int_ft = bt2.IntegerFieldType(size=32, is_signed=True, base=8) - seq_ft = bt2.SequenceFieldType(int_ft, 'len_field') - declaration = self._get_declaration(seq_ft) - element_declaration = declaration.element_declaration - self.assertEqual(element_declaration.type, babeltrace.CTFTypeId.INTEGER) - self.assertEqual(element_declaration.size, 32) - self.assertEqual(element_declaration.base, 8) diff --git a/tests/bindings/python/babeltrace/test_reader_trace_intersection.py b/tests/bindings/python/babeltrace/test_reader_trace_intersection.py deleted file mode 100644 index 250d6c23..00000000 --- a/tests/bindings/python/babeltrace/test_reader_trace_intersection.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env python3 -# -# The MIT License (MIT) -# -# Copyright (C) 2016 - Jérémie Galarneau -# -# 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. - -import tempfile -import babeltrace.writer as btw -import babeltrace.reader as btr -import uuid -import shutil -import unittest - -class Entry(object): - def __init__(self, stream_id, timestamp=None, end_of_packet=False): - self.stream_id = stream_id - self.timestamp = timestamp - self.end_of_packet = end_of_packet - - -class Packet(object): - def __init__(self, timestamps): - self.timestamps = timestamps - - -class TraceIntersectionTestCase(unittest.TestCase): - def _create_trace(self, stream_descriptions): - trace_path = tempfile.mkdtemp() - trace = btw.Writer(trace_path) - clock = btw.Clock('test_clock') - clock.uuid = self._clock_uuid - trace.add_clock(clock) - - integer_field_type = btw.IntegerFieldDeclaration(32) - - event_class = btw.EventClass('simple_event') - event_class.add_field(integer_field_type, 'int_field') - - stream_class = btw.StreamClass('test_stream') - stream_class.add_event_class(event_class) - stream_class.clock = clock - - streams = [] - stream_entries = [] - for stream_id, stream_packets in enumerate(stream_descriptions): - stream = trace.create_stream(stream_class) - streams.append(stream) - - for packet in stream_packets: - for timestamp in packet.timestamps: - stream_entries.append(Entry(stream_id, timestamp)) - # Mark the last inserted entry as the end of packet - stream_entries[len(stream_entries) - 1].end_of_packet = True - - # Sort stream entries which will provide us with a time-ordered list of - # events to insert in the streams. - for entry in sorted(stream_entries, key=lambda entry: entry.timestamp): - clock.time = entry.timestamp - event = btw.Event(event_class) - event.payload('int_field').value = entry.stream_id - streams[entry.stream_id].append_event(event) - if entry.end_of_packet is True: - streams[entry.stream_id].flush() - - return trace_path - - def setUp(self): - self._clock_uuid = uuid.uuid4() - self._trace_path_early = self._create_trace( - [ - [Packet(range(1, 7)), Packet(range(11, 18))], - [Packet(range(8, 15)), Packet(range(22, 24)), Packet(range(30, 60))], - [Packet(range(11, 14))] - ] - ) - self._trace_path_late = self._create_trace( - [ - [Packet(range(100, 105)), Packet(range(109, 120))], - [Packet(range(88, 95)), Packet(range(96, 110)), Packet(range(112, 140))], - [Packet(range(99, 105))] - ] - ) - - self._expected_timestamps_early = [] - for ts in range(11, 14): - for stream in range(3): - self._expected_timestamps_early.append(ts) - - self._expected_timestamps_late = [] - for ts in range(100, 105): - for stream in range(3): - self._expected_timestamps_late.append(ts) - - self._expected_timestamps_union = (self._expected_timestamps_early + - self._expected_timestamps_late) - - def tearDown(self): - shutil.rmtree(self._trace_path_early) - shutil.rmtree(self._trace_path_late) - pass - - @staticmethod - def _check_trace_expected_timestamps(trace_paths, expected_timestamps): - traces = btr.TraceCollection(intersect_mode=True) - for trace_path in trace_paths: - trace_handle = traces.add_trace(trace_path, 'ctf') - if trace_handle is None: - print('# Failed to open trace at {}'.format(trace_path)) - return False - for event in traces.events: - expected_timestamp = expected_timestamps.pop(0) - if event.timestamp != expected_timestamp: - print('# Unexpected timestamp ({}), expected {}'.format( - event.timestamp, expected_timestamp)) - return False - return True - - def test_trace_early(self): - self._check_trace_expected_timestamps([self._trace_path_early], - self._expected_timestamps_early) - - def test_trace_late(self): - self._check_trace_expected_timestamps([self._trace_path_late], - self._expected_timestamps_late) - - def test_trace_intersection(self): - self._check_trace_expected_timestamps([self._trace_path_early, - self._trace_path_late], - self._expected_timestamps_union) -- 2.34.1