Fix: Handle barectf 2 configurations with any configured byte order
authorErica Bugden <ebugden@efficios.com>
Fri, 5 May 2023 15:19:32 +0000 (11:19 -0400)
committerPhilippe Proulx <eeppeliteloop@gmail.com>
Tue, 16 May 2023 19:18:07 +0000 (15:18 -0400)
Context:

In barectf 2 (v2), the ‘byte-order’ property allows users to configure
the byte order with which traces are written (completely independently
of the traced architecture’s native byte order).

In barectf 3 (v3), the v2 property ‘byte-order’ was removed and the v3
property ‘native-byte-order’ is used instead. Currently, barectf 3
requires that the configured trace byte order match the byte order of
the traced architecture (i.e. the native byte order). This new
requirement promotes efficient tracing as it allows memcpy() to be used
for trace writing. Conversely, writing the trace in a different byte
order as the traced architecture requires at least one additional CPU
operation (byte swap) per written data point.

Issue:

Because of this use of memcpy() in trace writing (see implementation
section below), barectf 3 does not correctly handle barectf 2
configurations where the tracer's configured byte order does not match
the system's native byte order.

For example, consider a barectf 2 configuration file configured to
produce traces with a little-endian byte order
(byte-order: little-endian). If a barectf 3 tracer generated with this
configuration is used on a big-endian system, the traces produced will
appear corrupted.

Because the barectf 3 tracer copies data as-is with memcpy() (without
checking or swapping byte order), the byte order of the trace data
produced will not match the expected byte order (described in the
trace's metadata file) so the trace reader (e.g. babeltrace) will not be
able to read it.

Implementation:

The difference between barectf 2 (v2.3.1) and 3 byte order behavior:

 * barectf 2: Always uses the bt_bitfield_write functions when writing
    trace data.
 * barectf 3: Typically uses memcpy() when writing trace data (unless
    the data is not byte-aligned or has a length which is not a multiple
    of 8 bits)

In practice, the bt_bitfield_write functions are defined identically in
barectf 2 and barectf 3.

    Note: Although, barectf 2 does define the bt_bitfield_write
    functions with different type arguments depending on the configured
    byte order, in practice, these functions are _always_ called with
    the type unsigned char. So, there is no functional difference
    between how bt_bitfield_write_le and bt_bitfield_write_be are called
    regardless of the configured byte order. This means that we can get
    the same barectf 2 byte order behaviour in barectf 3 without
    adjusting the bt_bitfield_write functions based on the
    configuration.

Changes:

Handle barectf 2 configurations with any configured byte order by adding
an optional property ‘trace-byte-order’ (equivalent of the barectf 2
‘byte-order’ property). When this property is set, the tracer will
write the trace data in the configured byte order regardless of the
traced architecture’s native byte order (like barectf 2).

These changes are transparent for existing users of the barectf Python
library and no changes to their code are required.

The configuration property ‘trace-byte-order’ is implemented with a new
trace type class ‘TraceTypeWithUnknownNativeByteOrder’ both to avoid
breaking changes to the existing ‘TraceType’ class and to encourage use
of the ‘TraceType’ class over the new trace type.

The ‘trace-byte-order’ property is only intended to allow compatibility
with barectf 2 configurations. Because tracers configurated with
‘trace-byte-order’ will always use the bt_bitfield_write functions,
intentional use of this property in barectf 3 is unrecommended as it
could result in a less efficient tracer if the C compiler used is not
good at optimizing.

    Note: With a C compiler that optimizes well, the bt_bitfield_write
    functions will optimize down to either:
        a. 1 store instruction (equivalent to memcpy()), or
        b. 1 byte swap and 1 store (if the config byte order is
            different from the architecture’s native byte order).
    This raises the question: Why not just always use the
    bt_bitfield_write functions if they optimize so well and can be
    equivalent to a memcpy()? Because barectf is designed for use in
    embedded situations where toolchains are highly varied and it is not
    a given that the C compiler used is highly optimizing, it felt safer
    to still use memcpy() when the architecture and configured trace
    byte orders match as memcpy() is guaranteed to result in a quick
    write operation.

Testing:

Add the following test cases:

 * Configuration:
    * Fail if no byte order property is defined (byte-order-no.yaml)
    * Fail if both ‘native-byte-order’ and ‘trace-byte-order’ are
       defined (byte-order-yes-two-properties.yaml)
    * Pass if only ‘trace-byte-order’ is defined (byte-order-yes.yaml)
 * Tracing:
    * Barectf 2 configuration with ‘byte-order’ big endian (assuming a
       little endian test system) (trace-byte-order-big-endian.yaml)

The configuration test files are adapted from the effective
configuration generated from the barectf test config two-packets.yaml.

For the tracing test, the configuration was adapted from the barectf 2
wiki and the test source was adapted from the barectf test source
two-packets.c.

Philippe: Document the user-facing changes in `trace-type-obj.adoc`.

Change-Id: If0e17b537795a5093c406500706ca5d1fad051c6
Signed-off-by: Erica Bugden <ebugden@efficios.com>
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
17 files changed:
barectf/__init__.py
barectf/cgen.py
barectf/config.py
barectf/config_parse_v2.py
barectf/config_parse_v3.py
barectf/schemas/config/3/config.yaml
barectf/templates/c/bitfield.h.j2
barectf/templates/c/serialize-write-bit-array-statements.j2
barectf/templates/metadata/metadata.j2
docs/modules/yaml/pages/trace-type-obj.adoc
tests/config/yaml/3/configs/fail/type/byte-order-no.yaml [new file with mode: 0644]
tests/config/yaml/3/configs/fail/type/byte-order-yes-two-properties.yaml [new file with mode: 0644]
tests/config/yaml/3/configs/pass/type/byte-order-yes.yaml [new file with mode: 0644]
tests/tracing/configs/basic/byte-order/trace-byte-order-big-endian.yaml [new file with mode: 0644]
tests/tracing/expect/basic/byte-order/trace-byte-order-big-endian.data.expect [new file with mode: 0644]
tests/tracing/expect/basic/byte-order/trace-byte-order-big-endian.metadata.expect [new file with mode: 0644]
tests/tracing/src/basic/byte-order/trace-byte-order-big-endian.c [new file with mode: 0644]

index 533e96a184ff2352e4b10aef3b9784e6c014ea78..2939400bda06ce52cda5fb7929bb3a3a85c1670d 100644 (file)
@@ -83,6 +83,7 @@ StructureFieldTypeMembers = barectf_config.StructureFieldTypeMembers
 Trace = barectf_config.Trace
 TraceEnvironment = barectf_config.TraceEnvironment
 TraceType = barectf_config.TraceType
+TraceTypeWithUnknownNativeByteOrder = barectf_config.TraceTypeWithUnknownNativeByteOrder
 TraceTypeFeatures = barectf_config.TraceTypeFeatures
 UnsignedEnumerationFieldType = barectf_config.UnsignedEnumerationFieldType
 UnsignedIntegerFieldType = barectf_config.UnsignedIntegerFieldType
index a523f2f131ee2b7aa68849baea74847ecc453657..0e771cedc9a1e5ab8378d1ee3b853d5bd55db6e6 100644 (file)
@@ -546,7 +546,7 @@ class _CodeGen:
 
     # Trace type of this code generator's barectf configuration.
     @property
-    def _trace_type(self) -> barectf_config.TraceType:
+    def _trace_type(self) -> barectf_config._TraceType:
         return self._cfg.trace.type
 
     # Returns the name of a source variable for the operation `op`.
index 20849ad184b4ee42659600f56656422f6d940586..9189da9bd61b6a8bf2f7dcd2d1f7baf0ee4491fd 100644 (file)
@@ -703,10 +703,10 @@ class TraceTypeFeatures:
         return self._data_stream_type_id_field_type
 
 
-class TraceType:
-    def __init__(self, native_byte_order: ByteOrder, data_stream_types: Set[DataStreamType],
-                 uuid: _OptUuid = None, features: Optional[TraceTypeFeatures] = None):
-        self._native_byte_order = native_byte_order
+class _TraceType:
+    def __init__(self, trace_byte_order: ByteOrder, data_stream_types: Set[DataStreamType],
+                 uuid: _OptUuid, features: Optional[TraceTypeFeatures]):
+        self._trace_byte_order = trace_byte_order
         self._data_stream_types = frozenset(data_stream_types)
 
         # assign unique IDs
@@ -742,8 +742,8 @@ class TraceType:
         self._pkt_header_ft = StructureFieldType(8, members)
 
     @property
-    def native_byte_order(self) -> ByteOrder:
-        return self._native_byte_order
+    def trace_byte_order(self) -> ByteOrder:
+        return self._trace_byte_order
 
     @property
     def uuid(self) -> _OptUuid:
@@ -775,6 +775,35 @@ class TraceType:
         return clk_types
 
 
+# Standard trace type class for a barectf 3 configuration.
+#
+# The trace byte order property of an instance is the same as the
+# expected native byte order of the target system.
+class TraceType(_TraceType):
+    def __init__(self, trace_byte_order: ByteOrder, data_stream_types: Set[DataStreamType],
+                 uuid: _OptUuid = None, features: Optional[TraceTypeFeatures] = None):
+        super().__init__(trace_byte_order, data_stream_types, uuid, features)
+
+    @property
+    def native_byte_order(self) -> ByteOrder:
+        return self._trace_byte_order
+
+
+# This trace type class specifically exists to support barectf 2
+# configurations. Such configurations define the actual trace byte order
+# instead of the expected native byte order of the target system.
+#
+# The user provides the trace byte order property of an instance.
+#
+# IMPORTANT: When possible, prefer the `TraceType` class instead, as
+# enforcing the trace byte order could result in a less efficient
+# generated tracer.
+class TraceTypeWithUnknownNativeByteOrder(_TraceType):
+    def __init__(self, trace_byte_order: ByteOrder, data_stream_types: Set[DataStreamType],
+                 uuid: _OptUuid = None, features: Optional[TraceTypeFeatures] = None):
+        super().__init__(trace_byte_order, data_stream_types, uuid, features)
+
+
 _EnvEntry = Union[str, int]
 _EnvEntries = Mapping[str, _EnvEntry]
 
@@ -794,7 +823,7 @@ class TraceEnvironment(collections.abc.Mapping):
 
 
 class Trace:
-    def __init__(self, type: TraceType, environment: Optional[_EnvEntries] = None):
+    def __init__(self, type: _TraceType, environment: Optional[_EnvEntries] = None):
         self._type = type
         self._set_env(environment)
 
@@ -816,7 +845,7 @@ class Trace:
         self._env = TraceEnvironment(typing.cast(_EnvEntries, init_env))
 
     @property
-    def type(self) -> TraceType:
+    def type(self) -> _TraceType:
         return self._type
 
     @property
index 8055f9c76393df4ceb26dc787fc17f14078f711d..16273eed9cdd95f7fe3c78935c52cf5f8bb72bc2 100644 (file)
@@ -129,7 +129,8 @@ class _Parser(config_parse_common._Parser):
         # remove `encoding` property
         _del_prop_if_exists(v3_ft_node, 'encoding')
 
-        # remove `byte-order` property (always native BO in v3)
+        # remove `byte-order` property (the equivalent barectf 3
+        # configuration property is named `trace-byte-order`)
         _del_prop_if_exists(v3_ft_node, 'byte-order')
 
         # remove `property-mappings` property
@@ -489,8 +490,8 @@ class _Parser(config_parse_common._Parser):
         v3_trace_type_node: _MapNode = collections.OrderedDict()
         v2_trace_node = v2_meta_node['trace']
 
-        # copy `byte-order` property as `native-byte-order` property
-        _copy_prop_if_exists(v3_trace_type_node, v2_trace_node, 'byte-order', 'native-byte-order')
+        # copy `byte-order` property as `trace-byte-order` property
+        _copy_prop_if_exists(v3_trace_type_node, v2_trace_node, 'byte-order', 'trace-byte-order')
 
         # copy `uuid` property
         _copy_prop_if_exists(v3_trace_type_node, v2_trace_node, 'uuid')
index 95edb3eb1f897d5c10cdb2eb0b73228b99b39cb6..d275654656511df687d1f38ef54cd01f9761ca4f 100644 (file)
@@ -657,8 +657,12 @@ class _Parser(barectf_config_parse_common._Parser):
                 dsts.add(self._create_dst(dst_name, dst_node))
 
             # create trace type
-            return barectf_config.TraceType(self._native_byte_order, dsts, trace_type_uuid,
-                                            features)
+            if self._trace_byte_order_prop_key == 'native-byte-order':
+                trace_type_cls = barectf_config.TraceType
+            else:
+                trace_type_cls = barectf_config.TraceTypeWithUnknownNativeByteOrder
+
+            return trace_type_cls(self._trace_byte_order, dsts, trace_type_uuid, features)
         except _ConfigurationParseError as exc:
             _append_error_ctx(exc, 'Trace type')
 
@@ -1091,6 +1095,12 @@ class _Parser(barectf_config_parse_common._Parser):
     def _trace_type_props(self) -> Iterable[Tuple[Any, str]]:
         yield from _Parser._props(self.config_node['trace']['type'])
 
+    def _set_trace_byte_order_prop_key(self):
+        if 'native-byte-order' in self._trace_type_node:
+            self._trace_byte_order_prop_key = 'native-byte-order'
+        else:
+            self._trace_byte_order_prop_key = 'trace-byte-order'
+
     # Normalize the properties of the configuration node.
     #
     # This method, for each property of the trace type node:
@@ -1099,8 +1109,7 @@ class _Parser(barectf_config_parse_common._Parser):
     #
     # 2. Chooses a specific `class` property value.
     #
-    # 3. Chooses a specific `byte-order`/`native-byte-order` property
-    #    value.
+    # 3. Chooses a specific trace byte order property value.
     #
     # 4. Chooses a specific `preferred-display-base` property value.
     #
@@ -1116,7 +1125,7 @@ class _Parser(barectf_config_parse_common._Parser):
                 parent_node[key] = 'little-endian'
 
         trace_node = self.config_node['trace']
-        normalize_byte_order_prop(self._trace_type_node, 'native-byte-order')
+        normalize_byte_order_prop(self._trace_type_node, self._trace_byte_order_prop_key)
 
         for parent_node, key in self._trace_type_props():
             node = parent_node[key]
@@ -1159,10 +1168,10 @@ class _Parser(barectf_config_parse_common._Parser):
             if node is None:
                 del trace_node[prop_name]
 
-    # Sets the parser's native byte order.
-    def _set_native_byte_order(self):
-        self._native_byte_order_node = self._trace_type_node['native-byte-order']
-        self._native_byte_order = self._byte_order_from_node(self._native_byte_order_node)
+    # Sets the parser's trace byte order.
+    def _set_trace_byte_order(self):
+        self._trace_byte_order_node = self._trace_type_node[self._trace_byte_order_prop_key]
+        self._trace_byte_order = self._byte_order_from_node(self._trace_byte_order_node)
 
     # Processes the inclusions of the event record type node
     # `ert_node`, returning the effective node.
@@ -1322,6 +1331,9 @@ class _Parser(barectf_config_parse_common._Parser):
         # effective configuration node.
         self._schema_validator.validate(self.config_node, 'config/3/config')
 
+        # Set the trace byte order property key.
+        self._set_trace_byte_order_prop_key()
+
         # Normalize properties.
         #
         # This process removes `None` properties and chooses specific
@@ -1336,8 +1348,8 @@ class _Parser(barectf_config_parse_common._Parser):
         # doesn't need to check for `None` nodes or enumerator aliases.
         self._normalize_props()
 
-        # Set the native byte order.
-        self._set_native_byte_order()
+        # Set the trace byte order.
+        self._set_trace_byte_order()
 
         # Create a barectf configuration object from the configuration
         # node.
index 76027c853359691a7df368584fc904966a1bcd3a..993b4f25175b95f414b6ead2e8498435e70cb3f5 100644 (file)
@@ -93,6 +93,8 @@ definitions:
     properties:
       native-byte-order:
         $ref: https://barectf.org/schemas/config/common/common.json#/definitions/byte-order-prop
+      trace-byte-order:
+        $ref: https://barectf.org/schemas/config/common/common.json#/definitions/byte-order-prop
       uuid:
         $ref: https://barectf.org/schemas/config/common/common.json#/definitions/opt-trace-type-uuid-prop
       $features:
@@ -154,8 +156,12 @@ definitions:
         additionalProperties: false
         minProperties: 1
     required:
-      - native-byte-order
       - data-stream-types
+    oneOf:
+      - required:
+        - trace-byte-order
+      - required:
+        - native-byte-order
     additionalProperties: false
   clock-type:
     title: Clock type object
index 4c7e4b3b51e16c166b9c720dbf0c8e1d5b909821..8d4e2033cef81cd78ea52b92ff767aa4811f1674 100644 (file)
@@ -98,8 +98,8 @@ do {                                                                  \
  * Also, consecutive bitfields are placed from higher to lower bits.
  */
 
-{% if cfg.trace.type.native_byte_order == barectf_config.ByteOrder.LITTLE_ENDIAN %}
-/* Native byte order: little-endian */
+{% if cfg.trace.type.trace_byte_order == barectf_config.ByteOrder.LITTLE_ENDIAN %}
+/* Trace byte order: little-endian */
 
 #define _bt_bitfield_write_le(_ptr, type, _start, _length, _vtype, _v) \
 do {                                                                   \
@@ -163,7 +163,7 @@ do {                                                                        \
 #define bt_bitfield_write_le(ptr, _start, _length, _vtype, _v) \
        _bt_bitfield_write_le(ptr, uint8_t, _start, _length, _vtype, _v)
 {% else %}
-/* Native byte order: big-endian */
+/* Trace byte order: big-endian */
 
 #define _bt_bitfield_write_be(_ptr, type, _start, _length, _vtype, _v) \
 do {                                                                   \
index c875cb11c37d4a5f5aebe334069c401aed9a0b7c..471cda5d38dbb3504bf346c7830fc2d7e3482966 100644 (file)
@@ -24,7 +24,9 @@
  #}
 {% import 'common.j2' as common %}
 {% set incr_at %}ctx->at += {{ op.ft.size }}{% endset %}
-{% if op.ft.alignment % 8 == 0 and op.ft.size in [8, 16, 32, 64] %}
+{% if op.ft.alignment % 8 == 0 and
+       op.ft.size in [8, 16, 32, 64] and
+       cfg.trace.type.__class__ != barectf_config.TraceTypeWithUnknownNativeByteOrder %}
        {% set c_type %}uint{{ op.ft.size }}_t{% endset %}
 {
        const {{ c_type }} tmp_val = ({{ c_type }}) {{ src }};
@@ -33,7 +35,7 @@
        {{ incr_at }};
 }
 {%- else %}
-       {% set bo = 'le' if cfg.trace.type.native_byte_order == barectf_config.ByteOrder.LITTLE_ENDIAN else 'be' %}
+       {% set bo = 'le' if cfg.trace.type.trace_byte_order == barectf_config.ByteOrder.LITTLE_ENDIAN else 'be' %}
        {% set c_type_non_const = c_type | replace('const ', '') %}
        {% set offset_in_byte = 'ctx->at % 8' if op.offset_in_byte == none else op.offset_in_byte %}
 bt_bitfield_write_{{ bo }}(&ctx->buf[_BITS_TO_BYTES(ctx->at)], {{ offset_in_byte }}, {{ op.ft.size }},
index b1f2c18f1f4921ba832104e62ea86f8469495444..090a4e8fce83fb47825de0ddd5a24a394d24d72e 100644 (file)
@@ -39,7 +39,7 @@
 trace {
        major = 1;
        minor = 8;
-       byte_order = {{ 'le' if cfg.trace.type.native_byte_order == barectf_config.ByteOrder.LITTLE_ENDIAN else 'be' }};
+       byte_order = {{ 'le' if cfg.trace.type.trace_byte_order == barectf_config.ByteOrder.LITTLE_ENDIAN else 'be' }};
 {% if cfg.trace.type.uuid %}
        uuid = "{{ cfg.trace.type.uuid }}";
 {% endif %}
index b0257b1548c09cd85d5a397bf6eb1910c7fd6cc7..c964aea562fd13e13eabfafedab44d692f6f6f90 100644 (file)
@@ -21,7 +21,29 @@ xref:trace-obj.adoc#type-prop[`type` property] of a trace object.
 |xref:common-values.adoc#byte-order[Byte order]
 |Native byte order of the system which produces this trace type's
 instance's xref:how-barectf-works:ctf-primer.adoc#ds[data streams].
-|Yes
+
+You must not use this property and the
+<<trace-bo-prop,`trace-byte-order`>> property at the same time.
+|Yes, if the `trace-byte-order` property is missing
+|
+
+|[[trace-bo-prop]]`trace-byte-order`
+|xref:common-values.adoc#byte-order[Byte order]
+|Byte order of fields of this trace type's
+instance's xref:how-barectf-works:ctf-primer.adoc#ds[data streams].
+
+[IMPORTANT]
+====
+This property exists to support barectf{nbsp}2 configurations.
+
+Prefer the <<native-bo-prop,`native-byte-order`>> property instead, as
+enforcing the trace byte order could result in a less efficient
+generated tracer.
+====
+
+You must not use this property and the `native-byte-order` property at
+the same time.
+|Yes, if the `native-byte-order` property is missing
 |
 
 |[[uuid-prop]]`uuid`
diff --git a/tests/config/yaml/3/configs/fail/type/byte-order-no.yaml b/tests/config/yaml/3/configs/fail/type/byte-order-no.yaml
new file mode 100644 (file)
index 0000000..deb65d9
--- /dev/null
@@ -0,0 +1,44 @@
+# The MIT License (MIT)
+#
+# Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2023 Erica Bugden <ebugden@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.
+
+# Tests that configuration parsing fails when no trace type byte order
+# property exists (neither `native-byte-order` nor `trace-byte-order`).
+%YAML 1.2
+--- !<tag:barectf.org,2020/3/config>
+trace:
+  type:
+    data-stream-types:
+      my_stream:
+        $is-default: true
+        $features:
+          packet:
+            discarded-event-records-counter-snapshot-field-type: false
+        event-record-types:
+          my_event:
+            payload-field-type:
+              class: structure
+              members:
+              - my_field:
+                  field-type:
+                    class: string
diff --git a/tests/config/yaml/3/configs/fail/type/byte-order-yes-two-properties.yaml b/tests/config/yaml/3/configs/fail/type/byte-order-yes-two-properties.yaml
new file mode 100644 (file)
index 0000000..510e81f
--- /dev/null
@@ -0,0 +1,47 @@
+# The MIT License (MIT)
+#
+# Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2023 Erica Bugden <ebugden@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.
+
+# Tests that configuration parsing fails when both `native-byte-order`
+# and `trace-byte-order` trace type properties exist: barectf accepts
+# one or the other, but not both.
+%YAML 1.2
+--- !<tag:barectf.org,2020/3/config>
+trace:
+  type:
+    native-byte-order: little-endian
+    trace-byte-order: little-endian
+    data-stream-types:
+      my_stream:
+        $is-default: true
+        $features:
+          packet:
+            discarded-event-records-counter-snapshot-field-type: false
+        event-record-types:
+          my_event:
+            payload-field-type:
+              class: structure
+              members:
+              - my_field:
+                  field-type:
+                    class: string
diff --git a/tests/config/yaml/3/configs/pass/type/byte-order-yes.yaml b/tests/config/yaml/3/configs/pass/type/byte-order-yes.yaml
new file mode 100644 (file)
index 0000000..e327c83
--- /dev/null
@@ -0,0 +1,45 @@
+# The MIT License (MIT)
+#
+# Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2023 Erica Bugden <ebugden@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.
+
+# Tests that configuration parsing succeeds if only one trace type byte
+# order property exists (`trace-byte-order` in this case).
+%YAML 1.2
+--- !<tag:barectf.org,2020/3/config>
+trace:
+  type:
+    trace-byte-order: big-endian
+    data-stream-types:
+      my_stream:
+        $is-default: true
+        $features:
+          packet:
+            discarded-event-records-counter-snapshot-field-type: false
+        event-record-types:
+          my_event:
+            payload-field-type:
+              class: structure
+              members:
+              - my_field:
+                  field-type:
+                    class: string
diff --git a/tests/tracing/configs/basic/byte-order/trace-byte-order-big-endian.yaml b/tests/tracing/configs/basic/byte-order/trace-byte-order-big-endian.yaml
new file mode 100644 (file)
index 0000000..59930cf
--- /dev/null
@@ -0,0 +1,54 @@
+# The MIT License (MIT)
+#
+# Copyright (c) 2020 Philippe Proulx <pproulx@efficios.com>
+# Copyright (c) 2023 Erica Bugden <ebugden@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.
+
+# Tests that barectf generates a tracer which produces a valid trace on
+# a little-endian system given a barectf 2 configuration having its
+# `byte-order` trace type property set to `big-endian`.
+#
+# NOTE: This test does not validate that it runs on a little-endian
+# system, but we can assume that that is the case since it is what the
+# barectf tests currently require.
+version: '2.2'
+metadata:
+  type-aliases:
+    uint16:
+      class: int
+      size: 16
+  trace:
+    byte-order: big-endian
+  streams:
+    default:
+      $default: true
+      packet-context-type:
+        class: struct
+        fields:
+          packet_size: uint16
+          content_size: uint16
+      events:
+        my_event:
+          payload-type:
+            class: struct
+            fields:
+              my_field:
+                class: str
diff --git a/tests/tracing/expect/basic/byte-order/trace-byte-order-big-endian.data.expect b/tests/tracing/expect/basic/byte-order/trace-byte-order-big-endian.data.expect
new file mode 100644 (file)
index 0000000..6e1c447
Binary files /dev/null and b/tests/tracing/expect/basic/byte-order/trace-byte-order-big-endian.data.expect differ
diff --git a/tests/tracing/expect/basic/byte-order/trace-byte-order-big-endian.metadata.expect b/tests/tracing/expect/basic/byte-order/trace-byte-order-big-endian.metadata.expect
new file mode 100644 (file)
index 0000000..6a005e7
--- /dev/null
@@ -0,0 +1,76 @@
+/* CTF 1.8 */
+
+/*
+ * The MIT License (MIT)
+ *
+ *
+ * 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.
+ *
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ *
+ *
+ * For more details, see <https://barectf.org/>.
+ */
+
+trace {
+       major = 1;
+       minor = 8;
+       byte_order = be;
+       packet.header := struct {
+       } align(8);
+};
+
+env {
+       domain = "bare";
+       tracer_name = "barectf";
+};
+
+/* Data stream type `default` */
+stream {
+       packet.context := struct {
+               integer {
+                       signed = false;
+                       size = 16;
+                       align = 8;
+                       byte_order = native;
+                       base = 10;
+               } packet_size;
+               integer {
+                       signed = false;
+                       size = 16;
+                       align = 8;
+                       byte_order = native;
+                       base = 10;
+               } content_size;
+       } align(8);
+       event.header := struct {
+       } align(8);
+};
+
+event {
+       id = 0;
+       name = "my_event";
+       fields := struct {
+               string {
+                       encoding = UTF8;
+               } my_field;
+       } align(1);
+};
diff --git a/tests/tracing/src/basic/byte-order/trace-byte-order-big-endian.c b/tests/tracing/src/basic/byte-order/trace-byte-order-big-endian.c
new file mode 100644 (file)
index 0000000..8bb300a
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 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 <assert.h>
+
+#include "test-platform.h"
+#include "barectf.h"
+
+int main(void)
+{
+       struct test_platform_ctx * const platform_ctx = test_platform_init(128);
+
+       assert(platform_ctx);
+       barectf_default_trace_my_event(test_platform_barectf_ctx(platform_ctx),
+               "When she was younger, Akko went to a magic show hosted by a witch named Shiny Chariot.");
+       barectf_default_trace_my_event(test_platform_barectf_ctx(platform_ctx),
+               "Akko was so inspired that she dreamed to someday be a cool witch.");
+       test_platform_fini(platform_ctx);
+       return 0;
+}
This page took 0.035918 seconds and 4 git commands to generate.