-/tests/bitfield/test_bitfield
-/tests/argpar/test_argpar
-/tests/ctf-writer/ctf_writer
+/tests/bitfield/test-bitfield
+/tests/argpar/test-argpar
+/tests/ctf-writer/ctf-writer
/tests/lib/plugin
-/tests/lib/test_bt_uuid
-/tests/lib/test_bt_values
-/tests/lib/test_fields_bin
-/tests/lib/test_graph_topo
-/tests/lib/test_trace_ir_ref
-/tests/lib/test_simple_sink
-/tests/lib/test_remove_destruction_listener_in_destruction_listener
+/tests/lib/test-bt-uuid
+/tests/lib/test-bt-values
+/tests/lib/test-fields-bin
+/tests/lib/test-graph-topo
+/tests/lib/test-trace-ir-ref
+/tests/lib/test-simple-sink
+/tests/lib/test-remove-destruction-listener-in-destruction-listener
/tests/lib/conds/conds-triggers
-/tests/param-validation/test_param_validation
-/tests/plugins/flt.lttng-utils.debug-info/test_bin_info
-/tests/plugins/flt.lttng-utils.debug-info/test_dwarf
+/tests/param-validation/test-param-validation
+/tests/plugins/flt.lttng-utils.debug-info/test-bin-info
+/tests/plugins/flt.lttng-utils.debug-info/test-dwarf
/tests/plugins/src.ctf.fs/succeed/gen-trace-simple
/tests/plugins/sink.ctf.fs/succeed/gen-trace-float
/tests/plugins/sink.ctf.fs/succeed/gen-trace-double
If building in-tree, you can run single tests from the tree directly:
----
-$ ./tests/plugins/sink.text.pretty/test_enum
+$ ./tests/plugins/sink.text.pretty/test-enum.sh
----
If building out-of-tree, you can get the appropriate environment by sourcing
----
$ source /path/to/my/build/tests/utils/env.sh
-$ ./tests/plugins/sink.text.pretty/test_enum
+$ ./tests/plugins/sink.text.pretty/test-enum.sh
----
==== Python
-You can use the `tests/utils/run_python_bt2` script to run any command
-within an environment making the build's `bt2` Python package available.
+You can use the `tests/utils/run-python-bt2.sh` script to run any
+command within an environment making the build's `bt2` Python package
+available.
-`run_python_bt2` uses <<test-env,`utils.sh`>> which needs to know the
+`run-python-bt2.sh` uses <<test-env,`utils.sh`>> which needs to know the
build directory, so make sure you set the `BT_TESTS_BUILDDIR`
environment variable correctly _if you build out of tree_, for example:
----
You can run any command which needs the `bt2` Python package through
-`run_python_bt2`, for example:
+`run-python-bt2.sh`, for example:
----
-$ ./tests/utils/run_python_bt2 ipython3
+$ ./tests/utils/run-python-bt2.sh ipython3
----
=== Report format
* Run:
+
----
-$ ./tests/utils/run_python_bt2 ./tests/bindings/python/bt2/test_python_bt2
+$ ./tests/utils/run-python-bt2.sh ./tests/bindings/python/bt2/test-python-bt2.sh
----
+
or:
+
----
-$ ./tests/utils/run_python_bt2 python3 ./tests/utils/python/testrunner.py \
+$ ./tests/utils/run-python-bt2.sh python3 ./tests/utils/python/testrunner.py \
./tests/bindings/python/bt2/ -p '*.py'
----
* Run:
+
----
-$ ./tests/utils/run_python_bt2 python3 ./tests/utils/python/testrunner.py \
+$ ./tests/utils/run-python-bt2.sh python3 ./tests/utils/python/testrunner.py \
./tests/bindings/python/bt2 -t test_value
----
* Run:
+
----
-$ ./tests/utils/run_python_bt2 python3 ./tests/utils/python/testrunner.py \
+$ ./tests/utils/run-python-bt2.sh python3 ./tests/utils/python/testrunner.py \
./tests/bindings/python/bt2/ -t test_value.RealValueTestCase
----
* Run:
+
----
-$ ./tests/utils/run_python_bt2 python3 ./tests/utils/python/testrunner.py \
+$ ./tests/utils/run-python-bt2.sh python3 ./tests/utils/python/testrunner.py \
./tests/bindings/python/bt2/ -t test_value.RealValueTestCase.test_assign_pos_int
----
bindings/python/bt2/.coveragerc
dist_check_SCRIPTS = \
+ bindings/python/bt2/test-python-bt2.sh \
bindings/python/bt2/test_clock_class.py \
bindings/python/bt2/test_component_class.py \
bindings/python/bt2/test_component.py \
bindings/python/bt2/test_packet.py \
bindings/python/bt2/test_plugin.py \
bindings/python/bt2/test_port.py \
- bindings/python/bt2/test_python_bt2 \
bindings/python/bt2/test_query_executor.py \
bindings/python/bt2/test_stream_class.py \
bindings/python/bt2/test_stream.py \
bindings/python/bt2/test_trace.py \
bindings/python/bt2/test_value.py \
bindings/python/bt2/utils.py \
- cli/convert/test_auto_source_discovery_grouping \
- cli/convert/test_auto_source_discovery_params \
- cli/convert/test_auto_source_discovery_log_level \
- cli/convert/test_convert_args \
- cli/list-plugins/test_list_plugins \
- cli/params/test_params \
- cli/query/test_query \
- cli/test_exit_status \
- cli/test_help \
- cli/test_intersection \
- cli/test_output_ctf_metadata \
- cli/test_output_path_ctf_non_lttng_trace \
- cli/test_packet_seq_num \
- cli/test_trace_copy \
- cli/test_trace_read \
- cli/test_trimmer \
- plugins/sink.text.details/succeed/test_succeed \
- plugins/sink.text.pretty/test_enum \
+ cli/convert/test-auto-source-discovery-grouping.sh \
+ cli/convert/test-auto-source-discovery-params.sh \
+ cli/convert/test-auto-source-discovery-log-level.sh \
+ cli/convert/test-convert-args.sh \
+ cli/list-plugins/test-list-plugins.sh \
+ cli/params/test-params.sh \
+ cli/query/test-query.sh \
+ cli/test-exit-status.sh \
+ cli/test-help.sh \
+ cli/test-intersection.sh \
+ cli/test-output-ctf-metadata.sh \
+ cli/test-output-path-ctf-non-lttng-trace.sh \
+ cli/test-packet-seq-num.sh \
+ cli/test-trace-copy.sh \
+ cli/test-trace-read.sh \
+ cli/test-trimmer.sh \
+ plugins/sink.text.details/succeed/test-succeed.sh \
+ plugins/sink.text.pretty/test-enum.sh \
plugins/sink.text.pretty/test_pretty.py \
- plugins/sink.text.pretty/test_pretty_python \
- plugins/src.ctf.lttng-live/test_live \
+ plugins/sink.text.pretty/test-pretty-python.sh \
+ plugins/src.ctf.lttng-live/test-live.sh \
python-plugin-provider/bt_plugin_test_python_plugin_provider.py \
- python-plugin-provider/test_python_plugin_provider \
+ python-plugin-provider/test-python-plugin-provider.sh \
python-plugin-provider/test_python_plugin_provider.py
TESTS_BINDINGS =
if ENABLE_PYTHON_BINDINGS
-TESTS_BINDINGS += bindings/python/bt2/test_python_bt2
+TESTS_BINDINGS += bindings/python/bt2/test-python-bt2.sh
endif
TESTS_CLI = \
- cli/convert/test_convert_args \
- cli/test_help \
- cli/test_intersection \
- cli/test_output_ctf_metadata \
- cli/test_output_path_ctf_non_lttng_trace \
- cli/test_packet_seq_num \
- cli/test_trace_copy \
- cli/test_trace_read \
- cli/test_trimmer
+ cli/convert/test-convert-args.sh \
+ cli/test-help.sh \
+ cli/test-intersection.sh \
+ cli/test-output-ctf-metadata.sh \
+ cli/test-output-path-ctf-non-lttng-trace.sh \
+ cli/test-packet-seq-num.sh \
+ cli/test-trace-copy.sh \
+ cli/test-trace-read.sh \
+ cli/test-trimmer.sh
TESTS_LIB = \
- lib/test_bt_uuid \
- lib/test_bt_values \
- lib/test_fields \
- lib/test_graph_topo \
- lib/test_remove_destruction_listener_in_destruction_listener \
- lib/test_simple_sink \
- lib/test_trace_ir_ref
+ lib/test-bt-uuid \
+ lib/test-bt-values \
+ lib/test-fields.sh \
+ lib/test-graph-topo \
+ lib/test-remove-destruction-listener-in-destruction-listener \
+ lib/test-simple-sink \
+ lib/test-trace-ir-ref
TESTS_BITFIELD = \
- bitfield/test_bitfield
+ bitfield/test-bitfield
TESTS_CTF_WRITER = \
- ctf-writer/test_ctf_writer
+ ctf-writer/test-ctf-writer.sh
if !ENABLE_BUILT_IN_PLUGINS
-TESTS_LIB += lib/test_plugin
+TESTS_LIB += lib/test-plugin.sh
endif
TESTS_PLUGINS = \
- plugins/src.ctf.fs/fail/test_fail \
- plugins/src.ctf.fs/succeed/test_succeed \
- plugins/src.ctf.fs/test_deterministic_ordering \
- plugins/sink.ctf.fs/succeed/test_succeed \
- plugins/sink.text.details/succeed/test_succeed
+ plugins/src.ctf.fs/fail/test-fail.sh \
+ plugins/src.ctf.fs/succeed/test-succeed.sh \
+ plugins/src.ctf.fs/test-deterministic-ordering.sh \
+ plugins/sink.ctf.fs/succeed/test-succeed.sh \
+ plugins/sink.text.details/succeed/test-succeed.sh
if !ENABLE_BUILT_IN_PLUGINS
if ENABLE_PYTHON_BINDINGS
-TESTS_PLUGINS += plugins/src.ctf.fs/query/test_query_support_info
-TESTS_PLUGINS += plugins/src.ctf.fs/query/test_query_trace_info
-TESTS_PLUGINS += plugins/src.ctf.fs/query/test_query_metadata_info
-TESTS_PLUGINS += plugins/sink.ctf.fs/test_assume_single_trace
-TESTS_PLUGINS += plugins/sink.ctf.fs/test_stream_names
+TESTS_PLUGINS += plugins/src.ctf.fs/query/test-query-support-info.sh
+TESTS_PLUGINS += plugins/src.ctf.fs/query/test-query-trace-info.sh
+TESTS_PLUGINS += plugins/src.ctf.fs/query/test-query-metadata-info.sh
+TESTS_PLUGINS += plugins/sink.ctf.fs/test-assume-single-trace.sh
+TESTS_PLUGINS += plugins/sink.ctf.fs/test-stream-names.sh
endif
endif
if ENABLE_DEBUG_INFO
TESTS_PLUGINS += \
- plugins/flt.lttng-utils.debug-info/test_dwarf_i386-linux-gnu \
- plugins/flt.lttng-utils.debug-info/test_dwarf_powerpc-linux-gnu \
- plugins/flt.lttng-utils.debug-info/test_dwarf_powerpc64le-linux-gnu \
- plugins/flt.lttng-utils.debug-info/test_dwarf_x86_64-linux-gnu \
- plugins/flt.lttng-utils.debug-info/test_bin_info_i386-linux-gnu \
- plugins/flt.lttng-utils.debug-info/test_bin_info_powerpc-linux-gnu \
- plugins/flt.lttng-utils.debug-info/test_bin_info_powerpc64le-linux-gnu \
- plugins/flt.lttng-utils.debug-info/test_bin_info_x86_64-linux-gnu
+ plugins/flt.lttng-utils.debug-info/test-dwarf-i386-linux-gnu.sh \
+ plugins/flt.lttng-utils.debug-info/test-dwarf-powerpc-linux-gnu.sh \
+ plugins/flt.lttng-utils.debug-info/test-dwarf-powerpc64le-linux-gnu.sh \
+ plugins/flt.lttng-utils.debug-info/test-dwarf-x86-64-linux-gnu.sh \
+ plugins/flt.lttng-utils.debug-info/test-bin-info-i386-linux-gnu.sh \
+ plugins/flt.lttng-utils.debug-info/test-bin-info-powerpc-linux-gnu.sh \
+ plugins/flt.lttng-utils.debug-info/test-bin-info-powerpc64le-linux-gnu.sh \
+ plugins/flt.lttng-utils.debug-info/test-bin-info-x86-64-linux-gnu.sh
endif
if ENABLE_PYTHON_PLUGINS
if ENABLE_PYTHON_BINDINGS
TESTS_CLI += \
- cli/convert/test_auto_source_discovery_grouping \
- cli/convert/test_auto_source_discovery_log_level \
- cli/convert/test_auto_source_discovery_params \
- cli/list-plugins/test_list_plugins \
- cli/params/test_params \
- cli/query/test_query \
- cli/test_exit_status
-
-TESTS_PLUGINS += plugins/flt.utils.trimmer/test_trimming \
- plugins/flt.utils.muxer/succeed/test_succeed \
- plugins/sink.text.pretty/test_enum
+ cli/convert/test-auto-source-discovery-grouping.sh \
+ cli/convert/test-auto-source-discovery-log-level.sh \
+ cli/convert/test-auto-source-discovery-params.sh \
+ cli/list-plugins/test-list-plugins.sh \
+ cli/params/test-params.sh \
+ cli/query/test-query.sh \
+ cli/test-exit-status.sh
+
+TESTS_PLUGINS += plugins/flt.utils.trimmer/test-trimming.sh \
+ plugins/flt.utils.muxer/succeed/test-succeed.sh \
+ plugins/sink.text.pretty/test-enum.sh
endif
endif
if HAVE_PYTHON
-TESTS_PLUGINS += plugins/src.ctf.lttng-live/test_live
+TESTS_PLUGINS += plugins/src.ctf.lttng-live/test-live.sh
if DEV_MODE
-TESTS_LIB += lib/conds/test_conds
+TESTS_LIB += lib/conds/test-conds.sh
endif
endif
TESTS_PYTHON_PLUGIN_PROVIDER =
if ENABLE_PYTHON_PLUGINS
-TESTS_PYTHON_PLUGIN_PROVIDER += python-plugin-provider/test_python_plugin_provider
-TESTS_PLUGINS += plugins/sink.text.pretty/test_pretty_python
+TESTS_PYTHON_PLUGIN_PROVIDER += python-plugin-provider/test-python-plugin-provider.sh
+TESTS_PLUGINS += plugins/sink.text.pretty/test-pretty-python.sh
if ENABLE_DEBUG_INFO
TESTS_PLUGINS += \
- plugins/flt.lttng-utils.debug-info/test_succeed
+ plugins/flt.lttng-utils.debug-info/test-succeed.sh
endif
endif
TESTS_PARAM_VALIDATION = \
- param-validation/test_param_validation
+ param-validation/test-param-validation
LOG_DRIVER_FLAGS = --merge --comments
LOG_DRIVER = env AM_TAP_AWK='$(AWK)' \
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
+fi
+
+# shellcheck source=../../../utils/utils.sh
+source "$UTILSSH"
+
+run_python_bt2_test "${BT_TESTS_SRCDIR}/bindings/python/bt2" "test_*"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
-fi
-
-# shellcheck source=../../../utils/utils.sh
-source "$UTILSSH"
-
-run_python_bt2_test "${BT_TESTS_SRCDIR}/bindings/python/bt2" "test_*"
AM_CPPFLAGS += -I$(top_srcdir)/tests/utils
-test_bitfield_SOURCES = test_bitfield.c
+test_bitfield_SOURCES = test-bitfield.c
test_bitfield_LDADD = \
$(top_builddir)/tests/utils/tap/libtap.la \
$(top_builddir)/tests/utils/libtestcommon.la
-noinst_PROGRAMS = test_bitfield
+noinst_PROGRAMS = test-bitfield
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2010-2019 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *
+ * BabelTrace - bitfield test program
+ */
+
+#include "compat/bitfield.h"
+#include <time.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <tap/tap.h>
+
+unsigned int glob;
+
+/*
+ * This function is only declared to show the size of a bitfield write in
+ * objdump. The declaration is there to avoid a -Wmissing-prototypes warning.
+ */
+void fct(void);
+void fct(void)
+{
+ bt_bitfield_write(&glob, unsigned int, 12, 15, 0x12345678);
+}
+
+/* Test array size, in bytes */
+#define TEST_LEN 128
+#define NR_TESTS 10
+#define SIGNED_INT_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%X, signed int dest, varying read unit size"
+#define SIGNED_INT_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%X, signed int source, varying write unit size"
+#define SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, signed long long dest, varying read unit size"
+#define SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, signed long long source, varying write unit size"
+#define UNSIGNED_INT_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%X, unsigned int dest, varying read unit size"
+#define UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%X, unsigned int source, varying write unit size"
+#define UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, unsigned long long dest, varying read unit size"
+#define UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, unsigned long long source, varying write unit size"
+#define DIAG_FMT_STR(val_type_fmt) "Failed reading value written \"%s\"-wise, with start=%i" \
+ " and length=%i. Read 0x" val_type_fmt
+
+static
+unsigned int fls_u64(uint64_t x)
+{
+ unsigned int r = 64;
+
+ if (!x)
+ return 0;
+
+ if (!(x & 0xFFFFFFFF00000000ULL)) {
+ x <<= 32;
+ r -= 32;
+ }
+ if (!(x & 0xFFFF000000000000ULL)) {
+ x <<= 16;
+ r -= 16;
+ }
+ if (!(x & 0xFF00000000000000ULL)) {
+ x <<= 8;
+ r -= 8;
+ }
+ if (!(x & 0xF000000000000000ULL)) {
+ x <<= 4;
+ r -= 4;
+ }
+ if (!(x & 0xC000000000000000ULL)) {
+ x <<= 2;
+ r -= 2;
+ }
+ if (!(x & 0x8000000000000000ULL)) {
+ x <<= 1;
+ r -= 1;
+ }
+ return r;
+}
+
+static
+unsigned int fls_u32(uint32_t x)
+{
+ unsigned int r = 32;
+
+ if (!x)
+ return 0;
+ if (!(x & 0xFFFF0000U)) {
+ x <<= 16;
+ r -= 16;
+ }
+ if (!(x & 0xFF000000U)) {
+ x <<= 8;
+ r -= 8;
+ }
+ if (!(x & 0xF0000000U)) {
+ x <<= 4;
+ r -= 4;
+ }
+ if (!(x & 0xC0000000U)) {
+ x <<= 2;
+ r -= 2;
+ }
+ if (!(x & 0x80000000U)) {
+ x <<= 1;
+ r -= 1;
+ }
+ return r;
+}
+
+#define print_byte_array(c, len) \
+do { \
+ unsigned long i; \
+ \
+ for (i = 0; i < (len); i++) { \
+ printf("0x%X", (c)[i]); \
+ if (i != (len) - 1) \
+ printf(" "); \
+ } \
+ printf("\n"); \
+} while (0)
+
+#define init_byte_array(c, len, val) \
+do { \
+ unsigned long i; \
+ \
+ for (i = 0; i < (len); i++) \
+ (c)[i] = (val); \
+} while (0)
+
+#define check_result(ref, val, buffer, typename, start, len, \
+ desc_fmt_str, val_type_fmt) \
+({ \
+ if ((val) != (ref)) { \
+ fail(desc_fmt_str, ref); \
+ diag(DIAG_FMT_STR(val_type_fmt), #typename, start, len, val); \
+ printf("# "); \
+ print_byte_array(buffer, TEST_LEN); \
+ } \
+ (val) != (ref); \
+})
+
+static
+void run_test_unsigned_write(unsigned int src_ui, unsigned long long src_ull)
+{
+ unsigned int nrbits_ui, nrbits_ull;
+ union {
+ unsigned char c[TEST_LEN];
+ unsigned short s[TEST_LEN/sizeof(unsigned short)];
+ unsigned int i[TEST_LEN/sizeof(unsigned int)];
+ unsigned long l[TEST_LEN/sizeof(unsigned long)];
+ unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
+ } target;
+ unsigned long long readval;
+ unsigned int s, l;
+
+ /* The number of bits needed to represent 0 is 0. */
+ nrbits_ui = fls_u32(src_ui);
+
+ /* Write from unsigned integer src input. */
+ for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
+ for (l = nrbits_ui; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval);
+ if (check_result(src_ui, readval, target.c, unsigned char,
+ s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.s, unsigned short, s, l, src_ui);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval);
+ if (check_result(src_ui, readval, target.c, unsigned short,
+ s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.i, unsigned int, s, l, src_ui);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval);
+ if (check_result(src_ui, readval, target.c, unsigned int,
+ s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.l, unsigned long, s, l, src_ui);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval);
+ if (check_result(src_ui, readval, target.c, unsigned long,
+ s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.ll, unsigned long long, s, l, src_ui);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval);
+ if (check_result(src_ui, readval, target.c, unsigned long long,
+ s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+ }
+ }
+ pass(UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR, src_ui);
+
+ /* The number of bits needed to represent 0 is 0. */
+ nrbits_ull = fls_u64(src_ull);
+
+ /* Write from unsigned long long src input. */
+ for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
+ for (l = nrbits_ull; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval);
+ if (check_result(src_ull, readval, target.c, unsigned char,
+ s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.s, unsigned short, s, l, src_ull);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval);
+ if (check_result(src_ull, readval, target.c, unsigned short,
+ s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.i, unsigned int, s, l, src_ull);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval);
+ if (check_result(src_ull, readval, target.c, unsigned int,
+ s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.l, unsigned long, s, l, src_ull);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval);
+ if (check_result(src_ull, readval, target.c, unsigned long,
+ s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.ll, unsigned long long, s, l, src_ull);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval);
+ if (check_result(src_ull, readval, target.c, unsigned long long,
+ s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+ }
+ }
+ pass(UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR, src_ull);
+}
+
+static
+void run_test_unsigned_read(unsigned int src_ui, unsigned long long src_ull)
+{
+ unsigned int nrbits_ui, nrbits_ull, readval_ui;
+ union {
+ unsigned char c[TEST_LEN];
+ unsigned short s[TEST_LEN/sizeof(unsigned short)];
+ unsigned int i[TEST_LEN/sizeof(unsigned int)];
+ unsigned long l[TEST_LEN/sizeof(unsigned long)];
+ unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
+ } target;
+ unsigned long long readval_ull;
+ unsigned int s, l;
+
+ /* The number of bits needed to represent 0 is 0. */
+ nrbits_ui = fls_u32(src_ui);
+
+ /* Read to unsigned integer readval output. */
+ for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
+ for (l = nrbits_ui; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval_ui);
+ if (check_result(src_ui, readval_ui, target.c, unsigned char,
+ s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
+ "%X")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
+ bt_bitfield_read(target.s, unsigned short, s, l, &readval_ui);
+ if (check_result(src_ui, readval_ui, target.c, unsigned short,
+ s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
+ "%X")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
+ bt_bitfield_read(target.i, unsigned int, s, l, &readval_ui);
+ if (check_result(src_ui, readval_ui, target.c, unsigned int,
+ s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
+ "%X")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
+ bt_bitfield_read(target.l, unsigned long, s, l, &readval_ui);
+ if (check_result(src_ui, readval_ui, target.c, unsigned long,
+ s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
+ "%X")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
+ bt_bitfield_read(target.ll, unsigned long long, s, l, &readval_ui);
+ if (check_result(src_ui, readval_ui, target.c, unsigned long long,
+ s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
+ "%X")) {
+ return;
+ }
+ }
+ }
+ pass(UNSIGNED_INT_READ_TEST_DESC_FMT_STR, src_ui);
+
+ /* The number of bits needed to represent 0 is 0. */
+ nrbits_ull = fls_u64(src_ull);
+
+ /* Read to unsigned long long readval output. */
+ for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
+ for (l = nrbits_ull; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
+ bt_bitfield_read(target.c, unsigned char, s, l, &readval_ull);
+ if (check_result(src_ull, readval_ull, target.c, unsigned char,
+ s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
+ bt_bitfield_read(target.s, unsigned short, s, l, &readval_ull);
+ if (check_result(src_ull, readval_ull, target.c, unsigned short,
+ s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
+ bt_bitfield_read(target.i, unsigned int, s, l, &readval_ull);
+ if (check_result(src_ull, readval_ull, target.c, unsigned int,
+ s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
+ bt_bitfield_read(target.l, unsigned long, s, l, &readval_ull);
+ if (check_result(src_ull, readval_ull, target.c, unsigned long,
+ s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
+ bt_bitfield_read(target.ll, unsigned long long, s, l, &readval_ull);
+ if (check_result(src_ull, readval_ull, target.c, unsigned long long,
+ s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+ }
+ }
+ pass(UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR, src_ull);
+}
+
+static
+void run_test_unsigned(unsigned int src_ui, unsigned long long src_ull)
+{
+ run_test_unsigned_write(src_ui, src_ull);
+ run_test_unsigned_read(src_ui, src_ull);
+}
+
+static
+void run_test_signed_write(int src_i, long long src_ll)
+{
+ unsigned int nrbits_i, nrbits_ll;
+ union {
+ signed char c[TEST_LEN];
+ short s[TEST_LEN/sizeof(short)];
+ int i[TEST_LEN/sizeof(int)];
+ long l[TEST_LEN/sizeof(long)];
+ long long ll[TEST_LEN/sizeof(long long)];
+ } target;
+ long long readval;
+ unsigned int s, l;
+
+ if (!src_i)
+ nrbits_i = 0; /* The number of bits needed to represent 0 is 0. */
+ else if (src_i & 0x80000000U)
+ nrbits_i = fls_u32(~src_i) + 1; /* Find least significant bit conveying sign */
+ else
+ nrbits_i = fls_u32(src_i) + 1; /* Keep sign at 0 */
+
+ /* Write from signed integer src input. */
+ for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
+ for (l = nrbits_i; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
+ init_byte_array(target.c, TEST_LEN, 0x0);
+ bt_bitfield_write(target.c, signed char, s, l, src_i);
+ bt_bitfield_read(target.c, signed char, s, l, &readval);
+ if (check_result(src_i, readval, target.c, signed char,
+ s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0x0);
+ bt_bitfield_write(target.s, short, s, l, src_i);
+ bt_bitfield_read(target.c, signed char, s, l, &readval);
+ if (check_result(src_i, readval, target.c, short,
+ s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0x0);
+ bt_bitfield_write(target.i, int, s, l, src_i);
+ bt_bitfield_read(target.c, signed char, s, l, &readval);
+ if (check_result(src_i, readval, target.c, int,
+ s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0x0);
+ bt_bitfield_write(target.l, long, s, l, src_i);
+ bt_bitfield_read(target.c, signed char, s, l, &readval);
+ if (check_result(src_i, readval, target.c, long,
+ s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0x0);
+ bt_bitfield_write(target.ll, long long, s, l, src_i);
+ bt_bitfield_read(target.c, signed char, s, l, &readval);
+ if (check_result(src_i, readval, target.c, long long,
+ s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+ }
+ }
+ pass(SIGNED_INT_WRITE_TEST_DESC_FMT_STR, src_i);
+
+ if (!src_ll)
+ nrbits_ll = 0; /* The number of bits needed to represent 0 is 0. */
+ else if (src_ll & 0x8000000000000000ULL)
+ nrbits_ll = fls_u64(~src_ll) + 1; /* Find least significant bit conveying sign */
+ else
+ nrbits_ll = fls_u64(src_ll) + 1; /* Keep sign at 0 */
+
+ /* Write from signed long long src input. */
+ for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
+ for (l = nrbits_ll; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
+ init_byte_array(target.c, TEST_LEN, 0x0);
+ bt_bitfield_write(target.c, signed char, s, l, src_ll);
+ bt_bitfield_read(target.c, signed char, s, l, &readval);
+ if (check_result(src_ll, readval, target.c, signed char,
+ s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0x0);
+ bt_bitfield_write(target.s, short, s, l, src_ll);
+ bt_bitfield_read(target.c, signed char, s, l, &readval);
+ if (check_result(src_ll, readval, target.c, short,
+ s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0x0);
+ bt_bitfield_write(target.i, int, s, l, src_ll);
+ bt_bitfield_read(target.c, signed char, s, l, &readval);
+ if (check_result(src_ll, readval, target.c, int,
+ s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0x0);
+ bt_bitfield_write(target.l, long, s, l, src_ll);
+ bt_bitfield_read(target.c, signed char, s, l, &readval);
+ if (check_result(src_ll, readval, target.c, long,
+ s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0x0);
+ bt_bitfield_write(target.ll, long long, s, l, src_ll);
+ bt_bitfield_read(target.c, signed char, s, l, &readval);
+ if (check_result(src_ll, readval, target.c, long long,
+ s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+ }
+ }
+ pass(SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR, src_ll);
+}
+
+static
+void run_test_signed_read(int src_i, long long src_ll)
+{
+ unsigned int nrbits_i, nrbits_ll;
+ int readval_i;
+ union {
+ unsigned char c[TEST_LEN];
+ unsigned short s[TEST_LEN/sizeof(unsigned short)];
+ unsigned int i[TEST_LEN/sizeof(unsigned int)];
+ unsigned long l[TEST_LEN/sizeof(unsigned long)];
+ unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
+ } target;
+ long long readval_ll;
+ unsigned int s, l;
+
+ if (!src_i)
+ nrbits_i = 0; /* The number of bits needed to represent 0 is 0. */
+ else if (src_i & 0x80000000U)
+ nrbits_i = fls_u32(~src_i) + 1; /* Find least significant bit conveying sign */
+ else
+ nrbits_i = fls_u32(src_i) + 1; /* Keep sign at 0 */
+
+ /* Read to signed integer readval output. */
+ for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
+ for (l = nrbits_i; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, signed char, s, l, src_i);
+ bt_bitfield_read(target.c, signed char, s, l, &readval_i);
+ if (check_result(src_i, readval_i, target.c, signed char,
+ s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
+ "%X")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, signed char, s, l, src_i);
+ bt_bitfield_read(target.s, short, s, l, &readval_i);
+ if (check_result(src_i, readval_i, target.c, short,
+ s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
+ "%X")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, signed char, s, l, src_i);
+ bt_bitfield_read(target.i, int, s, l, &readval_i);
+ if (check_result(src_i, readval_i, target.c, int,
+ s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
+ "%X")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, signed char, s, l, src_i);
+ bt_bitfield_read(target.l, long, s, l, &readval_i);
+ if (check_result(src_i, readval_i, target.c, long,
+ s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
+ "%X")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, signed char, s, l, src_i);
+ bt_bitfield_read(target.ll, long long, s, l, &readval_i);
+ if (check_result(src_i, readval_i, target.c, long long,
+ s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
+ "%X")) {
+ return;
+ }
+ }
+ }
+ pass(SIGNED_INT_READ_TEST_DESC_FMT_STR, src_i);
+
+ if (!src_ll)
+ nrbits_ll = 0; /* The number of bits needed to represent 0 is 0. */
+ if (src_ll & 0x8000000000000000ULL)
+ nrbits_ll = fls_u64(~src_ll) + 1; /* Find least significant bit conveying sign */
+ else
+ nrbits_ll = fls_u64(src_ll) + 1; /* Keep sign at 0 */
+
+ /* Read to signed long long readval output. */
+ for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
+ for (l = nrbits_ll; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, signed char, s, l, src_ll);
+ bt_bitfield_read(target.c, signed char, s, l, &readval_ll);
+ if (check_result(src_ll, readval_ll, target.c, signed char,
+ s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, signed char, s, l, src_ll);
+ bt_bitfield_read(target.s, short, s, l, &readval_ll);
+ if (check_result(src_ll, readval_ll, target.c, short,
+ s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, signed char, s, l, src_ll);
+ bt_bitfield_read(target.i, int, s, l, &readval_ll);
+ if (check_result(src_ll, readval_ll, target.c, int,
+ s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, signed char, s, l, src_ll);
+ bt_bitfield_read(target.l, long, s, l, &readval_ll);
+ if (check_result(src_ll, readval_ll, target.c, long,
+ s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+
+ init_byte_array(target.c, TEST_LEN, 0xFF);
+ bt_bitfield_write(target.c, signed char, s, l, src_ll);
+ bt_bitfield_read(target.ll, long long, s, l, &readval_ll);
+ if (check_result(src_ll, readval_ll, target.c, long long,
+ s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
+ "%llX")) {
+ return;
+ }
+ }
+ }
+ pass(SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR, src_ll);
+}
+
+static
+void run_test_signed(int src_i, long long src_ll)
+{
+ run_test_signed_write(src_i, src_ll);
+ run_test_signed_read(src_i, src_ll);
+}
+
+static
+void run_test(void)
+{
+ int i;
+
+ plan_tests(NR_TESTS * 8 + 24);
+
+ srand(time(NULL));
+
+ run_test_unsigned(0, 0);
+ run_test_signed(0, 0);
+ run_test_unsigned(1, 1);
+ run_test_unsigned(~0U, ~0ULL);
+ run_test_signed(-1U, -1ULL);
+ run_test_signed(0x80000000U, 0x8000000000000000ULL);
+
+ for (i = 0; i < NR_TESTS; i++) {
+ unsigned int src_ui = rand();
+ unsigned long long src_ull = ((unsigned long long) (unsigned int) rand() << 32) |
+ (unsigned long long) (unsigned int) rand();
+
+ run_test_unsigned(src_ui, src_ull);
+ run_test_signed((int) src_ui, (long long) src_ull);
+ }
+}
+
+static
+int print_encodings(unsigned long src, unsigned int shift, unsigned int len)
+{
+ union {
+ unsigned char c[8];
+ unsigned short s[4];
+ unsigned int i[2];
+ unsigned long l[2];
+ unsigned long long ll[1];
+ } target;
+ unsigned long long readval;
+
+ init_byte_array(target.c, 8, 0xFF);
+ bt_bitfield_write(target.c, unsigned char, shift, len, src);
+ printf("bytewise\n");
+ print_byte_array(target.c, 8);
+
+ init_byte_array(target.c, 8, 0xFF);
+ bt_bitfield_write(target.s, unsigned short, shift, len, src);
+ printf("shortwise\n");
+ print_byte_array(target.c, 8);
+
+ init_byte_array(target.c, 8, 0xFF);
+ bt_bitfield_write(target.i, unsigned int, shift, len, src);
+ printf("intwise\n");
+ print_byte_array(target.c, 8);
+
+ init_byte_array(target.c, 8, 0xFF);
+ bt_bitfield_write(target.l, unsigned long, shift, len, src);
+ printf("longwise\n");
+ print_byte_array(target.c, 8);
+
+ init_byte_array(target.c, 8, 0xFF);
+ bt_bitfield_write(target.ll, unsigned long long, shift, len, src);
+ printf("lluwise\n");
+ print_byte_array(target.c, 8);
+
+ bt_bitfield_read(target.c, unsigned char, shift, len, &readval);
+ printf("read: %llX\n", readval);
+ print_byte_array(target.c, 8);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ if (argc > 1) {
+ /* Print encodings */
+ unsigned long src;
+ unsigned int shift, len;
+
+ src = atoi(argv[1]);
+ if (argc > 2)
+ shift = atoi(argv[2]);
+ else
+ shift = 12;
+ if (argc > 3)
+ len = atoi(argv[3]);
+ else
+ len = 40;
+ return print_encodings(src, shift, len);
+ }
+
+ /* Run tap-formated tests */
+ run_test();
+ return exit_status();
+}
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2010-2019 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
- *
- * BabelTrace - bitfield test program
- */
-
-#include "compat/bitfield.h"
-#include <time.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <tap/tap.h>
-
-unsigned int glob;
-
-/*
- * This function is only declared to show the size of a bitfield write in
- * objdump. The declaration is there to avoid a -Wmissing-prototypes warning.
- */
-void fct(void);
-void fct(void)
-{
- bt_bitfield_write(&glob, unsigned int, 12, 15, 0x12345678);
-}
-
-/* Test array size, in bytes */
-#define TEST_LEN 128
-#define NR_TESTS 10
-#define SIGNED_INT_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%X, signed int dest, varying read unit size"
-#define SIGNED_INT_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%X, signed int source, varying write unit size"
-#define SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, signed long long dest, varying read unit size"
-#define SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, signed long long source, varying write unit size"
-#define UNSIGNED_INT_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%X, unsigned int dest, varying read unit size"
-#define UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%X, unsigned int source, varying write unit size"
-#define UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, unsigned long long dest, varying read unit size"
-#define UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR "Writing and reading back 0x%llX, unsigned long long source, varying write unit size"
-#define DIAG_FMT_STR(val_type_fmt) "Failed reading value written \"%s\"-wise, with start=%i" \
- " and length=%i. Read 0x" val_type_fmt
-
-static
-unsigned int fls_u64(uint64_t x)
-{
- unsigned int r = 64;
-
- if (!x)
- return 0;
-
- if (!(x & 0xFFFFFFFF00000000ULL)) {
- x <<= 32;
- r -= 32;
- }
- if (!(x & 0xFFFF000000000000ULL)) {
- x <<= 16;
- r -= 16;
- }
- if (!(x & 0xFF00000000000000ULL)) {
- x <<= 8;
- r -= 8;
- }
- if (!(x & 0xF000000000000000ULL)) {
- x <<= 4;
- r -= 4;
- }
- if (!(x & 0xC000000000000000ULL)) {
- x <<= 2;
- r -= 2;
- }
- if (!(x & 0x8000000000000000ULL)) {
- x <<= 1;
- r -= 1;
- }
- return r;
-}
-
-static
-unsigned int fls_u32(uint32_t x)
-{
- unsigned int r = 32;
-
- if (!x)
- return 0;
- if (!(x & 0xFFFF0000U)) {
- x <<= 16;
- r -= 16;
- }
- if (!(x & 0xFF000000U)) {
- x <<= 8;
- r -= 8;
- }
- if (!(x & 0xF0000000U)) {
- x <<= 4;
- r -= 4;
- }
- if (!(x & 0xC0000000U)) {
- x <<= 2;
- r -= 2;
- }
- if (!(x & 0x80000000U)) {
- x <<= 1;
- r -= 1;
- }
- return r;
-}
-
-#define print_byte_array(c, len) \
-do { \
- unsigned long i; \
- \
- for (i = 0; i < (len); i++) { \
- printf("0x%X", (c)[i]); \
- if (i != (len) - 1) \
- printf(" "); \
- } \
- printf("\n"); \
-} while (0)
-
-#define init_byte_array(c, len, val) \
-do { \
- unsigned long i; \
- \
- for (i = 0; i < (len); i++) \
- (c)[i] = (val); \
-} while (0)
-
-#define check_result(ref, val, buffer, typename, start, len, \
- desc_fmt_str, val_type_fmt) \
-({ \
- if ((val) != (ref)) { \
- fail(desc_fmt_str, ref); \
- diag(DIAG_FMT_STR(val_type_fmt), #typename, start, len, val); \
- printf("# "); \
- print_byte_array(buffer, TEST_LEN); \
- } \
- (val) != (ref); \
-})
-
-static
-void run_test_unsigned_write(unsigned int src_ui, unsigned long long src_ull)
-{
- unsigned int nrbits_ui, nrbits_ull;
- union {
- unsigned char c[TEST_LEN];
- unsigned short s[TEST_LEN/sizeof(unsigned short)];
- unsigned int i[TEST_LEN/sizeof(unsigned int)];
- unsigned long l[TEST_LEN/sizeof(unsigned long)];
- unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
- } target;
- unsigned long long readval;
- unsigned int s, l;
-
- /* The number of bits needed to represent 0 is 0. */
- nrbits_ui = fls_u32(src_ui);
-
- /* Write from unsigned integer src input. */
- for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
- for (l = nrbits_ui; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval);
- if (check_result(src_ui, readval, target.c, unsigned char,
- s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.s, unsigned short, s, l, src_ui);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval);
- if (check_result(src_ui, readval, target.c, unsigned short,
- s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.i, unsigned int, s, l, src_ui);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval);
- if (check_result(src_ui, readval, target.c, unsigned int,
- s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.l, unsigned long, s, l, src_ui);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval);
- if (check_result(src_ui, readval, target.c, unsigned long,
- s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.ll, unsigned long long, s, l, src_ui);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval);
- if (check_result(src_ui, readval, target.c, unsigned long long,
- s, l, UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
- }
- }
- pass(UNSIGNED_INT_WRITE_TEST_DESC_FMT_STR, src_ui);
-
- /* The number of bits needed to represent 0 is 0. */
- nrbits_ull = fls_u64(src_ull);
-
- /* Write from unsigned long long src input. */
- for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
- for (l = nrbits_ull; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval);
- if (check_result(src_ull, readval, target.c, unsigned char,
- s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.s, unsigned short, s, l, src_ull);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval);
- if (check_result(src_ull, readval, target.c, unsigned short,
- s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.i, unsigned int, s, l, src_ull);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval);
- if (check_result(src_ull, readval, target.c, unsigned int,
- s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.l, unsigned long, s, l, src_ull);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval);
- if (check_result(src_ull, readval, target.c, unsigned long,
- s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.ll, unsigned long long, s, l, src_ull);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval);
- if (check_result(src_ull, readval, target.c, unsigned long long,
- s, l, UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
- }
- }
- pass(UNSIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR, src_ull);
-}
-
-static
-void run_test_unsigned_read(unsigned int src_ui, unsigned long long src_ull)
-{
- unsigned int nrbits_ui, nrbits_ull, readval_ui;
- union {
- unsigned char c[TEST_LEN];
- unsigned short s[TEST_LEN/sizeof(unsigned short)];
- unsigned int i[TEST_LEN/sizeof(unsigned int)];
- unsigned long l[TEST_LEN/sizeof(unsigned long)];
- unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
- } target;
- unsigned long long readval_ull;
- unsigned int s, l;
-
- /* The number of bits needed to represent 0 is 0. */
- nrbits_ui = fls_u32(src_ui);
-
- /* Read to unsigned integer readval output. */
- for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
- for (l = nrbits_ui; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval_ui);
- if (check_result(src_ui, readval_ui, target.c, unsigned char,
- s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
- "%X")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
- bt_bitfield_read(target.s, unsigned short, s, l, &readval_ui);
- if (check_result(src_ui, readval_ui, target.c, unsigned short,
- s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
- "%X")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
- bt_bitfield_read(target.i, unsigned int, s, l, &readval_ui);
- if (check_result(src_ui, readval_ui, target.c, unsigned int,
- s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
- "%X")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
- bt_bitfield_read(target.l, unsigned long, s, l, &readval_ui);
- if (check_result(src_ui, readval_ui, target.c, unsigned long,
- s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
- "%X")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ui);
- bt_bitfield_read(target.ll, unsigned long long, s, l, &readval_ui);
- if (check_result(src_ui, readval_ui, target.c, unsigned long long,
- s, l, UNSIGNED_INT_READ_TEST_DESC_FMT_STR,
- "%X")) {
- return;
- }
- }
- }
- pass(UNSIGNED_INT_READ_TEST_DESC_FMT_STR, src_ui);
-
- /* The number of bits needed to represent 0 is 0. */
- nrbits_ull = fls_u64(src_ull);
-
- /* Read to unsigned long long readval output. */
- for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
- for (l = nrbits_ull; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
- bt_bitfield_read(target.c, unsigned char, s, l, &readval_ull);
- if (check_result(src_ull, readval_ull, target.c, unsigned char,
- s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
- bt_bitfield_read(target.s, unsigned short, s, l, &readval_ull);
- if (check_result(src_ull, readval_ull, target.c, unsigned short,
- s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
- bt_bitfield_read(target.i, unsigned int, s, l, &readval_ull);
- if (check_result(src_ull, readval_ull, target.c, unsigned int,
- s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
- bt_bitfield_read(target.l, unsigned long, s, l, &readval_ull);
- if (check_result(src_ull, readval_ull, target.c, unsigned long,
- s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, unsigned char, s, l, src_ull);
- bt_bitfield_read(target.ll, unsigned long long, s, l, &readval_ull);
- if (check_result(src_ull, readval_ull, target.c, unsigned long long,
- s, l, UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
- }
- }
- pass(UNSIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR, src_ull);
-}
-
-static
-void run_test_unsigned(unsigned int src_ui, unsigned long long src_ull)
-{
- run_test_unsigned_write(src_ui, src_ull);
- run_test_unsigned_read(src_ui, src_ull);
-}
-
-static
-void run_test_signed_write(int src_i, long long src_ll)
-{
- unsigned int nrbits_i, nrbits_ll;
- union {
- signed char c[TEST_LEN];
- short s[TEST_LEN/sizeof(short)];
- int i[TEST_LEN/sizeof(int)];
- long l[TEST_LEN/sizeof(long)];
- long long ll[TEST_LEN/sizeof(long long)];
- } target;
- long long readval;
- unsigned int s, l;
-
- if (!src_i)
- nrbits_i = 0; /* The number of bits needed to represent 0 is 0. */
- else if (src_i & 0x80000000U)
- nrbits_i = fls_u32(~src_i) + 1; /* Find least significant bit conveying sign */
- else
- nrbits_i = fls_u32(src_i) + 1; /* Keep sign at 0 */
-
- /* Write from signed integer src input. */
- for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
- for (l = nrbits_i; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
- init_byte_array(target.c, TEST_LEN, 0x0);
- bt_bitfield_write(target.c, signed char, s, l, src_i);
- bt_bitfield_read(target.c, signed char, s, l, &readval);
- if (check_result(src_i, readval, target.c, signed char,
- s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0x0);
- bt_bitfield_write(target.s, short, s, l, src_i);
- bt_bitfield_read(target.c, signed char, s, l, &readval);
- if (check_result(src_i, readval, target.c, short,
- s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0x0);
- bt_bitfield_write(target.i, int, s, l, src_i);
- bt_bitfield_read(target.c, signed char, s, l, &readval);
- if (check_result(src_i, readval, target.c, int,
- s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0x0);
- bt_bitfield_write(target.l, long, s, l, src_i);
- bt_bitfield_read(target.c, signed char, s, l, &readval);
- if (check_result(src_i, readval, target.c, long,
- s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0x0);
- bt_bitfield_write(target.ll, long long, s, l, src_i);
- bt_bitfield_read(target.c, signed char, s, l, &readval);
- if (check_result(src_i, readval, target.c, long long,
- s, l, SIGNED_INT_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
- }
- }
- pass(SIGNED_INT_WRITE_TEST_DESC_FMT_STR, src_i);
-
- if (!src_ll)
- nrbits_ll = 0; /* The number of bits needed to represent 0 is 0. */
- else if (src_ll & 0x8000000000000000ULL)
- nrbits_ll = fls_u64(~src_ll) + 1; /* Find least significant bit conveying sign */
- else
- nrbits_ll = fls_u64(src_ll) + 1; /* Keep sign at 0 */
-
- /* Write from signed long long src input. */
- for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
- for (l = nrbits_ll; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
- init_byte_array(target.c, TEST_LEN, 0x0);
- bt_bitfield_write(target.c, signed char, s, l, src_ll);
- bt_bitfield_read(target.c, signed char, s, l, &readval);
- if (check_result(src_ll, readval, target.c, signed char,
- s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0x0);
- bt_bitfield_write(target.s, short, s, l, src_ll);
- bt_bitfield_read(target.c, signed char, s, l, &readval);
- if (check_result(src_ll, readval, target.c, short,
- s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0x0);
- bt_bitfield_write(target.i, int, s, l, src_ll);
- bt_bitfield_read(target.c, signed char, s, l, &readval);
- if (check_result(src_ll, readval, target.c, int,
- s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0x0);
- bt_bitfield_write(target.l, long, s, l, src_ll);
- bt_bitfield_read(target.c, signed char, s, l, &readval);
- if (check_result(src_ll, readval, target.c, long,
- s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0x0);
- bt_bitfield_write(target.ll, long long, s, l, src_ll);
- bt_bitfield_read(target.c, signed char, s, l, &readval);
- if (check_result(src_ll, readval, target.c, long long,
- s, l, SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
- }
- }
- pass(SIGNED_LONG_LONG_WRITE_TEST_DESC_FMT_STR, src_ll);
-}
-
-static
-void run_test_signed_read(int src_i, long long src_ll)
-{
- unsigned int nrbits_i, nrbits_ll;
- int readval_i;
- union {
- unsigned char c[TEST_LEN];
- unsigned short s[TEST_LEN/sizeof(unsigned short)];
- unsigned int i[TEST_LEN/sizeof(unsigned int)];
- unsigned long l[TEST_LEN/sizeof(unsigned long)];
- unsigned long long ll[TEST_LEN/sizeof(unsigned long long)];
- } target;
- long long readval_ll;
- unsigned int s, l;
-
- if (!src_i)
- nrbits_i = 0; /* The number of bits needed to represent 0 is 0. */
- else if (src_i & 0x80000000U)
- nrbits_i = fls_u32(~src_i) + 1; /* Find least significant bit conveying sign */
- else
- nrbits_i = fls_u32(src_i) + 1; /* Keep sign at 0 */
-
- /* Read to signed integer readval output. */
- for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
- for (l = nrbits_i; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, signed char, s, l, src_i);
- bt_bitfield_read(target.c, signed char, s, l, &readval_i);
- if (check_result(src_i, readval_i, target.c, signed char,
- s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
- "%X")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, signed char, s, l, src_i);
- bt_bitfield_read(target.s, short, s, l, &readval_i);
- if (check_result(src_i, readval_i, target.c, short,
- s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
- "%X")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, signed char, s, l, src_i);
- bt_bitfield_read(target.i, int, s, l, &readval_i);
- if (check_result(src_i, readval_i, target.c, int,
- s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
- "%X")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, signed char, s, l, src_i);
- bt_bitfield_read(target.l, long, s, l, &readval_i);
- if (check_result(src_i, readval_i, target.c, long,
- s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
- "%X")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, signed char, s, l, src_i);
- bt_bitfield_read(target.ll, long long, s, l, &readval_i);
- if (check_result(src_i, readval_i, target.c, long long,
- s, l, SIGNED_INT_READ_TEST_DESC_FMT_STR,
- "%X")) {
- return;
- }
- }
- }
- pass(SIGNED_INT_READ_TEST_DESC_FMT_STR, src_i);
-
- if (!src_ll)
- nrbits_ll = 0; /* The number of bits needed to represent 0 is 0. */
- if (src_ll & 0x8000000000000000ULL)
- nrbits_ll = fls_u64(~src_ll) + 1; /* Find least significant bit conveying sign */
- else
- nrbits_ll = fls_u64(src_ll) + 1; /* Keep sign at 0 */
-
- /* Read to signed long long readval output. */
- for (s = 0; s < CHAR_BIT * TEST_LEN; s++) {
- for (l = nrbits_ll; l <= (CHAR_BIT * TEST_LEN) - s; l++) {
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, signed char, s, l, src_ll);
- bt_bitfield_read(target.c, signed char, s, l, &readval_ll);
- if (check_result(src_ll, readval_ll, target.c, signed char,
- s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, signed char, s, l, src_ll);
- bt_bitfield_read(target.s, short, s, l, &readval_ll);
- if (check_result(src_ll, readval_ll, target.c, short,
- s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, signed char, s, l, src_ll);
- bt_bitfield_read(target.i, int, s, l, &readval_ll);
- if (check_result(src_ll, readval_ll, target.c, int,
- s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, signed char, s, l, src_ll);
- bt_bitfield_read(target.l, long, s, l, &readval_ll);
- if (check_result(src_ll, readval_ll, target.c, long,
- s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
-
- init_byte_array(target.c, TEST_LEN, 0xFF);
- bt_bitfield_write(target.c, signed char, s, l, src_ll);
- bt_bitfield_read(target.ll, long long, s, l, &readval_ll);
- if (check_result(src_ll, readval_ll, target.c, long long,
- s, l, SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR,
- "%llX")) {
- return;
- }
- }
- }
- pass(SIGNED_LONG_LONG_READ_TEST_DESC_FMT_STR, src_ll);
-}
-
-static
-void run_test_signed(int src_i, long long src_ll)
-{
- run_test_signed_write(src_i, src_ll);
- run_test_signed_read(src_i, src_ll);
-}
-
-static
-void run_test(void)
-{
- int i;
-
- plan_tests(NR_TESTS * 8 + 24);
-
- srand(time(NULL));
-
- run_test_unsigned(0, 0);
- run_test_signed(0, 0);
- run_test_unsigned(1, 1);
- run_test_unsigned(~0U, ~0ULL);
- run_test_signed(-1U, -1ULL);
- run_test_signed(0x80000000U, 0x8000000000000000ULL);
-
- for (i = 0; i < NR_TESTS; i++) {
- unsigned int src_ui = rand();
- unsigned long long src_ull = ((unsigned long long) (unsigned int) rand() << 32) |
- (unsigned long long) (unsigned int) rand();
-
- run_test_unsigned(src_ui, src_ull);
- run_test_signed((int) src_ui, (long long) src_ull);
- }
-}
-
-static
-int print_encodings(unsigned long src, unsigned int shift, unsigned int len)
-{
- union {
- unsigned char c[8];
- unsigned short s[4];
- unsigned int i[2];
- unsigned long l[2];
- unsigned long long ll[1];
- } target;
- unsigned long long readval;
-
- init_byte_array(target.c, 8, 0xFF);
- bt_bitfield_write(target.c, unsigned char, shift, len, src);
- printf("bytewise\n");
- print_byte_array(target.c, 8);
-
- init_byte_array(target.c, 8, 0xFF);
- bt_bitfield_write(target.s, unsigned short, shift, len, src);
- printf("shortwise\n");
- print_byte_array(target.c, 8);
-
- init_byte_array(target.c, 8, 0xFF);
- bt_bitfield_write(target.i, unsigned int, shift, len, src);
- printf("intwise\n");
- print_byte_array(target.c, 8);
-
- init_byte_array(target.c, 8, 0xFF);
- bt_bitfield_write(target.l, unsigned long, shift, len, src);
- printf("longwise\n");
- print_byte_array(target.c, 8);
-
- init_byte_array(target.c, 8, 0xFF);
- bt_bitfield_write(target.ll, unsigned long long, shift, len, src);
- printf("lluwise\n");
- print_byte_array(target.c, 8);
-
- bt_bitfield_read(target.c, unsigned char, shift, len, &readval);
- printf("read: %llX\n", readval);
- print_byte_array(target.c, 8);
-
- return 0;
-}
-
-int main(int argc, char **argv)
-{
- if (argc > 1) {
- /* Print encodings */
- unsigned long src;
- unsigned int shift, len;
-
- src = atoi(argv[1]);
- if (argc > 2)
- shift = atoi(argv[2]);
- else
- shift = 12;
- if (argc > 3)
- len = atoi(argv[3]);
- else
- len = 40;
- return print_encodings(src, shift, len);
- }
-
- /* Run tap-formated tests */
- run_test();
- return exit_status();
-}
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+
+# Test the auto source disovery mechanism of the CLI.
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+SH_TAP=1 source "$UTILSSH"
+
+NUM_TESTS=3
+
+plan_tests $NUM_TESTS
+
+data_dir="${BT_TESTS_DATADIR}/auto-source-discovery/grouping"
+plugin_dir="${data_dir}"
+trace_dir="${data_dir}/traces"
+
+stdout_expected_file="${BT_TESTS_DATADIR}/cli/convert/auto-source-discovery-grouping.expect"
+stdout_actual_file=$(mktemp -t stdout-actual.XXXXXX)
+stderr_actual_file=$(mktemp -t actual-stderr.XXXXXX)
+
+bt_cli "$stdout_actual_file" "$stderr_actual_file" \
+ --plugin-path "${plugin_dir}" convert "ABCDE" "${trace_dir}" some_other_non_opt \
+ -c sink.text.details --params='with-metadata=false'
+ok "$?" "CLI runs successfully"
+
+# Check components and their inputs.
+bt_diff "$stdout_expected_file" "$stdout_actual_file"
+ok "$?" "expected components are instantiated with expected inputs"
+
+# Check that expected warning is printed.
+# shellcheck disable=SC2016
+grep -q 'No trace was found based on input `some_other_non_opt`' "$stderr_actual_file"
+ok "$?" "warning is printed"
+
+rm -f "$stdout_actual_file"
+rm -f "$stderr_actual_file"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+
+# Test how log level options are applied to sources auto-discovered by the
+# convert command.
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+SH_TAP=1 source "$UTILSSH"
+
+NUM_TESTS=4
+
+plan_tests $NUM_TESTS
+
+data_dir="${BT_TESTS_DATADIR}/auto-source-discovery/params-log-level"
+plugin_dir="${data_dir}"
+dir_a="${data_dir}/dir-a"
+dir_b="${data_dir}/dir-b"
+dir_ab="${data_dir}/dir-ab"
+
+expected_file=$(mktemp -t expected.XXXXXX)
+
+print_log_level=(--params 'what="log-level"')
+details_sink=("-c" "sink.text.details" "--params=with-metadata=false")
+
+debug=2
+trace=1
+
+# Apply log level to two components from one non-option argument.
+cat > "$expected_file" <<END
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceA: ${debug}
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceB: ${debug}
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+END
+
+bt_diff_cli "$expected_file" "/dev/null" \
+ --plugin-path "${plugin_dir}" convert \
+ "${dir_ab}" --log-level DEBUG "${print_log_level[@]}" \
+ "${details_sink[@]}"
+ok "$?" "apply log level to two components from one non-option argument"
+
+# Apply log level to two components from two distinct non-option arguments.
+cat > "$expected_file" <<END
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceA: ${debug}
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceB: ${trace}
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+END
+
+bt_diff_cli "$expected_file" "/dev/null" \
+ --plugin-path "${plugin_dir}" convert \
+ "${dir_a}" --log-level DEBUG "${print_log_level[@]}" "${dir_b}" --log-level TRACE "${print_log_level[@]}" \
+ "${details_sink[@]}"
+ok "$?" "apply log level to two non-option arguments"
+
+# Apply log level to one component coming from one non-option argument and one component coming from two non-option arguments (1).
+cat > "$expected_file" <<END
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceA: ${trace}
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceB: ${trace}
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+END
+
+bt_diff_cli "$expected_file" "/dev/null" \
+ --plugin-path "${plugin_dir}" convert \
+ "${dir_a}" --log-level DEBUG "${print_log_level[@]}" "${dir_ab}" --log-level TRACE "${print_log_level[@]}" \
+ "${details_sink[@]}"
+ok "$?" "apply log level to one component coming from one non-option argument and one component coming from two non-option arguments (1)"
+
+# Apply log level to one component coming from one non-option argument and one component coming from two non-option arguments (2).
+cat > "$expected_file" <<END
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceA: ${trace}
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceB: ${debug}
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+END
+
+bt_diff_cli "$expected_file" "/dev/null" \
+ --plugin-path "${plugin_dir}" convert \
+ "${dir_ab}" --log-level DEBUG "${print_log_level[@]}" "${dir_a}" --log-level TRACE "${print_log_level[@]}" \
+ "${details_sink[@]}"
+ok "$?" "apply log level to one component coming from one non-option argument and one component coming from two non-option arguments (2)"
+
+rm -f "$expected_file"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+
+# Test how parameters are applied to sources auto-discovered by the convert
+# command.
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+SH_TAP=1 source "$UTILSSH"
+
+NUM_TESTS=4
+
+plan_tests $NUM_TESTS
+
+data_dir="${BT_TESTS_DATADIR}/auto-source-discovery/params-log-level"
+plugin_dir="${data_dir}"
+dir_a="${data_dir}/dir-a"
+dir_b="${data_dir}/dir-b"
+dir_ab="${data_dir}/dir-ab"
+
+expected_file=$(mktemp -t expected.XXXXXX)
+
+print_test_params=("--params" 'what="test-params"')
+details_sink=("-c" "sink.text.details" "--params=with-metadata=false")
+
+# Apply params to two components from one non-option argument.
+cat > "$expected_file" <<END
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceA: ('test-allo', 'madame')
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceB: ('test-allo', 'madame')
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+END
+
+bt_diff_cli "$expected_file" "/dev/null" \
+ --plugin-path "${plugin_dir}" convert \
+ "${dir_ab}" --params 'test-allo="madame"' "${print_test_params[@]}" \
+ "${details_sink[@]}"
+ok "$?" "apply params to two components from one non-option argument"
+
+# Apply params to two components from two distinct non-option arguments.
+cat > "$expected_file" <<END
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceA: ('test-allo', 'madame')
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceB: ('test-bonjour', 'monsieur')
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+END
+
+bt_diff_cli "$expected_file" "/dev/null" \
+ --plugin-path "${plugin_dir}" convert \
+ "${dir_a}" --params 'test-allo="madame"' "${print_test_params[@]}" "${dir_b}" --params 'test-bonjour="monsieur"' "${print_test_params[@]}" \
+ "${details_sink[@]}"
+ok "$?" "apply params to two non-option arguments"
+
+# Apply params to one component coming from one non-option argument and one component coming from two non-option arguments (1).
+cat > "$expected_file" <<END
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceA: ('test-allo', 'madame'), ('test-bonjour', 'monsieur')
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceB: ('test-bonjour', 'monsieur')
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+END
+
+bt_diff_cli "$expected_file" "/dev/null" \
+ --plugin-path "${plugin_dir}" convert \
+ "${dir_a}" --params 'test-allo="madame"' "${print_test_params[@]}" "${dir_ab}" --params 'test-bonjour="monsieur"' "${print_test_params[@]}" \
+ "${details_sink[@]}"
+ok "$?" "apply params to one component coming from one non-option argument and one component coming from two non-option arguments (1)"
+
+# Apply params to one component coming from one non-option argument and one component coming from two non-option arguments (2).
+cat > "$expected_file" <<END
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceA: ('test-bonjour', 'monsieur'), ('test-salut', 'les amis')
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: TestSourceB: ('test-bonjour', 'madame'), ('test-salut', 'les amis')
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+END
+
+bt_diff_cli "$expected_file" "/dev/null" \
+ --plugin-path "${plugin_dir}" convert \
+ "${dir_ab}" --params 'test-bonjour="madame",test-salut="les amis"' "${print_test_params[@]}" "${dir_a}" --params 'test-bonjour="monsieur"' "${print_test_params[@]}" \
+ "${details_sink[@]}"
+ok "$?" "apply params to one component coming from one non-option argument and one component coming from two non-option arguments (2)"
+
+rm -f "$expected_file"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+tmp_stdout=$(mktemp -t test-convert-args-stdout.XXXXXX)
+tmp_stderr=$(mktemp -t test-convert-args-stderr.XXXXXX)
+
+test_bt_convert_run_args() {
+ local what="$1"
+ local convert_args="$2"
+ local expected_run_args="$3"
+
+ local run_args
+
+ # Split argument string into array.
+ IFS=' ' read -ra convert_args_array <<< "$convert_args"
+
+ # Execute convert command.
+ bt_cli "${tmp_stdout}" "${tmp_stderr}" convert --run-args "${convert_args_array[@]}"
+ ok $? "${what}: success exit status"
+
+ run_args=$(cat "${tmp_stdout}")
+
+ # Verify output run args.
+ [ "$run_args" = "$expected_run_args" ]
+ ok $? "${what}: run arguments"
+}
+
+test_bt_convert_fails() {
+ local what="$1"
+ local convert_args="$2"
+ local expected_error_str="$3"
+
+ # Split argument string into array.
+ IFS=' ' read -ra convert_args_array <<< "$convert_args"
+
+ # Execute convert command.
+ bt_cli "${tmp_stdout}" "${tmp_stderr}" convert --run-args "${convert_args_array[@]}"
+ isnt "$?" 0 "failure exit status"
+
+ # Nothing should be printed on stdout.
+ bt_diff /dev/null "${tmp_stdout}"
+ ok $? "$what: nothing is printed on stdout"
+
+ # Check for expected error string in stderr.
+ grep --quiet --fixed-strings -e "$expected_error_str" "$tmp_stderr"
+ local status=$?
+ ok "$status" "$what: expected error message"
+ if [ "$status" -ne 0 ]; then
+ diag "Expected error string '${expected_error_str}' not found in stderr:"
+ diag "$(cat "${tmp_stderr}")"
+ fi
+}
+
+path_to_trace="${BT_CTF_TRACES_PATH}/succeed/succeed1"
+path_to_trace2="${BT_CTF_TRACES_PATH}/succeed/succeed2"
+output_path="/output/path"
+
+if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
+ # Use Windows native paths for comparison because Unix
+ # paths are converted by the shell before they are passed
+ # to the native babeltrace2 binary.
+ path_to_trace=$(cygpath -m "$path_to_trace")
+ path_to_trace2=$(cygpath -m "$path_to_trace2")
+ output_path=$(cygpath -m "$output_path")
+fi
+
+plan_tests 161
+
+test_bt_convert_run_args 'path non-option arg' "$path_to_trace" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option args' "$path_to_trace $path_to_trace2" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\", \"${path_to_trace2}\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + named user source with --params' "$path_to_trace --component ZZ:source.another.source --params salut=yes" "--component ZZ:source.another.source --params salut=yes --component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect ZZ:muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'unnamed user source' '--component source.salut.com' "--component source.salut.com:source.salut.com --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect 'source\.salut\.com:muxer' --connect muxer:pretty"
+test_bt_convert_run_args "path non-option arg + user source named \`auto-disc-source-ctf-fs\`" "--component auto-disc-source-ctf-fs:source.salut.com $path_to_trace" "--component auto-disc-source-ctf-fs:source.salut.com --component auto-disc-source-ctf-fs-0:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect auto-disc-source-ctf-fs-0:muxer --connect muxer:pretty"
+test_bt_convert_run_args "path non-option arg + user sink named \`pretty\`" "--component pretty:sink.my.sink $path_to_trace" "--component pretty:sink.my.sink --component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args "path non-option arg + user filter named \`muxer\`" "--component muxer:filter.salut.com $path_to_trace" "--component muxer:filter.salut.com --component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer-0:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer-0 --connect muxer-0:muxer --connect muxer:pretty"
+test_bt_convert_run_args "path non-option arg + --begin + user filter named \`trimmer\`" "$path_to_trace --component trimmer:filter.salut.com --begin=abc" "--component trimmer:filter.salut.com --component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component trimmer-0:filter.utils.trimmer --params 'begin=\"abc\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:trimmer-0 --connect trimmer-0:trimmer --connect trimmer:pretty"
+test_bt_convert_run_args 'path non-option arg + --begin' "$path_to_trace --begin=123" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component trimmer:filter.utils.trimmer --params 'begin=\"123\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:trimmer --connect trimmer:pretty"
+test_bt_convert_run_args 'path non-option arg + --begin --end' "$path_to_trace --end=456 --begin 123" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component trimmer:filter.utils.trimmer --params 'end=\"456\"' --params 'begin=\"123\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:trimmer --connect trimmer:pretty"
+test_bt_convert_run_args 'path non-option arg + --timerange' "$path_to_trace --timerange=[abc,xyz]" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component trimmer:filter.utils.trimmer --params 'begin=\"abc\"' --params 'end=\"xyz\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:trimmer --connect trimmer:pretty"
+test_bt_convert_run_args 'path non-option arg + --clock-cycles' "$path_to_trace --clock-cycles" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params clock-cycles=yes --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --clock-date' "$path_to_trace --clock-date" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params clock-date=yes --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --clock-force-correlate' "$path_to_trace --clock-force-correlate" "--component auto-disc-source-ctf-fs:source.ctf.fs --params force-clock-class-origin-unix-epoch=yes --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --clock-gmt' "$path_to_trace --clock-gmt" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params clock-gmt=yes --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --clock-offset' "$path_to_trace --clock-offset=15487" "--component auto-disc-source-ctf-fs:source.ctf.fs --params clock-class-offset-s=15487 --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --clock-offset-ns' "$path_to_trace --clock-offset-ns=326159487" "--component auto-disc-source-ctf-fs:source.ctf.fs --params clock-class-offset-ns=326159487 --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --clock-seconds' "$path_to_trace --clock-seconds" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params clock-seconds=yes --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --color' "$path_to_trace --color=never" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params 'color=\"never\"' --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --debug-info' "$path_to_trace --debug-info" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component debug-info:filter.lttng-utils.debug-info --connect auto-disc-source-ctf-fs:muxer --connect muxer:debug-info --connect debug-info:pretty"
+test_bt_convert_run_args 'path non-option arg + --debug-info-dir' "$path_to_trace --debug-info-dir=${output_path}" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component debug-info:filter.lttng-utils.debug-info --params 'debug-info-dir=\"${output_path}\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:debug-info --connect debug-info:pretty"
+test_bt_convert_run_args 'path non-option arg + --debug-info-target-prefix' "$path_to_trace --debug-info-target-prefix=${output_path}" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component debug-info:filter.lttng-utils.debug-info --params 'target-prefix=\"${output_path}\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:debug-info --connect debug-info:pretty"
+test_bt_convert_run_args 'path non-option arg + --debug-info-full-path' "$path_to_trace --debug-info-full-path" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component debug-info:filter.lttng-utils.debug-info --params full-path=yes --connect auto-disc-source-ctf-fs:muxer --connect muxer:debug-info --connect debug-info:pretty"
+test_bt_convert_run_args 'path non-option arg + --fields=trace:domain,loglevel' "--fields=trace:domain,loglevel $path_to_trace" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params field-trace:domain=yes,field-loglevel=yes,field-default=hide --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --fields=all' "--fields=all $path_to_trace" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params field-default=show --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --names=context,header' "--names=context,header $path_to_trace" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params name-context=yes,name-header=yes,name-default=hide --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --names=all' "--names=all $path_to_trace" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params name-default=show --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --no-delta' "$path_to_trace --no-delta" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params no-delta=yes --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + --output' "$path_to_trace --output $output_path" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params 'path=\"$output_path\"' --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + -i ctf' "$path_to_trace -i ctf" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'URL non-option arg + -i lttng-live' 'net://some-host/host/target/session -i lttng-live' "--component lttng-live:source.ctf.lttng-live --params 'inputs=[\"net://some-host/host/target/session\"]' --params 'session-not-found-action=\"end\"' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect lttng-live:muxer --connect muxer:pretty"
+test_bt_convert_run_args 'path non-option arg + -o dummy' "$path_to_trace -o dummy" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component dummy:sink.utils.dummy --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:dummy"
+test_bt_convert_run_args 'path non-option arg + -o ctf + --output' "$path_to_trace -o ctf --output $output_path" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component sink-ctf-fs:sink.ctf.fs --params 'path=\"$output_path\"' --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:sink-ctf-fs"
+test_bt_convert_run_args 'path non-option arg + user sink with log level' "$path_to_trace -c sink.mein.sink -lW" "--component sink.mein.sink:sink.mein.sink --log-level W --component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect 'muxer:sink\.mein\.sink'"
+
+test_bt_convert_fails \
+ 'bad --component format (plugin only)' \
+ '--component salut' \
+ "Invalid format for --component option's argument:"
+
+test_bt_convert_fails \
+ 'bad --component format (name and plugin only)' \
+ '--component name:salut' \
+ "Missing component class type (\`source\`, \`filter\`, or \`sink\`)."
+
+test_bt_convert_fails \
+ 'bad --component format (name only)' \
+ '--component name:' \
+ "Missing component class type (\`source\`, \`filter\`, or \`sink\`)."
+
+test_bt_convert_fails \
+ 'bad --component format (extra dot found)' \
+ '--component name:source.plugin.comp.cls' \
+ "Invalid format for --component option's argument:"
+
+test_bt_convert_fails \
+ 'duplicate component name' \
+ '--component hello:sink.a.b --component hello:source.c.d' \
+ 'Duplicate component instance name:'
+
+test_bt_convert_fails \
+ 'unknown option' \
+ '--component hello:sink.a.b --salut' \
+ "Unknown option \`--salut\`"
+
+# The error string spans two lines in this error message, it's not convenient to
+# check for multiple lines, so we just check the first line.
+test_bt_convert_fails \
+ '--params without current component' \
+ '--params lol=23' \
+ "No current component (--component option) or non-option argument of which to"
+
+test_bt_convert_fails \
+ 'duplicate --begin' \
+ '--begin abc --clock-seconds --begin cde' \
+ 'At --begin option: --begin or --timerange option already specified'
+
+test_bt_convert_fails \
+ 'duplicate --end' \
+ '--begin abc --end xyz --clock-seconds --end cde' \
+ 'At --end option: --end or --timerange option already specified'
+
+test_bt_convert_fails \
+ '--begin and --timerange' \
+ '--begin abc --clock-seconds --timerange abc,def' \
+ 'At --timerange option: --begin, --end, or --timerange option already specified'
+
+test_bt_convert_fails \
+ '--end and --timerange' \
+ '--end abc --clock-seconds --timerange abc,def' \
+ 'At --timerange option: --begin, --end, or --timerange option already specified'
+
+test_bt_convert_fails \
+ 'bad --timerange format (1)' \
+ '--timerange abc' \
+ "Invalid --timerange option's argument: expecting BEGIN,END or [BEGIN,END]:"
+
+test_bt_convert_fails \
+ 'bad --timerange format (2)' \
+ '--timerange abc,' \
+ "Invalid --timerange option's argument: expecting BEGIN,END or [BEGIN,END]:"
+
+test_bt_convert_fails \
+ 'bad --timerange format (3)' \
+ '--timerange ,cde' \
+ "Invalid --timerange option's argument: expecting BEGIN,END or [BEGIN,END]:"
+
+test_bt_convert_fails \
+ 'bad --fields format' \
+ '--fields salut' \
+ "Unknown field: \`salut\`."
+
+test_bt_convert_fails \
+ 'bad --names format' \
+ '--names salut' \
+ "Unknown name: \`salut\`."
+
+test_bt_convert_fails \
+ 'unknown -i' \
+ '-i lol' \
+ 'Unknown legacy input format:'
+
+test_bt_convert_fails \
+ 'duplicate -i' \
+ '-i lttng-live --clock-seconds --input-format=ctf' \
+ 'Duplicate --input-format option.'
+
+test_bt_convert_fails \
+ 'unknown -o' \
+ '-o lol' \
+ 'Unknown legacy output format:'
+
+test_bt_convert_fails \
+ 'duplicate -o' \
+ '-o dummy --clock-seconds --output-format=text' \
+ 'Duplicate --output-format option.'
+
+test_bt_convert_fails \
+ '--run-args and --run-args-0' \
+ "$path_to_trace --run-args --run-args-0" \
+ 'Cannot specify --run-args and --run-args-0.'
+
+test_bt_convert_fails \
+ '-o ctf-metadata without path' \
+ '-o ctf-metadata' \
+ '--output-format=ctf-metadata specified without a path.'
+
+test_bt_convert_fails \
+ '-i lttng-live and implicit source.ctf.fs' \
+ '-i lttng-live net://some-host/host/target/session --clock-offset=23' \
+ '--clock-offset specified, but no source.ctf.fs component instantiated.'
+
+test_bt_convert_fails \
+ 'implicit source.ctf.fs without path' \
+ '--clock-offset=23' \
+ '--clock-offset specified, but no source.ctf.fs component instantiated.'
+
+test_bt_convert_fails \
+ 'implicit source.ctf.lttng-live without URL' \
+ '-i lttng-live' \
+ "Missing URL for implicit \`source.ctf.lttng-live\` component."
+
+test_bt_convert_fails \
+ 'no source' \
+ '-o text' \
+ 'No source component.'
+
+test_bt_convert_fails \
+ '-o ctf without --output' \
+ 'my-trace -o ctf' \
+ '--output-format=ctf specified without --output (trace output path).'
+
+# The error string spans two lines in this error message, it's not convenient to
+# check for multiple lines, so we just check the first line.
+test_bt_convert_fails \
+ '-o ctf + --output with implicit sink.text.pretty' \
+ "my-trace -o ctf --output $output_path --no-delta" \
+ 'Ambiguous --output option: --output-format=ctf specified but another option'
+
+test_bt_convert_fails \
+ '--stream-intersection' \
+ "$path_to_trace --stream-intersection" \
+ 'Cannot specify --stream-intersection with --run-args or --run-args-0.'
+
+test_bt_convert_fails \
+ 'two sinks with -o dummy + --clock-seconds' \
+ "$path_to_trace -o dummy --clock-seconds" \
+ 'More than one sink component specified.'
+
+test_bt_convert_fails \
+ 'path non-option arg + user sink + -o text' \
+ "$path_to_trace --component=sink.abc.def -o text" \
+ 'More than one sink component specified.'
+
+rm -f "${tmp_stdout}"
+rm -f "${tmp_stderr}"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-
-# Test the auto source disovery mechanism of the CLI.
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-SH_TAP=1 source "$UTILSSH"
-
-NUM_TESTS=3
-
-plan_tests $NUM_TESTS
-
-data_dir="${BT_TESTS_DATADIR}/auto-source-discovery/grouping"
-plugin_dir="${data_dir}"
-trace_dir="${data_dir}/traces"
-
-stdout_expected_file="${BT_TESTS_DATADIR}/cli/convert/auto-source-discovery-grouping.expect"
-stdout_actual_file=$(mktemp -t stdout-actual.XXXXXX)
-stderr_actual_file=$(mktemp -t actual-stderr.XXXXXX)
-
-bt_cli "$stdout_actual_file" "$stderr_actual_file" \
- --plugin-path "${plugin_dir}" convert "ABCDE" "${trace_dir}" some_other_non_opt \
- -c sink.text.details --params='with-metadata=false'
-ok "$?" "CLI runs successfully"
-
-# Check components and their inputs.
-bt_diff "$stdout_expected_file" "$stdout_actual_file"
-ok "$?" "expected components are instantiated with expected inputs"
-
-# Check that expected warning is printed.
-# shellcheck disable=SC2016
-grep -q 'No trace was found based on input `some_other_non_opt`' "$stderr_actual_file"
-ok "$?" "warning is printed"
-
-rm -f "$stdout_actual_file"
-rm -f "$stderr_actual_file"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-
-# Test how log level options are applied to sources auto-discovered by the
-# convert command.
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-SH_TAP=1 source "$UTILSSH"
-
-NUM_TESTS=4
-
-plan_tests $NUM_TESTS
-
-data_dir="${BT_TESTS_DATADIR}/auto-source-discovery/params-log-level"
-plugin_dir="${data_dir}"
-dir_a="${data_dir}/dir-a"
-dir_b="${data_dir}/dir-b"
-dir_ab="${data_dir}/dir-ab"
-
-expected_file=$(mktemp -t expected.XXXXXX)
-
-print_log_level=(--params 'what="log-level"')
-details_sink=("-c" "sink.text.details" "--params=with-metadata=false")
-
-debug=2
-trace=1
-
-# Apply log level to two components from one non-option argument.
-cat > "$expected_file" <<END
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceA: ${debug}
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceB: ${debug}
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-END
-
-bt_diff_cli "$expected_file" "/dev/null" \
- --plugin-path "${plugin_dir}" convert \
- "${dir_ab}" --log-level DEBUG "${print_log_level[@]}" \
- "${details_sink[@]}"
-ok "$?" "apply log level to two components from one non-option argument"
-
-# Apply log level to two components from two distinct non-option arguments.
-cat > "$expected_file" <<END
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceA: ${debug}
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceB: ${trace}
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-END
-
-bt_diff_cli "$expected_file" "/dev/null" \
- --plugin-path "${plugin_dir}" convert \
- "${dir_a}" --log-level DEBUG "${print_log_level[@]}" "${dir_b}" --log-level TRACE "${print_log_level[@]}" \
- "${details_sink[@]}"
-ok "$?" "apply log level to two non-option arguments"
-
-# Apply log level to one component coming from one non-option argument and one component coming from two non-option arguments (1).
-cat > "$expected_file" <<END
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceA: ${trace}
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceB: ${trace}
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-END
-
-bt_diff_cli "$expected_file" "/dev/null" \
- --plugin-path "${plugin_dir}" convert \
- "${dir_a}" --log-level DEBUG "${print_log_level[@]}" "${dir_ab}" --log-level TRACE "${print_log_level[@]}" \
- "${details_sink[@]}"
-ok "$?" "apply log level to one component coming from one non-option argument and one component coming from two non-option arguments (1)"
-
-# Apply log level to one component coming from one non-option argument and one component coming from two non-option arguments (2).
-cat > "$expected_file" <<END
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceA: ${trace}
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceB: ${debug}
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-END
-
-bt_diff_cli "$expected_file" "/dev/null" \
- --plugin-path "${plugin_dir}" convert \
- "${dir_ab}" --log-level DEBUG "${print_log_level[@]}" "${dir_a}" --log-level TRACE "${print_log_level[@]}" \
- "${details_sink[@]}"
-ok "$?" "apply log level to one component coming from one non-option argument and one component coming from two non-option arguments (2)"
-
-rm -f "$expected_file"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-
-# Test how parameters are applied to sources auto-discovered by the convert
-# command.
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-SH_TAP=1 source "$UTILSSH"
-
-NUM_TESTS=4
-
-plan_tests $NUM_TESTS
-
-data_dir="${BT_TESTS_DATADIR}/auto-source-discovery/params-log-level"
-plugin_dir="${data_dir}"
-dir_a="${data_dir}/dir-a"
-dir_b="${data_dir}/dir-b"
-dir_ab="${data_dir}/dir-ab"
-
-expected_file=$(mktemp -t expected.XXXXXX)
-
-print_test_params=("--params" 'what="test-params"')
-details_sink=("-c" "sink.text.details" "--params=with-metadata=false")
-
-# Apply params to two components from one non-option argument.
-cat > "$expected_file" <<END
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceA: ('test-allo', 'madame')
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceB: ('test-allo', 'madame')
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-END
-
-bt_diff_cli "$expected_file" "/dev/null" \
- --plugin-path "${plugin_dir}" convert \
- "${dir_ab}" --params 'test-allo="madame"' "${print_test_params[@]}" \
- "${details_sink[@]}"
-ok "$?" "apply params to two components from one non-option argument"
-
-# Apply params to two components from two distinct non-option arguments.
-cat > "$expected_file" <<END
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceA: ('test-allo', 'madame')
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceB: ('test-bonjour', 'monsieur')
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-END
-
-bt_diff_cli "$expected_file" "/dev/null" \
- --plugin-path "${plugin_dir}" convert \
- "${dir_a}" --params 'test-allo="madame"' "${print_test_params[@]}" "${dir_b}" --params 'test-bonjour="monsieur"' "${print_test_params[@]}" \
- "${details_sink[@]}"
-ok "$?" "apply params to two non-option arguments"
-
-# Apply params to one component coming from one non-option argument and one component coming from two non-option arguments (1).
-cat > "$expected_file" <<END
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceA: ('test-allo', 'madame'), ('test-bonjour', 'monsieur')
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceB: ('test-bonjour', 'monsieur')
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-END
-
-bt_diff_cli "$expected_file" "/dev/null" \
- --plugin-path "${plugin_dir}" convert \
- "${dir_a}" --params 'test-allo="madame"' "${print_test_params[@]}" "${dir_ab}" --params 'test-bonjour="monsieur"' "${print_test_params[@]}" \
- "${details_sink[@]}"
-ok "$?" "apply params to one component coming from one non-option argument and one component coming from two non-option arguments (1)"
-
-# Apply params to one component coming from one non-option argument and one component coming from two non-option arguments (2).
-cat > "$expected_file" <<END
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceA: ('test-bonjour', 'monsieur'), ('test-salut', 'les amis')
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: TestSourceB: ('test-bonjour', 'madame'), ('test-salut', 'les amis')
- Trace:
- Stream (ID 0, Class ID 0)
-
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-END
-
-bt_diff_cli "$expected_file" "/dev/null" \
- --plugin-path "${plugin_dir}" convert \
- "${dir_ab}" --params 'test-bonjour="madame",test-salut="les amis"' "${print_test_params[@]}" "${dir_a}" --params 'test-bonjour="monsieur"' "${print_test_params[@]}" \
- "${details_sink[@]}"
-ok "$?" "apply params to one component coming from one non-option argument and one component coming from two non-option arguments (2)"
-
-rm -f "$expected_file"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-tmp_stdout=$(mktemp -t test_convert_args_stdout.XXXXXX)
-tmp_stderr=$(mktemp -t test_convert_args_stderr.XXXXXX)
-
-test_bt_convert_run_args() {
- local what="$1"
- local convert_args="$2"
- local expected_run_args="$3"
-
- local run_args
-
- # Split argument string into array.
- IFS=' ' read -ra convert_args_array <<< "$convert_args"
-
- # Execute convert command.
- bt_cli "${tmp_stdout}" "${tmp_stderr}" convert --run-args "${convert_args_array[@]}"
- ok $? "${what}: success exit status"
-
- run_args=$(cat "${tmp_stdout}")
-
- # Verify output run args.
- [ "$run_args" = "$expected_run_args" ]
- ok $? "${what}: run arguments"
-}
-
-test_bt_convert_fails() {
- local what="$1"
- local convert_args="$2"
- local expected_error_str="$3"
-
- # Split argument string into array.
- IFS=' ' read -ra convert_args_array <<< "$convert_args"
-
- # Execute convert command.
- bt_cli "${tmp_stdout}" "${tmp_stderr}" convert --run-args "${convert_args_array[@]}"
- isnt "$?" 0 "failure exit status"
-
- # Nothing should be printed on stdout.
- bt_diff /dev/null "${tmp_stdout}"
- ok $? "$what: nothing is printed on stdout"
-
- # Check for expected error string in stderr.
- grep --quiet --fixed-strings -e "$expected_error_str" "$tmp_stderr"
- local status=$?
- ok "$status" "$what: expected error message"
- if [ "$status" -ne 0 ]; then
- diag "Expected error string '${expected_error_str}' not found in stderr:"
- diag "$(cat "${tmp_stderr}")"
- fi
-}
-
-path_to_trace="${BT_CTF_TRACES_PATH}/succeed/succeed1"
-path_to_trace2="${BT_CTF_TRACES_PATH}/succeed/succeed2"
-output_path="/output/path"
-
-if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
- # Use Windows native paths for comparison because Unix
- # paths are converted by the shell before they are passed
- # to the native babeltrace2 binary.
- path_to_trace=$(cygpath -m "$path_to_trace")
- path_to_trace2=$(cygpath -m "$path_to_trace2")
- output_path=$(cygpath -m "$output_path")
-fi
-
-plan_tests 161
-
-test_bt_convert_run_args 'path non-option arg' "$path_to_trace" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option args' "$path_to_trace $path_to_trace2" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\", \"${path_to_trace2}\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + named user source with --params' "$path_to_trace --component ZZ:source.another.source --params salut=yes" "--component ZZ:source.another.source --params salut=yes --component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect ZZ:muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'unnamed user source' '--component source.salut.com' "--component source.salut.com:source.salut.com --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect 'source\.salut\.com:muxer' --connect muxer:pretty"
-test_bt_convert_run_args "path non-option arg + user source named \`auto-disc-source-ctf-fs\`" "--component auto-disc-source-ctf-fs:source.salut.com $path_to_trace" "--component auto-disc-source-ctf-fs:source.salut.com --component auto-disc-source-ctf-fs-0:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect auto-disc-source-ctf-fs-0:muxer --connect muxer:pretty"
-test_bt_convert_run_args "path non-option arg + user sink named \`pretty\`" "--component pretty:sink.my.sink $path_to_trace" "--component pretty:sink.my.sink --component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args "path non-option arg + user filter named \`muxer\`" "--component muxer:filter.salut.com $path_to_trace" "--component muxer:filter.salut.com --component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer-0:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer-0 --connect muxer-0:muxer --connect muxer:pretty"
-test_bt_convert_run_args "path non-option arg + --begin + user filter named \`trimmer\`" "$path_to_trace --component trimmer:filter.salut.com --begin=abc" "--component trimmer:filter.salut.com --component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component trimmer-0:filter.utils.trimmer --params 'begin=\"abc\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:trimmer-0 --connect trimmer-0:trimmer --connect trimmer:pretty"
-test_bt_convert_run_args 'path non-option arg + --begin' "$path_to_trace --begin=123" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component trimmer:filter.utils.trimmer --params 'begin=\"123\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:trimmer --connect trimmer:pretty"
-test_bt_convert_run_args 'path non-option arg + --begin --end' "$path_to_trace --end=456 --begin 123" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component trimmer:filter.utils.trimmer --params 'end=\"456\"' --params 'begin=\"123\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:trimmer --connect trimmer:pretty"
-test_bt_convert_run_args 'path non-option arg + --timerange' "$path_to_trace --timerange=[abc,xyz]" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component trimmer:filter.utils.trimmer --params 'begin=\"abc\"' --params 'end=\"xyz\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:trimmer --connect trimmer:pretty"
-test_bt_convert_run_args 'path non-option arg + --clock-cycles' "$path_to_trace --clock-cycles" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params clock-cycles=yes --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --clock-date' "$path_to_trace --clock-date" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params clock-date=yes --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --clock-force-correlate' "$path_to_trace --clock-force-correlate" "--component auto-disc-source-ctf-fs:source.ctf.fs --params force-clock-class-origin-unix-epoch=yes --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --clock-gmt' "$path_to_trace --clock-gmt" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params clock-gmt=yes --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --clock-offset' "$path_to_trace --clock-offset=15487" "--component auto-disc-source-ctf-fs:source.ctf.fs --params clock-class-offset-s=15487 --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --clock-offset-ns' "$path_to_trace --clock-offset-ns=326159487" "--component auto-disc-source-ctf-fs:source.ctf.fs --params clock-class-offset-ns=326159487 --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --clock-seconds' "$path_to_trace --clock-seconds" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params clock-seconds=yes --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --color' "$path_to_trace --color=never" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params 'color=\"never\"' --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --debug-info' "$path_to_trace --debug-info" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component debug-info:filter.lttng-utils.debug-info --connect auto-disc-source-ctf-fs:muxer --connect muxer:debug-info --connect debug-info:pretty"
-test_bt_convert_run_args 'path non-option arg + --debug-info-dir' "$path_to_trace --debug-info-dir=${output_path}" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component debug-info:filter.lttng-utils.debug-info --params 'debug-info-dir=\"${output_path}\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:debug-info --connect debug-info:pretty"
-test_bt_convert_run_args 'path non-option arg + --debug-info-target-prefix' "$path_to_trace --debug-info-target-prefix=${output_path}" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component debug-info:filter.lttng-utils.debug-info --params 'target-prefix=\"${output_path}\"' --connect auto-disc-source-ctf-fs:muxer --connect muxer:debug-info --connect debug-info:pretty"
-test_bt_convert_run_args 'path non-option arg + --debug-info-full-path' "$path_to_trace --debug-info-full-path" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --component debug-info:filter.lttng-utils.debug-info --params full-path=yes --connect auto-disc-source-ctf-fs:muxer --connect muxer:debug-info --connect debug-info:pretty"
-test_bt_convert_run_args 'path non-option arg + --fields=trace:domain,loglevel' "--fields=trace:domain,loglevel $path_to_trace" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params field-trace:domain=yes,field-loglevel=yes,field-default=hide --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --fields=all' "--fields=all $path_to_trace" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params field-default=show --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --names=context,header' "--names=context,header $path_to_trace" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params name-context=yes,name-header=yes,name-default=hide --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --names=all' "--names=all $path_to_trace" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params name-default=show --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --no-delta' "$path_to_trace --no-delta" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params no-delta=yes --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + --output' "$path_to_trace --output $output_path" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --params 'path=\"$output_path\"' --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + -i ctf' "$path_to_trace -i ctf" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'URL non-option arg + -i lttng-live' 'net://some-host/host/target/session -i lttng-live' "--component lttng-live:source.ctf.lttng-live --params 'inputs=[\"net://some-host/host/target/session\"]' --params 'session-not-found-action=\"end\"' --component pretty:sink.text.pretty --component muxer:filter.utils.muxer --connect lttng-live:muxer --connect muxer:pretty"
-test_bt_convert_run_args 'path non-option arg + -o dummy' "$path_to_trace -o dummy" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component dummy:sink.utils.dummy --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:dummy"
-test_bt_convert_run_args 'path non-option arg + -o ctf + --output' "$path_to_trace -o ctf --output $output_path" "--component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component sink-ctf-fs:sink.ctf.fs --params 'path=\"$output_path\"' --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect muxer:sink-ctf-fs"
-test_bt_convert_run_args 'path non-option arg + user sink with log level' "$path_to_trace -c sink.mein.sink -lW" "--component sink.mein.sink:sink.mein.sink --log-level W --component auto-disc-source-ctf-fs:source.ctf.fs --params 'inputs=[\"$path_to_trace\"]' --component muxer:filter.utils.muxer --connect auto-disc-source-ctf-fs:muxer --connect 'muxer:sink\.mein\.sink'"
-
-test_bt_convert_fails \
- 'bad --component format (plugin only)' \
- '--component salut' \
- "Invalid format for --component option's argument:"
-
-test_bt_convert_fails \
- 'bad --component format (name and plugin only)' \
- '--component name:salut' \
- "Missing component class type (\`source\`, \`filter\`, or \`sink\`)."
-
-test_bt_convert_fails \
- 'bad --component format (name only)' \
- '--component name:' \
- "Missing component class type (\`source\`, \`filter\`, or \`sink\`)."
-
-test_bt_convert_fails \
- 'bad --component format (extra dot found)' \
- '--component name:source.plugin.comp.cls' \
- "Invalid format for --component option's argument:"
-
-test_bt_convert_fails \
- 'duplicate component name' \
- '--component hello:sink.a.b --component hello:source.c.d' \
- 'Duplicate component instance name:'
-
-test_bt_convert_fails \
- 'unknown option' \
- '--component hello:sink.a.b --salut' \
- "Unknown option \`--salut\`"
-
-# The error string spans two lines in this error message, it's not convenient to
-# check for multiple lines, so we just check the first line.
-test_bt_convert_fails \
- '--params without current component' \
- '--params lol=23' \
- "No current component (--component option) or non-option argument of which to"
-
-test_bt_convert_fails \
- 'duplicate --begin' \
- '--begin abc --clock-seconds --begin cde' \
- 'At --begin option: --begin or --timerange option already specified'
-
-test_bt_convert_fails \
- 'duplicate --end' \
- '--begin abc --end xyz --clock-seconds --end cde' \
- 'At --end option: --end or --timerange option already specified'
-
-test_bt_convert_fails \
- '--begin and --timerange' \
- '--begin abc --clock-seconds --timerange abc,def' \
- 'At --timerange option: --begin, --end, or --timerange option already specified'
-
-test_bt_convert_fails \
- '--end and --timerange' \
- '--end abc --clock-seconds --timerange abc,def' \
- 'At --timerange option: --begin, --end, or --timerange option already specified'
-
-test_bt_convert_fails \
- 'bad --timerange format (1)' \
- '--timerange abc' \
- "Invalid --timerange option's argument: expecting BEGIN,END or [BEGIN,END]:"
-
-test_bt_convert_fails \
- 'bad --timerange format (2)' \
- '--timerange abc,' \
- "Invalid --timerange option's argument: expecting BEGIN,END or [BEGIN,END]:"
-
-test_bt_convert_fails \
- 'bad --timerange format (3)' \
- '--timerange ,cde' \
- "Invalid --timerange option's argument: expecting BEGIN,END or [BEGIN,END]:"
-
-test_bt_convert_fails \
- 'bad --fields format' \
- '--fields salut' \
- "Unknown field: \`salut\`."
-
-test_bt_convert_fails \
- 'bad --names format' \
- '--names salut' \
- "Unknown name: \`salut\`."
-
-test_bt_convert_fails \
- 'unknown -i' \
- '-i lol' \
- 'Unknown legacy input format:'
-
-test_bt_convert_fails \
- 'duplicate -i' \
- '-i lttng-live --clock-seconds --input-format=ctf' \
- 'Duplicate --input-format option.'
-
-test_bt_convert_fails \
- 'unknown -o' \
- '-o lol' \
- 'Unknown legacy output format:'
-
-test_bt_convert_fails \
- 'duplicate -o' \
- '-o dummy --clock-seconds --output-format=text' \
- 'Duplicate --output-format option.'
-
-test_bt_convert_fails \
- '--run-args and --run-args-0' \
- "$path_to_trace --run-args --run-args-0" \
- 'Cannot specify --run-args and --run-args-0.'
-
-test_bt_convert_fails \
- '-o ctf-metadata without path' \
- '-o ctf-metadata' \
- '--output-format=ctf-metadata specified without a path.'
-
-test_bt_convert_fails \
- '-i lttng-live and implicit source.ctf.fs' \
- '-i lttng-live net://some-host/host/target/session --clock-offset=23' \
- '--clock-offset specified, but no source.ctf.fs component instantiated.'
-
-test_bt_convert_fails \
- 'implicit source.ctf.fs without path' \
- '--clock-offset=23' \
- '--clock-offset specified, but no source.ctf.fs component instantiated.'
-
-test_bt_convert_fails \
- 'implicit source.ctf.lttng-live without URL' \
- '-i lttng-live' \
- "Missing URL for implicit \`source.ctf.lttng-live\` component."
-
-test_bt_convert_fails \
- 'no source' \
- '-o text' \
- 'No source component.'
-
-test_bt_convert_fails \
- '-o ctf without --output' \
- 'my-trace -o ctf' \
- '--output-format=ctf specified without --output (trace output path).'
-
-# The error string spans two lines in this error message, it's not convenient to
-# check for multiple lines, so we just check the first line.
-test_bt_convert_fails \
- '-o ctf + --output with implicit sink.text.pretty' \
- "my-trace -o ctf --output $output_path --no-delta" \
- 'Ambiguous --output option: --output-format=ctf specified but another option'
-
-test_bt_convert_fails \
- '--stream-intersection' \
- "$path_to_trace --stream-intersection" \
- 'Cannot specify --stream-intersection with --run-args or --run-args-0.'
-
-test_bt_convert_fails \
- 'two sinks with -o dummy + --clock-seconds' \
- "$path_to_trace -o dummy --clock-seconds" \
- 'More than one sink component specified.'
-
-test_bt_convert_fails \
- 'path non-option arg + user sink + -o text' \
- "$path_to_trace --component=sink.abc.def -o text" \
- 'More than one sink component specified.'
-
-rm -f "${tmp_stdout}"
-rm -f "${tmp_stderr}"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 EfficiOS Inc.
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+SH_TAP=1 source "$UTILSSH"
+
+plan_tests 3
+
+data_dir="${BT_TESTS_DATADIR}/cli/list-plugins"
+plugin_dir="${data_dir}"
+
+stdout_file=$(mktemp -t test-cli-list-plugins-stdout.XXXXXX)
+stderr_file=$(mktemp -t test-cli-list-plugins-stderr.XXXXXX)
+grep_stdout_file=$(mktemp -t test-cli-list-plugins-grep-stdout.XXXXXX)
+py_plugin_expected_stdout_file=$(mktemp -t test-cli-list-plugins-expected-py-plugin-stdout.XXXXXX)
+
+# Run list-plugins.
+bt_cli "$stdout_file" "$stderr_file" \
+ --plugin-path "$plugin_dir" \
+ list-plugins
+ok "$?" "exit code is 0"
+
+# Extract the section about our custom this-is-a-plugin Python plugin.
+grep --after-context=11 '^this-is-a-plugin:$' "${stdout_file}" > "${grep_stdout_file}"
+ok "$?" "entry for this-is-a-plugin is present"
+
+if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
+ platform_plugin_dir=$(cygpath -m "${plugin_dir}")
+else
+ platform_plugin_dir="${plugin_dir}"
+fi
+
+# Generate the expected output file for that plugin.
+cat <<- EOF > "${py_plugin_expected_stdout_file}"
+ this-is-a-plugin:
+ Path: ${platform_plugin_dir}/bt_plugin_list_plugins.py
+ Version: 1.2.3bob
+ Description: A plugin
+ Author: Jorge Mario Bergoglio
+ License: The license
+ Source component classes:
+ 'source.this-is-a-plugin.ThisIsASource'
+ Filter component classes:
+ 'filter.this-is-a-plugin.ThisIsAFilter'
+ Sink component classes:
+ 'sink.this-is-a-plugin.ThisIsASink'
+EOF
+
+# Compare the entry for this-is-a-plugin with the expected version.
+bt_diff "${py_plugin_expected_stdout_file}" "${grep_stdout_file}"
+ok "$?" "entry for this-is-a-plugin is as expected"
+
+rm -f "${stdout_file}"
+rm -f "${stderr_file}"
+rm -f "${grep_stdout_file}"
+rm -f "${py_plugin_expected_stdout_file}"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 EfficiOS Inc.
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-SH_TAP=1 source "$UTILSSH"
-
-plan_tests 3
-
-data_dir="${BT_TESTS_DATADIR}/cli/list-plugins"
-plugin_dir="${data_dir}"
-
-stdout_file=$(mktemp -t test_cli_list_plugins_stdout.XXXXXX)
-stderr_file=$(mktemp -t test_cli_list_plugins_stderr.XXXXXX)
-grep_stdout_file=$(mktemp -t test_cli_list_plugins_grep_stdout.XXXXXX)
-py_plugin_expected_stdout_file=$(mktemp -t test_cli_list_plugins_expected_py_plugin_stdout.XXXXXX)
-
-# Run list-plugins.
-bt_cli "$stdout_file" "$stderr_file" \
- --plugin-path "$plugin_dir" \
- list-plugins
-ok "$?" "exit code is 0"
-
-# Extract the section about our custom this-is-a-plugin Python plugin.
-grep --after-context=11 '^this-is-a-plugin:$' "${stdout_file}" > "${grep_stdout_file}"
-ok "$?" "entry for this-is-a-plugin is present"
-
-if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
- platform_plugin_dir=$(cygpath -m "${plugin_dir}")
-else
- platform_plugin_dir="${plugin_dir}"
-fi
-
-# Generate the expected output file for that plugin.
-cat <<- EOF > "${py_plugin_expected_stdout_file}"
- this-is-a-plugin:
- Path: ${platform_plugin_dir}/bt_plugin_list_plugins.py
- Version: 1.2.3bob
- Description: A plugin
- Author: Jorge Mario Bergoglio
- License: The license
- Source component classes:
- 'source.this-is-a-plugin.ThisIsASource'
- Filter component classes:
- 'filter.this-is-a-plugin.ThisIsAFilter'
- Sink component classes:
- 'sink.this-is-a-plugin.ThisIsASink'
-EOF
-
-# Compare the entry for this-is-a-plugin with the expected version.
-bt_diff "${py_plugin_expected_stdout_file}" "${grep_stdout_file}"
-ok "$?" "entry for this-is-a-plugin is as expected"
-
-rm -f "${stdout_file}"
-rm -f "${stderr_file}"
-rm -f "${grep_stdout_file}"
-rm -f "${py_plugin_expected_stdout_file}"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+
+# Test how parameters are applied to sources auto-discovered by the convert
+# command.
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+SH_TAP=1 source "$UTILSSH"
+
+NUM_TESTS=9
+
+plan_tests $NUM_TESTS
+
+data_dir="${BT_TESTS_DATADIR}/cli/params"
+plugin_dir="${data_dir}"
+
+expected_file=$(mktemp -t expected.XXXXXX)
+
+function expect_success
+{
+ local test_name="$1"
+ local params_str="$2"
+ local expected_str="$3"
+
+ echo "$expected_str" > "$expected_file"
+
+ bt_diff_cli "$expected_file" /dev/null --plugin-path "$plugin_dir" -c "src.text.dmesg" \
+ -c "sink.params.SinkThatPrintsParams" --params "$params_str"
+ ok "$?" "$test_name"
+}
+
+expect_success 'null' 'a=null,b=nul,c=NULL' \
+ '{a=None, b=None, c=None}'
+expect_success 'bool' 'a=true,b=TRUE,c=yes,d=YES,e=false,f=FALSE,g=no,h=NO' \
+ '{a=True, b=True, c=True, d=True, e=False, f=False, g=False, h=False}'
+expect_success 'signed integer' 'a=0b110, b=022, c=22, d=0x22' \
+ '{a=6, b=18, c=22, d=34}'
+expect_success 'unsigned integer' 'a=+0b110, b=+022, c=+22, d=+0x22' \
+ '{a=6u, b=18u, c=22u, d=34u}'
+expect_success 'string' 'a="avril lavigne", b=patata, c="This\"is\\escaped"' \
+ '{a=avril lavigne, b=patata, c=This"is\escaped}'
+expect_success 'float' 'a=1.234, b=17., c=.28, d=-18.28' \
+ '{a=1.2340000, b=17.0000000, c=0.2800000, d=-18.2800000}'
+expect_success 'float scientific notation' 'a=10.5e6, b=10.5E6, c=10.5e-6, d=10.5E-6' \
+ '{a=10500000.0000000, b=10500000.0000000, c=0.0000105, d=0.0000105}'
+expect_success 'array' 'a=[1, [["hi",]]]' \
+ '{a=[1, [[hi]]]}'
+expect_success 'map' 'a=4,a={},b={salut="la gang",comment="ca va",oh={x=2}}' \
+ '{a={}, b={comment=ca va, oh={x=2}, salut=la gang}}'
+
+rm -f "$expected_file"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-
-# Test how parameters are applied to sources auto-discovered by the convert
-# command.
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-SH_TAP=1 source "$UTILSSH"
-
-NUM_TESTS=9
-
-plan_tests $NUM_TESTS
-
-data_dir="${BT_TESTS_DATADIR}/cli/params"
-plugin_dir="${data_dir}"
-
-expected_file=$(mktemp -t expected.XXXXXX)
-
-function expect_success
-{
- local test_name="$1"
- local params_str="$2"
- local expected_str="$3"
-
- echo "$expected_str" > "$expected_file"
-
- bt_diff_cli "$expected_file" /dev/null --plugin-path "$plugin_dir" -c "src.text.dmesg" \
- -c "sink.params.SinkThatPrintsParams" --params "$params_str"
- ok "$?" "$test_name"
-}
-
-expect_success 'null' 'a=null,b=nul,c=NULL' \
- '{a=None, b=None, c=None}'
-expect_success 'bool' 'a=true,b=TRUE,c=yes,d=YES,e=false,f=FALSE,g=no,h=NO' \
- '{a=True, b=True, c=True, d=True, e=False, f=False, g=False, h=False}'
-expect_success 'signed integer' 'a=0b110, b=022, c=22, d=0x22' \
- '{a=6, b=18, c=22, d=34}'
-expect_success 'unsigned integer' 'a=+0b110, b=+022, c=+22, d=+0x22' \
- '{a=6u, b=18u, c=22u, d=34u}'
-expect_success 'string' 'a="avril lavigne", b=patata, c="This\"is\\escaped"' \
- '{a=avril lavigne, b=patata, c=This"is\escaped}'
-expect_success 'float' 'a=1.234, b=17., c=.28, d=-18.28' \
- '{a=1.2340000, b=17.0000000, c=0.2800000, d=-18.2800000}'
-expect_success 'float scientific notation' 'a=10.5e6, b=10.5E6, c=10.5e-6, d=10.5E-6' \
- '{a=10500000.0000000, b=10500000.0000000, c=0.0000105, d=0.0000105}'
-expect_success 'array' 'a=[1, [["hi",]]]' \
- '{a=[1, [[hi]]]}'
-expect_success 'map' 'a=4,a={},b={salut="la gang",comment="ca va",oh={x=2}}' \
- '{a={}, b={comment=ca va, oh={x=2}, salut=la gang}}'
-
-rm -f "$expected_file"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+SH_TAP=1 source "$UTILSSH"
+
+NUM_TESTS=15
+
+plan_tests $NUM_TESTS
+
+data_dir="${BT_TESTS_DATADIR}/cli/query"
+plugin_dir="${data_dir}"
+
+stdout_expected_file=$(mktemp -t test-cli-query-stdout-expected.XXXXXX)
+stdout_file=$(mktemp -t test-cli-query-stdout.XXXXXX)
+stderr_file=$(mktemp -t test-cli-query-stderr.XXXXXX)
+
+expect_success() {
+ local expected_str="$1"
+ shift 1
+ local args=("$@")
+
+ echo "$expected_str" > "$stdout_expected_file"
+
+ bt_diff_cli "$stdout_expected_file" /dev/null \
+ --plugin-path "$plugin_dir" \
+ query "src.query.SourceWithQueryThatPrintsParams" \
+ "${args[@]}"
+ ok "$?" "${args[*]}"
+}
+
+expect_failure() {
+ local expected_str="$1"
+ shift 1
+ local args=("$@")
+ local test_name="${args[*]}"
+
+ echo -n > "$stdout_expected_file"
+
+ bt_cli "$stdout_file" "$stderr_file" \
+ --plugin-path "$plugin_dir" \
+ query \
+ "${args[@]}"
+ isnt "$?" 0 "${test_name}: exit code is not 0"
+
+ bt_diff /dev/null "$stdout_file"
+ ok "$?" "${test_name}: nothing output on stout"
+
+ # Ensure that a CLI error stack is printed (and that babeltrace doesn't
+ # abort before that).
+ grep --silent "^ERROR: " "${stderr_file}"
+ ok $? "${test_name}: babeltrace produces an error stack"
+
+ grep --silent "${expected_str}" "${stderr_file}"
+ ok "$?" "${test_name}: expect \`${expected_str}\` error message on stderr"
+}
+
+expect_success 'the-object:{}' \
+ 'the-object'
+expect_success "the-object:{a=2}" \
+ 'the-object' -p 'a=2'
+
+# Check that -p parameters are processed in order.
+expect_success "the-object:{a=3, ben=kin, voyons=donc}" \
+ 'the-object' -p 'a=2,ben=kin' -p 'voyons=donc,a=3'
+
+# Failure inside the component class' query method.
+expect_failure "ValueError: catastrophic failure" \
+ 'src.query.SourceWithQueryThatPrintsParams' 'please-fail' '-p' 'a=2'
+
+# Non-existent component class.
+expect_failure 'Cannot find component class: plugin-name="query", comp-cls-name="NonExistentSource", comp-cls-type=SOURCE' \
+ 'src.query.NonExistentSource' 'the-object' '-p' 'a=2'
+
+# Wrong parameter syntax.
+expect_failure "Invalid format for --params option's argument:" \
+ 'src.query.SourceWithQueryThatPrintsParams' 'please-fail' '-p' 'a=3,'
+
+rm -f "$stdout_expected_file"
+rm -f "$stdout_file"
+rm -f "$stderr_file"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-SH_TAP=1 source "$UTILSSH"
-
-NUM_TESTS=15
-
-plan_tests $NUM_TESTS
-
-data_dir="${BT_TESTS_DATADIR}/cli/query"
-plugin_dir="${data_dir}"
-
-stdout_expected_file=$(mktemp -t test_cli_query_stdout_xpected.XXXXXX)
-stdout_file=$(mktemp -t test_cli_query_stdout.XXXXXX)
-stderr_file=$(mktemp -t test_cli_query_stderr.XXXXXX)
-
-expect_success() {
- local expected_str="$1"
- shift 1
- local args=("$@")
-
- echo "$expected_str" > "$stdout_expected_file"
-
- bt_diff_cli "$stdout_expected_file" /dev/null \
- --plugin-path "$plugin_dir" \
- query "src.query.SourceWithQueryThatPrintsParams" \
- "${args[@]}"
- ok "$?" "${args[*]}"
-}
-
-expect_failure() {
- local expected_str="$1"
- shift 1
- local args=("$@")
- local test_name="${args[*]}"
-
- echo -n > "$stdout_expected_file"
-
- bt_cli "$stdout_file" "$stderr_file" \
- --plugin-path "$plugin_dir" \
- query \
- "${args[@]}"
- isnt "$?" 0 "${test_name}: exit code is not 0"
-
- bt_diff /dev/null "$stdout_file"
- ok "$?" "${test_name}: nothing output on stout"
-
- # Ensure that a CLI error stack is printed (and that babeltrace doesn't
- # abort before that).
- grep --silent "^ERROR: " "${stderr_file}"
- ok $? "${test_name}: babeltrace produces an error stack"
-
- grep --silent "${expected_str}" "${stderr_file}"
- ok "$?" "${test_name}: expect \`${expected_str}\` error message on stderr"
-}
-
-expect_success 'the-object:{}' \
- 'the-object'
-expect_success "the-object:{a=2}" \
- 'the-object' -p 'a=2'
-
-# Check that -p parameters are processed in order.
-expect_success "the-object:{a=3, ben=kin, voyons=donc}" \
- 'the-object' -p 'a=2,ben=kin' -p 'voyons=donc,a=3'
-
-# Failure inside the component class' query method.
-expect_failure "ValueError: catastrophic failure" \
- 'src.query.SourceWithQueryThatPrintsParams' 'please-fail' '-p' 'a=2'
-
-# Non-existent component class.
-expect_failure 'Cannot find component class: plugin-name="query", comp-cls-name="NonExistentSource", comp-cls-type=SOURCE' \
- 'src.query.NonExistentSource' 'the-object' '-p' 'a=2'
-
-# Wrong parameter syntax.
-expect_failure "Invalid format for --params option's argument:" \
- 'src.query.SourceWithQueryThatPrintsParams' 'please-fail' '-p' 'a=3,'
-
-rm -f "$stdout_expected_file"
-rm -f "$stdout_file"
-rm -f "$stderr_file"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 EfficiOS Inc.
+#
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+data_dir="$BT_TESTS_DATADIR/cli/exit-status"
+source_name="src.test-exit-status.StatusSrc"
+
+test_interrupted_graph() {
+ local cli_args=("--plugin-path=$data_dir" "-c" "$source_name" "-p" "case=\"INTERRUPTED\"")
+ local actual_stdout
+ local actual_stderr
+
+ actual_stdout=$(mktemp -t test-cli-exit-status-stdout-actual.XXXXXX)
+ actual_stderr=$(mktemp -t test-cli-exit-status-stderr-actual.XXXXXX)
+
+ bt_cli "$actual_stdout" "$actual_stderr" "${cli_args[@]}"
+
+ is $? 2 "Interrupted graph exits with status 2"
+
+ bt_diff /dev/null "$actual_stdout"
+ ok $? "Interrupted graph gives no stdout"
+
+ bt_diff /dev/null "$actual_stderr"
+ ok $? "Interrupted graph gives no stderr"
+
+ rm -f "${actual_stdout}"
+ rm -f "${actual_stderr}"
+}
+
+test_error_graph() {
+ local cli_args=("--plugin-path=$data_dir" "-c" "$source_name" "-p" "case=\"ERROR\"")
+ local actual_stdout
+ local actual_stderr
+
+ actual_stdout=$(mktemp -t test-cli-exit-status-stdout-actual.XXXXXX)
+ actual_stderr=$(mktemp -t test-cli-exit-status-stderr-actual.XXXXXX)
+
+ bt_cli "$actual_stdout" "$actual_stderr" "${cli_args[@]}"
+
+ is $? 1 "Erroring graph exits with status 1"
+
+ bt_diff /dev/null "$actual_stdout"
+ ok $? "Erroring graph gives expected stdout"
+
+ like "$(cat "${actual_stderr}")" "TypeError: Raising type error" \
+ "Erroring graph gives expected error message"
+
+ rm -f "${actual_stdout}"
+ rm -f "${actual_stderr}"
+}
+
+test_stop_graph() {
+ local cli_args=("--plugin-path=$data_dir" "-c" "$source_name" "-p" "case=\"STOP\"")
+ local actual_stdout
+ local actual_stderr
+
+ actual_stdout=$(mktemp -t test-cli-exit-status-stdout-actual.XXXXXX)
+ actual_stderr=$(mktemp -t test-cli-exit-status-stderr-actual.XXXXXX)
+
+ bt_cli "$actual_stdout" "$actual_stderr" "${cli_args[@]}"
+
+ is $? 0 "Successful graph exits with status 0"
+
+ bt_diff /dev/null "$actual_stdout"
+ ok $? "Successful graph gives no stdout"
+
+ bt_diff /dev/null "$actual_stderr"
+ ok $? "Successful graph gives no stderr"
+
+ rm -f "${actual_stdout}"
+ rm -f "${actual_stderr}"
+}
+
+plan_tests 9
+
+test_interrupted_graph
+test_error_graph
+test_stop_graph
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 EfficiOS Inc.
+#
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+plan_tests 21
+
+stdout=$(mktemp -t test-help-stdout.XXXXXX)
+stderr=$(mktemp -t test-help-stderr.XXXXXX)
+
+# Return 0 if file "$1" exists and is empty, non-0 otherwise.
+
+is_empty()
+{
+ [[ -f "$1" && ! -s "$1" ]]
+}
+
+# Test with a working plugin name.
+bt_cli "${stdout}" "${stderr}" help ctf
+ok $? "help ctf plugin exit status"
+
+grep --silent 'Description: CTF input and output' "${stdout}"
+ok $? "help ctf plugin expected output"
+
+is_empty "${stderr}"
+ok $? "help ctf plugin produces no error"
+
+# Test with a working component class name.
+bt_cli "${stdout}" "${stderr}" help src.ctf.fs
+ok $? "help src.ctf.fs component class exit status"
+
+grep --silent 'Description: Read CTF traces from the file system.' "${stdout}"
+ok $? "help src.ctf.fs component class expected output"
+
+is_empty "${stderr}"
+ok $? "help src.ctf.fs component class produces no error"
+
+# Test without parameter.
+bt_cli "${stdout}" "${stderr}" help
+isnt $? 0 "help without parameter exit status"
+
+grep --silent "Missing plugin name or component class descriptor." "${stderr}"
+ok $? "help without parameter produces expected error"
+
+is_empty "${stdout}"
+ok $? "help without parameter produces no output"
+
+# Test with too many parameters.
+bt_cli "${stdout}" "${stderr}" help ctf fs
+isnt $? 0 "help with too many parameters exit status"
+
+grep --silent "Extraneous command-line argument specified to \`help\` command:" "${stderr}"
+ok $? "help with too many parameters produces expected error"
+
+is_empty "${stdout}"
+ok $? "help with too many parameters produces no output"
+
+# Test with unknown plugin name.
+bt_cli "${stdout}" "${stderr}" help zigotos
+isnt $? 0 "help with unknown plugin name"
+
+grep --silent 'Cannot find plugin: plugin-name="zigotos"' "${stderr}"
+ok $? "help with unknown plugin name produces expected error"
+
+is_empty "${stdout}"
+ok $? "help with unknown plugin name produces no output"
+
+# Test with unknown component class name (but known plugin).
+bt_cli "${stdout}" "${stderr}" help src.ctf.bob
+isnt $? 0 "help with unknown component class name"
+
+grep --silent 'Cannot find component class: plugin-name="ctf", comp-cls-name="bob", comp-cls-type=SOURCE' "${stderr}"
+ok $? "help with unknown component class name produces expected error"
+
+grep --silent 'Description: CTF input and output' "${stdout}"
+ok $? "help with unknown component class name prints plugin help"
+
+# Test with unknown component class plugin
+bt_cli "${stdout}" "${stderr}" help src.bob.fs
+isnt $? 0 "help with unknown component class plugin"
+
+grep --silent 'Cannot find plugin: plugin-name="bob"' "${stderr}"
+ok $? "help with unknown component class plugin produces expected error"
+
+is_empty "${stdout}"
+ok $? "help with unknown component class plugin produces no output"
+
+rm -f "${stdout}" "${stderr}"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 Julien Desfossez <jdesfossez@efficios.com>
+#
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+plan_tests 20
+
+stdout=$(mktemp -t test-intersection-stdout.XXXXXX)
+stderr=$(mktemp -t test-intersection-stderr.XXXXXX)
+
+test_intersect() {
+ local trace="$1"
+ local totalevents="$2"
+ local intersect="$3"
+
+ local cnt
+
+ bt_cli "${stdout}" "/dev/null" "${trace}"
+ ok $? "run without --stream-intersection"
+
+ cnt=$(wc -l < "${stdout}")
+ test "${cnt// /}" = "$totalevents"
+ ok $? "$totalevents events in the whole trace"
+
+ bt_cli "${stdout}" "/dev/null" --stream-intersection "${trace}"
+ ok $? "run with --stream-intersection"
+
+ cnt=$(wc -l < "${stdout}")
+ test "${cnt// /}" = "$intersect"
+ ok $? "$intersect events in streams intersecting"
+}
+
+test_intersect_fails() {
+ local trace="$1"
+ local totalevents="$2"
+ local expected_error_message="$3"
+
+ bt_cli "${stdout}" "/dev/null" "${trace}"
+ ok $? "run without --stream-intersection"
+
+ cnt=$(wc -l < "${stdout}")
+ test "${cnt// /}" = "$totalevents"
+ ok $? "$totalevents events in the whole trace"
+
+ bt_cli "${stdout}" "${stderr}" --stream-intersection "${trace}"
+ isnt "$?" 0 "run with --stream-intersection fails"
+
+ grep --silent "${expected_error_message}" "${stderr}"
+ ok $? "stderr contains expected error message"
+}
+
+diag "Test the stream intersection feature"
+
+diag "2 streams offsetted with 3 packets intersecting"
+test_intersect "${BT_CTF_TRACES_PATH}/intersection/3eventsintersect" 8 3
+
+diag "2 streams offsetted with 3 packets intersecting (exchanged file names)"
+test_intersect "${BT_CTF_TRACES_PATH}/intersection/3eventsintersectreverse" 8 3
+
+diag "Only 1 stream"
+test_intersect "${BT_CTF_TRACES_PATH}/intersection/onestream" 3 3
+
+diag "No intersection between 2 streams"
+test_intersect_fails "${BT_CTF_TRACES_PATH}/intersection/nointersect" 6 \
+ "Trimming time range's beginning time is greater than end time: "
+
+diag "No stream at all"
+test_intersect_fails "${BT_CTF_TRACES_PATH}/intersection/nostream" 0 \
+ "Trace has no streams: "
+
+rm -f "${stdout}" "${stderr}"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+NUM_TESTS=3
+
+plan_tests $NUM_TESTS
+
+tmp_metadata=$(mktemp)
+
+# Test a valid trace directory.
+"${BT_TESTS_BT2_BIN}" -o ctf-metadata "${BT_CTF_TRACES_PATH}/succeed/wk-heartbeat-u" > "$tmp_metadata"
+ok $? "Run babeltrace -o ctf-metadata with a valid trace directory, correct exit status"
+
+bt_diff "${BT_TESTS_DATADIR}/cli/test-output-ctf-metadata.ref" "$tmp_metadata"
+ok $? "Run babeltrace -o ctf-metadata with a valid trace directory, correct output"
+
+# Test an invalid trace directory.
+"${BT_TESTS_BT2_BIN}" -o ctf-metadata "${BT_CTF_TRACES_PATH}" >/dev/null 2>&1
+isnt $? 0 "Run babeltrace -o ctf-metadata with an invalid trace directory, expecting failure"
+
+rm -f "$tmp_metadata"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) EfficiOS Inc.
+#
+
+# This test verifies that generic (non-LTTng) CTF traces are output with the
+# expected directory structure.
+#
+# Traces found when invoking
+#
+# babeltrace2 in -c sink.ctf.fs -p 'path="out"'
+#
+# are expected to use the same directory structure relative to `out` as the
+# original traces had relative to `in`.
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+plan_tests 3
+
+temp_input_dir=$(mktemp -t -d test-output-path-ctf-non-lttng-trace-input.XXXXXX)
+temp_output_dir=$(mktemp -t -d test-output-path-ctf-non-lttng-trace-output.XXXXXX)
+
+mkdir -p "${temp_input_dir}/a/b/c"
+cp -a "${BT_CTF_TRACES_PATH}/intersection/3eventsintersect" "${temp_input_dir}/a/b/c"
+
+mkdir -p "${temp_input_dir}/a/b/c"
+cp -a "${BT_CTF_TRACES_PATH}/intersection/3eventsintersectreverse" "${temp_input_dir}/a/b/c"
+
+mkdir -p "${temp_input_dir}/d/e/f"
+cp -a "${BT_CTF_TRACES_PATH}/intersection/nointersect" "${temp_input_dir}/d/e/f"
+
+bt_cli "/dev/null" "/dev/null" "${temp_input_dir}" -c sink.ctf.fs -p "path=\"${temp_output_dir}\""
+
+test -f "${temp_output_dir}/a/b/c/3eventsintersect/metadata"
+ok "$?" "3eventsintersect output trace exists"
+
+test -f "${temp_output_dir}/a/b/c/3eventsintersectreverse/metadata"
+ok "$?" "3eventsintersectreverse output trace exists"
+
+test -f "${temp_output_dir}/d/e/f/nointersect/metadata"
+ok "$?" "nointersect output trace exists"
+
+rm -rf "${temp_input_dir}" "${temp_output_dir}"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 Julien Desfossez <jdesfossez@efficios.com>
+#
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+NUM_TESTS=10
+
+plan_tests $NUM_TESTS
+
+test_no_lost() {
+ local trace=$1
+
+ "${BT_TESTS_BT2_BIN}" "$trace" >/dev/null 2>&1
+ ok $? "Trace parses"
+ "${BT_TESTS_BT2_BIN}" "$trace" 2>&1 >/dev/null | "${BT_TESTS_GREP_BIN}" "\[warning\] Tracer lost"
+ if test $? = 0; then
+ fail 1 "Should not find any lost events"
+ else
+ ok 0 "No events lost"
+ fi
+}
+
+test_lost() {
+ local trace=$1
+ local expectedcountstr=$2
+
+ "${BT_TESTS_BT2_BIN}" "$trace" >/dev/null 2>&1
+ ok $? "Trace parses"
+
+ # Convert warnings like:
+ # WARNING: Tracer discarded 2 trace packets between ....
+ # WARNING: Tracer discarded 3 trace packets between ....
+ # into "2,3" and make sure it matches the expected result
+ "${BT_TESTS_BT2_BIN}" "$trace" 2>&1 >/dev/null | "${BT_TESTS_GREP_BIN}" "WARNING: Tracer discarded" \
+ | cut -d" " -f4 | tr "\n" "," | "${BT_TESTS_SED_BIN}" "s/.$//" | \
+ "${BT_TESTS_GREP_BIN}" "$expectedcountstr" >/dev/null
+ ok $? "Lost events string matches $expectedcountstr"
+
+}
+
+diag "Test the packet_seq_num validation"
+
+diag "No packet lost"
+test_no_lost "${BT_CTF_TRACES_PATH}/packet-seq-num/no-lost"
+
+diag "No packet lost, packet_seq_num not starting at 0"
+test_no_lost "${BT_CTF_TRACES_PATH}/packet-seq-num/no-lost-not-starting-at-0"
+
+diag "1 stream, 2 packets lost before the last packet"
+test_lost "${BT_CTF_TRACES_PATH}/packet-seq-num/2-lost-before-last" "2"
+
+diag "2 streams, packets lost in one of them"
+test_lost "${BT_CTF_TRACES_PATH}/packet-seq-num/2-streams-lost-in-1" "2"
+
+diag "2 streams, packets lost in both"
+test_lost "${BT_CTF_TRACES_PATH}/packet-seq-num/2-streams-lost-in-2" "2,3,1"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com>
+#
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+clean_tmp() {
+ rm -rf "${out_path}" "${text_output1}" "${text_output2_intermediary}" "${text_output2}"
+}
+
+SUCCESS_TRACES=("${BT_CTF_TRACES_PATH}/succeed/"*)
+
+# -4 because there are two empty traces that we skip
+NUM_TESTS=$((${#SUCCESS_TRACES[@]} * 3 - 4))
+
+plan_tests $NUM_TESTS
+
+for path in "${SUCCESS_TRACES[@]}"; do
+ out_path="$(mktemp -d)"
+ text_output1="$(mktemp)"
+ text_output2_intermediary="$(mktemp)"
+ text_output2="$(mktemp)"
+ trace="$(basename "${path}")"
+ sort_cmd="cat" # by default do not sort the trace
+
+ bt_cli "${text_output1}" "/dev/null" --no-delta "${path}"
+ ret=$?
+ cnt="$(wc -l < "${text_output1}")"
+ if test "$ret" == 0 && test "${cnt// /}" == 0; then
+ pass "Empty trace ${trace}, nothing to copy"
+ clean_tmp
+ continue
+ fi
+
+ # If the trace has a timestamp (starts with [), check if there are
+ # duplicate timestamps in the output.
+ # If there are, we have to sort the text output to make sure it is
+ # always the same.
+ head -1 "${text_output1}" | "${BT_TESTS_GREP_BIN}" "^\[" >/dev/null
+ if test $? = 0; then
+ # shellcheck disable=SC2016
+ uniq_ts_cnt="$("${BT_TESTS_AWK_BIN}" '{ print $1 }' < "${text_output1}" | sort | uniq | wc -l)"
+ # Extract only the timestamp columns and compare the number of
+ # unique lines with the total number of lines to see if there
+ # are duplicate timestamps.
+ if test "${cnt// /}" != "${uniq_ts_cnt// /}"; then
+ diag "Trace with non unique timestamps, sorting the output"
+ sort_cmd="sort"
+ tmp="$(mktemp)"
+ sort "${text_output1}" > "$tmp"
+ rm "${text_output1}"
+ text_output1="$tmp"
+ fi
+ fi
+
+ bt_cli "/dev/null" "/dev/null" "${path}" --component sink.ctf.fs "--params=path=\"${out_path}\""
+ ok $? "Copy trace ${trace} with ctf-fs sink"
+
+ bt_cli "/dev/null" "/dev/null" "${out_path}"
+ ok $? "Read the new trace in ${out_path}"
+
+ bt_cli "${text_output2_intermediary}" "/dev/null" --no-delta "${out_path}"
+ $sort_cmd "${text_output2_intermediary}" > "${text_output2}"
+ cnt=$(diff "${text_output1}" "${text_output2}" | wc -l)
+ test "${cnt// /}" == 0
+ ok $? "Exact same content between the two traces"
+
+ clean_tmp
+done
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2013 Christian Babeux <christian.babeux@efficios.com>
+#
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+SUCCESS_TRACES=("${BT_CTF_TRACES_PATH}/succeed/"*)
+FAIL_TRACES=("${BT_CTF_TRACES_PATH}/fail/"*)
+
+NUM_TESTS=$((${#SUCCESS_TRACES[@]} + ${#FAIL_TRACES[@]}))
+
+plan_tests $NUM_TESTS
+
+for path in "${SUCCESS_TRACES[@]}"; do
+ trace=$(basename "${path}")
+ "${BT_TESTS_BT2_BIN}" "${path}" > /dev/null 2>&1
+ ok $? "Run babeltrace2 with trace ${trace}"
+done
+
+for path in "${FAIL_TRACES[@]}"; do
+ trace=$(basename "${path}")
+ if "${BT_TESTS_BT2_BIN}" "${path}" > /dev/null 2>&1; then
+ fail "Run babeltrace2 with invalid trace ${trace}"
+ else
+ pass "Run babeltrace2 with invalid trace ${trace}"
+ fi
+done
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com>
+#
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+TRACE_PATH="${BT_CTF_TRACES_PATH}/succeed/wk-heartbeat-u/"
+
+NUM_TESTS=118
+
+plan_tests $NUM_TESTS
+
+tmp_out=$(mktemp)
+tmp_err=$(mktemp)
+
+
+# Run Babeltrace with some command line arguments, verify exit status and
+# number of output events (i.e. number of output lines)
+#
+# Arguments:
+#
+# $1: expected number of events
+# $2: test description
+# remaining arguments: command-line arguments to pass to Babeltrace
+
+function expect_success()
+{
+ local expected_num_events="$1"
+ local msg="$2"
+ shift 2
+
+ bt_cli "${tmp_out}" /dev/null "${TRACE_PATH}" "$@"
+ ok $? "trimmer: ${msg}: exit status"
+
+ num_events=$(wc -l < "${tmp_out}")
+ # Use bash parameter expansion to strip spaces added by BSD 'wc' on macOs and Solaris
+ is "${num_events// /}" "${expected_num_events}" "trimmer: ${msg}: number of events (${expected_num_events})"
+}
+
+# Run Babeltrace with some command line arguments, verify that the exit status
+# is not 0 and that the error message contains a given string.
+#
+# Arguments:
+#
+# $1: a string expected to be found in the error message
+# $2: test description
+# remaining arguments: command-line arguments to pass to Babeltrace
+
+function expect_failure()
+{
+ local expected_err_string="$1"
+ local msg="$2"
+ shift 2
+
+ # We check the error message logged by the trimmer plugin, set the env
+ # var necessary for it to log errors.
+ BABELTRACE_FLT_UTILS_TRIMMER_LOG_LEVEL=E bt_cli "${tmp_out}" "${tmp_err}" "${TRACE_PATH}" "$@"
+ isnt $? 0 "trimmer: ${msg}: exit status"
+
+ num_events=$(wc -l < "${tmp_out}")
+ # Use bash parameter expansion to strip spaces added by BSD 'wc' on macOs and Solaris
+ is "${num_events// /}" 0 "trimmer: ${msg}: number of events (0)"
+
+ stderr="$(cat "${tmp_err}")"
+ # "like" doesn't like when the passed text is empty.
+ if [ -n "${stderr}" ]; then
+ like "${stderr}" "${expected_err_string}" "trimmer: ${msg}: error message"
+ else
+ fail "trimmer: ${msg}: error message"
+ diag "Nothing was output on stderr".
+ fi
+
+}
+
+expect_success 18 "--begin, GMT relative timestamps" \
+ --clock-gmt --begin 17:48:17.587029529
+expect_success 9 "--end, GMT relative timestamps" \
+ --clock-gmt --end 17:48:17.588680018
+expect_success 7 "--begin and --end, GMT relative timestamps" \
+ --clock-gmt --begin 17:48:17.587029529 --end 17:48:17.588680018
+expect_success 0 "--begin, out of range, GMT relative timestamps" \
+ --clock-gmt --begin 18:48:17.587029529
+expect_success 0 "--end, out of range, GMT relative timestamps" \
+ --clock-gmt --end 16:48:17.588680018
+
+expect_success 18 "--begin, GMT absolute timestamps" \
+ --clock-gmt --begin "2012-10-29 17:48:17.587029529"
+expect_success 9 "--end, GMT absolute timestamps" \
+ --clock-gmt --end "2012-10-29 17:48:17.588680018"
+expect_success 7 "--begin and --end, GMT absolute timestamps" \
+ --clock-gmt --begin "2012-10-29 17:48:17.587029529" --end "2012-10-29 17:48:17.588680018"
+expect_success 0 "--begin, out of range, GMT absolute timestamps" \
+ --clock-gmt --begin "2012-10-29 18:48:17.587029529"
+expect_success 0 "--begin, out of range, GMT absolute timestamps" \
+ --clock-gmt --end "2012-10-29 16:48:17.588680018"
+
+# Note here that the POSIX notation is a bit weird.
+# The libc documentation shed some light on this:
+# The offset specifies the time value you must add to the local time to get a
+# Coordinated Universal Time value. It has syntax like [+|-]hh[:mm[:ss]]. This
+# is positive if the local time zone is west of the Prime Meridian and negative
+# if it is east. The hour must be between 0 and 24, and the minute and seconds
+# between 0 and 59. [1]
+#
+# This is why we use EST5 to simulate an effective UTC-5:00 time.
+#
+# [1] https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
+export TZ=EST5
+
+expect_success 18 "--begin, EST relative timestamps" \
+ --begin "12:48:17.587029529"
+expect_success 9 "--end, EST relative timestamps" \
+ --end "12:48:17.588680018"
+expect_success 7 "--begin and --end, EST relative timestamps" \
+ --begin "12:48:17.587029529" --end "12:48:17.588680018"
+expect_success 0 "--begin, out of range, EST relative timestamps" \
+ --begin "13:48:17.587029529"
+expect_success 0 "--end, out of range, EST relative timestamps" \
+ --end "11:48:17.588680018"
+
+expect_success 18 "--begin, EST absolute timestamps" \
+ --begin "2012-10-29 12:48:17.587029529"
+expect_success 9 "--end, EST absolute timestamps" \
+ --end "12:48:17.588680018"
+expect_success 7 "--begin and --end, EST absolute timestamps" \
+ --begin "2012-10-29 12:48:17.587029529" --end "2012-10-29 12:48:17.588680018"
+expect_success 0 "--begin, out of range, EST absolute timestamps" \
+ --begin "2012-10-29 13:48:17.587029529"
+expect_success 0 "--end, out of range, EST absolute timestamps" \
+ --end "2012-10-29 11:48:17.588680018"
+
+# Check various formats.
+#
+# We sometimes apply a clock offset to make the events of the trace span two
+# different seconds or minutes.
+
+expect_success 13 "date time format: partial nanosecond precision" \
+ --begin="2012-10-29 12:48:17.588"
+expect_success 11 "date time format: second precision" \
+ --clock-offset-ns=411282268 --begin="2012-10-29 12:48:18"
+expect_success 11 "date time format: minute precision" \
+ --clock-offset=42 --clock-offset-ns=411282268 --begin="2012-10-29 12:49"
+
+expect_success 11 "seconds from origin format: nanosecond precision" \
+ --begin="1351532897.588717732"
+expect_success 11 "seconds from origin format: partial nanosecond precision" \
+ --begin="1351532897.58871773"
+expect_success 11 "seconds from origin format: second precision" \
+ --clock-offset-ns=411282268 --begin="1351532898"
+
+expect_failure "Invalid date/time format" "date time format: too many nanosecond digits" \
+ --begin="2012-10-29 12:48:17.1231231231"
+expect_failure "Invalid date/time format" "date time format: missing nanoseconds" \
+ --begin="2012-10-29 12:48:17."
+expect_failure "Invalid date/time format" "date time format: seconds with too many digit" \
+ --begin="2012-10-29 12:48:123"
+expect_failure "Invalid date/time format" "date time format: seconds with missing digit" \
+ --begin="2012-10-29 12:48:1"
+expect_failure "Invalid date/time format" "date time format: minutes with too many digit" \
+ --begin="2012-10-29 12:489:17"
+expect_failure "Invalid date/time format" "date time format: minutes with missing digit" \
+ --begin="2012-10-29 12:4:17"
+expect_failure "Invalid date/time format" "date time format: hours with too many digit" \
+ --begin="2012-10-29 123:48:17"
+expect_failure "Invalid date/time format" "date time format: hours with missing digit" \
+ --begin="2012-10-29 2:48:17"
+expect_failure "Invalid date/time format" "date time format: missing seconds" \
+ --begin="2012-10-29 12:48:"
+expect_failure "Invalid date/time format" "date time format: missing minutes 1" \
+ --begin="2012-10-29 12:"
+expect_failure "Invalid date/time format" "date time format: missing minutes 2" \
+ --begin="2012-10-29 12"
+expect_failure "Invalid date/time format" "date time format: missing time" \
+ --begin="2012-10-29 "
+expect_failure "Invalid date/time format" "date time format: day with too many digit" \
+ --begin="2012-10-291"
+expect_failure "Invalid date/time format" "date time format: day with missing digit" \
+ --begin="2012-10-2"
+expect_failure "Invalid date/time format" "date time format: month with too many digit" \
+ --begin="2012-101-29"
+expect_failure "Invalid date/time format" "date time format: month with missing digit" \
+ --begin="2012-1-29"
+expect_failure "Invalid date/time format" "date time format: year with too many digits" \
+ --begin="20121-10-29"
+expect_failure "Invalid date/time format" "date time format: year with missing digits" \
+ --begin="12-10-29"
+expect_failure "Invalid date/time format" "date time format: missing day 1" \
+ --begin="2012-10-"
+expect_failure "Invalid date/time format" "date time format: missing day 2" \
+ --begin="2012-10"
+
+expect_failure "Invalid date/time format" "seconds from origin format: too many nanosecond digits" \
+ --begin="1351532898.1231231231"
+expect_failure "Invalid date/time format" "seconds from origin format: missing nanseconds" \
+ --begin="1351532898."
+
+rm "${tmp_out}" "${tmp_err}"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 EfficiOS Inc.
-#
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-data_dir="$BT_TESTS_DATADIR/cli/exit_status"
-source_name="src.test_exit_status.StatusSrc"
-
-test_interrupted_graph() {
- local cli_args=("--plugin-path=$data_dir" "-c" "$source_name" "-p" "case=\"INTERRUPTED\"")
- local actual_stdout
- local actual_stderr
-
- actual_stdout=$(mktemp -t test_cli_exit_status_stdout_actual.XXXXXX)
- actual_stderr=$(mktemp -t test_cli_exit_status_stderr_actual.XXXXXX)
-
- bt_cli "$actual_stdout" "$actual_stderr" "${cli_args[@]}"
-
- is $? 2 "Interrupted graph exits with status 2"
-
- bt_diff /dev/null "$actual_stdout"
- ok $? "Interrupted graph gives no stdout"
-
- bt_diff /dev/null "$actual_stderr"
- ok $? "Interrupted graph gives no stderr"
-
- rm -f "${actual_stdout}"
- rm -f "${actual_stderr}"
-}
-
-test_error_graph() {
- local cli_args=("--plugin-path=$data_dir" "-c" "$source_name" "-p" "case=\"ERROR\"")
- local actual_stdout
- local actual_stderr
-
- actual_stdout=$(mktemp -t test_cli_exit_status_stdout_actual.XXXXXX)
- actual_stderr=$(mktemp -t test_cli_exit_status_stderr_actual.XXXXXX)
-
- bt_cli "$actual_stdout" "$actual_stderr" "${cli_args[@]}"
-
- is $? 1 "Erroring graph exits with status 1"
-
- bt_diff /dev/null "$actual_stdout"
- ok $? "Erroring graph gives expected stdout"
-
- like "$(cat "${actual_stderr}")" "TypeError: Raising type error" \
- "Erroring graph gives expected error message"
-
- rm -f "${actual_stdout}"
- rm -f "${actual_stderr}"
-}
-
-test_stop_graph() {
- local cli_args=("--plugin-path=$data_dir" "-c" "$source_name" "-p" "case=\"STOP\"")
- local actual_stdout
- local actual_stderr
-
- actual_stdout=$(mktemp -t test_cli_exit_status_stdout_actual.XXXXXX)
- actual_stderr=$(mktemp -t test_cli_exit_status_stderr_actual.XXXXXX)
-
- bt_cli "$actual_stdout" "$actual_stderr" "${cli_args[@]}"
-
- is $? 0 "Successful graph exits with status 0"
-
- bt_diff /dev/null "$actual_stdout"
- ok $? "Successful graph gives no stdout"
-
- bt_diff /dev/null "$actual_stderr"
- ok $? "Successful graph gives no stderr"
-
- rm -f "${actual_stdout}"
- rm -f "${actual_stderr}"
-}
-
-plan_tests 9
-
-test_interrupted_graph
-test_error_graph
-test_stop_graph
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 EfficiOS Inc.
-#
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-plan_tests 21
-
-stdout=$(mktemp -t test_help_stdout.XXXXXX)
-stderr=$(mktemp -t test_help_stderr.XXXXXX)
-
-# Return 0 if file "$1" exists and is empty, non-0 otherwise.
-
-is_empty()
-{
- [[ -f "$1" && ! -s "$1" ]]
-}
-
-# Test with a working plugin name.
-bt_cli "${stdout}" "${stderr}" help ctf
-ok $? "help ctf plugin exit status"
-
-grep --silent 'Description: CTF input and output' "${stdout}"
-ok $? "help ctf plugin expected output"
-
-is_empty "${stderr}"
-ok $? "help ctf plugin produces no error"
-
-# Test with a working component class name.
-bt_cli "${stdout}" "${stderr}" help src.ctf.fs
-ok $? "help src.ctf.fs component class exit status"
-
-grep --silent 'Description: Read CTF traces from the file system.' "${stdout}"
-ok $? "help src.ctf.fs component class expected output"
-
-is_empty "${stderr}"
-ok $? "help src.ctf.fs component class produces no error"
-
-# Test without parameter.
-bt_cli "${stdout}" "${stderr}" help
-isnt $? 0 "help without parameter exit status"
-
-grep --silent "Missing plugin name or component class descriptor." "${stderr}"
-ok $? "help without parameter produces expected error"
-
-is_empty "${stdout}"
-ok $? "help without parameter produces no output"
-
-# Test with too many parameters.
-bt_cli "${stdout}" "${stderr}" help ctf fs
-isnt $? 0 "help with too many parameters exit status"
-
-grep --silent "Extraneous command-line argument specified to \`help\` command:" "${stderr}"
-ok $? "help with too many parameters produces expected error"
-
-is_empty "${stdout}"
-ok $? "help with too many parameters produces no output"
-
-# Test with unknown plugin name.
-bt_cli "${stdout}" "${stderr}" help zigotos
-isnt $? 0 "help with unknown plugin name"
-
-grep --silent 'Cannot find plugin: plugin-name="zigotos"' "${stderr}"
-ok $? "help with unknown plugin name produces expected error"
-
-is_empty "${stdout}"
-ok $? "help with unknown plugin name produces no output"
-
-# Test with unknown component class name (but known plugin).
-bt_cli "${stdout}" "${stderr}" help src.ctf.bob
-isnt $? 0 "help with unknown component class name"
-
-grep --silent 'Cannot find component class: plugin-name="ctf", comp-cls-name="bob", comp-cls-type=SOURCE' "${stderr}"
-ok $? "help with unknown component class name produces expected error"
-
-grep --silent 'Description: CTF input and output' "${stdout}"
-ok $? "help with unknown component class name prints plugin help"
-
-# Test with unknown component class plugin
-bt_cli "${stdout}" "${stderr}" help src.bob.fs
-isnt $? 0 "help with unknown component class plugin"
-
-grep --silent 'Cannot find plugin: plugin-name="bob"' "${stderr}"
-ok $? "help with unknown component class plugin produces expected error"
-
-is_empty "${stdout}"
-ok $? "help with unknown component class plugin produces no output"
-
-rm -f "${stdout}" "${stderr}"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2015 Julien Desfossez <jdesfossez@efficios.com>
-#
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-plan_tests 20
-
-stdout=$(mktemp -t test_intersection_stdout.XXXXXX)
-stderr=$(mktemp -t test_intersection_stderr.XXXXXX)
-
-test_intersect() {
- local trace="$1"
- local totalevents="$2"
- local intersect="$3"
-
- local cnt
-
- bt_cli "${stdout}" "/dev/null" "${trace}"
- ok $? "run without --stream-intersection"
-
- cnt=$(wc -l < "${stdout}")
- test "${cnt// /}" = "$totalevents"
- ok $? "$totalevents events in the whole trace"
-
- bt_cli "${stdout}" "/dev/null" --stream-intersection "${trace}"
- ok $? "run with --stream-intersection"
-
- cnt=$(wc -l < "${stdout}")
- test "${cnt// /}" = "$intersect"
- ok $? "$intersect events in streams intersecting"
-}
-
-test_intersect_fails() {
- local trace="$1"
- local totalevents="$2"
- local expected_error_message="$3"
-
- bt_cli "${stdout}" "/dev/null" "${trace}"
- ok $? "run without --stream-intersection"
-
- cnt=$(wc -l < "${stdout}")
- test "${cnt// /}" = "$totalevents"
- ok $? "$totalevents events in the whole trace"
-
- bt_cli "${stdout}" "${stderr}" --stream-intersection "${trace}"
- isnt "$?" 0 "run with --stream-intersection fails"
-
- grep --silent "${expected_error_message}" "${stderr}"
- ok $? "stderr contains expected error message"
-}
-
-diag "Test the stream intersection feature"
-
-diag "2 streams offsetted with 3 packets intersecting"
-test_intersect "${BT_CTF_TRACES_PATH}/intersection/3eventsintersect" 8 3
-
-diag "2 streams offsetted with 3 packets intersecting (exchanged file names)"
-test_intersect "${BT_CTF_TRACES_PATH}/intersection/3eventsintersectreverse" 8 3
-
-diag "Only 1 stream"
-test_intersect "${BT_CTF_TRACES_PATH}/intersection/onestream" 3 3
-
-diag "No intersection between 2 streams"
-test_intersect_fails "${BT_CTF_TRACES_PATH}/intersection/nointersect" 6 \
- "Trimming time range's beginning time is greater than end time: "
-
-diag "No stream at all"
-test_intersect_fails "${BT_CTF_TRACES_PATH}/intersection/nostream" 0 \
- "Trace has no streams: "
-
-rm -f "${stdout}" "${stderr}"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-NUM_TESTS=3
-
-plan_tests $NUM_TESTS
-
-tmp_metadata=$(mktemp)
-
-# Test a valid trace directory.
-"${BT_TESTS_BT2_BIN}" -o ctf-metadata "${BT_CTF_TRACES_PATH}/succeed/wk-heartbeat-u" > "$tmp_metadata"
-ok $? "Run babeltrace -o ctf-metadata with a valid trace directory, correct exit status"
-
-bt_diff "${BT_TESTS_DATADIR}/cli/test_output_ctf_metadata.ref" "$tmp_metadata"
-ok $? "Run babeltrace -o ctf-metadata with a valid trace directory, correct output"
-
-# Test an invalid trace directory.
-"${BT_TESTS_BT2_BIN}" -o ctf-metadata "${BT_CTF_TRACES_PATH}" >/dev/null 2>&1
-isnt $? 0 "Run babeltrace -o ctf-metadata with an invalid trace directory, expecting failure"
-
-rm -f "$tmp_metadata"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) EfficiOS Inc.
-#
-
-# This test verifies that generic (non-LTTng) CTF traces are output with the
-# expected directory structure.
-#
-# Traces found when invoking
-#
-# babeltrace2 in -c sink.ctf.fs -p 'path="out"'
-#
-# are expected to use the same directory structure relative to `out` as the
-# original traces had relative to `in`.
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-plan_tests 3
-
-temp_input_dir=$(mktemp -t -d test_output_path_ctf_non_lttng_trace_input.XXXXXX)
-temp_output_dir=$(mktemp -t -d test_output_path_ctf_non_lttng_trace_output.XXXXXX)
-
-mkdir -p "${temp_input_dir}/a/b/c"
-cp -a "${BT_CTF_TRACES_PATH}/intersection/3eventsintersect" "${temp_input_dir}/a/b/c"
-
-mkdir -p "${temp_input_dir}/a/b/c"
-cp -a "${BT_CTF_TRACES_PATH}/intersection/3eventsintersectreverse" "${temp_input_dir}/a/b/c"
-
-mkdir -p "${temp_input_dir}/d/e/f"
-cp -a "${BT_CTF_TRACES_PATH}/intersection/nointersect" "${temp_input_dir}/d/e/f"
-
-bt_cli "/dev/null" "/dev/null" "${temp_input_dir}" -c sink.ctf.fs -p "path=\"${temp_output_dir}\""
-
-test -f "${temp_output_dir}/a/b/c/3eventsintersect/metadata"
-ok "$?" "3eventsintersect output trace exists"
-
-test -f "${temp_output_dir}/a/b/c/3eventsintersectreverse/metadata"
-ok "$?" "3eventsintersectreverse output trace exists"
-
-test -f "${temp_output_dir}/d/e/f/nointersect/metadata"
-ok "$?" "nointersect output trace exists"
-
-rm -rf "${temp_input_dir}" "${temp_output_dir}"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2015 Julien Desfossez <jdesfossez@efficios.com>
-#
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-NUM_TESTS=10
-
-plan_tests $NUM_TESTS
-
-test_no_lost() {
- local trace=$1
-
- "${BT_TESTS_BT2_BIN}" "$trace" >/dev/null 2>&1
- ok $? "Trace parses"
- "${BT_TESTS_BT2_BIN}" "$trace" 2>&1 >/dev/null | "${BT_TESTS_GREP_BIN}" "\[warning\] Tracer lost"
- if test $? = 0; then
- fail 1 "Should not find any lost events"
- else
- ok 0 "No events lost"
- fi
-}
-
-test_lost() {
- local trace=$1
- local expectedcountstr=$2
-
- "${BT_TESTS_BT2_BIN}" "$trace" >/dev/null 2>&1
- ok $? "Trace parses"
-
- # Convert warnings like:
- # WARNING: Tracer discarded 2 trace packets between ....
- # WARNING: Tracer discarded 3 trace packets between ....
- # into "2,3" and make sure it matches the expected result
- "${BT_TESTS_BT2_BIN}" "$trace" 2>&1 >/dev/null | "${BT_TESTS_GREP_BIN}" "WARNING: Tracer discarded" \
- | cut -d" " -f4 | tr "\n" "," | "${BT_TESTS_SED_BIN}" "s/.$//" | \
- "${BT_TESTS_GREP_BIN}" "$expectedcountstr" >/dev/null
- ok $? "Lost events string matches $expectedcountstr"
-
-}
-
-diag "Test the packet_seq_num validation"
-
-diag "No packet lost"
-test_no_lost "${BT_CTF_TRACES_PATH}/packet_seq_num/no_lost"
-
-diag "No packet lost, packet_seq_num not starting at 0"
-test_no_lost "${BT_CTF_TRACES_PATH}/packet_seq_num/no_lost_not_starting_at_0"
-
-diag "1 stream, 2 packets lost before the last packet"
-test_lost "${BT_CTF_TRACES_PATH}/packet_seq_num/2_lost_before_last" "2"
-
-diag "2 streams, packets lost in one of them"
-test_lost "${BT_CTF_TRACES_PATH}/packet_seq_num/2_streams_lost_in_1" "2"
-
-diag "2 streams, packets lost in both"
-test_lost "${BT_CTF_TRACES_PATH}/packet_seq_num/2_streams_lost_in_2" "2,3,1"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com>
-#
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-clean_tmp() {
- rm -rf "${out_path}" "${text_output1}" "${text_output2_intermediary}" "${text_output2}"
-}
-
-SUCCESS_TRACES=("${BT_CTF_TRACES_PATH}/succeed/"*)
-
-# -4 because there are two empty traces that we skip
-NUM_TESTS=$((${#SUCCESS_TRACES[@]} * 3 - 4))
-
-plan_tests $NUM_TESTS
-
-for path in "${SUCCESS_TRACES[@]}"; do
- out_path="$(mktemp -d)"
- text_output1="$(mktemp)"
- text_output2_intermediary="$(mktemp)"
- text_output2="$(mktemp)"
- trace="$(basename "${path}")"
- sort_cmd="cat" # by default do not sort the trace
-
- bt_cli "${text_output1}" "/dev/null" --no-delta "${path}"
- ret=$?
- cnt="$(wc -l < "${text_output1}")"
- if test "$ret" == 0 && test "${cnt// /}" == 0; then
- pass "Empty trace ${trace}, nothing to copy"
- clean_tmp
- continue
- fi
-
- # If the trace has a timestamp (starts with [), check if there are
- # duplicate timestamps in the output.
- # If there are, we have to sort the text output to make sure it is
- # always the same.
- head -1 "${text_output1}" | "${BT_TESTS_GREP_BIN}" "^\[" >/dev/null
- if test $? = 0; then
- # shellcheck disable=SC2016
- uniq_ts_cnt="$("${BT_TESTS_AWK_BIN}" '{ print $1 }' < "${text_output1}" | sort | uniq | wc -l)"
- # Extract only the timestamp columns and compare the number of
- # unique lines with the total number of lines to see if there
- # are duplicate timestamps.
- if test "${cnt// /}" != "${uniq_ts_cnt// /}"; then
- diag "Trace with non unique timestamps, sorting the output"
- sort_cmd="sort"
- tmp="$(mktemp)"
- sort "${text_output1}" > "$tmp"
- rm "${text_output1}"
- text_output1="$tmp"
- fi
- fi
-
- bt_cli "/dev/null" "/dev/null" "${path}" --component sink.ctf.fs "--params=path=\"${out_path}\""
- ok $? "Copy trace ${trace} with ctf-fs sink"
-
- bt_cli "/dev/null" "/dev/null" "${out_path}"
- ok $? "Read the new trace in ${out_path}"
-
- bt_cli "${text_output2_intermediary}" "/dev/null" --no-delta "${out_path}"
- $sort_cmd "${text_output2_intermediary}" > "${text_output2}"
- cnt=$(diff "${text_output1}" "${text_output2}" | wc -l)
- test "${cnt// /}" == 0
- ok $? "Exact same content between the two traces"
-
- clean_tmp
-done
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2013 Christian Babeux <christian.babeux@efficios.com>
-#
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-SUCCESS_TRACES=("${BT_CTF_TRACES_PATH}/succeed/"*)
-FAIL_TRACES=("${BT_CTF_TRACES_PATH}/fail/"*)
-
-NUM_TESTS=$((${#SUCCESS_TRACES[@]} + ${#FAIL_TRACES[@]}))
-
-plan_tests $NUM_TESTS
-
-for path in "${SUCCESS_TRACES[@]}"; do
- trace=$(basename "${path}")
- "${BT_TESTS_BT2_BIN}" "${path}" > /dev/null 2>&1
- ok $? "Run babeltrace2 with trace ${trace}"
-done
-
-for path in "${FAIL_TRACES[@]}"; do
- trace=$(basename "${path}")
- if "${BT_TESTS_BT2_BIN}" "${path}" > /dev/null 2>&1; then
- fail "Run babeltrace2 with invalid trace ${trace}"
- else
- pass "Run babeltrace2 with invalid trace ${trace}"
- fi
-done
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2017 Julien Desfossez <jdesfossez@efficios.com>
-#
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-TRACE_PATH="${BT_CTF_TRACES_PATH}/succeed/wk-heartbeat-u/"
-
-NUM_TESTS=118
-
-plan_tests $NUM_TESTS
-
-tmp_out=$(mktemp)
-tmp_err=$(mktemp)
-
-
-# Run Babeltrace with some command line arguments, verify exit status and
-# number of output events (i.e. number of output lines)
-#
-# Arguments:
-#
-# $1: expected number of events
-# $2: test description
-# remaining arguments: command-line arguments to pass to Babeltrace
-
-function expect_success()
-{
- local expected_num_events="$1"
- local msg="$2"
- shift 2
-
- bt_cli "${tmp_out}" /dev/null "${TRACE_PATH}" "$@"
- ok $? "trimmer: ${msg}: exit status"
-
- num_events=$(wc -l < "${tmp_out}")
- # Use bash parameter expansion to strip spaces added by BSD 'wc' on macOs and Solaris
- is "${num_events// /}" "${expected_num_events}" "trimmer: ${msg}: number of events (${expected_num_events})"
-}
-
-# Run Babeltrace with some command line arguments, verify that the exit status
-# is not 0 and that the error message contains a given string.
-#
-# Arguments:
-#
-# $1: a string expected to be found in the error message
-# $2: test description
-# remaining arguments: command-line arguments to pass to Babeltrace
-
-function expect_failure()
-{
- local expected_err_string="$1"
- local msg="$2"
- shift 2
-
- # We check the error message logged by the trimmer plugin, set the env
- # var necessary for it to log errors.
- BABELTRACE_FLT_UTILS_TRIMMER_LOG_LEVEL=E bt_cli "${tmp_out}" "${tmp_err}" "${TRACE_PATH}" "$@"
- isnt $? 0 "trimmer: ${msg}: exit status"
-
- num_events=$(wc -l < "${tmp_out}")
- # Use bash parameter expansion to strip spaces added by BSD 'wc' on macOs and Solaris
- is "${num_events// /}" 0 "trimmer: ${msg}: number of events (0)"
-
- stderr="$(cat "${tmp_err}")"
- # "like" doesn't like when the passed text is empty.
- if [ -n "${stderr}" ]; then
- like "${stderr}" "${expected_err_string}" "trimmer: ${msg}: error message"
- else
- fail "trimmer: ${msg}: error message"
- diag "Nothing was output on stderr".
- fi
-
-}
-
-expect_success 18 "--begin, GMT relative timestamps" \
- --clock-gmt --begin 17:48:17.587029529
-expect_success 9 "--end, GMT relative timestamps" \
- --clock-gmt --end 17:48:17.588680018
-expect_success 7 "--begin and --end, GMT relative timestamps" \
- --clock-gmt --begin 17:48:17.587029529 --end 17:48:17.588680018
-expect_success 0 "--begin, out of range, GMT relative timestamps" \
- --clock-gmt --begin 18:48:17.587029529
-expect_success 0 "--end, out of range, GMT relative timestamps" \
- --clock-gmt --end 16:48:17.588680018
-
-expect_success 18 "--begin, GMT absolute timestamps" \
- --clock-gmt --begin "2012-10-29 17:48:17.587029529"
-expect_success 9 "--end, GMT absolute timestamps" \
- --clock-gmt --end "2012-10-29 17:48:17.588680018"
-expect_success 7 "--begin and --end, GMT absolute timestamps" \
- --clock-gmt --begin "2012-10-29 17:48:17.587029529" --end "2012-10-29 17:48:17.588680018"
-expect_success 0 "--begin, out of range, GMT absolute timestamps" \
- --clock-gmt --begin "2012-10-29 18:48:17.587029529"
-expect_success 0 "--begin, out of range, GMT absolute timestamps" \
- --clock-gmt --end "2012-10-29 16:48:17.588680018"
-
-# Note here that the POSIX notation is a bit weird.
-# The libc documentation shed some light on this:
-# The offset specifies the time value you must add to the local time to get a
-# Coordinated Universal Time value. It has syntax like [+|-]hh[:mm[:ss]]. This
-# is positive if the local time zone is west of the Prime Meridian and negative
-# if it is east. The hour must be between 0 and 24, and the minute and seconds
-# between 0 and 59. [1]
-#
-# This is why we use EST5 to simulate an effective UTC-5:00 time.
-#
-# [1] https://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
-export TZ=EST5
-
-expect_success 18 "--begin, EST relative timestamps" \
- --begin "12:48:17.587029529"
-expect_success 9 "--end, EST relative timestamps" \
- --end "12:48:17.588680018"
-expect_success 7 "--begin and --end, EST relative timestamps" \
- --begin "12:48:17.587029529" --end "12:48:17.588680018"
-expect_success 0 "--begin, out of range, EST relative timestamps" \
- --begin "13:48:17.587029529"
-expect_success 0 "--end, out of range, EST relative timestamps" \
- --end "11:48:17.588680018"
-
-expect_success 18 "--begin, EST absolute timestamps" \
- --begin "2012-10-29 12:48:17.587029529"
-expect_success 9 "--end, EST absolute timestamps" \
- --end "12:48:17.588680018"
-expect_success 7 "--begin and --end, EST absolute timestamps" \
- --begin "2012-10-29 12:48:17.587029529" --end "2012-10-29 12:48:17.588680018"
-expect_success 0 "--begin, out of range, EST absolute timestamps" \
- --begin "2012-10-29 13:48:17.587029529"
-expect_success 0 "--end, out of range, EST absolute timestamps" \
- --end "2012-10-29 11:48:17.588680018"
-
-# Check various formats.
-#
-# We sometimes apply a clock offset to make the events of the trace span two
-# different seconds or minutes.
-
-expect_success 13 "date time format: partial nanosecond precision" \
- --begin="2012-10-29 12:48:17.588"
-expect_success 11 "date time format: second precision" \
- --clock-offset-ns=411282268 --begin="2012-10-29 12:48:18"
-expect_success 11 "date time format: minute precision" \
- --clock-offset=42 --clock-offset-ns=411282268 --begin="2012-10-29 12:49"
-
-expect_success 11 "seconds from origin format: nanosecond precision" \
- --begin="1351532897.588717732"
-expect_success 11 "seconds from origin format: partial nanosecond precision" \
- --begin="1351532897.58871773"
-expect_success 11 "seconds from origin format: second precision" \
- --clock-offset-ns=411282268 --begin="1351532898"
-
-expect_failure "Invalid date/time format" "date time format: too many nanosecond digits" \
- --begin="2012-10-29 12:48:17.1231231231"
-expect_failure "Invalid date/time format" "date time format: missing nanoseconds" \
- --begin="2012-10-29 12:48:17."
-expect_failure "Invalid date/time format" "date time format: seconds with too many digit" \
- --begin="2012-10-29 12:48:123"
-expect_failure "Invalid date/time format" "date time format: seconds with missing digit" \
- --begin="2012-10-29 12:48:1"
-expect_failure "Invalid date/time format" "date time format: minutes with too many digit" \
- --begin="2012-10-29 12:489:17"
-expect_failure "Invalid date/time format" "date time format: minutes with missing digit" \
- --begin="2012-10-29 12:4:17"
-expect_failure "Invalid date/time format" "date time format: hours with too many digit" \
- --begin="2012-10-29 123:48:17"
-expect_failure "Invalid date/time format" "date time format: hours with missing digit" \
- --begin="2012-10-29 2:48:17"
-expect_failure "Invalid date/time format" "date time format: missing seconds" \
- --begin="2012-10-29 12:48:"
-expect_failure "Invalid date/time format" "date time format: missing minutes 1" \
- --begin="2012-10-29 12:"
-expect_failure "Invalid date/time format" "date time format: missing minutes 2" \
- --begin="2012-10-29 12"
-expect_failure "Invalid date/time format" "date time format: missing time" \
- --begin="2012-10-29 "
-expect_failure "Invalid date/time format" "date time format: day with too many digit" \
- --begin="2012-10-291"
-expect_failure "Invalid date/time format" "date time format: day with missing digit" \
- --begin="2012-10-2"
-expect_failure "Invalid date/time format" "date time format: month with too many digit" \
- --begin="2012-101-29"
-expect_failure "Invalid date/time format" "date time format: month with missing digit" \
- --begin="2012-1-29"
-expect_failure "Invalid date/time format" "date time format: year with too many digits" \
- --begin="20121-10-29"
-expect_failure "Invalid date/time format" "date time format: year with missing digits" \
- --begin="12-10-29"
-expect_failure "Invalid date/time format" "date time format: missing day 1" \
- --begin="2012-10-"
-expect_failure "Invalid date/time format" "date time format: missing day 2" \
- --begin="2012-10"
-
-expect_failure "Invalid date/time format" "seconds from origin format: too many nanosecond digits" \
- --begin="1351532898.1231231231"
-expect_failure "Invalid date/time format" "seconds from origin format: missing nanseconds" \
- --begin="1351532898."
-
-rm "${tmp_out}" "${tmp_err}"
AM_CPPFLAGS += -I$(top_srcdir)/tests/utils
-noinst_PROGRAMS = ctf_writer
+noinst_PROGRAMS = ctf-writer
-ctf_writer_SOURCES = ctf_writer.c
+ctf_writer_SOURCES = ctf-writer.c
ctf_writer_LDADD = \
$(top_builddir)/tests/utils/tap/libtap.la \
$(top_builddir)/tests/utils/libtestcommon.la \
$(top_builddir)/src/logging/liblogging.la
-dist_check_SCRIPTS = test_ctf_writer
+dist_check_SCRIPTS = test-ctf-writer.sh
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2013-2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ */
+
+#include <babeltrace2-ctf-writer/writer.h>
+#include <babeltrace2-ctf-writer/clock.h>
+#include <babeltrace2-ctf-writer/clock-class.h>
+#include <babeltrace2-ctf-writer/stream.h>
+#include <babeltrace2-ctf-writer/event.h>
+#include <babeltrace2-ctf-writer/event-types.h>
+#include <babeltrace2-ctf-writer/event-fields.h>
+#include <babeltrace2-ctf-writer/stream-class.h>
+#include <babeltrace2-ctf-writer/trace.h>
+#include <babeltrace2/babeltrace.h>
+#include <glib.h>
+#include <unistd.h>
+#include "compat/stdlib.h"
+#include <stdio.h>
+#include "compat/limits.h"
+#include "compat/stdio.h"
+#include <string.h>
+#include "common/assert.h"
+#include "common/uuid.h"
+#include <fcntl.h>
+#include "tap/tap.h"
+#include <math.h>
+#include <float.h>
+#include "common.h"
+
+#ifdef __FreeBSD__
+/* Required for WIFEXITED and WEXITSTATUS */
+#include <sys/wait.h>
+#endif
+
+#define METADATA_LINE_SIZE 512
+#define SEQUENCE_TEST_LENGTH 10
+#define ARRAY_TEST_LENGTH 5
+#define PACKET_RESIZE_TEST_DEF_LENGTH 100000
+
+#define DEFAULT_CLOCK_FREQ 1000000000
+#define DEFAULT_CLOCK_PRECISION 1
+#define DEFAULT_CLOCK_OFFSET 0
+#define DEFAULT_CLOCK_OFFSET_S 0
+#define DEFAULT_CLOCK_IS_ABSOLUTE 0
+#define DEFAULT_CLOCK_TIME 0
+#define DEFAULT_CLOCK_VALUE 0
+
+#define NR_TESTS 325
+
+struct bt_utsname {
+ char sysname[BABELTRACE_HOST_NAME_MAX];
+ char nodename[BABELTRACE_HOST_NAME_MAX];
+ char release[BABELTRACE_HOST_NAME_MAX];
+ char version[BABELTRACE_HOST_NAME_MAX];
+ char machine[BABELTRACE_HOST_NAME_MAX];
+};
+
+static int64_t current_time = 42;
+static unsigned int packet_resize_test_length = PACKET_RESIZE_TEST_DEF_LENGTH;
+
+/* Return 1 if uuids match, zero if different. */
+static
+int uuid_match(const uint8_t *uuid_a, const uint8_t *uuid_b)
+{
+ int ret = 0;
+ int i;
+
+ if (!uuid_a || !uuid_b) {
+ goto end;
+ }
+
+ for (i = 0; i < 16; i++) {
+ if (uuid_a[i] != uuid_b[i]) {
+ goto end;
+ }
+ }
+
+ ret = 1;
+end:
+ return ret;
+}
+
+static
+void validate_trace(char *parser_path, char *trace_path)
+{
+ int ret = 0;
+ gint exit_status;
+ const char *argv[] = {parser_path, trace_path, "-o", "dummy", NULL};
+
+ if (!parser_path || !trace_path) {
+ ret = -1;
+ goto result;
+ }
+
+ if (!g_spawn_sync(NULL,
+ (gchar **) argv,
+ NULL,
+ G_SPAWN_STDOUT_TO_DEV_NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ &exit_status,
+ NULL)) {
+ diag("Failed to spawn babeltrace.");
+ ret = -1;
+ goto result;
+ }
+
+ /* Replace by g_spawn_check_exit_status when we require glib >= 2.34 */
+#ifdef G_OS_UNIX
+ ret = WIFEXITED(exit_status) ? WEXITSTATUS(exit_status) : -1;
+#else
+ ret = exit_status;
+#endif
+
+ if (ret != 0) {
+ diag("Babeltrace returned an error.");
+ goto result;
+ }
+
+result:
+ ok(ret == 0, "Babeltrace could read the resulting trace");
+}
+
+static
+void append_simple_event(struct bt_ctf_stream_class *stream_class,
+ struct bt_ctf_stream *stream, struct bt_ctf_clock *clock)
+{
+ /* Create and add a simple event class */
+ struct bt_ctf_event_class *simple_event_class =
+ bt_ctf_event_class_create("Simple Event");
+ struct bt_ctf_field_type *uint_12_type =
+ bt_ctf_field_type_integer_create(12);
+ struct bt_ctf_field_type *int_64_type =
+ bt_ctf_field_type_integer_create(64);
+ struct bt_ctf_field_type *float_type =
+ bt_ctf_field_type_floating_point_create();
+ struct bt_ctf_field_type *enum_type;
+ struct bt_ctf_field_type *enum_type_unsigned =
+ bt_ctf_field_type_enumeration_create(uint_12_type);
+ struct bt_ctf_field_type *event_context_type =
+ bt_ctf_field_type_structure_create();
+ struct bt_ctf_field_type *event_payload_type = NULL;
+ struct bt_ctf_field_type *returned_type;
+ struct bt_ctf_event *simple_event;
+ struct bt_ctf_field *integer_field;
+ struct bt_ctf_field *float_field;
+ struct bt_ctf_field *enum_field;
+ struct bt_ctf_field *enum_field_unsigned;
+ struct bt_ctf_field *enum_container_field;
+ const char *mapping_name_test = "truie";
+ const double double_test_value = 3.1415;
+ struct bt_ctf_field *enum_container_field_unsigned;
+ const char *mapping_name_negative_test = "negative_value";
+ const char *ret_char;
+ double ret_double;
+ int64_t ret_range_start_int64_t, ret_range_end_int64_t;
+ uint64_t ret_range_start_uint64_t, ret_range_end_uint64_t;
+ struct bt_ctf_event_class *ret_event_class;
+ struct bt_ctf_field *packet_context;
+ struct bt_ctf_field *packet_context_field;
+ struct bt_ctf_field *stream_event_context;
+ struct bt_ctf_field *stream_event_context_field;
+ struct bt_ctf_field *event_context;
+ struct bt_ctf_field *event_context_field;
+ struct bt_ctf_field_type *ep_integer_field_type = NULL;
+ struct bt_ctf_field_type *ep_enum_field_type = NULL;
+ struct bt_ctf_field_type *ep_enum_field_unsigned_type = NULL;
+ struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
+ int ret;
+
+ ok(uint_12_type, "Create an unsigned integer type");
+
+ ok(!bt_ctf_field_type_integer_set_signed(int_64_type, 1),
+ "Set signed 64 bit integer signedness to true");
+ ok(int_64_type, "Create a signed integer type");
+ enum_type = bt_ctf_field_type_enumeration_create(int_64_type);
+
+ returned_type = bt_ctf_field_type_enumeration_get_container_field_type(enum_type);
+ ok(returned_type == int_64_type, "bt_ctf_field_type_enumeration_get_container_field_type returns the right type");
+ ok(!bt_ctf_field_type_enumeration_create(enum_type),
+ "bt_ctf_field_enumeration_type_create rejects non-integer container field types");
+ bt_ctf_object_put_ref(returned_type);
+
+ bt_ctf_field_type_set_alignment(float_type, 32);
+ ok(bt_ctf_field_type_get_alignment(float_type) == 32,
+ "bt_ctf_field_type_get_alignment returns a correct value");
+
+ ok(bt_ctf_field_type_floating_point_set_exponent_digits(float_type, 11) == 0,
+ "Set a floating point type's exponent digit count");
+ ok(bt_ctf_field_type_floating_point_set_mantissa_digits(float_type, 53) == 0,
+ "Set a floating point type's mantissa digit count");
+
+ ok(bt_ctf_field_type_floating_point_get_exponent_digits(float_type) == 11,
+ "bt_ctf_field_type_floating_point_get_exponent_digits returns the correct value");
+ ok(bt_ctf_field_type_floating_point_get_mantissa_digits(float_type) == 53,
+ "bt_ctf_field_type_floating_point_get_mantissa_digits returns the correct value");
+
+ ok(bt_ctf_field_type_enumeration_add_mapping(enum_type,
+ mapping_name_negative_test, -12345, 0) == 0,
+ "bt_ctf_field_type_enumeration_add_mapping accepts negative enumeration mappings");
+ ok(bt_ctf_field_type_enumeration_add_mapping(enum_type,
+ "escaping; \"test\"", 1, 1) == 0,
+ "bt_ctf_field_type_enumeration_add_mapping accepts enumeration mapping strings containing quotes");
+ ok(bt_ctf_field_type_enumeration_add_mapping(enum_type,
+ "\tanother \'escaping\'\n test\"", 2, 4) == 0,
+ "bt_ctf_field_type_enumeration_add_mapping accepts enumeration mapping strings containing special characters");
+ ok(bt_ctf_field_type_enumeration_add_mapping(enum_type,
+ "event clock int float", 5, 22) == 0,
+ "Accept enumeration mapping strings containing reserved keywords");
+ bt_ctf_field_type_enumeration_add_mapping(enum_type, mapping_name_test,
+ 42, 42);
+ ok(bt_ctf_field_type_enumeration_add_mapping(enum_type, mapping_name_test,
+ 43, 51) == 0, "bt_ctf_field_type_enumeration_add_mapping accepts duplicate mapping names");
+ ok(bt_ctf_field_type_enumeration_add_mapping(enum_type, "something",
+ -500, -400) == 0, "bt_ctf_field_type_enumeration_add_mapping accepts overlapping enum entries");
+ ok(bt_ctf_field_type_enumeration_add_mapping(enum_type, mapping_name_test,
+ -54, -55), "bt_ctf_field_type_enumeration_add_mapping rejects mapping where end < start");
+ bt_ctf_field_type_enumeration_add_mapping(enum_type, "another entry", -42000, -13000);
+
+ ok(bt_ctf_event_class_add_field(simple_event_class, enum_type,
+ "enum_field") == 0, "Add signed enumeration field to event");
+
+ ok(bt_ctf_field_type_enumeration_signed_get_mapping_by_index(enum_type, 0, NULL,
+ &ret_range_start_int64_t, &ret_range_end_int64_t) == 0,
+ "bt_ctf_field_type_enumeration_signed_get_mapping_by_index handles a NULL string correctly");
+ ok(bt_ctf_field_type_enumeration_signed_get_mapping_by_index(enum_type, 0, &ret_char,
+ NULL, &ret_range_end_int64_t) == 0,
+ "bt_ctf_field_type_enumeration_signed_get_mapping_by_index handles a NULL start correctly");
+ ok(bt_ctf_field_type_enumeration_signed_get_mapping_by_index(enum_type, 0, &ret_char,
+ &ret_range_start_int64_t, NULL) == 0,
+ "bt_ctf_field_type_enumeration_signed_get_mapping_by_index handles a NULL end correctly");
+ /* Assumes entries are sorted by range_start values. */
+ ok(bt_ctf_field_type_enumeration_signed_get_mapping_by_index(enum_type, 6, &ret_char,
+ &ret_range_start_int64_t, &ret_range_end_int64_t) == 0,
+ "bt_ctf_field_type_enumeration_signed_get_mapping_by_index returns a value");
+ ok(strcmp(ret_char, mapping_name_test) == 0,
+ "bt_ctf_field_type_enumeration_signed_get_mapping_by_index returns a correct mapping name");
+ ok(ret_range_start_int64_t == 42,
+ "bt_ctf_field_type_enumeration_signed_get_mapping_by_index returns a correct mapping start");
+ ok(ret_range_end_int64_t == 42,
+ "bt_ctf_field_type_enumeration_signed_get_mapping_by_index returns a correct mapping end");
+
+ ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned,
+ "escaping; \"test\"", 0, 0) == 0,
+ "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts enumeration mapping strings containing quotes");
+ ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned,
+ "\tanother \'escaping\'\n test\"", 1, 4) == 0,
+ "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts enumeration mapping strings containing special characters");
+ ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned,
+ "event clock int float", 5, 22) == 0,
+ "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts enumeration mapping strings containing reserved keywords");
+ ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned, mapping_name_test,
+ 42, 42) == 0, "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts single-value ranges");
+ ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned, mapping_name_test,
+ 43, 51) == 0, "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts duplicate mapping names");
+ ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned, "something",
+ 7, 8) == 0, "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts overlapping enum entries");
+ ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned, mapping_name_test,
+ 55, 54), "bt_ctf_field_type_enumeration_unsigned_add_mapping rejects mapping where end < start");
+ ok(bt_ctf_event_class_add_field(simple_event_class, enum_type_unsigned,
+ "enum_field_unsigned") == 0, "Add unsigned enumeration field to event");
+
+ ok(bt_ctf_field_type_enumeration_get_mapping_count(enum_type_unsigned) == 6,
+ "bt_ctf_field_type_enumeration_get_mapping_count returns the correct value");
+
+ ok(bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index(enum_type_unsigned, 0, NULL,
+ &ret_range_start_uint64_t, &ret_range_end_uint64_t) == 0,
+ "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index handles a NULL string correctly");
+ ok(bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index(enum_type_unsigned, 0, &ret_char,
+ NULL, &ret_range_end_uint64_t) == 0,
+ "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index handles a NULL start correctly");
+ ok(bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index(enum_type_unsigned, 0, &ret_char,
+ &ret_range_start_uint64_t, NULL) == 0,
+ "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index handles a NULL end correctly");
+ ok(bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index(enum_type_unsigned, 4, &ret_char,
+ &ret_range_start_uint64_t, &ret_range_end_uint64_t) == 0,
+ "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index returns a value");
+ ok(strcmp(ret_char, mapping_name_test) == 0,
+ "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index returns a correct mapping name");
+ ok(ret_range_start_uint64_t == 42,
+ "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index returns a correct mapping start");
+ ok(ret_range_end_uint64_t == 42,
+ "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index returns a correct mapping end");
+
+ bt_ctf_event_class_add_field(simple_event_class, uint_12_type,
+ "integer_field");
+ bt_ctf_event_class_add_field(simple_event_class, float_type,
+ "float_field");
+
+ ret = bt_ctf_event_class_set_id(simple_event_class, 13);
+ BT_ASSERT(ret == 0);
+
+ /* Set an event context type which will contain a single integer. */
+ ok(!bt_ctf_field_type_structure_add_field(event_context_type, uint_12_type,
+ "event_specific_context"),
+ "Add event specific context field");
+
+ ok(bt_ctf_event_class_set_context_field_type(NULL, event_context_type) < 0,
+ "bt_ctf_event_class_set_context_field_type handles a NULL event class correctly");
+ ok(!bt_ctf_event_class_set_context_field_type(simple_event_class, event_context_type),
+ "Set an event class' context type successfully");
+ returned_type = bt_ctf_event_class_get_context_field_type(simple_event_class);
+ ok(returned_type == event_context_type,
+ "bt_ctf_event_class_get_context_field_type returns the appropriate type");
+ bt_ctf_object_put_ref(returned_type);
+
+ ok(!bt_ctf_stream_class_add_event_class(stream_class, simple_event_class),
+ "Adding simple event class to stream class");
+
+ /*
+ * bt_ctf_stream_class_add_event_class() copies the field types
+ * of simple_event_class, so we retrieve the new ones to create
+ * the appropriate fields.
+ */
+ BT_CTF_OBJECT_PUT_REF_AND_RESET(event_context_type);
+ BT_CTF_OBJECT_PUT_REF_AND_RESET(event_payload_type);
+ event_payload_type = bt_ctf_event_class_get_payload_field_type(
+ simple_event_class);
+ BT_ASSERT(event_payload_type);
+ event_context_type = bt_ctf_event_class_get_context_field_type(
+ simple_event_class);
+ BT_ASSERT(event_context_type);
+ ep_integer_field_type =
+ bt_ctf_field_type_structure_get_field_type_by_name(
+ event_payload_type, "integer_field");
+ BT_ASSERT(ep_integer_field_type);
+ ep_enum_field_type =
+ bt_ctf_field_type_structure_get_field_type_by_name(
+ event_payload_type, "enum_field");
+ BT_ASSERT(ep_enum_field_type);
+ ep_enum_field_unsigned_type =
+ bt_ctf_field_type_structure_get_field_type_by_name(
+ event_payload_type, "enum_field_unsigned");
+ BT_ASSERT(ep_enum_field_unsigned_type);
+
+ ok(bt_ctf_stream_class_get_event_class_count(stream_class) == 1,
+ "bt_ctf_stream_class_get_event_class_count returns a correct number of event classes");
+ ret_event_class = bt_ctf_stream_class_get_event_class_by_index(stream_class, 0);
+ ok(ret_event_class == simple_event_class,
+ "bt_ctf_stream_class_get_event_class returns the correct event class");
+ bt_ctf_object_put_ref(ret_event_class);
+ ok(!bt_ctf_stream_class_get_event_class_by_id(stream_class, 2),
+ "bt_ctf_stream_class_get_event_class_by_id returns NULL when the requested ID doesn't exist");
+ ret_event_class =
+ bt_ctf_stream_class_get_event_class_by_id(stream_class, 13);
+ ok(ret_event_class == simple_event_class,
+ "bt_ctf_stream_class_get_event_class_by_id returns a correct event class");
+ bt_ctf_object_put_ref(ret_event_class);
+
+ simple_event = bt_ctf_event_create(simple_event_class);
+ ok(simple_event,
+ "Instantiate an event containing a single integer field");
+
+ integer_field = bt_ctf_field_create(ep_integer_field_type);
+ bt_ctf_field_integer_unsigned_set_value(integer_field, 42);
+ ok(bt_ctf_event_set_payload(simple_event, "integer_field",
+ integer_field) == 0, "Use bt_ctf_event_set_payload to set a manually allocated field");
+
+ float_field = bt_ctf_event_get_payload(simple_event, "float_field");
+ bt_ctf_field_floating_point_set_value(float_field, double_test_value);
+ ok(!bt_ctf_field_floating_point_get_value(float_field, &ret_double),
+ "bt_ctf_field_floating_point_get_value returns a double value");
+ ok(fabs(ret_double - double_test_value) <= DBL_EPSILON,
+ "bt_ctf_field_floating_point_get_value returns a correct value");
+
+ enum_field = bt_ctf_field_create(ep_enum_field_type);
+ BT_ASSERT(enum_field);
+
+ enum_container_field = bt_ctf_field_enumeration_get_container(enum_field);
+ ok(bt_ctf_field_integer_signed_set_value(
+ enum_container_field, -42) == 0,
+ "Set signed enumeration container value");
+ ret = bt_ctf_event_set_payload(simple_event, "enum_field", enum_field);
+ BT_ASSERT(!ret);
+ BT_CTF_OBJECT_PUT_REF_AND_RESET(iter);
+
+ enum_field_unsigned = bt_ctf_field_create(ep_enum_field_unsigned_type);
+ BT_ASSERT(enum_field_unsigned);
+ enum_container_field_unsigned = bt_ctf_field_enumeration_get_container(
+ enum_field_unsigned);
+ ok(bt_ctf_field_integer_unsigned_set_value(
+ enum_container_field_unsigned, 42) == 0,
+ "Set unsigned enumeration container value");
+ ret = bt_ctf_event_set_payload(simple_event, "enum_field_unsigned",
+ enum_field_unsigned);
+ BT_ASSERT(!ret);
+
+ ok(bt_ctf_clock_set_time(clock, current_time) == 0, "Set clock time");
+
+ /* Populate stream event context */
+ stream_event_context =
+ bt_ctf_event_get_stream_event_context(simple_event);
+ BT_ASSERT(stream_event_context);
+ stream_event_context_field = bt_ctf_field_structure_get_field_by_name(
+ stream_event_context, "common_event_context");
+ bt_ctf_field_integer_unsigned_set_value(stream_event_context_field, 42);
+
+ /* Populate the event's context */
+ event_context = bt_ctf_event_get_context(simple_event);
+ ok(event_context,
+ "bt_ctf_event_get_context returns a field");
+ returned_type = bt_ctf_field_get_type(event_context);
+ ok(returned_type == event_context_type,
+ "bt_ctf_event_get_context returns a field of the appropriate type");
+ event_context_field = bt_ctf_field_structure_get_field_by_name(event_context,
+ "event_specific_context");
+ ok(!bt_ctf_field_integer_unsigned_set_value(event_context_field, 1234),
+ "Successfully set an event context's value");
+ ok(!bt_ctf_event_set_context(simple_event, event_context),
+ "Set an event context successfully");
+
+ ok(bt_ctf_stream_append_event(stream, simple_event) == 0,
+ "Append simple event to trace stream");
+
+ packet_context = bt_ctf_stream_get_packet_context(stream);
+ ok(packet_context,
+ "bt_ctf_stream_get_packet_context returns a packet context");
+
+ packet_context_field = bt_ctf_field_structure_get_field_by_name(packet_context,
+ "packet_size");
+ ok(packet_context_field,
+ "Packet context contains the default packet_size field.");
+ bt_ctf_object_put_ref(packet_context_field);
+ packet_context_field = bt_ctf_field_structure_get_field_by_name(packet_context,
+ "custom_packet_context_field");
+ ok(bt_ctf_field_integer_unsigned_set_value(packet_context_field, 8) == 0,
+ "Custom packet context field value successfully set.");
+
+ ok(bt_ctf_stream_set_packet_context(stream, packet_context) == 0,
+ "Successfully set a stream's packet context");
+
+ ok(bt_ctf_stream_flush(stream) == 0,
+ "Flush trace stream with one event");
+
+ bt_ctf_object_put_ref(simple_event_class);
+ bt_ctf_object_put_ref(simple_event);
+ bt_ctf_object_put_ref(uint_12_type);
+ bt_ctf_object_put_ref(int_64_type);
+ bt_ctf_object_put_ref(float_type);
+ bt_ctf_object_put_ref(enum_type);
+ bt_ctf_object_put_ref(enum_type_unsigned);
+ bt_ctf_object_put_ref(returned_type);
+ bt_ctf_object_put_ref(event_context_type);
+ bt_ctf_object_put_ref(integer_field);
+ bt_ctf_object_put_ref(float_field);
+ bt_ctf_object_put_ref(enum_field);
+ bt_ctf_object_put_ref(enum_field_unsigned);
+ bt_ctf_object_put_ref(enum_container_field);
+ bt_ctf_object_put_ref(enum_container_field_unsigned);
+ bt_ctf_object_put_ref(packet_context);
+ bt_ctf_object_put_ref(packet_context_field);
+ bt_ctf_object_put_ref(stream_event_context);
+ bt_ctf_object_put_ref(stream_event_context_field);
+ bt_ctf_object_put_ref(event_context);
+ bt_ctf_object_put_ref(event_context_field);
+ bt_ctf_object_put_ref(event_payload_type);
+ bt_ctf_object_put_ref(ep_integer_field_type);
+ bt_ctf_object_put_ref(ep_enum_field_type);
+ bt_ctf_object_put_ref(ep_enum_field_unsigned_type);
+ bt_ctf_object_put_ref(iter);
+}
+
+static
+void append_complex_event(struct bt_ctf_stream_class *stream_class,
+ struct bt_ctf_stream *stream, struct bt_ctf_clock *clock)
+{
+ int i;
+ struct event_class_attrs_counts ;
+ const char *complex_test_event_string = "Complex Test Event";
+ const char *test_string_1 = "Test ";
+ const char *test_string_2 = "string ";
+ const char *test_string_3 = "abcdefghi";
+ const char *test_string_4 = "abcd\0efg\0hi";
+ const char *test_string_cat = "Test string abcdeefg";
+ struct bt_ctf_field_type *uint_35_type =
+ bt_ctf_field_type_integer_create(35);
+ struct bt_ctf_field_type *int_16_type =
+ bt_ctf_field_type_integer_create(16);
+ struct bt_ctf_field_type *uint_3_type =
+ bt_ctf_field_type_integer_create(3);
+ struct bt_ctf_field_type *enum_variant_type =
+ bt_ctf_field_type_enumeration_create(uint_3_type);
+ struct bt_ctf_field_type *variant_type =
+ bt_ctf_field_type_variant_create(enum_variant_type,
+ "variant_selector");
+ struct bt_ctf_field_type *string_type =
+ bt_ctf_field_type_string_create();
+ struct bt_ctf_field_type *sequence_type;
+ struct bt_ctf_field_type *array_type;
+ struct bt_ctf_field_type *inner_structure_type =
+ bt_ctf_field_type_structure_create();
+ struct bt_ctf_field_type *complex_structure_type =
+ bt_ctf_field_type_structure_create();
+ struct bt_ctf_field_type *ret_field_type;
+ struct bt_ctf_event_class *event_class;
+ struct bt_ctf_event *event;
+ struct bt_ctf_field *uint_35_field, *int_16_field, *a_string_field,
+ *inner_structure_field, *complex_structure_field,
+ *a_sequence_field, *enum_variant_field, *enum_container_field,
+ *variant_field, *an_array_field, *stream_event_ctx_field,
+ *stream_event_ctx_int_field;
+ uint64_t ret_unsigned_int;
+ int64_t ret_signed_int;
+ const char *ret_string;
+ struct bt_ctf_stream_class *ret_stream_class;
+ struct bt_ctf_event_class *ret_event_class;
+ struct bt_ctf_field *packet_context, *packet_context_field;
+
+ ok(bt_ctf_field_type_set_alignment(int_16_type, 0),
+ "bt_ctf_field_type_set_alignment handles 0-alignment correctly");
+ ok(bt_ctf_field_type_set_alignment(int_16_type, 3),
+ "bt_ctf_field_type_set_alignment handles wrong alignment correctly (3)");
+ ok(bt_ctf_field_type_set_alignment(int_16_type, 24),
+ "bt_ctf_field_type_set_alignment handles wrong alignment correctly (24)");
+ ok(!bt_ctf_field_type_set_alignment(int_16_type, 4),
+ "bt_ctf_field_type_set_alignment handles correct alignment correctly (4)");
+ ok(!bt_ctf_field_type_set_alignment(int_16_type, 32),
+ "Set alignment of signed 16 bit integer to 32");
+ ok(!bt_ctf_field_type_integer_set_signed(int_16_type, 1),
+ "Set integer signedness to true");
+ ok(!bt_ctf_field_type_integer_set_base(uint_35_type,
+ BT_CTF_INTEGER_BASE_HEXADECIMAL),
+ "Set signed 16 bit integer base to hexadecimal");
+
+ array_type = bt_ctf_field_type_array_create(int_16_type, ARRAY_TEST_LENGTH);
+ sequence_type = bt_ctf_field_type_sequence_create(int_16_type,
+ "seq_len");
+
+ ret_field_type = bt_ctf_field_type_array_get_element_field_type(
+ array_type);
+ ok(ret_field_type == int_16_type,
+ "bt_ctf_field_type_array_get_element_field_type returns the correct type");
+ bt_ctf_object_put_ref(ret_field_type);
+
+ ok(bt_ctf_field_type_array_get_length(array_type) == ARRAY_TEST_LENGTH,
+ "bt_ctf_field_type_array_get_length returns the correct length");
+
+ ok(bt_ctf_field_type_structure_add_field(inner_structure_type,
+ inner_structure_type, "yes"), "Cannot add self to structure");
+ ok(!bt_ctf_field_type_structure_add_field(inner_structure_type,
+ uint_35_type, "seq_len"), "Add seq_len field to inner structure");
+ ok(!bt_ctf_field_type_structure_add_field(inner_structure_type,
+ sequence_type, "a_sequence"), "Add a_sequence field to inner structure");
+ ok(!bt_ctf_field_type_structure_add_field(inner_structure_type,
+ array_type, "an_array"), "Add an_array field to inner structure");
+
+ bt_ctf_field_type_enumeration_add_mapping(enum_variant_type,
+ "UINT3_TYPE", 0, 0);
+ bt_ctf_field_type_enumeration_add_mapping(enum_variant_type,
+ "INT16_TYPE", 1, 1);
+ bt_ctf_field_type_enumeration_add_mapping(enum_variant_type,
+ "UINT35_TYPE", 2, 7);
+
+ ok(bt_ctf_field_type_variant_add_field(variant_type, uint_3_type,
+ "An unknown entry"), "Reject a variant field based on an unknown tag value");
+ ok(bt_ctf_field_type_variant_add_field(variant_type, uint_3_type,
+ "UINT3_TYPE") == 0, "Add a field to a variant");
+ ok(!bt_ctf_field_type_variant_add_field(variant_type, int_16_type,
+ "INT16_TYPE"), "Add INT16_TYPE field to variant");
+ ok(!bt_ctf_field_type_variant_add_field(variant_type, uint_35_type,
+ "UINT35_TYPE"), "Add UINT35_TYPE field to variant");
+
+ ret_field_type = bt_ctf_field_type_variant_get_tag_field_type(variant_type);
+ ok(ret_field_type == enum_variant_type,
+ "bt_ctf_field_type_variant_get_tag_field_type returns a correct tag type");
+ bt_ctf_object_put_ref(ret_field_type);
+
+ ret_string = bt_ctf_field_type_variant_get_tag_name(variant_type);
+ ok(ret_string ? strcmp(ret_string, "variant_selector") == 0 : 0,
+ "bt_ctf_field_type_variant_get_tag_name returns the correct variant tag name");
+ ret_field_type = bt_ctf_field_type_variant_get_field_type_by_name(
+ variant_type, "INT16_TYPE");
+ ok(ret_field_type == int_16_type,
+ "bt_ctf_field_type_variant_get_field_type_by_name returns a correct field type");
+ bt_ctf_object_put_ref(ret_field_type);
+
+ ok(bt_ctf_field_type_variant_get_field_count(variant_type) == 3,
+ "bt_ctf_field_type_variant_get_field_count returns the correct count");
+
+ ok(bt_ctf_field_type_variant_get_field_by_index(variant_type, NULL, &ret_field_type, 0) == 0,
+ "bt_ctf_field_type_variant_get_field handles a NULL field name correctly");
+ bt_ctf_object_put_ref(ret_field_type);
+ ok(bt_ctf_field_type_variant_get_field_by_index(variant_type, &ret_string, NULL, 0) == 0,
+ "bt_ctf_field_type_variant_get_field handles a NULL field type correctly");
+ ok(bt_ctf_field_type_variant_get_field_by_index(variant_type, &ret_string, &ret_field_type, 1) == 0,
+ "bt_ctf_field_type_variant_get_field returns a field");
+ ok(strcmp("INT16_TYPE", ret_string) == 0,
+ "bt_ctf_field_type_variant_get_field returns a correct field name");
+ ok(ret_field_type == int_16_type,
+ "bt_ctf_field_type_variant_get_field returns a correct field type");
+ bt_ctf_object_put_ref(ret_field_type);
+
+ ok(!bt_ctf_field_type_structure_add_field(complex_structure_type,
+ enum_variant_type, "variant_selector"),
+ "Add variant_selector field to complex structure");
+ ok(!bt_ctf_field_type_structure_add_field(complex_structure_type,
+ string_type, "string"), "Add `string` field to complex structure");
+ ok(!bt_ctf_field_type_structure_add_field(complex_structure_type,
+ variant_type, "variant_value"),
+ "Add variant_value field to complex structure");
+ ok(!bt_ctf_field_type_structure_add_field(complex_structure_type,
+ inner_structure_type, "inner_structure"),
+ "Add inner_structure field to complex structure");
+
+ event_class = bt_ctf_event_class_create(complex_test_event_string);
+ ok(event_class, "Create an event class");
+ ok(bt_ctf_event_class_add_field(event_class, uint_35_type, ""),
+ "Reject addition of a field with an empty name to an event");
+ ok(bt_ctf_event_class_add_field(event_class, NULL, "an_integer"),
+ "Reject addition of a field with a NULL type to an event");
+ ok(bt_ctf_event_class_add_field(event_class, uint_35_type,
+ "int"),
+ "Reject addition of a type with an illegal name to an event");
+ ok(bt_ctf_event_class_add_field(event_class, uint_35_type,
+ "uint_35") == 0,
+ "Add field of type unsigned integer to an event");
+ ok(bt_ctf_event_class_add_field(event_class, int_16_type,
+ "int_16") == 0, "Add field of type signed integer to an event");
+ ok(bt_ctf_event_class_add_field(event_class, complex_structure_type,
+ "complex_structure") == 0,
+ "Add composite structure to an event");
+
+ ret_string = bt_ctf_event_class_get_name(event_class);
+ ok(strcmp(ret_string, complex_test_event_string) == 0,
+ "bt_ctf_event_class_get_name returns a correct name");
+ ok(bt_ctf_event_class_get_id(event_class) < 0,
+ "bt_ctf_event_class_get_id returns a negative value when not set");
+ ok(bt_ctf_event_class_set_id(NULL, 42) < 0,
+ "bt_ctf_event_class_set_id handles NULL correctly");
+ ok(bt_ctf_event_class_set_id(event_class, 42) == 0,
+ "Set an event class' id");
+ ok(bt_ctf_event_class_get_id(event_class) == 42,
+ "bt_ctf_event_class_get_id returns the correct value");
+
+ /* Test event class attributes */
+ ok(bt_ctf_event_class_get_log_level(event_class) == BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED,
+ "event class has the expected initial log level");
+ ok(!bt_ctf_event_class_get_emf_uri(event_class),
+ "as expected, event class has no initial EMF URI");
+ ok(bt_ctf_event_class_set_log_level(NULL, BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO),
+ "bt_ctf_event_class_set_log_level handles a NULL event class correctly");
+ ok(bt_ctf_event_class_set_log_level(event_class, BT_CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN),
+ "bt_ctf_event_class_set_log_level handles an unknown log level correctly");
+ ok(!bt_ctf_event_class_set_log_level(event_class, BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO),
+ "bt_ctf_event_class_set_log_level succeeds with a valid log level");
+ ok(bt_ctf_event_class_get_log_level(event_class) == BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO,
+ "bt_ctf_event_class_get_log_level returns the expected log level");
+ ok(bt_ctf_event_class_set_emf_uri(NULL, "https://babeltrace.org/"),
+ "bt_ctf_event_class_set_emf_uri handles a NULL event class correctly");
+ ok(!bt_ctf_event_class_set_emf_uri(event_class, "https://babeltrace.org/"),
+ "bt_ctf_event_class_set_emf_uri succeeds with a valid EMF URI");
+ ok(strcmp(bt_ctf_event_class_get_emf_uri(event_class), "https://babeltrace.org/") == 0,
+ "bt_ctf_event_class_get_emf_uri returns the expected EMF URI");
+ ok(!bt_ctf_event_class_set_emf_uri(event_class, NULL),
+ "bt_ctf_event_class_set_emf_uri succeeds with NULL (to reset)");
+ ok(!bt_ctf_event_class_get_emf_uri(event_class),
+ "as expected, event class has no EMF URI after reset");
+
+ /* Add event class to the stream class */
+ ok(bt_ctf_stream_class_add_event_class(stream_class, NULL),
+ "Reject addition of NULL event class to a stream class");
+ ok(bt_ctf_stream_class_add_event_class(stream_class,
+ event_class) == 0, "Add an event class to stream class");
+
+ ret_stream_class = bt_ctf_event_class_get_stream_class(event_class);
+ ok(ret_stream_class == stream_class,
+ "bt_ctf_event_class_get_stream_class returns the correct stream class");
+ bt_ctf_object_put_ref(ret_stream_class);
+
+ ok(!bt_ctf_event_class_get_field_by_name(event_class, "truie"),
+ "bt_ctf_event_class_get_field_by_name handles an invalid field name correctly");
+ ret_field_type = bt_ctf_event_class_get_field_by_name(event_class,
+ "complex_structure");
+ bt_ctf_object_put_ref(ret_field_type);
+
+ event = bt_ctf_event_create(event_class);
+ ok(event, "Instanciate a complex event");
+
+ ret_event_class = bt_ctf_event_get_class(event);
+ ok(ret_event_class == event_class,
+ "bt_ctf_event_get_class returns the correct event class");
+ bt_ctf_object_put_ref(ret_event_class);
+
+ uint_35_field = bt_ctf_event_get_payload(event, "uint_35");
+ ok(uint_35_field, "Use bt_ctf_event_get_payload to get a field instance ");
+ bt_ctf_field_integer_unsigned_set_value(uint_35_field, 0x0DDF00D);
+ ok(bt_ctf_field_integer_unsigned_get_value(uint_35_field,
+ &ret_unsigned_int) == 0,
+ "bt_ctf_field_integer_unsigned_get_value succeeds after setting a value");
+ ok(ret_unsigned_int == 0x0DDF00D,
+ "bt_ctf_field_integer_unsigned_get_value returns the correct value");
+ bt_ctf_object_put_ref(uint_35_field);
+
+ int_16_field = bt_ctf_event_get_payload(event, "int_16");
+ bt_ctf_field_integer_signed_set_value(int_16_field, -12345);
+ ok(bt_ctf_field_integer_signed_get_value(int_16_field,
+ &ret_signed_int) == 0,
+ "bt_ctf_field_integer_signed_get_value succeeds after setting a value");
+ ok(ret_signed_int == -12345,
+ "bt_ctf_field_integer_signed_get_value returns the correct value");
+ bt_ctf_object_put_ref(int_16_field);
+
+ complex_structure_field = bt_ctf_event_get_payload(event,
+ "complex_structure");
+
+ inner_structure_field = bt_ctf_field_structure_get_field_by_index(
+ complex_structure_field, 3);
+ ret_field_type = bt_ctf_field_get_type(inner_structure_field);
+ bt_ctf_object_put_ref(inner_structure_field);
+ bt_ctf_object_put_ref(ret_field_type);
+
+ inner_structure_field = bt_ctf_field_structure_get_field_by_name(
+ complex_structure_field, "inner_structure");
+ a_string_field = bt_ctf_field_structure_get_field_by_name(
+ complex_structure_field, "string");
+ enum_variant_field = bt_ctf_field_structure_get_field_by_name(
+ complex_structure_field, "variant_selector");
+ variant_field = bt_ctf_field_structure_get_field_by_name(
+ complex_structure_field, "variant_value");
+ uint_35_field = bt_ctf_field_structure_get_field_by_name(
+ inner_structure_field, "seq_len");
+ a_sequence_field = bt_ctf_field_structure_get_field_by_name(
+ inner_structure_field, "a_sequence");
+ an_array_field = bt_ctf_field_structure_get_field_by_name(
+ inner_structure_field, "an_array");
+
+ enum_container_field = bt_ctf_field_enumeration_get_container(
+ enum_variant_field);
+ bt_ctf_field_integer_unsigned_set_value(enum_container_field, 1);
+ int_16_field = bt_ctf_field_variant_get_field(variant_field,
+ enum_variant_field);
+ bt_ctf_field_integer_signed_set_value(int_16_field, -200);
+ bt_ctf_object_put_ref(int_16_field);
+ bt_ctf_field_string_set_value(a_string_field,
+ test_string_1);
+ ok(!bt_ctf_field_string_append(a_string_field, test_string_2),
+ "bt_ctf_field_string_append succeeds");
+ ok(!bt_ctf_field_string_append_len(a_string_field, test_string_3, 5),
+ "bt_ctf_field_string_append_len succeeds (append 5 characters)");
+ ok(!bt_ctf_field_string_append_len(a_string_field, &test_string_4[5], 3),
+ "bt_ctf_field_string_append_len succeeds (append 0 characters)");
+ ok(!bt_ctf_field_string_append_len(a_string_field, test_string_3, 0),
+ "bt_ctf_field_string_append_len succeeds (append 0 characters)");
+
+ ret_string = bt_ctf_field_string_get_value(a_string_field);
+ ok(ret_string, "bt_ctf_field_string_get_value returns a string");
+ ok(ret_string ? strcmp(ret_string, test_string_cat) == 0 : 0,
+ "bt_ctf_field_string_get_value returns a correct value");
+ bt_ctf_field_integer_unsigned_set_value(uint_35_field,
+ SEQUENCE_TEST_LENGTH);
+
+ ret_field_type = bt_ctf_field_type_variant_get_field_type_from_tag(
+ variant_type, enum_variant_field);
+ ok(ret_field_type == int_16_type,
+ "bt_ctf_field_type_variant_get_field_type_from_tag returns the correct field type");
+
+ ok(bt_ctf_field_sequence_set_length(a_sequence_field,
+ uint_35_field) == 0, "Set a sequence field's length");
+
+ for (i = 0; i < SEQUENCE_TEST_LENGTH; i++) {
+ int_16_field = bt_ctf_field_sequence_get_field(
+ a_sequence_field, i);
+ bt_ctf_field_integer_signed_set_value(int_16_field, 4 - i);
+ bt_ctf_object_put_ref(int_16_field);
+ }
+
+ for (i = 0; i < ARRAY_TEST_LENGTH; i++) {
+ int_16_field = bt_ctf_field_array_get_field(
+ an_array_field, i);
+ bt_ctf_field_integer_signed_set_value(int_16_field, i);
+ bt_ctf_object_put_ref(int_16_field);
+ }
+
+ stream_event_ctx_field = bt_ctf_event_get_stream_event_context(event);
+ BT_ASSERT(stream_event_ctx_field);
+ stream_event_ctx_int_field = bt_ctf_field_structure_get_field_by_name(
+ stream_event_ctx_field, "common_event_context");
+ BT_CTF_OBJECT_PUT_REF_AND_RESET(stream_event_ctx_field);
+ bt_ctf_field_integer_unsigned_set_value(stream_event_ctx_int_field, 17);
+ BT_CTF_OBJECT_PUT_REF_AND_RESET(stream_event_ctx_int_field);
+
+ bt_ctf_clock_set_time(clock, ++current_time);
+ ok(bt_ctf_stream_append_event(stream, event) == 0,
+ "Append a complex event to a stream");
+
+ /*
+ * Populate the custom packet context field with a dummy value
+ * otherwise flush will fail.
+ */
+ packet_context = bt_ctf_stream_get_packet_context(stream);
+ packet_context_field = bt_ctf_field_structure_get_field_by_name(packet_context,
+ "custom_packet_context_field");
+ bt_ctf_field_integer_unsigned_set_value(packet_context_field, 1);
+
+ ok(bt_ctf_stream_flush(stream) == 0,
+ "Flush a stream containing a complex event");
+
+ bt_ctf_object_put_ref(uint_35_field);
+ bt_ctf_object_put_ref(a_string_field);
+ bt_ctf_object_put_ref(inner_structure_field);
+ bt_ctf_object_put_ref(complex_structure_field);
+ bt_ctf_object_put_ref(a_sequence_field);
+ bt_ctf_object_put_ref(an_array_field);
+ bt_ctf_object_put_ref(enum_variant_field);
+ bt_ctf_object_put_ref(enum_container_field);
+ bt_ctf_object_put_ref(variant_field);
+ bt_ctf_object_put_ref(packet_context_field);
+ bt_ctf_object_put_ref(packet_context);
+ bt_ctf_object_put_ref(uint_35_type);
+ bt_ctf_object_put_ref(int_16_type);
+ bt_ctf_object_put_ref(string_type);
+ bt_ctf_object_put_ref(sequence_type);
+ bt_ctf_object_put_ref(array_type);
+ bt_ctf_object_put_ref(inner_structure_type);
+ bt_ctf_object_put_ref(complex_structure_type);
+ bt_ctf_object_put_ref(uint_3_type);
+ bt_ctf_object_put_ref(enum_variant_type);
+ bt_ctf_object_put_ref(variant_type);
+ bt_ctf_object_put_ref(ret_field_type);
+ bt_ctf_object_put_ref(event_class);
+ bt_ctf_object_put_ref(event);
+}
+
+static
+void type_field_tests(void)
+{
+ struct bt_ctf_field *uint_12;
+ struct bt_ctf_field *int_16;
+ struct bt_ctf_field *string;
+ struct bt_ctf_field_type *composite_structure_type;
+ struct bt_ctf_field_type *structure_seq_type;
+ struct bt_ctf_field_type *string_type;
+ struct bt_ctf_field_type *sequence_type;
+ struct bt_ctf_field_type *uint_8_type;
+ struct bt_ctf_field_type *int_16_type;
+ struct bt_ctf_field_type *uint_12_type =
+ bt_ctf_field_type_integer_create(12);
+ struct bt_ctf_field_type *enumeration_type;
+ struct bt_ctf_field_type *returned_type;
+ const char *ret_string;
+
+ ok(uint_12_type, "Create an unsigned integer type");
+ ok(bt_ctf_field_type_integer_set_base(uint_12_type,
+ BT_CTF_INTEGER_BASE_BINARY) == 0,
+ "Set integer type's base as binary");
+ ok(bt_ctf_field_type_integer_set_base(uint_12_type,
+ BT_CTF_INTEGER_BASE_DECIMAL) == 0,
+ "Set integer type's base as decimal");
+ ok(bt_ctf_field_type_integer_set_base(uint_12_type,
+ BT_CTF_INTEGER_BASE_UNKNOWN),
+ "Reject integer type's base set as unknown");
+ ok(bt_ctf_field_type_integer_set_base(uint_12_type,
+ BT_CTF_INTEGER_BASE_OCTAL) == 0,
+ "Set integer type's base as octal");
+ ok(bt_ctf_field_type_integer_set_base(uint_12_type,
+ BT_CTF_INTEGER_BASE_HEXADECIMAL) == 0,
+ "Set integer type's base as hexadecimal");
+ ok(bt_ctf_field_type_integer_set_base(uint_12_type, 457417),
+ "Reject unknown integer base value");
+ ok(bt_ctf_field_type_integer_set_signed(uint_12_type, 952835) == 0,
+ "Set integer type signedness to signed");
+ ok(bt_ctf_field_type_integer_set_signed(uint_12_type, 0) == 0,
+ "Set integer type signedness to unsigned");
+ ok(bt_ctf_field_type_integer_get_size(uint_12_type) == 12,
+ "bt_ctf_field_type_integer_get_size returns a correct value");
+ ok(bt_ctf_field_type_integer_get_signed(uint_12_type) == 0,
+ "bt_ctf_field_type_integer_get_signed returns a correct value for unsigned types");
+
+ ok(bt_ctf_field_type_set_byte_order(NULL,
+ BT_CTF_BYTE_ORDER_LITTLE_ENDIAN) < 0,
+ "bt_ctf_field_type_set_byte_order handles NULL correctly");
+ ok(bt_ctf_field_type_set_byte_order(uint_12_type,
+ (enum bt_ctf_byte_order) 42) < 0,
+ "bt_ctf_field_type_set_byte_order rejects invalid values");
+ ok(bt_ctf_field_type_set_byte_order(uint_12_type,
+ BT_CTF_BYTE_ORDER_LITTLE_ENDIAN) == 0,
+ "Set an integer's byte order to little endian");
+ ok(bt_ctf_field_type_set_byte_order(uint_12_type,
+ BT_CTF_BYTE_ORDER_BIG_ENDIAN) == 0,
+ "Set an integer's byte order to big endian");
+ ok(bt_ctf_field_type_get_byte_order(uint_12_type) ==
+ BT_CTF_BYTE_ORDER_BIG_ENDIAN,
+ "bt_ctf_field_type_get_byte_order returns a correct value");
+
+ ok(bt_ctf_field_type_get_type_id(uint_12_type) ==
+ BT_CTF_FIELD_TYPE_ID_INTEGER,
+ "bt_ctf_field_type_get_type_id returns a correct value with an integer type");
+
+ ok(bt_ctf_field_type_integer_get_base(uint_12_type) ==
+ BT_CTF_INTEGER_BASE_HEXADECIMAL,
+ "bt_ctf_field_type_integer_get_base returns a correct value");
+
+ ok(bt_ctf_field_type_integer_set_encoding(NULL,
+ BT_CTF_STRING_ENCODING_ASCII) < 0,
+ "bt_ctf_field_type_integer_set_encoding handles NULL correctly");
+ ok(bt_ctf_field_type_integer_set_encoding(uint_12_type,
+ (enum bt_ctf_string_encoding) 123) < 0,
+ "bt_ctf_field_type_integer_set_encoding handles invalid encodings correctly");
+ ok(bt_ctf_field_type_integer_set_encoding(uint_12_type,
+ BT_CTF_STRING_ENCODING_UTF8) == 0,
+ "Set integer type encoding to UTF8");
+ ok(bt_ctf_field_type_integer_get_encoding(uint_12_type) ==
+ BT_CTF_STRING_ENCODING_UTF8,
+ "bt_ctf_field_type_integer_get_encoding returns a correct value");
+
+ int_16_type = bt_ctf_field_type_integer_create(16);
+ BT_ASSERT(int_16_type);
+ ok(!bt_ctf_field_type_integer_set_signed(int_16_type, 1),
+ "Set signedness of 16 bit integer to true");
+ ok(bt_ctf_field_type_integer_get_signed(int_16_type) == 1,
+ "bt_ctf_field_type_integer_get_signed returns a correct value for signed types");
+ uint_8_type = bt_ctf_field_type_integer_create(8);
+ sequence_type =
+ bt_ctf_field_type_sequence_create(int_16_type, "seq_len");
+ ok(sequence_type, "Create a sequence of int16_t type");
+ ok(bt_ctf_field_type_get_type_id(sequence_type) ==
+ BT_CTF_FIELD_TYPE_ID_SEQUENCE,
+ "bt_ctf_field_type_get_type_id returns a correct value with a sequence type");
+
+ ret_string = bt_ctf_field_type_sequence_get_length_field_name(
+ sequence_type);
+ ok(strcmp(ret_string, "seq_len") == 0,
+ "bt_ctf_field_type_sequence_get_length_field_name returns the correct value");
+ returned_type = bt_ctf_field_type_sequence_get_element_field_type(
+ sequence_type);
+ ok(returned_type == int_16_type,
+ "bt_ctf_field_type_sequence_get_element_field_type returns the correct type");
+ bt_ctf_object_put_ref(returned_type);
+
+ string_type = bt_ctf_field_type_string_create();
+ ok(string_type, "Create a string type");
+ ok(bt_ctf_field_type_string_set_encoding(string_type,
+ BT_CTF_STRING_ENCODING_NONE),
+ "Reject invalid \"None\" string encoding");
+ ok(bt_ctf_field_type_string_set_encoding(string_type,
+ 42),
+ "Reject invalid string encoding");
+ ok(bt_ctf_field_type_string_set_encoding(string_type,
+ BT_CTF_STRING_ENCODING_ASCII) == 0,
+ "Set string encoding to ASCII");
+
+ ok(bt_ctf_field_type_string_get_encoding(string_type) ==
+ BT_CTF_STRING_ENCODING_ASCII,
+ "bt_ctf_field_type_string_get_encoding returns the correct value");
+
+ structure_seq_type = bt_ctf_field_type_structure_create();
+ ok(bt_ctf_field_type_get_type_id(structure_seq_type) ==
+ BT_CTF_FIELD_TYPE_ID_STRUCT,
+ "bt_ctf_field_type_get_type_id returns a correct value with a structure type");
+ ok(structure_seq_type, "Create a structure type");
+ ok(bt_ctf_field_type_structure_add_field(structure_seq_type,
+ uint_8_type, "seq_len") == 0,
+ "Add a uint8_t type to a structure");
+ ok(bt_ctf_field_type_structure_add_field(structure_seq_type,
+ sequence_type, "a_sequence") == 0,
+ "Add a sequence type to a structure");
+
+ ok(bt_ctf_field_type_structure_get_field_count(structure_seq_type) == 2,
+ "bt_ctf_field_type_structure_get_field_count returns a correct value");
+
+ ok(bt_ctf_field_type_structure_get_field(structure_seq_type,
+ NULL, &returned_type, 1) == 0,
+ "bt_ctf_field_type_structure_get_field handles a NULL name correctly");
+ bt_ctf_object_put_ref(returned_type);
+ ok(bt_ctf_field_type_structure_get_field(structure_seq_type,
+ &ret_string, NULL, 1) == 0,
+ "bt_ctf_field_type_structure_get_field handles a NULL return type correctly");
+ ok(bt_ctf_field_type_structure_get_field(structure_seq_type,
+ &ret_string, &returned_type, 1) == 0,
+ "bt_ctf_field_type_structure_get_field returns a field");
+ ok(strcmp(ret_string, "a_sequence") == 0,
+ "bt_ctf_field_type_structure_get_field returns a correct field name");
+ ok(returned_type == sequence_type,
+ "bt_ctf_field_type_structure_get_field returns a correct field type");
+ bt_ctf_object_put_ref(returned_type);
+
+ returned_type = bt_ctf_field_type_structure_get_field_type_by_name(
+ structure_seq_type, "a_sequence");
+ ok(returned_type == sequence_type,
+ "bt_ctf_field_type_structure_get_field_type_by_name returns the correct field type");
+ bt_ctf_object_put_ref(returned_type);
+
+ composite_structure_type = bt_ctf_field_type_structure_create();
+ ok(bt_ctf_field_type_structure_add_field(composite_structure_type,
+ string_type, "a_string") == 0,
+ "Add a string type to a structure");
+ ok(bt_ctf_field_type_structure_add_field(composite_structure_type,
+ structure_seq_type, "inner_structure") == 0,
+ "Add a structure type to a structure");
+
+ returned_type = bt_ctf_field_type_structure_get_field_type_by_name(
+ structure_seq_type, "a_sequence");
+ ok(returned_type == sequence_type,
+ "bt_ctf_field_type_structure_get_field_type_by_name returns a correct type");
+ bt_ctf_object_put_ref(returned_type);
+
+ int_16 = bt_ctf_field_create(int_16_type);
+ ok(int_16, "Instanciate a signed 16-bit integer");
+ uint_12 = bt_ctf_field_create(uint_12_type);
+ ok(uint_12, "Instanciate an unsigned 12-bit integer");
+ returned_type = bt_ctf_field_get_type(int_16);
+ ok(returned_type == int_16_type,
+ "bt_ctf_field_get_type returns the correct type");
+
+ /* Can't modify types after instanciating them */
+ ok(bt_ctf_field_type_integer_set_base(uint_12_type,
+ BT_CTF_INTEGER_BASE_DECIMAL),
+ "Check an integer type' base can't be modified after instanciation");
+ ok(bt_ctf_field_type_integer_set_signed(uint_12_type, 0),
+ "Check an integer type's signedness can't be modified after instanciation");
+
+ /* Check overflows are properly tested for */
+ ok(bt_ctf_field_integer_signed_set_value(int_16, -32768) == 0,
+ "Check -32768 is allowed for a signed 16-bit integer");
+ ok(bt_ctf_field_integer_signed_set_value(int_16, 32767) == 0,
+ "Check 32767 is allowed for a signed 16-bit integer");
+ ok(bt_ctf_field_integer_signed_set_value(int_16, -42) == 0,
+ "Check -42 is allowed for a signed 16-bit integer");
+
+ ok(bt_ctf_field_integer_unsigned_set_value(uint_12, 4095) == 0,
+ "Check 4095 is allowed for an unsigned 12-bit integer");
+ ok(bt_ctf_field_integer_unsigned_set_value(uint_12, 0) == 0,
+ "Check 0 is allowed for an unsigned 12-bit integer");
+
+ string = bt_ctf_field_create(string_type);
+ ok(string, "Instanciate a string field");
+ ok(bt_ctf_field_string_set_value(string, "A value") == 0,
+ "Set a string's value");
+
+ enumeration_type = bt_ctf_field_type_enumeration_create(uint_12_type);
+ ok(enumeration_type,
+ "Create an enumeration type with an unsigned 12-bit integer as container");
+
+ bt_ctf_object_put_ref(string);
+ bt_ctf_object_put_ref(uint_12);
+ bt_ctf_object_put_ref(int_16);
+ bt_ctf_object_put_ref(composite_structure_type);
+ bt_ctf_object_put_ref(structure_seq_type);
+ bt_ctf_object_put_ref(string_type);
+ bt_ctf_object_put_ref(sequence_type);
+ bt_ctf_object_put_ref(uint_8_type);
+ bt_ctf_object_put_ref(int_16_type);
+ bt_ctf_object_put_ref(uint_12_type);
+ bt_ctf_object_put_ref(enumeration_type);
+ bt_ctf_object_put_ref(returned_type);
+}
+
+static
+void packet_resize_test(struct bt_ctf_stream_class *stream_class,
+ struct bt_ctf_stream *stream, struct bt_ctf_clock *clock)
+{
+ /*
+ * Append enough events to force the underlying packet to be resized.
+ * Also tests that a new event can be declared after a stream has been
+ * instantiated and used/flushed.
+ */
+ int ret = 0;
+ int i;
+ struct bt_ctf_event_class *event_class = bt_ctf_event_class_create(
+ "Spammy_Event");
+ struct bt_ctf_field_type *integer_type =
+ bt_ctf_field_type_integer_create(17);
+ struct bt_ctf_field_type *string_type =
+ bt_ctf_field_type_string_create();
+ struct bt_ctf_event *event = NULL;
+ struct bt_ctf_field *ret_field = NULL;
+ struct bt_ctf_field_type *ret_field_type = NULL;
+ uint64_t ret_uint64;
+ int events_appended = 0;
+ struct bt_ctf_field *packet_context = NULL,
+ *packet_context_field = NULL, *stream_event_context = NULL;
+ struct bt_ctf_field_type *ep_field_1_type = NULL;
+ struct bt_ctf_field_type *ep_a_string_type = NULL;
+ struct bt_ctf_field_type *ep_type = NULL;
+
+ ret |= bt_ctf_event_class_add_field(event_class, integer_type,
+ "field_1");
+ ret |= bt_ctf_event_class_add_field(event_class, string_type,
+ "a_string");
+ ret |= bt_ctf_stream_class_add_event_class(stream_class, event_class);
+ ok(ret == 0, "Add a new event class to a stream class after writing an event");
+ if (ret) {
+ goto end;
+ }
+
+ /*
+ * bt_ctf_stream_class_add_event_class() copies the field types
+ * of event_class, so we retrieve the new ones to create the
+ * appropriate fields.
+ */
+ ep_type = bt_ctf_event_class_get_payload_field_type(event_class);
+ BT_ASSERT(ep_type);
+ ep_field_1_type = bt_ctf_field_type_structure_get_field_type_by_name(
+ ep_type, "field_1");
+ BT_ASSERT(ep_field_1_type);
+ ep_a_string_type = bt_ctf_field_type_structure_get_field_type_by_name(
+ ep_type, "a_string");
+ BT_ASSERT(ep_a_string_type);
+
+ event = bt_ctf_event_create(event_class);
+ ret_field = bt_ctf_event_get_payload(event, 0);
+ ret_field_type = bt_ctf_field_get_type(ret_field);
+ bt_ctf_object_put_ref(ret_field_type);
+ bt_ctf_object_put_ref(ret_field);
+ bt_ctf_object_put_ref(event);
+
+ for (i = 0; i < packet_resize_test_length; i++) {
+ event = bt_ctf_event_create(event_class);
+ struct bt_ctf_field *integer =
+ bt_ctf_field_create(ep_field_1_type);
+ struct bt_ctf_field *string =
+ bt_ctf_field_create(ep_a_string_type);
+
+ ret |= bt_ctf_clock_set_time(clock, ++current_time);
+ ret |= bt_ctf_field_integer_unsigned_set_value(integer, i);
+ ret |= bt_ctf_event_set_payload(event, "field_1",
+ integer);
+ bt_ctf_object_put_ref(integer);
+ ret |= bt_ctf_field_string_set_value(string, "This is a test");
+ ret |= bt_ctf_event_set_payload(event, "a_string",
+ string);
+ bt_ctf_object_put_ref(string);
+
+ /* Populate stream event context */
+ stream_event_context =
+ bt_ctf_event_get_stream_event_context(event);
+ integer = bt_ctf_field_structure_get_field_by_name(stream_event_context,
+ "common_event_context");
+ BT_CTF_OBJECT_PUT_REF_AND_RESET(stream_event_context);
+ ret |= bt_ctf_field_integer_unsigned_set_value(integer,
+ i % 42);
+ bt_ctf_object_put_ref(integer);
+
+ ret |= bt_ctf_stream_append_event(stream, event);
+ bt_ctf_object_put_ref(event);
+
+ if (ret) {
+ break;
+ }
+ }
+
+ events_appended = !!(i == packet_resize_test_length);
+ ret = bt_ctf_stream_get_discarded_events_count(stream, &ret_uint64);
+ ok(ret == 0 && ret_uint64 == 0,
+ "bt_ctf_stream_get_discarded_events_count returns a correct number of discarded events when none were discarded");
+ bt_ctf_stream_append_discarded_events(stream, 1000);
+ ret = bt_ctf_stream_get_discarded_events_count(stream, &ret_uint64);
+ ok(ret == 0 && ret_uint64 == 1000,
+ "bt_ctf_stream_get_discarded_events_count returns a correct number of discarded events when some were discarded");
+
+end:
+ ok(events_appended, "Append 100 000 events to a stream");
+
+ /*
+ * Populate the custom packet context field with a dummy value
+ * otherwise flush will fail.
+ */
+ packet_context = bt_ctf_stream_get_packet_context(stream);
+ packet_context_field = bt_ctf_field_structure_get_field_by_name(packet_context,
+ "custom_packet_context_field");
+ bt_ctf_field_integer_unsigned_set_value(packet_context_field, 2);
+
+ ok(bt_ctf_stream_flush(stream) == 0,
+ "Flush a stream that forces a packet resize");
+ ret = bt_ctf_stream_get_discarded_events_count(stream, &ret_uint64);
+ ok(ret == 0 && ret_uint64 == 1000,
+ "bt_ctf_stream_get_discarded_events_count returns a correct number of discarded events after a flush");
+ bt_ctf_object_put_ref(integer_type);
+ bt_ctf_object_put_ref(string_type);
+ bt_ctf_object_put_ref(packet_context);
+ bt_ctf_object_put_ref(packet_context_field);
+ bt_ctf_object_put_ref(stream_event_context);
+ bt_ctf_object_put_ref(event_class);
+ bt_ctf_object_put_ref(ep_field_1_type);
+ bt_ctf_object_put_ref(ep_a_string_type);
+ bt_ctf_object_put_ref(ep_type);
+}
+
+static
+void test_empty_stream(struct bt_ctf_writer *writer)
+{
+ int ret = 0;
+ struct bt_ctf_trace *trace = NULL, *ret_trace = NULL;
+ struct bt_ctf_stream_class *stream_class = NULL;
+ struct bt_ctf_stream *stream = NULL;
+
+ trace = bt_ctf_writer_get_trace(writer);
+ if (!trace) {
+ diag("Failed to get trace from writer");
+ ret = -1;
+ goto end;
+ }
+
+ stream_class = bt_ctf_stream_class_create("empty_stream");
+ if (!stream_class) {
+ diag("Failed to create stream class");
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_stream_class_set_packet_context_type(stream_class, NULL);
+ BT_ASSERT(ret == 0);
+ ret = bt_ctf_stream_class_set_event_header_type(stream_class, NULL);
+ BT_ASSERT(ret == 0);
+
+ ok(!bt_ctf_stream_class_get_trace(stream_class),
+ "bt_ctf_stream_class_get_trace returns NULL when stream class is orphaned");
+
+ stream = bt_ctf_writer_create_stream(writer, stream_class);
+ if (!stream) {
+ diag("Failed to create writer stream");
+ ret = -1;
+ goto end;
+ }
+
+ ret_trace = bt_ctf_stream_class_get_trace(stream_class);
+ ok(ret_trace == trace,
+ "bt_ctf_stream_class_get_trace returns the correct trace after a stream has been created");
+end:
+ ok(ret == 0,
+ "Created a stream class with default attributes and an empty stream");
+ bt_ctf_object_put_ref(trace);
+ bt_ctf_object_put_ref(ret_trace);
+ bt_ctf_object_put_ref(stream);
+ bt_ctf_object_put_ref(stream_class);
+}
+
+static
+void test_custom_event_header_stream(struct bt_ctf_writer *writer,
+ struct bt_ctf_clock *clock)
+{
+ int i, ret;
+ struct bt_ctf_stream_class *stream_class = NULL;
+ struct bt_ctf_stream *stream = NULL;
+ struct bt_ctf_field_type *integer_type = NULL,
+ *sequence_type = NULL, *event_header_type = NULL;
+ struct bt_ctf_field *integer = NULL, *sequence = NULL,
+ *event_header = NULL, *packet_header = NULL;
+ struct bt_ctf_event_class *event_class = NULL;
+ struct bt_ctf_event *event = NULL;
+
+ stream_class = bt_ctf_stream_class_create("custom_event_header_stream");
+ if (!stream_class) {
+ fail("Failed to create stream class");
+ goto end;
+ }
+
+ ret = bt_ctf_stream_class_set_clock(stream_class, clock);
+ if (ret) {
+ fail("Failed to set stream class clock");
+ goto end;
+ }
+
+ /*
+ * Customize event header to add an "seq_len" integer member
+ * which will be used as the length of a sequence in an event of this
+ * stream.
+ */
+ event_header_type = bt_ctf_stream_class_get_event_header_type(
+ stream_class);
+ if (!event_header_type) {
+ fail("Failed to get event header type");
+ goto end;
+ }
+
+ integer_type = bt_ctf_field_type_integer_create(13);
+ if (!integer_type) {
+ fail("Failed to create length integer type");
+ goto end;
+ }
+
+ ret = bt_ctf_field_type_structure_add_field(event_header_type,
+ integer_type, "seq_len");
+ if (ret) {
+ fail("Failed to add a new field to stream event header");
+ goto end;
+ }
+
+ event_class = bt_ctf_event_class_create("sequence_event");
+ if (!event_class) {
+ fail("Failed to create event class");
+ goto end;
+ }
+
+ /*
+ * This event's payload will contain a sequence which references
+ * stream.event.header.seq_len as its length field.
+ */
+ sequence_type = bt_ctf_field_type_sequence_create(integer_type,
+ "stream.event.header.seq_len");
+ if (!sequence_type) {
+ fail("Failed to create a sequence");
+ goto end;
+ }
+
+ ret = bt_ctf_event_class_add_field(event_class, sequence_type,
+ "some_sequence");
+ if (ret) {
+ fail("Failed to add a sequence to an event class");
+ goto end;
+ }
+
+ ret = bt_ctf_stream_class_add_event_class(stream_class, event_class);
+ if (ret) {
+ fail("Failed to add event class to stream class");
+ goto end;
+ }
+
+ stream = bt_ctf_writer_create_stream(writer, stream_class);
+ if (!stream) {
+ fail("Failed to create stream")
+ goto end;
+ }
+
+ /*
+ * We have defined a custom packet header field. We have to populate it
+ * explicitly.
+ */
+ packet_header = bt_ctf_stream_get_packet_header(stream);
+ if (!packet_header) {
+ fail("Failed to get stream packet header");
+ goto end;
+ }
+
+ integer = bt_ctf_field_structure_get_field_by_name(packet_header,
+ "custom_trace_packet_header_field");
+ if (!integer) {
+ fail("Failed to retrieve custom_trace_packet_header_field");
+ goto end;
+ }
+
+ ret = bt_ctf_field_integer_unsigned_set_value(integer, 3487);
+ if (ret) {
+ fail("Failed to set custom_trace_packet_header_field value");
+ goto end;
+ }
+ bt_ctf_object_put_ref(integer);
+
+ event = bt_ctf_event_create(event_class);
+ if (!event) {
+ fail("Failed to create event");
+ goto end;
+ }
+
+ event_header = bt_ctf_event_get_header(event);
+ if (!event_header) {
+ fail("Failed to get event header");
+ goto end;
+ }
+
+ integer = bt_ctf_field_structure_get_field_by_name(event_header,
+ "seq_len");
+ if (!integer) {
+ fail("Failed to get seq_len field from event header");
+ goto end;
+ }
+
+ ret = bt_ctf_field_integer_unsigned_set_value(integer, 2);
+ if (ret) {
+ fail("Failed to set seq_len value in event header");
+ goto end;
+ }
+
+ /* Populate both sequence integer fields */
+ sequence = bt_ctf_event_get_payload(event, "some_sequence");
+ if (!sequence) {
+ fail("Failed to retrieve sequence from event");
+ goto end;
+ }
+
+ ret = bt_ctf_field_sequence_set_length(sequence, integer);
+ if (ret) {
+ fail("Failed to set sequence length");
+ goto end;
+ }
+ bt_ctf_object_put_ref(integer);
+
+ for (i = 0; i < 2; i++) {
+ integer = bt_ctf_field_sequence_get_field(sequence, i);
+ if (ret) {
+ fail("Failed to retrieve sequence element");
+ goto end;
+ }
+
+ ret = bt_ctf_field_integer_unsigned_set_value(integer, i);
+ if (ret) {
+ fail("Failed to set sequence element value");
+ goto end;
+ }
+
+ bt_ctf_object_put_ref(integer);
+ integer = NULL;
+ }
+
+ ret = bt_ctf_stream_append_event(stream, event);
+ if (ret) {
+ fail("Failed to append event to stream");
+ goto end;
+ }
+
+ ret = bt_ctf_stream_flush(stream);
+ if (ret) {
+ fail("Failed to flush custom_event_header stream");
+ }
+end:
+ bt_ctf_object_put_ref(stream);
+ bt_ctf_object_put_ref(stream_class);
+ bt_ctf_object_put_ref(event_class);
+ bt_ctf_object_put_ref(event);
+ bt_ctf_object_put_ref(integer);
+ bt_ctf_object_put_ref(sequence);
+ bt_ctf_object_put_ref(event_header);
+ bt_ctf_object_put_ref(packet_header);
+ bt_ctf_object_put_ref(sequence_type);
+ bt_ctf_object_put_ref(integer_type);
+ bt_ctf_object_put_ref(event_header_type);
+}
+
+static
+void test_instanciate_event_before_stream(struct bt_ctf_writer *writer,
+ struct bt_ctf_clock *clock)
+{
+ int ret = 0;
+ struct bt_ctf_stream_class *stream_class = NULL;
+ struct bt_ctf_stream *stream = NULL,
+ *ret_stream = NULL;
+ struct bt_ctf_event_class *event_class = NULL;
+ struct bt_ctf_event *event = NULL;
+ struct bt_ctf_field_type *integer_type = NULL;
+ struct bt_ctf_field *payload_field = NULL;
+ struct bt_ctf_field *integer = NULL;
+
+ stream_class = bt_ctf_stream_class_create("event_before_stream_test");
+ if (!stream_class) {
+ diag("Failed to create stream class");
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_stream_class_set_clock(stream_class, clock);
+ if (ret) {
+ diag("Failed to set stream class clock");
+ goto end;
+ }
+
+ event_class = bt_ctf_event_class_create("some_event_class_name");
+ integer_type = bt_ctf_field_type_integer_create(32);
+ if (!integer_type) {
+ diag("Failed to create integer field type");
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_event_class_add_field(event_class, integer_type,
+ "integer_field");
+ if (ret) {
+ diag("Failed to add field to event class");
+ goto end;
+ }
+
+ ret = bt_ctf_stream_class_add_event_class(stream_class,
+ event_class);
+ if (ret) {
+ diag("Failed to add event class to stream class");
+ }
+
+ event = bt_ctf_event_create(event_class);
+ if (!event) {
+ diag("Failed to create event");
+ ret = -1;
+ goto end;
+ }
+
+ payload_field = bt_ctf_event_get_payload_field(event);
+ if (!payload_field) {
+ diag("Failed to get event's payload field");
+ ret = -1;
+ goto end;
+ }
+
+ integer = bt_ctf_field_structure_get_field_by_index(payload_field, 0);
+ if (!integer) {
+ diag("Failed to get integer field payload from event");
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_field_integer_unsigned_set_value(integer, 1234);
+ if (ret) {
+ diag("Failed to set integer field value");
+ goto end;
+ }
+
+ stream = bt_ctf_writer_create_stream(writer, stream_class);
+ if (!stream) {
+ diag("Failed to create writer stream");
+ ret = -1;
+ goto end;
+ }
+
+ ret = bt_ctf_stream_append_event(stream, event);
+ if (ret) {
+ diag("Failed to append event to stream");
+ goto end;
+ }
+
+ ret_stream = bt_ctf_event_get_stream(event);
+ ok(ret_stream == stream,
+ "bt_ctf_event_get_stream returns an event's stream after it has been appended");
+end:
+ ok(ret == 0,
+ "Create an event before instanciating its associated stream");
+ bt_ctf_object_put_ref(stream);
+ bt_ctf_object_put_ref(ret_stream);
+ bt_ctf_object_put_ref(stream_class);
+ bt_ctf_object_put_ref(event_class);
+ bt_ctf_object_put_ref(event);
+ bt_ctf_object_put_ref(integer_type);
+ bt_ctf_object_put_ref(integer);
+ bt_ctf_object_put_ref(payload_field);
+}
+
+static
+void append_existing_event_class(struct bt_ctf_stream_class *stream_class)
+{
+ int ret;
+ struct bt_ctf_event_class *event_class;
+
+ event_class = bt_ctf_event_class_create("Simple Event");
+ BT_ASSERT(event_class);
+ ok(bt_ctf_stream_class_add_event_class(stream_class, event_class) == 0,
+ "two event classes with the same name may cohabit within the same stream class");
+ bt_ctf_object_put_ref(event_class);
+
+ event_class = bt_ctf_event_class_create("different name, ok");
+ BT_ASSERT(event_class);
+ ret = bt_ctf_event_class_set_id(event_class, 13);
+ BT_ASSERT(ret == 0);
+ ok(bt_ctf_stream_class_add_event_class(stream_class, event_class),
+ "two event classes with the same ID cannot cohabit within the same stream class");
+ bt_ctf_object_put_ref(event_class);
+}
+
+static
+void test_clock_utils(void)
+{
+ int ret;
+ struct bt_ctf_clock *clock = NULL;
+
+ clock = bt_ctf_clock_create("water");
+ BT_ASSERT(clock);
+ ret = bt_ctf_clock_set_offset_s(clock, 1234);
+ BT_ASSERT(!ret);
+ ret = bt_ctf_clock_set_offset(clock, 1000);
+ BT_ASSERT(!ret);
+ ret = bt_ctf_clock_set_frequency(clock, 1000000000);
+ BT_ASSERT(!ret);
+ ret = bt_ctf_clock_set_frequency(clock, 1534);
+ BT_ASSERT(!ret);
+
+ BT_CTF_OBJECT_PUT_REF_AND_RESET(clock);
+}
+
+int main(int argc, char **argv)
+{
+ const char *env_resize_length;
+ gchar *trace_path;
+ gchar *metadata_path;
+ const char *clock_name = "test_clock";
+ const char *clock_description = "This is a test clock";
+ const char *returned_clock_name;
+ const char *returned_clock_description;
+ const uint64_t frequency = 1123456789;
+ const int64_t offset_s = 13515309;
+ const int64_t offset = 1234567;
+ int64_t get_offset_s,
+ get_offset;
+ const uint64_t precision = 10;
+ const int is_absolute = 0xFF;
+ char *metadata_string;
+ struct bt_ctf_writer *writer;
+ struct bt_utsname name = {"GNU/Linux", "testhost", "4.4.0-87-generic",
+ "#110-Ubuntu SMP Tue Jul 18 12:55:35 UTC 2017", "x86_64"};
+ struct bt_ctf_clock *clock, *ret_clock;
+ struct bt_ctf_stream_class *stream_class, *ret_stream_class;
+ struct bt_ctf_stream *stream1;
+ struct bt_ctf_stream *stream;
+ const char *ret_string;
+ const uint8_t *ret_uuid;
+ bt_uuid_t tmp_uuid = { 0 };
+ struct bt_ctf_field_type *packet_context_type,
+ *packet_context_field_type,
+ *packet_header_type,
+ *packet_header_field_type,
+ *integer_type,
+ *stream_event_context_type,
+ *ret_field_type,
+ *event_header_field_type;
+ struct bt_ctf_field *packet_header, *packet_header_field;
+ struct bt_ctf_trace *trace;
+ int ret;
+
+ if (argc < 2) {
+ printf("Usage: tests-ctf-writer path_to_babeltrace\n");
+ return -1;
+ }
+
+ env_resize_length = getenv("PACKET_RESIZE_TEST_LENGTH");
+ if (env_resize_length) {
+ packet_resize_test_length =
+ (unsigned int) atoi(env_resize_length);
+ }
+
+ plan_tests(NR_TESTS);
+
+ trace_path = g_build_filename(g_get_tmp_dir(), "ctfwriter_XXXXXX", NULL);
+ if (!bt_mkdtemp(trace_path)) {
+ perror("# perror");
+ }
+
+ metadata_path = g_build_filename(trace_path, "metadata", NULL);
+
+ writer = bt_ctf_writer_create(trace_path);
+ ok(writer, "bt_ctf_create succeeds in creating trace with path");
+
+ ok(!bt_ctf_writer_get_trace(NULL),
+ "bt_ctf_writer_get_trace correctly handles NULL");
+ trace = bt_ctf_writer_get_trace(writer);
+ ok(bt_ctf_trace_set_native_byte_order(trace, BT_CTF_BYTE_ORDER_NATIVE),
+ "Cannot set a trace's byte order to BT_CTF_BYTE_ORDER_NATIVE");
+ ok(bt_ctf_trace_set_native_byte_order(trace, BT_CTF_BYTE_ORDER_UNSPECIFIED),
+ "Cannot set a trace's byte order to BT_CTF_BYTE_ORDER_UNSPECIFIED");
+ ok(trace,
+ "bt_ctf_writer_get_trace returns a bt_ctf_trace object");
+ ok(bt_ctf_trace_set_native_byte_order(trace, BT_CTF_BYTE_ORDER_BIG_ENDIAN) == 0,
+ "Set a trace's byte order to big endian");
+ ok(bt_ctf_trace_get_native_byte_order(trace) == BT_CTF_BYTE_ORDER_BIG_ENDIAN,
+ "bt_ctf_trace_get_native_byte_order returns a correct endianness");
+
+ /* Add environment context to the trace */
+ ok(bt_ctf_writer_add_environment_field(writer, "host", name.nodename) == 0,
+ "Add host (%s) environment field to writer instance",
+ name.nodename);
+ ok(bt_ctf_writer_add_environment_field(NULL, "test_field",
+ "test_value"),
+ "bt_ctf_writer_add_environment_field error with NULL writer");
+ ok(bt_ctf_writer_add_environment_field(writer, NULL,
+ "test_value"),
+ "bt_ctf_writer_add_environment_field error with NULL field name");
+ ok(bt_ctf_writer_add_environment_field(writer, "test_field",
+ NULL),
+ "bt_ctf_writer_add_environment_field error with NULL field value");
+
+ /* Test bt_ctf_trace_set_environment_field_integer */
+ ok(bt_ctf_trace_set_environment_field_integer(NULL, "test_env_int",
+ -194875),
+ "bt_ctf_trace_set_environment_field_integer handles a NULL trace correctly");
+ ok(bt_ctf_trace_set_environment_field_integer(trace, NULL, -194875),
+ "bt_ctf_trace_set_environment_field_integer handles a NULL name correctly");
+ ok(!bt_ctf_trace_set_environment_field_integer(trace, "test_env_int",
+ -164973),
+ "bt_ctf_trace_set_environment_field_integer succeeds");
+
+ /* Test bt_ctf_trace_set_environment_field_string */
+ ok(bt_ctf_trace_set_environment_field_string(NULL, "test_env_str",
+ "yeah"),
+ "bt_ctf_trace_set_environment_field_string handles a NULL trace correctly");
+ ok(bt_ctf_trace_set_environment_field_string(trace, NULL, "yeah"),
+ "bt_ctf_trace_set_environment_field_string handles a NULL name correctly");
+ ok(bt_ctf_trace_set_environment_field_string(trace, "test_env_str",
+ NULL),
+ "bt_ctf_trace_set_environment_field_string handles a NULL value correctly");
+ ok(!bt_ctf_trace_set_environment_field_string(trace, "test_env_str",
+ "oh yeah"),
+ "bt_ctf_trace_set_environment_field_string succeeds");
+
+ /* Test environment field replacement */
+ ok(!bt_ctf_trace_set_environment_field_integer(trace, "test_env_int",
+ 654321),
+ "bt_ctf_trace_set_environment_field_integer succeeds with an existing name");
+
+ ok(bt_ctf_writer_add_environment_field(writer, "sysname", name.sysname)
+ == 0, "Add sysname (%s) environment field to writer instance",
+ name.sysname);
+ ok(bt_ctf_writer_add_environment_field(writer, "nodename",
+ name.nodename) == 0,
+ "Add nodename (%s) environment field to writer instance",
+ name.nodename);
+ ok(bt_ctf_writer_add_environment_field(writer, "release", name.release)
+ == 0, "Add release (%s) environment field to writer instance",
+ name.release);
+ ok(bt_ctf_writer_add_environment_field(writer, "version", name.version)
+ == 0, "Add version (%s) environment field to writer instance",
+ name.version);
+ ok(bt_ctf_writer_add_environment_field(writer, "machine", name.machine)
+ == 0, "Add machine (%s) environment field to writer istance",
+ name.machine);
+
+ /* Define a clock and add it to the trace */
+ ok(!bt_ctf_clock_create("signed"),
+ "Illegal clock name rejected");
+ clock = bt_ctf_clock_create(clock_name);
+ ok(clock, "Clock created sucessfully");
+ returned_clock_name = bt_ctf_clock_get_name(clock);
+ ok(returned_clock_name, "bt_ctf_clock_get_name returns a clock name");
+ ok(returned_clock_name ? strcmp(returned_clock_name, clock_name) == 0 : 0,
+ "Returned clock name is valid");
+
+ returned_clock_description = bt_ctf_clock_get_description(clock);
+ ok(!returned_clock_description, "bt_ctf_clock_get_description returns NULL on an unset description");
+ ok(bt_ctf_clock_set_description(clock, clock_description) == 0,
+ "Clock description set successfully");
+
+ returned_clock_description = bt_ctf_clock_get_description(clock);
+ ok(returned_clock_description,
+ "bt_ctf_clock_get_description returns a description.");
+ ok(returned_clock_description ?
+ strcmp(returned_clock_description, clock_description) == 0 : 0,
+ "Returned clock description is valid");
+
+ ok(bt_ctf_clock_get_frequency(clock) == DEFAULT_CLOCK_FREQ,
+ "bt_ctf_clock_get_frequency returns the correct default frequency");
+ ok(bt_ctf_clock_set_frequency(clock, frequency) == 0,
+ "Set clock frequency");
+ ok(bt_ctf_clock_get_frequency(clock) == frequency,
+ "bt_ctf_clock_get_frequency returns the correct frequency once it is set");
+
+ ok(bt_ctf_clock_get_offset_s(clock, &get_offset_s) == 0,
+ "bt_ctf_clock_get_offset_s succeeds");
+ ok(get_offset_s == DEFAULT_CLOCK_OFFSET_S,
+ "bt_ctf_clock_get_offset_s returns the correct default offset (in seconds)");
+ ok(bt_ctf_clock_set_offset_s(clock, offset_s) == 0,
+ "Set clock offset (seconds)");
+ ok(bt_ctf_clock_get_offset_s(clock, &get_offset_s) == 0,
+ "bt_ctf_clock_get_offset_s succeeds");
+ ok(get_offset_s == offset_s,
+ "bt_ctf_clock_get_offset_s returns the correct default offset (in seconds) once it is set");
+
+ ok(bt_ctf_clock_get_offset(clock, &get_offset) == 0,
+ "bt_ctf_clock_get_offset succeeds");
+ ok(get_offset == DEFAULT_CLOCK_OFFSET,
+ "bt_ctf_clock_get_offset returns the correct default offset (in ticks)");
+ ok(bt_ctf_clock_set_offset(clock, offset) == 0, "Set clock offset");
+ ok(bt_ctf_clock_get_offset(clock, &get_offset) == 0,
+ "bt_ctf_clock_get_offset succeeds");
+ ok(get_offset == offset,
+ "bt_ctf_clock_get_offset returns the correct default offset (in ticks) once it is set");
+
+ ok(bt_ctf_clock_get_precision(clock) == DEFAULT_CLOCK_PRECISION,
+ "bt_ctf_clock_get_precision returns the correct default precision");
+ ok(bt_ctf_clock_set_precision(clock, precision) == 0,
+ "Set clock precision");
+ ok(bt_ctf_clock_get_precision(clock) == precision,
+ "bt_ctf_clock_get_precision returns the correct precision once it is set");
+
+ ok(bt_ctf_clock_get_is_absolute(clock) == DEFAULT_CLOCK_IS_ABSOLUTE,
+ "bt_ctf_clock_get_precision returns the correct default is_absolute attribute");
+ ok(bt_ctf_clock_set_is_absolute(clock, is_absolute) == 0,
+ "Set clock absolute property");
+ ok(bt_ctf_clock_get_is_absolute(clock) == !!is_absolute,
+ "bt_ctf_clock_get_precision returns the correct is_absolute attribute once it is set");
+ ok(bt_ctf_clock_set_time(clock, current_time) == 0,
+ "Set clock time");
+ ret_uuid = bt_ctf_clock_get_uuid(clock);
+ ok(ret_uuid,
+ "bt_ctf_clock_get_uuid returns a UUID");
+ if (ret_uuid) {
+ memcpy(tmp_uuid, ret_uuid, sizeof(tmp_uuid));
+ /* Slightly modify UUID */
+ tmp_uuid[sizeof(tmp_uuid) - 1]++;
+ }
+
+ ok(bt_ctf_clock_set_uuid(clock, tmp_uuid) == 0,
+ "bt_ctf_clock_set_uuid sets a new uuid successfully");
+ ret_uuid = bt_ctf_clock_get_uuid(clock);
+ ok(ret_uuid,
+ "bt_ctf_clock_get_uuid returns a UUID after setting a new one");
+ ok(uuid_match(ret_uuid, tmp_uuid),
+ "bt_ctf_clock_get_uuid returns the correct UUID after setting a new one");
+
+ /* Define a stream class */
+ stream_class = bt_ctf_stream_class_create("test_stream");
+ ret_string = bt_ctf_stream_class_get_name(stream_class);
+ ok(ret_string && strcmp(ret_string, "test_stream") == 0,
+ "bt_ctf_stream_class_get_name returns a correct stream class name");
+
+ ok(!bt_ctf_stream_class_get_clock(stream_class),
+ "bt_ctf_stream_class_get_clock returns NULL when a clock was not set");
+ ok(!bt_ctf_stream_class_get_clock(NULL),
+ "bt_ctf_stream_class_get_clock handles NULL correctly");
+
+ ok(stream_class, "Create stream class");
+ ok(bt_ctf_stream_class_set_clock(stream_class, clock) == 0,
+ "Set a stream class' clock");
+ ret_clock = bt_ctf_stream_class_get_clock(stream_class);
+ ok(ret_clock == clock,
+ "bt_ctf_stream_class_get_clock returns a correct clock");
+ bt_ctf_object_put_ref(ret_clock);
+
+ /* Test the event fields and event types APIs */
+ type_field_tests();
+
+ ok(bt_ctf_stream_class_get_id(stream_class) < 0,
+ "bt_ctf_stream_class_get_id returns an error when no id is set");
+ ok(bt_ctf_stream_class_set_id(NULL, 123) < 0,
+ "bt_ctf_stream_class_set_id handles NULL correctly");
+ ok(bt_ctf_stream_class_set_id(stream_class, 123) == 0,
+ "Set an stream class' id");
+ ok(bt_ctf_stream_class_get_id(stream_class) == 123,
+ "bt_ctf_stream_class_get_id returns the correct value");
+
+ /* Validate default event header fields */
+ ret_field_type = bt_ctf_stream_class_get_event_header_type(
+ stream_class);
+ ok(ret_field_type,
+ "bt_ctf_stream_class_get_event_header_type returns an event header type");
+ ok(bt_ctf_field_type_get_type_id(ret_field_type) == BT_CTF_FIELD_TYPE_ID_STRUCT,
+ "Default event header type is a structure");
+ event_header_field_type =
+ bt_ctf_field_type_structure_get_field_type_by_name(
+ ret_field_type, "id");
+ ok(event_header_field_type,
+ "Default event header type contains an \"id\" field");
+ ok(bt_ctf_field_type_get_type_id(
+ event_header_field_type) == BT_CTF_FIELD_TYPE_ID_INTEGER,
+ "Default event header \"id\" field is an integer");
+ bt_ctf_object_put_ref(event_header_field_type);
+ event_header_field_type =
+ bt_ctf_field_type_structure_get_field_type_by_name(
+ ret_field_type, "timestamp");
+ ok(event_header_field_type,
+ "Default event header type contains a \"timestamp\" field");
+ ok(bt_ctf_field_type_get_type_id(
+ event_header_field_type) == BT_CTF_FIELD_TYPE_ID_INTEGER,
+ "Default event header \"timestamp\" field is an integer");
+ bt_ctf_object_put_ref(event_header_field_type);
+ bt_ctf_object_put_ref(ret_field_type);
+
+ /* Add a custom trace packet header field */
+ packet_header_type = bt_ctf_trace_get_packet_header_field_type(trace);
+ ok(packet_header_type,
+ "bt_ctf_trace_get_packet_header_field_type returns a packet header");
+ ok(bt_ctf_field_type_get_type_id(packet_header_type) == BT_CTF_FIELD_TYPE_ID_STRUCT,
+ "bt_ctf_trace_get_packet_header_field_type returns a packet header of type struct");
+ ret_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
+ packet_header_type, "magic");
+ ok(ret_field_type, "Default packet header type contains a \"magic\" field");
+ bt_ctf_object_put_ref(ret_field_type);
+ ret_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
+ packet_header_type, "uuid");
+ ok(ret_field_type, "Default packet header type contains a \"uuid\" field");
+ bt_ctf_object_put_ref(ret_field_type);
+ ret_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
+ packet_header_type, "stream_id");
+ ok(ret_field_type, "Default packet header type contains a \"stream_id\" field");
+ bt_ctf_object_put_ref(ret_field_type);
+
+ packet_header_field_type = bt_ctf_field_type_integer_create(22);
+ ok(!bt_ctf_field_type_structure_add_field(packet_header_type,
+ packet_header_field_type, "custom_trace_packet_header_field"),
+ "Added a custom trace packet header field successfully");
+
+ ok(bt_ctf_trace_set_packet_header_field_type(NULL, packet_header_type) < 0,
+ "bt_ctf_trace_set_packet_header_field_type handles a NULL trace correctly");
+ ok(!bt_ctf_trace_set_packet_header_field_type(trace, packet_header_type),
+ "Set a trace packet_header_type successfully");
+
+ /* Add a custom field to the stream class' packet context */
+ packet_context_type = bt_ctf_stream_class_get_packet_context_type(stream_class);
+ ok(packet_context_type,
+ "bt_ctf_stream_class_get_packet_context_type returns a packet context type.");
+ ok(bt_ctf_field_type_get_type_id(packet_context_type) == BT_CTF_FIELD_TYPE_ID_STRUCT,
+ "Packet context is a structure");
+
+ ok(bt_ctf_stream_class_set_packet_context_type(NULL, packet_context_type),
+ "bt_ctf_stream_class_set_packet_context_type handles a NULL stream class correctly");
+
+ integer_type = bt_ctf_field_type_integer_create(32);
+
+ ok(bt_ctf_stream_class_set_packet_context_type(stream_class,
+ integer_type) < 0,
+ "bt_ctf_stream_class_set_packet_context_type rejects a packet context that is not a structure");
+
+ /* Create a "uint5_t" equivalent custom packet context field */
+ packet_context_field_type = bt_ctf_field_type_integer_create(5);
+
+ ret = bt_ctf_field_type_structure_add_field(packet_context_type,
+ packet_context_field_type, "custom_packet_context_field");
+ ok(ret == 0, "Packet context field added successfully");
+
+ /* Define a stream event context containing a my_integer field. */
+ stream_event_context_type = bt_ctf_field_type_structure_create();
+ bt_ctf_field_type_structure_add_field(stream_event_context_type,
+ integer_type, "common_event_context");
+
+ ok(bt_ctf_stream_class_set_event_context_type(NULL,
+ stream_event_context_type) < 0,
+ "bt_ctf_stream_class_set_event_context_type handles a NULL stream_class correctly");
+ ok(bt_ctf_stream_class_set_event_context_type(stream_class,
+ integer_type) < 0,
+ "bt_ctf_stream_class_set_event_context_type validates that the event context os a structure");
+
+ ok(bt_ctf_stream_class_set_event_context_type(
+ stream_class, stream_event_context_type) == 0,
+ "Set a new stream event context type");
+
+ ret_field_type = bt_ctf_stream_class_get_event_context_type(
+ stream_class);
+ ok(ret_field_type == stream_event_context_type,
+ "bt_ctf_stream_class_get_event_context_type returns the correct field type.");
+ bt_ctf_object_put_ref(ret_field_type);
+
+
+ /* Instantiate a stream and append events */
+ ret = bt_ctf_writer_add_clock(writer, clock);
+ BT_ASSERT(ret == 0);
+
+ ok(bt_ctf_trace_get_stream_count(trace) == 0,
+ "bt_ctf_trace_get_stream_count() succeeds and returns the correct value (0)");
+ stream1 = bt_ctf_writer_create_stream(writer, stream_class);
+ ok(stream1, "Instanciate a stream class from writer");
+ ok(bt_ctf_trace_get_stream_count(trace) == 1,
+ "bt_ctf_trace_get_stream_count() succeeds and returns the correct value (1)");
+ stream = bt_ctf_trace_get_stream_by_index(trace, 0);
+ ok(stream == stream1,
+ "bt_ctf_trace_get_stream_by_index() succeeds and returns the correct value");
+ BT_CTF_OBJECT_PUT_REF_AND_RESET(stream);
+
+ /*
+ * Creating a stream through a writer adds the given stream
+ * class to the writer's trace, thus registering the stream
+ * class's clock to the trace.
+ */
+
+ ret_stream_class = bt_ctf_stream_get_class(stream1);
+ ok(ret_stream_class,
+ "bt_ctf_stream_get_class returns a stream class");
+ ok(ret_stream_class == stream_class,
+ "Returned stream class is of the correct type");
+
+ /*
+ * Packet header, packet context, event header, and stream
+ * event context types were copied for the resolving
+ * process
+ */
+ BT_CTF_OBJECT_PUT_REF_AND_RESET(packet_header_type);
+ BT_CTF_OBJECT_PUT_REF_AND_RESET(packet_context_type);
+ BT_CTF_OBJECT_PUT_REF_AND_RESET(stream_event_context_type);
+ packet_header_type = bt_ctf_trace_get_packet_header_field_type(trace);
+ BT_ASSERT(packet_header_type);
+ packet_context_type =
+ bt_ctf_stream_class_get_packet_context_type(stream_class);
+ BT_ASSERT(packet_context_type);
+ stream_event_context_type =
+ bt_ctf_stream_class_get_event_context_type(stream_class);
+ BT_ASSERT(stream_event_context_type);
+
+ /*
+ * Try to modify the packet context type after a stream has been
+ * created.
+ */
+ ret = bt_ctf_field_type_structure_add_field(packet_header_type,
+ packet_header_field_type, "should_fail");
+ ok(ret < 0,
+ "Trace packet header type can't be modified once a stream has been instanciated");
+
+ /*
+ * Try to modify the packet context type after a stream has been
+ * created.
+ */
+ ret = bt_ctf_field_type_structure_add_field(packet_context_type,
+ packet_context_field_type, "should_fail");
+ ok(ret < 0,
+ "Packet context type can't be modified once a stream has been instanciated");
+
+ /*
+ * Try to modify the stream event context type after a stream has been
+ * created.
+ */
+ ret = bt_ctf_field_type_structure_add_field(stream_event_context_type,
+ integer_type, "should_fail");
+ ok(ret < 0,
+ "Stream event context type can't be modified once a stream has been instanciated");
+
+ /* Should fail after instanciating a stream (frozen) */
+ ok(bt_ctf_stream_class_set_clock(stream_class, clock),
+ "Changes to a stream class that was already instantiated fail");
+
+ /* Populate the custom packet header field only once for all tests */
+ ok(!bt_ctf_stream_get_packet_header(NULL),
+ "bt_ctf_stream_get_packet_header handles NULL correctly");
+ packet_header = bt_ctf_stream_get_packet_header(stream1);
+ ok(packet_header,
+ "bt_ctf_stream_get_packet_header returns a packet header");
+ ret_field_type = bt_ctf_field_get_type(packet_header);
+ ok(ret_field_type == packet_header_type,
+ "Stream returns a packet header of the appropriate type");
+ bt_ctf_object_put_ref(ret_field_type);
+ packet_header_field = bt_ctf_field_structure_get_field_by_name(packet_header,
+ "custom_trace_packet_header_field");
+ ok(packet_header_field,
+ "Packet header structure contains a custom field with the appropriate name");
+ ret_field_type = bt_ctf_field_get_type(packet_header_field);
+ ok(!bt_ctf_field_integer_unsigned_set_value(packet_header_field,
+ 54321), "Set custom packet header value successfully");
+ ok(bt_ctf_stream_set_packet_header(stream1, NULL) < 0,
+ "bt_ctf_stream_set_packet_header handles a NULL packet header correctly");
+ ok(bt_ctf_stream_set_packet_header(NULL, packet_header) < 0,
+ "bt_ctf_stream_set_packet_header handles a NULL stream correctly");
+ ok(bt_ctf_stream_set_packet_header(stream1, packet_header_field) < 0,
+ "bt_ctf_stream_set_packet_header rejects a packet header of the wrong type");
+ ok(!bt_ctf_stream_set_packet_header(stream1, packet_header),
+ "Successfully set a stream's packet header");
+
+ ok(bt_ctf_writer_add_environment_field(writer, "new_field", "test") == 0,
+ "Add environment field to writer after stream creation");
+
+ test_clock_utils();
+
+ test_instanciate_event_before_stream(writer, clock);
+
+ append_simple_event(stream_class, stream1, clock);
+
+ packet_resize_test(stream_class, stream1, clock);
+
+ append_complex_event(stream_class, stream1, clock);
+
+ append_existing_event_class(stream_class);
+
+ test_empty_stream(writer);
+
+ test_custom_event_header_stream(writer, clock);
+
+ metadata_string = bt_ctf_writer_get_metadata_string(writer);
+ ok(metadata_string, "Get metadata string");
+
+ bt_ctf_writer_flush_metadata(writer);
+
+ bt_ctf_object_put_ref(clock);
+ bt_ctf_object_put_ref(ret_stream_class);
+ bt_ctf_object_put_ref(writer);
+ bt_ctf_object_put_ref(stream1);
+ bt_ctf_object_put_ref(packet_context_type);
+ bt_ctf_object_put_ref(packet_context_field_type);
+ bt_ctf_object_put_ref(integer_type);
+ bt_ctf_object_put_ref(stream_event_context_type);
+ bt_ctf_object_put_ref(ret_field_type);
+ bt_ctf_object_put_ref(packet_header_type);
+ bt_ctf_object_put_ref(packet_header_field_type);
+ bt_ctf_object_put_ref(packet_header);
+ bt_ctf_object_put_ref(packet_header_field);
+ bt_ctf_object_put_ref(trace);
+ free(metadata_string);
+ bt_ctf_object_put_ref(stream_class);
+
+ validate_trace(argv[1], trace_path);
+
+ recursive_rmdir(trace_path);
+ g_free(trace_path);
+ g_free(metadata_path);
+
+ return exit_status();
+}
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2013-2017 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- */
-
-#include <babeltrace2-ctf-writer/writer.h>
-#include <babeltrace2-ctf-writer/clock.h>
-#include <babeltrace2-ctf-writer/clock-class.h>
-#include <babeltrace2-ctf-writer/stream.h>
-#include <babeltrace2-ctf-writer/event.h>
-#include <babeltrace2-ctf-writer/event-types.h>
-#include <babeltrace2-ctf-writer/event-fields.h>
-#include <babeltrace2-ctf-writer/stream-class.h>
-#include <babeltrace2-ctf-writer/trace.h>
-#include <babeltrace2/babeltrace.h>
-#include <glib.h>
-#include <unistd.h>
-#include "compat/stdlib.h"
-#include <stdio.h>
-#include "compat/limits.h"
-#include "compat/stdio.h"
-#include <string.h>
-#include "common/assert.h"
-#include "common/uuid.h"
-#include <fcntl.h>
-#include "tap/tap.h"
-#include <math.h>
-#include <float.h>
-#include "common.h"
-
-#ifdef __FreeBSD__
-/* Required for WIFEXITED and WEXITSTATUS */
-#include <sys/wait.h>
-#endif
-
-#define METADATA_LINE_SIZE 512
-#define SEQUENCE_TEST_LENGTH 10
-#define ARRAY_TEST_LENGTH 5
-#define PACKET_RESIZE_TEST_DEF_LENGTH 100000
-
-#define DEFAULT_CLOCK_FREQ 1000000000
-#define DEFAULT_CLOCK_PRECISION 1
-#define DEFAULT_CLOCK_OFFSET 0
-#define DEFAULT_CLOCK_OFFSET_S 0
-#define DEFAULT_CLOCK_IS_ABSOLUTE 0
-#define DEFAULT_CLOCK_TIME 0
-#define DEFAULT_CLOCK_VALUE 0
-
-#define NR_TESTS 325
-
-struct bt_utsname {
- char sysname[BABELTRACE_HOST_NAME_MAX];
- char nodename[BABELTRACE_HOST_NAME_MAX];
- char release[BABELTRACE_HOST_NAME_MAX];
- char version[BABELTRACE_HOST_NAME_MAX];
- char machine[BABELTRACE_HOST_NAME_MAX];
-};
-
-static int64_t current_time = 42;
-static unsigned int packet_resize_test_length = PACKET_RESIZE_TEST_DEF_LENGTH;
-
-/* Return 1 if uuids match, zero if different. */
-static
-int uuid_match(const uint8_t *uuid_a, const uint8_t *uuid_b)
-{
- int ret = 0;
- int i;
-
- if (!uuid_a || !uuid_b) {
- goto end;
- }
-
- for (i = 0; i < 16; i++) {
- if (uuid_a[i] != uuid_b[i]) {
- goto end;
- }
- }
-
- ret = 1;
-end:
- return ret;
-}
-
-static
-void validate_trace(char *parser_path, char *trace_path)
-{
- int ret = 0;
- gint exit_status;
- const char *argv[] = {parser_path, trace_path, "-o", "dummy", NULL};
-
- if (!parser_path || !trace_path) {
- ret = -1;
- goto result;
- }
-
- if (!g_spawn_sync(NULL,
- (gchar **) argv,
- NULL,
- G_SPAWN_STDOUT_TO_DEV_NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- &exit_status,
- NULL)) {
- diag("Failed to spawn babeltrace.");
- ret = -1;
- goto result;
- }
-
- /* Replace by g_spawn_check_exit_status when we require glib >= 2.34 */
-#ifdef G_OS_UNIX
- ret = WIFEXITED(exit_status) ? WEXITSTATUS(exit_status) : -1;
-#else
- ret = exit_status;
-#endif
-
- if (ret != 0) {
- diag("Babeltrace returned an error.");
- goto result;
- }
-
-result:
- ok(ret == 0, "Babeltrace could read the resulting trace");
-}
-
-static
-void append_simple_event(struct bt_ctf_stream_class *stream_class,
- struct bt_ctf_stream *stream, struct bt_ctf_clock *clock)
-{
- /* Create and add a simple event class */
- struct bt_ctf_event_class *simple_event_class =
- bt_ctf_event_class_create("Simple Event");
- struct bt_ctf_field_type *uint_12_type =
- bt_ctf_field_type_integer_create(12);
- struct bt_ctf_field_type *int_64_type =
- bt_ctf_field_type_integer_create(64);
- struct bt_ctf_field_type *float_type =
- bt_ctf_field_type_floating_point_create();
- struct bt_ctf_field_type *enum_type;
- struct bt_ctf_field_type *enum_type_unsigned =
- bt_ctf_field_type_enumeration_create(uint_12_type);
- struct bt_ctf_field_type *event_context_type =
- bt_ctf_field_type_structure_create();
- struct bt_ctf_field_type *event_payload_type = NULL;
- struct bt_ctf_field_type *returned_type;
- struct bt_ctf_event *simple_event;
- struct bt_ctf_field *integer_field;
- struct bt_ctf_field *float_field;
- struct bt_ctf_field *enum_field;
- struct bt_ctf_field *enum_field_unsigned;
- struct bt_ctf_field *enum_container_field;
- const char *mapping_name_test = "truie";
- const double double_test_value = 3.1415;
- struct bt_ctf_field *enum_container_field_unsigned;
- const char *mapping_name_negative_test = "negative_value";
- const char *ret_char;
- double ret_double;
- int64_t ret_range_start_int64_t, ret_range_end_int64_t;
- uint64_t ret_range_start_uint64_t, ret_range_end_uint64_t;
- struct bt_ctf_event_class *ret_event_class;
- struct bt_ctf_field *packet_context;
- struct bt_ctf_field *packet_context_field;
- struct bt_ctf_field *stream_event_context;
- struct bt_ctf_field *stream_event_context_field;
- struct bt_ctf_field *event_context;
- struct bt_ctf_field *event_context_field;
- struct bt_ctf_field_type *ep_integer_field_type = NULL;
- struct bt_ctf_field_type *ep_enum_field_type = NULL;
- struct bt_ctf_field_type *ep_enum_field_unsigned_type = NULL;
- struct bt_ctf_field_type_enumeration_mapping_iterator *iter = NULL;
- int ret;
-
- ok(uint_12_type, "Create an unsigned integer type");
-
- ok(!bt_ctf_field_type_integer_set_signed(int_64_type, 1),
- "Set signed 64 bit integer signedness to true");
- ok(int_64_type, "Create a signed integer type");
- enum_type = bt_ctf_field_type_enumeration_create(int_64_type);
-
- returned_type = bt_ctf_field_type_enumeration_get_container_field_type(enum_type);
- ok(returned_type == int_64_type, "bt_ctf_field_type_enumeration_get_container_field_type returns the right type");
- ok(!bt_ctf_field_type_enumeration_create(enum_type),
- "bt_ctf_field_enumeration_type_create rejects non-integer container field types");
- bt_ctf_object_put_ref(returned_type);
-
- bt_ctf_field_type_set_alignment(float_type, 32);
- ok(bt_ctf_field_type_get_alignment(float_type) == 32,
- "bt_ctf_field_type_get_alignment returns a correct value");
-
- ok(bt_ctf_field_type_floating_point_set_exponent_digits(float_type, 11) == 0,
- "Set a floating point type's exponent digit count");
- ok(bt_ctf_field_type_floating_point_set_mantissa_digits(float_type, 53) == 0,
- "Set a floating point type's mantissa digit count");
-
- ok(bt_ctf_field_type_floating_point_get_exponent_digits(float_type) == 11,
- "bt_ctf_field_type_floating_point_get_exponent_digits returns the correct value");
- ok(bt_ctf_field_type_floating_point_get_mantissa_digits(float_type) == 53,
- "bt_ctf_field_type_floating_point_get_mantissa_digits returns the correct value");
-
- ok(bt_ctf_field_type_enumeration_add_mapping(enum_type,
- mapping_name_negative_test, -12345, 0) == 0,
- "bt_ctf_field_type_enumeration_add_mapping accepts negative enumeration mappings");
- ok(bt_ctf_field_type_enumeration_add_mapping(enum_type,
- "escaping; \"test\"", 1, 1) == 0,
- "bt_ctf_field_type_enumeration_add_mapping accepts enumeration mapping strings containing quotes");
- ok(bt_ctf_field_type_enumeration_add_mapping(enum_type,
- "\tanother \'escaping\'\n test\"", 2, 4) == 0,
- "bt_ctf_field_type_enumeration_add_mapping accepts enumeration mapping strings containing special characters");
- ok(bt_ctf_field_type_enumeration_add_mapping(enum_type,
- "event clock int float", 5, 22) == 0,
- "Accept enumeration mapping strings containing reserved keywords");
- bt_ctf_field_type_enumeration_add_mapping(enum_type, mapping_name_test,
- 42, 42);
- ok(bt_ctf_field_type_enumeration_add_mapping(enum_type, mapping_name_test,
- 43, 51) == 0, "bt_ctf_field_type_enumeration_add_mapping accepts duplicate mapping names");
- ok(bt_ctf_field_type_enumeration_add_mapping(enum_type, "something",
- -500, -400) == 0, "bt_ctf_field_type_enumeration_add_mapping accepts overlapping enum entries");
- ok(bt_ctf_field_type_enumeration_add_mapping(enum_type, mapping_name_test,
- -54, -55), "bt_ctf_field_type_enumeration_add_mapping rejects mapping where end < start");
- bt_ctf_field_type_enumeration_add_mapping(enum_type, "another entry", -42000, -13000);
-
- ok(bt_ctf_event_class_add_field(simple_event_class, enum_type,
- "enum_field") == 0, "Add signed enumeration field to event");
-
- ok(bt_ctf_field_type_enumeration_signed_get_mapping_by_index(enum_type, 0, NULL,
- &ret_range_start_int64_t, &ret_range_end_int64_t) == 0,
- "bt_ctf_field_type_enumeration_signed_get_mapping_by_index handles a NULL string correctly");
- ok(bt_ctf_field_type_enumeration_signed_get_mapping_by_index(enum_type, 0, &ret_char,
- NULL, &ret_range_end_int64_t) == 0,
- "bt_ctf_field_type_enumeration_signed_get_mapping_by_index handles a NULL start correctly");
- ok(bt_ctf_field_type_enumeration_signed_get_mapping_by_index(enum_type, 0, &ret_char,
- &ret_range_start_int64_t, NULL) == 0,
- "bt_ctf_field_type_enumeration_signed_get_mapping_by_index handles a NULL end correctly");
- /* Assumes entries are sorted by range_start values. */
- ok(bt_ctf_field_type_enumeration_signed_get_mapping_by_index(enum_type, 6, &ret_char,
- &ret_range_start_int64_t, &ret_range_end_int64_t) == 0,
- "bt_ctf_field_type_enumeration_signed_get_mapping_by_index returns a value");
- ok(strcmp(ret_char, mapping_name_test) == 0,
- "bt_ctf_field_type_enumeration_signed_get_mapping_by_index returns a correct mapping name");
- ok(ret_range_start_int64_t == 42,
- "bt_ctf_field_type_enumeration_signed_get_mapping_by_index returns a correct mapping start");
- ok(ret_range_end_int64_t == 42,
- "bt_ctf_field_type_enumeration_signed_get_mapping_by_index returns a correct mapping end");
-
- ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned,
- "escaping; \"test\"", 0, 0) == 0,
- "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts enumeration mapping strings containing quotes");
- ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned,
- "\tanother \'escaping\'\n test\"", 1, 4) == 0,
- "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts enumeration mapping strings containing special characters");
- ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned,
- "event clock int float", 5, 22) == 0,
- "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts enumeration mapping strings containing reserved keywords");
- ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned, mapping_name_test,
- 42, 42) == 0, "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts single-value ranges");
- ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned, mapping_name_test,
- 43, 51) == 0, "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts duplicate mapping names");
- ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned, "something",
- 7, 8) == 0, "bt_ctf_field_type_enumeration_unsigned_add_mapping accepts overlapping enum entries");
- ok(bt_ctf_field_type_enumeration_unsigned_add_mapping(enum_type_unsigned, mapping_name_test,
- 55, 54), "bt_ctf_field_type_enumeration_unsigned_add_mapping rejects mapping where end < start");
- ok(bt_ctf_event_class_add_field(simple_event_class, enum_type_unsigned,
- "enum_field_unsigned") == 0, "Add unsigned enumeration field to event");
-
- ok(bt_ctf_field_type_enumeration_get_mapping_count(enum_type_unsigned) == 6,
- "bt_ctf_field_type_enumeration_get_mapping_count returns the correct value");
-
- ok(bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index(enum_type_unsigned, 0, NULL,
- &ret_range_start_uint64_t, &ret_range_end_uint64_t) == 0,
- "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index handles a NULL string correctly");
- ok(bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index(enum_type_unsigned, 0, &ret_char,
- NULL, &ret_range_end_uint64_t) == 0,
- "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index handles a NULL start correctly");
- ok(bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index(enum_type_unsigned, 0, &ret_char,
- &ret_range_start_uint64_t, NULL) == 0,
- "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index handles a NULL end correctly");
- ok(bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index(enum_type_unsigned, 4, &ret_char,
- &ret_range_start_uint64_t, &ret_range_end_uint64_t) == 0,
- "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index returns a value");
- ok(strcmp(ret_char, mapping_name_test) == 0,
- "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index returns a correct mapping name");
- ok(ret_range_start_uint64_t == 42,
- "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index returns a correct mapping start");
- ok(ret_range_end_uint64_t == 42,
- "bt_ctf_field_type_enumeration_unsigned_get_mapping_by_index returns a correct mapping end");
-
- bt_ctf_event_class_add_field(simple_event_class, uint_12_type,
- "integer_field");
- bt_ctf_event_class_add_field(simple_event_class, float_type,
- "float_field");
-
- ret = bt_ctf_event_class_set_id(simple_event_class, 13);
- BT_ASSERT(ret == 0);
-
- /* Set an event context type which will contain a single integer. */
- ok(!bt_ctf_field_type_structure_add_field(event_context_type, uint_12_type,
- "event_specific_context"),
- "Add event specific context field");
-
- ok(bt_ctf_event_class_set_context_field_type(NULL, event_context_type) < 0,
- "bt_ctf_event_class_set_context_field_type handles a NULL event class correctly");
- ok(!bt_ctf_event_class_set_context_field_type(simple_event_class, event_context_type),
- "Set an event class' context type successfully");
- returned_type = bt_ctf_event_class_get_context_field_type(simple_event_class);
- ok(returned_type == event_context_type,
- "bt_ctf_event_class_get_context_field_type returns the appropriate type");
- bt_ctf_object_put_ref(returned_type);
-
- ok(!bt_ctf_stream_class_add_event_class(stream_class, simple_event_class),
- "Adding simple event class to stream class");
-
- /*
- * bt_ctf_stream_class_add_event_class() copies the field types
- * of simple_event_class, so we retrieve the new ones to create
- * the appropriate fields.
- */
- BT_CTF_OBJECT_PUT_REF_AND_RESET(event_context_type);
- BT_CTF_OBJECT_PUT_REF_AND_RESET(event_payload_type);
- event_payload_type = bt_ctf_event_class_get_payload_field_type(
- simple_event_class);
- BT_ASSERT(event_payload_type);
- event_context_type = bt_ctf_event_class_get_context_field_type(
- simple_event_class);
- BT_ASSERT(event_context_type);
- ep_integer_field_type =
- bt_ctf_field_type_structure_get_field_type_by_name(
- event_payload_type, "integer_field");
- BT_ASSERT(ep_integer_field_type);
- ep_enum_field_type =
- bt_ctf_field_type_structure_get_field_type_by_name(
- event_payload_type, "enum_field");
- BT_ASSERT(ep_enum_field_type);
- ep_enum_field_unsigned_type =
- bt_ctf_field_type_structure_get_field_type_by_name(
- event_payload_type, "enum_field_unsigned");
- BT_ASSERT(ep_enum_field_unsigned_type);
-
- ok(bt_ctf_stream_class_get_event_class_count(stream_class) == 1,
- "bt_ctf_stream_class_get_event_class_count returns a correct number of event classes");
- ret_event_class = bt_ctf_stream_class_get_event_class_by_index(stream_class, 0);
- ok(ret_event_class == simple_event_class,
- "bt_ctf_stream_class_get_event_class returns the correct event class");
- bt_ctf_object_put_ref(ret_event_class);
- ok(!bt_ctf_stream_class_get_event_class_by_id(stream_class, 2),
- "bt_ctf_stream_class_get_event_class_by_id returns NULL when the requested ID doesn't exist");
- ret_event_class =
- bt_ctf_stream_class_get_event_class_by_id(stream_class, 13);
- ok(ret_event_class == simple_event_class,
- "bt_ctf_stream_class_get_event_class_by_id returns a correct event class");
- bt_ctf_object_put_ref(ret_event_class);
-
- simple_event = bt_ctf_event_create(simple_event_class);
- ok(simple_event,
- "Instantiate an event containing a single integer field");
-
- integer_field = bt_ctf_field_create(ep_integer_field_type);
- bt_ctf_field_integer_unsigned_set_value(integer_field, 42);
- ok(bt_ctf_event_set_payload(simple_event, "integer_field",
- integer_field) == 0, "Use bt_ctf_event_set_payload to set a manually allocated field");
-
- float_field = bt_ctf_event_get_payload(simple_event, "float_field");
- bt_ctf_field_floating_point_set_value(float_field, double_test_value);
- ok(!bt_ctf_field_floating_point_get_value(float_field, &ret_double),
- "bt_ctf_field_floating_point_get_value returns a double value");
- ok(fabs(ret_double - double_test_value) <= DBL_EPSILON,
- "bt_ctf_field_floating_point_get_value returns a correct value");
-
- enum_field = bt_ctf_field_create(ep_enum_field_type);
- BT_ASSERT(enum_field);
-
- enum_container_field = bt_ctf_field_enumeration_get_container(enum_field);
- ok(bt_ctf_field_integer_signed_set_value(
- enum_container_field, -42) == 0,
- "Set signed enumeration container value");
- ret = bt_ctf_event_set_payload(simple_event, "enum_field", enum_field);
- BT_ASSERT(!ret);
- BT_CTF_OBJECT_PUT_REF_AND_RESET(iter);
-
- enum_field_unsigned = bt_ctf_field_create(ep_enum_field_unsigned_type);
- BT_ASSERT(enum_field_unsigned);
- enum_container_field_unsigned = bt_ctf_field_enumeration_get_container(
- enum_field_unsigned);
- ok(bt_ctf_field_integer_unsigned_set_value(
- enum_container_field_unsigned, 42) == 0,
- "Set unsigned enumeration container value");
- ret = bt_ctf_event_set_payload(simple_event, "enum_field_unsigned",
- enum_field_unsigned);
- BT_ASSERT(!ret);
-
- ok(bt_ctf_clock_set_time(clock, current_time) == 0, "Set clock time");
-
- /* Populate stream event context */
- stream_event_context =
- bt_ctf_event_get_stream_event_context(simple_event);
- BT_ASSERT(stream_event_context);
- stream_event_context_field = bt_ctf_field_structure_get_field_by_name(
- stream_event_context, "common_event_context");
- bt_ctf_field_integer_unsigned_set_value(stream_event_context_field, 42);
-
- /* Populate the event's context */
- event_context = bt_ctf_event_get_context(simple_event);
- ok(event_context,
- "bt_ctf_event_get_context returns a field");
- returned_type = bt_ctf_field_get_type(event_context);
- ok(returned_type == event_context_type,
- "bt_ctf_event_get_context returns a field of the appropriate type");
- event_context_field = bt_ctf_field_structure_get_field_by_name(event_context,
- "event_specific_context");
- ok(!bt_ctf_field_integer_unsigned_set_value(event_context_field, 1234),
- "Successfully set an event context's value");
- ok(!bt_ctf_event_set_context(simple_event, event_context),
- "Set an event context successfully");
-
- ok(bt_ctf_stream_append_event(stream, simple_event) == 0,
- "Append simple event to trace stream");
-
- packet_context = bt_ctf_stream_get_packet_context(stream);
- ok(packet_context,
- "bt_ctf_stream_get_packet_context returns a packet context");
-
- packet_context_field = bt_ctf_field_structure_get_field_by_name(packet_context,
- "packet_size");
- ok(packet_context_field,
- "Packet context contains the default packet_size field.");
- bt_ctf_object_put_ref(packet_context_field);
- packet_context_field = bt_ctf_field_structure_get_field_by_name(packet_context,
- "custom_packet_context_field");
- ok(bt_ctf_field_integer_unsigned_set_value(packet_context_field, 8) == 0,
- "Custom packet context field value successfully set.");
-
- ok(bt_ctf_stream_set_packet_context(stream, packet_context) == 0,
- "Successfully set a stream's packet context");
-
- ok(bt_ctf_stream_flush(stream) == 0,
- "Flush trace stream with one event");
-
- bt_ctf_object_put_ref(simple_event_class);
- bt_ctf_object_put_ref(simple_event);
- bt_ctf_object_put_ref(uint_12_type);
- bt_ctf_object_put_ref(int_64_type);
- bt_ctf_object_put_ref(float_type);
- bt_ctf_object_put_ref(enum_type);
- bt_ctf_object_put_ref(enum_type_unsigned);
- bt_ctf_object_put_ref(returned_type);
- bt_ctf_object_put_ref(event_context_type);
- bt_ctf_object_put_ref(integer_field);
- bt_ctf_object_put_ref(float_field);
- bt_ctf_object_put_ref(enum_field);
- bt_ctf_object_put_ref(enum_field_unsigned);
- bt_ctf_object_put_ref(enum_container_field);
- bt_ctf_object_put_ref(enum_container_field_unsigned);
- bt_ctf_object_put_ref(packet_context);
- bt_ctf_object_put_ref(packet_context_field);
- bt_ctf_object_put_ref(stream_event_context);
- bt_ctf_object_put_ref(stream_event_context_field);
- bt_ctf_object_put_ref(event_context);
- bt_ctf_object_put_ref(event_context_field);
- bt_ctf_object_put_ref(event_payload_type);
- bt_ctf_object_put_ref(ep_integer_field_type);
- bt_ctf_object_put_ref(ep_enum_field_type);
- bt_ctf_object_put_ref(ep_enum_field_unsigned_type);
- bt_ctf_object_put_ref(iter);
-}
-
-static
-void append_complex_event(struct bt_ctf_stream_class *stream_class,
- struct bt_ctf_stream *stream, struct bt_ctf_clock *clock)
-{
- int i;
- struct event_class_attrs_counts ;
- const char *complex_test_event_string = "Complex Test Event";
- const char *test_string_1 = "Test ";
- const char *test_string_2 = "string ";
- const char *test_string_3 = "abcdefghi";
- const char *test_string_4 = "abcd\0efg\0hi";
- const char *test_string_cat = "Test string abcdeefg";
- struct bt_ctf_field_type *uint_35_type =
- bt_ctf_field_type_integer_create(35);
- struct bt_ctf_field_type *int_16_type =
- bt_ctf_field_type_integer_create(16);
- struct bt_ctf_field_type *uint_3_type =
- bt_ctf_field_type_integer_create(3);
- struct bt_ctf_field_type *enum_variant_type =
- bt_ctf_field_type_enumeration_create(uint_3_type);
- struct bt_ctf_field_type *variant_type =
- bt_ctf_field_type_variant_create(enum_variant_type,
- "variant_selector");
- struct bt_ctf_field_type *string_type =
- bt_ctf_field_type_string_create();
- struct bt_ctf_field_type *sequence_type;
- struct bt_ctf_field_type *array_type;
- struct bt_ctf_field_type *inner_structure_type =
- bt_ctf_field_type_structure_create();
- struct bt_ctf_field_type *complex_structure_type =
- bt_ctf_field_type_structure_create();
- struct bt_ctf_field_type *ret_field_type;
- struct bt_ctf_event_class *event_class;
- struct bt_ctf_event *event;
- struct bt_ctf_field *uint_35_field, *int_16_field, *a_string_field,
- *inner_structure_field, *complex_structure_field,
- *a_sequence_field, *enum_variant_field, *enum_container_field,
- *variant_field, *an_array_field, *stream_event_ctx_field,
- *stream_event_ctx_int_field;
- uint64_t ret_unsigned_int;
- int64_t ret_signed_int;
- const char *ret_string;
- struct bt_ctf_stream_class *ret_stream_class;
- struct bt_ctf_event_class *ret_event_class;
- struct bt_ctf_field *packet_context, *packet_context_field;
-
- ok(bt_ctf_field_type_set_alignment(int_16_type, 0),
- "bt_ctf_field_type_set_alignment handles 0-alignment correctly");
- ok(bt_ctf_field_type_set_alignment(int_16_type, 3),
- "bt_ctf_field_type_set_alignment handles wrong alignment correctly (3)");
- ok(bt_ctf_field_type_set_alignment(int_16_type, 24),
- "bt_ctf_field_type_set_alignment handles wrong alignment correctly (24)");
- ok(!bt_ctf_field_type_set_alignment(int_16_type, 4),
- "bt_ctf_field_type_set_alignment handles correct alignment correctly (4)");
- ok(!bt_ctf_field_type_set_alignment(int_16_type, 32),
- "Set alignment of signed 16 bit integer to 32");
- ok(!bt_ctf_field_type_integer_set_signed(int_16_type, 1),
- "Set integer signedness to true");
- ok(!bt_ctf_field_type_integer_set_base(uint_35_type,
- BT_CTF_INTEGER_BASE_HEXADECIMAL),
- "Set signed 16 bit integer base to hexadecimal");
-
- array_type = bt_ctf_field_type_array_create(int_16_type, ARRAY_TEST_LENGTH);
- sequence_type = bt_ctf_field_type_sequence_create(int_16_type,
- "seq_len");
-
- ret_field_type = bt_ctf_field_type_array_get_element_field_type(
- array_type);
- ok(ret_field_type == int_16_type,
- "bt_ctf_field_type_array_get_element_field_type returns the correct type");
- bt_ctf_object_put_ref(ret_field_type);
-
- ok(bt_ctf_field_type_array_get_length(array_type) == ARRAY_TEST_LENGTH,
- "bt_ctf_field_type_array_get_length returns the correct length");
-
- ok(bt_ctf_field_type_structure_add_field(inner_structure_type,
- inner_structure_type, "yes"), "Cannot add self to structure");
- ok(!bt_ctf_field_type_structure_add_field(inner_structure_type,
- uint_35_type, "seq_len"), "Add seq_len field to inner structure");
- ok(!bt_ctf_field_type_structure_add_field(inner_structure_type,
- sequence_type, "a_sequence"), "Add a_sequence field to inner structure");
- ok(!bt_ctf_field_type_structure_add_field(inner_structure_type,
- array_type, "an_array"), "Add an_array field to inner structure");
-
- bt_ctf_field_type_enumeration_add_mapping(enum_variant_type,
- "UINT3_TYPE", 0, 0);
- bt_ctf_field_type_enumeration_add_mapping(enum_variant_type,
- "INT16_TYPE", 1, 1);
- bt_ctf_field_type_enumeration_add_mapping(enum_variant_type,
- "UINT35_TYPE", 2, 7);
-
- ok(bt_ctf_field_type_variant_add_field(variant_type, uint_3_type,
- "An unknown entry"), "Reject a variant field based on an unknown tag value");
- ok(bt_ctf_field_type_variant_add_field(variant_type, uint_3_type,
- "UINT3_TYPE") == 0, "Add a field to a variant");
- ok(!bt_ctf_field_type_variant_add_field(variant_type, int_16_type,
- "INT16_TYPE"), "Add INT16_TYPE field to variant");
- ok(!bt_ctf_field_type_variant_add_field(variant_type, uint_35_type,
- "UINT35_TYPE"), "Add UINT35_TYPE field to variant");
-
- ret_field_type = bt_ctf_field_type_variant_get_tag_field_type(variant_type);
- ok(ret_field_type == enum_variant_type,
- "bt_ctf_field_type_variant_get_tag_field_type returns a correct tag type");
- bt_ctf_object_put_ref(ret_field_type);
-
- ret_string = bt_ctf_field_type_variant_get_tag_name(variant_type);
- ok(ret_string ? strcmp(ret_string, "variant_selector") == 0 : 0,
- "bt_ctf_field_type_variant_get_tag_name returns the correct variant tag name");
- ret_field_type = bt_ctf_field_type_variant_get_field_type_by_name(
- variant_type, "INT16_TYPE");
- ok(ret_field_type == int_16_type,
- "bt_ctf_field_type_variant_get_field_type_by_name returns a correct field type");
- bt_ctf_object_put_ref(ret_field_type);
-
- ok(bt_ctf_field_type_variant_get_field_count(variant_type) == 3,
- "bt_ctf_field_type_variant_get_field_count returns the correct count");
-
- ok(bt_ctf_field_type_variant_get_field_by_index(variant_type, NULL, &ret_field_type, 0) == 0,
- "bt_ctf_field_type_variant_get_field handles a NULL field name correctly");
- bt_ctf_object_put_ref(ret_field_type);
- ok(bt_ctf_field_type_variant_get_field_by_index(variant_type, &ret_string, NULL, 0) == 0,
- "bt_ctf_field_type_variant_get_field handles a NULL field type correctly");
- ok(bt_ctf_field_type_variant_get_field_by_index(variant_type, &ret_string, &ret_field_type, 1) == 0,
- "bt_ctf_field_type_variant_get_field returns a field");
- ok(strcmp("INT16_TYPE", ret_string) == 0,
- "bt_ctf_field_type_variant_get_field returns a correct field name");
- ok(ret_field_type == int_16_type,
- "bt_ctf_field_type_variant_get_field returns a correct field type");
- bt_ctf_object_put_ref(ret_field_type);
-
- ok(!bt_ctf_field_type_structure_add_field(complex_structure_type,
- enum_variant_type, "variant_selector"),
- "Add variant_selector field to complex structure");
- ok(!bt_ctf_field_type_structure_add_field(complex_structure_type,
- string_type, "string"), "Add `string` field to complex structure");
- ok(!bt_ctf_field_type_structure_add_field(complex_structure_type,
- variant_type, "variant_value"),
- "Add variant_value field to complex structure");
- ok(!bt_ctf_field_type_structure_add_field(complex_structure_type,
- inner_structure_type, "inner_structure"),
- "Add inner_structure field to complex structure");
-
- event_class = bt_ctf_event_class_create(complex_test_event_string);
- ok(event_class, "Create an event class");
- ok(bt_ctf_event_class_add_field(event_class, uint_35_type, ""),
- "Reject addition of a field with an empty name to an event");
- ok(bt_ctf_event_class_add_field(event_class, NULL, "an_integer"),
- "Reject addition of a field with a NULL type to an event");
- ok(bt_ctf_event_class_add_field(event_class, uint_35_type,
- "int"),
- "Reject addition of a type with an illegal name to an event");
- ok(bt_ctf_event_class_add_field(event_class, uint_35_type,
- "uint_35") == 0,
- "Add field of type unsigned integer to an event");
- ok(bt_ctf_event_class_add_field(event_class, int_16_type,
- "int_16") == 0, "Add field of type signed integer to an event");
- ok(bt_ctf_event_class_add_field(event_class, complex_structure_type,
- "complex_structure") == 0,
- "Add composite structure to an event");
-
- ret_string = bt_ctf_event_class_get_name(event_class);
- ok(strcmp(ret_string, complex_test_event_string) == 0,
- "bt_ctf_event_class_get_name returns a correct name");
- ok(bt_ctf_event_class_get_id(event_class) < 0,
- "bt_ctf_event_class_get_id returns a negative value when not set");
- ok(bt_ctf_event_class_set_id(NULL, 42) < 0,
- "bt_ctf_event_class_set_id handles NULL correctly");
- ok(bt_ctf_event_class_set_id(event_class, 42) == 0,
- "Set an event class' id");
- ok(bt_ctf_event_class_get_id(event_class) == 42,
- "bt_ctf_event_class_get_id returns the correct value");
-
- /* Test event class attributes */
- ok(bt_ctf_event_class_get_log_level(event_class) == BT_CTF_EVENT_CLASS_LOG_LEVEL_UNSPECIFIED,
- "event class has the expected initial log level");
- ok(!bt_ctf_event_class_get_emf_uri(event_class),
- "as expected, event class has no initial EMF URI");
- ok(bt_ctf_event_class_set_log_level(NULL, BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO),
- "bt_ctf_event_class_set_log_level handles a NULL event class correctly");
- ok(bt_ctf_event_class_set_log_level(event_class, BT_CTF_EVENT_CLASS_LOG_LEVEL_UNKNOWN),
- "bt_ctf_event_class_set_log_level handles an unknown log level correctly");
- ok(!bt_ctf_event_class_set_log_level(event_class, BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO),
- "bt_ctf_event_class_set_log_level succeeds with a valid log level");
- ok(bt_ctf_event_class_get_log_level(event_class) == BT_CTF_EVENT_CLASS_LOG_LEVEL_INFO,
- "bt_ctf_event_class_get_log_level returns the expected log level");
- ok(bt_ctf_event_class_set_emf_uri(NULL, "https://babeltrace.org/"),
- "bt_ctf_event_class_set_emf_uri handles a NULL event class correctly");
- ok(!bt_ctf_event_class_set_emf_uri(event_class, "https://babeltrace.org/"),
- "bt_ctf_event_class_set_emf_uri succeeds with a valid EMF URI");
- ok(strcmp(bt_ctf_event_class_get_emf_uri(event_class), "https://babeltrace.org/") == 0,
- "bt_ctf_event_class_get_emf_uri returns the expected EMF URI");
- ok(!bt_ctf_event_class_set_emf_uri(event_class, NULL),
- "bt_ctf_event_class_set_emf_uri succeeds with NULL (to reset)");
- ok(!bt_ctf_event_class_get_emf_uri(event_class),
- "as expected, event class has no EMF URI after reset");
-
- /* Add event class to the stream class */
- ok(bt_ctf_stream_class_add_event_class(stream_class, NULL),
- "Reject addition of NULL event class to a stream class");
- ok(bt_ctf_stream_class_add_event_class(stream_class,
- event_class) == 0, "Add an event class to stream class");
-
- ret_stream_class = bt_ctf_event_class_get_stream_class(event_class);
- ok(ret_stream_class == stream_class,
- "bt_ctf_event_class_get_stream_class returns the correct stream class");
- bt_ctf_object_put_ref(ret_stream_class);
-
- ok(!bt_ctf_event_class_get_field_by_name(event_class, "truie"),
- "bt_ctf_event_class_get_field_by_name handles an invalid field name correctly");
- ret_field_type = bt_ctf_event_class_get_field_by_name(event_class,
- "complex_structure");
- bt_ctf_object_put_ref(ret_field_type);
-
- event = bt_ctf_event_create(event_class);
- ok(event, "Instanciate a complex event");
-
- ret_event_class = bt_ctf_event_get_class(event);
- ok(ret_event_class == event_class,
- "bt_ctf_event_get_class returns the correct event class");
- bt_ctf_object_put_ref(ret_event_class);
-
- uint_35_field = bt_ctf_event_get_payload(event, "uint_35");
- ok(uint_35_field, "Use bt_ctf_event_get_payload to get a field instance ");
- bt_ctf_field_integer_unsigned_set_value(uint_35_field, 0x0DDF00D);
- ok(bt_ctf_field_integer_unsigned_get_value(uint_35_field,
- &ret_unsigned_int) == 0,
- "bt_ctf_field_integer_unsigned_get_value succeeds after setting a value");
- ok(ret_unsigned_int == 0x0DDF00D,
- "bt_ctf_field_integer_unsigned_get_value returns the correct value");
- bt_ctf_object_put_ref(uint_35_field);
-
- int_16_field = bt_ctf_event_get_payload(event, "int_16");
- bt_ctf_field_integer_signed_set_value(int_16_field, -12345);
- ok(bt_ctf_field_integer_signed_get_value(int_16_field,
- &ret_signed_int) == 0,
- "bt_ctf_field_integer_signed_get_value succeeds after setting a value");
- ok(ret_signed_int == -12345,
- "bt_ctf_field_integer_signed_get_value returns the correct value");
- bt_ctf_object_put_ref(int_16_field);
-
- complex_structure_field = bt_ctf_event_get_payload(event,
- "complex_structure");
-
- inner_structure_field = bt_ctf_field_structure_get_field_by_index(
- complex_structure_field, 3);
- ret_field_type = bt_ctf_field_get_type(inner_structure_field);
- bt_ctf_object_put_ref(inner_structure_field);
- bt_ctf_object_put_ref(ret_field_type);
-
- inner_structure_field = bt_ctf_field_structure_get_field_by_name(
- complex_structure_field, "inner_structure");
- a_string_field = bt_ctf_field_structure_get_field_by_name(
- complex_structure_field, "string");
- enum_variant_field = bt_ctf_field_structure_get_field_by_name(
- complex_structure_field, "variant_selector");
- variant_field = bt_ctf_field_structure_get_field_by_name(
- complex_structure_field, "variant_value");
- uint_35_field = bt_ctf_field_structure_get_field_by_name(
- inner_structure_field, "seq_len");
- a_sequence_field = bt_ctf_field_structure_get_field_by_name(
- inner_structure_field, "a_sequence");
- an_array_field = bt_ctf_field_structure_get_field_by_name(
- inner_structure_field, "an_array");
-
- enum_container_field = bt_ctf_field_enumeration_get_container(
- enum_variant_field);
- bt_ctf_field_integer_unsigned_set_value(enum_container_field, 1);
- int_16_field = bt_ctf_field_variant_get_field(variant_field,
- enum_variant_field);
- bt_ctf_field_integer_signed_set_value(int_16_field, -200);
- bt_ctf_object_put_ref(int_16_field);
- bt_ctf_field_string_set_value(a_string_field,
- test_string_1);
- ok(!bt_ctf_field_string_append(a_string_field, test_string_2),
- "bt_ctf_field_string_append succeeds");
- ok(!bt_ctf_field_string_append_len(a_string_field, test_string_3, 5),
- "bt_ctf_field_string_append_len succeeds (append 5 characters)");
- ok(!bt_ctf_field_string_append_len(a_string_field, &test_string_4[5], 3),
- "bt_ctf_field_string_append_len succeeds (append 0 characters)");
- ok(!bt_ctf_field_string_append_len(a_string_field, test_string_3, 0),
- "bt_ctf_field_string_append_len succeeds (append 0 characters)");
-
- ret_string = bt_ctf_field_string_get_value(a_string_field);
- ok(ret_string, "bt_ctf_field_string_get_value returns a string");
- ok(ret_string ? strcmp(ret_string, test_string_cat) == 0 : 0,
- "bt_ctf_field_string_get_value returns a correct value");
- bt_ctf_field_integer_unsigned_set_value(uint_35_field,
- SEQUENCE_TEST_LENGTH);
-
- ret_field_type = bt_ctf_field_type_variant_get_field_type_from_tag(
- variant_type, enum_variant_field);
- ok(ret_field_type == int_16_type,
- "bt_ctf_field_type_variant_get_field_type_from_tag returns the correct field type");
-
- ok(bt_ctf_field_sequence_set_length(a_sequence_field,
- uint_35_field) == 0, "Set a sequence field's length");
-
- for (i = 0; i < SEQUENCE_TEST_LENGTH; i++) {
- int_16_field = bt_ctf_field_sequence_get_field(
- a_sequence_field, i);
- bt_ctf_field_integer_signed_set_value(int_16_field, 4 - i);
- bt_ctf_object_put_ref(int_16_field);
- }
-
- for (i = 0; i < ARRAY_TEST_LENGTH; i++) {
- int_16_field = bt_ctf_field_array_get_field(
- an_array_field, i);
- bt_ctf_field_integer_signed_set_value(int_16_field, i);
- bt_ctf_object_put_ref(int_16_field);
- }
-
- stream_event_ctx_field = bt_ctf_event_get_stream_event_context(event);
- BT_ASSERT(stream_event_ctx_field);
- stream_event_ctx_int_field = bt_ctf_field_structure_get_field_by_name(
- stream_event_ctx_field, "common_event_context");
- BT_CTF_OBJECT_PUT_REF_AND_RESET(stream_event_ctx_field);
- bt_ctf_field_integer_unsigned_set_value(stream_event_ctx_int_field, 17);
- BT_CTF_OBJECT_PUT_REF_AND_RESET(stream_event_ctx_int_field);
-
- bt_ctf_clock_set_time(clock, ++current_time);
- ok(bt_ctf_stream_append_event(stream, event) == 0,
- "Append a complex event to a stream");
-
- /*
- * Populate the custom packet context field with a dummy value
- * otherwise flush will fail.
- */
- packet_context = bt_ctf_stream_get_packet_context(stream);
- packet_context_field = bt_ctf_field_structure_get_field_by_name(packet_context,
- "custom_packet_context_field");
- bt_ctf_field_integer_unsigned_set_value(packet_context_field, 1);
-
- ok(bt_ctf_stream_flush(stream) == 0,
- "Flush a stream containing a complex event");
-
- bt_ctf_object_put_ref(uint_35_field);
- bt_ctf_object_put_ref(a_string_field);
- bt_ctf_object_put_ref(inner_structure_field);
- bt_ctf_object_put_ref(complex_structure_field);
- bt_ctf_object_put_ref(a_sequence_field);
- bt_ctf_object_put_ref(an_array_field);
- bt_ctf_object_put_ref(enum_variant_field);
- bt_ctf_object_put_ref(enum_container_field);
- bt_ctf_object_put_ref(variant_field);
- bt_ctf_object_put_ref(packet_context_field);
- bt_ctf_object_put_ref(packet_context);
- bt_ctf_object_put_ref(uint_35_type);
- bt_ctf_object_put_ref(int_16_type);
- bt_ctf_object_put_ref(string_type);
- bt_ctf_object_put_ref(sequence_type);
- bt_ctf_object_put_ref(array_type);
- bt_ctf_object_put_ref(inner_structure_type);
- bt_ctf_object_put_ref(complex_structure_type);
- bt_ctf_object_put_ref(uint_3_type);
- bt_ctf_object_put_ref(enum_variant_type);
- bt_ctf_object_put_ref(variant_type);
- bt_ctf_object_put_ref(ret_field_type);
- bt_ctf_object_put_ref(event_class);
- bt_ctf_object_put_ref(event);
-}
-
-static
-void type_field_tests(void)
-{
- struct bt_ctf_field *uint_12;
- struct bt_ctf_field *int_16;
- struct bt_ctf_field *string;
- struct bt_ctf_field_type *composite_structure_type;
- struct bt_ctf_field_type *structure_seq_type;
- struct bt_ctf_field_type *string_type;
- struct bt_ctf_field_type *sequence_type;
- struct bt_ctf_field_type *uint_8_type;
- struct bt_ctf_field_type *int_16_type;
- struct bt_ctf_field_type *uint_12_type =
- bt_ctf_field_type_integer_create(12);
- struct bt_ctf_field_type *enumeration_type;
- struct bt_ctf_field_type *returned_type;
- const char *ret_string;
-
- ok(uint_12_type, "Create an unsigned integer type");
- ok(bt_ctf_field_type_integer_set_base(uint_12_type,
- BT_CTF_INTEGER_BASE_BINARY) == 0,
- "Set integer type's base as binary");
- ok(bt_ctf_field_type_integer_set_base(uint_12_type,
- BT_CTF_INTEGER_BASE_DECIMAL) == 0,
- "Set integer type's base as decimal");
- ok(bt_ctf_field_type_integer_set_base(uint_12_type,
- BT_CTF_INTEGER_BASE_UNKNOWN),
- "Reject integer type's base set as unknown");
- ok(bt_ctf_field_type_integer_set_base(uint_12_type,
- BT_CTF_INTEGER_BASE_OCTAL) == 0,
- "Set integer type's base as octal");
- ok(bt_ctf_field_type_integer_set_base(uint_12_type,
- BT_CTF_INTEGER_BASE_HEXADECIMAL) == 0,
- "Set integer type's base as hexadecimal");
- ok(bt_ctf_field_type_integer_set_base(uint_12_type, 457417),
- "Reject unknown integer base value");
- ok(bt_ctf_field_type_integer_set_signed(uint_12_type, 952835) == 0,
- "Set integer type signedness to signed");
- ok(bt_ctf_field_type_integer_set_signed(uint_12_type, 0) == 0,
- "Set integer type signedness to unsigned");
- ok(bt_ctf_field_type_integer_get_size(uint_12_type) == 12,
- "bt_ctf_field_type_integer_get_size returns a correct value");
- ok(bt_ctf_field_type_integer_get_signed(uint_12_type) == 0,
- "bt_ctf_field_type_integer_get_signed returns a correct value for unsigned types");
-
- ok(bt_ctf_field_type_set_byte_order(NULL,
- BT_CTF_BYTE_ORDER_LITTLE_ENDIAN) < 0,
- "bt_ctf_field_type_set_byte_order handles NULL correctly");
- ok(bt_ctf_field_type_set_byte_order(uint_12_type,
- (enum bt_ctf_byte_order) 42) < 0,
- "bt_ctf_field_type_set_byte_order rejects invalid values");
- ok(bt_ctf_field_type_set_byte_order(uint_12_type,
- BT_CTF_BYTE_ORDER_LITTLE_ENDIAN) == 0,
- "Set an integer's byte order to little endian");
- ok(bt_ctf_field_type_set_byte_order(uint_12_type,
- BT_CTF_BYTE_ORDER_BIG_ENDIAN) == 0,
- "Set an integer's byte order to big endian");
- ok(bt_ctf_field_type_get_byte_order(uint_12_type) ==
- BT_CTF_BYTE_ORDER_BIG_ENDIAN,
- "bt_ctf_field_type_get_byte_order returns a correct value");
-
- ok(bt_ctf_field_type_get_type_id(uint_12_type) ==
- BT_CTF_FIELD_TYPE_ID_INTEGER,
- "bt_ctf_field_type_get_type_id returns a correct value with an integer type");
-
- ok(bt_ctf_field_type_integer_get_base(uint_12_type) ==
- BT_CTF_INTEGER_BASE_HEXADECIMAL,
- "bt_ctf_field_type_integer_get_base returns a correct value");
-
- ok(bt_ctf_field_type_integer_set_encoding(NULL,
- BT_CTF_STRING_ENCODING_ASCII) < 0,
- "bt_ctf_field_type_integer_set_encoding handles NULL correctly");
- ok(bt_ctf_field_type_integer_set_encoding(uint_12_type,
- (enum bt_ctf_string_encoding) 123) < 0,
- "bt_ctf_field_type_integer_set_encoding handles invalid encodings correctly");
- ok(bt_ctf_field_type_integer_set_encoding(uint_12_type,
- BT_CTF_STRING_ENCODING_UTF8) == 0,
- "Set integer type encoding to UTF8");
- ok(bt_ctf_field_type_integer_get_encoding(uint_12_type) ==
- BT_CTF_STRING_ENCODING_UTF8,
- "bt_ctf_field_type_integer_get_encoding returns a correct value");
-
- int_16_type = bt_ctf_field_type_integer_create(16);
- BT_ASSERT(int_16_type);
- ok(!bt_ctf_field_type_integer_set_signed(int_16_type, 1),
- "Set signedness of 16 bit integer to true");
- ok(bt_ctf_field_type_integer_get_signed(int_16_type) == 1,
- "bt_ctf_field_type_integer_get_signed returns a correct value for signed types");
- uint_8_type = bt_ctf_field_type_integer_create(8);
- sequence_type =
- bt_ctf_field_type_sequence_create(int_16_type, "seq_len");
- ok(sequence_type, "Create a sequence of int16_t type");
- ok(bt_ctf_field_type_get_type_id(sequence_type) ==
- BT_CTF_FIELD_TYPE_ID_SEQUENCE,
- "bt_ctf_field_type_get_type_id returns a correct value with a sequence type");
-
- ret_string = bt_ctf_field_type_sequence_get_length_field_name(
- sequence_type);
- ok(strcmp(ret_string, "seq_len") == 0,
- "bt_ctf_field_type_sequence_get_length_field_name returns the correct value");
- returned_type = bt_ctf_field_type_sequence_get_element_field_type(
- sequence_type);
- ok(returned_type == int_16_type,
- "bt_ctf_field_type_sequence_get_element_field_type returns the correct type");
- bt_ctf_object_put_ref(returned_type);
-
- string_type = bt_ctf_field_type_string_create();
- ok(string_type, "Create a string type");
- ok(bt_ctf_field_type_string_set_encoding(string_type,
- BT_CTF_STRING_ENCODING_NONE),
- "Reject invalid \"None\" string encoding");
- ok(bt_ctf_field_type_string_set_encoding(string_type,
- 42),
- "Reject invalid string encoding");
- ok(bt_ctf_field_type_string_set_encoding(string_type,
- BT_CTF_STRING_ENCODING_ASCII) == 0,
- "Set string encoding to ASCII");
-
- ok(bt_ctf_field_type_string_get_encoding(string_type) ==
- BT_CTF_STRING_ENCODING_ASCII,
- "bt_ctf_field_type_string_get_encoding returns the correct value");
-
- structure_seq_type = bt_ctf_field_type_structure_create();
- ok(bt_ctf_field_type_get_type_id(structure_seq_type) ==
- BT_CTF_FIELD_TYPE_ID_STRUCT,
- "bt_ctf_field_type_get_type_id returns a correct value with a structure type");
- ok(structure_seq_type, "Create a structure type");
- ok(bt_ctf_field_type_structure_add_field(structure_seq_type,
- uint_8_type, "seq_len") == 0,
- "Add a uint8_t type to a structure");
- ok(bt_ctf_field_type_structure_add_field(structure_seq_type,
- sequence_type, "a_sequence") == 0,
- "Add a sequence type to a structure");
-
- ok(bt_ctf_field_type_structure_get_field_count(structure_seq_type) == 2,
- "bt_ctf_field_type_structure_get_field_count returns a correct value");
-
- ok(bt_ctf_field_type_structure_get_field(structure_seq_type,
- NULL, &returned_type, 1) == 0,
- "bt_ctf_field_type_structure_get_field handles a NULL name correctly");
- bt_ctf_object_put_ref(returned_type);
- ok(bt_ctf_field_type_structure_get_field(structure_seq_type,
- &ret_string, NULL, 1) == 0,
- "bt_ctf_field_type_structure_get_field handles a NULL return type correctly");
- ok(bt_ctf_field_type_structure_get_field(structure_seq_type,
- &ret_string, &returned_type, 1) == 0,
- "bt_ctf_field_type_structure_get_field returns a field");
- ok(strcmp(ret_string, "a_sequence") == 0,
- "bt_ctf_field_type_structure_get_field returns a correct field name");
- ok(returned_type == sequence_type,
- "bt_ctf_field_type_structure_get_field returns a correct field type");
- bt_ctf_object_put_ref(returned_type);
-
- returned_type = bt_ctf_field_type_structure_get_field_type_by_name(
- structure_seq_type, "a_sequence");
- ok(returned_type == sequence_type,
- "bt_ctf_field_type_structure_get_field_type_by_name returns the correct field type");
- bt_ctf_object_put_ref(returned_type);
-
- composite_structure_type = bt_ctf_field_type_structure_create();
- ok(bt_ctf_field_type_structure_add_field(composite_structure_type,
- string_type, "a_string") == 0,
- "Add a string type to a structure");
- ok(bt_ctf_field_type_structure_add_field(composite_structure_type,
- structure_seq_type, "inner_structure") == 0,
- "Add a structure type to a structure");
-
- returned_type = bt_ctf_field_type_structure_get_field_type_by_name(
- structure_seq_type, "a_sequence");
- ok(returned_type == sequence_type,
- "bt_ctf_field_type_structure_get_field_type_by_name returns a correct type");
- bt_ctf_object_put_ref(returned_type);
-
- int_16 = bt_ctf_field_create(int_16_type);
- ok(int_16, "Instanciate a signed 16-bit integer");
- uint_12 = bt_ctf_field_create(uint_12_type);
- ok(uint_12, "Instanciate an unsigned 12-bit integer");
- returned_type = bt_ctf_field_get_type(int_16);
- ok(returned_type == int_16_type,
- "bt_ctf_field_get_type returns the correct type");
-
- /* Can't modify types after instanciating them */
- ok(bt_ctf_field_type_integer_set_base(uint_12_type,
- BT_CTF_INTEGER_BASE_DECIMAL),
- "Check an integer type' base can't be modified after instanciation");
- ok(bt_ctf_field_type_integer_set_signed(uint_12_type, 0),
- "Check an integer type's signedness can't be modified after instanciation");
-
- /* Check overflows are properly tested for */
- ok(bt_ctf_field_integer_signed_set_value(int_16, -32768) == 0,
- "Check -32768 is allowed for a signed 16-bit integer");
- ok(bt_ctf_field_integer_signed_set_value(int_16, 32767) == 0,
- "Check 32767 is allowed for a signed 16-bit integer");
- ok(bt_ctf_field_integer_signed_set_value(int_16, -42) == 0,
- "Check -42 is allowed for a signed 16-bit integer");
-
- ok(bt_ctf_field_integer_unsigned_set_value(uint_12, 4095) == 0,
- "Check 4095 is allowed for an unsigned 12-bit integer");
- ok(bt_ctf_field_integer_unsigned_set_value(uint_12, 0) == 0,
- "Check 0 is allowed for an unsigned 12-bit integer");
-
- string = bt_ctf_field_create(string_type);
- ok(string, "Instanciate a string field");
- ok(bt_ctf_field_string_set_value(string, "A value") == 0,
- "Set a string's value");
-
- enumeration_type = bt_ctf_field_type_enumeration_create(uint_12_type);
- ok(enumeration_type,
- "Create an enumeration type with an unsigned 12-bit integer as container");
-
- bt_ctf_object_put_ref(string);
- bt_ctf_object_put_ref(uint_12);
- bt_ctf_object_put_ref(int_16);
- bt_ctf_object_put_ref(composite_structure_type);
- bt_ctf_object_put_ref(structure_seq_type);
- bt_ctf_object_put_ref(string_type);
- bt_ctf_object_put_ref(sequence_type);
- bt_ctf_object_put_ref(uint_8_type);
- bt_ctf_object_put_ref(int_16_type);
- bt_ctf_object_put_ref(uint_12_type);
- bt_ctf_object_put_ref(enumeration_type);
- bt_ctf_object_put_ref(returned_type);
-}
-
-static
-void packet_resize_test(struct bt_ctf_stream_class *stream_class,
- struct bt_ctf_stream *stream, struct bt_ctf_clock *clock)
-{
- /*
- * Append enough events to force the underlying packet to be resized.
- * Also tests that a new event can be declared after a stream has been
- * instantiated and used/flushed.
- */
- int ret = 0;
- int i;
- struct bt_ctf_event_class *event_class = bt_ctf_event_class_create(
- "Spammy_Event");
- struct bt_ctf_field_type *integer_type =
- bt_ctf_field_type_integer_create(17);
- struct bt_ctf_field_type *string_type =
- bt_ctf_field_type_string_create();
- struct bt_ctf_event *event = NULL;
- struct bt_ctf_field *ret_field = NULL;
- struct bt_ctf_field_type *ret_field_type = NULL;
- uint64_t ret_uint64;
- int events_appended = 0;
- struct bt_ctf_field *packet_context = NULL,
- *packet_context_field = NULL, *stream_event_context = NULL;
- struct bt_ctf_field_type *ep_field_1_type = NULL;
- struct bt_ctf_field_type *ep_a_string_type = NULL;
- struct bt_ctf_field_type *ep_type = NULL;
-
- ret |= bt_ctf_event_class_add_field(event_class, integer_type,
- "field_1");
- ret |= bt_ctf_event_class_add_field(event_class, string_type,
- "a_string");
- ret |= bt_ctf_stream_class_add_event_class(stream_class, event_class);
- ok(ret == 0, "Add a new event class to a stream class after writing an event");
- if (ret) {
- goto end;
- }
-
- /*
- * bt_ctf_stream_class_add_event_class() copies the field types
- * of event_class, so we retrieve the new ones to create the
- * appropriate fields.
- */
- ep_type = bt_ctf_event_class_get_payload_field_type(event_class);
- BT_ASSERT(ep_type);
- ep_field_1_type = bt_ctf_field_type_structure_get_field_type_by_name(
- ep_type, "field_1");
- BT_ASSERT(ep_field_1_type);
- ep_a_string_type = bt_ctf_field_type_structure_get_field_type_by_name(
- ep_type, "a_string");
- BT_ASSERT(ep_a_string_type);
-
- event = bt_ctf_event_create(event_class);
- ret_field = bt_ctf_event_get_payload(event, 0);
- ret_field_type = bt_ctf_field_get_type(ret_field);
- bt_ctf_object_put_ref(ret_field_type);
- bt_ctf_object_put_ref(ret_field);
- bt_ctf_object_put_ref(event);
-
- for (i = 0; i < packet_resize_test_length; i++) {
- event = bt_ctf_event_create(event_class);
- struct bt_ctf_field *integer =
- bt_ctf_field_create(ep_field_1_type);
- struct bt_ctf_field *string =
- bt_ctf_field_create(ep_a_string_type);
-
- ret |= bt_ctf_clock_set_time(clock, ++current_time);
- ret |= bt_ctf_field_integer_unsigned_set_value(integer, i);
- ret |= bt_ctf_event_set_payload(event, "field_1",
- integer);
- bt_ctf_object_put_ref(integer);
- ret |= bt_ctf_field_string_set_value(string, "This is a test");
- ret |= bt_ctf_event_set_payload(event, "a_string",
- string);
- bt_ctf_object_put_ref(string);
-
- /* Populate stream event context */
- stream_event_context =
- bt_ctf_event_get_stream_event_context(event);
- integer = bt_ctf_field_structure_get_field_by_name(stream_event_context,
- "common_event_context");
- BT_CTF_OBJECT_PUT_REF_AND_RESET(stream_event_context);
- ret |= bt_ctf_field_integer_unsigned_set_value(integer,
- i % 42);
- bt_ctf_object_put_ref(integer);
-
- ret |= bt_ctf_stream_append_event(stream, event);
- bt_ctf_object_put_ref(event);
-
- if (ret) {
- break;
- }
- }
-
- events_appended = !!(i == packet_resize_test_length);
- ret = bt_ctf_stream_get_discarded_events_count(stream, &ret_uint64);
- ok(ret == 0 && ret_uint64 == 0,
- "bt_ctf_stream_get_discarded_events_count returns a correct number of discarded events when none were discarded");
- bt_ctf_stream_append_discarded_events(stream, 1000);
- ret = bt_ctf_stream_get_discarded_events_count(stream, &ret_uint64);
- ok(ret == 0 && ret_uint64 == 1000,
- "bt_ctf_stream_get_discarded_events_count returns a correct number of discarded events when some were discarded");
-
-end:
- ok(events_appended, "Append 100 000 events to a stream");
-
- /*
- * Populate the custom packet context field with a dummy value
- * otherwise flush will fail.
- */
- packet_context = bt_ctf_stream_get_packet_context(stream);
- packet_context_field = bt_ctf_field_structure_get_field_by_name(packet_context,
- "custom_packet_context_field");
- bt_ctf_field_integer_unsigned_set_value(packet_context_field, 2);
-
- ok(bt_ctf_stream_flush(stream) == 0,
- "Flush a stream that forces a packet resize");
- ret = bt_ctf_stream_get_discarded_events_count(stream, &ret_uint64);
- ok(ret == 0 && ret_uint64 == 1000,
- "bt_ctf_stream_get_discarded_events_count returns a correct number of discarded events after a flush");
- bt_ctf_object_put_ref(integer_type);
- bt_ctf_object_put_ref(string_type);
- bt_ctf_object_put_ref(packet_context);
- bt_ctf_object_put_ref(packet_context_field);
- bt_ctf_object_put_ref(stream_event_context);
- bt_ctf_object_put_ref(event_class);
- bt_ctf_object_put_ref(ep_field_1_type);
- bt_ctf_object_put_ref(ep_a_string_type);
- bt_ctf_object_put_ref(ep_type);
-}
-
-static
-void test_empty_stream(struct bt_ctf_writer *writer)
-{
- int ret = 0;
- struct bt_ctf_trace *trace = NULL, *ret_trace = NULL;
- struct bt_ctf_stream_class *stream_class = NULL;
- struct bt_ctf_stream *stream = NULL;
-
- trace = bt_ctf_writer_get_trace(writer);
- if (!trace) {
- diag("Failed to get trace from writer");
- ret = -1;
- goto end;
- }
-
- stream_class = bt_ctf_stream_class_create("empty_stream");
- if (!stream_class) {
- diag("Failed to create stream class");
- ret = -1;
- goto end;
- }
-
- ret = bt_ctf_stream_class_set_packet_context_type(stream_class, NULL);
- BT_ASSERT(ret == 0);
- ret = bt_ctf_stream_class_set_event_header_type(stream_class, NULL);
- BT_ASSERT(ret == 0);
-
- ok(!bt_ctf_stream_class_get_trace(stream_class),
- "bt_ctf_stream_class_get_trace returns NULL when stream class is orphaned");
-
- stream = bt_ctf_writer_create_stream(writer, stream_class);
- if (!stream) {
- diag("Failed to create writer stream");
- ret = -1;
- goto end;
- }
-
- ret_trace = bt_ctf_stream_class_get_trace(stream_class);
- ok(ret_trace == trace,
- "bt_ctf_stream_class_get_trace returns the correct trace after a stream has been created");
-end:
- ok(ret == 0,
- "Created a stream class with default attributes and an empty stream");
- bt_ctf_object_put_ref(trace);
- bt_ctf_object_put_ref(ret_trace);
- bt_ctf_object_put_ref(stream);
- bt_ctf_object_put_ref(stream_class);
-}
-
-static
-void test_custom_event_header_stream(struct bt_ctf_writer *writer,
- struct bt_ctf_clock *clock)
-{
- int i, ret;
- struct bt_ctf_stream_class *stream_class = NULL;
- struct bt_ctf_stream *stream = NULL;
- struct bt_ctf_field_type *integer_type = NULL,
- *sequence_type = NULL, *event_header_type = NULL;
- struct bt_ctf_field *integer = NULL, *sequence = NULL,
- *event_header = NULL, *packet_header = NULL;
- struct bt_ctf_event_class *event_class = NULL;
- struct bt_ctf_event *event = NULL;
-
- stream_class = bt_ctf_stream_class_create("custom_event_header_stream");
- if (!stream_class) {
- fail("Failed to create stream class");
- goto end;
- }
-
- ret = bt_ctf_stream_class_set_clock(stream_class, clock);
- if (ret) {
- fail("Failed to set stream class clock");
- goto end;
- }
-
- /*
- * Customize event header to add an "seq_len" integer member
- * which will be used as the length of a sequence in an event of this
- * stream.
- */
- event_header_type = bt_ctf_stream_class_get_event_header_type(
- stream_class);
- if (!event_header_type) {
- fail("Failed to get event header type");
- goto end;
- }
-
- integer_type = bt_ctf_field_type_integer_create(13);
- if (!integer_type) {
- fail("Failed to create length integer type");
- goto end;
- }
-
- ret = bt_ctf_field_type_structure_add_field(event_header_type,
- integer_type, "seq_len");
- if (ret) {
- fail("Failed to add a new field to stream event header");
- goto end;
- }
-
- event_class = bt_ctf_event_class_create("sequence_event");
- if (!event_class) {
- fail("Failed to create event class");
- goto end;
- }
-
- /*
- * This event's payload will contain a sequence which references
- * stream.event.header.seq_len as its length field.
- */
- sequence_type = bt_ctf_field_type_sequence_create(integer_type,
- "stream.event.header.seq_len");
- if (!sequence_type) {
- fail("Failed to create a sequence");
- goto end;
- }
-
- ret = bt_ctf_event_class_add_field(event_class, sequence_type,
- "some_sequence");
- if (ret) {
- fail("Failed to add a sequence to an event class");
- goto end;
- }
-
- ret = bt_ctf_stream_class_add_event_class(stream_class, event_class);
- if (ret) {
- fail("Failed to add event class to stream class");
- goto end;
- }
-
- stream = bt_ctf_writer_create_stream(writer, stream_class);
- if (!stream) {
- fail("Failed to create stream")
- goto end;
- }
-
- /*
- * We have defined a custom packet header field. We have to populate it
- * explicitly.
- */
- packet_header = bt_ctf_stream_get_packet_header(stream);
- if (!packet_header) {
- fail("Failed to get stream packet header");
- goto end;
- }
-
- integer = bt_ctf_field_structure_get_field_by_name(packet_header,
- "custom_trace_packet_header_field");
- if (!integer) {
- fail("Failed to retrieve custom_trace_packet_header_field");
- goto end;
- }
-
- ret = bt_ctf_field_integer_unsigned_set_value(integer, 3487);
- if (ret) {
- fail("Failed to set custom_trace_packet_header_field value");
- goto end;
- }
- bt_ctf_object_put_ref(integer);
-
- event = bt_ctf_event_create(event_class);
- if (!event) {
- fail("Failed to create event");
- goto end;
- }
-
- event_header = bt_ctf_event_get_header(event);
- if (!event_header) {
- fail("Failed to get event header");
- goto end;
- }
-
- integer = bt_ctf_field_structure_get_field_by_name(event_header,
- "seq_len");
- if (!integer) {
- fail("Failed to get seq_len field from event header");
- goto end;
- }
-
- ret = bt_ctf_field_integer_unsigned_set_value(integer, 2);
- if (ret) {
- fail("Failed to set seq_len value in event header");
- goto end;
- }
-
- /* Populate both sequence integer fields */
- sequence = bt_ctf_event_get_payload(event, "some_sequence");
- if (!sequence) {
- fail("Failed to retrieve sequence from event");
- goto end;
- }
-
- ret = bt_ctf_field_sequence_set_length(sequence, integer);
- if (ret) {
- fail("Failed to set sequence length");
- goto end;
- }
- bt_ctf_object_put_ref(integer);
-
- for (i = 0; i < 2; i++) {
- integer = bt_ctf_field_sequence_get_field(sequence, i);
- if (ret) {
- fail("Failed to retrieve sequence element");
- goto end;
- }
-
- ret = bt_ctf_field_integer_unsigned_set_value(integer, i);
- if (ret) {
- fail("Failed to set sequence element value");
- goto end;
- }
-
- bt_ctf_object_put_ref(integer);
- integer = NULL;
- }
-
- ret = bt_ctf_stream_append_event(stream, event);
- if (ret) {
- fail("Failed to append event to stream");
- goto end;
- }
-
- ret = bt_ctf_stream_flush(stream);
- if (ret) {
- fail("Failed to flush custom_event_header stream");
- }
-end:
- bt_ctf_object_put_ref(stream);
- bt_ctf_object_put_ref(stream_class);
- bt_ctf_object_put_ref(event_class);
- bt_ctf_object_put_ref(event);
- bt_ctf_object_put_ref(integer);
- bt_ctf_object_put_ref(sequence);
- bt_ctf_object_put_ref(event_header);
- bt_ctf_object_put_ref(packet_header);
- bt_ctf_object_put_ref(sequence_type);
- bt_ctf_object_put_ref(integer_type);
- bt_ctf_object_put_ref(event_header_type);
-}
-
-static
-void test_instanciate_event_before_stream(struct bt_ctf_writer *writer,
- struct bt_ctf_clock *clock)
-{
- int ret = 0;
- struct bt_ctf_stream_class *stream_class = NULL;
- struct bt_ctf_stream *stream = NULL,
- *ret_stream = NULL;
- struct bt_ctf_event_class *event_class = NULL;
- struct bt_ctf_event *event = NULL;
- struct bt_ctf_field_type *integer_type = NULL;
- struct bt_ctf_field *payload_field = NULL;
- struct bt_ctf_field *integer = NULL;
-
- stream_class = bt_ctf_stream_class_create("event_before_stream_test");
- if (!stream_class) {
- diag("Failed to create stream class");
- ret = -1;
- goto end;
- }
-
- ret = bt_ctf_stream_class_set_clock(stream_class, clock);
- if (ret) {
- diag("Failed to set stream class clock");
- goto end;
- }
-
- event_class = bt_ctf_event_class_create("some_event_class_name");
- integer_type = bt_ctf_field_type_integer_create(32);
- if (!integer_type) {
- diag("Failed to create integer field type");
- ret = -1;
- goto end;
- }
-
- ret = bt_ctf_event_class_add_field(event_class, integer_type,
- "integer_field");
- if (ret) {
- diag("Failed to add field to event class");
- goto end;
- }
-
- ret = bt_ctf_stream_class_add_event_class(stream_class,
- event_class);
- if (ret) {
- diag("Failed to add event class to stream class");
- }
-
- event = bt_ctf_event_create(event_class);
- if (!event) {
- diag("Failed to create event");
- ret = -1;
- goto end;
- }
-
- payload_field = bt_ctf_event_get_payload_field(event);
- if (!payload_field) {
- diag("Failed to get event's payload field");
- ret = -1;
- goto end;
- }
-
- integer = bt_ctf_field_structure_get_field_by_index(payload_field, 0);
- if (!integer) {
- diag("Failed to get integer field payload from event");
- ret = -1;
- goto end;
- }
-
- ret = bt_ctf_field_integer_unsigned_set_value(integer, 1234);
- if (ret) {
- diag("Failed to set integer field value");
- goto end;
- }
-
- stream = bt_ctf_writer_create_stream(writer, stream_class);
- if (!stream) {
- diag("Failed to create writer stream");
- ret = -1;
- goto end;
- }
-
- ret = bt_ctf_stream_append_event(stream, event);
- if (ret) {
- diag("Failed to append event to stream");
- goto end;
- }
-
- ret_stream = bt_ctf_event_get_stream(event);
- ok(ret_stream == stream,
- "bt_ctf_event_get_stream returns an event's stream after it has been appended");
-end:
- ok(ret == 0,
- "Create an event before instanciating its associated stream");
- bt_ctf_object_put_ref(stream);
- bt_ctf_object_put_ref(ret_stream);
- bt_ctf_object_put_ref(stream_class);
- bt_ctf_object_put_ref(event_class);
- bt_ctf_object_put_ref(event);
- bt_ctf_object_put_ref(integer_type);
- bt_ctf_object_put_ref(integer);
- bt_ctf_object_put_ref(payload_field);
-}
-
-static
-void append_existing_event_class(struct bt_ctf_stream_class *stream_class)
-{
- int ret;
- struct bt_ctf_event_class *event_class;
-
- event_class = bt_ctf_event_class_create("Simple Event");
- BT_ASSERT(event_class);
- ok(bt_ctf_stream_class_add_event_class(stream_class, event_class) == 0,
- "two event classes with the same name may cohabit within the same stream class");
- bt_ctf_object_put_ref(event_class);
-
- event_class = bt_ctf_event_class_create("different name, ok");
- BT_ASSERT(event_class);
- ret = bt_ctf_event_class_set_id(event_class, 13);
- BT_ASSERT(ret == 0);
- ok(bt_ctf_stream_class_add_event_class(stream_class, event_class),
- "two event classes with the same ID cannot cohabit within the same stream class");
- bt_ctf_object_put_ref(event_class);
-}
-
-static
-void test_clock_utils(void)
-{
- int ret;
- struct bt_ctf_clock *clock = NULL;
-
- clock = bt_ctf_clock_create("water");
- BT_ASSERT(clock);
- ret = bt_ctf_clock_set_offset_s(clock, 1234);
- BT_ASSERT(!ret);
- ret = bt_ctf_clock_set_offset(clock, 1000);
- BT_ASSERT(!ret);
- ret = bt_ctf_clock_set_frequency(clock, 1000000000);
- BT_ASSERT(!ret);
- ret = bt_ctf_clock_set_frequency(clock, 1534);
- BT_ASSERT(!ret);
-
- BT_CTF_OBJECT_PUT_REF_AND_RESET(clock);
-}
-
-int main(int argc, char **argv)
-{
- const char *env_resize_length;
- gchar *trace_path;
- gchar *metadata_path;
- const char *clock_name = "test_clock";
- const char *clock_description = "This is a test clock";
- const char *returned_clock_name;
- const char *returned_clock_description;
- const uint64_t frequency = 1123456789;
- const int64_t offset_s = 13515309;
- const int64_t offset = 1234567;
- int64_t get_offset_s,
- get_offset;
- const uint64_t precision = 10;
- const int is_absolute = 0xFF;
- char *metadata_string;
- struct bt_ctf_writer *writer;
- struct bt_utsname name = {"GNU/Linux", "testhost", "4.4.0-87-generic",
- "#110-Ubuntu SMP Tue Jul 18 12:55:35 UTC 2017", "x86_64"};
- struct bt_ctf_clock *clock, *ret_clock;
- struct bt_ctf_stream_class *stream_class, *ret_stream_class;
- struct bt_ctf_stream *stream1;
- struct bt_ctf_stream *stream;
- const char *ret_string;
- const uint8_t *ret_uuid;
- bt_uuid_t tmp_uuid = { 0 };
- struct bt_ctf_field_type *packet_context_type,
- *packet_context_field_type,
- *packet_header_type,
- *packet_header_field_type,
- *integer_type,
- *stream_event_context_type,
- *ret_field_type,
- *event_header_field_type;
- struct bt_ctf_field *packet_header, *packet_header_field;
- struct bt_ctf_trace *trace;
- int ret;
-
- if (argc < 2) {
- printf("Usage: tests-ctf-writer path_to_babeltrace\n");
- return -1;
- }
-
- env_resize_length = getenv("PACKET_RESIZE_TEST_LENGTH");
- if (env_resize_length) {
- packet_resize_test_length =
- (unsigned int) atoi(env_resize_length);
- }
-
- plan_tests(NR_TESTS);
-
- trace_path = g_build_filename(g_get_tmp_dir(), "ctfwriter_XXXXXX", NULL);
- if (!bt_mkdtemp(trace_path)) {
- perror("# perror");
- }
-
- metadata_path = g_build_filename(trace_path, "metadata", NULL);
-
- writer = bt_ctf_writer_create(trace_path);
- ok(writer, "bt_ctf_create succeeds in creating trace with path");
-
- ok(!bt_ctf_writer_get_trace(NULL),
- "bt_ctf_writer_get_trace correctly handles NULL");
- trace = bt_ctf_writer_get_trace(writer);
- ok(bt_ctf_trace_set_native_byte_order(trace, BT_CTF_BYTE_ORDER_NATIVE),
- "Cannot set a trace's byte order to BT_CTF_BYTE_ORDER_NATIVE");
- ok(bt_ctf_trace_set_native_byte_order(trace, BT_CTF_BYTE_ORDER_UNSPECIFIED),
- "Cannot set a trace's byte order to BT_CTF_BYTE_ORDER_UNSPECIFIED");
- ok(trace,
- "bt_ctf_writer_get_trace returns a bt_ctf_trace object");
- ok(bt_ctf_trace_set_native_byte_order(trace, BT_CTF_BYTE_ORDER_BIG_ENDIAN) == 0,
- "Set a trace's byte order to big endian");
- ok(bt_ctf_trace_get_native_byte_order(trace) == BT_CTF_BYTE_ORDER_BIG_ENDIAN,
- "bt_ctf_trace_get_native_byte_order returns a correct endianness");
-
- /* Add environment context to the trace */
- ok(bt_ctf_writer_add_environment_field(writer, "host", name.nodename) == 0,
- "Add host (%s) environment field to writer instance",
- name.nodename);
- ok(bt_ctf_writer_add_environment_field(NULL, "test_field",
- "test_value"),
- "bt_ctf_writer_add_environment_field error with NULL writer");
- ok(bt_ctf_writer_add_environment_field(writer, NULL,
- "test_value"),
- "bt_ctf_writer_add_environment_field error with NULL field name");
- ok(bt_ctf_writer_add_environment_field(writer, "test_field",
- NULL),
- "bt_ctf_writer_add_environment_field error with NULL field value");
-
- /* Test bt_ctf_trace_set_environment_field_integer */
- ok(bt_ctf_trace_set_environment_field_integer(NULL, "test_env_int",
- -194875),
- "bt_ctf_trace_set_environment_field_integer handles a NULL trace correctly");
- ok(bt_ctf_trace_set_environment_field_integer(trace, NULL, -194875),
- "bt_ctf_trace_set_environment_field_integer handles a NULL name correctly");
- ok(!bt_ctf_trace_set_environment_field_integer(trace, "test_env_int",
- -164973),
- "bt_ctf_trace_set_environment_field_integer succeeds");
-
- /* Test bt_ctf_trace_set_environment_field_string */
- ok(bt_ctf_trace_set_environment_field_string(NULL, "test_env_str",
- "yeah"),
- "bt_ctf_trace_set_environment_field_string handles a NULL trace correctly");
- ok(bt_ctf_trace_set_environment_field_string(trace, NULL, "yeah"),
- "bt_ctf_trace_set_environment_field_string handles a NULL name correctly");
- ok(bt_ctf_trace_set_environment_field_string(trace, "test_env_str",
- NULL),
- "bt_ctf_trace_set_environment_field_string handles a NULL value correctly");
- ok(!bt_ctf_trace_set_environment_field_string(trace, "test_env_str",
- "oh yeah"),
- "bt_ctf_trace_set_environment_field_string succeeds");
-
- /* Test environment field replacement */
- ok(!bt_ctf_trace_set_environment_field_integer(trace, "test_env_int",
- 654321),
- "bt_ctf_trace_set_environment_field_integer succeeds with an existing name");
-
- ok(bt_ctf_writer_add_environment_field(writer, "sysname", name.sysname)
- == 0, "Add sysname (%s) environment field to writer instance",
- name.sysname);
- ok(bt_ctf_writer_add_environment_field(writer, "nodename",
- name.nodename) == 0,
- "Add nodename (%s) environment field to writer instance",
- name.nodename);
- ok(bt_ctf_writer_add_environment_field(writer, "release", name.release)
- == 0, "Add release (%s) environment field to writer instance",
- name.release);
- ok(bt_ctf_writer_add_environment_field(writer, "version", name.version)
- == 0, "Add version (%s) environment field to writer instance",
- name.version);
- ok(bt_ctf_writer_add_environment_field(writer, "machine", name.machine)
- == 0, "Add machine (%s) environment field to writer istance",
- name.machine);
-
- /* Define a clock and add it to the trace */
- ok(!bt_ctf_clock_create("signed"),
- "Illegal clock name rejected");
- clock = bt_ctf_clock_create(clock_name);
- ok(clock, "Clock created sucessfully");
- returned_clock_name = bt_ctf_clock_get_name(clock);
- ok(returned_clock_name, "bt_ctf_clock_get_name returns a clock name");
- ok(returned_clock_name ? strcmp(returned_clock_name, clock_name) == 0 : 0,
- "Returned clock name is valid");
-
- returned_clock_description = bt_ctf_clock_get_description(clock);
- ok(!returned_clock_description, "bt_ctf_clock_get_description returns NULL on an unset description");
- ok(bt_ctf_clock_set_description(clock, clock_description) == 0,
- "Clock description set successfully");
-
- returned_clock_description = bt_ctf_clock_get_description(clock);
- ok(returned_clock_description,
- "bt_ctf_clock_get_description returns a description.");
- ok(returned_clock_description ?
- strcmp(returned_clock_description, clock_description) == 0 : 0,
- "Returned clock description is valid");
-
- ok(bt_ctf_clock_get_frequency(clock) == DEFAULT_CLOCK_FREQ,
- "bt_ctf_clock_get_frequency returns the correct default frequency");
- ok(bt_ctf_clock_set_frequency(clock, frequency) == 0,
- "Set clock frequency");
- ok(bt_ctf_clock_get_frequency(clock) == frequency,
- "bt_ctf_clock_get_frequency returns the correct frequency once it is set");
-
- ok(bt_ctf_clock_get_offset_s(clock, &get_offset_s) == 0,
- "bt_ctf_clock_get_offset_s succeeds");
- ok(get_offset_s == DEFAULT_CLOCK_OFFSET_S,
- "bt_ctf_clock_get_offset_s returns the correct default offset (in seconds)");
- ok(bt_ctf_clock_set_offset_s(clock, offset_s) == 0,
- "Set clock offset (seconds)");
- ok(bt_ctf_clock_get_offset_s(clock, &get_offset_s) == 0,
- "bt_ctf_clock_get_offset_s succeeds");
- ok(get_offset_s == offset_s,
- "bt_ctf_clock_get_offset_s returns the correct default offset (in seconds) once it is set");
-
- ok(bt_ctf_clock_get_offset(clock, &get_offset) == 0,
- "bt_ctf_clock_get_offset succeeds");
- ok(get_offset == DEFAULT_CLOCK_OFFSET,
- "bt_ctf_clock_get_offset returns the correct default offset (in ticks)");
- ok(bt_ctf_clock_set_offset(clock, offset) == 0, "Set clock offset");
- ok(bt_ctf_clock_get_offset(clock, &get_offset) == 0,
- "bt_ctf_clock_get_offset succeeds");
- ok(get_offset == offset,
- "bt_ctf_clock_get_offset returns the correct default offset (in ticks) once it is set");
-
- ok(bt_ctf_clock_get_precision(clock) == DEFAULT_CLOCK_PRECISION,
- "bt_ctf_clock_get_precision returns the correct default precision");
- ok(bt_ctf_clock_set_precision(clock, precision) == 0,
- "Set clock precision");
- ok(bt_ctf_clock_get_precision(clock) == precision,
- "bt_ctf_clock_get_precision returns the correct precision once it is set");
-
- ok(bt_ctf_clock_get_is_absolute(clock) == DEFAULT_CLOCK_IS_ABSOLUTE,
- "bt_ctf_clock_get_precision returns the correct default is_absolute attribute");
- ok(bt_ctf_clock_set_is_absolute(clock, is_absolute) == 0,
- "Set clock absolute property");
- ok(bt_ctf_clock_get_is_absolute(clock) == !!is_absolute,
- "bt_ctf_clock_get_precision returns the correct is_absolute attribute once it is set");
- ok(bt_ctf_clock_set_time(clock, current_time) == 0,
- "Set clock time");
- ret_uuid = bt_ctf_clock_get_uuid(clock);
- ok(ret_uuid,
- "bt_ctf_clock_get_uuid returns a UUID");
- if (ret_uuid) {
- memcpy(tmp_uuid, ret_uuid, sizeof(tmp_uuid));
- /* Slightly modify UUID */
- tmp_uuid[sizeof(tmp_uuid) - 1]++;
- }
-
- ok(bt_ctf_clock_set_uuid(clock, tmp_uuid) == 0,
- "bt_ctf_clock_set_uuid sets a new uuid successfully");
- ret_uuid = bt_ctf_clock_get_uuid(clock);
- ok(ret_uuid,
- "bt_ctf_clock_get_uuid returns a UUID after setting a new one");
- ok(uuid_match(ret_uuid, tmp_uuid),
- "bt_ctf_clock_get_uuid returns the correct UUID after setting a new one");
-
- /* Define a stream class */
- stream_class = bt_ctf_stream_class_create("test_stream");
- ret_string = bt_ctf_stream_class_get_name(stream_class);
- ok(ret_string && strcmp(ret_string, "test_stream") == 0,
- "bt_ctf_stream_class_get_name returns a correct stream class name");
-
- ok(!bt_ctf_stream_class_get_clock(stream_class),
- "bt_ctf_stream_class_get_clock returns NULL when a clock was not set");
- ok(!bt_ctf_stream_class_get_clock(NULL),
- "bt_ctf_stream_class_get_clock handles NULL correctly");
-
- ok(stream_class, "Create stream class");
- ok(bt_ctf_stream_class_set_clock(stream_class, clock) == 0,
- "Set a stream class' clock");
- ret_clock = bt_ctf_stream_class_get_clock(stream_class);
- ok(ret_clock == clock,
- "bt_ctf_stream_class_get_clock returns a correct clock");
- bt_ctf_object_put_ref(ret_clock);
-
- /* Test the event fields and event types APIs */
- type_field_tests();
-
- ok(bt_ctf_stream_class_get_id(stream_class) < 0,
- "bt_ctf_stream_class_get_id returns an error when no id is set");
- ok(bt_ctf_stream_class_set_id(NULL, 123) < 0,
- "bt_ctf_stream_class_set_id handles NULL correctly");
- ok(bt_ctf_stream_class_set_id(stream_class, 123) == 0,
- "Set an stream class' id");
- ok(bt_ctf_stream_class_get_id(stream_class) == 123,
- "bt_ctf_stream_class_get_id returns the correct value");
-
- /* Validate default event header fields */
- ret_field_type = bt_ctf_stream_class_get_event_header_type(
- stream_class);
- ok(ret_field_type,
- "bt_ctf_stream_class_get_event_header_type returns an event header type");
- ok(bt_ctf_field_type_get_type_id(ret_field_type) == BT_CTF_FIELD_TYPE_ID_STRUCT,
- "Default event header type is a structure");
- event_header_field_type =
- bt_ctf_field_type_structure_get_field_type_by_name(
- ret_field_type, "id");
- ok(event_header_field_type,
- "Default event header type contains an \"id\" field");
- ok(bt_ctf_field_type_get_type_id(
- event_header_field_type) == BT_CTF_FIELD_TYPE_ID_INTEGER,
- "Default event header \"id\" field is an integer");
- bt_ctf_object_put_ref(event_header_field_type);
- event_header_field_type =
- bt_ctf_field_type_structure_get_field_type_by_name(
- ret_field_type, "timestamp");
- ok(event_header_field_type,
- "Default event header type contains a \"timestamp\" field");
- ok(bt_ctf_field_type_get_type_id(
- event_header_field_type) == BT_CTF_FIELD_TYPE_ID_INTEGER,
- "Default event header \"timestamp\" field is an integer");
- bt_ctf_object_put_ref(event_header_field_type);
- bt_ctf_object_put_ref(ret_field_type);
-
- /* Add a custom trace packet header field */
- packet_header_type = bt_ctf_trace_get_packet_header_field_type(trace);
- ok(packet_header_type,
- "bt_ctf_trace_get_packet_header_field_type returns a packet header");
- ok(bt_ctf_field_type_get_type_id(packet_header_type) == BT_CTF_FIELD_TYPE_ID_STRUCT,
- "bt_ctf_trace_get_packet_header_field_type returns a packet header of type struct");
- ret_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
- packet_header_type, "magic");
- ok(ret_field_type, "Default packet header type contains a \"magic\" field");
- bt_ctf_object_put_ref(ret_field_type);
- ret_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
- packet_header_type, "uuid");
- ok(ret_field_type, "Default packet header type contains a \"uuid\" field");
- bt_ctf_object_put_ref(ret_field_type);
- ret_field_type = bt_ctf_field_type_structure_get_field_type_by_name(
- packet_header_type, "stream_id");
- ok(ret_field_type, "Default packet header type contains a \"stream_id\" field");
- bt_ctf_object_put_ref(ret_field_type);
-
- packet_header_field_type = bt_ctf_field_type_integer_create(22);
- ok(!bt_ctf_field_type_structure_add_field(packet_header_type,
- packet_header_field_type, "custom_trace_packet_header_field"),
- "Added a custom trace packet header field successfully");
-
- ok(bt_ctf_trace_set_packet_header_field_type(NULL, packet_header_type) < 0,
- "bt_ctf_trace_set_packet_header_field_type handles a NULL trace correctly");
- ok(!bt_ctf_trace_set_packet_header_field_type(trace, packet_header_type),
- "Set a trace packet_header_type successfully");
-
- /* Add a custom field to the stream class' packet context */
- packet_context_type = bt_ctf_stream_class_get_packet_context_type(stream_class);
- ok(packet_context_type,
- "bt_ctf_stream_class_get_packet_context_type returns a packet context type.");
- ok(bt_ctf_field_type_get_type_id(packet_context_type) == BT_CTF_FIELD_TYPE_ID_STRUCT,
- "Packet context is a structure");
-
- ok(bt_ctf_stream_class_set_packet_context_type(NULL, packet_context_type),
- "bt_ctf_stream_class_set_packet_context_type handles a NULL stream class correctly");
-
- integer_type = bt_ctf_field_type_integer_create(32);
-
- ok(bt_ctf_stream_class_set_packet_context_type(stream_class,
- integer_type) < 0,
- "bt_ctf_stream_class_set_packet_context_type rejects a packet context that is not a structure");
-
- /* Create a "uint5_t" equivalent custom packet context field */
- packet_context_field_type = bt_ctf_field_type_integer_create(5);
-
- ret = bt_ctf_field_type_structure_add_field(packet_context_type,
- packet_context_field_type, "custom_packet_context_field");
- ok(ret == 0, "Packet context field added successfully");
-
- /* Define a stream event context containing a my_integer field. */
- stream_event_context_type = bt_ctf_field_type_structure_create();
- bt_ctf_field_type_structure_add_field(stream_event_context_type,
- integer_type, "common_event_context");
-
- ok(bt_ctf_stream_class_set_event_context_type(NULL,
- stream_event_context_type) < 0,
- "bt_ctf_stream_class_set_event_context_type handles a NULL stream_class correctly");
- ok(bt_ctf_stream_class_set_event_context_type(stream_class,
- integer_type) < 0,
- "bt_ctf_stream_class_set_event_context_type validates that the event context os a structure");
-
- ok(bt_ctf_stream_class_set_event_context_type(
- stream_class, stream_event_context_type) == 0,
- "Set a new stream event context type");
-
- ret_field_type = bt_ctf_stream_class_get_event_context_type(
- stream_class);
- ok(ret_field_type == stream_event_context_type,
- "bt_ctf_stream_class_get_event_context_type returns the correct field type.");
- bt_ctf_object_put_ref(ret_field_type);
-
-
- /* Instantiate a stream and append events */
- ret = bt_ctf_writer_add_clock(writer, clock);
- BT_ASSERT(ret == 0);
-
- ok(bt_ctf_trace_get_stream_count(trace) == 0,
- "bt_ctf_trace_get_stream_count() succeeds and returns the correct value (0)");
- stream1 = bt_ctf_writer_create_stream(writer, stream_class);
- ok(stream1, "Instanciate a stream class from writer");
- ok(bt_ctf_trace_get_stream_count(trace) == 1,
- "bt_ctf_trace_get_stream_count() succeeds and returns the correct value (1)");
- stream = bt_ctf_trace_get_stream_by_index(trace, 0);
- ok(stream == stream1,
- "bt_ctf_trace_get_stream_by_index() succeeds and returns the correct value");
- BT_CTF_OBJECT_PUT_REF_AND_RESET(stream);
-
- /*
- * Creating a stream through a writer adds the given stream
- * class to the writer's trace, thus registering the stream
- * class's clock to the trace.
- */
-
- ret_stream_class = bt_ctf_stream_get_class(stream1);
- ok(ret_stream_class,
- "bt_ctf_stream_get_class returns a stream class");
- ok(ret_stream_class == stream_class,
- "Returned stream class is of the correct type");
-
- /*
- * Packet header, packet context, event header, and stream
- * event context types were copied for the resolving
- * process
- */
- BT_CTF_OBJECT_PUT_REF_AND_RESET(packet_header_type);
- BT_CTF_OBJECT_PUT_REF_AND_RESET(packet_context_type);
- BT_CTF_OBJECT_PUT_REF_AND_RESET(stream_event_context_type);
- packet_header_type = bt_ctf_trace_get_packet_header_field_type(trace);
- BT_ASSERT(packet_header_type);
- packet_context_type =
- bt_ctf_stream_class_get_packet_context_type(stream_class);
- BT_ASSERT(packet_context_type);
- stream_event_context_type =
- bt_ctf_stream_class_get_event_context_type(stream_class);
- BT_ASSERT(stream_event_context_type);
-
- /*
- * Try to modify the packet context type after a stream has been
- * created.
- */
- ret = bt_ctf_field_type_structure_add_field(packet_header_type,
- packet_header_field_type, "should_fail");
- ok(ret < 0,
- "Trace packet header type can't be modified once a stream has been instanciated");
-
- /*
- * Try to modify the packet context type after a stream has been
- * created.
- */
- ret = bt_ctf_field_type_structure_add_field(packet_context_type,
- packet_context_field_type, "should_fail");
- ok(ret < 0,
- "Packet context type can't be modified once a stream has been instanciated");
-
- /*
- * Try to modify the stream event context type after a stream has been
- * created.
- */
- ret = bt_ctf_field_type_structure_add_field(stream_event_context_type,
- integer_type, "should_fail");
- ok(ret < 0,
- "Stream event context type can't be modified once a stream has been instanciated");
-
- /* Should fail after instanciating a stream (frozen) */
- ok(bt_ctf_stream_class_set_clock(stream_class, clock),
- "Changes to a stream class that was already instantiated fail");
-
- /* Populate the custom packet header field only once for all tests */
- ok(!bt_ctf_stream_get_packet_header(NULL),
- "bt_ctf_stream_get_packet_header handles NULL correctly");
- packet_header = bt_ctf_stream_get_packet_header(stream1);
- ok(packet_header,
- "bt_ctf_stream_get_packet_header returns a packet header");
- ret_field_type = bt_ctf_field_get_type(packet_header);
- ok(ret_field_type == packet_header_type,
- "Stream returns a packet header of the appropriate type");
- bt_ctf_object_put_ref(ret_field_type);
- packet_header_field = bt_ctf_field_structure_get_field_by_name(packet_header,
- "custom_trace_packet_header_field");
- ok(packet_header_field,
- "Packet header structure contains a custom field with the appropriate name");
- ret_field_type = bt_ctf_field_get_type(packet_header_field);
- ok(!bt_ctf_field_integer_unsigned_set_value(packet_header_field,
- 54321), "Set custom packet header value successfully");
- ok(bt_ctf_stream_set_packet_header(stream1, NULL) < 0,
- "bt_ctf_stream_set_packet_header handles a NULL packet header correctly");
- ok(bt_ctf_stream_set_packet_header(NULL, packet_header) < 0,
- "bt_ctf_stream_set_packet_header handles a NULL stream correctly");
- ok(bt_ctf_stream_set_packet_header(stream1, packet_header_field) < 0,
- "bt_ctf_stream_set_packet_header rejects a packet header of the wrong type");
- ok(!bt_ctf_stream_set_packet_header(stream1, packet_header),
- "Successfully set a stream's packet header");
-
- ok(bt_ctf_writer_add_environment_field(writer, "new_field", "test") == 0,
- "Add environment field to writer after stream creation");
-
- test_clock_utils();
-
- test_instanciate_event_before_stream(writer, clock);
-
- append_simple_event(stream_class, stream1, clock);
-
- packet_resize_test(stream_class, stream1, clock);
-
- append_complex_event(stream_class, stream1, clock);
-
- append_existing_event_class(stream_class);
-
- test_empty_stream(writer);
-
- test_custom_event_header_stream(writer, clock);
-
- metadata_string = bt_ctf_writer_get_metadata_string(writer);
- ok(metadata_string, "Get metadata string");
-
- bt_ctf_writer_flush_metadata(writer);
-
- bt_ctf_object_put_ref(clock);
- bt_ctf_object_put_ref(ret_stream_class);
- bt_ctf_object_put_ref(writer);
- bt_ctf_object_put_ref(stream1);
- bt_ctf_object_put_ref(packet_context_type);
- bt_ctf_object_put_ref(packet_context_field_type);
- bt_ctf_object_put_ref(integer_type);
- bt_ctf_object_put_ref(stream_event_context_type);
- bt_ctf_object_put_ref(ret_field_type);
- bt_ctf_object_put_ref(packet_header_type);
- bt_ctf_object_put_ref(packet_header_field_type);
- bt_ctf_object_put_ref(packet_header);
- bt_ctf_object_put_ref(packet_header_field);
- bt_ctf_object_put_ref(trace);
- free(metadata_string);
- bt_ctf_object_put_ref(stream_class);
-
- validate_trace(argv[1], trace_path);
-
- recursive_rmdir(trace_path);
- g_free(trace_path);
- g_free(metadata_path);
-
- return exit_status();
-}
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2013 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+"${BT_TESTS_BUILDDIR}/ctf-writer/ctf-writer" "$BT_TESTS_BT2_BIN"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2013 Jérémie Galarneau <jeremie.galarneau@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-"${BT_TESTS_BUILDDIR}/ctf-writer/ctf_writer" "$BT_TESTS_BT2_BIN"
--- /dev/null
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 EfficiOS Inc.
+#
+
+import os
+import time
+import signal
+
+import bt2
+
+bt2.register_plugin(__name__, "test-exit-status")
+
+
+class StatusIter(bt2._UserMessageIterator):
+ def __init__(self, config, output_port):
+ self.case = output_port.user_data["case"]
+
+ def __next__(self):
+ if self.case == "STOP":
+ raise bt2.Stop()
+ if self.case == "INTERRUPTED":
+ os.kill(os.getpid(), signal.SIGINT)
+
+ # Wait until the graph is in the interrupted state.
+ timeout_s = 10
+ for _ in range(timeout_s * 10):
+ if self._is_interrupted:
+ raise bt2.TryAgain()
+
+ time.sleep(0.1)
+
+ raise Exception(
+ "{} was not interrupted after {} seconds".format(
+ self.__class__.__name__, timeout_s
+ )
+ )
+
+ elif self.case == "ERROR":
+ raise TypeError("Raising type error")
+ else:
+ raise ValueError("Invalid parameter")
+
+
+@bt2.plugin_component_class
+class StatusSrc(bt2._UserSourceComponent, message_iterator_class=StatusIter):
+ def __init__(self, config, params, obj):
+ self._add_output_port("out", {"case": params["case"]})
+++ /dev/null
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 EfficiOS Inc.
-#
-
-import os
-import time
-import signal
-
-import bt2
-
-bt2.register_plugin(__name__, "test_exit_status")
-
-
-class StatusIter(bt2._UserMessageIterator):
- def __init__(self, config, output_port):
- self.case = output_port.user_data["case"]
-
- def __next__(self):
- if self.case == "STOP":
- raise bt2.Stop()
- if self.case == "INTERRUPTED":
- os.kill(os.getpid(), signal.SIGINT)
-
- # Wait until the graph is in the interrupted state.
- timeout_s = 10
- for _ in range(timeout_s * 10):
- if self._is_interrupted:
- raise bt2.TryAgain()
-
- time.sleep(0.1)
-
- raise Exception(
- "{} was not interrupted after {} seconds".format(
- self.__class__.__name__, timeout_s
- )
- )
-
- elif self.case == "ERROR":
- raise TypeError("Raising type error")
- else:
- raise ValueError("Invalid parameter")
-
-
-@bt2.plugin_component_class
-class StatusSrc(bt2._UserSourceComponent, message_iterator_class=StatusIter):
- def __init__(self, config, params, obj):
- self._add_output_port("out", {"case": params["case"]})
--- /dev/null
+/* CTF 1.8 */
+
+typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
+typealias integer { size = 16; align = 8; signed = false; } := uint16_t;
+typealias integer { size = 32; align = 8; signed = false; } := uint32_t;
+typealias integer { size = 64; align = 8; signed = false; } := uint64_t;
+typealias integer { size = 5; align = 1; signed = false; } := uint5_t;
+typealias integer { size = 27; align = 1; signed = false; } := uint27_t;
+
+trace {
+ major = 1;
+ minor = 8;
+ uuid = "624b19d9-19cd-4eae-bab8-8342e1b96a5d";
+ byte_order = le;
+ packet.header := struct {
+ uint32_t magic;
+ uint8_t uuid[16];
+ uint32_t stream_id;
+ };
+};
+
+env {
+ vpid = 3208;
+ procname = "wk-heartbeat";
+ domain = "ust";
+ tracer_name = "lttng-ust";
+ tracer_major = 2;
+ tracer_minor = 0;
+ tracer_patchlevel = 2;
+};
+
+clock {
+ name = monotonic;
+ uuid = "c19b5ac9-b8e6-4f78-be95-a605d04e34c6";
+ description = "Monotonic Clock";
+ freq = 1000000000; /* Frequency, in Hz */
+ /* clock value offset from Epoch is: offset * (1/freq) */
+ offset = 1351530929945824323;
+};
+
+typealias integer {
+ size = 27; align = 1; signed = false;
+ map = clock.monotonic.value;
+} := uint27_clock_monotonic_t;
+
+typealias integer {
+ size = 32; align = 8; signed = false;
+ map = clock.monotonic.value;
+} := uint32_clock_monotonic_t;
+
+typealias integer {
+ size = 64; align = 8; signed = false;
+ map = clock.monotonic.value;
+} := uint64_clock_monotonic_t;
+
+struct packet_context {
+ uint64_clock_monotonic_t timestamp_begin;
+ uint64_clock_monotonic_t timestamp_end;
+ uint32_t events_discarded;
+ uint32_t content_size;
+ uint32_t packet_size;
+ uint32_t cpu_id;
+};
+
+struct event_header_compact {
+ enum : uint5_t { compact = 0 ... 30, extended = 31 } id;
+ variant <id> {
+ struct {
+ uint27_clock_monotonic_t timestamp;
+ } compact;
+ struct {
+ uint32_t id;
+ uint64_clock_monotonic_t timestamp;
+ } extended;
+ } v;
+} align(8);
+
+struct event_header_large {
+ enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;
+ variant <id> {
+ struct {
+ uint32_clock_monotonic_t timestamp;
+ } compact;
+ struct {
+ uint32_t id;
+ uint64_clock_monotonic_t timestamp;
+ } extended;
+ } v;
+} align(8);
+
+stream {
+ id = 0;
+ event.header := struct event_header_compact;
+ packet.context := struct packet_context;
+ event.context := struct {
+ integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _vtid;
+ integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _vpid;
+ };
+};
+
+event {
+ name = "heartbeat:msg";
+ id = 0;
+ stream_id = 0;
+ loglevel = 13;
+ fields := struct {
+ string _msg;
+ };
+};
+
+
+++ /dev/null
-/* CTF 1.8 */
-
-typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-typealias integer { size = 16; align = 8; signed = false; } := uint16_t;
-typealias integer { size = 32; align = 8; signed = false; } := uint32_t;
-typealias integer { size = 64; align = 8; signed = false; } := uint64_t;
-typealias integer { size = 5; align = 1; signed = false; } := uint5_t;
-typealias integer { size = 27; align = 1; signed = false; } := uint27_t;
-
-trace {
- major = 1;
- minor = 8;
- uuid = "624b19d9-19cd-4eae-bab8-8342e1b96a5d";
- byte_order = le;
- packet.header := struct {
- uint32_t magic;
- uint8_t uuid[16];
- uint32_t stream_id;
- };
-};
-
-env {
- vpid = 3208;
- procname = "wk-heartbeat";
- domain = "ust";
- tracer_name = "lttng-ust";
- tracer_major = 2;
- tracer_minor = 0;
- tracer_patchlevel = 2;
-};
-
-clock {
- name = monotonic;
- uuid = "c19b5ac9-b8e6-4f78-be95-a605d04e34c6";
- description = "Monotonic Clock";
- freq = 1000000000; /* Frequency, in Hz */
- /* clock value offset from Epoch is: offset * (1/freq) */
- offset = 1351530929945824323;
-};
-
-typealias integer {
- size = 27; align = 1; signed = false;
- map = clock.monotonic.value;
-} := uint27_clock_monotonic_t;
-
-typealias integer {
- size = 32; align = 8; signed = false;
- map = clock.monotonic.value;
-} := uint32_clock_monotonic_t;
-
-typealias integer {
- size = 64; align = 8; signed = false;
- map = clock.monotonic.value;
-} := uint64_clock_monotonic_t;
-
-struct packet_context {
- uint64_clock_monotonic_t timestamp_begin;
- uint64_clock_monotonic_t timestamp_end;
- uint32_t events_discarded;
- uint32_t content_size;
- uint32_t packet_size;
- uint32_t cpu_id;
-};
-
-struct event_header_compact {
- enum : uint5_t { compact = 0 ... 30, extended = 31 } id;
- variant <id> {
- struct {
- uint27_clock_monotonic_t timestamp;
- } compact;
- struct {
- uint32_t id;
- uint64_clock_monotonic_t timestamp;
- } extended;
- } v;
-} align(8);
-
-struct event_header_large {
- enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;
- variant <id> {
- struct {
- uint32_clock_monotonic_t timestamp;
- } compact;
- struct {
- uint32_t id;
- uint64_clock_monotonic_t timestamp;
- } extended;
- } v;
-} align(8);
-
-stream {
- id = 0;
- event.header := struct event_header_compact;
- packet.context := struct packet_context;
- event.context := struct {
- integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _vtid;
- integer { size = 32; align = 8; signed = 1; encoding = none; base = 10; } _vpid;
- };
-};
-
-event {
- name = "heartbeat:msg";
- id = 0;
- stream_id = 0;
- loglevel = 13;
- fields := struct {
- string _msg;
- };
-};
-
-
--- /dev/null
+/* CTF 1.8 */
+
+typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
+typealias integer { size = 16; align = 8; signed = false; } := uint16_t;
+typealias integer { size = 32; align = 8; signed = false; } := uint32_t;
+typealias integer { size = 64; align = 8; signed = false; } := uint64_t;
+typealias integer { size = 64; align = 8; signed = false; } := unsigned long;
+typealias integer { size = 5; align = 1; signed = false; } := uint5_t;
+typealias integer { size = 27; align = 1; signed = false; } := uint27_t;
+
+trace {
+ major = 1;
+ minor = 8;
+ uuid = "0339cd08-892d-404c-9291-64c1a8a74c81";
+ byte_order = le;
+ packet.header := struct {
+ uint32_t magic;
+ uint8_t uuid[16];
+ uint32_t stream_id;
+ uint64_t stream_instance_id;
+ };
+};
+
+env {
+ domain = "ust";
+ tracer_name = "lttng-ust";
+ tracer_major = 2;
+ tracer_minor = 12;
+ tracer_buffering_scheme = "uid";
+ tracer_buffering_id = 1000;
+ architecture_bit_width = 64;
+ trace_name = "barney_descontie";
+ trace_creation_datetime = "20200715T174253-0400";
+ hostname = "raton";
+};
+
+clock {
+ name = "monotonic";
+ uuid = "81a04b89-9028-4d3e-a28d-5fbd53a8eb9d";
+ description = "Monotonic Clock";
+ freq = 1000000000; /* Frequency, in Hz */
+ /* clock value offset from Epoch is: offset * (1/freq) */
+ offset = 1594406328768346378;
+};
+
+typealias integer {
+ size = 27; align = 1; signed = false;
+ map = clock.monotonic.value;
+} := uint27_clock_monotonic_t;
+
+typealias integer {
+ size = 32; align = 8; signed = false;
+ map = clock.monotonic.value;
+} := uint32_clock_monotonic_t;
+
+typealias integer {
+ size = 64; align = 8; signed = false;
+ map = clock.monotonic.value;
+} := uint64_clock_monotonic_t;
+
+struct packet_context {
+ uint64_clock_monotonic_t timestamp_begin;
+ uint64_clock_monotonic_t timestamp_end;
+ uint64_t content_size;
+ uint64_t packet_size;
+ uint64_t packet_seq_num;
+ unsigned long events_discarded;
+ uint32_t cpu_id;
+};
+
+struct event_header_compact {
+ enum : uint5_t { compact = 0 ... 30, extended = 31 } id;
+ variant <id> {
+ struct {
+ uint27_clock_monotonic_t timestamp;
+ } compact;
+ struct {
+ uint32_t id;
+ uint64_clock_monotonic_t timestamp;
+ } extended;
+ } v;
+} align(8);
+
+struct event_header_large {
+ enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;
+ variant <id> {
+ struct {
+ uint32_clock_monotonic_t timestamp;
+ } compact;
+ struct {
+ uint32_t id;
+ uint64_clock_monotonic_t timestamp;
+ } extended;
+ } v;
+} align(8);
+
+stream {
+ id = 0;
+ event.header := struct event_header_large;
+ packet.context := struct packet_context;
+};
+
+event {
+ name = "my_app:signe_de_pia$$e";
+ id = 0;
+ stream_id = 0;
+ loglevel = 13;
+ fields := struct {
+ };
+};
+
+event {
+ name = "my_app:signe_de_pia$$e_2";
+ id = 1;
+ stream_id = 0;
+ loglevel = 13;
+ fields := struct {
+ };
+};
+++ /dev/null
-/* CTF 1.8 */
-
-typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-typealias integer { size = 16; align = 8; signed = false; } := uint16_t;
-typealias integer { size = 32; align = 8; signed = false; } := uint32_t;
-typealias integer { size = 64; align = 8; signed = false; } := uint64_t;
-typealias integer { size = 64; align = 8; signed = false; } := unsigned long;
-typealias integer { size = 5; align = 1; signed = false; } := uint5_t;
-typealias integer { size = 27; align = 1; signed = false; } := uint27_t;
-
-trace {
- major = 1;
- minor = 8;
- uuid = "0339cd08-892d-404c-9291-64c1a8a74c81";
- byte_order = le;
- packet.header := struct {
- uint32_t magic;
- uint8_t uuid[16];
- uint32_t stream_id;
- uint64_t stream_instance_id;
- };
-};
-
-env {
- domain = "ust";
- tracer_name = "lttng-ust";
- tracer_major = 2;
- tracer_minor = 12;
- tracer_buffering_scheme = "uid";
- tracer_buffering_id = 1000;
- architecture_bit_width = 64;
- trace_name = "barney_descontie";
- trace_creation_datetime = "20200715T174253-0400";
- hostname = "raton";
-};
-
-clock {
- name = "monotonic";
- uuid = "81a04b89-9028-4d3e-a28d-5fbd53a8eb9d";
- description = "Monotonic Clock";
- freq = 1000000000; /* Frequency, in Hz */
- /* clock value offset from Epoch is: offset * (1/freq) */
- offset = 1594406328768346378;
-};
-
-typealias integer {
- size = 27; align = 1; signed = false;
- map = clock.monotonic.value;
-} := uint27_clock_monotonic_t;
-
-typealias integer {
- size = 32; align = 8; signed = false;
- map = clock.monotonic.value;
-} := uint32_clock_monotonic_t;
-
-typealias integer {
- size = 64; align = 8; signed = false;
- map = clock.monotonic.value;
-} := uint64_clock_monotonic_t;
-
-struct packet_context {
- uint64_clock_monotonic_t timestamp_begin;
- uint64_clock_monotonic_t timestamp_end;
- uint64_t content_size;
- uint64_t packet_size;
- uint64_t packet_seq_num;
- unsigned long events_discarded;
- uint32_t cpu_id;
-};
-
-struct event_header_compact {
- enum : uint5_t { compact = 0 ... 30, extended = 31 } id;
- variant <id> {
- struct {
- uint27_clock_monotonic_t timestamp;
- } compact;
- struct {
- uint32_t id;
- uint64_clock_monotonic_t timestamp;
- } extended;
- } v;
-} align(8);
-
-struct event_header_large {
- enum : uint16_t { compact = 0 ... 65534, extended = 65535 } id;
- variant <id> {
- struct {
- uint32_clock_monotonic_t timestamp;
- } compact;
- struct {
- uint32_t id;
- uint64_clock_monotonic_t timestamp;
- } extended;
- } v;
-} align(8);
-
-stream {
- id = 0;
- event.header := struct event_header_large;
- packet.context := struct packet_context;
-};
-
-event {
- name = "my_app:signe_de_pia$$e";
- id = 0;
- stream_id = 0;
- loglevel = 13;
- fields := struct {
- };
-};
-
-event {
- name = "my_app:signe_de_pia$$e_2";
- id = 1;
- stream_id = 0;
- loglevel = 13;
- fields := struct {
- };
-};
--- /dev/null
+--- metadata
+/* CTF 1.8 */
+
+typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
+
+trace {
+ major = 1;
+ minor = 8;
+ byte_order = le;
+};
+
+struct packet_context {
+ uint8_t timestamp_begin;
+ uint8_t timestamp_end;
+ uint8_t content_size;
+ uint8_t packet_size;
+};
+
+struct event_header {
+ uint8_t id;
+ uint8_t timestamp;
+};
+
+stream {
+ event.header := struct event_header;
+ packet.context := struct packet_context;
+};
+
+event {
+ name = "event1";
+ id = 1;
+ fields := struct {
+ uint8_t len;
+ uint8_t seq[len];
+ };
+};
+
+event {
+ name = "event2";
+ id = 2;
+ fields := struct {
+ uint8_t len;
+ uint8_t seq[len];
+ };
+};
+
+--- channel0_0
+!macro packet(ts_beg, event_id)
+ <beg>
+ [ ts_beg : 8] # timestamp begin
+ [ ts_beg + 1 : 8] # timestamp end
+ [8 * (end - beg) : 8] # content size in bits
+ [8 * (end - beg) : 8] # packet size in bits
+
+ [ event_id : 8] # event id
+ [ ts_beg : 8] # timestamp
+ [ 0 : 8] # len field
+ <end>
+!end
+
+{ p1_ts = 10 }
+{ p2_ts = 20 }
+
+<p1>
+m:packet(p1_ts, 1)
+<p1_end>
+
+<p2>
+m:packet(p2_ts, 2)
+<p2_end>
+
+--- index/channel0_0.idx
+!be
+
+[0xC1F1DCC1 : 32] # Magic number
+[ 1 : 32] # Major
+[ 0 : 32] # Minor
+[ 56 : 32] # Index entry size (56 bytes)
+
+# Packet 1
+!macro entry(beg_label, end_label, ts_beg)
+ [ beg_label : 64] # offset in bytes
+ [8 * (end_label - beg_label) : 64] # total size in bits
+ [8 * (end_label - beg_label) : 64] # content size in bits
+ [ ts_beg : 64] # timestamp begin
+ [ ts_beg + 1 : 64] # timestamp end
+ [ 0 : 64] # events discarded
+ [ 0 : 64] # stream class id
+!end
+
+m:entry(p1, p1_end, p1_ts)
+m:entry(p2, p2_end, p2_ts)
+++ /dev/null
---- metadata
-/* CTF 1.8 */
-
-typealias integer { size = 8; align = 8; signed = false; } := uint8_t;
-
-trace {
- major = 1;
- minor = 8;
- byte_order = le;
-};
-
-struct packet_context {
- uint8_t timestamp_begin;
- uint8_t timestamp_end;
- uint8_t content_size;
- uint8_t packet_size;
-};
-
-struct event_header {
- uint8_t id;
- uint8_t timestamp;
-};
-
-stream {
- event.header := struct event_header;
- packet.context := struct packet_context;
-};
-
-event {
- name = "event1";
- id = 1;
- fields := struct {
- uint8_t len;
- uint8_t seq[len];
- };
-};
-
-event {
- name = "event2";
- id = 2;
- fields := struct {
- uint8_t len;
- uint8_t seq[len];
- };
-};
-
---- channel0_0
-!macro packet(ts_beg, event_id)
- <beg>
- [ ts_beg : 8] # timestamp begin
- [ ts_beg + 1 : 8] # timestamp end
- [8 * (end - beg) : 8] # content size in bits
- [8 * (end - beg) : 8] # packet size in bits
-
- [ event_id : 8] # event id
- [ ts_beg : 8] # timestamp
- [ 0 : 8] # len field
- <end>
-!end
-
-{ p1_ts = 10 }
-{ p2_ts = 20 }
-
-<p1>
-m:packet(p1_ts, 1)
-<p1_end>
-
-<p2>
-m:packet(p2_ts, 2)
-<p2_end>
-
---- index/channel0_0.idx
-!be
-
-[0xC1F1DCC1 : 32] # Magic number
-[ 1 : 32] # Major
-[ 0 : 32] # Minor
-[ 56 : 32] # Index entry size (56 bytes)
-
-# Packet 1
-!macro entry(beg_label, end_label, ts_beg)
- [ beg_label : 64] # offset in bytes
- [8 * (end_label - beg_label) : 64] # total size in bits
- [8 * (end_label - beg_label) : 64] # content size in bits
- [ ts_beg : 64] # timestamp begin
- [ ts_beg + 1 : 64] # timestamp end
- [ 0 : 64] # events discarded
- [ 0 : 64] # stream class id
-!end
-
-m:entry(p1, p1_end, p1_ts)
-m:entry(p2, p2_end, p2_ts)
--- /dev/null
+/* CTF 1.8 */
+
+trace {
+ major = 1;
+ minor = 8;
+ uuid = "ad21eeaa-fab9-4692-aab8-ebd68c7feb17";
+ byte_order = be;
+ packet.header := struct {
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } magic;
+ integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } uuid[16];
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } stream_id;
+ } align(8);
+};
+
+env {
+ host = "sinkpad";
+};
+
+clock {
+ name = test_clock;
+ uuid = "d336520f-985d-481e-8e35-d99328655354";
+ description = "This is a test clock";
+ freq = 1000000000;
+ precision = 10;
+ offset_s = 13515309;
+ offset = 0;
+ absolute = TRUE;
+};
+
+stream {
+ id = 0;
+ event.header := struct {
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } id;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; map = clock.test_clock.value; } timestamp;
+ } align(8);
+
+ packet.context := struct {
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_begin;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_end;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } content_size;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } packet_size;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } events_discarded;
+ integer { size = 64; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_seq_num;
+ } align(8);
+};
+
+event {
+ id = 0;
+ name = "dummy_event";
+ stream_id = 0;
+ fields := struct {
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } dummy_value;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } tracefile_id;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_begin;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_end;
+ } align(1);
+};
+
--- /dev/null
+/* CTF 1.8 */
+
+trace {
+ major = 1;
+ minor = 8;
+ uuid = "61db8e6b-2069-40e4-84ed-bc15f42181f0";
+ byte_order = be;
+ packet.header := struct {
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } magic;
+ integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } uuid[16];
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } stream_id;
+ } align(8);
+};
+
+env {
+ host = "sinkpad";
+};
+
+clock {
+ name = test_clock;
+ uuid = "a0a8c252-db03-4f36-a148-80a0a3c4edff";
+ description = "This is a test clock";
+ freq = 1000000000;
+ precision = 10;
+ offset_s = 13515309;
+ offset = 0;
+ absolute = TRUE;
+};
+
+stream {
+ id = 0;
+ event.header := struct {
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } id;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; map = clock.test_clock.value; } timestamp;
+ } align(8);
+
+ packet.context := struct {
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_begin;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_end;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } content_size;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } packet_size;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } events_discarded;
+ integer { size = 64; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_seq_num;
+ } align(8);
+};
+
+event {
+ id = 0;
+ name = "dummy_event";
+ stream_id = 0;
+ fields := struct {
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } dummy_value;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } tracefile_id;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_begin;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_end;
+ } align(1);
+};
+
--- /dev/null
+/* CTF 1.8 */
+
+trace {
+ major = 1;
+ minor = 8;
+ uuid = "eb5045f7-b471-488e-b963-0221ddf423a7";
+ byte_order = be;
+ packet.header := struct {
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } magic;
+ integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } uuid[16];
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } stream_id;
+ } align(8);
+};
+
+env {
+ host = "sinkpad";
+};
+
+clock {
+ name = test_clock;
+ uuid = "2447a359-1e57-448f-96ef-3c324327047c";
+ description = "This is a test clock";
+ freq = 1000000000;
+ precision = 10;
+ offset_s = 13515309;
+ offset = 0;
+ absolute = TRUE;
+};
+
+stream {
+ id = 0;
+ event.header := struct {
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } id;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; map = clock.test_clock.value; } timestamp;
+ } align(8);
+
+ packet.context := struct {
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_begin;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_end;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } content_size;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } packet_size;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } events_discarded;
+ integer { size = 64; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_seq_num;
+ } align(8);
+};
+
+event {
+ id = 0;
+ name = "dummy_event";
+ stream_id = 0;
+ fields := struct {
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } dummy_value;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } tracefile_id;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_begin;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_end;
+ } align(1);
+};
+
--- /dev/null
+/* CTF 1.8 */
+
+/* This was generated by a Babeltrace `sink.ctf.fs` component. */
+
+trace {
+ major = 1;
+ minor = 8;
+ uuid = "1c810767-575e-4c4e-afa1-5d3e15081cb9";
+ byte_order = le;
+ packet.header := struct {
+ integer { size = 32; align = 8; base = x; } magic;
+ integer { size = 8; align = 8; } uuid[16];
+ integer { size = 64; align = 8; } stream_id;
+ integer { size = 64; align = 8; } stream_instance_id;
+ } align(8);
+};
+
+clock {
+ name = default;
+ freq = 1000000000;
+ precision = 0;
+ offset_s = 0;
+ offset = 0;
+ absolute = true;
+};
+
+stream {
+ id = 0;
+ packet.context := struct {
+ integer { size = 64; align = 8; } packet_size;
+ integer { size = 64; align = 8; } content_size;
+ integer { size = 64; align = 8; map = clock.default.value; } timestamp_begin;
+ integer { size = 64; align = 8; map = clock.default.value; } timestamp_end;
+ integer { size = 64; align = 8; } packet_seq_num;
+ } align(8);
+
+ event.header := struct {
+ integer { size = 64; align = 8; } id;
+ integer { size = 64; align = 8; map = clock.default.value; } timestamp;
+ } align(8);
+};
+
+event {
+ name = "my-event";
+ stream_id = 0;
+ id = 0;
+};
+
--- /dev/null
+/* CTF 1.8 */
+
+trace {
+ major = 1;
+ minor = 8;
+ uuid = "0bef2d78-5020-4b09-b520-64480ef5c0e6";
+ byte_order = be;
+ packet.header := struct {
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } magic;
+ integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } uuid[16];
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } stream_id;
+ } align(8);
+};
+
+env {
+ host = "sinkpad";
+};
+
+clock {
+ name = test_clock;
+ uuid = "ae130a0d-e10b-49cb-8b2d-64beaa23814c";
+ description = "This is a test clock";
+ freq = 1000000000;
+ precision = 10;
+ offset_s = 13932323;
+ offset = 0;
+ absolute = TRUE;
+};
+
+stream {
+ id = 0;
+ event.header := struct {
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } id;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; map = clock.test_clock.value; } timestamp;
+ } align(8);
+
+ packet.context := struct {
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_begin;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_end;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } content_size;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } packet_size;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } events_discarded;
+ integer { size = 64; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_seq_num;
+ } align(8);
+};
+
+event {
+ id = 0;
+ name = "dummy_event";
+ stream_id = 0;
+ fields := struct {
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } dummy_value;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } tracefile_id;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_begin;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_end;
+ } align(1);
+};
+
--- /dev/null
+/* CTF 1.8 */
+
+trace {
+ major = 1;
+ minor = 8;
+ uuid = "b7d90429-287f-45ff-897c-3db7c5ab8b5a";
+ byte_order = be;
+ packet.header := struct {
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } magic;
+ integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } uuid[16];
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } stream_id;
+ } align(8);
+};
+
+env {
+ host = "sinkpad";
+};
+
+clock {
+ name = test_clock;
+ uuid = "004fa3e8-48aa-453a-8be8-9d30ead9ac66";
+ description = "This is a test clock";
+ freq = 1000000000;
+ precision = 10;
+ offset_s = 13515309;
+ offset = 0;
+ absolute = TRUE;
+};
+
+stream {
+ id = 0;
+ event.header := struct {
+ integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } id;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; map = clock.test_clock.value; } timestamp;
+ } align(8);
+
+ packet.context := struct {
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_begin;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_end;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } content_size;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } packet_size;
+ integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } events_discarded;
+ integer { size = 64; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_seq_num;
+ } align(8);
+};
+
+event {
+ id = 0;
+ name = "dummy_event";
+ stream_id = 0;
+ fields := struct {
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } dummy_value;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } tracefile_id;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_begin;
+ integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_end;
+ } align(1);
+};
+
+++ /dev/null
-/* CTF 1.8 */
-
-trace {
- major = 1;
- minor = 8;
- uuid = "ad21eeaa-fab9-4692-aab8-ebd68c7feb17";
- byte_order = be;
- packet.header := struct {
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } magic;
- integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } uuid[16];
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } stream_id;
- } align(8);
-};
-
-env {
- host = "sinkpad";
-};
-
-clock {
- name = test_clock;
- uuid = "d336520f-985d-481e-8e35-d99328655354";
- description = "This is a test clock";
- freq = 1000000000;
- precision = 10;
- offset_s = 13515309;
- offset = 0;
- absolute = TRUE;
-};
-
-stream {
- id = 0;
- event.header := struct {
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } id;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; map = clock.test_clock.value; } timestamp;
- } align(8);
-
- packet.context := struct {
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_begin;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_end;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } content_size;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } packet_size;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } events_discarded;
- integer { size = 64; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_seq_num;
- } align(8);
-};
-
-event {
- id = 0;
- name = "dummy_event";
- stream_id = 0;
- fields := struct {
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } dummy_value;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } tracefile_id;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_begin;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_end;
- } align(1);
-};
-
+++ /dev/null
-/* CTF 1.8 */
-
-trace {
- major = 1;
- minor = 8;
- uuid = "61db8e6b-2069-40e4-84ed-bc15f42181f0";
- byte_order = be;
- packet.header := struct {
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } magic;
- integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } uuid[16];
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } stream_id;
- } align(8);
-};
-
-env {
- host = "sinkpad";
-};
-
-clock {
- name = test_clock;
- uuid = "a0a8c252-db03-4f36-a148-80a0a3c4edff";
- description = "This is a test clock";
- freq = 1000000000;
- precision = 10;
- offset_s = 13515309;
- offset = 0;
- absolute = TRUE;
-};
-
-stream {
- id = 0;
- event.header := struct {
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } id;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; map = clock.test_clock.value; } timestamp;
- } align(8);
-
- packet.context := struct {
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_begin;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_end;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } content_size;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } packet_size;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } events_discarded;
- integer { size = 64; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_seq_num;
- } align(8);
-};
-
-event {
- id = 0;
- name = "dummy_event";
- stream_id = 0;
- fields := struct {
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } dummy_value;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } tracefile_id;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_begin;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_end;
- } align(1);
-};
-
+++ /dev/null
-/* CTF 1.8 */
-
-trace {
- major = 1;
- minor = 8;
- uuid = "eb5045f7-b471-488e-b963-0221ddf423a7";
- byte_order = be;
- packet.header := struct {
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } magic;
- integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } uuid[16];
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } stream_id;
- } align(8);
-};
-
-env {
- host = "sinkpad";
-};
-
-clock {
- name = test_clock;
- uuid = "2447a359-1e57-448f-96ef-3c324327047c";
- description = "This is a test clock";
- freq = 1000000000;
- precision = 10;
- offset_s = 13515309;
- offset = 0;
- absolute = TRUE;
-};
-
-stream {
- id = 0;
- event.header := struct {
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } id;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; map = clock.test_clock.value; } timestamp;
- } align(8);
-
- packet.context := struct {
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_begin;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_end;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } content_size;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } packet_size;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } events_discarded;
- integer { size = 64; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_seq_num;
- } align(8);
-};
-
-event {
- id = 0;
- name = "dummy_event";
- stream_id = 0;
- fields := struct {
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } dummy_value;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } tracefile_id;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_begin;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_end;
- } align(1);
-};
-
+++ /dev/null
-/* CTF 1.8 */
-
-/* This was generated by a Babeltrace `sink.ctf.fs` component. */
-
-trace {
- major = 1;
- minor = 8;
- uuid = "1c810767-575e-4c4e-afa1-5d3e15081cb9";
- byte_order = le;
- packet.header := struct {
- integer { size = 32; align = 8; base = x; } magic;
- integer { size = 8; align = 8; } uuid[16];
- integer { size = 64; align = 8; } stream_id;
- integer { size = 64; align = 8; } stream_instance_id;
- } align(8);
-};
-
-clock {
- name = default;
- freq = 1000000000;
- precision = 0;
- offset_s = 0;
- offset = 0;
- absolute = true;
-};
-
-stream {
- id = 0;
- packet.context := struct {
- integer { size = 64; align = 8; } packet_size;
- integer { size = 64; align = 8; } content_size;
- integer { size = 64; align = 8; map = clock.default.value; } timestamp_begin;
- integer { size = 64; align = 8; map = clock.default.value; } timestamp_end;
- integer { size = 64; align = 8; } packet_seq_num;
- } align(8);
-
- event.header := struct {
- integer { size = 64; align = 8; } id;
- integer { size = 64; align = 8; map = clock.default.value; } timestamp;
- } align(8);
-};
-
-event {
- name = "my-event";
- stream_id = 0;
- id = 0;
-};
-
+++ /dev/null
-/* CTF 1.8 */
-
-trace {
- major = 1;
- minor = 8;
- uuid = "b7d90429-287f-45ff-897c-3db7c5ab8b5a";
- byte_order = be;
- packet.header := struct {
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } magic;
- integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } uuid[16];
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } stream_id;
- } align(8);
-};
-
-env {
- host = "sinkpad";
-};
-
-clock {
- name = test_clock;
- uuid = "004fa3e8-48aa-453a-8be8-9d30ead9ac66";
- description = "This is a test clock";
- freq = 1000000000;
- precision = 10;
- offset_s = 13515309;
- offset = 0;
- absolute = TRUE;
-};
-
-stream {
- id = 0;
- event.header := struct {
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } id;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; map = clock.test_clock.value; } timestamp;
- } align(8);
-
- packet.context := struct {
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_begin;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_end;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } content_size;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } packet_size;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } events_discarded;
- integer { size = 64; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_seq_num;
- } align(8);
-};
-
-event {
- id = 0;
- name = "dummy_event";
- stream_id = 0;
- fields := struct {
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } dummy_value;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } tracefile_id;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_begin;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_end;
- } align(1);
-};
-
+++ /dev/null
-/* CTF 1.8 */
-
-trace {
- major = 1;
- minor = 8;
- uuid = "0bef2d78-5020-4b09-b520-64480ef5c0e6";
- byte_order = be;
- packet.header := struct {
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } magic;
- integer { size = 8; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } uuid[16];
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } stream_id;
- } align(8);
-};
-
-env {
- host = "sinkpad";
-};
-
-clock {
- name = test_clock;
- uuid = "ae130a0d-e10b-49cb-8b2d-64beaa23814c";
- description = "This is a test clock";
- freq = 1000000000;
- precision = 10;
- offset_s = 13932323;
- offset = 0;
- absolute = TRUE;
-};
-
-stream {
- id = 0;
- event.header := struct {
- integer { size = 32; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } id;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; map = clock.test_clock.value; } timestamp;
- } align(8);
-
- packet.context := struct {
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_begin;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } timestamp_end;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } content_size;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } packet_size;
- integer { size = 64; align = 8; signed = false; encoding = none; base = decimal; byte_order = be; } events_discarded;
- integer { size = 64; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_seq_num;
- } align(8);
-};
-
-event {
- id = 0;
- name = "dummy_event";
- stream_id = 0;
- fields := struct {
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } dummy_value;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } tracefile_id;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_begin;
- integer { size = 32; align = 1; signed = false; encoding = none; base = decimal; byte_order = be; } packet_end;
- } align(1);
-};
-
BUILD_DIR ?= build
-OBJS=$(BUILD_DIR)/dwarf_full/libhello_so \
- $(BUILD_DIR)/elf_only/libhello_so \
- $(BUILD_DIR)/build_id/libhello_so \
- $(BUILD_DIR)/debug_link/libhello_so
+OBJS=$(BUILD_DIR)/dwarf-full/libhello-so \
+ $(BUILD_DIR)/elf-only/libhello-so \
+ $(BUILD_DIR)/build-id/libhello-so \
+ $(BUILD_DIR)/debug-link/libhello-so
all: $(OBJS)
$(CC) -gdwarf -fdebug-prefix-map=$(CURDIR)=. -fPIC -c -I. -o $@ $<
# Master copy: ELF with DWARF and build-id
-$(BUILD_DIR)/dwarf_full/libhello_so: tp.o libhello.o
+$(BUILD_DIR)/dwarf-full/libhello-so: tp.o libhello.o
mkdir -p $(@D)
$(CC) -shared -gdwarf -llttng-ust -ldl -Wl,-soname,libhello.so -Wl,--build-id=0x$(BUILD_ID) -o $@ $^
# ELF only, no debug symbols, no build-d
-$(BUILD_DIR)/elf_only/libhello_so: $(BUILD_DIR)/dwarf_full/libhello_so
+$(BUILD_DIR)/elf-only/libhello-so: $(BUILD_DIR)/dwarf-full/libhello-so
mkdir -p $(@D)
objcopy -g $< $@.tmp
objcopy --remove-section=.note.gnu.build-id $@.tmp
mv $@.tmp $@
# ELF with external build-id DWARF
-$(BUILD_DIR)/build_id/libhello_so: $(BUILD_DIR)/dwarf_full/libhello_so
+$(BUILD_DIR)/build-id/libhello-so: $(BUILD_DIR)/dwarf-full/libhello-so
mkdir -p $(@D)/.build-id/$(BUILD_ID_PREFIX)
objcopy --only-keep-debug $< $(@D)/.build-id/$(BUILD_ID_PREFIX)/$(BUILD_ID_SUFFIX).debug
objcopy -g $< $@
# ELF with external debug link DWARF
-$(BUILD_DIR)/debug_link/libhello_so: $(BUILD_DIR)/dwarf_full/libhello_so
+$(BUILD_DIR)/debug-link/libhello-so: $(BUILD_DIR)/dwarf-full/libhello-so
mkdir -p $(@D)
objcopy --remove-section=.note.gnu.build-id $< $@.tmp
- objcopy --only-keep-debug $@.tmp $(@D)/libhello_so.debug
+ objcopy --only-keep-debug $@.tmp $(@D)/libhello-so.debug
objcopy -g $@.tmp
- cd $(@D) && objcopy --add-gnu-debuglink=libhello_so.debug $(@F).tmp
+ cd $(@D) && objcopy --add-gnu-debuglink=libhello-so.debug $(@F).tmp
mv $@.tmp $@
clean:
The generated files are:
-* `ARCH/dwarf_full/libhello_so` (ELF and DWARF)
-* `ARCH/elf_only/libhello_so` (ELF only)
-* `ARCH/build_id/libhello_so` (ELF with separate DWARF via build ID)
-* `ARCH/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug` (DWARF for build ID)
-* `ARCH/debug_link/libhello_so` (ELF with separate DWARF via debug link)
-* `ARCH/debug_link/libhello_so.debug` (DWARF for debug link)
+* `ARCH/dwarf-full/libhello-so` (ELF and DWARF)
+* `ARCH/elf-only/libhello-so` (ELF only)
+* `ARCH/build-id/libhello-so` (ELF with separate DWARF via build ID)
+* `ARCH/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug` (DWARF for build ID)
+* `ARCH/debug_link/libhello-so` (ELF with separate DWARF via debug link)
+* `ARCH/debug_link/libhello-so.debug` (DWARF for debug link)
We use a suffix of "_so" instead of ".so" since some distributions
build systems will consider ".so" files as artifacts from a previous
$ build_id_prefix=cd
$ build_id_suffix=d98cdd87f7fe64c13b6daad553987eafd40cbb
$ build_id="$build_id_prefix$build_id_suffix"
- $ mkdir dwarf_full
- $ gcc -shared -g -llttng-ust -ldl -Wl,-soname,libhello.so -Wl,--build-id=0x$build_id -o dwarf_full/libhello_so tp.o libhello.o
+ $ mkdir dwarf-full
+ $ gcc -shared -g -llttng-ust -ldl -Wl,-soname,libhello.so -Wl,--build-id=0x$build_id -o dwarf-full/libhello-so tp.o libhello.o
## ELF only
- $ mkdir elf_only
- $ objcopy -g dwarf_full/libhello_so elf_only/libhello_so
- $ objcopy --remove-section=.note.gnu.build-id elf_only/libhello_so
+ $ mkdir elf-only
+ $ objcopy -g dwarf-full/libhello-so elf-only/libhello-so
+ $ objcopy --remove-section=.note.gnu.build-id elf-only/libhello-so
## ELF and DWARF with Build ID
- $ mkdir -p build_id/.build-id/$build_id_prefix
- $ objcopy --only-keep-debug dwarf_full/libhello_so build_id/.build-id/$build_id_prefix/$build_id_suffix.debug
- $ objcopy -g dwarf_full/libhello_so build_id/libhello_so
+ $ mkdir -p build-id/.build-id/$build_id_prefix
+ $ objcopy --only-keep-debug dwarf-full/libhello-so build-id/.build-id/$build_id_prefix/$build_id_suffix.debug
+ $ objcopy -g dwarf-full/libhello-so build-id/libhello-so
## ELF and DWARF with Debug Link
$ mkdir debug_link
- $ objcopy --remove-section=.note.gnu.build-id dwarf_full/libhello_so debug_link/libhello_so
- $ objcopy --only-keep-debug debug_link/libhello_so debug_link/libhello_so.debug
- $ objcopy -g debug_link/libhello_so
- $ cd debug_link && objcopy --add-gnu-debuglink=libhello_so.debug libhello_so && cd ..
+ $ objcopy --remove-section=.note.gnu.build-id dwarf-full/libhello-so debug_link/libhello-so
+ $ objcopy --only-keep-debug debug_link/libhello-so debug_link/libhello-so.debug
+ $ objcopy -g debug_link/libhello-so
+ $ cd debug_link && objcopy --add-gnu-debuglink=libhello-so.debug libhello-so && cd ..
Test program
steps:
1. Compile the example binary:
- $ ln -s x86_64-linux-gnu/dwarf_full/libhello_so libhello.so
+ $ ln -s x86-64-linux-gnu/dwarf-full/libhello-so libhello.so
$ gcc -I. -o debug_info_app main.c -L. -lhello -llttng-ust -ldl -Wl,--rpath=.
2. In order to have paths to binary and shared objects that are not relative
to the file system they were built on, we used a simple trick of copying
the following files to the root directory ('/') like this:
- $ sudo cp x86_64-linux-gnu/dwarf_full/libhello_so /libhello_so
+ $ sudo cp x86-64-linux-gnu/dwarf-full/libhello-so /libhello-so
$ sudo cp ./debug_info_app /
-3. Create symbolic link to the `/libhello_so` file with the `/libhello.so` name.
- $ sudo ln -s /libhello_so /libhello.so
+3. Create symbolic link to the `/libhello-so` file with the `/libhello.so` name.
+ $ sudo ln -s /libhello-so /libhello.so
4. Create the LTTng tracing session using the following commands:
$ cd /
$ sudo lttng create
$ sudo lttng add-context -u -t vpid -t ip
$ sudo lttng enable-event -u my_provider:my_first_tracepoint
- $ sudo lttng enable-event -u lttng_ust_statedump:bin_info --filter='path=="/libhello_so"'
+ $ sudo lttng enable-event -u lttng_ust_statedump:bin_info --filter='path=="/libhello-so"'
$ sudo lttng enable-event -u lttng_ust_statedump:bin_info --filter='path=="[linux-vdso.so.1]"'
$ sudo lttng start
$ sudo /debug_info_app
When running babeltrace with the `--debug-info-target-prefix` option or
`target-prefix` component paramater set to the directory containing the right
-`libhello_so` file. In the example used above, the `libhello_so` file is in the
-`x86_64-linux-gnu/dwarf_full/` directory.
+`libhello-so` file. In the example used above, the `libhello-so` file is in the
+`x86-64-linux-gnu/dwarf-full/` directory.
In the printed trace, the `my_provider:my_first_tracepoint` events should
contain information similar to this:
- debug_info = { bin = "libhello_so+0x2349", func = "foo+0xd2", src = "libhello.c:35" }
+ debug_info = { bin = "libhello-so+0x2349", func = "foo+0xd2", src = "libhello.c:35" }
import bt2
-bt2.register_plugin(__name__, "test_debug_info")
+bt2.register_plugin(__name__, "test-debug-info")
class CompleteIter(bt2._UserMessageIterator):
Payload:
baddr: 0x7f09:b7f9:8000
memsz: 2,114,208
- path: /libhello_so
+ path: /libhello-so
is_pic: 1
has_build_id: 1
has_debug_link: 0
vpid: 9746
ip: 0x7f09:b7f9:a349
debug_info:
- bin: libhello_so+0x2349
+ bin: libhello-so+0x2349
func: foo+0xd2
src: libhello.c:35
Payload:
vpid: 9746
ip: 0x7f09:b7f9:a448
debug_info:
- bin: libhello_so+0x2448
+ bin: libhello-so+0x2448
func: bar+0xd2
src: libhello.c:41
Payload:
TEST_CASES = {
- "diff_trace_name": DiffTraceName,
- "diff_event_class_name": DiffEventClassName,
- "diff_event_class_id": DiffEventClassId,
- "diff_stream_name": DiffStreamName,
- "diff_stream_no_name": DiffStreamNoName,
- "diff_stream_id": DiffStreamId,
- "diff_stream_class_id": DiffStreamClassId,
- "diff_stream_class_name": DiffStreamClassName,
- "diff_stream_class_no_name": DiffStreamClassNoName,
- "diff_inactivity_msg_cs": DiffInactivityMsgCs,
- "basic_timestamp_ordering": BasicTimestampOrdering,
- "multi_iter_ordering": MultiIterOrdering,
+ "diff-trace-name": DiffTraceName,
+ "diff-event-class-name": DiffEventClassName,
+ "diff-event-class-id": DiffEventClassId,
+ "diff-stream-name": DiffStreamName,
+ "diff-stream-no-name": DiffStreamNoName,
+ "diff-stream-id": DiffStreamId,
+ "diff-stream-class-id": DiffStreamClassId,
+ "diff-stream-class-name": DiffStreamClassName,
+ "diff-stream-class-no-name": DiffStreamClassNoName,
+ "diff-inactivity-msg-cs": DiffInactivityMsgCs,
+ "basic-timestamp-ordering": BasicTimestampOrdering,
+ "multi-iter-ordering": MultiIterOrdering,
}
bt2.register_plugin(__name__, "test-muxer")
--- /dev/null
+[0 cycles, 0 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[4 cycles, 4,000,000,000 ns from origin]
+{Trace 1, Stream class ID 2, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 2)
+
+[120 cycles, 120,000,000,000 ns from origin]
+{Trace 2, Stream class ID 1, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 1)
+
+[193 cycles, 193,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+[386 cycles, 386,000,000,000 ns from origin]
+{Trace 2, Stream class ID 1, Stream ID 0}
+Stream end
+
+[579 cycles, 579,000,000,000 ns from origin]
+{Trace 1, Stream class ID 2, Stream ID 0}
+Stream end
+++ /dev/null
-[0 cycles, 0 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Trace:
- Stream (ID 0, Class ID 0)
-
-[4 cycles, 4,000,000,000 ns from origin]
-{Trace 1, Stream class ID 2, Stream ID 0}
-Stream beginning:
- Trace:
- Stream (ID 0, Class ID 2)
-
-[120 cycles, 120,000,000,000 ns from origin]
-{Trace 2, Stream class ID 1, Stream ID 0}
-Stream beginning:
- Trace:
- Stream (ID 0, Class ID 1)
-
-[193 cycles, 193,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-[386 cycles, 386,000,000,000 ns from origin]
-{Trace 2, Stream class ID 1, Stream ID 0}
-Stream end
-
-[579 cycles, 579,000,000,000 ns from origin]
-{Trace 1, Stream class ID 2, Stream ID 0}
-Stream end
--- /dev/null
+[1 cycles, 1,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[2 cycles, 2,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[50 cycles, 50,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event (Class ID 1):
+
+[50 cycles, 50,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Event (Class ID 2):
+
+[193 cycles, 193,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+[386 cycles, 386,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+[4 cycles, 4,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[8 cycles, 8,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[50 cycles, 50,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Event `Gatineau` (Class ID 0):
+
+[50 cycles, 50,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `Hull` (Class ID 0):
+
+[193 cycles, 193,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+[386 cycles, 386,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+[0 cycles, 0 ns from origin]
+Message iterator inactivity:
+ Clock class:
+ Name: Chicoutimi
+ Frequency (Hz): 1
+ Precision (cycles): 0
+ Offset (s): 0
+ Offset (cycles): 0
+ Origin is Unix epoch: Yes
+
+[0 cycles, 0 ns from origin]
+Message iterator inactivity:
+ Clock class:
+ Name: La Baie
+ Frequency (Hz): 1
+ Precision (cycles): 0
+ Offset (s): 0
+ Offset (cycles): 0
+ Origin is Unix epoch: Yes
--- /dev/null
+[0 cycles, 0 ns from origin]
+{Trace 0, Stream class ID 18, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 18)
+
+[0 cycles, 0 ns from origin]
+{Trace 1, Stream class ID 23, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 23)
+
+[193 cycles, 193,000,000,000 ns from origin]
+{Trace 0, Stream class ID 18, Stream ID 0}
+Stream end
+
+[386 cycles, 386,000,000,000 ns from origin]
+{Trace 1, Stream class ID 23, Stream ID 0}
+Stream end
--- /dev/null
+[0 cycles, 0 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Class name: one
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[0 cycles, 0 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Class name: two
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[193 cycles, 193,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+
+[386 cycles, 386,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+[0 cycles, 0 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[0 cycles, 0 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Class name: one
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[193 cycles, 193,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+
+[386 cycles, 386,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+[0 cycles, 0 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 18}
+Stream beginning:
+ Trace:
+ Stream (ID 18, Class ID 0)
+
+[0 cycles, 0 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 23}
+Stream beginning:
+ Trace:
+ Stream (ID 23, Class ID 0)
+
+[193 cycles, 193,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 18}
+Stream end
+
+[386 cycles, 386,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 23}
+Stream end
--- /dev/null
+[0 cycles, 0 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: gascon
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[0 cycles, 0 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: port-daniel
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[193 cycles, 193,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+
+[386 cycles, 386,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+[0 cycles, 0 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[0 cycles, 0 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: one
+ Trace:
+ Stream (ID 0, Class ID 0)
+
+[193 cycles, 193,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+
+[386 cycles, 386,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+[0 cycles, 0 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace `noranda`:
+ Stream (ID 0, Class ID 0)
+
+[0 cycles, 0 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace `rouyn`:
+ Stream (ID 0, Class ID 0)
+
+[193 cycles, 193,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 0}
+Stream end
+
+[386 cycles, 386,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
+++ /dev/null
-[1 cycles, 1,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Trace:
- Stream (ID 0, Class ID 0)
-
-[2 cycles, 2,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Trace:
- Stream (ID 0, Class ID 0)
-
-[50 cycles, 50,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Event (Class ID 1):
-
-[50 cycles, 50,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Event (Class ID 2):
-
-[193 cycles, 193,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-[386 cycles, 386,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
+++ /dev/null
-[4 cycles, 4,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Trace:
- Stream (ID 0, Class ID 0)
-
-[8 cycles, 8,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Trace:
- Stream (ID 0, Class ID 0)
-
-[50 cycles, 50,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Event `Gatineau` (Class ID 0):
-
-[50 cycles, 50,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Event `Hull` (Class ID 0):
-
-[193 cycles, 193,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-[386 cycles, 386,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
+++ /dev/null
-[0 cycles, 0 ns from origin]
-Message iterator inactivity:
- Clock class:
- Name: Chicoutimi
- Frequency (Hz): 1
- Precision (cycles): 0
- Offset (s): 0
- Offset (cycles): 0
- Origin is Unix epoch: Yes
-
-[0 cycles, 0 ns from origin]
-Message iterator inactivity:
- Clock class:
- Name: La Baie
- Frequency (Hz): 1
- Precision (cycles): 0
- Offset (s): 0
- Offset (cycles): 0
- Origin is Unix epoch: Yes
+++ /dev/null
-[0 cycles, 0 ns from origin]
-{Trace 0, Stream class ID 18, Stream ID 0}
-Stream beginning:
- Trace:
- Stream (ID 0, Class ID 18)
-
-[0 cycles, 0 ns from origin]
-{Trace 1, Stream class ID 23, Stream ID 0}
-Stream beginning:
- Trace:
- Stream (ID 0, Class ID 23)
-
-[193 cycles, 193,000,000,000 ns from origin]
-{Trace 0, Stream class ID 18, Stream ID 0}
-Stream end
-
-[386 cycles, 386,000,000,000 ns from origin]
-{Trace 1, Stream class ID 23, Stream ID 0}
-Stream end
+++ /dev/null
-[0 cycles, 0 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Class name: one
- Trace:
- Stream (ID 0, Class ID 0)
-
-[0 cycles, 0 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Class name: two
- Trace:
- Stream (ID 0, Class ID 0)
-
-[193 cycles, 193,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
-
-[386 cycles, 386,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
+++ /dev/null
-[0 cycles, 0 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Trace:
- Stream (ID 0, Class ID 0)
-
-[0 cycles, 0 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Class name: one
- Trace:
- Stream (ID 0, Class ID 0)
-
-[193 cycles, 193,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-
-[386 cycles, 386,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
+++ /dev/null
-[0 cycles, 0 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 18}
-Stream beginning:
- Trace:
- Stream (ID 18, Class ID 0)
-
-[0 cycles, 0 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 23}
-Stream beginning:
- Trace:
- Stream (ID 23, Class ID 0)
-
-[193 cycles, 193,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 18}
-Stream end
-
-[386 cycles, 386,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 23}
-Stream end
+++ /dev/null
-[0 cycles, 0 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: gascon
- Trace:
- Stream (ID 0, Class ID 0)
-
-[0 cycles, 0 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: port-daniel
- Trace:
- Stream (ID 0, Class ID 0)
-
-[193 cycles, 193,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-
-[386 cycles, 386,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
+++ /dev/null
-[0 cycles, 0 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Trace:
- Stream (ID 0, Class ID 0)
-
-[0 cycles, 0 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: one
- Trace:
- Stream (ID 0, Class ID 0)
-
-[193 cycles, 193,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-
-[386 cycles, 386,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
+++ /dev/null
-[0 cycles, 0 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Trace `noranda`:
- Stream (ID 0, Class ID 0)
-
-[0 cycles, 0 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Trace `rouyn`:
- Stream (ID 0, Class ID 0)
-
-[193 cycles, 193,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 0}
-Stream end
-
-[386 cycles, 386,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
--- /dev/null
+[0 cycles, 0 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 1}
+Stream beginning:
+ Trace `hello`:
+ Stream (ID 1, Class ID 0)
+
+[1 cycles, 1,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 1}
+Stream beginning:
+ Trace `meow`:
+ Stream (ID 1, Class ID 0)
+
+[3 cycles, 3,000,000,000 ns from origin]
+{Trace 2, Stream class ID 1, Stream ID 1}
+Stream beginning:
+ Trace `meow`:
+ Stream (ID 1, Class ID 1)
+
+[25 cycles, 25,000,000,000 ns from origin]
+{Trace 3, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Trace `hello`:
+ Stream (ID 0, Class ID 0)
+
+[25 cycles, 25,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 1}
+Event `saumon atlantique` (Class ID 0):
+
+[25 cycles, 25,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 1}
+Packet beginning
+
+[25 cycles, 25,000,000,000 ns from origin]
+{Trace 2, Stream class ID 1, Stream ID 1}
+Event `bar rayé` (Class ID 0):
+
+[158 cycles, 158,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 1}
+Packet end
+
+[193 cycles, 193,000,000,000 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 1}
+Stream end
+
+[386 cycles, 386,000,000,000 ns from origin]
+{Trace 1, Stream class ID 0, Stream ID 1}
+Stream end
+
+[579 cycles, 579,000,000,000 ns from origin]
+{Trace 3, Stream class ID 0, Stream ID 0}
+Stream end
+
+[772 cycles, 772,000,000,000 ns from origin]
+{Trace 2, Stream class ID 1, Stream ID 1}
+Stream end
+++ /dev/null
-[0 cycles, 0 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 1}
-Stream beginning:
- Trace `hello`:
- Stream (ID 1, Class ID 0)
-
-[1 cycles, 1,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 1}
-Stream beginning:
- Trace `meow`:
- Stream (ID 1, Class ID 0)
-
-[3 cycles, 3,000,000,000 ns from origin]
-{Trace 2, Stream class ID 1, Stream ID 1}
-Stream beginning:
- Trace `meow`:
- Stream (ID 1, Class ID 1)
-
-[25 cycles, 25,000,000,000 ns from origin]
-{Trace 3, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Trace `hello`:
- Stream (ID 0, Class ID 0)
-
-[25 cycles, 25,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 1}
-Event `saumon atlantique` (Class ID 0):
-
-[25 cycles, 25,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 1}
-Packet beginning
-
-[25 cycles, 25,000,000,000 ns from origin]
-{Trace 2, Stream class ID 1, Stream ID 1}
-Event `bar rayé` (Class ID 0):
-
-[158 cycles, 158,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 1}
-Packet end
-
-[193 cycles, 193,000,000,000 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 1}
-Stream end
-
-[386 cycles, 386,000,000,000 ns from origin]
-{Trace 1, Stream class ID 0, Stream ID 1}
-Stream end
-
-[579 cycles, 579,000,000,000 ns from origin]
-{Trace 3, Stream class ID 0, Stream ID 0}
-Stream end
-
-[772 cycles, 772,000,000,000 ns from origin]
-{Trace 2, Stream class ID 1, Stream ID 1}
-Stream end
--- /dev/null
+Trace class:
+ Stream class (ID 0):
+ Supports packets: Yes
+ Packets have beginning default clock snapshot: Yes
+ Packets have end default clock snapshot: Yes
+ Supports discarded events: No
+ Supports discarded packets: Yes
+ Discarded packets have default clock snapshots: Yes
+ Default clock class:
+ Name: default
+ Frequency (Hz): 1,000,000,000
+ Precision (cycles): 0
+ Offset (s): 0
+ Offset (cycles): 0
+ Origin is Unix epoch: Yes
+ Event class `my-event` (ID 0):
+
+[Unknown]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: stream-1
+ Trace:
+ UUID: 1c810767-575e-4c4e-afa1-5d3e15081cb9
+ Stream (ID 0, Class ID 0)
+
+[0 cycles, 0 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet beginning
+
+[10 cycles, 10 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `my-event` (Class ID 0):
+
+[20 cycles, 20 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet end
+
+[80 cycles, 80 ns from origin]
+Message iterator inactivity:
+ Clock class:
+ Name: default
+ Frequency (Hz): 1,000,000,000
+ Precision (cycles): 0
+ Offset (s): 0
+ Offset (cycles): 0
+ Origin is Unix epoch: Yes
+
+[80 cycles, 80 ns from origin]
+[121 cycles, 121 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Discarded packets (7 packets)
+
+[121 cycles, 121 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet beginning
+
+[133 cycles, 133 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `my-event` (Class ID 0):
+
+[140 cycles, 140 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet end
+
+[Unknown]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+[
+ {
+ "name": "7-lost-between-2-with-index",
+ "id": 0,
+ "hostname": "hostname",
+ "live-timer-freq": 1,
+ "client-count": 0,
+ "traces": [
+ {
+ "path": "packet-seq-num/7-lost-between-2-with-index/",
+ "beacons": {
+ "stream_0": [ 80 ]
+ }
+ }
+ ]
+ }
+]
+++ /dev/null
-Trace class:
- Stream class (ID 0):
- Supports packets: Yes
- Packets have beginning default clock snapshot: Yes
- Packets have end default clock snapshot: Yes
- Supports discarded events: No
- Supports discarded packets: Yes
- Discarded packets have default clock snapshots: Yes
- Default clock class:
- Name: default
- Frequency (Hz): 1,000,000,000
- Precision (cycles): 0
- Offset (s): 0
- Offset (cycles): 0
- Origin is Unix epoch: Yes
- Event class `my-event` (ID 0):
-
-[Unknown]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: stream-1
- Trace:
- UUID: 1c810767-575e-4c4e-afa1-5d3e15081cb9
- Stream (ID 0, Class ID 0)
-
-[0 cycles, 0 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Packet beginning
-
-[10 cycles, 10 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Event `my-event` (Class ID 0):
-
-[20 cycles, 20 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Packet end
-
-[80 cycles, 80 ns from origin]
-Message iterator inactivity:
- Clock class:
- Name: default
- Frequency (Hz): 1,000,000,000
- Precision (cycles): 0
- Offset (s): 0
- Offset (cycles): 0
- Origin is Unix epoch: Yes
-
-[80 cycles, 80 ns from origin]
-[121 cycles, 121 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Discarded packets (7 packets)
-
-[121 cycles, 121 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Packet beginning
-
-[133 cycles, 133 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Event `my-event` (Class ID 0):
-
-[140 cycles, 140 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Packet end
-
-[Unknown]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
+++ /dev/null
-[
- {
- "name": "7_lost_between_2_with_index",
- "id": 0,
- "hostname": "hostname",
- "live-timer-freq": 1,
- "client-count": 0,
- "traces": [
- {
- "path": "packet_seq_num/7_lost_between_2_with_index/",
- "beacons": {
- "stream_0": [ 80 ]
- }
- }
- ]
- }
-]
--- /dev/null
+[
+ {
+ "name": "multi-domains",
+ "id": 0,
+ "hostname": "hostname",
+ "live-timer-freq": 1,
+ "client-count": 0,
+ "traces": [
+ {
+ "path": "succeed/multi-domains/ust/"
+ }
+ ]
+ },
+ {
+ "name": "multi-domains",
+ "id": 1,
+ "hostname": "hostname",
+ "live-timer-freq": 1,
+ "client-count": 0,
+ "traces": [
+ {
+ "path": "succeed/multi-domains/kernel/"
+ }
+ ]
+ },
+ {
+ "name": "trace-with-index",
+ "id": 2,
+ "hostname": "hostname",
+ "live-timer-freq": 1,
+ "client-count": 0,
+ "traces": [
+ {
+ "path": "succeed/trace-with-index/"
+ }
+ ]
+ }
+]
+++ /dev/null
-[
- {
- "name": "multi-domains",
- "id": 0,
- "hostname": "hostname",
- "live-timer-freq": 1,
- "client-count": 0,
- "traces": [
- {
- "path": "succeed/multi-domains/ust/"
- }
- ]
- },
- {
- "name": "multi-domains",
- "id": 1,
- "hostname": "hostname",
- "live-timer-freq": 1,
- "client-count": 0,
- "traces": [
- {
- "path": "succeed/multi-domains/kernel/"
- }
- ]
- },
- {
- "name": "trace-with-index",
- "id": 2,
- "hostname": "hostname",
- "live-timer-freq": 1,
- "client-count": 0,
- "traces": [
- {
- "path": "succeed/trace-with-index/"
- }
- ]
- }
-]
--- /dev/null
+[
+ {
+ "name": "multi-domains",
+ "id": 0,
+ "hostname": "hostname",
+ "live-timer-freq": 1,
+ "client-count": 0,
+ "traces": [
+ {
+ "path": "succeed/multi-domains/ust/"
+ }
+ ]
+ },
+ {
+ "name": "multi-domains",
+ "id": 1,
+ "hostname": "hostname",
+ "live-timer-freq": 1,
+ "client-count": 0,
+ "traces": [
+ {
+ "path": "succeed/multi-domains/kernel/"
+ }
+ ]
+ }
+]
--- /dev/null
+[
+ {
+ "name": "multi-domains",
+ "id": 0,
+ "hostname": "hostname",
+ "live-timer-freq": 1,
+ "client-count": 0,
+ "traces": [
+ {
+ "path": "succeed/multi-domains/kernel/"
+ }
+ ]
+ },
+ {
+ "name": "multi-domains",
+ "id": 1,
+ "hostname": "hostname",
+ "live-timer-freq": 1,
+ "client-count": 0,
+ "traces": [
+ {
+ "path": "succeed/multi-domains/ust/"
+ }
+ ]
+ }
+]
+++ /dev/null
-[
- {
- "name": "multi-domains",
- "id": 0,
- "hostname": "hostname",
- "live-timer-freq": 1,
- "client-count": 0,
- "traces": [
- {
- "path": "succeed/multi-domains/kernel/"
- }
- ]
- },
- {
- "name": "multi-domains",
- "id": 1,
- "hostname": "hostname",
- "live-timer-freq": 1,
- "client-count": 0,
- "traces": [
- {
- "path": "succeed/multi-domains/ust/"
- }
- ]
- }
-]
+++ /dev/null
-[
- {
- "name": "multi-domains",
- "id": 0,
- "hostname": "hostname",
- "live-timer-freq": 1,
- "client-count": 0,
- "traces": [
- {
- "path": "succeed/multi-domains/ust/"
- }
- ]
- },
- {
- "name": "multi-domains",
- "id": 1,
- "hostname": "hostname",
- "live-timer-freq": 1,
- "client-count": 0,
- "traces": [
- {
- "path": "succeed/multi-domains/kernel/"
- }
- ]
- }
-]
--- /dev/null
+[
+ {
+ "name": "trace-with-index",
+ "id": 0,
+ "hostname": "hostname",
+ "live-timer-freq": 1,
+ "client-count": 0,
+ "traces": [
+ {
+ "path": "succeed/trace-with-index/"
+ }
+ ]
+ }
+]
+++ /dev/null
-[
- {
- "name": "trace-with-index",
- "id": 0,
- "hostname": "hostname",
- "live-timer-freq": 1,
- "client-count": 0,
- "traces": [
- {
- "path": "succeed/trace-with-index/"
- }
- ]
- }
-]
--- /dev/null
+Trace class:
+ Stream class (ID 0):
+ Supports packets: Yes
+ Packets have beginning default clock snapshot: Yes
+ Packets have end default clock snapshot: Yes
+ Supports discarded events: Yes
+ Discarded events have default clock snapshots: Yes
+ Supports discarded packets: Yes
+ Discarded packets have default clock snapshots: Yes
+ Default clock class:
+ Name: monotonic
+ Description: Monotonic Clock
+ Frequency (Hz): 1,000,000,000
+ Precision (cycles): 0
+ Offset (s): 1,594,406,328
+ Offset (cycles): 768,346,378
+ Origin is Unix epoch: Yes
+ UUID: 81a04b89-9028-4d3e-a28d-5fbd53a8eb9d
+ Packet context field class: Structure (1 member):
+ cpu_id: Unsigned integer (32-bit, Base 10)
+ Event class `my_app:signe_de_pia$$e` (ID 0):
+ Log level: Debug (line)
+ Payload field class: Structure (0 members)
+ Event class `my_app:signe_de_pia$$e_2` (ID 1):
+ Log level: Debug (line)
+ Payload field class: Structure (0 members)
+
+[Unknown]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream beginning:
+ Name: stream-1
+ Trace:
+ UUID: 0339cd08-892d-404c-9291-64c1a8a74c81
+ Environment (10 entries):
+ architecture_bit_width: 64
+ domain: ust
+ hostname: raton
+ trace_creation_datetime: 20200715T174253-0400
+ trace_name: barney_descontie
+ tracer_buffering_id: 1000
+ tracer_buffering_scheme: uid
+ tracer_major: 2
+ tracer_minor: 12
+ tracer_name: lttng-ust
+ Stream (ID 0, Class ID 0)
+
+[443,073,474,574,097 cycles, 1,594,849,402,242,920,475 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet beginning:
+ Context:
+ cpu_id: 0
+
+[443,073,484,867,537 cycles, 1,594,849,402,253,213,915 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `my_app:signe_de_pia$$e` (Class ID 0):
+ Payload: Empty
+
+[443,076,225,270,435 cycles, 1,594,849,404,993,616,813 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet end
+
+[443,087,407,631,276 cycles, 1,594,849,416,175,977,654 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet beginning:
+ Context:
+ cpu_id: 0
+
+[443,087,407,631,276 cycles, 1,594,849,416,175,977,654 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `my_app:signe_de_pia$$e` (Class ID 0):
+ Payload: Empty
+
+[443,087,407,643,172 cycles, 1,594,849,416,175,989,550 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Event `my_app:signe_de_pia$$e_2` (Class ID 1):
+ Payload: Empty
+
+[443,089,152,508,997 cycles, 1,594,849,417,920,855,375 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Packet end
+
+[Unknown]
+{Trace 0, Stream class ID 0, Stream ID 0}
+Stream end
--- /dev/null
+[
+ {
+ "name": "split-metadata",
+ "id": 0,
+ "hostname": "hostname",
+ "live-timer-freq": 1,
+ "client-count": 0,
+ "traces": [
+ {
+ "path": "live/split-metadata/",
+ "beacons": {
+ },
+ "metadata-sections": [
+ {
+ "line": 1,
+ "timestamp": 443073474574097
+ },
+ "empty",
+ {
+ "line": 112,
+ "timestamp": 443087407631276
+ }
+ ]
+ }
+ ]
+ }
+]
+++ /dev/null
-Trace class:
- Stream class (ID 0):
- Supports packets: Yes
- Packets have beginning default clock snapshot: Yes
- Packets have end default clock snapshot: Yes
- Supports discarded events: Yes
- Discarded events have default clock snapshots: Yes
- Supports discarded packets: Yes
- Discarded packets have default clock snapshots: Yes
- Default clock class:
- Name: monotonic
- Description: Monotonic Clock
- Frequency (Hz): 1,000,000,000
- Precision (cycles): 0
- Offset (s): 1,594,406,328
- Offset (cycles): 768,346,378
- Origin is Unix epoch: Yes
- UUID: 81a04b89-9028-4d3e-a28d-5fbd53a8eb9d
- Packet context field class: Structure (1 member):
- cpu_id: Unsigned integer (32-bit, Base 10)
- Event class `my_app:signe_de_pia$$e` (ID 0):
- Log level: Debug (line)
- Payload field class: Structure (0 members)
- Event class `my_app:signe_de_pia$$e_2` (ID 1):
- Log level: Debug (line)
- Payload field class: Structure (0 members)
-
-[Unknown]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream beginning:
- Name: stream-1
- Trace:
- UUID: 0339cd08-892d-404c-9291-64c1a8a74c81
- Environment (10 entries):
- architecture_bit_width: 64
- domain: ust
- hostname: raton
- trace_creation_datetime: 20200715T174253-0400
- trace_name: barney_descontie
- tracer_buffering_id: 1000
- tracer_buffering_scheme: uid
- tracer_major: 2
- tracer_minor: 12
- tracer_name: lttng-ust
- Stream (ID 0, Class ID 0)
-
-[443,073,474,574,097 cycles, 1,594,849,402,242,920,475 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Packet beginning:
- Context:
- cpu_id: 0
-
-[443,073,484,867,537 cycles, 1,594,849,402,253,213,915 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Event `my_app:signe_de_pia$$e` (Class ID 0):
- Payload: Empty
-
-[443,076,225,270,435 cycles, 1,594,849,404,993,616,813 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Packet end
-
-[443,087,407,631,276 cycles, 1,594,849,416,175,977,654 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Packet beginning:
- Context:
- cpu_id: 0
-
-[443,087,407,631,276 cycles, 1,594,849,416,175,977,654 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Event `my_app:signe_de_pia$$e` (Class ID 0):
- Payload: Empty
-
-[443,087,407,643,172 cycles, 1,594,849,416,175,989,550 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Event `my_app:signe_de_pia$$e_2` (Class ID 1):
- Payload: Empty
-
-[443,089,152,508,997 cycles, 1,594,849,417,920,855,375 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Packet end
-
-[Unknown]
-{Trace 0, Stream class ID 0, Stream ID 0}
-Stream end
+++ /dev/null
-[
- {
- "name": "split_metadata",
- "id": 0,
- "hostname": "hostname",
- "live-timer-freq": 1,
- "client-count": 0,
- "traces": [
- {
- "path": "live/split_metadata/",
- "beacons": {
- },
- "metadata-sections": [
- {
- "line": 1,
- "timestamp": 443073474574097
- },
- "empty",
- {
- "line": 112,
- "timestamp": 443087407631276
- }
- ]
- }
- ]
- }
-]
--- /dev/null
+Trace class:
+ Stream class (ID 0):
+ Supports packets: Yes
+ Packets have beginning default clock snapshot: Yes
+ Packets have end default clock snapshot: Yes
+ Supports discarded events: No
+ Supports discarded packets: No
+ Default clock class:
+ Name: default
+ Frequency (Hz): 1,000,000,000
+ Precision (cycles): 0
+ Offset (s): 0
+ Offset (cycles): 0
+ Origin is Unix epoch: No
+ Event class `event1` (ID 1):
+ Payload field class: Structure (2 members):
+ len: Unsigned integer (8-bit, Base 10)
+ seq: Dynamic array (with length field) (Length field path [Event payload: 0]):
+ Element: Unsigned integer (8-bit, Base 10)
+ Event class `event2` (ID 2):
+ Payload field class: Structure (2 members):
+ len: Unsigned integer (8-bit, Base 10)
+ seq: Dynamic array (with length field) (Length field path [Event payload: 0]):
+ Element: Unsigned integer (8-bit, Base 10)
+
+[Unknown]
+{Trace 0, Stream class ID 0, Stream ID 1}
+Stream beginning:
+ Name: stream-1
+ Trace:
+ Stream (ID 1, Class ID 0)
+
+[10 cycles, 10 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 1}
+Packet beginning
+
+[10 cycles, 10 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 1}
+Event `event1` (Class ID 1):
+ Payload:
+ len: 0
+ seq: Empty
+
+[11 cycles, 11 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 1}
+Packet end
+
+[20 cycles, 20 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 1}
+Packet beginning
+
+[20 cycles, 20 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 1}
+Event `event2` (Class ID 2):
+ Payload:
+ len: 0
+ seq: Empty
+
+[21 cycles, 21 ns from origin]
+{Trace 0, Stream class ID 0, Stream ID 1}
+Packet end
+
+[Unknown]
+{Trace 0, Stream class ID 0, Stream ID 1}
+Stream end
--- /dev/null
+[
+ {
+ "name": "stored-values",
+ "id": 2,
+ "hostname": "hostname",
+ "live-timer-freq": 1,
+ "client-count": 0,
+ "traces": [
+ {
+ "path": "stored-values",
+ "metadata-sections": [
+ {
+ "line": 1,
+ "timestamp": 1
+ },
+ "empty",
+ {
+ "line": 37,
+ "timestamp": 20
+ }
+ ]
+ }
+ ]
+ }
+]
+++ /dev/null
-Trace class:
- Stream class (ID 0):
- Supports packets: Yes
- Packets have beginning default clock snapshot: Yes
- Packets have end default clock snapshot: Yes
- Supports discarded events: No
- Supports discarded packets: No
- Default clock class:
- Name: default
- Frequency (Hz): 1,000,000,000
- Precision (cycles): 0
- Offset (s): 0
- Offset (cycles): 0
- Origin is Unix epoch: No
- Event class `event1` (ID 1):
- Payload field class: Structure (2 members):
- len: Unsigned integer (8-bit, Base 10)
- seq: Dynamic array (with length field) (Length field path [Event payload: 0]):
- Element: Unsigned integer (8-bit, Base 10)
- Event class `event2` (ID 2):
- Payload field class: Structure (2 members):
- len: Unsigned integer (8-bit, Base 10)
- seq: Dynamic array (with length field) (Length field path [Event payload: 0]):
- Element: Unsigned integer (8-bit, Base 10)
-
-[Unknown]
-{Trace 0, Stream class ID 0, Stream ID 1}
-Stream beginning:
- Name: stream-1
- Trace:
- Stream (ID 1, Class ID 0)
-
-[10 cycles, 10 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 1}
-Packet beginning
-
-[10 cycles, 10 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 1}
-Event `event1` (Class ID 1):
- Payload:
- len: 0
- seq: Empty
-
-[11 cycles, 11 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 1}
-Packet end
-
-[20 cycles, 20 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 1}
-Packet beginning
-
-[20 cycles, 20 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 1}
-Event `event2` (Class ID 2):
- Payload:
- len: 0
- seq: Empty
-
-[21 cycles, 21 ns from origin]
-{Trace 0, Stream class ID 0, Stream ID 1}
-Packet end
-
-[Unknown]
-{Trace 0, Stream class ID 0, Stream ID 1}
-Stream end
+++ /dev/null
-[
- {
- "name": "stored_values",
- "id": 2,
- "hostname": "hostname",
- "live-timer-freq": 1,
- "client-count": 0,
- "traces": [
- {
- "path": "stored_values",
- "metadata-sections": [
- {
- "line": 1,
- "timestamp": 1
- },
- "empty",
- {
- "line": 37,
- "timestamp": 20
- }
- ]
- }
- ]
- }
-]
$(top_builddir)/src/lib/libbabeltrace2.la
noinst_PROGRAMS = \
- test_bt_uuid \
- test_bt_values \
- test_graph_topo \
- test_fields_bin \
- test_remove_destruction_listener_in_destruction_listener \
- test_simple_sink \
- test_trace_ir_ref
+ test-bt-uuid \
+ test-bt-values \
+ test-graph-topo \
+ test-fields-bin \
+ test-remove-destruction-listener-in-destruction-listener \
+ test-simple-sink \
+ test-trace-ir-ref
-test_bt_values_SOURCES = test_bt_values.c
-test_fields_bin_SOURCES = test_fields_bin.cpp
-test_simple_sink_SOURCES = test_simple_sink.c
-test_bt_uuid_SOURCES = test_bt_uuid.c
-test_trace_ir_ref_SOURCES = test_trace_ir_ref.c
-test_graph_topo_SOURCES = test_graph_topo.c
+test_bt_values_SOURCES = test-bt-values.c
+test_fields_bin_SOURCES = test-fields-bin.cpp
+test_simple_sink_SOURCES = test-simple-sink.c
+test_bt_uuid_SOURCES = test-bt-uuid.c
+test_trace_ir_ref_SOURCES = test-trace-ir-ref.c
+test_graph_topo_SOURCES = test-graph-topo.c
test_remove_destruction_listener_in_destruction_listener_SOURCES = \
- test_remove_destruction_listener_in_destruction_listener.c
+ test-remove-destruction-listener-in-destruction-listener.c
if !ENABLE_BUILT_IN_PLUGINS
noinst_PROGRAMS += plugin
SUBDIRS += test-plugin-plugins
endif
-dist_check_SCRIPTS = test_plugin test_fields
+dist_check_SCRIPTS = test-plugin.sh test-fields.sh
if HAVE_PYTHON
if DEV_MODE
noinst_PROGRAMS = conds-triggers
-dist_check_SCRIPTS = test_conds test.py
+dist_check_SCRIPTS = test-conds.sh test.py
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+reldir=lib/conds
+export BT_TESTS_LIB_CONDS_TRIGGER_BIN="$BT_TESTS_BUILDDIR/$reldir/conds-triggers"
+
+if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
+ BT_TESTS_LIB_CONDS_TRIGGER_BIN="$BT_TESTS_LIB_CONDS_TRIGGER_BIN.exe"
+fi
+
+run_python_bt2_test "$BT_TESTS_SRCDIR/$reldir" test.py
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2020 Philippe Proulx <pproulx@efficios.com>
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-reldir=lib/conds
-export BT_TESTS_LIB_CONDS_TRIGGER_BIN="$BT_TESTS_BUILDDIR/$reldir/conds-triggers"
-
-if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
- BT_TESTS_LIB_CONDS_TRIGGER_BIN="$BT_TESTS_LIB_CONDS_TRIGGER_BIN.exe"
-fi
-
-run_python_bt2_test "$BT_TESTS_SRCDIR/$reldir" test.py
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <tap/tap.h>
+
+#include "common/uuid.h"
+
+#define NR_TESTS 23
+
+static const char valid_str_1[] = "3d260c88-75ea-47b8-a7e2-d6077c0378d9";
+static const char valid_str_2[] = "611cf3a6-a68b-4515-834f-208bc2762592";
+static const char valid_str_3[] = "1b4855cc-96de-4ae8-abe3-86449c2a43c4";
+static const char valid_str_4[] = "8ADED5B9-ACD2-439F-A60C-897403AA2AB4";
+static const char valid_str_5[] = "f109e0a2-C619-4d18-b760-20EA20E0F69A";
+
+static bt_uuid_t valid_uuid_1 = {
+ 0x3d, 0x26, 0x0c, 0x88, 0x75, 0xea, 0x47, 0xb8,
+ 0xa7, 0xe2, 0xd6, 0x07, 0x7c, 0x03, 0x78, 0xd9
+};
+static bt_uuid_t valid_uuid_2 = {
+ 0x61, 0x1c, 0xf3, 0xa6, 0xa6, 0x8b, 0x45, 0x15,
+ 0x83, 0x4f, 0x20, 0x8b, 0xc2, 0x76, 0x25, 0x92
+};
+static bt_uuid_t valid_uuid_3 = {
+ 0x1b, 0x48, 0x55, 0xcc, 0x96, 0xde, 0x4a, 0xe8,
+ 0xab, 0xe3, 0x86, 0x44, 0x9c, 0x2a, 0x43, 0xc4
+};
+
+static const char invalid_str_1[] = "1b485!cc-96de-4XX8-abe3-86449c2a43?4";
+static const char invalid_str_2[] = "c2e6eddb&3955&4006&be3a&70bb63bd5f25";
+static const char invalid_str_3[] = "81b1cb88-ff42-45b9-ba4d-964088ee45";
+static const char invalid_str_4[] = "2d-6c6d756574-470e-9142-a4e6ad03f143";
+static const char invalid_str_5[] = "4542ad19-9e4f-4931-8261-2101c3e089ae7";
+static const char invalid_str_6[] = "XX0123";
+
+static
+void run_test_bt_uuid_from_str(void)
+{
+ int ret;
+ bt_uuid_t uuid1;
+
+ /*
+ * Parse valid UUID strings, expect success.
+ */
+ ret = bt_uuid_from_str(valid_str_1, uuid1);
+ ok(ret == 0, "bt_uuid_from_str - Parse valid string '%s', expect success", valid_str_1);
+
+ ret = bt_uuid_from_str(valid_str_2, uuid1);
+ ok(ret == 0, "bt_uuid_from_str - Parse valid string '%s', expect success", valid_str_2);
+
+ ret = bt_uuid_from_str(valid_str_3, uuid1);
+ ok(ret == 0, "bt_uuid_from_str - Parse valid string '%s', expect success", valid_str_3);
+
+ ret = bt_uuid_from_str(valid_str_4, uuid1);
+ ok(ret == 0, "bt_uuid_from_str - Parse valid string '%s', expect success", valid_str_4);
+
+ ret = bt_uuid_from_str(valid_str_5, uuid1);
+ ok(ret == 0, "bt_uuid_from_str - Parse valid string '%s', expect success", valid_str_5);
+
+ /*
+ * Parse invalid UUID strings, expect failure.
+ */
+ ret = bt_uuid_from_str(invalid_str_1, uuid1);
+ ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_1);
+
+ ret = bt_uuid_from_str(invalid_str_2, uuid1);
+ ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_2);
+
+ ret = bt_uuid_from_str(invalid_str_3, uuid1);
+ ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_3);
+
+ ret = bt_uuid_from_str(invalid_str_4, uuid1);
+ ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_4);
+
+ ret = bt_uuid_from_str(invalid_str_5, uuid1);
+ ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_5);
+
+ ret = bt_uuid_from_str(invalid_str_6, uuid1);
+ ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_6);
+}
+
+static
+void run_test_bt_uuid_to_str(void)
+{
+ char uuid_str[BT_UUID_STR_LEN + 1];
+
+ bt_uuid_to_str(valid_uuid_1, uuid_str);
+ ok(strcmp(uuid_str, valid_str_1) == 0, "bt_uuid_to_str - Convert UUID '%s' to string, expect success", valid_str_1);
+
+ bt_uuid_to_str(valid_uuid_2, uuid_str);
+ ok(strcmp(uuid_str, valid_str_2) == 0, "bt_uuid_to_str - Convert UUID '%s' to string, expect success", valid_str_2);
+
+ bt_uuid_to_str(valid_uuid_3, uuid_str);
+ ok(strcmp(uuid_str, valid_str_3) == 0, "bt_uuid_to_str - Convert UUID '%s' to string, expect success", valid_str_3);
+}
+
+static
+void run_test_bt_uuid_compare(void)
+{
+ int ret;
+ bt_uuid_t uuid1, uuid2;
+
+ bt_uuid_from_str(valid_str_1, uuid1);
+ bt_uuid_from_str(valid_str_1, uuid2);
+ ret = bt_uuid_compare(uuid1, uuid2);
+ ok(ret == 0, "bt_uuid_compare - Compare same UUID, expect success");
+
+ bt_uuid_from_str(valid_str_2, uuid2);
+ ret = bt_uuid_compare(uuid1, uuid2);
+ ok(ret != 0, "bt_uuid_compare - Compare different UUID, expect failure");
+ ok(ret < 0, "bt_uuid_compare - Compare different UUID, expect uuid1 smaller");
+ ret = bt_uuid_compare(uuid2, uuid1);
+ ok(ret > 0, "bt_uuid_compare - Compare different UUID, expect uuid2 bigger");
+}
+
+static
+void run_test_bt_uuid_copy(void)
+{
+ int ret;
+ bt_uuid_t uuid1;
+
+ bt_uuid_copy(uuid1, valid_uuid_1);
+ ret = bt_uuid_compare(uuid1, valid_uuid_1);
+
+ ok(ret == 0, "bt_uuid_copy - Compare copied UUID with source, expect success");
+}
+
+static
+void run_test_bt_uuid_generate(void)
+{
+ int ret;
+ bt_uuid_t uuid1, uuid2;
+
+ bt_uuid_generate(uuid1);
+ bt_uuid_generate(uuid2);
+
+ ok(bt_uuid_compare(uuid1, uuid2) != 0, "bt_uuid_generate - Generated UUIDs are different");
+
+ /*
+ * Set the two most significant bits (bits 6 and 7) of the
+ * clock_seq_hi_and_reserved to zero and one, respectively.
+ */
+ ret = uuid1[8] & (1 << 6);
+ ok(ret == 0, "bt_uuid_generate - bit 6 of clock_seq_hi_and_reserved is set to zero");
+
+ ret = uuid1[8] & (1 << 7);
+ ok(ret != 0, "bt_uuid_generate - bit 7 of clock_seq_hi_and_reserved is set to one");
+
+ /*
+ * Set the four most significant bits (bits 12 through 15) of the
+ * time_hi_and_version field to the 4-bit version number from
+ * Section 4.1.3.
+ */
+ ret = uuid1[6] >> 4;
+ ok(ret == BT_UUID_VER, "bt_uuid_generate - Generated UUID version check");
+}
+
+static
+void run_test(void)
+{
+ plan_tests(NR_TESTS);
+
+ run_test_bt_uuid_from_str();
+ run_test_bt_uuid_to_str();
+ run_test_bt_uuid_compare();
+ run_test_bt_uuid_copy();
+ run_test_bt_uuid_generate();
+}
+
+int main(int argc, char **argv)
+{
+ /* Run tap-formated tests */
+ run_test();
+
+ return exit_status();
+}
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (C) 2015 Philippe Proulx <pproulx@efficios.com>
+ *
+ * Babeltrace value objects tests
+ */
+
+#include <babeltrace2/babeltrace.h>
+#include "common/assert.h"
+#include <string.h>
+#include "tap/tap.h"
+
+#define NR_TESTS 190
+
+static
+void test_null(void)
+{
+ ok(bt_value_null, "bt_value_null is not NULL");
+ ok(bt_value_is_null(bt_value_null),
+ "bt_value_null is a null value object");
+ bt_value_get_ref(bt_value_null);
+ pass("getting bt_value_null does not cause a crash");
+ bt_value_put_ref(bt_value_null);
+ pass("putting bt_value_null does not cause a crash");
+}
+
+static
+void test_bool(void)
+{
+ bt_bool value;
+ bt_value *obj;
+
+ obj = bt_value_bool_create();
+ ok(obj && bt_value_is_bool(obj),
+ "bt_value_bool_create() returns a boolean value object");
+
+ value = BT_TRUE;
+ value = bt_value_bool_get(obj);
+ ok(!value, "default boolean value object value is BT_FALSE");
+
+ bt_value_bool_set(obj, BT_FALSE);
+ bt_value_bool_set(obj, BT_TRUE);
+ value = bt_value_bool_get(obj);
+ ok(value, "bt_value_bool_set() works");
+
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ pass("putting an existing boolean value object does not cause a crash")
+
+ value = BT_FALSE;
+ obj = bt_value_bool_create_init(BT_TRUE);
+ ok(obj && bt_value_is_bool(obj),
+ "bt_value_bool_create_init() returns a boolean value object");
+ value = bt_value_bool_get(obj);
+ ok(value,
+ "bt_value_bool_create_init() sets the appropriate initial value");
+
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+}
+
+static
+void test_unsigned_integer(void)
+{
+ uint64_t value;
+ bt_value *obj;
+
+ obj = bt_value_integer_unsigned_create();
+ ok(obj && bt_value_is_unsigned_integer(obj),
+ "bt_value_integer_unsigned_create() returns an unsigned integer value object");
+
+ value = 1961;
+ value = bt_value_integer_unsigned_get(obj);
+ ok(value == 0, "default unsigned integer value object value is 0");
+
+ bt_value_integer_unsigned_set(obj, 98765);
+ value = bt_value_integer_unsigned_get(obj);
+ ok(value == 98765, "bt_value_integer_unsigned_bool_set() works");
+
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ pass("putting an existing unsigned integer value object does not cause a crash")
+
+ obj = bt_value_integer_unsigned_create_init(321456987);
+ ok(obj && bt_value_is_unsigned_integer(obj),
+ "bt_value_integer_unsigned_create_init() returns an unsigned integer value object");
+ value = bt_value_integer_unsigned_get(obj);
+ ok(value == 321456987,
+ "bt_value_integer_unsigned_create_init() sets the appropriate initial value");
+
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+}
+
+static
+void test_signed_integer(void)
+{
+ int64_t value;
+ bt_value *obj;
+
+ obj = bt_value_integer_signed_create();
+ ok(obj && bt_value_is_signed_integer(obj),
+ "bt_value_integer_signed_create() returns a signed integer value object");
+
+ value = 1961;
+ value = bt_value_integer_signed_get(obj);
+ ok(value == 0, "default signed integer value object value is 0");
+
+ bt_value_integer_signed_set(obj, 98765);
+ value = bt_value_integer_signed_get(obj);
+ ok(value == 98765, "bt_value_integer_signed_bool_set() works");
+
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ pass("putting an existing signed integer value object does not cause a crash")
+
+ obj = bt_value_integer_signed_create_init(-321456987);
+ ok(obj && bt_value_is_signed_integer(obj),
+ "bt_value_integer_signed_create_init() returns a signed integer value object");
+ value = bt_value_integer_signed_get(obj);
+ ok(value == -321456987,
+ "bt_value_integer_signed_create_init() sets the appropriate initial value");
+
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+}
+
+static
+void test_real(void)
+{
+ double value;
+ bt_value *obj;
+
+ obj = bt_value_real_create();
+ ok(obj && bt_value_is_real(obj),
+ "bt_value_real_create() returns a real number value object");
+
+ value = 17.34;
+ value = bt_value_real_get(obj);
+ ok(value == 0.,
+ "default real number value object value is 0");
+
+ bt_value_real_set(obj, -3.1416);
+ value = bt_value_real_get(obj);
+ ok(value == -3.1416, "bt_value_real_set() works");
+
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ pass("putting an existing real number value object does not cause a crash")
+
+ obj = bt_value_real_create_init(33.1649758);
+ ok(obj && bt_value_is_real(obj),
+ "bt_value_real_create_init() returns a real number value object");
+ value = bt_value_real_get(obj);
+ ok(value == 33.1649758,
+ "bt_value_real_create_init() sets the appropriate initial value");
+
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+}
+
+static
+void test_string(void)
+{
+ const char *value;
+ bt_value *obj;
+
+ obj = bt_value_string_create();
+ ok(obj && bt_value_is_string(obj),
+ "bt_value_string_create() returns a string value object");
+
+ value = bt_value_string_get(obj);
+ ok(value && strcmp(value, "") == 0,
+ "default string value object value is \"\"");
+
+ bt_value_string_set(obj, "hello worldz");
+ value = bt_value_string_get(obj);
+ ok(value && strcmp(value, "hello worldz") == 0,
+ "bt_value_string_get() works");
+
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ pass("putting an existing string value object does not cause a crash")
+
+ obj = bt_value_string_create_init("initial value");
+ ok(obj && bt_value_is_string(obj),
+ "bt_value_string_create_init() returns a string value object");
+ value = bt_value_string_get(obj);
+ ok(value && strcmp(value, "initial value") == 0,
+ "bt_value_string_create_init() sets the appropriate initial value");
+
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+}
+
+static
+void test_array(void)
+{
+ int ret;
+ bt_bool bool_value;
+ int64_t int_value;
+ double real_value;
+ bt_value *obj;
+ const char *string_value;
+ bt_value *array_obj;
+ bt_value *appended_obj;
+
+ array_obj = bt_value_array_create();
+ ok(array_obj && bt_value_is_array(array_obj),
+ "bt_value_array_create() returns an array value object");
+ ok(bt_value_array_is_empty(array_obj),
+ "initial array value object size is 0");
+
+ obj = bt_value_integer_unsigned_create_init(345);
+ ret = bt_value_array_append_element(array_obj, obj);
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ obj = bt_value_integer_signed_create_init(-507);
+ ret |= bt_value_array_append_element(array_obj, obj);
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ obj = bt_value_real_create_init(-17.45);
+ ret |= bt_value_array_append_element(array_obj, obj);
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ obj = bt_value_bool_create_init(BT_TRUE);
+ ret |= bt_value_array_append_element(array_obj, obj);
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ ret |= bt_value_array_append_element(array_obj,
+ bt_value_null);
+ ok(!ret, "bt_value_array_append_element() succeeds");
+ ok(bt_value_array_get_length(array_obj) == 5,
+ "appending an element to an array value object increment its size");
+
+ obj = bt_value_array_borrow_element_by_index(array_obj, 0);
+ ok(bt_value_is_unsigned_integer(obj),
+ "bt_value_array_borrow_element_by_index() returns an value object with the appropriate type (unsigned integer)");
+ int_value = bt_value_integer_unsigned_get(obj);
+ ok(int_value == 345,
+ "bt_value_array_borrow_element_by_index() returns an value object with the appropriate value (unsigned integer)");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 1);
+ ok(bt_value_is_signed_integer(obj),
+ "bt_value_array_borrow_element_by_index() returns an value object with the appropriate type (signed integer)");
+ int_value = bt_value_integer_signed_get(obj);
+ ok(int_value == -507,
+ "bt_value_array_borrow_element_by_index() returns an value object with the appropriate value (signed integer)");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 2);
+ ok(bt_value_is_real(obj),
+ "bt_value_array_borrow_element_by_index() returns an value object with the appropriate type (real number)");
+ real_value = bt_value_real_get(obj);
+ ok(real_value == -17.45,
+ "bt_value_array_borrow_element_by_index() returns an value object with the appropriate value (real number)");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 3);
+ ok(bt_value_is_bool(obj),
+ "bt_value_array_borrow_element_by_index() returns an value object with the appropriate type (boolean)");
+ bool_value = bt_value_bool_get(obj);
+ ok(bool_value,
+ "bt_value_array_borrow_element_by_index() returns an value object with the appropriate value (boolean)");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 4);
+ ok(bt_value_null,
+ "bt_value_array_borrow_element_by_index() returns an value object with the appropriate type (null)");
+
+ obj = bt_value_integer_signed_create_init(1001);
+ BT_ASSERT(obj);
+ ok(!bt_value_array_set_element_by_index(array_obj, 2, obj),
+ "bt_value_array_set_element_by_index() succeeds");
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ obj = bt_value_array_borrow_element_by_index(array_obj, 2);
+ ok(bt_value_is_signed_integer(obj),
+ "bt_value_array_set_element_by_index() inserts an value object with the appropriate type");
+ int_value = bt_value_integer_signed_get(obj);
+ BT_ASSERT(!ret);
+ ok(int_value == 1001,
+ "bt_value_array_set_element_by_index() inserts an value object with the appropriate value");
+
+ ret = bt_value_array_append_bool_element(array_obj,
+ BT_FALSE);
+ ok(!ret, "bt_value_array_append_bool_element() succeeds");
+ ret = bt_value_array_append_unsigned_integer_element(array_obj,
+ 98765);
+ ok(!ret, "bt_value_array_append_unsigned_integer_element() succeeds");
+ ret = bt_value_array_append_signed_integer_element(array_obj,
+ -10101);
+ ok(!ret, "bt_value_array_append_signed_integer_element() succeeds");
+ ret = bt_value_array_append_real_element(array_obj,
+ 2.49578);
+ ok(!ret, "bt_value_array_append_real_element() succeeds");
+ ret = bt_value_array_append_string_element(array_obj,
+ "bt_value");
+ ok(!ret, "bt_value_array_append_string_element() succeeds");
+ ret = bt_value_array_append_empty_array_element(array_obj, NULL);
+ ok(!ret, "bt_value_array_append_empty_array_element() succeeds");
+ ret = bt_value_array_append_empty_array_element(array_obj, &appended_obj);
+ ok(!ret, "bt_value_array_append_empty_array_element() with returned value object succeeds");
+ ok(appended_obj,
+ "object returned by bt_value_array_append_empty_array_element() is not NULL");
+ ok(bt_value_is_array(appended_obj),
+ "object returned by bt_value_array_append_empty_array_element() is an array value");
+ ret = bt_value_array_append_empty_map_element(array_obj, NULL);
+ ok(!ret, "bt_value_array_append_empty_map_element() succeeds");
+ ret = bt_value_array_append_empty_map_element(array_obj, &appended_obj);
+ ok(!ret, "bt_value_array_append_empty_map_element() with returned value object succeeds");
+ ok(appended_obj,
+ "object returned by bt_value_array_append_empty_map_element() is not NULL");
+ ok(bt_value_is_map(appended_obj),
+ "object returned by bt_value_array_append_empty_map_element() is an array value");
+
+ ok(bt_value_array_get_length(array_obj) == 14,
+ "the bt_value_array_append_element_*() functions increment the array value object's size");
+ ok(!bt_value_array_is_empty(array_obj),
+ "map value object is not empty");
+
+ obj = bt_value_array_borrow_element_by_index(array_obj, 5);
+ ok(bt_value_is_bool(obj),
+ "bt_value_array_append_bool_element() appends a boolean value object");
+ bool_value = bt_value_bool_get(obj);
+ ok(!bool_value,
+ "bt_value_array_append_bool_element() appends the appropriate value");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 6);
+ ok(bt_value_is_unsigned_integer(obj),
+ "bt_value_array_append_unsigned_integer_element() appends an unsigned integer value object");
+ int_value = bt_value_integer_unsigned_get(obj);
+ ok(int_value == 98765,
+ "bt_value_array_append_unsigned_integer_element() appends the appropriate value");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 7);
+ ok(bt_value_is_signed_integer(obj),
+ "bt_value_array_append_signed_integer_element() appends a signed integer value object");
+ int_value = bt_value_integer_signed_get(obj);
+ ok(int_value == -10101,
+ "bt_value_array_append_signed_integer_element() appends the appropriate value");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 8);
+ ok(bt_value_is_real(obj),
+ "bt_value_array_append_real_element() appends a real number value object");
+ real_value = bt_value_real_get(obj);
+ ok(real_value == 2.49578,
+ "bt_value_array_append_real_element() appends the appropriate value");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 9);
+ ok(bt_value_is_string(obj),
+ "bt_value_array_append_string_element() appends a string value object");
+ string_value = bt_value_string_get(obj);
+ ok(!ret && string_value && strcmp(string_value, "bt_value") == 0,
+ "bt_value_array_append_string_element() appends the appropriate value");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 10);
+ ok(bt_value_is_array(obj),
+ "bt_value_array_append_empty_array_element() appends an array value object");
+ ok(bt_value_array_is_empty(obj),
+ "bt_value_array_append_empty_array_element() an empty array value object");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 11);
+ ok(bt_value_is_array(obj),
+ "bt_value_array_append_empty_array_element() appends an array value object");
+ ok(bt_value_array_is_empty(obj),
+ "bt_value_array_append_empty_array_element() an empty array value object");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 12);
+ ok(bt_value_is_map(obj),
+ "bt_value_array_append_empty_map_element() appends a map value object");
+ ok(bt_value_map_is_empty(obj),
+ "bt_value_array_append_empty_map_element() an empty map value object");
+ obj = bt_value_array_borrow_element_by_index(array_obj, 13);
+ ok(bt_value_is_map(obj),
+ "bt_value_array_append_empty_map_element() appends a map value object");
+ ok(bt_value_map_is_empty(obj),
+ "bt_value_array_append_empty_map_element() an empty map value object");
+
+ BT_VALUE_PUT_REF_AND_RESET(array_obj);
+ pass("putting an existing array value object does not cause a crash")
+}
+
+static
+bt_value_map_foreach_entry_func_status test_map_foreach_cb_count(
+ const char *key, bt_value *object,
+ void *data)
+{
+ int *count = data;
+
+ if (*count == 3) {
+ return BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_INTERRUPT;
+ } else if (*count == 4) {
+ return BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR;
+ } else if (*count == 5) {
+ return BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_MEMORY_ERROR;
+ }
+
+ (*count)++;
+
+ return BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK;
+}
+
+struct map_foreach_checklist {
+ bt_bool bool1;
+ bt_bool uint;
+ bt_bool int1;
+ bt_bool real1;
+ bt_bool null1;
+ bt_bool bool2;
+ bt_bool int2;
+ bt_bool real2;
+ bt_bool string2;
+ bt_bool array2;
+ bt_bool array3;
+ bt_bool map2;
+ bt_bool map3;
+};
+
+static
+bt_value_map_foreach_entry_func_status test_map_foreach_cb_check(
+ const char *key, bt_value *object, void *data)
+{
+ struct map_foreach_checklist *checklist = data;
+
+ if (strcmp(key, "bt_bool") == 0) {
+ if (checklist->bool1) {
+ fail("test_map_foreach_cb_check(): duplicate key \"bt_bool\"");
+ } else {
+ bt_bool val = BT_FALSE;
+
+ val = bt_value_bool_get(object);
+
+ if (val) {
+ pass("test_map_foreach_cb_check(): \"bt_bool\" value object has the right value");
+ checklist->bool1 = BT_TRUE;
+ } else {
+ fail("test_map_foreach_cb_check(): \"bt_bool\" value object has the wrong value");
+ }
+ }
+ } else if (strcmp(key, "uint") == 0) {
+ if (checklist->uint) {
+ fail("test_map_foreach_cb_check(): duplicate key \"uint\"");
+ } else {
+ uint64_t val = 0;
+
+ val = bt_value_integer_unsigned_get(object);
+
+ if (val == 19457) {
+ pass("test_map_foreach_cb_check(): \"uint\" value object has the right value");
+ checklist->uint = BT_TRUE;
+ } else {
+ fail("test_map_foreach_cb_check(): \"uint\" value object has the wrong value");
+ }
+ }
+ } else if (strcmp(key, "int") == 0) {
+ if (checklist->int1) {
+ fail("test_map_foreach_cb_check(): duplicate key \"int\"");
+ } else {
+ int64_t val = 0;
+
+ val = bt_value_integer_signed_get(object);
+
+ if (val == -12345) {
+ pass("test_map_foreach_cb_check(): \"int\" value object has the right value");
+ checklist->int1 = BT_TRUE;
+ } else {
+ fail("test_map_foreach_cb_check(): \"int\" value object has the wrong value");
+ }
+ }
+ } else if (strcmp(key, "real") == 0) {
+ if (checklist->real1) {
+ fail("test_map_foreach_cb_check(): duplicate key \"real\"");
+ } else {
+ double val = 0;
+
+ val = bt_value_real_get(object);
+
+ if (val == 5.444) {
+ pass("test_map_foreach_cb_check(): \"real\" value object has the right value");
+ checklist->real1 = BT_TRUE;
+ } else {
+ fail("test_map_foreach_cb_check(): \"real\" value object has the wrong value");
+ }
+ }
+ } else if (strcmp(key, "null") == 0) {
+ if (checklist->null1) {
+ fail("test_map_foreach_cb_check(): duplicate key \"bt_bool\"");
+ } else {
+ ok(bt_value_is_null(object), "test_map_foreach_cb_check(): success getting \"null\" value object");
+ checklist->null1 = BT_TRUE;
+ }
+ } else if (strcmp(key, "bool2") == 0) {
+ if (checklist->bool2) {
+ fail("test_map_foreach_cb_check(): duplicate key \"bool2\"");
+ } else {
+ bt_bool val = BT_FALSE;
+
+ val = bt_value_bool_get(object);
+
+ if (val) {
+ pass("test_map_foreach_cb_check(): \"bool2\" value object has the right value");
+ checklist->bool2 = BT_TRUE;
+ } else {
+ fail("test_map_foreach_cb_check(): \"bool2\" value object has the wrong value");
+ }
+ }
+ } else if (strcmp(key, "int2") == 0) {
+ if (checklist->int2) {
+ fail("test_map_foreach_cb_check(): duplicate key \"int2\"");
+ } else {
+ int64_t val = 0;
+
+ val = bt_value_integer_signed_get(object);
+
+ if (val == 98765) {
+ pass("test_map_foreach_cb_check(): \"int2\" value object has the right value");
+ checklist->int2 = BT_TRUE;
+ } else {
+ fail("test_map_foreach_cb_check(): \"int2\" value object has the wrong value");
+ }
+ }
+ } else if (strcmp(key, "real2") == 0) {
+ if (checklist->real2) {
+ fail("test_map_foreach_cb_check(): duplicate key \"real2\"");
+ } else {
+ double val = 0;
+
+ val = bt_value_real_get(object);
+
+ if (val == -49.0001) {
+ pass("test_map_foreach_cb_check(): \"real2\" value object has the right value");
+ checklist->real2 = BT_TRUE;
+ } else {
+ fail("test_map_foreach_cb_check(): \"real2\" value object has the wrong value");
+ }
+ }
+ } else if (strcmp(key, "string2") == 0) {
+ if (checklist->string2) {
+ fail("test_map_foreach_cb_check(): duplicate key \"string2\"");
+ } else {
+ const char *val;
+
+ val = bt_value_string_get(object);
+
+ if (val && strcmp(val, "bt_value") == 0) {
+ pass("test_map_foreach_cb_check(): \"string2\" value object has the right value");
+ checklist->string2 = BT_TRUE;
+ } else {
+ fail("test_map_foreach_cb_check(): \"string2\" value object has the wrong value");
+ }
+ }
+ } else if (strcmp(key, "array2") == 0) {
+ if (checklist->array2) {
+ fail("test_map_foreach_cb_check(): duplicate key \"array2\"");
+ } else {
+ ok(bt_value_is_array(object), "test_map_foreach_cb_check(): success getting \"array2\" value object");
+ ok(bt_value_array_is_empty(object),
+ "test_map_foreach_cb_check(): \"array2\" value object is empty");
+ checklist->array2 = BT_TRUE;
+ }
+ } else if (strcmp(key, "array3") == 0) {
+ if (checklist->array3) {
+ fail("test_map_foreach_cb_check(): duplicate key \"array3\"");
+ } else {
+ ok(bt_value_is_array(object), "test_map_foreach_cb_check(): success getting \"array3\" value object");
+ ok(bt_value_array_is_empty(object),
+ "test_map_foreach_cb_check(): \"array3\" value object is empty");
+ checklist->array3 = BT_TRUE;
+ }
+ } else if (strcmp(key, "map3") == 0) {
+ if (checklist->map3) {
+ fail("test_map_foreach_cb_check(): duplicate key \"map3\"");
+ } else {
+ ok(bt_value_is_map(object), "test_map_foreach_cb_check(): success getting \"map3\" value object");
+ ok(bt_value_map_is_empty(object),
+ "test_map_foreach_cb_check(): \"map3\" value object is empty");
+ checklist->map3 = BT_TRUE;
+ }
+ } else if (strcmp(key, "map2") == 0) {
+ if (checklist->map2) {
+ fail("test_map_foreach_cb_check(): duplicate key \"map2\"");
+ } else {
+ ok(bt_value_is_map(object), "test_map_foreach_cb_check(): success getting \"map2\" value object");
+ ok(bt_value_map_is_empty(object),
+ "test_map_foreach_cb_check(): \"map2\" value object is empty");
+ checklist->map2 = BT_TRUE;
+ }
+ } else {
+ fail("test_map_foreach_cb_check(): unknown map key \"%s\"",
+ key);
+ }
+
+ return BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK;
+}
+
+static
+void test_map(void)
+{
+ int ret;
+ int count = 0;
+ bt_bool bool_value;
+ int64_t int_value;
+ double real_value;
+ bt_value *obj;
+ bt_value *map_obj;
+ bt_value *inserted_obj;
+ struct map_foreach_checklist checklist;
+
+ map_obj = bt_value_map_create();
+ ok(map_obj && bt_value_is_map(map_obj),
+ "bt_value_map_create() returns a map value object");
+ ok(bt_value_map_get_size(map_obj) == 0,
+ "initial map value object size is 0");
+
+ obj = bt_value_integer_unsigned_create_init(19457);
+ ret = bt_value_map_insert_entry(map_obj, "uint", obj);
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ obj = bt_value_integer_signed_create_init(-12345);
+ ret |= bt_value_map_insert_entry(map_obj, "int", obj);
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ obj = bt_value_real_create_init(5.444);
+ ret |= bt_value_map_insert_entry(map_obj, "real", obj);
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ obj = bt_value_bool_create();
+ ret |= bt_value_map_insert_entry(map_obj, "bt_bool", obj);
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ ret |= bt_value_map_insert_entry(map_obj, "null",
+ bt_value_null);
+ ok(!ret, "bt_value_map_insert_entry() succeeds");
+ ok(bt_value_map_get_size(map_obj) == 5,
+ "inserting an element into a map value object increment its size");
+
+ obj = bt_value_bool_create_init(BT_TRUE);
+ ret = bt_value_map_insert_entry(map_obj, "bt_bool", obj);
+ BT_VALUE_PUT_REF_AND_RESET(obj);
+ ok(!ret, "bt_value_map_insert_entry() accepts an existing key");
+
+ obj = bt_value_map_borrow_entry_value(map_obj, "life");
+ ok(!obj, "bt_value_map_borrow_entry_value() returns NULL with an non existing key");
+ obj = bt_value_map_borrow_entry_value(map_obj, "real");
+ ok(obj && bt_value_is_real(obj),
+ "bt_value_map_borrow_entry_value() returns an value object with the appropriate type (real)");
+ real_value = bt_value_real_get(obj);
+ ok(real_value == 5.444,
+ "bt_value_map_borrow_entry_value() returns an value object with the appropriate value (real)");
+ obj = bt_value_map_borrow_entry_value(map_obj, "uint");
+ ok(obj && bt_value_is_unsigned_integer(obj),
+ "bt_value_map_borrow_entry_value() returns an value object with the appropriate type (unsigned integer)");
+ int_value = bt_value_integer_unsigned_get(obj);
+ ok(int_value == 19457,
+ "bt_value_map_borrow_entry_value() returns an value object with the appropriate value (unsigned integer)");
+ obj = bt_value_map_borrow_entry_value(map_obj, "int");
+ ok(obj && bt_value_is_signed_integer(obj),
+ "bt_value_map_borrow_entry_value() returns an value object with the appropriate type (signed integer)");
+ int_value = bt_value_integer_signed_get(obj);
+ ok(int_value == -12345,
+ "bt_value_map_borrow_entry_value() returns an value object with the appropriate value (signed integer)");
+ obj = bt_value_map_borrow_entry_value(map_obj, "null");
+ ok(obj && bt_value_is_null(obj),
+ "bt_value_map_borrow_entry_value() returns an value object with the appropriate type (null)");
+ obj = bt_value_map_borrow_entry_value(map_obj, "bt_bool");
+ ok(obj && bt_value_is_bool(obj),
+ "bt_value_map_borrow_entry_value() returns an value object with the appropriate type (boolean)");
+ bool_value = bt_value_bool_get(obj);
+ ok(bool_value,
+ "bt_value_map_borrow_entry_value() returns an value object with the appropriate value (boolean)");
+
+ ret = bt_value_map_insert_bool_entry(map_obj, "bool2",
+ BT_TRUE);
+ ok(!ret, "bt_value_map_insert_bool_entry() succeeds");
+ ret = bt_value_map_insert_signed_integer_entry(map_obj, "int2",
+ 98765);
+ ok(!ret, "bt_value_map_insert_signed_integer_entry() succeeds");
+ ret = bt_value_map_insert_real_entry(map_obj, "real2",
+ -49.0001);
+ ok(!ret, "bt_value_map_insert_real_entry() succeeds");
+ ret = bt_value_map_insert_string_entry(map_obj, "string2",
+ "bt_value");
+ ok(!ret, "bt_value_map_insert_string_entry() succeeds");
+ ret = bt_value_map_insert_empty_array_entry(map_obj, "array2", NULL);
+ ok(!ret, "bt_value_map_insert_empty_array_entry() succeeds");
+ ret = bt_value_map_insert_empty_array_entry(map_obj, "array3", &inserted_obj);
+ ok(!ret, "bt_value_map_insert_empty_array_entry() with returned value object succeeds");
+ ok(inserted_obj,
+ "object returned by bt_value_map_insert_empty_array_entry() is not NULL");
+ ok(bt_value_is_array(inserted_obj),
+ "object returned by bt_value_map_insert_empty_array_entry() is an array value");
+ ret = bt_value_map_insert_empty_map_entry(map_obj, "map2", NULL);
+ ok(!ret, "bt_value_map_insert_empty_map_entry() succeeds");
+ ret = bt_value_map_insert_empty_map_entry(map_obj, "map3", &inserted_obj);
+ ok(!ret, "bt_value_map_insert_empty_map_entry() with returned value object succeeds");
+ ok(inserted_obj,
+ "object returned by bt_value_map_insert_empty_map_entry() is not NULL");
+ ok(bt_value_is_map(inserted_obj),
+ "object returned by bt_value_map_insert_empty_map_entry() is an array value");
+
+ ok(bt_value_map_get_size(map_obj) == 13,
+ "the bt_value_map_insert*() functions increment the map value object's size");
+
+ ok(!bt_value_map_has_entry(map_obj, "hello"),
+ "map value object does not have key \"hello\"");
+ ok(bt_value_map_has_entry(map_obj, "bt_bool"),
+ "map value object has key \"bt_bool\"");
+ ok(bt_value_map_has_entry(map_obj, "uint"),
+ "map value object has key \"uint\"");
+ ok(bt_value_map_has_entry(map_obj, "int"),
+ "map value object has key \"int\"");
+ ok(bt_value_map_has_entry(map_obj, "real"),
+ "map value object has key \"real\"");
+ ok(bt_value_map_has_entry(map_obj, "null"),
+ "map value object has key \"null\"");
+ ok(bt_value_map_has_entry(map_obj, "bool2"),
+ "map value object has key \"bool2\"");
+ ok(bt_value_map_has_entry(map_obj, "int2"),
+ "map value object has key \"int2\"");
+ ok(bt_value_map_has_entry(map_obj, "real2"),
+ "map value object has key \"real2\"");
+ ok(bt_value_map_has_entry(map_obj, "string2"),
+ "map value object has key \"string2\"");
+ ok(bt_value_map_has_entry(map_obj, "array2"),
+ "map value object has key \"array2\"");
+ ok(bt_value_map_has_entry(map_obj, "array3"),
+ "map value object has key \"array3\"");
+ ok(bt_value_map_has_entry(map_obj, "map2"),
+ "map value object has key \"map2\"");
+ ok(bt_value_map_has_entry(map_obj, "map3"),
+ "map value object has key \"map3\"");
+
+ ret = bt_value_map_foreach_entry(map_obj, test_map_foreach_cb_count,
+ &count);
+ ok(ret == BT_VALUE_MAP_FOREACH_ENTRY_STATUS_INTERRUPTED && count == 3,
+ "bt_value_map_foreach_entry() breaks the loop when the user function returns BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_INTERRUPT");
+
+ count = 4;
+ ret = bt_value_map_foreach_entry(map_obj, test_map_foreach_cb_count,
+ &count);
+ ok(ret == BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR,
+ "bt_value_map_foreach_entry() fails when the user function returns BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR");
+ bt_current_thread_clear_error();
+
+ count = 5;
+ ret = bt_value_map_foreach_entry(map_obj, test_map_foreach_cb_count,
+ &count);
+ ok(ret == BT_VALUE_MAP_FOREACH_ENTRY_STATUS_MEMORY_ERROR,
+ "bt_value_map_foreach_entry() fails when the user function returns BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_MEMORY_ERROR");
+ bt_current_thread_clear_error();
+
+ memset(&checklist, 0, sizeof(checklist));
+ ret = bt_value_map_foreach_entry(map_obj, test_map_foreach_cb_check,
+ &checklist);
+ ok(ret == BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK,
+ "bt_value_map_foreach_entry() succeeds with test_map_foreach_cb_check()");
+ ok(checklist.bool1 && checklist.uint && checklist.int1 &&
+ checklist.real1 && checklist.null1 && checklist.bool2 &&
+ checklist.int2 && checklist.real2 && checklist.string2 &&
+ checklist.array2 && checklist.map2,
+ "bt_value_map_foreach_entry() iterates over all the map value object's elements");
+
+ BT_VALUE_PUT_REF_AND_RESET(map_obj);
+ pass("putting an existing map value object does not cause a crash")
+}
+
+static
+void test_types(void)
+{
+ test_null();
+ test_bool();
+ test_unsigned_integer();
+ test_signed_integer();
+ test_real();
+ test_string();
+ test_array();
+ test_map();
+}
+
+static
+void test_is_equal_null(void)
+{
+ ok(bt_value_is_equal(bt_value_null, bt_value_null),
+ "null value objects are equivalent");
+}
+
+static
+void test_is_equal_bool(void)
+{
+ bt_value *bool1 =
+ bt_value_bool_create_init(BT_FALSE);
+ bt_value *bool2 =
+ bt_value_bool_create_init(BT_TRUE);
+ bt_value *bool3 =
+ bt_value_bool_create_init(BT_FALSE);
+
+ BT_ASSERT(bool1 && bool2 && bool3);
+ ok(!bt_value_is_equal(bt_value_null, bool1),
+ "cannot compare null value object and bt_bool value object");
+ ok(!bt_value_is_equal(bool1, bool2),
+ "boolean value objects are not equivalent (BT_FALSE and BT_TRUE)");
+ ok(bt_value_is_equal(bool1, bool3),
+ "boolean value objects are equivalent (BT_FALSE and BT_FALSE)");
+
+ BT_VALUE_PUT_REF_AND_RESET(bool1);
+ BT_VALUE_PUT_REF_AND_RESET(bool2);
+ BT_VALUE_PUT_REF_AND_RESET(bool3);
+}
+
+static
+void test_is_equal_unsigned_integer(void)
+{
+ bt_value *int1 =
+ bt_value_integer_unsigned_create_init(10);
+ bt_value *int2 =
+ bt_value_integer_unsigned_create_init(23);
+ bt_value *int3 =
+ bt_value_integer_unsigned_create_init(10);
+
+ BT_ASSERT(int1 && int2 && int3);
+ ok(!bt_value_is_equal(bt_value_null, int1),
+ "cannot compare null value object and unsigned integer value object");
+ ok(!bt_value_is_equal(int1, int2),
+ "unsigned integer value objects are not equivalent (10 and 23)");
+ ok(bt_value_is_equal(int1, int3),
+ "unsigned integer value objects are equivalent (10 and 10)");
+
+ BT_VALUE_PUT_REF_AND_RESET(int1);
+ BT_VALUE_PUT_REF_AND_RESET(int2);
+ BT_VALUE_PUT_REF_AND_RESET(int3);
+}
+
+static
+void test_is_equal_signed_integer(void)
+{
+ bt_value *int1 =
+ bt_value_integer_signed_create_init(10);
+ bt_value *int2 =
+ bt_value_integer_signed_create_init(-23);
+ bt_value *int3 =
+ bt_value_integer_signed_create_init(10);
+
+ BT_ASSERT(int1 && int2 && int3);
+ ok(!bt_value_is_equal(bt_value_null, int1),
+ "cannot compare null value object and signed integer value object");
+ ok(!bt_value_is_equal(int1, int2),
+ "signed integer value objects are not equivalent (10 and -23)");
+ ok(bt_value_is_equal(int1, int3),
+ "signed integer value objects are equivalent (10 and 10)");
+
+ BT_VALUE_PUT_REF_AND_RESET(int1);
+ BT_VALUE_PUT_REF_AND_RESET(int2);
+ BT_VALUE_PUT_REF_AND_RESET(int3);
+}
+
+static
+void test_is_equal_real(void)
+{
+ bt_value *real1 =
+ bt_value_real_create_init(17.38);
+ bt_value *real2 =
+ bt_value_real_create_init(-14.23);
+ bt_value *real3 =
+ bt_value_real_create_init(17.38);
+
+ BT_ASSERT(real1 && real2 && real3);
+
+ ok(!bt_value_is_equal(bt_value_null, real1),
+ "cannot compare null value object and real number value object");
+ ok(!bt_value_is_equal(real1, real2),
+ "real number value objects are not equivalent (17.38 and -14.23)");
+ ok(bt_value_is_equal(real1, real3),
+ "real number value objects are equivalent (17.38 and 17.38)");
+
+ BT_VALUE_PUT_REF_AND_RESET(real1);
+ BT_VALUE_PUT_REF_AND_RESET(real2);
+ BT_VALUE_PUT_REF_AND_RESET(real3);
+}
+
+static
+void test_is_equal_string(void)
+{
+ bt_value *string1 =
+ bt_value_string_create_init("hello");
+ bt_value *string2 =
+ bt_value_string_create_init("bt_value");
+ bt_value *string3 =
+ bt_value_string_create_init("hello");
+
+ BT_ASSERT(string1 && string2 && string3);
+
+ ok(!bt_value_is_equal(bt_value_null, string1),
+ "cannot compare null value object and string value object");
+ ok(!bt_value_is_equal(string1, string2),
+ "string value objects are not equivalent (\"hello\" and \"bt_value\")");
+ ok(bt_value_is_equal(string1, string3),
+ "string value objects are equivalent (\"hello\" and \"hello\")");
+
+ BT_VALUE_PUT_REF_AND_RESET(string1);
+ BT_VALUE_PUT_REF_AND_RESET(string2);
+ BT_VALUE_PUT_REF_AND_RESET(string3);
+}
+
+static
+void test_is_equal_array(void)
+{
+ bt_value *array1 = bt_value_array_create();
+ bt_value *array2 = bt_value_array_create();
+ bt_value *array3 = bt_value_array_create();
+ bt_value_array_append_element_status append_status;
+
+ BT_ASSERT(array1 && array2 && array3);
+
+ ok(bt_value_is_equal(array1, array2),
+ "empty array value objects are equivalent");
+
+ append_status = bt_value_array_append_signed_integer_element(array1, 23);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_real_element(array1, 14.2);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_bool_element(array1, BT_FALSE);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_real_element(array2, 14.2);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_signed_integer_element(array2, 23);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_bool_element(array2, BT_FALSE);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_signed_integer_element(array3, 23);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_real_element(array3, 14.2);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_bool_element(array3, BT_FALSE);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ BT_ASSERT(bt_value_array_get_length(array1) == 3);
+ BT_ASSERT(bt_value_array_get_length(array2) == 3);
+ BT_ASSERT(bt_value_array_get_length(array3) == 3);
+
+ ok(!bt_value_is_equal(bt_value_null, array1),
+ "cannot compare null value object and array value object");
+ ok(!bt_value_is_equal(array1, array2),
+ "array value objects are not equivalent ([23, 14.2, BT_FALSE] and [14.2, 23, BT_FALSE])");
+ ok(bt_value_is_equal(array1, array3),
+ "array value objects are equivalent ([23, 14.2, BT_FALSE] and [23, 14.2, BT_FALSE])");
+
+ BT_VALUE_PUT_REF_AND_RESET(array1);
+ BT_VALUE_PUT_REF_AND_RESET(array2);
+ BT_VALUE_PUT_REF_AND_RESET(array3);
+}
+
+static
+void test_is_equal_map(void)
+{
+ bt_value *map1 = bt_value_map_create();
+ bt_value *map2 = bt_value_map_create();
+ bt_value *map3 = bt_value_map_create();
+ bt_value_map_insert_entry_status insert_status;
+
+ BT_ASSERT(map1 && map2 && map3);
+
+ ok(bt_value_is_equal(map1, map2),
+ "empty map value objects are equivalent");
+
+
+ insert_status = bt_value_map_insert_signed_integer_entry(map1, "one", 23);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_real_entry(map1, "two", 14.2);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_bool_entry(map1, "three",
+ BT_FALSE);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_real_entry(map2, "one", 14.2);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_signed_integer_entry(map2, "two", 23);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_bool_entry(map2, "three",
+ BT_FALSE);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_bool_entry(map3, "three",
+ BT_FALSE);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_signed_integer_entry(map3, "one", 23);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_real_entry(map3, "two", 14.2);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ BT_ASSERT(bt_value_map_get_size(map1) == 3);
+ BT_ASSERT(bt_value_map_get_size(map2) == 3);
+ BT_ASSERT(bt_value_map_get_size(map3) == 3);
+
+ ok(!bt_value_is_equal(bt_value_null, map1),
+ "cannot compare null value object and map value object");
+ ok(!bt_value_is_equal(map1, map2),
+ "map value objects are not equivalent");
+ ok(bt_value_is_equal(map1, map3),
+ "map value objects are equivalent");
+
+ BT_VALUE_PUT_REF_AND_RESET(map1);
+ BT_VALUE_PUT_REF_AND_RESET(map2);
+ BT_VALUE_PUT_REF_AND_RESET(map3);
+}
+
+static
+void test_is_equal(void)
+{
+ test_is_equal_null();
+ test_is_equal_bool();
+ test_is_equal_unsigned_integer();
+ test_is_equal_signed_integer();
+ test_is_equal_real();
+ test_is_equal_string();
+ test_is_equal_array();
+ test_is_equal_map();
+}
+
+static
+void test_copy(void)
+{
+ /*
+ * Here's the deal here. If we make sure that each value object
+ * of our deep copy has a different address than its source, and
+ * that bt_value_is_equal() returns BT_TRUE for the top-level
+ * value object, taking into account that we test the
+ * correctness of bt_value_is_equal() elsewhere, then the deep
+ * copy is a success.
+ */
+ bt_value *null_copy_obj;
+ bt_value *bool_obj, *bool_copy_obj;
+ bt_value *unsigned_integer_obj, *unsigned_integer_copy_obj;
+ bt_value *signed_integer_obj, *signed_integer_copy_obj;
+ bt_value *real_obj, *real_copy_obj;
+ bt_value *string_obj, *string_copy_obj;
+ bt_value *array_obj, *array_copy_obj;
+ bt_value *map_obj, *map_copy_obj;
+ bt_value_array_append_element_status append_status;
+ bt_value_map_insert_entry_status insert_status;
+ bt_value_copy_status copy_status;
+
+ bool_obj = bt_value_bool_create_init(BT_TRUE);
+ unsigned_integer_obj = bt_value_integer_unsigned_create_init(23);
+ signed_integer_obj = bt_value_integer_signed_create_init(-47);
+ real_obj = bt_value_real_create_init(-3.1416);
+ string_obj = bt_value_string_create_init("test");
+ array_obj = bt_value_array_create();
+ map_obj = bt_value_map_create();
+
+ BT_ASSERT(bool_obj && unsigned_integer_obj && signed_integer_obj &&
+ real_obj && string_obj && array_obj && map_obj);
+
+ append_status = bt_value_array_append_element(array_obj, bool_obj);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_element(array_obj, unsigned_integer_obj);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_element(array_obj, signed_integer_obj);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_element(array_obj, real_obj);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ append_status = bt_value_array_append_element(array_obj, bt_value_null);
+ BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
+ insert_status = bt_value_map_insert_entry(map_obj, "array", array_obj);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_entry(map_obj, "string", string_obj);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+
+ copy_status = bt_value_copy(map_obj, &map_copy_obj);
+ ok(copy_status == BT_VALUE_COPY_STATUS_OK && map_copy_obj,
+ "bt_value_copy() succeeds");
+
+ ok(map_obj != map_copy_obj,
+ "bt_value_copy() returns a different pointer (map)");
+ string_copy_obj = bt_value_map_borrow_entry_value(map_copy_obj,
+ "string");
+ ok(string_copy_obj != string_obj,
+ "bt_value_copy() returns a different pointer (string)");
+ array_copy_obj = bt_value_map_borrow_entry_value(map_copy_obj,
+ "array");
+ ok(array_copy_obj != array_obj,
+ "bt_value_copy() returns a different pointer (array)");
+ bool_copy_obj = bt_value_array_borrow_element_by_index(
+ array_copy_obj, 0);
+ ok(bool_copy_obj != bool_obj,
+ "bt_value_copy() returns a different pointer (bool)");
+ unsigned_integer_copy_obj = bt_value_array_borrow_element_by_index(
+ array_copy_obj, 1);
+ ok(unsigned_integer_copy_obj != unsigned_integer_obj,
+ "bt_value_copy() returns a different pointer (unsigned integer)");
+ signed_integer_copy_obj = bt_value_array_borrow_element_by_index(
+ array_copy_obj, 2);
+ ok(signed_integer_copy_obj != signed_integer_obj,
+ "bt_value_copy() returns a different pointer (signed integer)");
+ real_copy_obj = bt_value_array_borrow_element_by_index(
+ array_copy_obj, 3);
+ ok(real_copy_obj != real_obj,
+ "bt_value_copy() returns a different pointer (real)");
+ null_copy_obj = bt_value_array_borrow_element_by_index(
+ array_copy_obj, 4);
+ ok(null_copy_obj == bt_value_null,
+ "bt_value_copy() returns the same pointer (null)");
+
+ ok(bt_value_is_equal(map_obj, map_copy_obj),
+ "source and destination value objects have the same content");
+
+ BT_VALUE_PUT_REF_AND_RESET(map_copy_obj);
+ BT_VALUE_PUT_REF_AND_RESET(bool_obj);
+ BT_VALUE_PUT_REF_AND_RESET(unsigned_integer_obj);
+ BT_VALUE_PUT_REF_AND_RESET(signed_integer_obj);
+ BT_VALUE_PUT_REF_AND_RESET(real_obj);
+ BT_VALUE_PUT_REF_AND_RESET(string_obj);
+ BT_VALUE_PUT_REF_AND_RESET(array_obj);
+ BT_VALUE_PUT_REF_AND_RESET(map_obj);
+}
+
+static
+bt_bool compare_map_elements(const bt_value *map_a, const bt_value *map_b,
+ const char *key)
+{
+ const bt_value *elem_a = NULL;
+ const bt_value *elem_b = NULL;
+ bt_bool equal;
+
+ elem_a = bt_value_map_borrow_entry_value_const(map_a, key);
+ elem_b = bt_value_map_borrow_entry_value_const(map_b, key);
+ equal = bt_value_is_equal(elem_a, elem_b);
+ return equal;
+}
+
+static
+void test_extend(void)
+{
+ bt_value *base_map = bt_value_map_create();
+ bt_value *extension_map = bt_value_map_create();
+ bt_value *extended_map = NULL;
+ bt_value *array = bt_value_array_create();
+ bt_value_map_insert_entry_status insert_status;
+ bt_value_copy_status copy_status;
+ bt_value_map_extend_status extend_status;
+
+ BT_ASSERT(base_map);
+ BT_ASSERT(extension_map);
+ BT_ASSERT(array);
+ insert_status = bt_value_map_insert_bool_entry(base_map, "file",
+ BT_TRUE);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_bool_entry(base_map, "edit",
+ BT_FALSE);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_signed_integer_entry(base_map,
+ "selection", 17);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_signed_integer_entry(base_map, "find",
+ -34);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_bool_entry(extension_map, "edit",
+ BT_TRUE);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_signed_integer_entry(extension_map,
+ "find", 101);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ insert_status = bt_value_map_insert_real_entry(extension_map,
+ "project", -404);
+ BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
+ copy_status = bt_value_copy(base_map, &extended_map);
+ BT_ASSERT(copy_status == BT_VALUE_COPY_STATUS_OK);
+ extend_status = bt_value_map_extend(extended_map, extension_map);
+ ok(extend_status == BT_VALUE_MAP_EXTEND_STATUS_OK &&
+ extended_map, "bt_value_map_extend() succeeds");
+ ok(bt_value_map_get_size(extended_map) == 5,
+ "bt_value_map_extend() returns a map object with the correct size");
+ ok(compare_map_elements(base_map,
+ extended_map, "file"),
+ "bt_value_map_extend() picks the appropriate element (file)");
+ ok(compare_map_elements(extension_map,
+ extended_map, "edit"),
+ "bt_value_map_extend() picks the appropriate element (edit)");
+ ok(compare_map_elements(base_map,
+ extended_map, "selection"),
+ "bt_value_map_extend() picks the appropriate element (selection)");
+ ok(compare_map_elements(extension_map,
+ extended_map, "find"),
+ "bt_value_map_extend() picks the appropriate element (find)");
+ ok(compare_map_elements(extension_map,
+ extended_map, "project"),
+ "bt_value_map_extend() picks the appropriate element (project)");
+
+ BT_VALUE_PUT_REF_AND_RESET(array);
+ BT_VALUE_PUT_REF_AND_RESET(base_map);
+ BT_VALUE_PUT_REF_AND_RESET(extension_map);
+ BT_VALUE_PUT_REF_AND_RESET(extended_map);
+}
+
+int main(void)
+{
+ plan_tests(NR_TESTS);
+ test_types();
+ test_is_equal();
+ test_copy();
+ test_extend();
+ return exit_status();
+}
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2023 EfficiOS Inc.
+ */
+
+#include "utils/run-in.hpp"
+#include "tap/tap.h"
+#include "common/assert.h"
+#include <cstring>
+
+static const int NR_TESTS = 2;
+
+static void test_string_clear()
+{
+ runInMsgIterClsInit([](bt_self_message_iterator * const self) {
+ /* Boilerplate to get a string field */
+ const auto traceCls =
+ bt_trace_class_create(bt_self_message_iterator_borrow_component(self));
+ const auto streamCls = bt_stream_class_create(traceCls);
+ const auto eventCls = bt_event_class_create(streamCls);
+ const auto payloadCls = bt_field_class_structure_create(traceCls);
+
+ {
+ const auto stringFieldCls = bt_field_class_string_create(traceCls);
+ const auto status =
+ bt_field_class_structure_append_member(payloadCls, "str", stringFieldCls);
+ BT_ASSERT(status == BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_OK);
+ bt_field_class_put_ref(stringFieldCls);
+ }
+
+ {
+ const auto status = bt_event_class_set_payload_field_class(eventCls, payloadCls);
+ BT_ASSERT(status == BT_EVENT_CLASS_SET_FIELD_CLASS_STATUS_OK);
+ }
+
+ const auto trace = bt_trace_create(traceCls);
+ const auto stream = bt_stream_create(streamCls, trace);
+ const auto msg = bt_message_event_create(self, eventCls, stream);
+ const auto field = bt_field_structure_borrow_member_field_by_name(
+ bt_event_borrow_payload_field(bt_message_event_borrow_event(msg)), "str");
+
+ /* Set the field to a known non-empty value */
+ {
+ const auto status = bt_field_string_set_value(field, "pomme");
+ BT_ASSERT(status == BT_FIELD_STRING_SET_VALUE_STATUS_OK);
+ BT_ASSERT(std::strcmp(bt_field_string_get_value(field), "pomme") == 0);
+ }
+
+ /* Clear the field, verify its value and length */
+ bt_field_string_clear(field);
+ ok(std::strcmp(bt_field_string_get_value(field), "") == 0, "string field is empty");
+ ok(bt_field_string_get_length(field) == 0, "string field length is 0");
+
+ bt_message_put_ref(msg);
+ bt_stream_put_ref(stream);
+ bt_trace_put_ref(trace);
+ bt_field_class_put_ref(payloadCls);
+ bt_event_class_put_ref(eventCls);
+ bt_stream_class_put_ref(streamCls);
+ bt_trace_class_put_ref(traceCls);
+ });
+}
+
+int main()
+{
+ plan_tests(NR_TESTS);
+
+ test_string_clear();
+
+ return exit_status();
+}
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2023 EfficiOS, Inc.
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+run_python_bt2 "${BT_TESTS_BUILDDIR}/lib/test-fields-bin"
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
+ */
+
+#include <babeltrace2/babeltrace.h>
+#include "common/assert.h"
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+#include <glib.h>
+
+#include "tap/tap.h"
+
+#define NR_TESTS 26
+
+enum event_type {
+ SRC_COMP_OUTPUT_PORT_CONNECTED,
+ SINK_COMP_INPUT_PORT_CONNECTED,
+ GRAPH_SRC_OUTPUT_PORT_ADDED,
+ GRAPH_SINK_INPUT_PORT_ADDED,
+};
+
+enum test {
+ TEST_EMPTY_GRAPH,
+ TEST_SIMPLE,
+ TEST_SRC_PORT_CONNECTED_ERROR,
+ TEST_SINK_PORT_CONNECTED_ERROR,
+ TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
+};
+
+struct event {
+ enum event_type type;
+
+ union {
+ struct {
+ const bt_component *comp;
+ const bt_port *self_port;
+ const bt_port *other_port;
+ } src_comp_output_port_connected;
+
+ struct {
+ const bt_component *comp;
+ const bt_port *self_port;
+ const bt_port *other_port;
+ } sink_comp_input_port_connected;
+
+ struct {
+ const bt_component *comp;
+ const bt_port *port;
+ } graph_src_output_port_added;
+
+ struct {
+ const bt_component *comp;
+ const bt_port *port;
+ } graph_sink_input_port_added;
+ } data;
+};
+
+static GArray *events;
+static bt_message_iterator_class *msg_iter_class;
+static bt_component_class_source *src_comp_class;
+static bt_component_class_sink *sink_comp_class;
+static enum test current_test;
+
+static
+void clear_events(void)
+{
+ g_array_set_size(events, 0);
+}
+
+static
+void append_event(struct event *event)
+{
+ g_array_append_val(events, *event);
+}
+
+static
+bool compare_events(struct event *ev_a, struct event *ev_b)
+{
+ if (ev_a->type != ev_b->type) {
+ return false;
+ }
+
+ switch (ev_a->type) {
+ case SRC_COMP_OUTPUT_PORT_CONNECTED:
+ if (ev_a->data.src_comp_output_port_connected.comp !=
+ ev_b->data.src_comp_output_port_connected.comp) {
+ return false;
+ }
+
+ if (ev_a->data.src_comp_output_port_connected.self_port !=
+ ev_b->data.src_comp_output_port_connected.self_port) {
+ return false;
+ }
+
+ if (ev_a->data.src_comp_output_port_connected.other_port !=
+ ev_b->data.src_comp_output_port_connected.other_port) {
+ return false;
+ }
+ break;
+ case SINK_COMP_INPUT_PORT_CONNECTED:
+ if (ev_a->data.sink_comp_input_port_connected.comp !=
+ ev_b->data.sink_comp_input_port_connected.comp) {
+ return false;
+ }
+
+ if (ev_a->data.sink_comp_input_port_connected.self_port !=
+ ev_b->data.sink_comp_input_port_connected.self_port) {
+ return false;
+ }
+
+ if (ev_a->data.sink_comp_input_port_connected.other_port !=
+ ev_b->data.sink_comp_input_port_connected.other_port) {
+ return false;
+ }
+ break;
+ case GRAPH_SRC_OUTPUT_PORT_ADDED:
+ if (ev_a->data.graph_src_output_port_added.comp !=
+ ev_b->data.graph_src_output_port_added.comp) {
+ return false;
+ }
+
+ if (ev_a->data.graph_src_output_port_added.port !=
+ ev_b->data.graph_src_output_port_added.port) {
+ return false;
+ }
+ break;
+ case GRAPH_SINK_INPUT_PORT_ADDED:
+ if (ev_a->data.graph_sink_input_port_added.comp !=
+ ev_b->data.graph_sink_input_port_added.comp) {
+ return false;
+ }
+
+ if (ev_a->data.graph_sink_input_port_added.port !=
+ ev_b->data.graph_sink_input_port_added.port) {
+ return false;
+ }
+ break;
+ default:
+ abort();
+ }
+
+ return true;
+}
+
+static
+bool has_event(struct event *event)
+{
+ size_t i;
+
+ for (i = 0; i < events->len; i++) {
+ struct event *ev = &bt_g_array_index(events, struct event, i);
+
+ if (compare_events(event, ev)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static
+size_t event_pos(struct event *event)
+{
+ size_t i;
+
+ for (i = 0; i < events->len; i++) {
+ struct event *ev = &bt_g_array_index(events, struct event, i);
+
+ if (compare_events(event, ev)) {
+ return i;
+ }
+ }
+
+ return SIZE_MAX;
+}
+
+static
+bt_message_iterator_class_next_method_status src_iter_next(
+ bt_self_message_iterator *self_iterator,
+ bt_message_array_const msgs, uint64_t capacity,
+ uint64_t *count)
+{
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
+}
+
+static
+bt_component_class_port_connected_method_status src_output_port_connected(
+ bt_self_component_source *self_comp,
+ bt_self_component_port_output *self_comp_port,
+ const bt_port_input *other_port)
+{
+ int ret;
+ struct event event = {
+ .type = SRC_COMP_OUTPUT_PORT_CONNECTED,
+ .data.src_comp_output_port_connected = {
+ .comp = bt_self_component_as_component(
+ bt_self_component_source_as_self_component(
+ self_comp)),
+ .self_port = bt_self_component_port_as_port(
+ bt_self_component_port_output_as_self_component_port(
+ self_comp_port)),
+ .other_port = bt_port_input_as_port_const(other_port),
+ },
+ };
+
+ append_event(&event);
+
+ switch (current_test) {
+ case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED:
+ ret = bt_self_component_source_add_output_port(
+ self_comp, "hello", NULL, NULL);
+ BT_ASSERT(ret == 0);
+ break;
+ case TEST_SRC_PORT_CONNECTED_ERROR:
+ return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
+ default:
+ break;
+ }
+
+ return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_OK;
+}
+
+static
+bt_component_class_port_connected_method_status sink_input_port_connected(
+ bt_self_component_sink *self_comp,
+ bt_self_component_port_input *self_comp_port,
+ const bt_port_output *other_port)
+{
+ struct event event = {
+ .type = SINK_COMP_INPUT_PORT_CONNECTED,
+ .data.sink_comp_input_port_connected = {
+ .comp = bt_self_component_as_component(
+ bt_self_component_sink_as_self_component(
+ self_comp)),
+ .self_port = bt_self_component_port_as_port(
+ bt_self_component_port_input_as_self_component_port(
+ self_comp_port)),
+ .other_port = bt_port_output_as_port_const(other_port),
+ },
+ };
+
+ append_event(&event);
+
+ if (current_test == TEST_SINK_PORT_CONNECTED_ERROR) {
+ return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
+ } else {
+ return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_OK;
+ }
+}
+
+static
+bt_component_class_initialize_method_status src_init(
+ bt_self_component_source *self_comp,
+ bt_self_component_source_configuration *config,
+ const bt_value *params, void *init_method_data)
+{
+ int ret;
+
+ ret = bt_self_component_source_add_output_port(
+ self_comp, "out", NULL, NULL);
+ BT_ASSERT(ret == 0);
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
+}
+
+static
+bt_component_class_initialize_method_status sink_init(
+ bt_self_component_sink *self_comp,
+ bt_self_component_sink_configuration *config,
+ const bt_value *params, void *init_method_data)
+{
+ int ret;
+
+ ret = bt_self_component_sink_add_input_port(self_comp,
+ "in", NULL, NULL);
+ BT_ASSERT(ret == 0);
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
+}
+
+static
+bt_component_class_sink_consume_method_status sink_consume(
+ bt_self_component_sink *self_comp)
+{
+ return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
+}
+
+static
+bt_graph_listener_func_status graph_src_output_port_added(
+ const bt_component_source *comp, const bt_port_output *port,
+ void *data)
+{
+ struct event event = {
+ .type = GRAPH_SRC_OUTPUT_PORT_ADDED,
+ .data.graph_src_output_port_added = {
+ .comp = bt_component_source_as_component_const(comp),
+ .port = bt_port_output_as_port_const(port),
+ },
+ };
+
+ append_event(&event);
+
+ return BT_GRAPH_LISTENER_FUNC_STATUS_OK;
+}
+
+static
+bt_graph_listener_func_status graph_sink_input_port_added(
+ const bt_component_sink *comp, const bt_port_input *port,
+ void *data)
+{
+ struct event event = {
+ .type = GRAPH_SINK_INPUT_PORT_ADDED,
+ .data.graph_sink_input_port_added = {
+ .comp = bt_component_sink_as_component_const(comp),
+ .port = bt_port_input_as_port_const(port),
+ },
+ };
+
+ append_event(&event);
+
+ return BT_GRAPH_LISTENER_FUNC_STATUS_OK;
+}
+
+static
+void init_test(void)
+{
+ int ret;
+
+ msg_iter_class = bt_message_iterator_class_create(src_iter_next);
+ BT_ASSERT(msg_iter_class);
+
+ src_comp_class = bt_component_class_source_create(
+ "src", msg_iter_class);
+ BT_ASSERT(src_comp_class);
+ ret = bt_component_class_source_set_initialize_method(
+ src_comp_class, src_init);
+ BT_ASSERT(ret == 0);
+ ret = bt_component_class_source_set_output_port_connected_method(
+ src_comp_class, src_output_port_connected);
+ BT_ASSERT(ret == 0);
+ sink_comp_class = bt_component_class_sink_create("sink",
+ sink_consume);
+ BT_ASSERT(sink_comp_class);
+ ret = bt_component_class_sink_set_initialize_method(sink_comp_class,
+ sink_init);
+ BT_ASSERT(ret == 0);
+ ret = bt_component_class_sink_set_input_port_connected_method(
+ sink_comp_class, sink_input_port_connected);
+ BT_ASSERT(ret == 0);
+ events = g_array_new(FALSE, TRUE, sizeof(struct event));
+ BT_ASSERT(events);
+}
+
+static
+void fini_test(void)
+{
+ bt_component_class_source_put_ref(src_comp_class);
+ bt_component_class_sink_put_ref(sink_comp_class);
+ g_array_free(events, TRUE);
+ BT_MESSAGE_ITERATOR_CLASS_PUT_REF_AND_RESET(msg_iter_class);
+}
+
+static
+const bt_component_source *create_src(bt_graph *graph)
+{
+ const bt_component_source *comp;
+ int ret;
+
+ ret = bt_graph_add_source_component(graph, src_comp_class,
+ "src-comp", NULL, BT_LOGGING_LEVEL_NONE, &comp);
+ BT_ASSERT(ret == 0);
+ return comp;
+}
+
+static
+const bt_component_sink *create_sink(bt_graph *graph)
+{
+ const bt_component_sink *comp;
+ int ret;
+
+ ret = bt_graph_add_sink_component(graph, sink_comp_class,
+ "sink-comp", NULL, BT_LOGGING_LEVEL_NONE, &comp);
+ BT_ASSERT(ret == 0);
+ return comp;
+}
+
+static
+bt_graph *create_graph(void)
+{
+ bt_graph *graph = bt_graph_create(0);
+ int ret;
+
+ BT_ASSERT(graph);
+ ret = bt_graph_add_source_component_output_port_added_listener(
+ graph, graph_src_output_port_added, NULL, NULL);
+ BT_ASSERT(ret >= 0);
+ ret = bt_graph_add_sink_component_input_port_added_listener(
+ graph, graph_sink_input_port_added, NULL, NULL);
+ BT_ASSERT(ret >= 0);
+ return graph;
+}
+
+static
+void prepare_test(enum test test, const char *name)
+{
+ clear_events();
+ current_test = test;
+ diag("test: %s", name);
+}
+
+static
+void test_src_adds_port_in_port_connected(void)
+{
+ const bt_component_source *src;
+ const bt_component_sink *sink;
+ const bt_component *gsrc;
+ const bt_component *gsink;
+ bt_graph *graph;
+ const bt_port_output *src_def_port;
+ const bt_port_output *src_hello_port;
+ const bt_port_input *sink_def_port;
+ const bt_port *gsrc_def_port;
+ const bt_port *gsrc_hello_port;
+ const bt_port *gsink_def_port;
+ struct event event;
+ bt_graph_connect_ports_status status;
+ size_t src_port_connected_pos;
+ size_t graph_port_added_src_pos;
+
+ prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
+ "source adds port in port connected");
+ graph = create_graph();
+ BT_ASSERT(graph);
+ src = create_src(graph);
+ sink = create_sink(graph);
+ src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
+ "out");
+ BT_ASSERT(src_def_port);
+ sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
+ "in");
+ BT_ASSERT(sink_def_port);
+ status = bt_graph_connect_ports(graph, src_def_port,
+ sink_def_port, NULL);
+ BT_ASSERT(status == 0);
+ src_hello_port = bt_component_source_borrow_output_port_by_name_const(src,
+ "hello");
+ BT_ASSERT(src_hello_port);
+ gsrc = bt_component_source_as_component_const(src);
+ gsink = bt_component_sink_as_component_const(sink);
+ gsrc_def_port = bt_port_output_as_port_const(src_def_port);
+ gsrc_hello_port = bt_port_output_as_port_const(src_hello_port);
+ gsink_def_port = bt_port_input_as_port_const(sink_def_port);
+
+ /* We're supposed to have 5 events */
+ ok(events->len == 5, "we have the expected number of events");
+
+ /* Source's port added */
+ event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
+ event.data.graph_src_output_port_added.comp = gsrc;
+ event.data.graph_src_output_port_added.port = gsrc_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
+
+ /* Sink's port added */
+ event.type = GRAPH_SINK_INPUT_PORT_ADDED;
+ event.data.graph_sink_input_port_added.comp = gsink;
+ event.data.graph_sink_input_port_added.port = gsink_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
+
+ /* Source's port connected */
+ event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
+ event.data.src_comp_output_port_connected.comp = gsrc;
+ event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
+ event.data.src_comp_output_port_connected.other_port = gsink_def_port;
+ ok(has_event(&event), "got the expected source's port connected event");
+ src_port_connected_pos = event_pos(&event);
+
+ /* Graph's port added (source) */
+ event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
+ event.data.graph_src_output_port_added.comp = gsrc;
+ event.data.graph_src_output_port_added.port = gsrc_hello_port;
+ ok(has_event(&event), "got the expected graph's port added event (for source)");
+ graph_port_added_src_pos = event_pos(&event);
+
+ /* Sink's port connected */
+ event.type = SINK_COMP_INPUT_PORT_CONNECTED;
+ event.data.sink_comp_input_port_connected.comp = gsink;
+ event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
+ event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
+ ok(has_event(&event), "got the expected sink's port connected event");
+
+ /* Order of events */
+ ok(src_port_connected_pos < graph_port_added_src_pos,
+ "event order is good");
+
+ bt_graph_put_ref(graph);
+}
+
+static
+void test_simple(void)
+{
+ const bt_component_source *src;
+ const bt_component_sink *sink;
+ const bt_component *gsrc;
+ const bt_component *gsink;
+ bt_graph *graph;
+ const bt_port_output *src_def_port;
+ const bt_port_input *sink_def_port;
+ const bt_port *gsrc_def_port;
+ const bt_port *gsink_def_port;
+ struct event event;
+ bt_graph_connect_ports_status status;
+
+ prepare_test(TEST_SIMPLE, "simple");
+ graph = create_graph();
+ BT_ASSERT(graph);
+ src = create_src(graph);
+ sink = create_sink(graph);
+ src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
+ "out");
+ BT_ASSERT(src_def_port);
+ sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
+ "in");
+ BT_ASSERT(sink_def_port);
+ status = bt_graph_connect_ports(graph, src_def_port,
+ sink_def_port, NULL);
+ BT_ASSERT(status == 0);
+ gsrc = bt_component_source_as_component_const(src);
+ gsink = bt_component_sink_as_component_const(sink);
+ gsrc_def_port = bt_port_output_as_port_const(src_def_port);
+ gsink_def_port = bt_port_input_as_port_const(sink_def_port);
+
+ /* We're supposed to have 4 events */
+ ok(events->len == 4, "we have the expected number of events");
+
+ /* Source's port added */
+ event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
+ event.data.graph_src_output_port_added.comp = gsrc;
+ event.data.graph_src_output_port_added.port = gsrc_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
+
+ /* Sink's port added */
+ event.type = GRAPH_SINK_INPUT_PORT_ADDED;
+ event.data.graph_sink_input_port_added.comp = gsink;
+ event.data.graph_sink_input_port_added.port = gsink_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
+
+ /* Source's port connected */
+ event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
+ event.data.src_comp_output_port_connected.comp = gsrc;
+ event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
+ event.data.src_comp_output_port_connected.other_port = gsink_def_port;
+ ok(has_event(&event), "got the expected source's port connected event");
+
+ /* Sink's port connected */
+ event.type = SINK_COMP_INPUT_PORT_CONNECTED;
+ event.data.sink_comp_input_port_connected.comp = gsink;
+ event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
+ event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
+ ok(has_event(&event), "got the expected sink's port connected event");
+
+ bt_graph_put_ref(graph);
+}
+
+static
+void test_src_port_connected_error(void)
+{
+ const bt_component_source *src;
+ const bt_component_sink *sink;
+ const bt_component *gsrc;
+ const bt_component *gsink;
+ bt_graph *graph;
+ const bt_port_output *src_def_port;
+ const bt_port_input *sink_def_port;
+ const bt_port *gsrc_def_port;
+ const bt_port *gsink_def_port;
+ const bt_connection *conn = NULL;
+ struct event event;
+ bt_graph_connect_ports_status status;
+
+ prepare_test(TEST_SRC_PORT_CONNECTED_ERROR, "port connected error: source");
+ graph = create_graph();
+ BT_ASSERT(graph);
+ src = create_src(graph);
+ sink = create_sink(graph);
+ src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
+ "out");
+ BT_ASSERT(src_def_port);
+ sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
+ "in");
+ BT_ASSERT(sink_def_port);
+ status = bt_graph_connect_ports(graph, src_def_port,
+ sink_def_port, &conn);
+ ok(status != BT_GRAPH_CONNECT_PORTS_STATUS_OK,
+ "bt_graph_connect_ports() returns an error");
+ bt_current_thread_clear_error();
+ ok(!conn, "returned connection is still NULL");
+ gsrc = bt_component_source_as_component_const(src);
+ gsink = bt_component_sink_as_component_const(sink);
+ gsrc_def_port = bt_port_output_as_port_const(src_def_port);
+ gsink_def_port = bt_port_input_as_port_const(sink_def_port);
+
+ /* We're supposed to have 3 events */
+ ok(events->len == 3, "we have the expected number of events");
+
+ /* Source's port added */
+ event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
+ event.data.graph_src_output_port_added.comp = gsrc;
+ event.data.graph_src_output_port_added.port = gsrc_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
+
+ /* Sink's port added */
+ event.type = GRAPH_SINK_INPUT_PORT_ADDED;
+ event.data.graph_sink_input_port_added.comp = gsink;
+ event.data.graph_sink_input_port_added.port = gsink_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
+
+ /* Source's port connected */
+ event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
+ event.data.src_comp_output_port_connected.comp = gsrc;
+ event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
+ event.data.src_comp_output_port_connected.other_port = gsink_def_port;
+ ok(has_event(&event), "got the expected source's port connected event");
+
+ bt_graph_put_ref(graph);
+}
+
+static
+void test_sink_port_connected_error(void)
+{
+ const bt_component_source *src;
+ const bt_component_sink *sink;
+ const bt_component *gsrc;
+ const bt_component *gsink;
+ bt_graph *graph;
+ const bt_port_output *src_def_port;
+ const bt_port_input *sink_def_port;
+ const bt_port *gsrc_def_port;
+ const bt_port *gsink_def_port;
+ const bt_connection *conn = NULL;
+ struct event event;
+ bt_graph_connect_ports_status status;
+
+ prepare_test(TEST_SINK_PORT_CONNECTED_ERROR, "port connected error: sink");
+ graph = create_graph();
+ BT_ASSERT(graph);
+ src = create_src(graph);
+ sink = create_sink(graph);
+ src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
+ "out");
+ BT_ASSERT(src_def_port);
+ sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
+ "in");
+ BT_ASSERT(sink_def_port);
+ status = bt_graph_connect_ports(graph, src_def_port,
+ sink_def_port, &conn);
+ ok(status != BT_GRAPH_CONNECT_PORTS_STATUS_OK,
+ "bt_graph_connect_ports() returns an error");
+ bt_current_thread_clear_error();
+ ok(!conn, "returned connection is still NULL");
+ gsrc = bt_component_source_as_component_const(src);
+ gsink = bt_component_sink_as_component_const(sink);
+ gsrc_def_port = bt_port_output_as_port_const(src_def_port);
+ gsink_def_port = bt_port_input_as_port_const(sink_def_port);
+
+ /* We're supposed to have 4 events */
+ ok(events->len == 4, "we have the expected number of events");
+
+ /* Source's port added */
+ event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
+ event.data.graph_src_output_port_added.comp = gsrc;
+ event.data.graph_src_output_port_added.port = gsrc_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
+
+ /* Sink's port added */
+ event.type = GRAPH_SINK_INPUT_PORT_ADDED;
+ event.data.graph_sink_input_port_added.comp = gsink;
+ event.data.graph_sink_input_port_added.port = gsink_def_port;
+ ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
+
+ /* Source's port connected */
+ event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
+ event.data.src_comp_output_port_connected.comp = gsrc;
+ event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
+ event.data.src_comp_output_port_connected.other_port = gsink_def_port;
+ ok(has_event(&event), "got the expected source's port connected event");
+
+ /* Sink's port connected */
+ event.type = SINK_COMP_INPUT_PORT_CONNECTED;
+ event.data.sink_comp_input_port_connected.comp = gsink;
+ event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
+ event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
+ ok(has_event(&event), "got the expected sink's port connected event");
+
+ bt_graph_put_ref(graph);
+}
+
+static
+void test_empty_graph(void)
+{
+ bt_graph *graph;
+
+ prepare_test(TEST_EMPTY_GRAPH, "empty graph");
+ graph = create_graph();
+ ok(events->len == 0, "empty graph generates no events");
+ bt_graph_put_ref(graph);
+}
+
+int main(int argc, char **argv)
+{
+ plan_tests(NR_TESTS);
+ init_test();
+ test_empty_graph();
+ test_simple();
+ test_src_port_connected_error();
+ test_sink_port_connected_error();
+ test_src_adds_port_in_port_connected();
+ fini_test();
+ return exit_status();
+}
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+"${BT_TESTS_BUILDDIR}/lib/plugin" "${BT_TESTS_BUILDDIR}/lib/test-plugin-plugins/.libs"
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2019 Efficios, Inc.
+ */
+
+/*
+ * Test that remove a trace class or trace destruction listener from within
+ * a destruction listener of the same object works.
+ */
+
+#include <babeltrace2/babeltrace.h>
+#include <common/assert.h>
+#include <tap/tap.h>
+#include <stdbool.h>
+
+#define NR_TESTS 16
+
+static bt_listener_id trace_class_destroyed_1_id;
+static bt_listener_id trace_class_destroyed_2_id;
+static bt_listener_id trace_class_destroyed_3_id;
+static bt_listener_id trace_class_destroyed_4_id;
+static bt_listener_id trace_class_destroyed_5_id;
+
+static bt_listener_id trace_destroyed_1_id;
+static bt_listener_id trace_destroyed_2_id;
+static bt_listener_id trace_destroyed_3_id;
+static bt_listener_id trace_destroyed_4_id;
+static bt_listener_id trace_destroyed_5_id;
+
+static bool trace_class_destroyed_1_called = false;
+static bool trace_class_destroyed_2_called = false;
+static bool trace_class_destroyed_3_called = false;
+static bool trace_class_destroyed_4_called = false;
+static bool trace_class_destroyed_5_called = false;
+
+static bool trace_destroyed_1_called = false;
+static bool trace_destroyed_2_called = false;
+static bool trace_destroyed_3_called = false;
+static bool trace_destroyed_4_called = false;
+static bool trace_destroyed_5_called = false;
+
+static
+void trace_class_destroyed_1(const bt_trace_class *tc, void *data)
+{
+ trace_class_destroyed_1_called = true;
+}
+
+static
+void trace_class_destroyed_2(const bt_trace_class *tc, void *data)
+{
+ bt_trace_class_remove_listener_status remove_listener_status;
+
+ trace_class_destroyed_2_called = true;
+
+ /* Remove self. You shall not crash. */
+ remove_listener_status = bt_trace_class_remove_destruction_listener(
+ tc, trace_class_destroyed_2_id);
+ ok(remove_listener_status == BT_TRACE_CLASS_REMOVE_LISTENER_STATUS_OK,
+ "remove trace class listener 2 from 2");
+}
+
+static
+void trace_class_destroyed_3(const bt_trace_class *tc, void *data)
+{
+ bt_trace_class_remove_listener_status remove_listener_status;
+
+ trace_class_destroyed_3_called = true;
+
+ /* Remove an already called listener. */
+ remove_listener_status = bt_trace_class_remove_destruction_listener(
+ tc, trace_class_destroyed_1_id);
+ ok(remove_listener_status == BT_TRACE_CLASS_REMOVE_LISTENER_STATUS_OK,
+ "remove trace class listener 1 from 3");
+}
+
+static
+void trace_class_destroyed_4(const bt_trace_class *tc, void *data)
+{
+ bt_trace_class_remove_listener_status remove_listener_status;
+
+ trace_class_destroyed_4_called = true;
+
+ /* Remove a not yet called listener. */
+ remove_listener_status = bt_trace_class_remove_destruction_listener(
+ tc, trace_class_destroyed_5_id);
+ ok(remove_listener_status == BT_TRACE_CLASS_REMOVE_LISTENER_STATUS_OK,
+ "remove trace class listener 5 from 4");
+}
+
+static
+void trace_class_destroyed_5(const bt_trace_class *tc, void *data)
+{
+ trace_class_destroyed_5_called = true;
+}
+
+static
+void trace_destroyed_1(const bt_trace *t, void *data)
+{
+ trace_destroyed_1_called = true;
+}
+
+static
+void trace_destroyed_2(const bt_trace *t, void *data)
+{
+ bt_trace_remove_listener_status remove_listener_status;
+
+ trace_destroyed_2_called = true;
+
+ /* Remove self. You shall not crash. */
+ remove_listener_status = bt_trace_remove_destruction_listener(
+ t, trace_destroyed_2_id);
+ ok(remove_listener_status == BT_TRACE_REMOVE_LISTENER_STATUS_OK,
+ "remove trace listener 2 from 2");
+}
+
+static
+void trace_destroyed_3(const bt_trace *t, void *data)
+{
+ bt_trace_remove_listener_status remove_listener_status;
+
+ trace_destroyed_3_called = true;
+
+ /* Remove an already called listener. */
+ remove_listener_status = bt_trace_remove_destruction_listener(
+ t, trace_destroyed_1_id);
+ ok(remove_listener_status == BT_TRACE_REMOVE_LISTENER_STATUS_OK,
+ "remove trace listener 1 from 3");
+}
+
+static
+void trace_destroyed_4(const bt_trace *t, void *data)
+{
+ bt_trace_remove_listener_status remove_listener_status;
+
+ trace_destroyed_4_called = true;
+
+ /* Remove a not yet called listener. */
+ remove_listener_status = bt_trace_remove_destruction_listener(
+ t, trace_destroyed_5_id);
+ ok(remove_listener_status == BT_TRACE_REMOVE_LISTENER_STATUS_OK,
+ "remove trace listener 5 from 4");
+}
+
+static
+void trace_destroyed_5(const bt_trace *t, void *data)
+{
+ trace_destroyed_5_called = true;
+}
+
+static
+bt_component_class_initialize_method_status hello_init(
+ bt_self_component_source *self_component,
+ bt_self_component_source_configuration *config,
+ const bt_value *params, void *init_method_data)
+{
+ bt_self_component *self_comp;
+ bt_trace_class *tc;
+ bt_trace *t;
+ bt_trace_class_add_listener_status trace_class_add_listener_status;
+ bt_trace_add_listener_status trace_add_listener_status;
+
+ self_comp = bt_self_component_source_as_self_component(self_component);
+ tc = bt_trace_class_create(self_comp);
+ BT_ASSERT(tc);
+
+ trace_class_add_listener_status = bt_trace_class_add_destruction_listener(
+ tc, trace_class_destroyed_1, NULL, &trace_class_destroyed_1_id);
+ BT_ASSERT(trace_class_add_listener_status == BT_TRACE_CLASS_ADD_LISTENER_STATUS_OK);
+
+ trace_class_add_listener_status = bt_trace_class_add_destruction_listener(
+ tc, trace_class_destroyed_2, NULL, &trace_class_destroyed_2_id);
+ BT_ASSERT(trace_class_add_listener_status == BT_TRACE_CLASS_ADD_LISTENER_STATUS_OK);
+
+ trace_class_add_listener_status = bt_trace_class_add_destruction_listener(
+ tc, trace_class_destroyed_3, NULL, &trace_class_destroyed_3_id);
+ BT_ASSERT(trace_class_add_listener_status == BT_TRACE_CLASS_ADD_LISTENER_STATUS_OK);
+
+ trace_class_add_listener_status = bt_trace_class_add_destruction_listener(
+ tc, trace_class_destroyed_4, NULL, &trace_class_destroyed_4_id);
+ BT_ASSERT(trace_class_add_listener_status == BT_TRACE_CLASS_ADD_LISTENER_STATUS_OK);
+
+ trace_class_add_listener_status = bt_trace_class_add_destruction_listener(
+ tc, trace_class_destroyed_5, NULL, &trace_class_destroyed_5_id);
+ BT_ASSERT(trace_class_add_listener_status == BT_TRACE_CLASS_ADD_LISTENER_STATUS_OK);
+
+ t = bt_trace_create(tc);
+ BT_ASSERT(t);
+
+ trace_add_listener_status = bt_trace_add_destruction_listener(
+ t, trace_destroyed_1, NULL, &trace_destroyed_1_id);
+ BT_ASSERT(trace_add_listener_status == BT_TRACE_ADD_LISTENER_STATUS_OK);
+
+ trace_add_listener_status = bt_trace_add_destruction_listener(
+ t, trace_destroyed_2, NULL, &trace_destroyed_2_id);
+ BT_ASSERT(trace_add_listener_status == BT_TRACE_ADD_LISTENER_STATUS_OK);
+
+ trace_add_listener_status = bt_trace_add_destruction_listener(
+ t, trace_destroyed_3, NULL, &trace_destroyed_3_id);
+ BT_ASSERT(trace_add_listener_status == BT_TRACE_ADD_LISTENER_STATUS_OK);
+
+ trace_add_listener_status = bt_trace_add_destruction_listener(
+ t, trace_destroyed_4, NULL, &trace_destroyed_4_id);
+ BT_ASSERT(trace_add_listener_status == BT_TRACE_ADD_LISTENER_STATUS_OK);
+
+ trace_add_listener_status = bt_trace_add_destruction_listener(
+ t, trace_destroyed_5, NULL, &trace_destroyed_5_id);
+ BT_ASSERT(trace_add_listener_status == BT_TRACE_ADD_LISTENER_STATUS_OK);
+
+ /* Destroy the trace. */
+ bt_trace_put_ref(t);
+
+ ok(trace_destroyed_1_called, "trace destruction listener 1 called");
+ ok(trace_destroyed_2_called, "trace destruction listener 2 called");
+ ok(trace_destroyed_3_called, "trace destruction listener 3 called");
+ ok(trace_destroyed_4_called, "trace destruction listener 4 called");
+ ok(!trace_destroyed_5_called, "trace destruction listener 5 not called");
+
+ /* Destroy the trace class. */
+ bt_trace_class_put_ref(tc);
+
+ ok(trace_class_destroyed_1_called, "trace class destruction listener 1 called");
+ ok(trace_class_destroyed_2_called, "trace class destruction listener 2 called");
+ ok(trace_class_destroyed_3_called, "trace class destruction listener 3 called");
+ ok(trace_class_destroyed_4_called, "trace class destruction listener 4 called");
+ ok(!trace_class_destroyed_5_called, "trace class destruction listener 5 not called");
+
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
+}
+
+static
+bt_message_iterator_class_next_method_status hello_iter_next(
+ bt_self_message_iterator *message_iterator,
+ bt_message_array_const msgs, uint64_t capacity,
+ uint64_t *count)
+{
+ BT_ASSERT(false);
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK;
+}
+
+int main(int argc, char **argv)
+{
+ bt_graph *graph;
+ bt_message_iterator_class *msg_iter_cls;
+ bt_component_class_source *source_cc;
+ bt_component_class_set_method_status set_method_status;
+ bt_graph_add_component_status add_component_status;
+ const bt_component_source *source;
+
+ plan_tests(NR_TESTS);
+
+ msg_iter_cls = bt_message_iterator_class_create(hello_iter_next);
+ BT_ASSERT(msg_iter_cls);
+
+ source_cc = bt_component_class_source_create("Hello", msg_iter_cls);
+ BT_ASSERT(source_cc);
+
+ set_method_status = bt_component_class_source_set_initialize_method(
+ source_cc, hello_init);
+ BT_ASSERT(set_method_status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK);
+
+ graph = bt_graph_create(0);
+ BT_ASSERT(graph);
+
+ add_component_status = bt_graph_add_source_component(
+ graph, source_cc, "name", NULL,
+ BT_LOGGING_LEVEL_WARNING, &source);
+ BT_ASSERT(add_component_status == BT_GRAPH_ADD_COMPONENT_STATUS_OK);
+
+ bt_component_class_source_put_ref(source_cc);
+ bt_message_iterator_class_put_ref(msg_iter_cls);
+ bt_graph_put_ref(graph);
+
+ return exit_status();
+}
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
+ */
+
+#include <babeltrace2/babeltrace.h>
+#include "common/assert.h"
+#include <string.h>
+#include "tap/tap.h"
+
+#define NR_TESTS 68
+
+struct test_data {
+ bt_graph_simple_sink_component_initialize_func_status init_status;
+ bt_graph_simple_sink_component_consume_func_status consume_status;
+};
+
+static
+bt_graph_simple_sink_component_initialize_func_status simple_INITIALIZE_func(
+ bt_message_iterator *iterator,
+ void *data)
+{
+ struct test_data *test_data = data;
+
+ ok(iterator, "Message iterator is not NULL in initialization function");
+ ok(data, "Data is not NULL in initialization function");
+ return test_data->init_status;
+}
+
+static
+bt_graph_simple_sink_component_consume_func_status simple_consume_func(
+ bt_message_iterator *iterator,
+ void *data)
+{
+ struct test_data *test_data = data;
+
+ ok(iterator, "Message iterator is not NULL in consume function");
+ ok(data, "Data is not NULL in consume function");
+ return test_data->consume_status;
+}
+
+static
+void simple_fini_func(void *data)
+{
+ ok(data, "Data is not NULL in finalization function");
+}
+
+static
+bt_component_class_initialize_method_status src_init(
+ bt_self_component_source *self_comp,
+ bt_self_component_source_configuration *config,
+ const bt_value *params, void *init_method_data)
+{
+ bt_self_component_add_port_status status;
+
+ status = bt_self_component_source_add_output_port(self_comp,
+ "out", NULL, NULL);
+ BT_ASSERT(status == BT_SELF_COMPONENT_ADD_PORT_STATUS_OK);
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
+}
+
+static
+bt_message_iterator_class_next_method_status src_iter_next(
+ bt_self_message_iterator *message_iterator,
+ bt_message_array_const msgs, uint64_t capacity,
+ uint64_t *count)
+{
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END;
+}
+
+static
+bt_graph *create_graph_with_source(const bt_port_output **out_port)
+{
+ bt_message_iterator_class *msg_iter_cls;
+ bt_component_class_source *src_comp_cls;
+ bt_graph *graph;
+ const bt_component_source *src_comp = NULL;
+ bt_graph_add_component_status add_comp_status;
+ bt_component_class_set_method_status set_method_status;
+
+ BT_ASSERT(out_port);
+
+ msg_iter_cls = bt_message_iterator_class_create(src_iter_next);
+ BT_ASSERT(msg_iter_cls);
+
+ src_comp_cls = bt_component_class_source_create("src", msg_iter_cls);
+ BT_ASSERT(src_comp_cls);
+ set_method_status = bt_component_class_source_set_initialize_method(
+ src_comp_cls, src_init);
+ BT_ASSERT(set_method_status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK);
+ graph = bt_graph_create(0);
+ BT_ASSERT(graph);
+ add_comp_status = bt_graph_add_source_component(graph, src_comp_cls,
+ "src", NULL, BT_LOGGING_LEVEL_NONE, &src_comp);
+ BT_ASSERT(add_comp_status == BT_GRAPH_ADD_COMPONENT_STATUS_OK);
+ BT_ASSERT(src_comp);
+ *out_port = bt_component_source_borrow_output_port_by_index_const(
+ src_comp, 0);
+ BT_ASSERT(*out_port);
+ bt_component_class_source_put_ref(src_comp_cls);
+ bt_message_iterator_class_put_ref(msg_iter_cls);
+ return graph;
+}
+
+static
+void test_simple_expect_run_once_status(
+ bt_graph_simple_sink_component_initialize_func_status init_status,
+ bt_graph_simple_sink_component_consume_func_status consume_status,
+ bt_graph_run_once_status exp_run_once_status)
+{
+ const bt_port_output *src_out_port = NULL;
+ bt_graph *graph;
+ const bt_component_sink *sink_comp = NULL;
+ const bt_port_input *sink_in_port;
+ bt_graph_add_component_status add_comp_status;
+ bt_graph_run_once_status run_once_status;
+ bt_graph_connect_ports_status connect_status;
+ struct test_data test_data = {
+ .init_status = init_status,
+ .consume_status = consume_status,
+ };
+ const struct bt_error *err;
+
+ graph = create_graph_with_source(&src_out_port);
+ BT_ASSERT(graph);
+ BT_ASSERT(src_out_port);
+
+ add_comp_status = bt_graph_add_simple_sink_component(graph, "sink",
+ simple_INITIALIZE_func, simple_consume_func, simple_fini_func,
+ &test_data, &sink_comp);
+ BT_ASSERT(add_comp_status == BT_GRAPH_ADD_COMPONENT_STATUS_OK);
+ BT_ASSERT(sink_comp);
+
+ sink_in_port = bt_component_sink_borrow_input_port_by_name_const(
+ sink_comp, "in");
+ ok(sink_in_port,
+ "Simple sink component has an input port named \"in\"");
+
+ connect_status = bt_graph_connect_ports(graph, src_out_port,
+ sink_in_port, NULL);
+ ok(connect_status == BT_GRAPH_CONNECT_PORTS_STATUS_OK,
+ "Simple sink component's \"in\" port is connectable");
+
+ run_once_status = bt_graph_run_once(graph);
+ ok(run_once_status == exp_run_once_status,
+ "Graph \"run once\" status is the expected one (status code: %d)",
+ run_once_status);
+
+ err = bt_current_thread_take_error();
+ ok((run_once_status < 0) == (err != NULL),
+ "Current thread error is set if bt_graph_run_once returned an error");
+
+ bt_graph_put_ref(graph);
+ if (err) {
+ bt_error_release(err);
+ }
+}
+
+int main(void)
+{
+ plan_tests(NR_TESTS);
+
+ /* Test initialization function status */
+ test_simple_expect_run_once_status(
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_OK,
+ BT_GRAPH_RUN_ONCE_STATUS_OK);
+ test_simple_expect_run_once_status(
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_ERROR,
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_OK,
+ BT_GRAPH_RUN_ONCE_STATUS_ERROR);
+ test_simple_expect_run_once_status(
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_MEMORY_ERROR,
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_OK,
+ BT_GRAPH_RUN_ONCE_STATUS_MEMORY_ERROR);
+
+ /* Test "consume" function status */
+ test_simple_expect_run_once_status(
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_OK,
+ BT_GRAPH_RUN_ONCE_STATUS_OK);
+ test_simple_expect_run_once_status(
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_ERROR,
+ BT_GRAPH_RUN_ONCE_STATUS_ERROR);
+ test_simple_expect_run_once_status(
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_MEMORY_ERROR,
+ BT_GRAPH_RUN_ONCE_STATUS_MEMORY_ERROR);
+ test_simple_expect_run_once_status(
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_AGAIN,
+ BT_GRAPH_RUN_ONCE_STATUS_AGAIN);
+ test_simple_expect_run_once_status(
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
+ BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_END,
+ BT_GRAPH_RUN_ONCE_STATUS_END);
+
+ return exit_status();
+}
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
+ *
+ * Trace IR Reference Count test
+ */
+
+#include <stdio.h>
+#include "tap/tap.h"
+#include <babeltrace2/babeltrace.h>
+#include "lib/object.h"
+#include "compat/stdlib.h"
+#include "common/assert.h"
+#include <babeltrace2-ctf-writer/writer.h>
+#include <babeltrace2-ctf-writer/clock.h>
+#include <babeltrace2-ctf-writer/clock-class.h>
+#include <babeltrace2-ctf-writer/stream.h>
+#include <babeltrace2-ctf-writer/event.h>
+#include <babeltrace2-ctf-writer/event-types.h>
+#include <babeltrace2-ctf-writer/event-fields.h>
+#include <babeltrace2-ctf-writer/stream-class.h>
+#include <babeltrace2-ctf-writer/trace.h>
+#include "common.h"
+
+#define NR_TESTS 37
+
+struct bt_user {
+ bt_trace_class *tc;
+ bt_stream_class *sc;
+ bt_event_class *ec;
+ bt_stream *stream;
+ bt_event *event;
+};
+
+struct writer_user {
+ struct bt_ctf_writer *writer;
+ struct bt_ctf_trace *tc;
+ struct bt_ctf_stream_class *sc;
+ struct bt_ctf_event_class *ec;
+ struct bt_ctf_stream *stream;
+ struct bt_ctf_event *event;
+};
+
+const char *writer_user_names[] = {
+ "writer",
+ "trace",
+ "stream class",
+ "event class",
+ "stream",
+ "event",
+};
+
+static const size_t WRITER_USER_NR_ELEMENTS =
+ sizeof(struct writer_user) / sizeof(void *);
+
+/**
+ * Returns a structure containing the following fields:
+ * - uint8_t payload_8;
+ * - uint16_t payload_16;
+ * - uint32_t payload_32;
+ */
+static bt_field_class *create_integer_struct(bt_trace_class *trace_class)
+{
+ int ret;
+ bt_field_class *structure = NULL;
+ bt_field_class *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
+
+ structure = bt_field_class_structure_create(trace_class);
+ BT_ASSERT(structure);
+ ui8 = bt_field_class_integer_unsigned_create(trace_class);
+ BT_ASSERT(ui8);
+ bt_field_class_integer_set_field_value_range(ui8, 8);
+ ret = bt_field_class_structure_append_member(structure,
+ "payload_8", ui8);
+ BT_ASSERT(ret == 0);
+ ui16 = bt_field_class_integer_unsigned_create(trace_class);
+ BT_ASSERT(ui16);
+ bt_field_class_integer_set_field_value_range(ui16, 16);
+ ret = bt_field_class_structure_append_member(structure,
+ "payload_16", ui16);
+ BT_ASSERT(ret == 0);
+ ui32 = bt_field_class_integer_unsigned_create(trace_class);
+ BT_ASSERT(ui32);
+ bt_field_class_integer_set_field_value_range(ui32, 32);
+ ret = bt_field_class_structure_append_member(structure,
+ "payload_32", ui32);
+ BT_ASSERT(ret == 0);
+ BT_FIELD_CLASS_PUT_REF_AND_RESET(ui8);
+ BT_FIELD_CLASS_PUT_REF_AND_RESET(ui16);
+ BT_FIELD_CLASS_PUT_REF_AND_RESET(ui32);
+ return structure;
+}
+
+static struct bt_ctf_field_type *create_writer_integer_struct(void)
+{
+ int ret;
+ struct bt_ctf_field_type *structure = NULL;
+ struct bt_ctf_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
+
+ structure = bt_ctf_field_type_structure_create();
+ BT_ASSERT(structure);
+ ui8 = bt_ctf_field_type_integer_create(8);
+ BT_ASSERT(ui8);
+ ret = bt_ctf_field_type_structure_add_field(structure, ui8,
+ "payload_8");
+ BT_ASSERT(ret == 0);
+ ui16 = bt_ctf_field_type_integer_create(16);
+ BT_ASSERT(ui16);
+ ret = bt_ctf_field_type_structure_add_field(structure, ui16,
+ "payload_16");
+ BT_ASSERT(ret == 0);
+ ui32 = bt_ctf_field_type_integer_create(32);
+ BT_ASSERT(ui32);
+ ret = bt_ctf_field_type_structure_add_field(structure, ui32,
+ "payload_32");
+ BT_ASSERT(ret == 0);
+ BT_OBJECT_PUT_REF_AND_RESET(ui8);
+ BT_OBJECT_PUT_REF_AND_RESET(ui16);
+ BT_OBJECT_PUT_REF_AND_RESET(ui32);
+ return structure;
+}
+
+/**
+ * A simple event has the following payload:
+ * - uint8_t payload_8;
+ * - uint16_t payload_16;
+ * - uint32_t payload_32;
+ */
+static bt_event_class *create_simple_event(
+ bt_stream_class *sc, const char *name)
+{
+ int ret;
+ bt_event_class *event = NULL;
+ bt_field_class *payload = NULL;
+
+ BT_ASSERT(name);
+ event = bt_event_class_create(sc);
+ BT_ASSERT(event);
+ ret = bt_event_class_set_name(event, name);
+ BT_ASSERT(ret == 0);
+ payload = create_integer_struct(bt_stream_class_borrow_trace_class(sc));
+ BT_ASSERT(payload);
+ ret = bt_event_class_set_payload_field_class(event, payload);
+ BT_ASSERT(ret == 0);
+ BT_FIELD_CLASS_PUT_REF_AND_RESET(payload);
+ return event;
+}
+
+/**
+ * A complex event has the following payload:
+ * - uint8_t payload_8;
+ * - uint16_t payload_16;
+ * - uint32_t payload_32;
+ * - struct payload_struct:
+ * - uint8_t payload_8;
+ * - uint16_t payload_16;
+ * - uint32_t payload_32;
+ */
+static bt_event_class *create_complex_event(bt_stream_class *sc,
+ const char *name)
+{
+ int ret;
+ bt_event_class *event = NULL;
+ bt_field_class *inner = NULL, *outer = NULL;
+ bt_trace_class *trace_class = bt_stream_class_borrow_trace_class(sc);
+
+ BT_ASSERT(name);
+ event = bt_event_class_create(sc);
+ BT_ASSERT(event);
+ ret = bt_event_class_set_name(event, name);
+ BT_ASSERT(ret == 0);
+ outer = create_integer_struct(trace_class);
+ BT_ASSERT(outer);
+ inner = create_integer_struct(trace_class);
+ BT_ASSERT(inner);
+ ret = bt_field_class_structure_append_member(outer,
+ "payload_struct", inner);
+ BT_ASSERT(ret == 0);
+ ret = bt_event_class_set_payload_field_class(event, outer);
+ BT_ASSERT(ret == 0);
+ BT_FIELD_CLASS_PUT_REF_AND_RESET(inner);
+ BT_FIELD_CLASS_PUT_REF_AND_RESET(outer);
+ return event;
+}
+
+static void create_sc1(bt_trace_class *trace_class)
+{
+ int ret;
+ bt_event_class *ec1 = NULL, *ec2 = NULL;
+ bt_stream_class *sc1 = NULL, *ret_stream = NULL;
+
+ sc1 = bt_stream_class_create(trace_class);
+ BT_ASSERT(sc1);
+ ret = bt_stream_class_set_name(sc1, "sc1");
+ BT_ASSERT(ret == 0);
+ ec1 = create_complex_event(sc1, "ec1");
+ BT_ASSERT(ec1);
+ ec2 = create_simple_event(sc1, "ec2");
+ BT_ASSERT(ec2);
+ ret_stream = bt_event_class_borrow_stream_class(ec1);
+ ok(ret_stream == sc1, "Borrow parent stream SC1 from EC1");
+ ret_stream = bt_event_class_borrow_stream_class(ec2);
+ ok(ret_stream == sc1, "Borrow parent stream SC1 from EC2");
+ BT_EVENT_CLASS_PUT_REF_AND_RESET(ec1);
+ BT_EVENT_CLASS_PUT_REF_AND_RESET(ec2);
+ BT_STREAM_CLASS_PUT_REF_AND_RESET(sc1);
+}
+
+static void create_sc2(bt_trace_class *trace_class)
+{
+ int ret;
+ bt_event_class *ec3 = NULL;
+ bt_stream_class *sc2 = NULL, *ret_stream = NULL;
+
+ sc2 = bt_stream_class_create(trace_class);
+ BT_ASSERT(sc2);
+ ret = bt_stream_class_set_name(sc2, "sc2");
+ BT_ASSERT(ret == 0);
+ ec3 = create_simple_event(sc2, "ec3");
+ ret_stream = bt_event_class_borrow_stream_class(ec3);
+ ok(ret_stream == sc2, "Borrow parent stream SC2 from EC3");
+ BT_EVENT_CLASS_PUT_REF_AND_RESET(ec3);
+ BT_STREAM_CLASS_PUT_REF_AND_RESET(sc2);
+}
+
+static bt_trace_class *create_tc1(bt_self_component_source *self_comp)
+{
+ bt_trace_class *tc1 = NULL;
+
+ tc1 = bt_trace_class_create(
+ bt_self_component_source_as_self_component(self_comp));
+ BT_ASSERT(tc1);
+ create_sc1(tc1);
+ create_sc2(tc1);
+ return tc1;
+}
+
+static void init_weak_refs(bt_trace_class *tc,
+ bt_trace_class **tc1,
+ bt_stream_class **sc1,
+ bt_stream_class **sc2,
+ bt_event_class **ec1,
+ bt_event_class **ec2,
+ bt_event_class **ec3)
+{
+ *tc1 = tc;
+ *sc1 = bt_trace_class_borrow_stream_class_by_index(tc, 0);
+ *sc2 = bt_trace_class_borrow_stream_class_by_index(tc, 1);
+ *ec1 = bt_stream_class_borrow_event_class_by_index(*sc1, 0);
+ *ec2 = bt_stream_class_borrow_event_class_by_index(*sc1, 1);
+ *ec3 = bt_stream_class_borrow_event_class_by_index(*sc2, 0);
+}
+
+static void test_example_scenario(bt_self_component_source *self_comp)
+{
+ /*
+ * Weak pointers to trace IR objects are to be used very
+ * carefully. This is NOT a good practice and is strongly
+ * discouraged; this is only done to facilitate the validation
+ * of expected reference counts without affecting them by taking
+ * "real" references to the objects.
+ */
+ bt_trace_class *tc1 = NULL, *weak_tc1 = NULL;
+ bt_stream_class *weak_sc1 = NULL, *weak_sc2 = NULL;
+ bt_event_class *weak_ec1 = NULL, *weak_ec2 = NULL,
+ *weak_ec3 = NULL;
+ struct bt_user user_a = { 0 }, user_b = { 0 }, user_c = { 0 };
+
+ /* The only reference which exists at this point is on TC1. */
+ tc1 = create_tc1(self_comp);
+ ok(tc1, "Initialize trace");
+ BT_ASSERT(tc1);
+ init_weak_refs(tc1, &weak_tc1, &weak_sc1, &weak_sc2, &weak_ec1,
+ &weak_ec2, &weak_ec3);
+ ok(bt_object_get_ref_count((void *) weak_sc1) == 0,
+ "Initial SC1 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
+ "Initial SC2 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_ec1) == 0,
+ "Initial EC1 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
+ "Initial EC2 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
+ "Initial EC3 reference count is 0");
+
+ /* User A has ownership of the trace. */
+ BT_OBJECT_MOVE_REF(user_a.tc, tc1);
+ ok(bt_object_get_ref_count((void *) user_a.tc) == 1,
+ "TC1 reference count is 1");
+
+ /* User A acquires a reference to SC2 from TC1. */
+ user_a.sc = bt_trace_class_borrow_stream_class_by_index(
+ user_a.tc, 1);
+ bt_stream_class_get_ref(user_a.sc);
+ ok(user_a.sc, "User A acquires SC2 from TC1");
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+ "TC1 reference count is 2");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
+ "SC2 reference count is 1");
+
+ /* User A acquires a reference to EC3 from SC2. */
+ user_a.ec = bt_stream_class_borrow_event_class_by_index(
+ user_a.sc, 0);
+ bt_event_class_get_ref(user_a.ec);
+ ok(user_a.ec, "User A acquires EC3 from SC2");
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+ "TC1 reference count is 2");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 2,
+ "SC2 reference count is 2");
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
+ "EC3 reference count is 1");
+
+ /* User A releases its reference to SC2. */
+ diag("User A releases SC2");
+ BT_STREAM_CLASS_PUT_REF_AND_RESET(user_a.sc);
+ /*
+ * We keep the pointer to SC2 around to validate its reference
+ * count.
+ */
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+ "TC1 reference count is 2");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
+ "SC2 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
+ "EC3 reference count is 1");
+
+ /* User A releases its reference to TC1. */
+ diag("User A releases TC1");
+ BT_TRACE_CLASS_PUT_REF_AND_RESET(user_a.tc);
+ /*
+ * We keep the pointer to TC1 around to validate its reference
+ * count.
+ */
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
+ "TC1 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
+ "SC2 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
+ "EC3 reference count is 1");
+
+ /* User B acquires a reference to SC1. */
+ diag("User B acquires a reference to SC1");
+ user_b.sc = weak_sc1;
+ bt_stream_class_get_ref(user_b.sc);
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
+ "TC1 reference count is 2");
+ ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
+ "SC1 reference count is 1");
+
+ /* User C acquires a reference to EC1. */
+ diag("User C acquires a reference to EC1");
+ user_c.ec = bt_stream_class_borrow_event_class_by_index(
+ user_b.sc, 0);
+ bt_event_class_get_ref(user_c.ec);
+ ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
+ "EC1 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_sc1) == 2,
+ "SC1 reference count is 2");
+
+ /* User A releases its reference on EC3. */
+ diag("User A releases its reference on EC3");
+ BT_EVENT_CLASS_PUT_REF_AND_RESET(user_a.ec);
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
+ "EC3 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
+ "SC2 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
+ "TC1 reference count is 1");
+
+ /* User B releases its reference on SC1. */
+ diag("User B releases its reference on SC1");
+ BT_STREAM_CLASS_PUT_REF_AND_RESET(user_b.sc);
+ ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
+ "SC1 reference count is 1");
+
+ /*
+ * User C is the sole owner of an object and is keeping the whole
+ * trace hierarchy "alive" by holding a reference to EC1.
+ */
+ ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
+ "TC1 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
+ "SC1 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
+ "SC2 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
+ "EC1 reference count is 1");
+ ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
+ "EC2 reference count is 0");
+ ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
+ "EC3 reference count is 0");
+
+ /* Reclaim last reference held by User C. */
+ BT_EVENT_CLASS_PUT_REF_AND_RESET(user_c.ec);
+}
+
+static
+bt_component_class_initialize_method_status src_init(
+ bt_self_component_source *self_comp,
+ bt_self_component_source_configuration *config,
+ const bt_value *params, void *init_method_data)
+{
+ test_example_scenario(self_comp);
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
+}
+
+static
+bt_message_iterator_class_next_method_status src_iter_next(
+ bt_self_message_iterator *self_iterator,
+ bt_message_array_const msgs, uint64_t capacity,
+ uint64_t *count)
+{
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
+}
+
+static void test_example_scenario_in_graph(void)
+{
+ bt_message_iterator_class *msg_iter_cls;
+ bt_component_class_source *comp_cls;
+ bt_graph *graph;
+ int ret;
+
+ msg_iter_cls = bt_message_iterator_class_create(src_iter_next);
+ BT_ASSERT(msg_iter_cls);
+
+ comp_cls = bt_component_class_source_create("src", msg_iter_cls);
+ BT_ASSERT(comp_cls);
+ ret = bt_component_class_source_set_initialize_method(comp_cls, src_init);
+ BT_ASSERT(ret == 0);
+ graph = bt_graph_create(0);
+ ret = bt_graph_add_source_component(graph, comp_cls, "src-comp",
+ NULL, BT_LOGGING_LEVEL_NONE, NULL);
+ BT_ASSERT(ret == 0);
+ bt_graph_put_ref(graph);
+ bt_component_class_source_put_ref(comp_cls);
+ bt_message_iterator_class_put_ref(msg_iter_cls);
+}
+
+static void create_writer_user_full(struct writer_user *user)
+{
+ gchar *trace_path;
+ struct bt_ctf_field_type *ft;
+ struct bt_ctf_field *field;
+ struct bt_ctf_clock *clock;
+ int ret;
+
+ trace_path = g_build_filename(g_get_tmp_dir(), "ctfwriter_XXXXXX", NULL);
+ if (!bt_mkdtemp(trace_path)) {
+ perror("# perror");
+ }
+
+ user->writer = bt_ctf_writer_create(trace_path);
+ BT_ASSERT(user->writer);
+ ret = bt_ctf_writer_set_byte_order(user->writer,
+ BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
+ BT_ASSERT(ret == 0);
+ user->tc = bt_ctf_writer_get_trace(user->writer);
+ BT_ASSERT(user->tc);
+ user->sc = bt_ctf_stream_class_create("sc");
+ BT_ASSERT(user->sc);
+ clock = bt_ctf_clock_create("the_clock");
+ BT_ASSERT(clock);
+ ret = bt_ctf_writer_add_clock(user->writer, clock);
+ BT_ASSERT(!ret);
+ ret = bt_ctf_stream_class_set_clock(user->sc, clock);
+ BT_ASSERT(!ret);
+ BT_OBJECT_PUT_REF_AND_RESET(clock);
+ user->stream = bt_ctf_writer_create_stream(user->writer, user->sc);
+ BT_ASSERT(user->stream);
+ user->ec = bt_ctf_event_class_create("ec");
+ BT_ASSERT(user->ec);
+ ft = create_writer_integer_struct();
+ BT_ASSERT(ft);
+ ret = bt_ctf_event_class_set_payload_field_type(user->ec, ft);
+ BT_OBJECT_PUT_REF_AND_RESET(ft);
+ BT_ASSERT(!ret);
+ ret = bt_ctf_stream_class_add_event_class(user->sc, user->ec);
+ BT_ASSERT(!ret);
+ user->event = bt_ctf_event_create(user->ec);
+ BT_ASSERT(user->event);
+ field = bt_ctf_event_get_payload(user->event, "payload_8");
+ BT_ASSERT(field);
+ ret = bt_ctf_field_integer_unsigned_set_value(field, 10);
+ BT_ASSERT(!ret);
+ BT_OBJECT_PUT_REF_AND_RESET(field);
+ field = bt_ctf_event_get_payload(user->event, "payload_16");
+ BT_ASSERT(field);
+ ret = bt_ctf_field_integer_unsigned_set_value(field, 20);
+ BT_ASSERT(!ret);
+ BT_OBJECT_PUT_REF_AND_RESET(field);
+ field = bt_ctf_event_get_payload(user->event, "payload_32");
+ BT_ASSERT(field);
+ ret = bt_ctf_field_integer_unsigned_set_value(field, 30);
+ BT_ASSERT(!ret);
+ BT_OBJECT_PUT_REF_AND_RESET(field);
+ ret = bt_ctf_stream_append_event(user->stream, user->event);
+ BT_ASSERT(!ret);
+ recursive_rmdir(trace_path);
+ g_free(trace_path);
+}
+
+static void test_put_order_swap(size_t *array, size_t a, size_t b)
+{
+ size_t temp = array[a];
+
+ array[a] = array[b];
+ array[b] = temp;
+}
+
+static void test_put_order_put_objects(size_t *array, size_t size)
+{
+ size_t i;
+ struct writer_user user = { 0 };
+ void **objects = (void *) &user;
+
+ create_writer_user_full(&user);
+ printf("# ");
+
+ for (i = 0; i < size; ++i) {
+ void *obj = objects[array[i]];
+
+ printf("%s", writer_user_names[array[i]]);
+ BT_OBJECT_PUT_REF_AND_RESET(obj);
+
+ if (i < size - 1) {
+ printf(" -> ");
+ }
+ }
+
+ puts("");
+}
+
+static void test_put_order_permute(size_t *array, int k, size_t size)
+{
+ if (k == 0) {
+ test_put_order_put_objects(array, size);
+ } else {
+ int i;
+
+ for (i = k - 1; i >= 0; i--) {
+ size_t next_k = k - 1;
+
+ test_put_order_swap(array, i, next_k);
+ test_put_order_permute(array, next_k, size);
+ test_put_order_swap(array, i, next_k);
+ }
+ }
+}
+
+static void test_put_order(void)
+{
+ size_t i;
+ size_t array[WRITER_USER_NR_ELEMENTS];
+
+ /* Initialize array of indexes */
+ for (i = 0; i < WRITER_USER_NR_ELEMENTS; ++i) {
+ array[i] = i;
+ }
+
+ test_put_order_permute(array, WRITER_USER_NR_ELEMENTS,
+ WRITER_USER_NR_ELEMENTS);
+}
+
+/**
+ * The objective of this test is to implement and expand upon the scenario
+ * described in the reference counting documentation and ensure that any node of
+ * the Trace, Stream Class, Event Class, Stream and Event hiearchy keeps all
+ * other "alive" and reachable.
+ *
+ * External tools (e.g. valgrind) should be used to confirm that this
+ * known-good test does not leak memory.
+ */
+int main(int argc, char **argv)
+{
+ /* Initialize tap harness before any tests */
+ plan_tests(NR_TESTS);
+
+ test_example_scenario_in_graph();
+ test_put_order();
+
+ return exit_status();
+}
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include <tap/tap.h>
-
-#include "common/uuid.h"
-
-#define NR_TESTS 23
-
-static const char valid_str_1[] = "3d260c88-75ea-47b8-a7e2-d6077c0378d9";
-static const char valid_str_2[] = "611cf3a6-a68b-4515-834f-208bc2762592";
-static const char valid_str_3[] = "1b4855cc-96de-4ae8-abe3-86449c2a43c4";
-static const char valid_str_4[] = "8ADED5B9-ACD2-439F-A60C-897403AA2AB4";
-static const char valid_str_5[] = "f109e0a2-C619-4d18-b760-20EA20E0F69A";
-
-static bt_uuid_t valid_uuid_1 = {
- 0x3d, 0x26, 0x0c, 0x88, 0x75, 0xea, 0x47, 0xb8,
- 0xa7, 0xe2, 0xd6, 0x07, 0x7c, 0x03, 0x78, 0xd9
-};
-static bt_uuid_t valid_uuid_2 = {
- 0x61, 0x1c, 0xf3, 0xa6, 0xa6, 0x8b, 0x45, 0x15,
- 0x83, 0x4f, 0x20, 0x8b, 0xc2, 0x76, 0x25, 0x92
-};
-static bt_uuid_t valid_uuid_3 = {
- 0x1b, 0x48, 0x55, 0xcc, 0x96, 0xde, 0x4a, 0xe8,
- 0xab, 0xe3, 0x86, 0x44, 0x9c, 0x2a, 0x43, 0xc4
-};
-
-static const char invalid_str_1[] = "1b485!cc-96de-4XX8-abe3-86449c2a43?4";
-static const char invalid_str_2[] = "c2e6eddb&3955&4006&be3a&70bb63bd5f25";
-static const char invalid_str_3[] = "81b1cb88-ff42-45b9-ba4d-964088ee45";
-static const char invalid_str_4[] = "2d-6c6d756574-470e-9142-a4e6ad03f143";
-static const char invalid_str_5[] = "4542ad19-9e4f-4931-8261-2101c3e089ae7";
-static const char invalid_str_6[] = "XX0123";
-
-static
-void run_test_bt_uuid_from_str(void)
-{
- int ret;
- bt_uuid_t uuid1;
-
- /*
- * Parse valid UUID strings, expect success.
- */
- ret = bt_uuid_from_str(valid_str_1, uuid1);
- ok(ret == 0, "bt_uuid_from_str - Parse valid string '%s', expect success", valid_str_1);
-
- ret = bt_uuid_from_str(valid_str_2, uuid1);
- ok(ret == 0, "bt_uuid_from_str - Parse valid string '%s', expect success", valid_str_2);
-
- ret = bt_uuid_from_str(valid_str_3, uuid1);
- ok(ret == 0, "bt_uuid_from_str - Parse valid string '%s', expect success", valid_str_3);
-
- ret = bt_uuid_from_str(valid_str_4, uuid1);
- ok(ret == 0, "bt_uuid_from_str - Parse valid string '%s', expect success", valid_str_4);
-
- ret = bt_uuid_from_str(valid_str_5, uuid1);
- ok(ret == 0, "bt_uuid_from_str - Parse valid string '%s', expect success", valid_str_5);
-
- /*
- * Parse invalid UUID strings, expect failure.
- */
- ret = bt_uuid_from_str(invalid_str_1, uuid1);
- ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_1);
-
- ret = bt_uuid_from_str(invalid_str_2, uuid1);
- ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_2);
-
- ret = bt_uuid_from_str(invalid_str_3, uuid1);
- ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_3);
-
- ret = bt_uuid_from_str(invalid_str_4, uuid1);
- ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_4);
-
- ret = bt_uuid_from_str(invalid_str_5, uuid1);
- ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_5);
-
- ret = bt_uuid_from_str(invalid_str_6, uuid1);
- ok(ret != 0, "bt_uuid_from_str - Parse invalid string '%s', expect failure", invalid_str_6);
-}
-
-static
-void run_test_bt_uuid_to_str(void)
-{
- char uuid_str[BT_UUID_STR_LEN + 1];
-
- bt_uuid_to_str(valid_uuid_1, uuid_str);
- ok(strcmp(uuid_str, valid_str_1) == 0, "bt_uuid_to_str - Convert UUID '%s' to string, expect success", valid_str_1);
-
- bt_uuid_to_str(valid_uuid_2, uuid_str);
- ok(strcmp(uuid_str, valid_str_2) == 0, "bt_uuid_to_str - Convert UUID '%s' to string, expect success", valid_str_2);
-
- bt_uuid_to_str(valid_uuid_3, uuid_str);
- ok(strcmp(uuid_str, valid_str_3) == 0, "bt_uuid_to_str - Convert UUID '%s' to string, expect success", valid_str_3);
-}
-
-static
-void run_test_bt_uuid_compare(void)
-{
- int ret;
- bt_uuid_t uuid1, uuid2;
-
- bt_uuid_from_str(valid_str_1, uuid1);
- bt_uuid_from_str(valid_str_1, uuid2);
- ret = bt_uuid_compare(uuid1, uuid2);
- ok(ret == 0, "bt_uuid_compare - Compare same UUID, expect success");
-
- bt_uuid_from_str(valid_str_2, uuid2);
- ret = bt_uuid_compare(uuid1, uuid2);
- ok(ret != 0, "bt_uuid_compare - Compare different UUID, expect failure");
- ok(ret < 0, "bt_uuid_compare - Compare different UUID, expect uuid1 smaller");
- ret = bt_uuid_compare(uuid2, uuid1);
- ok(ret > 0, "bt_uuid_compare - Compare different UUID, expect uuid2 bigger");
-}
-
-static
-void run_test_bt_uuid_copy(void)
-{
- int ret;
- bt_uuid_t uuid1;
-
- bt_uuid_copy(uuid1, valid_uuid_1);
- ret = bt_uuid_compare(uuid1, valid_uuid_1);
-
- ok(ret == 0, "bt_uuid_copy - Compare copied UUID with source, expect success");
-}
-
-static
-void run_test_bt_uuid_generate(void)
-{
- int ret;
- bt_uuid_t uuid1, uuid2;
-
- bt_uuid_generate(uuid1);
- bt_uuid_generate(uuid2);
-
- ok(bt_uuid_compare(uuid1, uuid2) != 0, "bt_uuid_generate - Generated UUIDs are different");
-
- /*
- * Set the two most significant bits (bits 6 and 7) of the
- * clock_seq_hi_and_reserved to zero and one, respectively.
- */
- ret = uuid1[8] & (1 << 6);
- ok(ret == 0, "bt_uuid_generate - bit 6 of clock_seq_hi_and_reserved is set to zero");
-
- ret = uuid1[8] & (1 << 7);
- ok(ret != 0, "bt_uuid_generate - bit 7 of clock_seq_hi_and_reserved is set to one");
-
- /*
- * Set the four most significant bits (bits 12 through 15) of the
- * time_hi_and_version field to the 4-bit version number from
- * Section 4.1.3.
- */
- ret = uuid1[6] >> 4;
- ok(ret == BT_UUID_VER, "bt_uuid_generate - Generated UUID version check");
-}
-
-static
-void run_test(void)
-{
- plan_tests(NR_TESTS);
-
- run_test_bt_uuid_from_str();
- run_test_bt_uuid_to_str();
- run_test_bt_uuid_compare();
- run_test_bt_uuid_copy();
- run_test_bt_uuid_generate();
-}
-
-int main(int argc, char **argv)
-{
- /* Run tap-formated tests */
- run_test();
-
- return exit_status();
-}
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation
- * Copyright (C) 2015 Philippe Proulx <pproulx@efficios.com>
- *
- * Babeltrace value objects tests
- */
-
-#include <babeltrace2/babeltrace.h>
-#include "common/assert.h"
-#include <string.h>
-#include "tap/tap.h"
-
-#define NR_TESTS 190
-
-static
-void test_null(void)
-{
- ok(bt_value_null, "bt_value_null is not NULL");
- ok(bt_value_is_null(bt_value_null),
- "bt_value_null is a null value object");
- bt_value_get_ref(bt_value_null);
- pass("getting bt_value_null does not cause a crash");
- bt_value_put_ref(bt_value_null);
- pass("putting bt_value_null does not cause a crash");
-}
-
-static
-void test_bool(void)
-{
- bt_bool value;
- bt_value *obj;
-
- obj = bt_value_bool_create();
- ok(obj && bt_value_is_bool(obj),
- "bt_value_bool_create() returns a boolean value object");
-
- value = BT_TRUE;
- value = bt_value_bool_get(obj);
- ok(!value, "default boolean value object value is BT_FALSE");
-
- bt_value_bool_set(obj, BT_FALSE);
- bt_value_bool_set(obj, BT_TRUE);
- value = bt_value_bool_get(obj);
- ok(value, "bt_value_bool_set() works");
-
- BT_VALUE_PUT_REF_AND_RESET(obj);
- pass("putting an existing boolean value object does not cause a crash")
-
- value = BT_FALSE;
- obj = bt_value_bool_create_init(BT_TRUE);
- ok(obj && bt_value_is_bool(obj),
- "bt_value_bool_create_init() returns a boolean value object");
- value = bt_value_bool_get(obj);
- ok(value,
- "bt_value_bool_create_init() sets the appropriate initial value");
-
- BT_VALUE_PUT_REF_AND_RESET(obj);
-}
-
-static
-void test_unsigned_integer(void)
-{
- uint64_t value;
- bt_value *obj;
-
- obj = bt_value_integer_unsigned_create();
- ok(obj && bt_value_is_unsigned_integer(obj),
- "bt_value_integer_unsigned_create() returns an unsigned integer value object");
-
- value = 1961;
- value = bt_value_integer_unsigned_get(obj);
- ok(value == 0, "default unsigned integer value object value is 0");
-
- bt_value_integer_unsigned_set(obj, 98765);
- value = bt_value_integer_unsigned_get(obj);
- ok(value == 98765, "bt_value_integer_unsigned_bool_set() works");
-
- BT_VALUE_PUT_REF_AND_RESET(obj);
- pass("putting an existing unsigned integer value object does not cause a crash")
-
- obj = bt_value_integer_unsigned_create_init(321456987);
- ok(obj && bt_value_is_unsigned_integer(obj),
- "bt_value_integer_unsigned_create_init() returns an unsigned integer value object");
- value = bt_value_integer_unsigned_get(obj);
- ok(value == 321456987,
- "bt_value_integer_unsigned_create_init() sets the appropriate initial value");
-
- BT_VALUE_PUT_REF_AND_RESET(obj);
-}
-
-static
-void test_signed_integer(void)
-{
- int64_t value;
- bt_value *obj;
-
- obj = bt_value_integer_signed_create();
- ok(obj && bt_value_is_signed_integer(obj),
- "bt_value_integer_signed_create() returns a signed integer value object");
-
- value = 1961;
- value = bt_value_integer_signed_get(obj);
- ok(value == 0, "default signed integer value object value is 0");
-
- bt_value_integer_signed_set(obj, 98765);
- value = bt_value_integer_signed_get(obj);
- ok(value == 98765, "bt_value_integer_signed_bool_set() works");
-
- BT_VALUE_PUT_REF_AND_RESET(obj);
- pass("putting an existing signed integer value object does not cause a crash")
-
- obj = bt_value_integer_signed_create_init(-321456987);
- ok(obj && bt_value_is_signed_integer(obj),
- "bt_value_integer_signed_create_init() returns a signed integer value object");
- value = bt_value_integer_signed_get(obj);
- ok(value == -321456987,
- "bt_value_integer_signed_create_init() sets the appropriate initial value");
-
- BT_VALUE_PUT_REF_AND_RESET(obj);
-}
-
-static
-void test_real(void)
-{
- double value;
- bt_value *obj;
-
- obj = bt_value_real_create();
- ok(obj && bt_value_is_real(obj),
- "bt_value_real_create() returns a real number value object");
-
- value = 17.34;
- value = bt_value_real_get(obj);
- ok(value == 0.,
- "default real number value object value is 0");
-
- bt_value_real_set(obj, -3.1416);
- value = bt_value_real_get(obj);
- ok(value == -3.1416, "bt_value_real_set() works");
-
- BT_VALUE_PUT_REF_AND_RESET(obj);
- pass("putting an existing real number value object does not cause a crash")
-
- obj = bt_value_real_create_init(33.1649758);
- ok(obj && bt_value_is_real(obj),
- "bt_value_real_create_init() returns a real number value object");
- value = bt_value_real_get(obj);
- ok(value == 33.1649758,
- "bt_value_real_create_init() sets the appropriate initial value");
-
- BT_VALUE_PUT_REF_AND_RESET(obj);
-}
-
-static
-void test_string(void)
-{
- const char *value;
- bt_value *obj;
-
- obj = bt_value_string_create();
- ok(obj && bt_value_is_string(obj),
- "bt_value_string_create() returns a string value object");
-
- value = bt_value_string_get(obj);
- ok(value && strcmp(value, "") == 0,
- "default string value object value is \"\"");
-
- bt_value_string_set(obj, "hello worldz");
- value = bt_value_string_get(obj);
- ok(value && strcmp(value, "hello worldz") == 0,
- "bt_value_string_get() works");
-
- BT_VALUE_PUT_REF_AND_RESET(obj);
- pass("putting an existing string value object does not cause a crash")
-
- obj = bt_value_string_create_init("initial value");
- ok(obj && bt_value_is_string(obj),
- "bt_value_string_create_init() returns a string value object");
- value = bt_value_string_get(obj);
- ok(value && strcmp(value, "initial value") == 0,
- "bt_value_string_create_init() sets the appropriate initial value");
-
- BT_VALUE_PUT_REF_AND_RESET(obj);
-}
-
-static
-void test_array(void)
-{
- int ret;
- bt_bool bool_value;
- int64_t int_value;
- double real_value;
- bt_value *obj;
- const char *string_value;
- bt_value *array_obj;
- bt_value *appended_obj;
-
- array_obj = bt_value_array_create();
- ok(array_obj && bt_value_is_array(array_obj),
- "bt_value_array_create() returns an array value object");
- ok(bt_value_array_is_empty(array_obj),
- "initial array value object size is 0");
-
- obj = bt_value_integer_unsigned_create_init(345);
- ret = bt_value_array_append_element(array_obj, obj);
- BT_VALUE_PUT_REF_AND_RESET(obj);
- obj = bt_value_integer_signed_create_init(-507);
- ret |= bt_value_array_append_element(array_obj, obj);
- BT_VALUE_PUT_REF_AND_RESET(obj);
- obj = bt_value_real_create_init(-17.45);
- ret |= bt_value_array_append_element(array_obj, obj);
- BT_VALUE_PUT_REF_AND_RESET(obj);
- obj = bt_value_bool_create_init(BT_TRUE);
- ret |= bt_value_array_append_element(array_obj, obj);
- BT_VALUE_PUT_REF_AND_RESET(obj);
- ret |= bt_value_array_append_element(array_obj,
- bt_value_null);
- ok(!ret, "bt_value_array_append_element() succeeds");
- ok(bt_value_array_get_length(array_obj) == 5,
- "appending an element to an array value object increment its size");
-
- obj = bt_value_array_borrow_element_by_index(array_obj, 0);
- ok(bt_value_is_unsigned_integer(obj),
- "bt_value_array_borrow_element_by_index() returns an value object with the appropriate type (unsigned integer)");
- int_value = bt_value_integer_unsigned_get(obj);
- ok(int_value == 345,
- "bt_value_array_borrow_element_by_index() returns an value object with the appropriate value (unsigned integer)");
- obj = bt_value_array_borrow_element_by_index(array_obj, 1);
- ok(bt_value_is_signed_integer(obj),
- "bt_value_array_borrow_element_by_index() returns an value object with the appropriate type (signed integer)");
- int_value = bt_value_integer_signed_get(obj);
- ok(int_value == -507,
- "bt_value_array_borrow_element_by_index() returns an value object with the appropriate value (signed integer)");
- obj = bt_value_array_borrow_element_by_index(array_obj, 2);
- ok(bt_value_is_real(obj),
- "bt_value_array_borrow_element_by_index() returns an value object with the appropriate type (real number)");
- real_value = bt_value_real_get(obj);
- ok(real_value == -17.45,
- "bt_value_array_borrow_element_by_index() returns an value object with the appropriate value (real number)");
- obj = bt_value_array_borrow_element_by_index(array_obj, 3);
- ok(bt_value_is_bool(obj),
- "bt_value_array_borrow_element_by_index() returns an value object with the appropriate type (boolean)");
- bool_value = bt_value_bool_get(obj);
- ok(bool_value,
- "bt_value_array_borrow_element_by_index() returns an value object with the appropriate value (boolean)");
- obj = bt_value_array_borrow_element_by_index(array_obj, 4);
- ok(bt_value_null,
- "bt_value_array_borrow_element_by_index() returns an value object with the appropriate type (null)");
-
- obj = bt_value_integer_signed_create_init(1001);
- BT_ASSERT(obj);
- ok(!bt_value_array_set_element_by_index(array_obj, 2, obj),
- "bt_value_array_set_element_by_index() succeeds");
- BT_VALUE_PUT_REF_AND_RESET(obj);
- obj = bt_value_array_borrow_element_by_index(array_obj, 2);
- ok(bt_value_is_signed_integer(obj),
- "bt_value_array_set_element_by_index() inserts an value object with the appropriate type");
- int_value = bt_value_integer_signed_get(obj);
- BT_ASSERT(!ret);
- ok(int_value == 1001,
- "bt_value_array_set_element_by_index() inserts an value object with the appropriate value");
-
- ret = bt_value_array_append_bool_element(array_obj,
- BT_FALSE);
- ok(!ret, "bt_value_array_append_bool_element() succeeds");
- ret = bt_value_array_append_unsigned_integer_element(array_obj,
- 98765);
- ok(!ret, "bt_value_array_append_unsigned_integer_element() succeeds");
- ret = bt_value_array_append_signed_integer_element(array_obj,
- -10101);
- ok(!ret, "bt_value_array_append_signed_integer_element() succeeds");
- ret = bt_value_array_append_real_element(array_obj,
- 2.49578);
- ok(!ret, "bt_value_array_append_real_element() succeeds");
- ret = bt_value_array_append_string_element(array_obj,
- "bt_value");
- ok(!ret, "bt_value_array_append_string_element() succeeds");
- ret = bt_value_array_append_empty_array_element(array_obj, NULL);
- ok(!ret, "bt_value_array_append_empty_array_element() succeeds");
- ret = bt_value_array_append_empty_array_element(array_obj, &appended_obj);
- ok(!ret, "bt_value_array_append_empty_array_element() with returned value object succeeds");
- ok(appended_obj,
- "object returned by bt_value_array_append_empty_array_element() is not NULL");
- ok(bt_value_is_array(appended_obj),
- "object returned by bt_value_array_append_empty_array_element() is an array value");
- ret = bt_value_array_append_empty_map_element(array_obj, NULL);
- ok(!ret, "bt_value_array_append_empty_map_element() succeeds");
- ret = bt_value_array_append_empty_map_element(array_obj, &appended_obj);
- ok(!ret, "bt_value_array_append_empty_map_element() with returned value object succeeds");
- ok(appended_obj,
- "object returned by bt_value_array_append_empty_map_element() is not NULL");
- ok(bt_value_is_map(appended_obj),
- "object returned by bt_value_array_append_empty_map_element() is an array value");
-
- ok(bt_value_array_get_length(array_obj) == 14,
- "the bt_value_array_append_element_*() functions increment the array value object's size");
- ok(!bt_value_array_is_empty(array_obj),
- "map value object is not empty");
-
- obj = bt_value_array_borrow_element_by_index(array_obj, 5);
- ok(bt_value_is_bool(obj),
- "bt_value_array_append_bool_element() appends a boolean value object");
- bool_value = bt_value_bool_get(obj);
- ok(!bool_value,
- "bt_value_array_append_bool_element() appends the appropriate value");
- obj = bt_value_array_borrow_element_by_index(array_obj, 6);
- ok(bt_value_is_unsigned_integer(obj),
- "bt_value_array_append_unsigned_integer_element() appends an unsigned integer value object");
- int_value = bt_value_integer_unsigned_get(obj);
- ok(int_value == 98765,
- "bt_value_array_append_unsigned_integer_element() appends the appropriate value");
- obj = bt_value_array_borrow_element_by_index(array_obj, 7);
- ok(bt_value_is_signed_integer(obj),
- "bt_value_array_append_signed_integer_element() appends a signed integer value object");
- int_value = bt_value_integer_signed_get(obj);
- ok(int_value == -10101,
- "bt_value_array_append_signed_integer_element() appends the appropriate value");
- obj = bt_value_array_borrow_element_by_index(array_obj, 8);
- ok(bt_value_is_real(obj),
- "bt_value_array_append_real_element() appends a real number value object");
- real_value = bt_value_real_get(obj);
- ok(real_value == 2.49578,
- "bt_value_array_append_real_element() appends the appropriate value");
- obj = bt_value_array_borrow_element_by_index(array_obj, 9);
- ok(bt_value_is_string(obj),
- "bt_value_array_append_string_element() appends a string value object");
- string_value = bt_value_string_get(obj);
- ok(!ret && string_value && strcmp(string_value, "bt_value") == 0,
- "bt_value_array_append_string_element() appends the appropriate value");
- obj = bt_value_array_borrow_element_by_index(array_obj, 10);
- ok(bt_value_is_array(obj),
- "bt_value_array_append_empty_array_element() appends an array value object");
- ok(bt_value_array_is_empty(obj),
- "bt_value_array_append_empty_array_element() an empty array value object");
- obj = bt_value_array_borrow_element_by_index(array_obj, 11);
- ok(bt_value_is_array(obj),
- "bt_value_array_append_empty_array_element() appends an array value object");
- ok(bt_value_array_is_empty(obj),
- "bt_value_array_append_empty_array_element() an empty array value object");
- obj = bt_value_array_borrow_element_by_index(array_obj, 12);
- ok(bt_value_is_map(obj),
- "bt_value_array_append_empty_map_element() appends a map value object");
- ok(bt_value_map_is_empty(obj),
- "bt_value_array_append_empty_map_element() an empty map value object");
- obj = bt_value_array_borrow_element_by_index(array_obj, 13);
- ok(bt_value_is_map(obj),
- "bt_value_array_append_empty_map_element() appends a map value object");
- ok(bt_value_map_is_empty(obj),
- "bt_value_array_append_empty_map_element() an empty map value object");
-
- BT_VALUE_PUT_REF_AND_RESET(array_obj);
- pass("putting an existing array value object does not cause a crash")
-}
-
-static
-bt_value_map_foreach_entry_func_status test_map_foreach_cb_count(
- const char *key, bt_value *object,
- void *data)
-{
- int *count = data;
-
- if (*count == 3) {
- return BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_INTERRUPT;
- } else if (*count == 4) {
- return BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR;
- } else if (*count == 5) {
- return BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_MEMORY_ERROR;
- }
-
- (*count)++;
-
- return BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK;
-}
-
-struct map_foreach_checklist {
- bt_bool bool1;
- bt_bool uint;
- bt_bool int1;
- bt_bool real1;
- bt_bool null1;
- bt_bool bool2;
- bt_bool int2;
- bt_bool real2;
- bt_bool string2;
- bt_bool array2;
- bt_bool array3;
- bt_bool map2;
- bt_bool map3;
-};
-
-static
-bt_value_map_foreach_entry_func_status test_map_foreach_cb_check(
- const char *key, bt_value *object, void *data)
-{
- struct map_foreach_checklist *checklist = data;
-
- if (strcmp(key, "bt_bool") == 0) {
- if (checklist->bool1) {
- fail("test_map_foreach_cb_check(): duplicate key \"bt_bool\"");
- } else {
- bt_bool val = BT_FALSE;
-
- val = bt_value_bool_get(object);
-
- if (val) {
- pass("test_map_foreach_cb_check(): \"bt_bool\" value object has the right value");
- checklist->bool1 = BT_TRUE;
- } else {
- fail("test_map_foreach_cb_check(): \"bt_bool\" value object has the wrong value");
- }
- }
- } else if (strcmp(key, "uint") == 0) {
- if (checklist->uint) {
- fail("test_map_foreach_cb_check(): duplicate key \"uint\"");
- } else {
- uint64_t val = 0;
-
- val = bt_value_integer_unsigned_get(object);
-
- if (val == 19457) {
- pass("test_map_foreach_cb_check(): \"uint\" value object has the right value");
- checklist->uint = BT_TRUE;
- } else {
- fail("test_map_foreach_cb_check(): \"uint\" value object has the wrong value");
- }
- }
- } else if (strcmp(key, "int") == 0) {
- if (checklist->int1) {
- fail("test_map_foreach_cb_check(): duplicate key \"int\"");
- } else {
- int64_t val = 0;
-
- val = bt_value_integer_signed_get(object);
-
- if (val == -12345) {
- pass("test_map_foreach_cb_check(): \"int\" value object has the right value");
- checklist->int1 = BT_TRUE;
- } else {
- fail("test_map_foreach_cb_check(): \"int\" value object has the wrong value");
- }
- }
- } else if (strcmp(key, "real") == 0) {
- if (checklist->real1) {
- fail("test_map_foreach_cb_check(): duplicate key \"real\"");
- } else {
- double val = 0;
-
- val = bt_value_real_get(object);
-
- if (val == 5.444) {
- pass("test_map_foreach_cb_check(): \"real\" value object has the right value");
- checklist->real1 = BT_TRUE;
- } else {
- fail("test_map_foreach_cb_check(): \"real\" value object has the wrong value");
- }
- }
- } else if (strcmp(key, "null") == 0) {
- if (checklist->null1) {
- fail("test_map_foreach_cb_check(): duplicate key \"bt_bool\"");
- } else {
- ok(bt_value_is_null(object), "test_map_foreach_cb_check(): success getting \"null\" value object");
- checklist->null1 = BT_TRUE;
- }
- } else if (strcmp(key, "bool2") == 0) {
- if (checklist->bool2) {
- fail("test_map_foreach_cb_check(): duplicate key \"bool2\"");
- } else {
- bt_bool val = BT_FALSE;
-
- val = bt_value_bool_get(object);
-
- if (val) {
- pass("test_map_foreach_cb_check(): \"bool2\" value object has the right value");
- checklist->bool2 = BT_TRUE;
- } else {
- fail("test_map_foreach_cb_check(): \"bool2\" value object has the wrong value");
- }
- }
- } else if (strcmp(key, "int2") == 0) {
- if (checklist->int2) {
- fail("test_map_foreach_cb_check(): duplicate key \"int2\"");
- } else {
- int64_t val = 0;
-
- val = bt_value_integer_signed_get(object);
-
- if (val == 98765) {
- pass("test_map_foreach_cb_check(): \"int2\" value object has the right value");
- checklist->int2 = BT_TRUE;
- } else {
- fail("test_map_foreach_cb_check(): \"int2\" value object has the wrong value");
- }
- }
- } else if (strcmp(key, "real2") == 0) {
- if (checklist->real2) {
- fail("test_map_foreach_cb_check(): duplicate key \"real2\"");
- } else {
- double val = 0;
-
- val = bt_value_real_get(object);
-
- if (val == -49.0001) {
- pass("test_map_foreach_cb_check(): \"real2\" value object has the right value");
- checklist->real2 = BT_TRUE;
- } else {
- fail("test_map_foreach_cb_check(): \"real2\" value object has the wrong value");
- }
- }
- } else if (strcmp(key, "string2") == 0) {
- if (checklist->string2) {
- fail("test_map_foreach_cb_check(): duplicate key \"string2\"");
- } else {
- const char *val;
-
- val = bt_value_string_get(object);
-
- if (val && strcmp(val, "bt_value") == 0) {
- pass("test_map_foreach_cb_check(): \"string2\" value object has the right value");
- checklist->string2 = BT_TRUE;
- } else {
- fail("test_map_foreach_cb_check(): \"string2\" value object has the wrong value");
- }
- }
- } else if (strcmp(key, "array2") == 0) {
- if (checklist->array2) {
- fail("test_map_foreach_cb_check(): duplicate key \"array2\"");
- } else {
- ok(bt_value_is_array(object), "test_map_foreach_cb_check(): success getting \"array2\" value object");
- ok(bt_value_array_is_empty(object),
- "test_map_foreach_cb_check(): \"array2\" value object is empty");
- checklist->array2 = BT_TRUE;
- }
- } else if (strcmp(key, "array3") == 0) {
- if (checklist->array3) {
- fail("test_map_foreach_cb_check(): duplicate key \"array3\"");
- } else {
- ok(bt_value_is_array(object), "test_map_foreach_cb_check(): success getting \"array3\" value object");
- ok(bt_value_array_is_empty(object),
- "test_map_foreach_cb_check(): \"array3\" value object is empty");
- checklist->array3 = BT_TRUE;
- }
- } else if (strcmp(key, "map3") == 0) {
- if (checklist->map3) {
- fail("test_map_foreach_cb_check(): duplicate key \"map3\"");
- } else {
- ok(bt_value_is_map(object), "test_map_foreach_cb_check(): success getting \"map3\" value object");
- ok(bt_value_map_is_empty(object),
- "test_map_foreach_cb_check(): \"map3\" value object is empty");
- checklist->map3 = BT_TRUE;
- }
- } else if (strcmp(key, "map2") == 0) {
- if (checklist->map2) {
- fail("test_map_foreach_cb_check(): duplicate key \"map2\"");
- } else {
- ok(bt_value_is_map(object), "test_map_foreach_cb_check(): success getting \"map2\" value object");
- ok(bt_value_map_is_empty(object),
- "test_map_foreach_cb_check(): \"map2\" value object is empty");
- checklist->map2 = BT_TRUE;
- }
- } else {
- fail("test_map_foreach_cb_check(): unknown map key \"%s\"",
- key);
- }
-
- return BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_OK;
-}
-
-static
-void test_map(void)
-{
- int ret;
- int count = 0;
- bt_bool bool_value;
- int64_t int_value;
- double real_value;
- bt_value *obj;
- bt_value *map_obj;
- bt_value *inserted_obj;
- struct map_foreach_checklist checklist;
-
- map_obj = bt_value_map_create();
- ok(map_obj && bt_value_is_map(map_obj),
- "bt_value_map_create() returns a map value object");
- ok(bt_value_map_get_size(map_obj) == 0,
- "initial map value object size is 0");
-
- obj = bt_value_integer_unsigned_create_init(19457);
- ret = bt_value_map_insert_entry(map_obj, "uint", obj);
- BT_VALUE_PUT_REF_AND_RESET(obj);
- obj = bt_value_integer_signed_create_init(-12345);
- ret |= bt_value_map_insert_entry(map_obj, "int", obj);
- BT_VALUE_PUT_REF_AND_RESET(obj);
- obj = bt_value_real_create_init(5.444);
- ret |= bt_value_map_insert_entry(map_obj, "real", obj);
- BT_VALUE_PUT_REF_AND_RESET(obj);
- obj = bt_value_bool_create();
- ret |= bt_value_map_insert_entry(map_obj, "bt_bool", obj);
- BT_VALUE_PUT_REF_AND_RESET(obj);
- ret |= bt_value_map_insert_entry(map_obj, "null",
- bt_value_null);
- ok(!ret, "bt_value_map_insert_entry() succeeds");
- ok(bt_value_map_get_size(map_obj) == 5,
- "inserting an element into a map value object increment its size");
-
- obj = bt_value_bool_create_init(BT_TRUE);
- ret = bt_value_map_insert_entry(map_obj, "bt_bool", obj);
- BT_VALUE_PUT_REF_AND_RESET(obj);
- ok(!ret, "bt_value_map_insert_entry() accepts an existing key");
-
- obj = bt_value_map_borrow_entry_value(map_obj, "life");
- ok(!obj, "bt_value_map_borrow_entry_value() returns NULL with an non existing key");
- obj = bt_value_map_borrow_entry_value(map_obj, "real");
- ok(obj && bt_value_is_real(obj),
- "bt_value_map_borrow_entry_value() returns an value object with the appropriate type (real)");
- real_value = bt_value_real_get(obj);
- ok(real_value == 5.444,
- "bt_value_map_borrow_entry_value() returns an value object with the appropriate value (real)");
- obj = bt_value_map_borrow_entry_value(map_obj, "uint");
- ok(obj && bt_value_is_unsigned_integer(obj),
- "bt_value_map_borrow_entry_value() returns an value object with the appropriate type (unsigned integer)");
- int_value = bt_value_integer_unsigned_get(obj);
- ok(int_value == 19457,
- "bt_value_map_borrow_entry_value() returns an value object with the appropriate value (unsigned integer)");
- obj = bt_value_map_borrow_entry_value(map_obj, "int");
- ok(obj && bt_value_is_signed_integer(obj),
- "bt_value_map_borrow_entry_value() returns an value object with the appropriate type (signed integer)");
- int_value = bt_value_integer_signed_get(obj);
- ok(int_value == -12345,
- "bt_value_map_borrow_entry_value() returns an value object with the appropriate value (signed integer)");
- obj = bt_value_map_borrow_entry_value(map_obj, "null");
- ok(obj && bt_value_is_null(obj),
- "bt_value_map_borrow_entry_value() returns an value object with the appropriate type (null)");
- obj = bt_value_map_borrow_entry_value(map_obj, "bt_bool");
- ok(obj && bt_value_is_bool(obj),
- "bt_value_map_borrow_entry_value() returns an value object with the appropriate type (boolean)");
- bool_value = bt_value_bool_get(obj);
- ok(bool_value,
- "bt_value_map_borrow_entry_value() returns an value object with the appropriate value (boolean)");
-
- ret = bt_value_map_insert_bool_entry(map_obj, "bool2",
- BT_TRUE);
- ok(!ret, "bt_value_map_insert_bool_entry() succeeds");
- ret = bt_value_map_insert_signed_integer_entry(map_obj, "int2",
- 98765);
- ok(!ret, "bt_value_map_insert_signed_integer_entry() succeeds");
- ret = bt_value_map_insert_real_entry(map_obj, "real2",
- -49.0001);
- ok(!ret, "bt_value_map_insert_real_entry() succeeds");
- ret = bt_value_map_insert_string_entry(map_obj, "string2",
- "bt_value");
- ok(!ret, "bt_value_map_insert_string_entry() succeeds");
- ret = bt_value_map_insert_empty_array_entry(map_obj, "array2", NULL);
- ok(!ret, "bt_value_map_insert_empty_array_entry() succeeds");
- ret = bt_value_map_insert_empty_array_entry(map_obj, "array3", &inserted_obj);
- ok(!ret, "bt_value_map_insert_empty_array_entry() with returned value object succeeds");
- ok(inserted_obj,
- "object returned by bt_value_map_insert_empty_array_entry() is not NULL");
- ok(bt_value_is_array(inserted_obj),
- "object returned by bt_value_map_insert_empty_array_entry() is an array value");
- ret = bt_value_map_insert_empty_map_entry(map_obj, "map2", NULL);
- ok(!ret, "bt_value_map_insert_empty_map_entry() succeeds");
- ret = bt_value_map_insert_empty_map_entry(map_obj, "map3", &inserted_obj);
- ok(!ret, "bt_value_map_insert_empty_map_entry() with returned value object succeeds");
- ok(inserted_obj,
- "object returned by bt_value_map_insert_empty_map_entry() is not NULL");
- ok(bt_value_is_map(inserted_obj),
- "object returned by bt_value_map_insert_empty_map_entry() is an array value");
-
- ok(bt_value_map_get_size(map_obj) == 13,
- "the bt_value_map_insert*() functions increment the map value object's size");
-
- ok(!bt_value_map_has_entry(map_obj, "hello"),
- "map value object does not have key \"hello\"");
- ok(bt_value_map_has_entry(map_obj, "bt_bool"),
- "map value object has key \"bt_bool\"");
- ok(bt_value_map_has_entry(map_obj, "uint"),
- "map value object has key \"uint\"");
- ok(bt_value_map_has_entry(map_obj, "int"),
- "map value object has key \"int\"");
- ok(bt_value_map_has_entry(map_obj, "real"),
- "map value object has key \"real\"");
- ok(bt_value_map_has_entry(map_obj, "null"),
- "map value object has key \"null\"");
- ok(bt_value_map_has_entry(map_obj, "bool2"),
- "map value object has key \"bool2\"");
- ok(bt_value_map_has_entry(map_obj, "int2"),
- "map value object has key \"int2\"");
- ok(bt_value_map_has_entry(map_obj, "real2"),
- "map value object has key \"real2\"");
- ok(bt_value_map_has_entry(map_obj, "string2"),
- "map value object has key \"string2\"");
- ok(bt_value_map_has_entry(map_obj, "array2"),
- "map value object has key \"array2\"");
- ok(bt_value_map_has_entry(map_obj, "array3"),
- "map value object has key \"array3\"");
- ok(bt_value_map_has_entry(map_obj, "map2"),
- "map value object has key \"map2\"");
- ok(bt_value_map_has_entry(map_obj, "map3"),
- "map value object has key \"map3\"");
-
- ret = bt_value_map_foreach_entry(map_obj, test_map_foreach_cb_count,
- &count);
- ok(ret == BT_VALUE_MAP_FOREACH_ENTRY_STATUS_INTERRUPTED && count == 3,
- "bt_value_map_foreach_entry() breaks the loop when the user function returns BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_INTERRUPT");
-
- count = 4;
- ret = bt_value_map_foreach_entry(map_obj, test_map_foreach_cb_count,
- &count);
- ok(ret == BT_VALUE_MAP_FOREACH_ENTRY_STATUS_USER_ERROR,
- "bt_value_map_foreach_entry() fails when the user function returns BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_ERROR");
- bt_current_thread_clear_error();
-
- count = 5;
- ret = bt_value_map_foreach_entry(map_obj, test_map_foreach_cb_count,
- &count);
- ok(ret == BT_VALUE_MAP_FOREACH_ENTRY_STATUS_MEMORY_ERROR,
- "bt_value_map_foreach_entry() fails when the user function returns BT_VALUE_MAP_FOREACH_ENTRY_FUNC_STATUS_MEMORY_ERROR");
- bt_current_thread_clear_error();
-
- memset(&checklist, 0, sizeof(checklist));
- ret = bt_value_map_foreach_entry(map_obj, test_map_foreach_cb_check,
- &checklist);
- ok(ret == BT_VALUE_MAP_FOREACH_ENTRY_STATUS_OK,
- "bt_value_map_foreach_entry() succeeds with test_map_foreach_cb_check()");
- ok(checklist.bool1 && checklist.uint && checklist.int1 &&
- checklist.real1 && checklist.null1 && checklist.bool2 &&
- checklist.int2 && checklist.real2 && checklist.string2 &&
- checklist.array2 && checklist.map2,
- "bt_value_map_foreach_entry() iterates over all the map value object's elements");
-
- BT_VALUE_PUT_REF_AND_RESET(map_obj);
- pass("putting an existing map value object does not cause a crash")
-}
-
-static
-void test_types(void)
-{
- test_null();
- test_bool();
- test_unsigned_integer();
- test_signed_integer();
- test_real();
- test_string();
- test_array();
- test_map();
-}
-
-static
-void test_is_equal_null(void)
-{
- ok(bt_value_is_equal(bt_value_null, bt_value_null),
- "null value objects are equivalent");
-}
-
-static
-void test_is_equal_bool(void)
-{
- bt_value *bool1 =
- bt_value_bool_create_init(BT_FALSE);
- bt_value *bool2 =
- bt_value_bool_create_init(BT_TRUE);
- bt_value *bool3 =
- bt_value_bool_create_init(BT_FALSE);
-
- BT_ASSERT(bool1 && bool2 && bool3);
- ok(!bt_value_is_equal(bt_value_null, bool1),
- "cannot compare null value object and bt_bool value object");
- ok(!bt_value_is_equal(bool1, bool2),
- "boolean value objects are not equivalent (BT_FALSE and BT_TRUE)");
- ok(bt_value_is_equal(bool1, bool3),
- "boolean value objects are equivalent (BT_FALSE and BT_FALSE)");
-
- BT_VALUE_PUT_REF_AND_RESET(bool1);
- BT_VALUE_PUT_REF_AND_RESET(bool2);
- BT_VALUE_PUT_REF_AND_RESET(bool3);
-}
-
-static
-void test_is_equal_unsigned_integer(void)
-{
- bt_value *int1 =
- bt_value_integer_unsigned_create_init(10);
- bt_value *int2 =
- bt_value_integer_unsigned_create_init(23);
- bt_value *int3 =
- bt_value_integer_unsigned_create_init(10);
-
- BT_ASSERT(int1 && int2 && int3);
- ok(!bt_value_is_equal(bt_value_null, int1),
- "cannot compare null value object and unsigned integer value object");
- ok(!bt_value_is_equal(int1, int2),
- "unsigned integer value objects are not equivalent (10 and 23)");
- ok(bt_value_is_equal(int1, int3),
- "unsigned integer value objects are equivalent (10 and 10)");
-
- BT_VALUE_PUT_REF_AND_RESET(int1);
- BT_VALUE_PUT_REF_AND_RESET(int2);
- BT_VALUE_PUT_REF_AND_RESET(int3);
-}
-
-static
-void test_is_equal_signed_integer(void)
-{
- bt_value *int1 =
- bt_value_integer_signed_create_init(10);
- bt_value *int2 =
- bt_value_integer_signed_create_init(-23);
- bt_value *int3 =
- bt_value_integer_signed_create_init(10);
-
- BT_ASSERT(int1 && int2 && int3);
- ok(!bt_value_is_equal(bt_value_null, int1),
- "cannot compare null value object and signed integer value object");
- ok(!bt_value_is_equal(int1, int2),
- "signed integer value objects are not equivalent (10 and -23)");
- ok(bt_value_is_equal(int1, int3),
- "signed integer value objects are equivalent (10 and 10)");
-
- BT_VALUE_PUT_REF_AND_RESET(int1);
- BT_VALUE_PUT_REF_AND_RESET(int2);
- BT_VALUE_PUT_REF_AND_RESET(int3);
-}
-
-static
-void test_is_equal_real(void)
-{
- bt_value *real1 =
- bt_value_real_create_init(17.38);
- bt_value *real2 =
- bt_value_real_create_init(-14.23);
- bt_value *real3 =
- bt_value_real_create_init(17.38);
-
- BT_ASSERT(real1 && real2 && real3);
-
- ok(!bt_value_is_equal(bt_value_null, real1),
- "cannot compare null value object and real number value object");
- ok(!bt_value_is_equal(real1, real2),
- "real number value objects are not equivalent (17.38 and -14.23)");
- ok(bt_value_is_equal(real1, real3),
- "real number value objects are equivalent (17.38 and 17.38)");
-
- BT_VALUE_PUT_REF_AND_RESET(real1);
- BT_VALUE_PUT_REF_AND_RESET(real2);
- BT_VALUE_PUT_REF_AND_RESET(real3);
-}
-
-static
-void test_is_equal_string(void)
-{
- bt_value *string1 =
- bt_value_string_create_init("hello");
- bt_value *string2 =
- bt_value_string_create_init("bt_value");
- bt_value *string3 =
- bt_value_string_create_init("hello");
-
- BT_ASSERT(string1 && string2 && string3);
-
- ok(!bt_value_is_equal(bt_value_null, string1),
- "cannot compare null value object and string value object");
- ok(!bt_value_is_equal(string1, string2),
- "string value objects are not equivalent (\"hello\" and \"bt_value\")");
- ok(bt_value_is_equal(string1, string3),
- "string value objects are equivalent (\"hello\" and \"hello\")");
-
- BT_VALUE_PUT_REF_AND_RESET(string1);
- BT_VALUE_PUT_REF_AND_RESET(string2);
- BT_VALUE_PUT_REF_AND_RESET(string3);
-}
-
-static
-void test_is_equal_array(void)
-{
- bt_value *array1 = bt_value_array_create();
- bt_value *array2 = bt_value_array_create();
- bt_value *array3 = bt_value_array_create();
- bt_value_array_append_element_status append_status;
-
- BT_ASSERT(array1 && array2 && array3);
-
- ok(bt_value_is_equal(array1, array2),
- "empty array value objects are equivalent");
-
- append_status = bt_value_array_append_signed_integer_element(array1, 23);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_real_element(array1, 14.2);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_bool_element(array1, BT_FALSE);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_real_element(array2, 14.2);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_signed_integer_element(array2, 23);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_bool_element(array2, BT_FALSE);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_signed_integer_element(array3, 23);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_real_element(array3, 14.2);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_bool_element(array3, BT_FALSE);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- BT_ASSERT(bt_value_array_get_length(array1) == 3);
- BT_ASSERT(bt_value_array_get_length(array2) == 3);
- BT_ASSERT(bt_value_array_get_length(array3) == 3);
-
- ok(!bt_value_is_equal(bt_value_null, array1),
- "cannot compare null value object and array value object");
- ok(!bt_value_is_equal(array1, array2),
- "array value objects are not equivalent ([23, 14.2, BT_FALSE] and [14.2, 23, BT_FALSE])");
- ok(bt_value_is_equal(array1, array3),
- "array value objects are equivalent ([23, 14.2, BT_FALSE] and [23, 14.2, BT_FALSE])");
-
- BT_VALUE_PUT_REF_AND_RESET(array1);
- BT_VALUE_PUT_REF_AND_RESET(array2);
- BT_VALUE_PUT_REF_AND_RESET(array3);
-}
-
-static
-void test_is_equal_map(void)
-{
- bt_value *map1 = bt_value_map_create();
- bt_value *map2 = bt_value_map_create();
- bt_value *map3 = bt_value_map_create();
- bt_value_map_insert_entry_status insert_status;
-
- BT_ASSERT(map1 && map2 && map3);
-
- ok(bt_value_is_equal(map1, map2),
- "empty map value objects are equivalent");
-
-
- insert_status = bt_value_map_insert_signed_integer_entry(map1, "one", 23);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_real_entry(map1, "two", 14.2);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_bool_entry(map1, "three",
- BT_FALSE);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_real_entry(map2, "one", 14.2);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_signed_integer_entry(map2, "two", 23);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_bool_entry(map2, "three",
- BT_FALSE);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_bool_entry(map3, "three",
- BT_FALSE);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_signed_integer_entry(map3, "one", 23);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_real_entry(map3, "two", 14.2);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- BT_ASSERT(bt_value_map_get_size(map1) == 3);
- BT_ASSERT(bt_value_map_get_size(map2) == 3);
- BT_ASSERT(bt_value_map_get_size(map3) == 3);
-
- ok(!bt_value_is_equal(bt_value_null, map1),
- "cannot compare null value object and map value object");
- ok(!bt_value_is_equal(map1, map2),
- "map value objects are not equivalent");
- ok(bt_value_is_equal(map1, map3),
- "map value objects are equivalent");
-
- BT_VALUE_PUT_REF_AND_RESET(map1);
- BT_VALUE_PUT_REF_AND_RESET(map2);
- BT_VALUE_PUT_REF_AND_RESET(map3);
-}
-
-static
-void test_is_equal(void)
-{
- test_is_equal_null();
- test_is_equal_bool();
- test_is_equal_unsigned_integer();
- test_is_equal_signed_integer();
- test_is_equal_real();
- test_is_equal_string();
- test_is_equal_array();
- test_is_equal_map();
-}
-
-static
-void test_copy(void)
-{
- /*
- * Here's the deal here. If we make sure that each value object
- * of our deep copy has a different address than its source, and
- * that bt_value_is_equal() returns BT_TRUE for the top-level
- * value object, taking into account that we test the
- * correctness of bt_value_is_equal() elsewhere, then the deep
- * copy is a success.
- */
- bt_value *null_copy_obj;
- bt_value *bool_obj, *bool_copy_obj;
- bt_value *unsigned_integer_obj, *unsigned_integer_copy_obj;
- bt_value *signed_integer_obj, *signed_integer_copy_obj;
- bt_value *real_obj, *real_copy_obj;
- bt_value *string_obj, *string_copy_obj;
- bt_value *array_obj, *array_copy_obj;
- bt_value *map_obj, *map_copy_obj;
- bt_value_array_append_element_status append_status;
- bt_value_map_insert_entry_status insert_status;
- bt_value_copy_status copy_status;
-
- bool_obj = bt_value_bool_create_init(BT_TRUE);
- unsigned_integer_obj = bt_value_integer_unsigned_create_init(23);
- signed_integer_obj = bt_value_integer_signed_create_init(-47);
- real_obj = bt_value_real_create_init(-3.1416);
- string_obj = bt_value_string_create_init("test");
- array_obj = bt_value_array_create();
- map_obj = bt_value_map_create();
-
- BT_ASSERT(bool_obj && unsigned_integer_obj && signed_integer_obj &&
- real_obj && string_obj && array_obj && map_obj);
-
- append_status = bt_value_array_append_element(array_obj, bool_obj);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_element(array_obj, unsigned_integer_obj);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_element(array_obj, signed_integer_obj);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_element(array_obj, real_obj);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- append_status = bt_value_array_append_element(array_obj, bt_value_null);
- BT_ASSERT(append_status == BT_VALUE_ARRAY_APPEND_ELEMENT_STATUS_OK);
- insert_status = bt_value_map_insert_entry(map_obj, "array", array_obj);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_entry(map_obj, "string", string_obj);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
-
- copy_status = bt_value_copy(map_obj, &map_copy_obj);
- ok(copy_status == BT_VALUE_COPY_STATUS_OK && map_copy_obj,
- "bt_value_copy() succeeds");
-
- ok(map_obj != map_copy_obj,
- "bt_value_copy() returns a different pointer (map)");
- string_copy_obj = bt_value_map_borrow_entry_value(map_copy_obj,
- "string");
- ok(string_copy_obj != string_obj,
- "bt_value_copy() returns a different pointer (string)");
- array_copy_obj = bt_value_map_borrow_entry_value(map_copy_obj,
- "array");
- ok(array_copy_obj != array_obj,
- "bt_value_copy() returns a different pointer (array)");
- bool_copy_obj = bt_value_array_borrow_element_by_index(
- array_copy_obj, 0);
- ok(bool_copy_obj != bool_obj,
- "bt_value_copy() returns a different pointer (bool)");
- unsigned_integer_copy_obj = bt_value_array_borrow_element_by_index(
- array_copy_obj, 1);
- ok(unsigned_integer_copy_obj != unsigned_integer_obj,
- "bt_value_copy() returns a different pointer (unsigned integer)");
- signed_integer_copy_obj = bt_value_array_borrow_element_by_index(
- array_copy_obj, 2);
- ok(signed_integer_copy_obj != signed_integer_obj,
- "bt_value_copy() returns a different pointer (signed integer)");
- real_copy_obj = bt_value_array_borrow_element_by_index(
- array_copy_obj, 3);
- ok(real_copy_obj != real_obj,
- "bt_value_copy() returns a different pointer (real)");
- null_copy_obj = bt_value_array_borrow_element_by_index(
- array_copy_obj, 4);
- ok(null_copy_obj == bt_value_null,
- "bt_value_copy() returns the same pointer (null)");
-
- ok(bt_value_is_equal(map_obj, map_copy_obj),
- "source and destination value objects have the same content");
-
- BT_VALUE_PUT_REF_AND_RESET(map_copy_obj);
- BT_VALUE_PUT_REF_AND_RESET(bool_obj);
- BT_VALUE_PUT_REF_AND_RESET(unsigned_integer_obj);
- BT_VALUE_PUT_REF_AND_RESET(signed_integer_obj);
- BT_VALUE_PUT_REF_AND_RESET(real_obj);
- BT_VALUE_PUT_REF_AND_RESET(string_obj);
- BT_VALUE_PUT_REF_AND_RESET(array_obj);
- BT_VALUE_PUT_REF_AND_RESET(map_obj);
-}
-
-static
-bt_bool compare_map_elements(const bt_value *map_a, const bt_value *map_b,
- const char *key)
-{
- const bt_value *elem_a = NULL;
- const bt_value *elem_b = NULL;
- bt_bool equal;
-
- elem_a = bt_value_map_borrow_entry_value_const(map_a, key);
- elem_b = bt_value_map_borrow_entry_value_const(map_b, key);
- equal = bt_value_is_equal(elem_a, elem_b);
- return equal;
-}
-
-static
-void test_extend(void)
-{
- bt_value *base_map = bt_value_map_create();
- bt_value *extension_map = bt_value_map_create();
- bt_value *extended_map = NULL;
- bt_value *array = bt_value_array_create();
- bt_value_map_insert_entry_status insert_status;
- bt_value_copy_status copy_status;
- bt_value_map_extend_status extend_status;
-
- BT_ASSERT(base_map);
- BT_ASSERT(extension_map);
- BT_ASSERT(array);
- insert_status = bt_value_map_insert_bool_entry(base_map, "file",
- BT_TRUE);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_bool_entry(base_map, "edit",
- BT_FALSE);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_signed_integer_entry(base_map,
- "selection", 17);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_signed_integer_entry(base_map, "find",
- -34);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_bool_entry(extension_map, "edit",
- BT_TRUE);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_signed_integer_entry(extension_map,
- "find", 101);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- insert_status = bt_value_map_insert_real_entry(extension_map,
- "project", -404);
- BT_ASSERT(insert_status == BT_VALUE_MAP_INSERT_ENTRY_STATUS_OK);
- copy_status = bt_value_copy(base_map, &extended_map);
- BT_ASSERT(copy_status == BT_VALUE_COPY_STATUS_OK);
- extend_status = bt_value_map_extend(extended_map, extension_map);
- ok(extend_status == BT_VALUE_MAP_EXTEND_STATUS_OK &&
- extended_map, "bt_value_map_extend() succeeds");
- ok(bt_value_map_get_size(extended_map) == 5,
- "bt_value_map_extend() returns a map object with the correct size");
- ok(compare_map_elements(base_map,
- extended_map, "file"),
- "bt_value_map_extend() picks the appropriate element (file)");
- ok(compare_map_elements(extension_map,
- extended_map, "edit"),
- "bt_value_map_extend() picks the appropriate element (edit)");
- ok(compare_map_elements(base_map,
- extended_map, "selection"),
- "bt_value_map_extend() picks the appropriate element (selection)");
- ok(compare_map_elements(extension_map,
- extended_map, "find"),
- "bt_value_map_extend() picks the appropriate element (find)");
- ok(compare_map_elements(extension_map,
- extended_map, "project"),
- "bt_value_map_extend() picks the appropriate element (project)");
-
- BT_VALUE_PUT_REF_AND_RESET(array);
- BT_VALUE_PUT_REF_AND_RESET(base_map);
- BT_VALUE_PUT_REF_AND_RESET(extension_map);
- BT_VALUE_PUT_REF_AND_RESET(extended_map);
-}
-
-int main(void)
-{
- plan_tests(NR_TESTS);
- test_types();
- test_is_equal();
- test_copy();
- test_extend();
- return exit_status();
-}
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2023 EfficiOS, Inc.
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-run_python_bt2 "${BT_TESTS_BUILDDIR}/lib/test_fields_bin"
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2023 EfficiOS Inc.
- */
-
-#include "utils/run-in.hpp"
-#include "tap/tap.h"
-#include "common/assert.h"
-#include <cstring>
-
-static const int NR_TESTS = 2;
-
-static void test_string_clear()
-{
- runInMsgIterClsInit([](bt_self_message_iterator * const self) {
- /* Boilerplate to get a string field */
- const auto traceCls =
- bt_trace_class_create(bt_self_message_iterator_borrow_component(self));
- const auto streamCls = bt_stream_class_create(traceCls);
- const auto eventCls = bt_event_class_create(streamCls);
- const auto payloadCls = bt_field_class_structure_create(traceCls);
-
- {
- const auto stringFieldCls = bt_field_class_string_create(traceCls);
- const auto status =
- bt_field_class_structure_append_member(payloadCls, "str", stringFieldCls);
- BT_ASSERT(status == BT_FIELD_CLASS_STRUCTURE_APPEND_MEMBER_STATUS_OK);
- bt_field_class_put_ref(stringFieldCls);
- }
-
- {
- const auto status = bt_event_class_set_payload_field_class(eventCls, payloadCls);
- BT_ASSERT(status == BT_EVENT_CLASS_SET_FIELD_CLASS_STATUS_OK);
- }
-
- const auto trace = bt_trace_create(traceCls);
- const auto stream = bt_stream_create(streamCls, trace);
- const auto msg = bt_message_event_create(self, eventCls, stream);
- const auto field = bt_field_structure_borrow_member_field_by_name(
- bt_event_borrow_payload_field(bt_message_event_borrow_event(msg)), "str");
-
- /* Set the field to a known non-empty value */
- {
- const auto status = bt_field_string_set_value(field, "pomme");
- BT_ASSERT(status == BT_FIELD_STRING_SET_VALUE_STATUS_OK);
- BT_ASSERT(std::strcmp(bt_field_string_get_value(field), "pomme") == 0);
- }
-
- /* Clear the field, verify its value and length */
- bt_field_string_clear(field);
- ok(std::strcmp(bt_field_string_get_value(field), "") == 0, "string field is empty");
- ok(bt_field_string_get_length(field) == 0, "string field length is 0");
-
- bt_message_put_ref(msg);
- bt_stream_put_ref(stream);
- bt_trace_put_ref(trace);
- bt_field_class_put_ref(payloadCls);
- bt_event_class_put_ref(eventCls);
- bt_stream_class_put_ref(streamCls);
- bt_trace_class_put_ref(traceCls);
- });
-}
-
-int main()
-{
- plan_tests(NR_TESTS);
-
- test_string_clear();
-
- return exit_status();
-}
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
- */
-
-#include <babeltrace2/babeltrace.h>
-#include "common/assert.h"
-#include <stdlib.h>
-#include <string.h>
-#include <stdbool.h>
-#include <glib.h>
-
-#include "tap/tap.h"
-
-#define NR_TESTS 26
-
-enum event_type {
- SRC_COMP_OUTPUT_PORT_CONNECTED,
- SINK_COMP_INPUT_PORT_CONNECTED,
- GRAPH_SRC_OUTPUT_PORT_ADDED,
- GRAPH_SINK_INPUT_PORT_ADDED,
-};
-
-enum test {
- TEST_EMPTY_GRAPH,
- TEST_SIMPLE,
- TEST_SRC_PORT_CONNECTED_ERROR,
- TEST_SINK_PORT_CONNECTED_ERROR,
- TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
-};
-
-struct event {
- enum event_type type;
-
- union {
- struct {
- const bt_component *comp;
- const bt_port *self_port;
- const bt_port *other_port;
- } src_comp_output_port_connected;
-
- struct {
- const bt_component *comp;
- const bt_port *self_port;
- const bt_port *other_port;
- } sink_comp_input_port_connected;
-
- struct {
- const bt_component *comp;
- const bt_port *port;
- } graph_src_output_port_added;
-
- struct {
- const bt_component *comp;
- const bt_port *port;
- } graph_sink_input_port_added;
- } data;
-};
-
-static GArray *events;
-static bt_message_iterator_class *msg_iter_class;
-static bt_component_class_source *src_comp_class;
-static bt_component_class_sink *sink_comp_class;
-static enum test current_test;
-
-static
-void clear_events(void)
-{
- g_array_set_size(events, 0);
-}
-
-static
-void append_event(struct event *event)
-{
- g_array_append_val(events, *event);
-}
-
-static
-bool compare_events(struct event *ev_a, struct event *ev_b)
-{
- if (ev_a->type != ev_b->type) {
- return false;
- }
-
- switch (ev_a->type) {
- case SRC_COMP_OUTPUT_PORT_CONNECTED:
- if (ev_a->data.src_comp_output_port_connected.comp !=
- ev_b->data.src_comp_output_port_connected.comp) {
- return false;
- }
-
- if (ev_a->data.src_comp_output_port_connected.self_port !=
- ev_b->data.src_comp_output_port_connected.self_port) {
- return false;
- }
-
- if (ev_a->data.src_comp_output_port_connected.other_port !=
- ev_b->data.src_comp_output_port_connected.other_port) {
- return false;
- }
- break;
- case SINK_COMP_INPUT_PORT_CONNECTED:
- if (ev_a->data.sink_comp_input_port_connected.comp !=
- ev_b->data.sink_comp_input_port_connected.comp) {
- return false;
- }
-
- if (ev_a->data.sink_comp_input_port_connected.self_port !=
- ev_b->data.sink_comp_input_port_connected.self_port) {
- return false;
- }
-
- if (ev_a->data.sink_comp_input_port_connected.other_port !=
- ev_b->data.sink_comp_input_port_connected.other_port) {
- return false;
- }
- break;
- case GRAPH_SRC_OUTPUT_PORT_ADDED:
- if (ev_a->data.graph_src_output_port_added.comp !=
- ev_b->data.graph_src_output_port_added.comp) {
- return false;
- }
-
- if (ev_a->data.graph_src_output_port_added.port !=
- ev_b->data.graph_src_output_port_added.port) {
- return false;
- }
- break;
- case GRAPH_SINK_INPUT_PORT_ADDED:
- if (ev_a->data.graph_sink_input_port_added.comp !=
- ev_b->data.graph_sink_input_port_added.comp) {
- return false;
- }
-
- if (ev_a->data.graph_sink_input_port_added.port !=
- ev_b->data.graph_sink_input_port_added.port) {
- return false;
- }
- break;
- default:
- abort();
- }
-
- return true;
-}
-
-static
-bool has_event(struct event *event)
-{
- size_t i;
-
- for (i = 0; i < events->len; i++) {
- struct event *ev = &bt_g_array_index(events, struct event, i);
-
- if (compare_events(event, ev)) {
- return true;
- }
- }
-
- return false;
-}
-
-static
-size_t event_pos(struct event *event)
-{
- size_t i;
-
- for (i = 0; i < events->len; i++) {
- struct event *ev = &bt_g_array_index(events, struct event, i);
-
- if (compare_events(event, ev)) {
- return i;
- }
- }
-
- return SIZE_MAX;
-}
-
-static
-bt_message_iterator_class_next_method_status src_iter_next(
- bt_self_message_iterator *self_iterator,
- bt_message_array_const msgs, uint64_t capacity,
- uint64_t *count)
-{
- return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
-}
-
-static
-bt_component_class_port_connected_method_status src_output_port_connected(
- bt_self_component_source *self_comp,
- bt_self_component_port_output *self_comp_port,
- const bt_port_input *other_port)
-{
- int ret;
- struct event event = {
- .type = SRC_COMP_OUTPUT_PORT_CONNECTED,
- .data.src_comp_output_port_connected = {
- .comp = bt_self_component_as_component(
- bt_self_component_source_as_self_component(
- self_comp)),
- .self_port = bt_self_component_port_as_port(
- bt_self_component_port_output_as_self_component_port(
- self_comp_port)),
- .other_port = bt_port_input_as_port_const(other_port),
- },
- };
-
- append_event(&event);
-
- switch (current_test) {
- case TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED:
- ret = bt_self_component_source_add_output_port(
- self_comp, "hello", NULL, NULL);
- BT_ASSERT(ret == 0);
- break;
- case TEST_SRC_PORT_CONNECTED_ERROR:
- return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
- default:
- break;
- }
-
- return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_OK;
-}
-
-static
-bt_component_class_port_connected_method_status sink_input_port_connected(
- bt_self_component_sink *self_comp,
- bt_self_component_port_input *self_comp_port,
- const bt_port_output *other_port)
-{
- struct event event = {
- .type = SINK_COMP_INPUT_PORT_CONNECTED,
- .data.sink_comp_input_port_connected = {
- .comp = bt_self_component_as_component(
- bt_self_component_sink_as_self_component(
- self_comp)),
- .self_port = bt_self_component_port_as_port(
- bt_self_component_port_input_as_self_component_port(
- self_comp_port)),
- .other_port = bt_port_output_as_port_const(other_port),
- },
- };
-
- append_event(&event);
-
- if (current_test == TEST_SINK_PORT_CONNECTED_ERROR) {
- return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_ERROR;
- } else {
- return BT_COMPONENT_CLASS_PORT_CONNECTED_METHOD_STATUS_OK;
- }
-}
-
-static
-bt_component_class_initialize_method_status src_init(
- bt_self_component_source *self_comp,
- bt_self_component_source_configuration *config,
- const bt_value *params, void *init_method_data)
-{
- int ret;
-
- ret = bt_self_component_source_add_output_port(
- self_comp, "out", NULL, NULL);
- BT_ASSERT(ret == 0);
- return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
-}
-
-static
-bt_component_class_initialize_method_status sink_init(
- bt_self_component_sink *self_comp,
- bt_self_component_sink_configuration *config,
- const bt_value *params, void *init_method_data)
-{
- int ret;
-
- ret = bt_self_component_sink_add_input_port(self_comp,
- "in", NULL, NULL);
- BT_ASSERT(ret == 0);
- return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
-}
-
-static
-bt_component_class_sink_consume_method_status sink_consume(
- bt_self_component_sink *self_comp)
-{
- return BT_COMPONENT_CLASS_SINK_CONSUME_METHOD_STATUS_OK;
-}
-
-static
-bt_graph_listener_func_status graph_src_output_port_added(
- const bt_component_source *comp, const bt_port_output *port,
- void *data)
-{
- struct event event = {
- .type = GRAPH_SRC_OUTPUT_PORT_ADDED,
- .data.graph_src_output_port_added = {
- .comp = bt_component_source_as_component_const(comp),
- .port = bt_port_output_as_port_const(port),
- },
- };
-
- append_event(&event);
-
- return BT_GRAPH_LISTENER_FUNC_STATUS_OK;
-}
-
-static
-bt_graph_listener_func_status graph_sink_input_port_added(
- const bt_component_sink *comp, const bt_port_input *port,
- void *data)
-{
- struct event event = {
- .type = GRAPH_SINK_INPUT_PORT_ADDED,
- .data.graph_sink_input_port_added = {
- .comp = bt_component_sink_as_component_const(comp),
- .port = bt_port_input_as_port_const(port),
- },
- };
-
- append_event(&event);
-
- return BT_GRAPH_LISTENER_FUNC_STATUS_OK;
-}
-
-static
-void init_test(void)
-{
- int ret;
-
- msg_iter_class = bt_message_iterator_class_create(src_iter_next);
- BT_ASSERT(msg_iter_class);
-
- src_comp_class = bt_component_class_source_create(
- "src", msg_iter_class);
- BT_ASSERT(src_comp_class);
- ret = bt_component_class_source_set_initialize_method(
- src_comp_class, src_init);
- BT_ASSERT(ret == 0);
- ret = bt_component_class_source_set_output_port_connected_method(
- src_comp_class, src_output_port_connected);
- BT_ASSERT(ret == 0);
- sink_comp_class = bt_component_class_sink_create("sink",
- sink_consume);
- BT_ASSERT(sink_comp_class);
- ret = bt_component_class_sink_set_initialize_method(sink_comp_class,
- sink_init);
- BT_ASSERT(ret == 0);
- ret = bt_component_class_sink_set_input_port_connected_method(
- sink_comp_class, sink_input_port_connected);
- BT_ASSERT(ret == 0);
- events = g_array_new(FALSE, TRUE, sizeof(struct event));
- BT_ASSERT(events);
-}
-
-static
-void fini_test(void)
-{
- bt_component_class_source_put_ref(src_comp_class);
- bt_component_class_sink_put_ref(sink_comp_class);
- g_array_free(events, TRUE);
- BT_MESSAGE_ITERATOR_CLASS_PUT_REF_AND_RESET(msg_iter_class);
-}
-
-static
-const bt_component_source *create_src(bt_graph *graph)
-{
- const bt_component_source *comp;
- int ret;
-
- ret = bt_graph_add_source_component(graph, src_comp_class,
- "src-comp", NULL, BT_LOGGING_LEVEL_NONE, &comp);
- BT_ASSERT(ret == 0);
- return comp;
-}
-
-static
-const bt_component_sink *create_sink(bt_graph *graph)
-{
- const bt_component_sink *comp;
- int ret;
-
- ret = bt_graph_add_sink_component(graph, sink_comp_class,
- "sink-comp", NULL, BT_LOGGING_LEVEL_NONE, &comp);
- BT_ASSERT(ret == 0);
- return comp;
-}
-
-static
-bt_graph *create_graph(void)
-{
- bt_graph *graph = bt_graph_create(0);
- int ret;
-
- BT_ASSERT(graph);
- ret = bt_graph_add_source_component_output_port_added_listener(
- graph, graph_src_output_port_added, NULL, NULL);
- BT_ASSERT(ret >= 0);
- ret = bt_graph_add_sink_component_input_port_added_listener(
- graph, graph_sink_input_port_added, NULL, NULL);
- BT_ASSERT(ret >= 0);
- return graph;
-}
-
-static
-void prepare_test(enum test test, const char *name)
-{
- clear_events();
- current_test = test;
- diag("test: %s", name);
-}
-
-static
-void test_src_adds_port_in_port_connected(void)
-{
- const bt_component_source *src;
- const bt_component_sink *sink;
- const bt_component *gsrc;
- const bt_component *gsink;
- bt_graph *graph;
- const bt_port_output *src_def_port;
- const bt_port_output *src_hello_port;
- const bt_port_input *sink_def_port;
- const bt_port *gsrc_def_port;
- const bt_port *gsrc_hello_port;
- const bt_port *gsink_def_port;
- struct event event;
- bt_graph_connect_ports_status status;
- size_t src_port_connected_pos;
- size_t graph_port_added_src_pos;
-
- prepare_test(TEST_SRC_ADDS_PORT_IN_PORT_CONNECTED,
- "source adds port in port connected");
- graph = create_graph();
- BT_ASSERT(graph);
- src = create_src(graph);
- sink = create_sink(graph);
- src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
- "out");
- BT_ASSERT(src_def_port);
- sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
- "in");
- BT_ASSERT(sink_def_port);
- status = bt_graph_connect_ports(graph, src_def_port,
- sink_def_port, NULL);
- BT_ASSERT(status == 0);
- src_hello_port = bt_component_source_borrow_output_port_by_name_const(src,
- "hello");
- BT_ASSERT(src_hello_port);
- gsrc = bt_component_source_as_component_const(src);
- gsink = bt_component_sink_as_component_const(sink);
- gsrc_def_port = bt_port_output_as_port_const(src_def_port);
- gsrc_hello_port = bt_port_output_as_port_const(src_hello_port);
- gsink_def_port = bt_port_input_as_port_const(sink_def_port);
-
- /* We're supposed to have 5 events */
- ok(events->len == 5, "we have the expected number of events");
-
- /* Source's port added */
- event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
- event.data.graph_src_output_port_added.comp = gsrc;
- event.data.graph_src_output_port_added.port = gsrc_def_port;
- ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
-
- /* Sink's port added */
- event.type = GRAPH_SINK_INPUT_PORT_ADDED;
- event.data.graph_sink_input_port_added.comp = gsink;
- event.data.graph_sink_input_port_added.port = gsink_def_port;
- ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
-
- /* Source's port connected */
- event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
- event.data.src_comp_output_port_connected.comp = gsrc;
- event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
- event.data.src_comp_output_port_connected.other_port = gsink_def_port;
- ok(has_event(&event), "got the expected source's port connected event");
- src_port_connected_pos = event_pos(&event);
-
- /* Graph's port added (source) */
- event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
- event.data.graph_src_output_port_added.comp = gsrc;
- event.data.graph_src_output_port_added.port = gsrc_hello_port;
- ok(has_event(&event), "got the expected graph's port added event (for source)");
- graph_port_added_src_pos = event_pos(&event);
-
- /* Sink's port connected */
- event.type = SINK_COMP_INPUT_PORT_CONNECTED;
- event.data.sink_comp_input_port_connected.comp = gsink;
- event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
- event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
- ok(has_event(&event), "got the expected sink's port connected event");
-
- /* Order of events */
- ok(src_port_connected_pos < graph_port_added_src_pos,
- "event order is good");
-
- bt_graph_put_ref(graph);
-}
-
-static
-void test_simple(void)
-{
- const bt_component_source *src;
- const bt_component_sink *sink;
- const bt_component *gsrc;
- const bt_component *gsink;
- bt_graph *graph;
- const bt_port_output *src_def_port;
- const bt_port_input *sink_def_port;
- const bt_port *gsrc_def_port;
- const bt_port *gsink_def_port;
- struct event event;
- bt_graph_connect_ports_status status;
-
- prepare_test(TEST_SIMPLE, "simple");
- graph = create_graph();
- BT_ASSERT(graph);
- src = create_src(graph);
- sink = create_sink(graph);
- src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
- "out");
- BT_ASSERT(src_def_port);
- sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
- "in");
- BT_ASSERT(sink_def_port);
- status = bt_graph_connect_ports(graph, src_def_port,
- sink_def_port, NULL);
- BT_ASSERT(status == 0);
- gsrc = bt_component_source_as_component_const(src);
- gsink = bt_component_sink_as_component_const(sink);
- gsrc_def_port = bt_port_output_as_port_const(src_def_port);
- gsink_def_port = bt_port_input_as_port_const(sink_def_port);
-
- /* We're supposed to have 4 events */
- ok(events->len == 4, "we have the expected number of events");
-
- /* Source's port added */
- event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
- event.data.graph_src_output_port_added.comp = gsrc;
- event.data.graph_src_output_port_added.port = gsrc_def_port;
- ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
-
- /* Sink's port added */
- event.type = GRAPH_SINK_INPUT_PORT_ADDED;
- event.data.graph_sink_input_port_added.comp = gsink;
- event.data.graph_sink_input_port_added.port = gsink_def_port;
- ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
-
- /* Source's port connected */
- event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
- event.data.src_comp_output_port_connected.comp = gsrc;
- event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
- event.data.src_comp_output_port_connected.other_port = gsink_def_port;
- ok(has_event(&event), "got the expected source's port connected event");
-
- /* Sink's port connected */
- event.type = SINK_COMP_INPUT_PORT_CONNECTED;
- event.data.sink_comp_input_port_connected.comp = gsink;
- event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
- event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
- ok(has_event(&event), "got the expected sink's port connected event");
-
- bt_graph_put_ref(graph);
-}
-
-static
-void test_src_port_connected_error(void)
-{
- const bt_component_source *src;
- const bt_component_sink *sink;
- const bt_component *gsrc;
- const bt_component *gsink;
- bt_graph *graph;
- const bt_port_output *src_def_port;
- const bt_port_input *sink_def_port;
- const bt_port *gsrc_def_port;
- const bt_port *gsink_def_port;
- const bt_connection *conn = NULL;
- struct event event;
- bt_graph_connect_ports_status status;
-
- prepare_test(TEST_SRC_PORT_CONNECTED_ERROR, "port connected error: source");
- graph = create_graph();
- BT_ASSERT(graph);
- src = create_src(graph);
- sink = create_sink(graph);
- src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
- "out");
- BT_ASSERT(src_def_port);
- sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
- "in");
- BT_ASSERT(sink_def_port);
- status = bt_graph_connect_ports(graph, src_def_port,
- sink_def_port, &conn);
- ok(status != BT_GRAPH_CONNECT_PORTS_STATUS_OK,
- "bt_graph_connect_ports() returns an error");
- bt_current_thread_clear_error();
- ok(!conn, "returned connection is still NULL");
- gsrc = bt_component_source_as_component_const(src);
- gsink = bt_component_sink_as_component_const(sink);
- gsrc_def_port = bt_port_output_as_port_const(src_def_port);
- gsink_def_port = bt_port_input_as_port_const(sink_def_port);
-
- /* We're supposed to have 3 events */
- ok(events->len == 3, "we have the expected number of events");
-
- /* Source's port added */
- event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
- event.data.graph_src_output_port_added.comp = gsrc;
- event.data.graph_src_output_port_added.port = gsrc_def_port;
- ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
-
- /* Sink's port added */
- event.type = GRAPH_SINK_INPUT_PORT_ADDED;
- event.data.graph_sink_input_port_added.comp = gsink;
- event.data.graph_sink_input_port_added.port = gsink_def_port;
- ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
-
- /* Source's port connected */
- event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
- event.data.src_comp_output_port_connected.comp = gsrc;
- event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
- event.data.src_comp_output_port_connected.other_port = gsink_def_port;
- ok(has_event(&event), "got the expected source's port connected event");
-
- bt_graph_put_ref(graph);
-}
-
-static
-void test_sink_port_connected_error(void)
-{
- const bt_component_source *src;
- const bt_component_sink *sink;
- const bt_component *gsrc;
- const bt_component *gsink;
- bt_graph *graph;
- const bt_port_output *src_def_port;
- const bt_port_input *sink_def_port;
- const bt_port *gsrc_def_port;
- const bt_port *gsink_def_port;
- const bt_connection *conn = NULL;
- struct event event;
- bt_graph_connect_ports_status status;
-
- prepare_test(TEST_SINK_PORT_CONNECTED_ERROR, "port connected error: sink");
- graph = create_graph();
- BT_ASSERT(graph);
- src = create_src(graph);
- sink = create_sink(graph);
- src_def_port = bt_component_source_borrow_output_port_by_name_const(src,
- "out");
- BT_ASSERT(src_def_port);
- sink_def_port = bt_component_sink_borrow_input_port_by_name_const(sink,
- "in");
- BT_ASSERT(sink_def_port);
- status = bt_graph_connect_ports(graph, src_def_port,
- sink_def_port, &conn);
- ok(status != BT_GRAPH_CONNECT_PORTS_STATUS_OK,
- "bt_graph_connect_ports() returns an error");
- bt_current_thread_clear_error();
- ok(!conn, "returned connection is still NULL");
- gsrc = bt_component_source_as_component_const(src);
- gsink = bt_component_sink_as_component_const(sink);
- gsrc_def_port = bt_port_output_as_port_const(src_def_port);
- gsink_def_port = bt_port_input_as_port_const(sink_def_port);
-
- /* We're supposed to have 4 events */
- ok(events->len == 4, "we have the expected number of events");
-
- /* Source's port added */
- event.type = GRAPH_SRC_OUTPUT_PORT_ADDED;
- event.data.graph_src_output_port_added.comp = gsrc;
- event.data.graph_src_output_port_added.port = gsrc_def_port;
- ok(has_event(&event), "got the expected graph's port added event (for source, initial)");
-
- /* Sink's port added */
- event.type = GRAPH_SINK_INPUT_PORT_ADDED;
- event.data.graph_sink_input_port_added.comp = gsink;
- event.data.graph_sink_input_port_added.port = gsink_def_port;
- ok(has_event(&event), "got the expected graph's port added event (for sink, initial)");
-
- /* Source's port connected */
- event.type = SRC_COMP_OUTPUT_PORT_CONNECTED;
- event.data.src_comp_output_port_connected.comp = gsrc;
- event.data.src_comp_output_port_connected.self_port = gsrc_def_port;
- event.data.src_comp_output_port_connected.other_port = gsink_def_port;
- ok(has_event(&event), "got the expected source's port connected event");
-
- /* Sink's port connected */
- event.type = SINK_COMP_INPUT_PORT_CONNECTED;
- event.data.sink_comp_input_port_connected.comp = gsink;
- event.data.sink_comp_input_port_connected.self_port = gsink_def_port;
- event.data.sink_comp_input_port_connected.other_port = gsrc_def_port;
- ok(has_event(&event), "got the expected sink's port connected event");
-
- bt_graph_put_ref(graph);
-}
-
-static
-void test_empty_graph(void)
-{
- bt_graph *graph;
-
- prepare_test(TEST_EMPTY_GRAPH, "empty graph");
- graph = create_graph();
- ok(events->len == 0, "empty graph generates no events");
- bt_graph_put_ref(graph);
-}
-
-int main(int argc, char **argv)
-{
- plan_tests(NR_TESTS);
- init_test();
- test_empty_graph();
- test_simple();
- test_src_port_connected_error();
- test_sink_port_connected_error();
- test_src_adds_port_in_port_connected();
- fini_test();
- return exit_status();
-}
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-"${BT_TESTS_BUILDDIR}/lib/plugin" "${BT_TESTS_BUILDDIR}/lib/test-plugin-plugins/.libs"
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2019 Efficios, Inc.
- */
-
-/*
- * Test that remove a trace class or trace destruction listener from within
- * a destruction listener of the same object works.
- */
-
-#include <babeltrace2/babeltrace.h>
-#include <common/assert.h>
-#include <tap/tap.h>
-#include <stdbool.h>
-
-#define NR_TESTS 16
-
-static bt_listener_id trace_class_destroyed_1_id;
-static bt_listener_id trace_class_destroyed_2_id;
-static bt_listener_id trace_class_destroyed_3_id;
-static bt_listener_id trace_class_destroyed_4_id;
-static bt_listener_id trace_class_destroyed_5_id;
-
-static bt_listener_id trace_destroyed_1_id;
-static bt_listener_id trace_destroyed_2_id;
-static bt_listener_id trace_destroyed_3_id;
-static bt_listener_id trace_destroyed_4_id;
-static bt_listener_id trace_destroyed_5_id;
-
-static bool trace_class_destroyed_1_called = false;
-static bool trace_class_destroyed_2_called = false;
-static bool trace_class_destroyed_3_called = false;
-static bool trace_class_destroyed_4_called = false;
-static bool trace_class_destroyed_5_called = false;
-
-static bool trace_destroyed_1_called = false;
-static bool trace_destroyed_2_called = false;
-static bool trace_destroyed_3_called = false;
-static bool trace_destroyed_4_called = false;
-static bool trace_destroyed_5_called = false;
-
-static
-void trace_class_destroyed_1(const bt_trace_class *tc, void *data)
-{
- trace_class_destroyed_1_called = true;
-}
-
-static
-void trace_class_destroyed_2(const bt_trace_class *tc, void *data)
-{
- bt_trace_class_remove_listener_status remove_listener_status;
-
- trace_class_destroyed_2_called = true;
-
- /* Remove self. You shall not crash. */
- remove_listener_status = bt_trace_class_remove_destruction_listener(
- tc, trace_class_destroyed_2_id);
- ok(remove_listener_status == BT_TRACE_CLASS_REMOVE_LISTENER_STATUS_OK,
- "remove trace class listener 2 from 2");
-}
-
-static
-void trace_class_destroyed_3(const bt_trace_class *tc, void *data)
-{
- bt_trace_class_remove_listener_status remove_listener_status;
-
- trace_class_destroyed_3_called = true;
-
- /* Remove an already called listener. */
- remove_listener_status = bt_trace_class_remove_destruction_listener(
- tc, trace_class_destroyed_1_id);
- ok(remove_listener_status == BT_TRACE_CLASS_REMOVE_LISTENER_STATUS_OK,
- "remove trace class listener 1 from 3");
-}
-
-static
-void trace_class_destroyed_4(const bt_trace_class *tc, void *data)
-{
- bt_trace_class_remove_listener_status remove_listener_status;
-
- trace_class_destroyed_4_called = true;
-
- /* Remove a not yet called listener. */
- remove_listener_status = bt_trace_class_remove_destruction_listener(
- tc, trace_class_destroyed_5_id);
- ok(remove_listener_status == BT_TRACE_CLASS_REMOVE_LISTENER_STATUS_OK,
- "remove trace class listener 5 from 4");
-}
-
-static
-void trace_class_destroyed_5(const bt_trace_class *tc, void *data)
-{
- trace_class_destroyed_5_called = true;
-}
-
-static
-void trace_destroyed_1(const bt_trace *t, void *data)
-{
- trace_destroyed_1_called = true;
-}
-
-static
-void trace_destroyed_2(const bt_trace *t, void *data)
-{
- bt_trace_remove_listener_status remove_listener_status;
-
- trace_destroyed_2_called = true;
-
- /* Remove self. You shall not crash. */
- remove_listener_status = bt_trace_remove_destruction_listener(
- t, trace_destroyed_2_id);
- ok(remove_listener_status == BT_TRACE_REMOVE_LISTENER_STATUS_OK,
- "remove trace listener 2 from 2");
-}
-
-static
-void trace_destroyed_3(const bt_trace *t, void *data)
-{
- bt_trace_remove_listener_status remove_listener_status;
-
- trace_destroyed_3_called = true;
-
- /* Remove an already called listener. */
- remove_listener_status = bt_trace_remove_destruction_listener(
- t, trace_destroyed_1_id);
- ok(remove_listener_status == BT_TRACE_REMOVE_LISTENER_STATUS_OK,
- "remove trace listener 1 from 3");
-}
-
-static
-void trace_destroyed_4(const bt_trace *t, void *data)
-{
- bt_trace_remove_listener_status remove_listener_status;
-
- trace_destroyed_4_called = true;
-
- /* Remove a not yet called listener. */
- remove_listener_status = bt_trace_remove_destruction_listener(
- t, trace_destroyed_5_id);
- ok(remove_listener_status == BT_TRACE_REMOVE_LISTENER_STATUS_OK,
- "remove trace listener 5 from 4");
-}
-
-static
-void trace_destroyed_5(const bt_trace *t, void *data)
-{
- trace_destroyed_5_called = true;
-}
-
-static
-bt_component_class_initialize_method_status hello_init(
- bt_self_component_source *self_component,
- bt_self_component_source_configuration *config,
- const bt_value *params, void *init_method_data)
-{
- bt_self_component *self_comp;
- bt_trace_class *tc;
- bt_trace *t;
- bt_trace_class_add_listener_status trace_class_add_listener_status;
- bt_trace_add_listener_status trace_add_listener_status;
-
- self_comp = bt_self_component_source_as_self_component(self_component);
- tc = bt_trace_class_create(self_comp);
- BT_ASSERT(tc);
-
- trace_class_add_listener_status = bt_trace_class_add_destruction_listener(
- tc, trace_class_destroyed_1, NULL, &trace_class_destroyed_1_id);
- BT_ASSERT(trace_class_add_listener_status == BT_TRACE_CLASS_ADD_LISTENER_STATUS_OK);
-
- trace_class_add_listener_status = bt_trace_class_add_destruction_listener(
- tc, trace_class_destroyed_2, NULL, &trace_class_destroyed_2_id);
- BT_ASSERT(trace_class_add_listener_status == BT_TRACE_CLASS_ADD_LISTENER_STATUS_OK);
-
- trace_class_add_listener_status = bt_trace_class_add_destruction_listener(
- tc, trace_class_destroyed_3, NULL, &trace_class_destroyed_3_id);
- BT_ASSERT(trace_class_add_listener_status == BT_TRACE_CLASS_ADD_LISTENER_STATUS_OK);
-
- trace_class_add_listener_status = bt_trace_class_add_destruction_listener(
- tc, trace_class_destroyed_4, NULL, &trace_class_destroyed_4_id);
- BT_ASSERT(trace_class_add_listener_status == BT_TRACE_CLASS_ADD_LISTENER_STATUS_OK);
-
- trace_class_add_listener_status = bt_trace_class_add_destruction_listener(
- tc, trace_class_destroyed_5, NULL, &trace_class_destroyed_5_id);
- BT_ASSERT(trace_class_add_listener_status == BT_TRACE_CLASS_ADD_LISTENER_STATUS_OK);
-
- t = bt_trace_create(tc);
- BT_ASSERT(t);
-
- trace_add_listener_status = bt_trace_add_destruction_listener(
- t, trace_destroyed_1, NULL, &trace_destroyed_1_id);
- BT_ASSERT(trace_add_listener_status == BT_TRACE_ADD_LISTENER_STATUS_OK);
-
- trace_add_listener_status = bt_trace_add_destruction_listener(
- t, trace_destroyed_2, NULL, &trace_destroyed_2_id);
- BT_ASSERT(trace_add_listener_status == BT_TRACE_ADD_LISTENER_STATUS_OK);
-
- trace_add_listener_status = bt_trace_add_destruction_listener(
- t, trace_destroyed_3, NULL, &trace_destroyed_3_id);
- BT_ASSERT(trace_add_listener_status == BT_TRACE_ADD_LISTENER_STATUS_OK);
-
- trace_add_listener_status = bt_trace_add_destruction_listener(
- t, trace_destroyed_4, NULL, &trace_destroyed_4_id);
- BT_ASSERT(trace_add_listener_status == BT_TRACE_ADD_LISTENER_STATUS_OK);
-
- trace_add_listener_status = bt_trace_add_destruction_listener(
- t, trace_destroyed_5, NULL, &trace_destroyed_5_id);
- BT_ASSERT(trace_add_listener_status == BT_TRACE_ADD_LISTENER_STATUS_OK);
-
- /* Destroy the trace. */
- bt_trace_put_ref(t);
-
- ok(trace_destroyed_1_called, "trace destruction listener 1 called");
- ok(trace_destroyed_2_called, "trace destruction listener 2 called");
- ok(trace_destroyed_3_called, "trace destruction listener 3 called");
- ok(trace_destroyed_4_called, "trace destruction listener 4 called");
- ok(!trace_destroyed_5_called, "trace destruction listener 5 not called");
-
- /* Destroy the trace class. */
- bt_trace_class_put_ref(tc);
-
- ok(trace_class_destroyed_1_called, "trace class destruction listener 1 called");
- ok(trace_class_destroyed_2_called, "trace class destruction listener 2 called");
- ok(trace_class_destroyed_3_called, "trace class destruction listener 3 called");
- ok(trace_class_destroyed_4_called, "trace class destruction listener 4 called");
- ok(!trace_class_destroyed_5_called, "trace class destruction listener 5 not called");
-
- return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
-}
-
-static
-bt_message_iterator_class_next_method_status hello_iter_next(
- bt_self_message_iterator *message_iterator,
- bt_message_array_const msgs, uint64_t capacity,
- uint64_t *count)
-{
- BT_ASSERT(false);
- return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK;
-}
-
-int main(int argc, char **argv)
-{
- bt_graph *graph;
- bt_message_iterator_class *msg_iter_cls;
- bt_component_class_source *source_cc;
- bt_component_class_set_method_status set_method_status;
- bt_graph_add_component_status add_component_status;
- const bt_component_source *source;
-
- plan_tests(NR_TESTS);
-
- msg_iter_cls = bt_message_iterator_class_create(hello_iter_next);
- BT_ASSERT(msg_iter_cls);
-
- source_cc = bt_component_class_source_create("Hello", msg_iter_cls);
- BT_ASSERT(source_cc);
-
- set_method_status = bt_component_class_source_set_initialize_method(
- source_cc, hello_init);
- BT_ASSERT(set_method_status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK);
-
- graph = bt_graph_create(0);
- BT_ASSERT(graph);
-
- add_component_status = bt_graph_add_source_component(
- graph, source_cc, "name", NULL,
- BT_LOGGING_LEVEL_WARNING, &source);
- BT_ASSERT(add_component_status == BT_GRAPH_ADD_COMPONENT_STATUS_OK);
-
- bt_component_class_source_put_ref(source_cc);
- bt_message_iterator_class_put_ref(msg_iter_cls);
- bt_graph_put_ref(graph);
-
- return exit_status();
-}
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
- */
-
-#include <babeltrace2/babeltrace.h>
-#include "common/assert.h"
-#include <string.h>
-#include "tap/tap.h"
-
-#define NR_TESTS 68
-
-struct test_data {
- bt_graph_simple_sink_component_initialize_func_status init_status;
- bt_graph_simple_sink_component_consume_func_status consume_status;
-};
-
-static
-bt_graph_simple_sink_component_initialize_func_status simple_INITIALIZE_func(
- bt_message_iterator *iterator,
- void *data)
-{
- struct test_data *test_data = data;
-
- ok(iterator, "Message iterator is not NULL in initialization function");
- ok(data, "Data is not NULL in initialization function");
- return test_data->init_status;
-}
-
-static
-bt_graph_simple_sink_component_consume_func_status simple_consume_func(
- bt_message_iterator *iterator,
- void *data)
-{
- struct test_data *test_data = data;
-
- ok(iterator, "Message iterator is not NULL in consume function");
- ok(data, "Data is not NULL in consume function");
- return test_data->consume_status;
-}
-
-static
-void simple_fini_func(void *data)
-{
- ok(data, "Data is not NULL in finalization function");
-}
-
-static
-bt_component_class_initialize_method_status src_init(
- bt_self_component_source *self_comp,
- bt_self_component_source_configuration *config,
- const bt_value *params, void *init_method_data)
-{
- bt_self_component_add_port_status status;
-
- status = bt_self_component_source_add_output_port(self_comp,
- "out", NULL, NULL);
- BT_ASSERT(status == BT_SELF_COMPONENT_ADD_PORT_STATUS_OK);
- return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
-}
-
-static
-bt_message_iterator_class_next_method_status src_iter_next(
- bt_self_message_iterator *message_iterator,
- bt_message_array_const msgs, uint64_t capacity,
- uint64_t *count)
-{
- return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END;
-}
-
-static
-bt_graph *create_graph_with_source(const bt_port_output **out_port)
-{
- bt_message_iterator_class *msg_iter_cls;
- bt_component_class_source *src_comp_cls;
- bt_graph *graph;
- const bt_component_source *src_comp = NULL;
- bt_graph_add_component_status add_comp_status;
- bt_component_class_set_method_status set_method_status;
-
- BT_ASSERT(out_port);
-
- msg_iter_cls = bt_message_iterator_class_create(src_iter_next);
- BT_ASSERT(msg_iter_cls);
-
- src_comp_cls = bt_component_class_source_create("src", msg_iter_cls);
- BT_ASSERT(src_comp_cls);
- set_method_status = bt_component_class_source_set_initialize_method(
- src_comp_cls, src_init);
- BT_ASSERT(set_method_status == BT_COMPONENT_CLASS_SET_METHOD_STATUS_OK);
- graph = bt_graph_create(0);
- BT_ASSERT(graph);
- add_comp_status = bt_graph_add_source_component(graph, src_comp_cls,
- "src", NULL, BT_LOGGING_LEVEL_NONE, &src_comp);
- BT_ASSERT(add_comp_status == BT_GRAPH_ADD_COMPONENT_STATUS_OK);
- BT_ASSERT(src_comp);
- *out_port = bt_component_source_borrow_output_port_by_index_const(
- src_comp, 0);
- BT_ASSERT(*out_port);
- bt_component_class_source_put_ref(src_comp_cls);
- bt_message_iterator_class_put_ref(msg_iter_cls);
- return graph;
-}
-
-static
-void test_simple_expect_run_once_status(
- bt_graph_simple_sink_component_initialize_func_status init_status,
- bt_graph_simple_sink_component_consume_func_status consume_status,
- bt_graph_run_once_status exp_run_once_status)
-{
- const bt_port_output *src_out_port = NULL;
- bt_graph *graph;
- const bt_component_sink *sink_comp = NULL;
- const bt_port_input *sink_in_port;
- bt_graph_add_component_status add_comp_status;
- bt_graph_run_once_status run_once_status;
- bt_graph_connect_ports_status connect_status;
- struct test_data test_data = {
- .init_status = init_status,
- .consume_status = consume_status,
- };
- const struct bt_error *err;
-
- graph = create_graph_with_source(&src_out_port);
- BT_ASSERT(graph);
- BT_ASSERT(src_out_port);
-
- add_comp_status = bt_graph_add_simple_sink_component(graph, "sink",
- simple_INITIALIZE_func, simple_consume_func, simple_fini_func,
- &test_data, &sink_comp);
- BT_ASSERT(add_comp_status == BT_GRAPH_ADD_COMPONENT_STATUS_OK);
- BT_ASSERT(sink_comp);
-
- sink_in_port = bt_component_sink_borrow_input_port_by_name_const(
- sink_comp, "in");
- ok(sink_in_port,
- "Simple sink component has an input port named \"in\"");
-
- connect_status = bt_graph_connect_ports(graph, src_out_port,
- sink_in_port, NULL);
- ok(connect_status == BT_GRAPH_CONNECT_PORTS_STATUS_OK,
- "Simple sink component's \"in\" port is connectable");
-
- run_once_status = bt_graph_run_once(graph);
- ok(run_once_status == exp_run_once_status,
- "Graph \"run once\" status is the expected one (status code: %d)",
- run_once_status);
-
- err = bt_current_thread_take_error();
- ok((run_once_status < 0) == (err != NULL),
- "Current thread error is set if bt_graph_run_once returned an error");
-
- bt_graph_put_ref(graph);
- if (err) {
- bt_error_release(err);
- }
-}
-
-int main(void)
-{
- plan_tests(NR_TESTS);
-
- /* Test initialization function status */
- test_simple_expect_run_once_status(
- BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
- BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_OK,
- BT_GRAPH_RUN_ONCE_STATUS_OK);
- test_simple_expect_run_once_status(
- BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_ERROR,
- BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_OK,
- BT_GRAPH_RUN_ONCE_STATUS_ERROR);
- test_simple_expect_run_once_status(
- BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_MEMORY_ERROR,
- BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_OK,
- BT_GRAPH_RUN_ONCE_STATUS_MEMORY_ERROR);
-
- /* Test "consume" function status */
- test_simple_expect_run_once_status(
- BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
- BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_OK,
- BT_GRAPH_RUN_ONCE_STATUS_OK);
- test_simple_expect_run_once_status(
- BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
- BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_ERROR,
- BT_GRAPH_RUN_ONCE_STATUS_ERROR);
- test_simple_expect_run_once_status(
- BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
- BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_MEMORY_ERROR,
- BT_GRAPH_RUN_ONCE_STATUS_MEMORY_ERROR);
- test_simple_expect_run_once_status(
- BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
- BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_AGAIN,
- BT_GRAPH_RUN_ONCE_STATUS_AGAIN);
- test_simple_expect_run_once_status(
- BT_GRAPH_SIMPLE_SINK_COMPONENT_INITIALIZE_FUNC_STATUS_OK,
- BT_GRAPH_SIMPLE_SINK_COMPONENT_CONSUME_FUNC_STATUS_END,
- BT_GRAPH_RUN_ONCE_STATUS_END);
-
- return exit_status();
-}
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2016 Jérémie Galarneau <jeremie.galarneau@efficios.com>
- *
- * Trace IR Reference Count test
- */
-
-#include <stdio.h>
-#include "tap/tap.h"
-#include <babeltrace2/babeltrace.h>
-#include "lib/object.h"
-#include "compat/stdlib.h"
-#include "common/assert.h"
-#include <babeltrace2-ctf-writer/writer.h>
-#include <babeltrace2-ctf-writer/clock.h>
-#include <babeltrace2-ctf-writer/clock-class.h>
-#include <babeltrace2-ctf-writer/stream.h>
-#include <babeltrace2-ctf-writer/event.h>
-#include <babeltrace2-ctf-writer/event-types.h>
-#include <babeltrace2-ctf-writer/event-fields.h>
-#include <babeltrace2-ctf-writer/stream-class.h>
-#include <babeltrace2-ctf-writer/trace.h>
-#include "common.h"
-
-#define NR_TESTS 37
-
-struct bt_user {
- bt_trace_class *tc;
- bt_stream_class *sc;
- bt_event_class *ec;
- bt_stream *stream;
- bt_event *event;
-};
-
-struct writer_user {
- struct bt_ctf_writer *writer;
- struct bt_ctf_trace *tc;
- struct bt_ctf_stream_class *sc;
- struct bt_ctf_event_class *ec;
- struct bt_ctf_stream *stream;
- struct bt_ctf_event *event;
-};
-
-const char *writer_user_names[] = {
- "writer",
- "trace",
- "stream class",
- "event class",
- "stream",
- "event",
-};
-
-static const size_t WRITER_USER_NR_ELEMENTS =
- sizeof(struct writer_user) / sizeof(void *);
-
-/**
- * Returns a structure containing the following fields:
- * - uint8_t payload_8;
- * - uint16_t payload_16;
- * - uint32_t payload_32;
- */
-static bt_field_class *create_integer_struct(bt_trace_class *trace_class)
-{
- int ret;
- bt_field_class *structure = NULL;
- bt_field_class *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
-
- structure = bt_field_class_structure_create(trace_class);
- BT_ASSERT(structure);
- ui8 = bt_field_class_integer_unsigned_create(trace_class);
- BT_ASSERT(ui8);
- bt_field_class_integer_set_field_value_range(ui8, 8);
- ret = bt_field_class_structure_append_member(structure,
- "payload_8", ui8);
- BT_ASSERT(ret == 0);
- ui16 = bt_field_class_integer_unsigned_create(trace_class);
- BT_ASSERT(ui16);
- bt_field_class_integer_set_field_value_range(ui16, 16);
- ret = bt_field_class_structure_append_member(structure,
- "payload_16", ui16);
- BT_ASSERT(ret == 0);
- ui32 = bt_field_class_integer_unsigned_create(trace_class);
- BT_ASSERT(ui32);
- bt_field_class_integer_set_field_value_range(ui32, 32);
- ret = bt_field_class_structure_append_member(structure,
- "payload_32", ui32);
- BT_ASSERT(ret == 0);
- BT_FIELD_CLASS_PUT_REF_AND_RESET(ui8);
- BT_FIELD_CLASS_PUT_REF_AND_RESET(ui16);
- BT_FIELD_CLASS_PUT_REF_AND_RESET(ui32);
- return structure;
-}
-
-static struct bt_ctf_field_type *create_writer_integer_struct(void)
-{
- int ret;
- struct bt_ctf_field_type *structure = NULL;
- struct bt_ctf_field_type *ui8 = NULL, *ui16 = NULL, *ui32 = NULL;
-
- structure = bt_ctf_field_type_structure_create();
- BT_ASSERT(structure);
- ui8 = bt_ctf_field_type_integer_create(8);
- BT_ASSERT(ui8);
- ret = bt_ctf_field_type_structure_add_field(structure, ui8,
- "payload_8");
- BT_ASSERT(ret == 0);
- ui16 = bt_ctf_field_type_integer_create(16);
- BT_ASSERT(ui16);
- ret = bt_ctf_field_type_structure_add_field(structure, ui16,
- "payload_16");
- BT_ASSERT(ret == 0);
- ui32 = bt_ctf_field_type_integer_create(32);
- BT_ASSERT(ui32);
- ret = bt_ctf_field_type_structure_add_field(structure, ui32,
- "payload_32");
- BT_ASSERT(ret == 0);
- BT_OBJECT_PUT_REF_AND_RESET(ui8);
- BT_OBJECT_PUT_REF_AND_RESET(ui16);
- BT_OBJECT_PUT_REF_AND_RESET(ui32);
- return structure;
-}
-
-/**
- * A simple event has the following payload:
- * - uint8_t payload_8;
- * - uint16_t payload_16;
- * - uint32_t payload_32;
- */
-static bt_event_class *create_simple_event(
- bt_stream_class *sc, const char *name)
-{
- int ret;
- bt_event_class *event = NULL;
- bt_field_class *payload = NULL;
-
- BT_ASSERT(name);
- event = bt_event_class_create(sc);
- BT_ASSERT(event);
- ret = bt_event_class_set_name(event, name);
- BT_ASSERT(ret == 0);
- payload = create_integer_struct(bt_stream_class_borrow_trace_class(sc));
- BT_ASSERT(payload);
- ret = bt_event_class_set_payload_field_class(event, payload);
- BT_ASSERT(ret == 0);
- BT_FIELD_CLASS_PUT_REF_AND_RESET(payload);
- return event;
-}
-
-/**
- * A complex event has the following payload:
- * - uint8_t payload_8;
- * - uint16_t payload_16;
- * - uint32_t payload_32;
- * - struct payload_struct:
- * - uint8_t payload_8;
- * - uint16_t payload_16;
- * - uint32_t payload_32;
- */
-static bt_event_class *create_complex_event(bt_stream_class *sc,
- const char *name)
-{
- int ret;
- bt_event_class *event = NULL;
- bt_field_class *inner = NULL, *outer = NULL;
- bt_trace_class *trace_class = bt_stream_class_borrow_trace_class(sc);
-
- BT_ASSERT(name);
- event = bt_event_class_create(sc);
- BT_ASSERT(event);
- ret = bt_event_class_set_name(event, name);
- BT_ASSERT(ret == 0);
- outer = create_integer_struct(trace_class);
- BT_ASSERT(outer);
- inner = create_integer_struct(trace_class);
- BT_ASSERT(inner);
- ret = bt_field_class_structure_append_member(outer,
- "payload_struct", inner);
- BT_ASSERT(ret == 0);
- ret = bt_event_class_set_payload_field_class(event, outer);
- BT_ASSERT(ret == 0);
- BT_FIELD_CLASS_PUT_REF_AND_RESET(inner);
- BT_FIELD_CLASS_PUT_REF_AND_RESET(outer);
- return event;
-}
-
-static void create_sc1(bt_trace_class *trace_class)
-{
- int ret;
- bt_event_class *ec1 = NULL, *ec2 = NULL;
- bt_stream_class *sc1 = NULL, *ret_stream = NULL;
-
- sc1 = bt_stream_class_create(trace_class);
- BT_ASSERT(sc1);
- ret = bt_stream_class_set_name(sc1, "sc1");
- BT_ASSERT(ret == 0);
- ec1 = create_complex_event(sc1, "ec1");
- BT_ASSERT(ec1);
- ec2 = create_simple_event(sc1, "ec2");
- BT_ASSERT(ec2);
- ret_stream = bt_event_class_borrow_stream_class(ec1);
- ok(ret_stream == sc1, "Borrow parent stream SC1 from EC1");
- ret_stream = bt_event_class_borrow_stream_class(ec2);
- ok(ret_stream == sc1, "Borrow parent stream SC1 from EC2");
- BT_EVENT_CLASS_PUT_REF_AND_RESET(ec1);
- BT_EVENT_CLASS_PUT_REF_AND_RESET(ec2);
- BT_STREAM_CLASS_PUT_REF_AND_RESET(sc1);
-}
-
-static void create_sc2(bt_trace_class *trace_class)
-{
- int ret;
- bt_event_class *ec3 = NULL;
- bt_stream_class *sc2 = NULL, *ret_stream = NULL;
-
- sc2 = bt_stream_class_create(trace_class);
- BT_ASSERT(sc2);
- ret = bt_stream_class_set_name(sc2, "sc2");
- BT_ASSERT(ret == 0);
- ec3 = create_simple_event(sc2, "ec3");
- ret_stream = bt_event_class_borrow_stream_class(ec3);
- ok(ret_stream == sc2, "Borrow parent stream SC2 from EC3");
- BT_EVENT_CLASS_PUT_REF_AND_RESET(ec3);
- BT_STREAM_CLASS_PUT_REF_AND_RESET(sc2);
-}
-
-static bt_trace_class *create_tc1(bt_self_component_source *self_comp)
-{
- bt_trace_class *tc1 = NULL;
-
- tc1 = bt_trace_class_create(
- bt_self_component_source_as_self_component(self_comp));
- BT_ASSERT(tc1);
- create_sc1(tc1);
- create_sc2(tc1);
- return tc1;
-}
-
-static void init_weak_refs(bt_trace_class *tc,
- bt_trace_class **tc1,
- bt_stream_class **sc1,
- bt_stream_class **sc2,
- bt_event_class **ec1,
- bt_event_class **ec2,
- bt_event_class **ec3)
-{
- *tc1 = tc;
- *sc1 = bt_trace_class_borrow_stream_class_by_index(tc, 0);
- *sc2 = bt_trace_class_borrow_stream_class_by_index(tc, 1);
- *ec1 = bt_stream_class_borrow_event_class_by_index(*sc1, 0);
- *ec2 = bt_stream_class_borrow_event_class_by_index(*sc1, 1);
- *ec3 = bt_stream_class_borrow_event_class_by_index(*sc2, 0);
-}
-
-static void test_example_scenario(bt_self_component_source *self_comp)
-{
- /*
- * Weak pointers to trace IR objects are to be used very
- * carefully. This is NOT a good practice and is strongly
- * discouraged; this is only done to facilitate the validation
- * of expected reference counts without affecting them by taking
- * "real" references to the objects.
- */
- bt_trace_class *tc1 = NULL, *weak_tc1 = NULL;
- bt_stream_class *weak_sc1 = NULL, *weak_sc2 = NULL;
- bt_event_class *weak_ec1 = NULL, *weak_ec2 = NULL,
- *weak_ec3 = NULL;
- struct bt_user user_a = { 0 }, user_b = { 0 }, user_c = { 0 };
-
- /* The only reference which exists at this point is on TC1. */
- tc1 = create_tc1(self_comp);
- ok(tc1, "Initialize trace");
- BT_ASSERT(tc1);
- init_weak_refs(tc1, &weak_tc1, &weak_sc1, &weak_sc2, &weak_ec1,
- &weak_ec2, &weak_ec3);
- ok(bt_object_get_ref_count((void *) weak_sc1) == 0,
- "Initial SC1 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
- "Initial SC2 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_ec1) == 0,
- "Initial EC1 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
- "Initial EC2 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
- "Initial EC3 reference count is 0");
-
- /* User A has ownership of the trace. */
- BT_OBJECT_MOVE_REF(user_a.tc, tc1);
- ok(bt_object_get_ref_count((void *) user_a.tc) == 1,
- "TC1 reference count is 1");
-
- /* User A acquires a reference to SC2 from TC1. */
- user_a.sc = bt_trace_class_borrow_stream_class_by_index(
- user_a.tc, 1);
- bt_stream_class_get_ref(user_a.sc);
- ok(user_a.sc, "User A acquires SC2 from TC1");
- ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
- "TC1 reference count is 2");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
- "SC2 reference count is 1");
-
- /* User A acquires a reference to EC3 from SC2. */
- user_a.ec = bt_stream_class_borrow_event_class_by_index(
- user_a.sc, 0);
- bt_event_class_get_ref(user_a.ec);
- ok(user_a.ec, "User A acquires EC3 from SC2");
- ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
- "TC1 reference count is 2");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 2,
- "SC2 reference count is 2");
- ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
- "EC3 reference count is 1");
-
- /* User A releases its reference to SC2. */
- diag("User A releases SC2");
- BT_STREAM_CLASS_PUT_REF_AND_RESET(user_a.sc);
- /*
- * We keep the pointer to SC2 around to validate its reference
- * count.
- */
- ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
- "TC1 reference count is 2");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
- "SC2 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
- "EC3 reference count is 1");
-
- /* User A releases its reference to TC1. */
- diag("User A releases TC1");
- BT_TRACE_CLASS_PUT_REF_AND_RESET(user_a.tc);
- /*
- * We keep the pointer to TC1 around to validate its reference
- * count.
- */
- ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
- "TC1 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 1,
- "SC2 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_ec3) == 1,
- "EC3 reference count is 1");
-
- /* User B acquires a reference to SC1. */
- diag("User B acquires a reference to SC1");
- user_b.sc = weak_sc1;
- bt_stream_class_get_ref(user_b.sc);
- ok(bt_object_get_ref_count((void *) weak_tc1) == 2,
- "TC1 reference count is 2");
- ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
- "SC1 reference count is 1");
-
- /* User C acquires a reference to EC1. */
- diag("User C acquires a reference to EC1");
- user_c.ec = bt_stream_class_borrow_event_class_by_index(
- user_b.sc, 0);
- bt_event_class_get_ref(user_c.ec);
- ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
- "EC1 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_sc1) == 2,
- "SC1 reference count is 2");
-
- /* User A releases its reference on EC3. */
- diag("User A releases its reference on EC3");
- BT_EVENT_CLASS_PUT_REF_AND_RESET(user_a.ec);
- ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
- "EC3 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
- "SC2 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
- "TC1 reference count is 1");
-
- /* User B releases its reference on SC1. */
- diag("User B releases its reference on SC1");
- BT_STREAM_CLASS_PUT_REF_AND_RESET(user_b.sc);
- ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
- "SC1 reference count is 1");
-
- /*
- * User C is the sole owner of an object and is keeping the whole
- * trace hierarchy "alive" by holding a reference to EC1.
- */
- ok(bt_object_get_ref_count((void *) weak_tc1) == 1,
- "TC1 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_sc1) == 1,
- "SC1 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_sc2) == 0,
- "SC2 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_ec1) == 1,
- "EC1 reference count is 1");
- ok(bt_object_get_ref_count((void *) weak_ec2) == 0,
- "EC2 reference count is 0");
- ok(bt_object_get_ref_count((void *) weak_ec3) == 0,
- "EC3 reference count is 0");
-
- /* Reclaim last reference held by User C. */
- BT_EVENT_CLASS_PUT_REF_AND_RESET(user_c.ec);
-}
-
-static
-bt_component_class_initialize_method_status src_init(
- bt_self_component_source *self_comp,
- bt_self_component_source_configuration *config,
- const bt_value *params, void *init_method_data)
-{
- test_example_scenario(self_comp);
- return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
-}
-
-static
-bt_message_iterator_class_next_method_status src_iter_next(
- bt_self_message_iterator *self_iterator,
- bt_message_array_const msgs, uint64_t capacity,
- uint64_t *count)
-{
- return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_ERROR;
-}
-
-static void test_example_scenario_in_graph(void)
-{
- bt_message_iterator_class *msg_iter_cls;
- bt_component_class_source *comp_cls;
- bt_graph *graph;
- int ret;
-
- msg_iter_cls = bt_message_iterator_class_create(src_iter_next);
- BT_ASSERT(msg_iter_cls);
-
- comp_cls = bt_component_class_source_create("src", msg_iter_cls);
- BT_ASSERT(comp_cls);
- ret = bt_component_class_source_set_initialize_method(comp_cls, src_init);
- BT_ASSERT(ret == 0);
- graph = bt_graph_create(0);
- ret = bt_graph_add_source_component(graph, comp_cls, "src-comp",
- NULL, BT_LOGGING_LEVEL_NONE, NULL);
- BT_ASSERT(ret == 0);
- bt_graph_put_ref(graph);
- bt_component_class_source_put_ref(comp_cls);
- bt_message_iterator_class_put_ref(msg_iter_cls);
-}
-
-static void create_writer_user_full(struct writer_user *user)
-{
- gchar *trace_path;
- struct bt_ctf_field_type *ft;
- struct bt_ctf_field *field;
- struct bt_ctf_clock *clock;
- int ret;
-
- trace_path = g_build_filename(g_get_tmp_dir(), "ctfwriter_XXXXXX", NULL);
- if (!bt_mkdtemp(trace_path)) {
- perror("# perror");
- }
-
- user->writer = bt_ctf_writer_create(trace_path);
- BT_ASSERT(user->writer);
- ret = bt_ctf_writer_set_byte_order(user->writer,
- BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
- BT_ASSERT(ret == 0);
- user->tc = bt_ctf_writer_get_trace(user->writer);
- BT_ASSERT(user->tc);
- user->sc = bt_ctf_stream_class_create("sc");
- BT_ASSERT(user->sc);
- clock = bt_ctf_clock_create("the_clock");
- BT_ASSERT(clock);
- ret = bt_ctf_writer_add_clock(user->writer, clock);
- BT_ASSERT(!ret);
- ret = bt_ctf_stream_class_set_clock(user->sc, clock);
- BT_ASSERT(!ret);
- BT_OBJECT_PUT_REF_AND_RESET(clock);
- user->stream = bt_ctf_writer_create_stream(user->writer, user->sc);
- BT_ASSERT(user->stream);
- user->ec = bt_ctf_event_class_create("ec");
- BT_ASSERT(user->ec);
- ft = create_writer_integer_struct();
- BT_ASSERT(ft);
- ret = bt_ctf_event_class_set_payload_field_type(user->ec, ft);
- BT_OBJECT_PUT_REF_AND_RESET(ft);
- BT_ASSERT(!ret);
- ret = bt_ctf_stream_class_add_event_class(user->sc, user->ec);
- BT_ASSERT(!ret);
- user->event = bt_ctf_event_create(user->ec);
- BT_ASSERT(user->event);
- field = bt_ctf_event_get_payload(user->event, "payload_8");
- BT_ASSERT(field);
- ret = bt_ctf_field_integer_unsigned_set_value(field, 10);
- BT_ASSERT(!ret);
- BT_OBJECT_PUT_REF_AND_RESET(field);
- field = bt_ctf_event_get_payload(user->event, "payload_16");
- BT_ASSERT(field);
- ret = bt_ctf_field_integer_unsigned_set_value(field, 20);
- BT_ASSERT(!ret);
- BT_OBJECT_PUT_REF_AND_RESET(field);
- field = bt_ctf_event_get_payload(user->event, "payload_32");
- BT_ASSERT(field);
- ret = bt_ctf_field_integer_unsigned_set_value(field, 30);
- BT_ASSERT(!ret);
- BT_OBJECT_PUT_REF_AND_RESET(field);
- ret = bt_ctf_stream_append_event(user->stream, user->event);
- BT_ASSERT(!ret);
- recursive_rmdir(trace_path);
- g_free(trace_path);
-}
-
-static void test_put_order_swap(size_t *array, size_t a, size_t b)
-{
- size_t temp = array[a];
-
- array[a] = array[b];
- array[b] = temp;
-}
-
-static void test_put_order_put_objects(size_t *array, size_t size)
-{
- size_t i;
- struct writer_user user = { 0 };
- void **objects = (void *) &user;
-
- create_writer_user_full(&user);
- printf("# ");
-
- for (i = 0; i < size; ++i) {
- void *obj = objects[array[i]];
-
- printf("%s", writer_user_names[array[i]]);
- BT_OBJECT_PUT_REF_AND_RESET(obj);
-
- if (i < size - 1) {
- printf(" -> ");
- }
- }
-
- puts("");
-}
-
-static void test_put_order_permute(size_t *array, int k, size_t size)
-{
- if (k == 0) {
- test_put_order_put_objects(array, size);
- } else {
- int i;
-
- for (i = k - 1; i >= 0; i--) {
- size_t next_k = k - 1;
-
- test_put_order_swap(array, i, next_k);
- test_put_order_permute(array, next_k, size);
- test_put_order_swap(array, i, next_k);
- }
- }
-}
-
-static void test_put_order(void)
-{
- size_t i;
- size_t array[WRITER_USER_NR_ELEMENTS];
-
- /* Initialize array of indexes */
- for (i = 0; i < WRITER_USER_NR_ELEMENTS; ++i) {
- array[i] = i;
- }
-
- test_put_order_permute(array, WRITER_USER_NR_ELEMENTS,
- WRITER_USER_NR_ELEMENTS);
-}
-
-/**
- * The objective of this test is to implement and expand upon the scenario
- * described in the reference counting documentation and ensure that any node of
- * the Trace, Stream Class, Event Class, Stream and Event hiearchy keeps all
- * other "alive" and reachable.
- *
- * External tools (e.g. valgrind) should be used to confirm that this
- * known-good test does not leak memory.
- */
-int main(int argc, char **argv)
-{
- /* Initialize tap harness before any tests */
- plan_tests(NR_TESTS);
-
- test_example_scenario_in_graph();
- test_put_order();
-
- return exit_status();
-}
AM_CPPFLAGS += -I$(top_srcdir)/tests/utils
-noinst_PROGRAMS = test_param_validation
-test_param_validation_SOURCES = test_param_validation.c
+noinst_PROGRAMS = test-param-validation
+test_param_validation_SOURCES = test-param-validation.c
test_param_validation_LDADD = \
$(top_builddir)/src/param-parse/libparam-parse.la \
$(top_builddir)/src/plugins/common/param-validation/libbabeltrace2-param-validation.la \
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) EfficiOS Inc.
+ */
+
+#include "tap/tap.h"
+#include "param-parse/param-parse.h"
+#include "plugins/common/param-validation/param-validation.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static
+enum bt_param_validation_status run_test(
+ const char *params_str,
+ const struct bt_param_validation_map_value_entry_descr *entries,
+ const char *test_name,
+ const char *expected_error)
+{
+ GString *err = g_string_new(NULL);
+ const bt_value *params;
+ enum bt_param_validation_status status;
+ gchar *validate_error = NULL;
+
+ if (!err) {
+ fprintf(stderr, "Failed to allocated a GString.\n");
+ abort();
+ }
+
+ params = bt_param_parse(params_str, err);
+
+ if (!params) {
+ fprintf(stderr, "Could not parse params: `%s`, %s\n",
+ params_str, err->str);
+ abort();
+ }
+
+ status = bt_param_validation_validate(params, entries, &validate_error);
+
+ if (expected_error) {
+ /* We expect a failure. */
+ ok(status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR,
+ "%s: validation fails", test_name);
+ ok(validate_error, "%s: error string is not NULL", test_name);
+
+#define BT_FMT "%s: error string contains expected string"
+ if (validate_error && strstr(validate_error, expected_error)) {
+ pass(BT_FMT, test_name);
+ } else {
+ fail(BT_FMT, test_name);
+ diag("could not find `%s` in `%s`", expected_error, validate_error);
+ }
+#undef BT_FMT
+
+ g_free(validate_error);
+ } else {
+ /* We expect a success. */
+ ok(status == BT_PARAM_VALIDATION_STATUS_OK, "%s: validation succeeds", test_name);
+ ok(!validate_error, "%s: error string is NULL", test_name);
+ }
+
+ bt_value_put_ref(params);
+ g_string_free(err, TRUE);
+
+ return status;
+}
+
+static
+void test_map_valid(void)
+{
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
+ { "fenouil", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_STRING } },
+ { "panais", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("carotte=2,fenouil=\"miam\"", entries, "valid map", NULL);
+}
+
+static
+void test_map_missing_key(void)
+{
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
+ { "tomate", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("carotte=2", entries, "missing key in map",
+ "Error validating parameters: missing mandatory entry `tomate`");
+}
+
+static
+void test_map_unexpected_key(void)
+{
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("tomate=2", entries, "unexpected key in map", "unexpected key `tomate`");
+}
+
+static
+void test_map_invalid_entry_value_type(void)
+{
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "carottes", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("carottes=\"orange\"", entries, "map entry with unexpected type",
+ "Error validating parameter `carottes`: unexpected type: expected-type=SIGNED_INTEGER, actual-type=STRING");
+}
+
+static
+void test_nested_error(void)
+{
+ const struct bt_param_validation_map_value_entry_descr poireau_entries[] = {
+ { "navet", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END,
+ };
+
+ const struct bt_param_validation_map_value_entry_descr carottes_elem_entries[] = {
+ { "poireau", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_MAP, .map = {
+ .entries = poireau_entries,
+ } } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END,
+ };
+
+ const struct bt_param_validation_value_descr carottes_elem = {
+ .type = BT_VALUE_TYPE_MAP,
+ .map = {
+ .entries = carottes_elem_entries,
+ }
+ };
+
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "carottes", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
+ .min_length = 0,
+ .max_length = BT_PARAM_VALIDATION_INFINITE,
+ .element_type = &carottes_elem,
+ } } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("carottes=[{poireau={navet=7}}, {poireau={}}]", entries, "error nested in maps and arrays",
+ "Error validating parameter `carottes[1].poireau`: missing mandatory entry `navet`");
+}
+
+static
+void test_array_valid(void)
+{
+ const struct bt_param_validation_value_descr carotte_elem = { .type = BT_VALUE_TYPE_BOOL, {} };
+
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
+ .min_length = 2,
+ .max_length = 22,
+ .element_type = &carotte_elem,
+ } } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("carotte=[true, false, true]", entries, "valid array", NULL);
+}
+
+static
+void test_array_empty_valid(void)
+{
+ const struct bt_param_validation_value_descr carotte_elem = { .type = BT_VALUE_TYPE_BOOL, {} };
+
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
+ .min_length = 0,
+ .max_length = 2,
+ .element_type = &carotte_elem,
+ } } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("carotte=[]", entries, "valid empty array", NULL);
+}
+
+static
+void test_array_invalid_too_small(void)
+{
+ const struct bt_param_validation_value_descr carotte_elem = { .type = BT_VALUE_TYPE_BOOL, {} };
+
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
+ .min_length = 1,
+ .max_length = 100,
+ .element_type = &carotte_elem,
+ } } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("carotte=[]", entries, "array too small",
+ "Error validating parameter `carotte`: array is smaller than the minimum length: array-length=0, min-length=1");
+}
+
+static
+void test_array_invalid_too_large(void)
+{
+ const struct bt_param_validation_value_descr carotte_elem = { .type = BT_VALUE_TYPE_BOOL, {} };
+
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
+ .min_length = 2,
+ .max_length = 2,
+ .element_type = &carotte_elem,
+ } } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("carotte=[true, false, false]", entries, "array too large",
+ "Error validating parameter `carotte`: array is larger than the maximum length: array-length=3, max-length=2");
+}
+
+static
+void test_array_invalid_elem_type(void)
+{
+ const struct bt_param_validation_value_descr carotte_elem = { .type = BT_VALUE_TYPE_BOOL, {} };
+
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
+ .min_length = 3,
+ .max_length = 3,
+ .element_type = &carotte_elem,
+ } } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("carotte=[true, false, 2]", entries, "array with invalid element type",
+ "Error validating parameter `carotte[2]`: unexpected type: expected-type=BOOL, actual-type=SIGNED_INTEGER");
+}
+
+static
+void test_string_valid_without_choices(void)
+{
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "haricot", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_STRING, { } } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("haricot=\"vert\"", entries, "valid string without choices", NULL);
+}
+
+static
+void test_string_valid_with_choices(void)
+{
+ const char *haricot_choices[] = {"vert", "jaune", "rouge", NULL};
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "haricot", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_STRING, .string = {
+ .choices = haricot_choices,
+ } } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("haricot=\"jaune\"", entries, "valid string with choices", NULL);
+}
+
+static
+void test_string_invalid_choice(void)
+{
+ const char *haricot_choices[] = {"vert", "jaune", "rouge", NULL};
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "haricot", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_STRING, .string = {
+ .choices = haricot_choices,
+ } } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("haricot=\"violet\"", entries, "string with invalid choice",
+ "Error validating parameter `haricot`: string is not amongst the available choices: string=violet, choices=[vert, jaune, rouge]");
+}
+
+static
+enum bt_param_validation_status custom_validation_func_valid(
+ const bt_value *value,
+ struct bt_param_validation_context *context)
+{
+ ok(bt_value_get_type(value) == BT_VALUE_TYPE_UNSIGNED_INTEGER,
+ "type of value passed to custom function is as expected");
+ ok(bt_value_integer_unsigned_get(value) == 1234,
+ "value passed to custom function is as expected");
+ return BT_PARAM_VALIDATION_STATUS_OK;
+}
+
+static
+void test_custom_validation_func_valid(void)
+{
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "navet", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, {
+ .validation_func = custom_validation_func_valid,
+ } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("navet=+1234", entries, "custom validation function with valid value", NULL);
+}
+
+static
+enum bt_param_validation_status custom_validation_func_invalid(
+ const bt_value *value,
+ struct bt_param_validation_context *context)
+{
+ return bt_param_validation_error(context, "wrooooong");
+}
+
+static
+void test_custom_validation_func_invalid(void)
+{
+ const struct bt_param_validation_map_value_entry_descr entries[] = {
+ { "navet", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, {
+ .validation_func = custom_validation_func_invalid,
+ } },
+ BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
+ };
+
+ run_test("navet=+1234", entries, "custom validation function with invalid value",
+ "Error validating parameter `navet`: wrooooong");
+}
+
+int main(void)
+{
+ plan_tests(41);
+
+ test_map_valid();
+
+ test_map_missing_key();
+ test_map_unexpected_key();
+ test_map_invalid_entry_value_type();
+
+ test_array_valid();
+ test_array_empty_valid();
+
+ test_array_invalid_too_small();
+ test_array_invalid_too_large();
+ test_array_invalid_elem_type();
+
+ test_string_valid_without_choices();
+ test_string_valid_with_choices();
+
+ test_string_invalid_choice();
+
+ test_custom_validation_func_valid();
+ test_custom_validation_func_invalid();
+
+ test_nested_error();
+
+ return exit_status();
+}
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) EfficiOS Inc.
- */
-
-#include "tap/tap.h"
-#include "param-parse/param-parse.h"
-#include "plugins/common/param-validation/param-validation.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static
-enum bt_param_validation_status run_test(
- const char *params_str,
- const struct bt_param_validation_map_value_entry_descr *entries,
- const char *test_name,
- const char *expected_error)
-{
- GString *err = g_string_new(NULL);
- const bt_value *params;
- enum bt_param_validation_status status;
- gchar *validate_error = NULL;
-
- if (!err) {
- fprintf(stderr, "Failed to allocated a GString.\n");
- abort();
- }
-
- params = bt_param_parse(params_str, err);
-
- if (!params) {
- fprintf(stderr, "Could not parse params: `%s`, %s\n",
- params_str, err->str);
- abort();
- }
-
- status = bt_param_validation_validate(params, entries, &validate_error);
-
- if (expected_error) {
- /* We expect a failure. */
- ok(status == BT_PARAM_VALIDATION_STATUS_VALIDATION_ERROR,
- "%s: validation fails", test_name);
- ok(validate_error, "%s: error string is not NULL", test_name);
-
-#define BT_FMT "%s: error string contains expected string"
- if (validate_error && strstr(validate_error, expected_error)) {
- pass(BT_FMT, test_name);
- } else {
- fail(BT_FMT, test_name);
- diag("could not find `%s` in `%s`", expected_error, validate_error);
- }
-#undef BT_FMT
-
- g_free(validate_error);
- } else {
- /* We expect a success. */
- ok(status == BT_PARAM_VALIDATION_STATUS_OK, "%s: validation succeeds", test_name);
- ok(!validate_error, "%s: error string is NULL", test_name);
- }
-
- bt_value_put_ref(params);
- g_string_free(err, TRUE);
-
- return status;
-}
-
-static
-void test_map_valid(void)
-{
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
- { "fenouil", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_STRING } },
- { "panais", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_OPTIONAL, { .type = BT_VALUE_TYPE_BOOL } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("carotte=2,fenouil=\"miam\"", entries, "valid map", NULL);
-}
-
-static
-void test_map_missing_key(void)
-{
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
- { "tomate", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("carotte=2", entries, "missing key in map",
- "Error validating parameters: missing mandatory entry `tomate`");
-}
-
-static
-void test_map_unexpected_key(void)
-{
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("tomate=2", entries, "unexpected key in map", "unexpected key `tomate`");
-}
-
-static
-void test_map_invalid_entry_value_type(void)
-{
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "carottes", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("carottes=\"orange\"", entries, "map entry with unexpected type",
- "Error validating parameter `carottes`: unexpected type: expected-type=SIGNED_INTEGER, actual-type=STRING");
-}
-
-static
-void test_nested_error(void)
-{
- const struct bt_param_validation_map_value_entry_descr poireau_entries[] = {
- { "navet", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_SIGNED_INTEGER } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END,
- };
-
- const struct bt_param_validation_map_value_entry_descr carottes_elem_entries[] = {
- { "poireau", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_MAP, .map = {
- .entries = poireau_entries,
- } } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END,
- };
-
- const struct bt_param_validation_value_descr carottes_elem = {
- .type = BT_VALUE_TYPE_MAP,
- .map = {
- .entries = carottes_elem_entries,
- }
- };
-
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "carottes", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
- .min_length = 0,
- .max_length = BT_PARAM_VALIDATION_INFINITE,
- .element_type = &carottes_elem,
- } } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("carottes=[{poireau={navet=7}}, {poireau={}}]", entries, "error nested in maps and arrays",
- "Error validating parameter `carottes[1].poireau`: missing mandatory entry `navet`");
-}
-
-static
-void test_array_valid(void)
-{
- const struct bt_param_validation_value_descr carotte_elem = { .type = BT_VALUE_TYPE_BOOL, {} };
-
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
- .min_length = 2,
- .max_length = 22,
- .element_type = &carotte_elem,
- } } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("carotte=[true, false, true]", entries, "valid array", NULL);
-}
-
-static
-void test_array_empty_valid(void)
-{
- const struct bt_param_validation_value_descr carotte_elem = { .type = BT_VALUE_TYPE_BOOL, {} };
-
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
- .min_length = 0,
- .max_length = 2,
- .element_type = &carotte_elem,
- } } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("carotte=[]", entries, "valid empty array", NULL);
-}
-
-static
-void test_array_invalid_too_small(void)
-{
- const struct bt_param_validation_value_descr carotte_elem = { .type = BT_VALUE_TYPE_BOOL, {} };
-
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
- .min_length = 1,
- .max_length = 100,
- .element_type = &carotte_elem,
- } } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("carotte=[]", entries, "array too small",
- "Error validating parameter `carotte`: array is smaller than the minimum length: array-length=0, min-length=1");
-}
-
-static
-void test_array_invalid_too_large(void)
-{
- const struct bt_param_validation_value_descr carotte_elem = { .type = BT_VALUE_TYPE_BOOL, {} };
-
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
- .min_length = 2,
- .max_length = 2,
- .element_type = &carotte_elem,
- } } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("carotte=[true, false, false]", entries, "array too large",
- "Error validating parameter `carotte`: array is larger than the maximum length: array-length=3, max-length=2");
-}
-
-static
-void test_array_invalid_elem_type(void)
-{
- const struct bt_param_validation_value_descr carotte_elem = { .type = BT_VALUE_TYPE_BOOL, {} };
-
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "carotte", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_ARRAY, .array = {
- .min_length = 3,
- .max_length = 3,
- .element_type = &carotte_elem,
- } } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("carotte=[true, false, 2]", entries, "array with invalid element type",
- "Error validating parameter `carotte[2]`: unexpected type: expected-type=BOOL, actual-type=SIGNED_INTEGER");
-}
-
-static
-void test_string_valid_without_choices(void)
-{
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "haricot", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { .type = BT_VALUE_TYPE_STRING, { } } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("haricot=\"vert\"", entries, "valid string without choices", NULL);
-}
-
-static
-void test_string_valid_with_choices(void)
-{
- const char *haricot_choices[] = {"vert", "jaune", "rouge", NULL};
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "haricot", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_STRING, .string = {
- .choices = haricot_choices,
- } } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("haricot=\"jaune\"", entries, "valid string with choices", NULL);
-}
-
-static
-void test_string_invalid_choice(void)
-{
- const char *haricot_choices[] = {"vert", "jaune", "rouge", NULL};
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "haricot", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, { BT_VALUE_TYPE_STRING, .string = {
- .choices = haricot_choices,
- } } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("haricot=\"violet\"", entries, "string with invalid choice",
- "Error validating parameter `haricot`: string is not amongst the available choices: string=violet, choices=[vert, jaune, rouge]");
-}
-
-static
-enum bt_param_validation_status custom_validation_func_valid(
- const bt_value *value,
- struct bt_param_validation_context *context)
-{
- ok(bt_value_get_type(value) == BT_VALUE_TYPE_UNSIGNED_INTEGER,
- "type of value passed to custom function is as expected");
- ok(bt_value_integer_unsigned_get(value) == 1234,
- "value passed to custom function is as expected");
- return BT_PARAM_VALIDATION_STATUS_OK;
-}
-
-static
-void test_custom_validation_func_valid(void)
-{
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "navet", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, {
- .validation_func = custom_validation_func_valid,
- } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("navet=+1234", entries, "custom validation function with valid value", NULL);
-}
-
-static
-enum bt_param_validation_status custom_validation_func_invalid(
- const bt_value *value,
- struct bt_param_validation_context *context)
-{
- return bt_param_validation_error(context, "wrooooong");
-}
-
-static
-void test_custom_validation_func_invalid(void)
-{
- const struct bt_param_validation_map_value_entry_descr entries[] = {
- { "navet", BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_MANDATORY, {
- .validation_func = custom_validation_func_invalid,
- } },
- BT_PARAM_VALIDATION_MAP_VALUE_ENTRY_END
- };
-
- run_test("navet=+1234", entries, "custom validation function with invalid value",
- "Error validating parameter `navet`: wrooooong");
-}
-
-int main(void)
-{
- plan_tests(41);
-
- test_map_valid();
-
- test_map_missing_key();
- test_map_unexpected_key();
- test_map_invalid_entry_value_type();
-
- test_array_valid();
- test_array_empty_valid();
-
- test_array_invalid_too_small();
- test_array_invalid_too_large();
- test_array_invalid_elem_type();
-
- test_string_valid_without_choices();
- test_string_valid_with_choices();
-
- test_string_invalid_choice();
-
- test_custom_validation_func_valid();
- test_custom_validation_func_invalid();
-
- test_nested_error();
-
- return exit_status();
-}
LIBTAP=$(top_builddir)/tests/utils/tap/libtap.la
dist_check_SCRIPTS = \
- test_bin_info_i386-linux-gnu \
- test_bin_info_powerpc64le-linux-gnu \
- test_bin_info_powerpc-linux-gnu \
- test_bin_info_x86_64-linux-gnu \
- test_dwarf_i386-linux-gnu \
- test_dwarf_powerpc64le-linux-gnu \
- test_dwarf_powerpc-linux-gnu \
- test_dwarf_x86_64-linux-gnu \
- test_succeed
+ test-bin-info-i386-linux-gnu.sh \
+ test-bin-info-powerpc64le-linux-gnu.sh \
+ test-bin-info-powerpc-linux-gnu.sh \
+ test-bin-info-x86-64-linux-gnu.sh \
+ test-dwarf-i386-linux-gnu.sh \
+ test-dwarf-powerpc64le-linux-gnu.sh \
+ test-dwarf-powerpc-linux-gnu.sh \
+ test-dwarf-x86-64-linux-gnu.sh \
+ test-succeed.sh
noinst_PROGRAMS =
endif # !ENABLE_BUILT_IN_PLUGINS
if ENABLE_DEBUG_INFO
-noinst_PROGRAMS += test_dwarf test_bin_info
+noinst_PROGRAMS += test-dwarf test-bin-info
test_dwarf_LDADD = \
$(top_builddir)/src/plugins/lttng-utils/debug-info/libdebug-info.la \
$(top_builddir)/src/common/libbabeltrace2-common.la \
$(ELFUTILS_LIBS) \
$(LIBTAP)
-test_dwarf_SOURCES = test_dwarf.c
+test_dwarf_SOURCES = test-dwarf.c
test_bin_info_LDADD = \
$(top_builddir)/src/plugins/lttng-utils/debug-info/libdebug-info.la \
$(top_builddir)/src/lib/libbabeltrace2.la \
$(ELFUTILS_LIBS) \
$(LIBTAP)
-test_bin_info_SOURCES = test_bin_info.c
+test_bin_info_SOURCES = test-bin-info.c
endif # ENABLE_DEBUG_INFO
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
+# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/flt.lttng-utils.debug-info"
+this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
+debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/i386-linux-gnu"
+
+"$this_dir_build/test-bin-info" \
+ --foo-addr=0x1c8d \
+ --printf-offset=0xda \
+ --printf-lineno=36 \
+ --tp-offset=0x12 \
+ --tp-lineno=35 \
+ --debug-link-crc=0xdeead493 \
+ --debug-info-dir "$debug_info_data" \
+ --build-id cdd98cdd87f7fe64c13b6daad553987eafd40cbb
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
+# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/flt.lttng-utils.debug-info"
+this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
+debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/powerpc-linux-gnu"
+
+"$this_dir_build/test-bin-info" \
+ --foo-addr=0x23bc \
+ --printf-offset=0x114 \
+ --printf-lineno=36 \
+ --tp-offset=0x28 \
+ --tp-lineno=35 \
+ --debug-link-crc=0xd7b98958 \
+ --debug-info-dir "$debug_info_data" \
+ --build-id cdd98cdd87f7fe64c13b6daad553987eafd40cbb
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
+# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/flt.lttng-utils.debug-info"
+this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
+debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/powerpc64le-linux-gnu"
+
+"$this_dir_build/test-bin-info" \
+ --foo-addr=0x2e7c \
+ --printf-offset=0x190 \
+ --printf-lineno=36 \
+ --tp-offset=0x1c \
+ --tp-lineno=35 \
+ --debug-link-crc=0x9b8eb2ff \
+ --debug-info-dir "$debug_info_data" \
+ --build-id cdd98cdd87f7fe64c13b6daad553987eafd40cbb
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
+# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/flt.lttng-utils.debug-info"
+this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
+debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/x86-64-linux-gnu"
+
+"$this_dir_build/test-bin-info" \
+ --foo-addr=0x2277 \
+ --printf-offset=0xf0 \
+ --printf-lineno=36 \
+ --tp-offset=0x89 \
+ --tp-lineno=35 \
+ --debug-link-crc=0x289a8fdc \
+ --debug-info-dir "$debug_info_data" \
+ --build-id cdd98cdd87f7fe64c13b6daad553987eafd40cbb
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
+ * Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
+ *
+ * Babeltrace SO info tests
+ */
+
+#define BT_LOG_OUTPUT_LEVEL BT_LOG_WARNING
+#define BT_LOG_TAG "TEST/BIN-INFO"
+#include "logging/log.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <glib.h>
+
+#include "common/macros.h"
+#include "common/assert.h"
+#include <lttng-utils/debug-info/bin-info.h>
+
+#include "tap/tap.h"
+
+#define NR_TESTS 57
+
+#define SO_NAME "libhello-so"
+#define DEBUG_NAME "libhello-so.debug"
+#define FUNC_FOO_FILENAME "./libhello.c"
+#define FUNC_FOO_PRINTF_NAME_FMT "foo+0x%" PRIx64
+#define FUNC_FOO_NAME_LEN 64
+
+#define DWARF_DIR_NAME "dwarf-full"
+#define ELF_DIR_NAME "elf-only"
+#define BUILDID_DIR_NAME "build-id"
+#define DEBUGLINK_DIR_NAME "debug-link"
+
+/* Lower bound of PIC address mapping */
+#define SO_LOW_ADDR 0x400000
+/* Size of PIC address mapping */
+#define SO_MEMSZ 0x800000
+/* An address outside the PIC mapping */
+#define SO_INV_ADDR 0x200000
+
+#define BUILD_ID_HEX_LEN 20
+
+static uint64_t opt_func_foo_addr;
+static uint64_t opt_func_foo_printf_offset;
+static uint64_t opt_func_foo_printf_line_no;
+static uint64_t opt_func_foo_tp_offset;
+static uint64_t opt_func_foo_tp_line_no;
+static uint64_t opt_debug_link_crc;
+static gchar *opt_build_id;
+static gchar *opt_debug_info_dir;
+
+static uint64_t func_foo_printf_addr;
+static uint64_t func_foo_tp_addr;
+static char func_foo_printf_name[FUNC_FOO_NAME_LEN];
+static uint8_t build_id[BUILD_ID_HEX_LEN];
+
+static GOptionEntry entries[] = {
+ {"foo-addr", 0, 0, G_OPTION_ARG_INT64, &opt_func_foo_addr,
+ "Offset to printf in foo", "0xX"},
+ {"printf-offset", 0, 0, G_OPTION_ARG_INT64, &opt_func_foo_printf_offset,
+ "Offset to printf in foo", "0xX"},
+ {"printf-lineno", 0, 0, G_OPTION_ARG_INT64,
+ &opt_func_foo_printf_line_no, "Line number to printf in foo", "N"},
+ {"tp-offset", 0, 0, G_OPTION_ARG_INT64, &opt_func_foo_tp_offset,
+ "Offset to tp in foo", "0xX"},
+ {"tp-lineno", 0, 0, G_OPTION_ARG_INT64, &opt_func_foo_tp_line_no,
+ "Line number to tp in foo", "N"},
+ {"debug-link-crc", 0, 0, G_OPTION_ARG_INT64, &opt_debug_link_crc,
+ "Debug link CRC", "0xX"},
+ {"build-id", 0, 0, G_OPTION_ARG_STRING, &opt_build_id, "Build ID",
+ "XXXXXXXXXXXXXXX"},
+ {"debug-info-dir", 0, 0, G_OPTION_ARG_STRING, &opt_debug_info_dir,
+ "Debug info directory", NULL},
+ {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}};
+
+static
+int build_id_to_bin(void)
+{
+ int ret, len, i;
+
+ if (!opt_build_id) {
+ goto error;
+ }
+
+ len = strnlen(opt_build_id, BUILD_ID_HEX_LEN * 2);
+ if (len != (BUILD_ID_HEX_LEN * 2)) {
+ goto error;
+ }
+
+ for (i = 0; i < (len / 2); i++) {
+ ret = sscanf(opt_build_id + 2 * i, "%02hhx", &build_id[i]);
+ if (ret != 1) {
+ goto error;
+ }
+ }
+
+ if (i != BUILD_ID_HEX_LEN) {
+ goto error;
+ }
+
+ return 0;
+error:
+ return -1;
+}
+
+static
+void subtest_has_address(struct bin_info *bin, uint64_t addr)
+{
+ int ret;
+
+ ret = bin_info_has_address(bin, SO_LOW_ADDR - 1);
+ ok(ret == 0, "bin_info_has_address - address under SO's range");
+
+ ret = bin_info_has_address(bin, SO_LOW_ADDR);
+ ok(ret == 1, "bin_info_has_address - lower bound of SO's range");
+
+ ret = bin_info_has_address(bin, addr);
+ ok(ret == 1, "bin_info_has_address - address in SO's range");
+
+ ret = bin_info_has_address(bin, SO_LOW_ADDR + SO_MEMSZ - 1);
+ ok(ret == 1, "bin_info_has_address - upper bound of SO's range");
+
+ ret = bin_info_has_address(bin, SO_LOW_ADDR + SO_MEMSZ);
+ ok(ret == 0, "bin_info_has_address - address above SO's range");
+}
+
+static
+void subtest_lookup_function_name(struct bin_info *bin, uint64_t addr,
+ char *func_name)
+{
+ int ret;
+ char *_func_name = NULL;
+
+ ret = bin_info_lookup_function_name(bin, addr, &_func_name);
+ ok(ret == 0, "bin_info_lookup_function_name successful at 0x%" PRIx64, addr);
+ if (_func_name) {
+ ok(strcmp(_func_name, func_name) == 0,
+ "bin_info_lookup_function_name - correct function name (%s == %s)",
+ func_name, _func_name);
+ free(_func_name);
+ _func_name = NULL;
+ } else {
+ skip(1,
+ "bin_info_lookup_function_name - function name is NULL");
+ }
+
+ /* Test function name lookup - erroneous address */
+ ret = bin_info_lookup_function_name(bin, SO_INV_ADDR, &_func_name);
+ ok(ret == -1 && !_func_name,
+ "bin_info_lookup_function_name - fail on invalid addr");
+ free(_func_name);
+}
+
+static
+void subtest_lookup_source_location(struct bin_info *bin, uint64_t addr,
+ uint64_t line_no, const char *filename)
+{
+ int ret;
+ struct source_location *src_loc = NULL;
+
+ ret = bin_info_lookup_source_location(bin, addr, &src_loc);
+ ok(ret == 0, "bin_info_lookup_source_location successful at 0x%" PRIx64,
+ addr);
+ if (src_loc) {
+ ok(src_loc->line_no == line_no,
+ "bin_info_lookup_source_location - correct line_no (%" PRIu64 " == %" PRIu64 ")",
+ line_no, src_loc->line_no);
+ ok(strcmp(src_loc->filename, filename) == 0,
+ "bin_info_lookup_source_location - correct filename (%s == %s)",
+ filename, src_loc->filename);
+ source_location_destroy(src_loc);
+ src_loc = NULL;
+ } else {
+ fail("bin_info_lookup_source_location - src_loc is NULL");
+ fail("bin_info_lookup_source_location - src_loc is NULL");
+ }
+
+ /* Test source location lookup - erroneous address */
+ ret = bin_info_lookup_source_location(bin, SO_INV_ADDR, &src_loc);
+ ok(ret == -1 && !src_loc,
+ "bin_info_lookup_source_location - fail on invalid addr");
+ if (src_loc) {
+ source_location_destroy(src_loc);
+ }
+}
+
+static
+void test_bin_info_build_id(const char *bin_info_dir)
+{
+ int ret;
+ char *data_dir, *bin_path;
+ struct bin_info *bin = NULL;
+ struct bt_fd_cache fdc;
+ uint8_t invalid_build_id[BUILD_ID_HEX_LEN] = {
+ 0xa3, 0xfd, 0x8b, 0xff, 0x45, 0xe1, 0xa9, 0x32, 0x15, 0xdd,
+ 0x6d, 0xaa, 0xd5, 0x53, 0x98, 0x7e, 0xaf, 0xd4, 0x0c, 0xbb
+ };
+
+ diag("bin-info tests - separate DWARF via build ID");
+
+ data_dir = g_build_filename(bin_info_dir, BUILDID_DIR_NAME, NULL);
+ bin_path =
+ g_build_filename(bin_info_dir, BUILDID_DIR_NAME, SO_NAME, NULL);
+
+ if (!data_dir || !bin_path) {
+ exit(EXIT_FAILURE);
+ }
+
+ ret = bt_fd_cache_init(&fdc, BT_LOG_OUTPUT_LEVEL);
+ if (ret != 0) {
+ diag("Failed to initialize FD cache");
+ exit(EXIT_FAILURE);
+ }
+
+ bin = bin_info_create(&fdc, bin_path, SO_LOW_ADDR, SO_MEMSZ, true,
+ data_dir, NULL, BT_LOG_OUTPUT_LEVEL, NULL);
+ ok(bin, "bin_info_create successful (%s)", bin_path);
+
+ /* Test setting invalid build_id */
+ ret = bin_info_set_build_id(bin, invalid_build_id, BUILD_ID_HEX_LEN);
+ ok(ret == -1, "bin_info_set_build_id fail on invalid build_id");
+
+ /* Test setting correct build_id */
+ ret = bin_info_set_build_id(bin, build_id, BUILD_ID_HEX_LEN);
+ ok(ret == 0, "bin_info_set_build_id successful");
+
+ /* Test bin_info_has_address */
+ subtest_has_address(bin, func_foo_printf_addr);
+
+ /* Test function name lookup (with DWARF) */
+ subtest_lookup_function_name(bin, func_foo_printf_addr,
+ func_foo_printf_name);
+
+ /* Test source location lookup */
+ subtest_lookup_source_location(bin, func_foo_printf_addr,
+ opt_func_foo_printf_line_no,
+ FUNC_FOO_FILENAME);
+
+ bin_info_destroy(bin);
+ bt_fd_cache_fini(&fdc);
+ g_free(data_dir);
+ g_free(bin_path);
+}
+
+static
+void test_bin_info_debug_link(const char *bin_info_dir)
+{
+ int ret;
+ char *data_dir, *bin_path;
+ struct bin_info *bin = NULL;
+ struct bt_fd_cache fdc;
+
+ diag("bin-info tests - separate DWARF via debug link");
+
+ data_dir = g_build_filename(bin_info_dir, DEBUGLINK_DIR_NAME, NULL);
+ bin_path = g_build_filename(bin_info_dir, DEBUGLINK_DIR_NAME, SO_NAME,
+ NULL);
+
+ if (!data_dir || !bin_path) {
+ exit(EXIT_FAILURE);
+ }
+
+ ret = bt_fd_cache_init(&fdc, BT_LOG_OUTPUT_LEVEL);
+ if (ret != 0) {
+ diag("Failed to initialize FD cache");
+ exit(EXIT_FAILURE);
+ }
+
+ bin = bin_info_create(&fdc, bin_path, SO_LOW_ADDR, SO_MEMSZ, true,
+ data_dir, NULL, BT_LOG_OUTPUT_LEVEL, NULL);
+ ok(bin, "bin_info_create successful (%s)", bin_path);
+
+ /* Test setting debug link */
+ ret = bin_info_set_debug_link(bin, DEBUG_NAME, opt_debug_link_crc);
+ ok(ret == 0, "bin_info_set_debug_link successful");
+
+ /* Test bin_info_has_address */
+ subtest_has_address(bin, func_foo_printf_addr);
+
+ /* Test function name lookup (with DWARF) */
+ subtest_lookup_function_name(bin, func_foo_printf_addr,
+ func_foo_printf_name);
+
+ /* Test source location lookup */
+ subtest_lookup_source_location(bin, func_foo_printf_addr,
+ opt_func_foo_printf_line_no,
+ FUNC_FOO_FILENAME);
+
+ bin_info_destroy(bin);
+ bt_fd_cache_fini(&fdc);
+ g_free(data_dir);
+ g_free(bin_path);
+}
+
+static
+void test_bin_info_elf(const char *bin_info_dir)
+{
+ int ret;
+ char *data_dir, *bin_path;
+ struct bin_info *bin = NULL;
+ struct source_location *src_loc = NULL;
+ struct bt_fd_cache fdc;
+
+ diag("bin-info tests - ELF only");
+
+ data_dir = g_build_filename(bin_info_dir, ELF_DIR_NAME, NULL);
+ bin_path = g_build_filename(bin_info_dir, ELF_DIR_NAME, SO_NAME, NULL);
+
+ if (!data_dir || !bin_path) {
+ exit(EXIT_FAILURE);
+ }
+
+ ret = bt_fd_cache_init(&fdc, BT_LOG_OUTPUT_LEVEL);
+ if (ret != 0) {
+ diag("Failed to initialize FD cache");
+ exit(EXIT_FAILURE);
+ }
+
+ bin = bin_info_create(&fdc, bin_path, SO_LOW_ADDR, SO_MEMSZ, true,
+ data_dir, NULL, BT_LOG_OUTPUT_LEVEL, NULL);
+ ok(bin, "bin_info_create successful (%s)", bin_path);
+
+ /* Test bin_info_has_address */
+ subtest_has_address(bin, func_foo_printf_addr);
+
+ /* Test function name lookup (with ELF) */
+ subtest_lookup_function_name(bin, func_foo_printf_addr,
+ func_foo_printf_name);
+
+ /* Test source location location - should fail on ELF only file */
+ ret = bin_info_lookup_source_location(bin, func_foo_printf_addr,
+ &src_loc);
+ ok(ret == -1,
+ "bin_info_lookup_source_location - fail on ELF only file");
+
+ source_location_destroy(src_loc);
+ bin_info_destroy(bin);
+ bt_fd_cache_fini(&fdc);
+ g_free(data_dir);
+ g_free(bin_path);
+}
+
+static
+void test_bin_info_bundled(const char *bin_info_dir)
+{
+ int ret;
+ char *data_dir, *bin_path;
+ struct bin_info *bin = NULL;
+ struct bt_fd_cache fdc;
+
+ diag("bin-info tests - DWARF bundled in SO file");
+
+ data_dir = g_build_filename(bin_info_dir, DWARF_DIR_NAME, NULL);
+ bin_path =
+ g_build_filename(bin_info_dir, DWARF_DIR_NAME, SO_NAME, NULL);
+
+ if (!data_dir || !bin_path) {
+ exit(EXIT_FAILURE);
+ }
+
+ ret = bt_fd_cache_init(&fdc, BT_LOG_OUTPUT_LEVEL);
+ if (ret != 0) {
+ diag("Failed to initialize FD cache");
+ exit(EXIT_FAILURE);
+ }
+
+ bin = bin_info_create(&fdc, bin_path, SO_LOW_ADDR, SO_MEMSZ, true,
+ data_dir, NULL, BT_LOG_OUTPUT_LEVEL, NULL);
+ ok(bin, "bin_info_create successful (%s)", bin_path);
+
+ /* Test bin_info_has_address */
+ subtest_has_address(bin, func_foo_printf_addr);
+
+ /* Test function name lookup (with DWARF) */
+ subtest_lookup_function_name(bin, func_foo_printf_addr,
+ func_foo_printf_name);
+
+ /* Test source location lookup */
+ subtest_lookup_source_location(bin, func_foo_printf_addr,
+ opt_func_foo_printf_line_no,
+ FUNC_FOO_FILENAME);
+
+ /* Test source location lookup - inlined function */
+ subtest_lookup_source_location(bin, func_foo_tp_addr,
+ opt_func_foo_tp_line_no,
+ FUNC_FOO_FILENAME);
+
+ bin_info_destroy(bin);
+ bt_fd_cache_fini(&fdc);
+ g_free(data_dir);
+ g_free(bin_path);
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+ GError *error = NULL;
+ GOptionContext *context;
+ int status;
+
+ plan_tests(NR_TESTS);
+
+ context = g_option_context_new("- bin info test");
+ g_option_context_add_main_entries(context, entries, NULL);
+ if (!g_option_context_parse(context, &argc, &argv, &error)) {
+ fprintf(stderr, "option parsing failed: %s\n", error->message);
+ status = EXIT_FAILURE;
+ goto end;
+ }
+
+ g_snprintf(func_foo_printf_name, FUNC_FOO_NAME_LEN,
+ FUNC_FOO_PRINTF_NAME_FMT, opt_func_foo_printf_offset);
+ func_foo_printf_addr =
+ SO_LOW_ADDR + opt_func_foo_addr + opt_func_foo_printf_offset;
+ func_foo_tp_addr =
+ SO_LOW_ADDR + opt_func_foo_addr + opt_func_foo_tp_offset;
+
+ if (build_id_to_bin()) {
+ fprintf(stderr, "Failed to parse / missing build id\n");
+ status = EXIT_FAILURE;
+ goto end;
+ }
+
+ ret = bin_info_init(BT_LOG_OUTPUT_LEVEL, NULL);
+ ok(ret == 0, "bin_info_init successful");
+
+ test_bin_info_elf(opt_debug_info_dir);
+ test_bin_info_bundled(opt_debug_info_dir);
+ test_bin_info_build_id(opt_debug_info_dir);
+ test_bin_info_debug_link(opt_debug_info_dir);
+
+ status = exit_status();
+
+end:
+ g_option_context_free(context);
+
+ return status;
+}
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
+# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/flt.lttng-utils.debug-info"
+this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
+debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/i386-linux-gnu"
+
+"$this_dir_build/test-dwarf" \
+ "$debug_info_data"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
+# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/flt.lttng-utils.debug-info"
+this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
+debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/powerpc-linux-gnu"
+
+"$this_dir_build/test-dwarf" \
+ "$debug_info_data"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
+# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/flt.lttng-utils.debug-info"
+this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
+debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/powerpc64le-linux-gnu"
+
+"$this_dir_build/test-dwarf" \
+ "$debug_info_data"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
+# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/flt.lttng-utils.debug-info"
+this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
+debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/x86-64-linux-gnu"
+
+"$this_dir_build/test-dwarf" \
+ "$debug_info_data/"
--- /dev/null
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation
+ * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
+ *
+ * Babeltrace bt_dwarf (DWARF utilities) tests
+ */
+
+#include <fcntl.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <lttng-utils/debug-info/dwarf.h>
+#include "tap/tap.h"
+
+#define NR_TESTS 17
+
+#define SO_NAME "libhello-so"
+#define DWARF_DIR_NAME "dwarf-full"
+#define ELF_DIR_NAME "elf-only"
+
+/*
+ * Test that we fail on an ELF file without DWARF.
+ */
+static
+void test_bt_no_dwarf(const char *data_dir)
+{
+ int fd;
+ char *path;
+ Dwarf *dwarf_info = NULL;
+
+ path = g_build_filename(data_dir, ELF_DIR_NAME, SO_NAME, NULL);
+ if (!path) {
+ diag("Failed to allocate memory for path");
+ exit(EXIT_FAILURE);
+ }
+
+ fd = open(path, O_RDONLY);
+ ok(fd >= 0, "Open ELF file %s", path);
+ if (fd < 0) {
+ skip(1, "dwarf_begin failed as expected");
+ } else {
+ dwarf_info = dwarf_begin(fd, DWARF_C_READ);
+ ok(!dwarf_info, "dwarf_begin failed as expected");
+ }
+
+ if (dwarf_info) {
+ dwarf_end(dwarf_info);
+ }
+
+ if (fd >= 0) {
+ close(fd);
+ }
+ g_free(path);
+}
+
+/*
+ * Test with a proper ELF file with DWARF.
+ */
+static
+void test_bt_dwarf(const char *data_dir)
+{
+ int fd, ret, tag;
+ char *path;
+ char *die_name = NULL;
+ struct bt_dwarf_cu *cu = NULL;
+ struct bt_dwarf_die *die = NULL;
+ Dwarf *dwarf_info = NULL;
+
+ path = g_build_filename(data_dir, DWARF_DIR_NAME, SO_NAME, NULL);
+ if (!path) {
+ diag("Failed to allocate memory for path");
+ exit(EXIT_FAILURE);
+ }
+
+ fd = open(path, O_RDONLY);
+ ok(fd >= 0, "Open DWARF file %s", path);
+ if (fd < 0) {
+ exit(EXIT_FAILURE);
+ }
+ dwarf_info = dwarf_begin(fd, DWARF_C_READ);
+ ok(dwarf_info, "dwarf_begin successful");
+ cu = bt_dwarf_cu_create(dwarf_info);
+ ok(cu, "bt_dwarf_cu_create successful");
+ ret = bt_dwarf_cu_next(cu);
+ ok(ret == 0, "bt_dwarf_cu_next successful");
+ die = bt_dwarf_die_create(cu);
+ ok(die, "bt_dwarf_die_create successful");
+ if (!die) {
+ exit(EXIT_FAILURE);
+ }
+ /*
+ * Test bt_dwarf_die_next twice, as the code path is different
+ * for DIEs at depth 0 (just created) and other depths.
+ */
+ ret = bt_dwarf_die_next(die);
+ ok(ret == 0, "bt_dwarf_die_next from root DIE successful");
+ ok(die->depth == 1,
+ "bt_dwarf_die_next from root DIE - correct depth value");
+ ret = bt_dwarf_die_next(die);
+ ok(ret == 0,
+ "bt_dwarf_die_next from non-root DIE successful");
+ ok(die->depth == 1,
+ "bt_dwarf_die_next from non-root DIE - correct depth value");
+
+ /* Reset DIE to test dwarf_child */
+ bt_dwarf_die_destroy(die);
+ die = bt_dwarf_die_create(cu);
+ if (!die) {
+ diag("Failed to create bt_dwarf_die");
+ exit(EXIT_FAILURE);
+ }
+
+ ret = bt_dwarf_die_child(die);
+ ok(ret == 0, "bt_dwarf_die_child successful");
+ ok(die->depth == 1, "bt_dwarf_die_child - correct depth value");
+
+ ret = bt_dwarf_die_get_tag(die, &tag);
+ ok(ret == 0, "bt_dwarf_die_get_tag successful");
+ ok(tag == DW_TAG_typedef, "bt_dwarf_die_get_tag - correct tag value");
+ ret = bt_dwarf_die_get_name(die, &die_name);
+ ok(ret == 0, "bt_dwarf_die_get_name successful");
+ ok(strcmp(die_name, "size_t") == 0,
+ "bt_dwarf_die_get_name - correct name value");
+
+ bt_dwarf_die_destroy(die);
+ bt_dwarf_cu_destroy(cu);
+ dwarf_end(dwarf_info);
+ free(die_name);
+ close(fd);
+ g_free(path);
+}
+
+int main(int argc, char **argv)
+{
+ const char *data_dir;
+
+ plan_tests(NR_TESTS);
+
+ if (argc != 2) {
+ return EXIT_FAILURE;
+ } else {
+ data_dir = argv[1];
+ }
+
+ test_bt_no_dwarf(data_dir);
+ test_bt_dwarf(data_dir);
+
+ return exit_status();
+}
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
+# Copyright (C) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
+#
+
+# This test validates that a `src.ctf.fs` component successfully reads
+# specific CTF traces and creates the expected messages.
+#
+# Such CTF traces to open either exist (in `tests/ctf-traces/succeed`)
+# or are generated by this test using local trace generators.
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/flt.lttng-utils.debug-info"
+succeed_trace_dir="$BT_CTF_TRACES_PATH/succeed"
+expect_dir="$BT_TESTS_DATADIR/$this_dir_relative"
+binary_artefact_dir="$BT_TESTS_DATADIR/$this_dir_relative"
+data_dir="$BT_TESTS_DATADIR/$this_dir_relative"
+
+test_debug_info() {
+ local name="$1"
+ local local_args=(
+ "-c" "flt.lttng-utils.debug-info"
+ "-p" "target-prefix=\"$binary_artefact_dir/x86-64-linux-gnu/dwarf-full\""
+ "-c" "sink.text.details"
+ "-p" "with-trace-name=no,with-stream-name=no"
+ )
+
+ bt_diff_cli "$expect_dir/trace-$name.expect" "/dev/null" \
+ "$succeed_trace_dir/$name" "${local_args[@]}"
+ ok $? "Trace '$name' gives the expected output"
+}
+
+test_compare_to_ctf_fs() {
+ # Compare the `sink.text.details` output of a graph with and without a
+ # `flt.lttng-utils.debug-info` component. Both should be identical for
+ # traces without LTTng debugging fields.
+ local test_name=$1
+ shift 1
+ local cli_args=("$@")
+ local debug_info_cli_args=("-c" "flt.lttng-utils.debug-info")
+ local details_cli_args=(
+ "-c" "sink.text.details"
+ "--params" "with-trace-name=false,with-stream-name=false,with-uuid=false"
+ )
+ local actual_stdout
+ local actual_stderr
+ local expected_stdout
+ local expected_stderr
+ local ret=0
+
+ actual_stdout=$(mktemp -t test-debug-info-stdout-actual.XXXXXX)
+ actual_stderr=$(mktemp -t test-debug-info-stderr-actual.XXXXXX)
+ expected_stdout=$(mktemp -t test-debug-info-stdout-expected.XXXXXX)
+ expected_stderr=$(mktemp -t test-debug-info-stderr-expected.XXXXXX)
+
+ # Create expected files using a graph without a `debug-info` component.
+ bt_cli "$expected_stdout" "$expected_stderr" "${cli_args[@]}" \
+ "${details_cli_args[@]}"
+
+ # Read the same trace with a `debug-info` component in the graph.
+ bt_cli "$actual_stdout" "$actual_stderr" "${cli_args[@]}" \
+ "${details_cli_args[@]}" "${debug_info_cli_args[@]}"
+
+ bt_diff "$expected_stdout" "$actual_stdout"
+ ok $? "Input '$test_name' gives the expected stdout"
+
+ bt_diff "$expected_stderr" "$actual_stderr"
+ ok $? "Input '$test_name' gives the expected stderr"
+
+ rm -f "$actual_stdout"
+ rm -f "$actual_stderr"
+ rm -f "$expected_stdout"
+ rm -f "$expected_stderr"
+}
+
+test_compare_ctf_src_trace() {
+ local trace_name=$1
+ local trace_path="$succeed_trace_dir/$trace_name"
+ local cli_args=("$trace_path")
+
+ diag "Comparing output with and without 'flt.lttng-utils.debug-info' on '$trace_name'"
+ test_compare_to_ctf_fs "src.ctf.fs with $trace_name trace" "${cli_args[@]}"
+}
+
+test_compare_complete_src_trace() {
+
+ local source_name="src.test-debug-info.CompleteSrc"
+ local cli_args=("--plugin-path=$data_dir" "-c" "$source_name")
+ test_compare_to_ctf_fs "$source_name" "${cli_args[@]}"
+}
+
+plan_tests 9
+
+test_debug_info debug-info
+
+test_compare_ctf_src_trace smalltrace
+test_compare_ctf_src_trace 2packets
+test_compare_ctf_src_trace session-rotation
+
+test_compare_complete_src_trace
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation
- * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
- * Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
- *
- * Babeltrace SO info tests
- */
-
-#define BT_LOG_OUTPUT_LEVEL BT_LOG_WARNING
-#define BT_LOG_TAG "TEST/BIN-INFO"
-#include "logging/log.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <inttypes.h>
-#include <glib.h>
-
-#include "common/macros.h"
-#include "common/assert.h"
-#include <lttng-utils/debug-info/bin-info.h>
-
-#include "tap/tap.h"
-
-#define NR_TESTS 57
-
-#define SO_NAME "libhello_so"
-#define DEBUG_NAME "libhello_so.debug"
-#define FUNC_FOO_FILENAME "./libhello.c"
-#define FUNC_FOO_PRINTF_NAME_FMT "foo+0x%" PRIx64
-#define FUNC_FOO_NAME_LEN 64
-
-#define DWARF_DIR_NAME "dwarf_full"
-#define ELF_DIR_NAME "elf_only"
-#define BUILDID_DIR_NAME "build_id"
-#define DEBUGLINK_DIR_NAME "debug_link"
-
-/* Lower bound of PIC address mapping */
-#define SO_LOW_ADDR 0x400000
-/* Size of PIC address mapping */
-#define SO_MEMSZ 0x800000
-/* An address outside the PIC mapping */
-#define SO_INV_ADDR 0x200000
-
-#define BUILD_ID_HEX_LEN 20
-
-static uint64_t opt_func_foo_addr;
-static uint64_t opt_func_foo_printf_offset;
-static uint64_t opt_func_foo_printf_line_no;
-static uint64_t opt_func_foo_tp_offset;
-static uint64_t opt_func_foo_tp_line_no;
-static uint64_t opt_debug_link_crc;
-static gchar *opt_build_id;
-static gchar *opt_debug_info_dir;
-
-static uint64_t func_foo_printf_addr;
-static uint64_t func_foo_tp_addr;
-static char func_foo_printf_name[FUNC_FOO_NAME_LEN];
-static uint8_t build_id[BUILD_ID_HEX_LEN];
-
-static GOptionEntry entries[] = {
- {"foo-addr", 0, 0, G_OPTION_ARG_INT64, &opt_func_foo_addr,
- "Offset to printf in foo", "0xX"},
- {"printf-offset", 0, 0, G_OPTION_ARG_INT64, &opt_func_foo_printf_offset,
- "Offset to printf in foo", "0xX"},
- {"printf-lineno", 0, 0, G_OPTION_ARG_INT64,
- &opt_func_foo_printf_line_no, "Line number to printf in foo", "N"},
- {"tp-offset", 0, 0, G_OPTION_ARG_INT64, &opt_func_foo_tp_offset,
- "Offset to tp in foo", "0xX"},
- {"tp-lineno", 0, 0, G_OPTION_ARG_INT64, &opt_func_foo_tp_line_no,
- "Line number to tp in foo", "N"},
- {"debug-link-crc", 0, 0, G_OPTION_ARG_INT64, &opt_debug_link_crc,
- "Debug link CRC", "0xX"},
- {"build-id", 0, 0, G_OPTION_ARG_STRING, &opt_build_id, "Build ID",
- "XXXXXXXXXXXXXXX"},
- {"debug-info-dir", 0, 0, G_OPTION_ARG_STRING, &opt_debug_info_dir,
- "Debug info directory", NULL},
- {NULL, 0, 0, G_OPTION_ARG_NONE, NULL, NULL, NULL}};
-
-static
-int build_id_to_bin(void)
-{
- int ret, len, i;
-
- if (!opt_build_id) {
- goto error;
- }
-
- len = strnlen(opt_build_id, BUILD_ID_HEX_LEN * 2);
- if (len != (BUILD_ID_HEX_LEN * 2)) {
- goto error;
- }
-
- for (i = 0; i < (len / 2); i++) {
- ret = sscanf(opt_build_id + 2 * i, "%02hhx", &build_id[i]);
- if (ret != 1) {
- goto error;
- }
- }
-
- if (i != BUILD_ID_HEX_LEN) {
- goto error;
- }
-
- return 0;
-error:
- return -1;
-}
-
-static
-void subtest_has_address(struct bin_info *bin, uint64_t addr)
-{
- int ret;
-
- ret = bin_info_has_address(bin, SO_LOW_ADDR - 1);
- ok(ret == 0, "bin_info_has_address - address under SO's range");
-
- ret = bin_info_has_address(bin, SO_LOW_ADDR);
- ok(ret == 1, "bin_info_has_address - lower bound of SO's range");
-
- ret = bin_info_has_address(bin, addr);
- ok(ret == 1, "bin_info_has_address - address in SO's range");
-
- ret = bin_info_has_address(bin, SO_LOW_ADDR + SO_MEMSZ - 1);
- ok(ret == 1, "bin_info_has_address - upper bound of SO's range");
-
- ret = bin_info_has_address(bin, SO_LOW_ADDR + SO_MEMSZ);
- ok(ret == 0, "bin_info_has_address - address above SO's range");
-}
-
-static
-void subtest_lookup_function_name(struct bin_info *bin, uint64_t addr,
- char *func_name)
-{
- int ret;
- char *_func_name = NULL;
-
- ret = bin_info_lookup_function_name(bin, addr, &_func_name);
- ok(ret == 0, "bin_info_lookup_function_name successful at 0x%" PRIx64, addr);
- if (_func_name) {
- ok(strcmp(_func_name, func_name) == 0,
- "bin_info_lookup_function_name - correct function name (%s == %s)",
- func_name, _func_name);
- free(_func_name);
- _func_name = NULL;
- } else {
- skip(1,
- "bin_info_lookup_function_name - function name is NULL");
- }
-
- /* Test function name lookup - erroneous address */
- ret = bin_info_lookup_function_name(bin, SO_INV_ADDR, &_func_name);
- ok(ret == -1 && !_func_name,
- "bin_info_lookup_function_name - fail on invalid addr");
- free(_func_name);
-}
-
-static
-void subtest_lookup_source_location(struct bin_info *bin, uint64_t addr,
- uint64_t line_no, const char *filename)
-{
- int ret;
- struct source_location *src_loc = NULL;
-
- ret = bin_info_lookup_source_location(bin, addr, &src_loc);
- ok(ret == 0, "bin_info_lookup_source_location successful at 0x%" PRIx64,
- addr);
- if (src_loc) {
- ok(src_loc->line_no == line_no,
- "bin_info_lookup_source_location - correct line_no (%" PRIu64 " == %" PRIu64 ")",
- line_no, src_loc->line_no);
- ok(strcmp(src_loc->filename, filename) == 0,
- "bin_info_lookup_source_location - correct filename (%s == %s)",
- filename, src_loc->filename);
- source_location_destroy(src_loc);
- src_loc = NULL;
- } else {
- fail("bin_info_lookup_source_location - src_loc is NULL");
- fail("bin_info_lookup_source_location - src_loc is NULL");
- }
-
- /* Test source location lookup - erroneous address */
- ret = bin_info_lookup_source_location(bin, SO_INV_ADDR, &src_loc);
- ok(ret == -1 && !src_loc,
- "bin_info_lookup_source_location - fail on invalid addr");
- if (src_loc) {
- source_location_destroy(src_loc);
- }
-}
-
-static
-void test_bin_info_build_id(const char *bin_info_dir)
-{
- int ret;
- char *data_dir, *bin_path;
- struct bin_info *bin = NULL;
- struct bt_fd_cache fdc;
- uint8_t invalid_build_id[BUILD_ID_HEX_LEN] = {
- 0xa3, 0xfd, 0x8b, 0xff, 0x45, 0xe1, 0xa9, 0x32, 0x15, 0xdd,
- 0x6d, 0xaa, 0xd5, 0x53, 0x98, 0x7e, 0xaf, 0xd4, 0x0c, 0xbb
- };
-
- diag("bin-info tests - separate DWARF via build ID");
-
- data_dir = g_build_filename(bin_info_dir, BUILDID_DIR_NAME, NULL);
- bin_path =
- g_build_filename(bin_info_dir, BUILDID_DIR_NAME, SO_NAME, NULL);
-
- if (!data_dir || !bin_path) {
- exit(EXIT_FAILURE);
- }
-
- ret = bt_fd_cache_init(&fdc, BT_LOG_OUTPUT_LEVEL);
- if (ret != 0) {
- diag("Failed to initialize FD cache");
- exit(EXIT_FAILURE);
- }
-
- bin = bin_info_create(&fdc, bin_path, SO_LOW_ADDR, SO_MEMSZ, true,
- data_dir, NULL, BT_LOG_OUTPUT_LEVEL, NULL);
- ok(bin, "bin_info_create successful (%s)", bin_path);
-
- /* Test setting invalid build_id */
- ret = bin_info_set_build_id(bin, invalid_build_id, BUILD_ID_HEX_LEN);
- ok(ret == -1, "bin_info_set_build_id fail on invalid build_id");
-
- /* Test setting correct build_id */
- ret = bin_info_set_build_id(bin, build_id, BUILD_ID_HEX_LEN);
- ok(ret == 0, "bin_info_set_build_id successful");
-
- /* Test bin_info_has_address */
- subtest_has_address(bin, func_foo_printf_addr);
-
- /* Test function name lookup (with DWARF) */
- subtest_lookup_function_name(bin, func_foo_printf_addr,
- func_foo_printf_name);
-
- /* Test source location lookup */
- subtest_lookup_source_location(bin, func_foo_printf_addr,
- opt_func_foo_printf_line_no,
- FUNC_FOO_FILENAME);
-
- bin_info_destroy(bin);
- bt_fd_cache_fini(&fdc);
- g_free(data_dir);
- g_free(bin_path);
-}
-
-static
-void test_bin_info_debug_link(const char *bin_info_dir)
-{
- int ret;
- char *data_dir, *bin_path;
- struct bin_info *bin = NULL;
- struct bt_fd_cache fdc;
-
- diag("bin-info tests - separate DWARF via debug link");
-
- data_dir = g_build_filename(bin_info_dir, DEBUGLINK_DIR_NAME, NULL);
- bin_path = g_build_filename(bin_info_dir, DEBUGLINK_DIR_NAME, SO_NAME,
- NULL);
-
- if (!data_dir || !bin_path) {
- exit(EXIT_FAILURE);
- }
-
- ret = bt_fd_cache_init(&fdc, BT_LOG_OUTPUT_LEVEL);
- if (ret != 0) {
- diag("Failed to initialize FD cache");
- exit(EXIT_FAILURE);
- }
-
- bin = bin_info_create(&fdc, bin_path, SO_LOW_ADDR, SO_MEMSZ, true,
- data_dir, NULL, BT_LOG_OUTPUT_LEVEL, NULL);
- ok(bin, "bin_info_create successful (%s)", bin_path);
-
- /* Test setting debug link */
- ret = bin_info_set_debug_link(bin, DEBUG_NAME, opt_debug_link_crc);
- ok(ret == 0, "bin_info_set_debug_link successful");
-
- /* Test bin_info_has_address */
- subtest_has_address(bin, func_foo_printf_addr);
-
- /* Test function name lookup (with DWARF) */
- subtest_lookup_function_name(bin, func_foo_printf_addr,
- func_foo_printf_name);
-
- /* Test source location lookup */
- subtest_lookup_source_location(bin, func_foo_printf_addr,
- opt_func_foo_printf_line_no,
- FUNC_FOO_FILENAME);
-
- bin_info_destroy(bin);
- bt_fd_cache_fini(&fdc);
- g_free(data_dir);
- g_free(bin_path);
-}
-
-static
-void test_bin_info_elf(const char *bin_info_dir)
-{
- int ret;
- char *data_dir, *bin_path;
- struct bin_info *bin = NULL;
- struct source_location *src_loc = NULL;
- struct bt_fd_cache fdc;
-
- diag("bin-info tests - ELF only");
-
- data_dir = g_build_filename(bin_info_dir, ELF_DIR_NAME, NULL);
- bin_path = g_build_filename(bin_info_dir, ELF_DIR_NAME, SO_NAME, NULL);
-
- if (!data_dir || !bin_path) {
- exit(EXIT_FAILURE);
- }
-
- ret = bt_fd_cache_init(&fdc, BT_LOG_OUTPUT_LEVEL);
- if (ret != 0) {
- diag("Failed to initialize FD cache");
- exit(EXIT_FAILURE);
- }
-
- bin = bin_info_create(&fdc, bin_path, SO_LOW_ADDR, SO_MEMSZ, true,
- data_dir, NULL, BT_LOG_OUTPUT_LEVEL, NULL);
- ok(bin, "bin_info_create successful (%s)", bin_path);
-
- /* Test bin_info_has_address */
- subtest_has_address(bin, func_foo_printf_addr);
-
- /* Test function name lookup (with ELF) */
- subtest_lookup_function_name(bin, func_foo_printf_addr,
- func_foo_printf_name);
-
- /* Test source location location - should fail on ELF only file */
- ret = bin_info_lookup_source_location(bin, func_foo_printf_addr,
- &src_loc);
- ok(ret == -1,
- "bin_info_lookup_source_location - fail on ELF only file");
-
- source_location_destroy(src_loc);
- bin_info_destroy(bin);
- bt_fd_cache_fini(&fdc);
- g_free(data_dir);
- g_free(bin_path);
-}
-
-static
-void test_bin_info_bundled(const char *bin_info_dir)
-{
- int ret;
- char *data_dir, *bin_path;
- struct bin_info *bin = NULL;
- struct bt_fd_cache fdc;
-
- diag("bin-info tests - DWARF bundled in SO file");
-
- data_dir = g_build_filename(bin_info_dir, DWARF_DIR_NAME, NULL);
- bin_path =
- g_build_filename(bin_info_dir, DWARF_DIR_NAME, SO_NAME, NULL);
-
- if (!data_dir || !bin_path) {
- exit(EXIT_FAILURE);
- }
-
- ret = bt_fd_cache_init(&fdc, BT_LOG_OUTPUT_LEVEL);
- if (ret != 0) {
- diag("Failed to initialize FD cache");
- exit(EXIT_FAILURE);
- }
-
- bin = bin_info_create(&fdc, bin_path, SO_LOW_ADDR, SO_MEMSZ, true,
- data_dir, NULL, BT_LOG_OUTPUT_LEVEL, NULL);
- ok(bin, "bin_info_create successful (%s)", bin_path);
-
- /* Test bin_info_has_address */
- subtest_has_address(bin, func_foo_printf_addr);
-
- /* Test function name lookup (with DWARF) */
- subtest_lookup_function_name(bin, func_foo_printf_addr,
- func_foo_printf_name);
-
- /* Test source location lookup */
- subtest_lookup_source_location(bin, func_foo_printf_addr,
- opt_func_foo_printf_line_no,
- FUNC_FOO_FILENAME);
-
- /* Test source location lookup - inlined function */
- subtest_lookup_source_location(bin, func_foo_tp_addr,
- opt_func_foo_tp_line_no,
- FUNC_FOO_FILENAME);
-
- bin_info_destroy(bin);
- bt_fd_cache_fini(&fdc);
- g_free(data_dir);
- g_free(bin_path);
-}
-
-int main(int argc, char **argv)
-{
- int ret;
- GError *error = NULL;
- GOptionContext *context;
- int status;
-
- plan_tests(NR_TESTS);
-
- context = g_option_context_new("- bin info test");
- g_option_context_add_main_entries(context, entries, NULL);
- if (!g_option_context_parse(context, &argc, &argv, &error)) {
- fprintf(stderr, "option parsing failed: %s\n", error->message);
- status = EXIT_FAILURE;
- goto end;
- }
-
- g_snprintf(func_foo_printf_name, FUNC_FOO_NAME_LEN,
- FUNC_FOO_PRINTF_NAME_FMT, opt_func_foo_printf_offset);
- func_foo_printf_addr =
- SO_LOW_ADDR + opt_func_foo_addr + opt_func_foo_printf_offset;
- func_foo_tp_addr =
- SO_LOW_ADDR + opt_func_foo_addr + opt_func_foo_tp_offset;
-
- if (build_id_to_bin()) {
- fprintf(stderr, "Failed to parse / missing build id\n");
- status = EXIT_FAILURE;
- goto end;
- }
-
- ret = bin_info_init(BT_LOG_OUTPUT_LEVEL, NULL);
- ok(ret == 0, "bin_info_init successful");
-
- test_bin_info_elf(opt_debug_info_dir);
- test_bin_info_bundled(opt_debug_info_dir);
- test_bin_info_build_id(opt_debug_info_dir);
- test_bin_info_debug_link(opt_debug_info_dir);
-
- status = exit_status();
-
-end:
- g_option_context_free(context);
-
- return status;
-}
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
-# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/flt.lttng-utils.debug-info"
-this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
-debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/i386-linux-gnu"
-
-"$this_dir_build/test_bin_info" \
- --foo-addr=0x1c8d \
- --printf-offset=0xda \
- --printf-lineno=36 \
- --tp-offset=0x12 \
- --tp-lineno=35 \
- --debug-link-crc=0xdeead493 \
- --debug-info-dir "$debug_info_data" \
- --build-id cdd98cdd87f7fe64c13b6daad553987eafd40cbb
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
-# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/flt.lttng-utils.debug-info"
-this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
-debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/powerpc-linux-gnu"
-
-"$this_dir_build/test_bin_info" \
- --foo-addr=0x23bc \
- --printf-offset=0x114 \
- --printf-lineno=36 \
- --tp-offset=0x28 \
- --tp-lineno=35 \
- --debug-link-crc=0xd7b98958 \
- --debug-info-dir "$debug_info_data" \
- --build-id cdd98cdd87f7fe64c13b6daad553987eafd40cbb
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
-# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/flt.lttng-utils.debug-info"
-this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
-debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/powerpc64le-linux-gnu"
-
-"$this_dir_build/test_bin_info" \
- --foo-addr=0x2e7c \
- --printf-offset=0x190 \
- --printf-lineno=36 \
- --tp-offset=0x1c \
- --tp-lineno=35 \
- --debug-link-crc=0x9b8eb2ff \
- --debug-info-dir "$debug_info_data" \
- --build-id cdd98cdd87f7fe64c13b6daad553987eafd40cbb
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
-# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/flt.lttng-utils.debug-info"
-this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
-debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/x86_64-linux-gnu"
-
-"$this_dir_build/test_bin_info" \
- --foo-addr=0x2277 \
- --printf-offset=0xf0 \
- --printf-lineno=36 \
- --tp-offset=0x89 \
- --tp-lineno=35 \
- --debug-link-crc=0x289a8fdc \
- --debug-info-dir "$debug_info_data" \
- --build-id cdd98cdd87f7fe64c13b6daad553987eafd40cbb
+++ /dev/null
-/*
- * SPDX-License-Identifier: GPL-2.0-only
- *
- * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation
- * Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
- *
- * Babeltrace bt_dwarf (DWARF utilities) tests
- */
-
-#include <fcntl.h>
-#include <glib.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <lttng-utils/debug-info/dwarf.h>
-#include "tap/tap.h"
-
-#define NR_TESTS 17
-
-#define SO_NAME "libhello_so"
-#define DWARF_DIR_NAME "dwarf_full"
-#define ELF_DIR_NAME "elf_only"
-
-/*
- * Test that we fail on an ELF file without DWARF.
- */
-static
-void test_bt_no_dwarf(const char *data_dir)
-{
- int fd;
- char *path;
- Dwarf *dwarf_info = NULL;
-
- path = g_build_filename(data_dir, ELF_DIR_NAME, SO_NAME, NULL);
- if (!path) {
- diag("Failed to allocate memory for path");
- exit(EXIT_FAILURE);
- }
-
- fd = open(path, O_RDONLY);
- ok(fd >= 0, "Open ELF file %s", path);
- if (fd < 0) {
- skip(1, "dwarf_begin failed as expected");
- } else {
- dwarf_info = dwarf_begin(fd, DWARF_C_READ);
- ok(!dwarf_info, "dwarf_begin failed as expected");
- }
-
- if (dwarf_info) {
- dwarf_end(dwarf_info);
- }
-
- if (fd >= 0) {
- close(fd);
- }
- g_free(path);
-}
-
-/*
- * Test with a proper ELF file with DWARF.
- */
-static
-void test_bt_dwarf(const char *data_dir)
-{
- int fd, ret, tag;
- char *path;
- char *die_name = NULL;
- struct bt_dwarf_cu *cu = NULL;
- struct bt_dwarf_die *die = NULL;
- Dwarf *dwarf_info = NULL;
-
- path = g_build_filename(data_dir, DWARF_DIR_NAME, SO_NAME, NULL);
- if (!path) {
- diag("Failed to allocate memory for path");
- exit(EXIT_FAILURE);
- }
-
- fd = open(path, O_RDONLY);
- ok(fd >= 0, "Open DWARF file %s", path);
- if (fd < 0) {
- exit(EXIT_FAILURE);
- }
- dwarf_info = dwarf_begin(fd, DWARF_C_READ);
- ok(dwarf_info, "dwarf_begin successful");
- cu = bt_dwarf_cu_create(dwarf_info);
- ok(cu, "bt_dwarf_cu_create successful");
- ret = bt_dwarf_cu_next(cu);
- ok(ret == 0, "bt_dwarf_cu_next successful");
- die = bt_dwarf_die_create(cu);
- ok(die, "bt_dwarf_die_create successful");
- if (!die) {
- exit(EXIT_FAILURE);
- }
- /*
- * Test bt_dwarf_die_next twice, as the code path is different
- * for DIEs at depth 0 (just created) and other depths.
- */
- ret = bt_dwarf_die_next(die);
- ok(ret == 0, "bt_dwarf_die_next from root DIE successful");
- ok(die->depth == 1,
- "bt_dwarf_die_next from root DIE - correct depth value");
- ret = bt_dwarf_die_next(die);
- ok(ret == 0,
- "bt_dwarf_die_next from non-root DIE successful");
- ok(die->depth == 1,
- "bt_dwarf_die_next from non-root DIE - correct depth value");
-
- /* Reset DIE to test dwarf_child */
- bt_dwarf_die_destroy(die);
- die = bt_dwarf_die_create(cu);
- if (!die) {
- diag("Failed to create bt_dwarf_die");
- exit(EXIT_FAILURE);
- }
-
- ret = bt_dwarf_die_child(die);
- ok(ret == 0, "bt_dwarf_die_child successful");
- ok(die->depth == 1, "bt_dwarf_die_child - correct depth value");
-
- ret = bt_dwarf_die_get_tag(die, &tag);
- ok(ret == 0, "bt_dwarf_die_get_tag successful");
- ok(tag == DW_TAG_typedef, "bt_dwarf_die_get_tag - correct tag value");
- ret = bt_dwarf_die_get_name(die, &die_name);
- ok(ret == 0, "bt_dwarf_die_get_name successful");
- ok(strcmp(die_name, "size_t") == 0,
- "bt_dwarf_die_get_name - correct name value");
-
- bt_dwarf_die_destroy(die);
- bt_dwarf_cu_destroy(cu);
- dwarf_end(dwarf_info);
- free(die_name);
- close(fd);
- g_free(path);
-}
-
-int main(int argc, char **argv)
-{
- const char *data_dir;
-
- plan_tests(NR_TESTS);
-
- if (argc != 2) {
- return EXIT_FAILURE;
- } else {
- data_dir = argv[1];
- }
-
- test_bt_no_dwarf(data_dir);
- test_bt_dwarf(data_dir);
-
- return exit_status();
-}
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
-# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/flt.lttng-utils.debug-info"
-this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
-debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/i386-linux-gnu"
-
-"$this_dir_build/test_dwarf" \
- "$debug_info_data"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
-# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/flt.lttng-utils.debug-info"
-this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
-debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/powerpc-linux-gnu"
-
-"$this_dir_build/test_dwarf" \
- "$debug_info_data"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
-# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/flt.lttng-utils.debug-info"
-this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
-debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/powerpc64le-linux-gnu"
-
-"$this_dir_build/test_dwarf" \
- "$debug_info_data"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2015 Antoine Busque <abusque@efficios.com>
-# Copyright (C) 2019 Michael Jeanson <mjeanson@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/flt.lttng-utils.debug-info"
-this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
-debug_info_data="$BT_TESTS_DATADIR/$this_dir_relative/x86_64-linux-gnu"
-
-"$this_dir_build/test_dwarf" \
- "$debug_info_data/"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
-# Copyright (C) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
-#
-
-# This test validates that a `src.ctf.fs` component successfully reads
-# specific CTF traces and creates the expected messages.
-#
-# Such CTF traces to open either exist (in `tests/ctf-traces/succeed`)
-# or are generated by this test using local trace generators.
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/flt.lttng-utils.debug-info"
-succeed_trace_dir="$BT_CTF_TRACES_PATH/succeed"
-expect_dir="$BT_TESTS_DATADIR/$this_dir_relative"
-binary_artefact_dir="$BT_TESTS_DATADIR/$this_dir_relative"
-data_dir="$BT_TESTS_DATADIR/$this_dir_relative"
-
-test_debug_info() {
- local name="$1"
- local local_args=(
- "-c" "flt.lttng-utils.debug-info"
- "-p" "target-prefix=\"$binary_artefact_dir/x86_64-linux-gnu/dwarf_full\""
- "-c" "sink.text.details"
- "-p" "with-trace-name=no,with-stream-name=no"
- )
-
- bt_diff_cli "$expect_dir/trace-$name.expect" "/dev/null" \
- "$succeed_trace_dir/$name" "${local_args[@]}"
- ok $? "Trace '$name' gives the expected output"
-}
-
-test_compare_to_ctf_fs() {
- # Compare the `sink.text.details` output of a graph with and without a
- # `flt.lttng-utils.debug-info` component. Both should be identical for
- # traces without LTTng debugging fields.
- local test_name=$1
- shift 1
- local cli_args=("$@")
- local debug_info_cli_args=("-c" "flt.lttng-utils.debug-info")
- local details_cli_args=(
- "-c" "sink.text.details"
- "--params" "with-trace-name=false,with-stream-name=false,with-uuid=false"
- )
- local actual_stdout
- local actual_stderr
- local expected_stdout
- local expected_stderr
- local ret=0
-
- actual_stdout=$(mktemp -t test_debug_info_stdout_actual.XXXXXX)
- actual_stderr=$(mktemp -t test_debug_info_stderr_actual.XXXXXX)
- expected_stdout=$(mktemp -t test_debug_info_stdout_expected.XXXXXX)
- expected_stderr=$(mktemp -t test_debug_info_stderr_expected.XXXXXX)
-
- # Create expected files using a graph without a `debug-info` component.
- bt_cli "$expected_stdout" "$expected_stderr" "${cli_args[@]}" \
- "${details_cli_args[@]}"
-
- # Read the same trace with a `debug-info` component in the graph.
- bt_cli "$actual_stdout" "$actual_stderr" "${cli_args[@]}" \
- "${details_cli_args[@]}" "${debug_info_cli_args[@]}"
-
- bt_diff "$expected_stdout" "$actual_stdout"
- ok $? "Input '$test_name' gives the expected stdout"
-
- bt_diff "$expected_stderr" "$actual_stderr"
- ok $? "Input '$test_name' gives the expected stderr"
-
- rm -f "$actual_stdout"
- rm -f "$actual_stderr"
- rm -f "$expected_stdout"
- rm -f "$expected_stderr"
-}
-
-test_compare_ctf_src_trace() {
- local trace_name=$1
- local trace_path="$succeed_trace_dir/$trace_name"
- local cli_args=("$trace_path")
-
- diag "Comparing output with and without 'flt.lttng-utils.debug-info' on '$trace_name'"
- test_compare_to_ctf_fs "src.ctf.fs with $trace_name trace" "${cli_args[@]}"
-}
-
-test_compare_complete_src_trace() {
-
- local source_name="src.test_debug_info.CompleteSrc"
- local cli_args=("--plugin-path=$data_dir" "-c" "$source_name")
- test_compare_to_ctf_fs "$source_name" "${cli_args[@]}"
-}
-
-plan_tests 9
-
-test_debug_info debug-info
-
-test_compare_ctf_src_trace smalltrace
-test_compare_ctf_src_trace 2packets
-test_compare_ctf_src_trace session-rotation
-
-test_compare_complete_src_trace
# SPDX-License-Identifier: MIT
dist_check_SCRIPTS = \
- test_succeed
+ test-succeed.sh
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
+#
+
+# This file tests what happens when we mux messages.
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
+fi
+
+# shellcheck source=../../../utils/utils.sh
+source "$UTILSSH"
+
+data_dir="$BT_TESTS_DATADIR/plugins/flt.utils.muxer"
+
+plan_tests 12
+
+function run_test
+{
+ local test_name="$1"
+ local local_args=(
+ "--plugin-path" "$data_dir"
+ "-c" "src.test-muxer.TheSourceOfConfusion"
+ "-p" "test-name=$test_name"
+ "-c" "sink.text.details"
+ "--params=compact=false,with-metadata=false"
+ )
+
+ stdout_expected="$data_dir/succeed/$test_name.expect"
+ bt_diff_cli "$stdout_expected" /dev/null "${local_args[@]}"
+ ok $? "$test_name"
+}
+
+
+test_cases=(
+ basic-timestamp-ordering
+ diff-event-class-id
+ diff-event-class-name
+ diff-inactivity-msg-cs
+ diff-stream-class-id
+ diff-stream-class-name
+ diff-stream-class-no-name
+ diff-stream-id
+ diff-stream-name
+ diff-stream-no-name
+ diff-trace-name
+ multi-iter-ordering
+)
+
+for i in "${test_cases[@]}"
+do
+ run_test "$i"
+done
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
-#
-
-# This file tests what happens when we mux messages.
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
-fi
-
-# shellcheck source=../../../utils/utils.sh
-source "$UTILSSH"
-
-data_dir="$BT_TESTS_DATADIR/plugins/flt.utils.muxer"
-
-plan_tests 12
-
-function run_test
-{
- local test_name="$1"
- local local_args=(
- "--plugin-path" "$data_dir"
- "-c" "src.test-muxer.TheSourceOfConfusion"
- "-p" "test-name=$test_name"
- "-c" "sink.text.details"
- "--params=compact=false,with-metadata=false"
- )
-
- stdout_expected="$data_dir/succeed/$test_name.expect"
- bt_diff_cli "$stdout_expected" /dev/null "${local_args[@]}"
- ok $? "$test_name"
-}
-
-
-test_cases=(
- basic_timestamp_ordering
- diff_event_class_id
- diff_event_class_name
- diff_inactivity_msg_cs
- diff_stream_class_id
- diff_stream_class_name
- diff_stream_class_no_name
- diff_stream_id
- diff_stream_name
- diff_stream_no_name
- diff_trace_name
- multi_iter_ordering
-)
-
-for i in "${test_cases[@]}"
-do
- run_test "$i"
-done
# SPDX-License-Identifier: MIT
dist_check_SCRIPTS = \
- test_trimming
+ test-trimming.sh
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+
+# This file tests what happens when we trim at different points in the message
+# flow.
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+data_dir="$BT_TESTS_DATADIR/plugins/flt.utils.trimmer"
+temp_stdout_expected=$(mktemp)
+temp_stderr_expected="/dev/null"
+
+plan_tests 56
+
+function run_test
+{
+ local begin_time="$1"
+ local end_time="$2"
+ # with_stream_msgs_cs and with_packet_msgs are set to "true" or "false"
+ # by the tests.
+ local local_args=(
+ "--plugin-path" "$data_dir"
+ "-c" "src.test-trimmer.TheSourceOfAllEvil"
+ "-p" "with-stream-msgs-cs=$with_stream_msgs_cs"
+ "-p" "with-packet-msgs=$with_packet_msgs"
+ "-c" "sink.text.details"
+ "--params=compact=true,with-metadata=false"
+ )
+
+ if [ "$with_stream_msgs_cs" = "true" ]; then
+ test_name="with stream message clock snapshots"
+ else
+ test_name="without stream message clock snapshots"
+ fi
+
+ if [ "$with_packet_msgs" = "true" ]; then
+ test_name="$test_name, with packet messages"
+ else
+ test_name="$test_name, without packet messages"
+ fi
+
+ if [ -n "$begin_time" ]; then
+ local_args+=("--begin=$begin_time")
+ test_name="$test_name, with --begin=$begin_time"
+ else
+ test_name="$test_name, without --begin"
+ fi
+
+ if [ -n "$end_time" ]; then
+ local_args+=("--end=$end_time")
+ test_name="$test_name, with --end=$end_time"
+ else
+ test_name="$test_name, without --end"
+ fi
+
+ bt_diff_cli "$temp_stdout_expected" "$temp_stderr_expected" "${local_args[@]}"
+ ok $? "$test_name"
+}
+
+function test_with_stream_msg_cs_with_packets {
+ with_stream_msgs_cs="true"
+ with_packet_msgs="true"
+
+ # Baseline (without trimming)
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+ run_test "" ""
+
+ # Trim begin at a time before what the clock class can represent
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+ run_test 50 ""
+
+ # Trim begin before stream beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+ run_test 10050 ""
+
+ # Trim begin before packet beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [150 10,150,000,000,000] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+ run_test 10150 ""
+
+ # Trim begin before first event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [250 10,250,000,000,000] {0 0 0} Stream beginning
+ [250 10,250,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+ run_test 10250 ""
+
+ # Trim begin before second event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [350 10,350,000,000,000] {0 0 0} Stream beginning
+ [350 10,350,000,000,000] {0 0 0} Packet beginning
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test 10350 ""
+
+ # Trim begin before packet end
+ cat <<- 'END' > "$temp_stdout_expected"
+ [850 10,850,000,000,000] {0 0 0} Stream beginning
+ [850 10,850,000,000,000] {0 0 0} Packet beginning
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test 10850 ""
+
+ # Trim begin after everything
+ cat <<- 'END' > "$temp_stdout_expected"
+ END
+
+ run_test 11050 ""
+
+ # Trim end after stream end
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 11050
+
+ # Trim end after packet end
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [950 10,950,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10950
+
+ # Trim end after second event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [450 10,450,000,000,000] {0 0 0} Packet end
+ [450 10,450,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10450
+
+ # Trim end after first event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [350 10,350,000,000,000] {0 0 0} Packet end
+ [350 10,350,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10350
+
+ # Trim end after packet beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [250 10,250,000,000,000] {0 0 0} Packet end
+ [250 10,250,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10250
+
+ # Trim end after stream beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [150 10,150,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10150
+
+ # Trim end before everything
+ cat <<- 'END' > "$temp_stdout_expected"
+ END
+
+ run_test "" 10050
+
+ # Trim end at a time before what the clock class can represent
+ cat <<- 'END' > "$temp_stdout_expected"
+ END
+
+ run_test "" 50
+}
+
+function test_without_stream_msg_cs_with_packets {
+ with_stream_msgs_cs="false"
+ with_packet_msgs="true"
+
+ # Baseline (without trimming)
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [Unknown] {0 0 0} Stream end
+ END
+ run_test "" ""
+
+ # Trim begin at a time before what the clock class can represent
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [Unknown] {0 0 0} Stream end
+ END
+ run_test 50 ""
+
+ # Trim begin before stream beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [Unknown] {0 0 0} Stream end
+ END
+ run_test 10050 ""
+
+ # Trim begin before packet beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [Unknown] {0 0 0} Stream end
+ END
+ run_test 10150 ""
+
+ # Trim begin before first event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [250 10,250,000,000,000] {0 0 0} Stream beginning
+ [250 10,250,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [Unknown] {0 0 0} Stream end
+ END
+ run_test 10250 ""
+
+ # Trim begin before second event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [350 10,350,000,000,000] {0 0 0} Stream beginning
+ [350 10,350,000,000,000] {0 0 0} Packet beginning
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [Unknown] {0 0 0} Stream end
+ END
+
+ run_test 10350 ""
+
+ # Trim begin before packet end
+ cat <<- 'END' > "$temp_stdout_expected"
+ [850 10,850,000,000,000] {0 0 0} Stream beginning
+ [850 10,850,000,000,000] {0 0 0} Packet beginning
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [Unknown] {0 0 0} Stream end
+ END
+
+ run_test 10850 ""
+
+ # Trim begin after everything
+ cat <<- 'END' > "$temp_stdout_expected"
+ END
+
+ run_test 11050 ""
+
+ # Trim end after stream end
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [Unknown] {0 0 0} Stream end
+ END
+
+ run_test "" 11050
+
+ # Trim end after packet end
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [900 10,900,000,000,000] {0 0 0} Packet end
+ [Unknown] {0 0 0} Stream end
+ END
+
+ run_test "" 10950
+
+ # Trim end after second event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [450 10,450,000,000,000] {0 0 0} Packet end
+ [450 10,450,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10450
+
+ # Trim end after first event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [350 10,350,000,000,000] {0 0 0} Packet end
+ [350 10,350,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10350
+
+ # Trim end after packet beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [200 10,200,000,000,000] {0 0 0} Packet beginning
+ [250 10,250,000,000,000] {0 0 0} Packet end
+ [250 10,250,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10250
+
+ # Trim end after stream beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [Unknown] {0 0 0} Stream end
+ END
+
+ run_test "" 10150
+
+ # Trim end before everything
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [Unknown] {0 0 0} Stream end
+ END
+
+ run_test "" 10050
+
+ # Trim end at a time before what the clock class can represent
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [Unknown] {0 0 0} Stream end
+ END
+
+ run_test "" 50
+}
+
+function test_with_stream_msg_cs_without_packets {
+ with_stream_msgs_cs="true"
+ with_packet_msgs="false"
+
+ # Baseline (without trimming)
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+ run_test "" ""
+
+ # Trim begin at a time before what the clock class can represent
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+ run_test 50 ""
+
+ # Trim begin before stream beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+ run_test 10050 ""
+
+ # Trim begin before first event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [250 10,250,000,000,000] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+ run_test 10250 ""
+
+ # Trim begin before second event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [350 10,350,000,000,000] {0 0 0} Stream beginning
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test 10350 ""
+
+ # Trim begin before packet end
+ cat <<- 'END' > "$temp_stdout_expected"
+ [850 10,850,000,000,000] {0 0 0} Stream beginning
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test 10850 ""
+
+ # Trim begin after everything
+ cat <<- 'END' > "$temp_stdout_expected"
+ END
+
+ run_test 11050 ""
+
+ # Trim end after stream end
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [1000 11,000,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 11050
+
+ # Trim end after packet end
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [950 10,950,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10950
+
+ # Trim end after second event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [450 10,450,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10450
+
+ # Trim end after first event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [350 10,350,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10350
+
+ # Trim end after packet beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [250 10,250,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10250
+
+ # Trim end after stream beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [100 10,100,000,000,000] {0 0 0} Stream beginning
+ [150 10,150,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10150
+
+ # Trim end before everything
+ cat <<- 'END' > "$temp_stdout_expected"
+ END
+
+ run_test "" 10050
+
+ # Trim end at a time before what the clock class can represent
+ cat <<- 'END' > "$temp_stdout_expected"
+ END
+
+ run_test "" 50
+}
+
+function test_without_stream_msg_cs_without_packets {
+ with_stream_msgs_cs="false"
+ with_packet_msgs="false"
+
+ # Baseline (without trimming)
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [Unknown] {0 0 0} Stream end
+ END
+ run_test "" ""
+
+ # Trim begin at a time before what the clock class can represent
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [Unknown] {0 0 0} Stream end
+ END
+ run_test 50 ""
+
+ # Trim begin before stream beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [Unknown] {0 0 0} Stream end
+ END
+ run_test 10050 ""
+
+ # Trim begin before second event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [350 10,350,000,000,000] {0 0 0} Stream beginning
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [Unknown] {0 0 0} Stream end
+ END
+
+ run_test 10350 ""
+
+ # Trim begin after everything
+ cat <<- 'END' > "$temp_stdout_expected"
+ END
+
+ run_test 11050 ""
+
+ # Trim end after stream end
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
+ [Unknown] {0 0 0} Stream end
+ END
+
+ run_test "" 11050
+
+ # Trim end after first event
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
+ [350 10,350,000,000,000] {0 0 0} Stream end
+ END
+
+ run_test "" 10350
+
+ # Trim end after stream beginning
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [Unknown] {0 0 0} Stream end
+ END
+
+ run_test "" 10150
+
+ # Trim end at a time before what the clock class can represent
+ cat <<- 'END' > "$temp_stdout_expected"
+ [Unknown] {0 0 0} Stream beginning
+ [Unknown] {0 0 0} Stream end
+ END
+
+ run_test "" 50
+}
+
+test_with_stream_msg_cs_with_packets
+test_without_stream_msg_cs_with_packets
+test_with_stream_msg_cs_without_packets
+test_without_stream_msg_cs_without_packets
+
+# Do not `rm` $temp_stderr_expected because it's set to `/dev/null` right now
+# and that would print an error.
+rm -f "$temp_stdout_expected"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-
-# This file tests what happens when we trim at different points in the message
-# flow.
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-data_dir="$BT_TESTS_DATADIR/plugins/flt.utils.trimmer"
-temp_stdout_expected=$(mktemp)
-temp_stderr_expected="/dev/null"
-
-plan_tests 56
-
-function run_test
-{
- local begin_time="$1"
- local end_time="$2"
- # with_stream_msgs_cs and with_packet_msgs are set to "true" or "false"
- # by the tests.
- local local_args=(
- "--plugin-path" "$data_dir"
- "-c" "src.test-trimmer.TheSourceOfAllEvil"
- "-p" "with-stream-msgs-cs=$with_stream_msgs_cs"
- "-p" "with-packet-msgs=$with_packet_msgs"
- "-c" "sink.text.details"
- "--params=compact=true,with-metadata=false"
- )
-
- if [ "$with_stream_msgs_cs" = "true" ]; then
- test_name="with stream message clock snapshots"
- else
- test_name="without stream message clock snapshots"
- fi
-
- if [ "$with_packet_msgs" = "true" ]; then
- test_name="$test_name, with packet messages"
- else
- test_name="$test_name, without packet messages"
- fi
-
- if [ -n "$begin_time" ]; then
- local_args+=("--begin=$begin_time")
- test_name="$test_name, with --begin=$begin_time"
- else
- test_name="$test_name, without --begin"
- fi
-
- if [ -n "$end_time" ]; then
- local_args+=("--end=$end_time")
- test_name="$test_name, with --end=$end_time"
- else
- test_name="$test_name, without --end"
- fi
-
- bt_diff_cli "$temp_stdout_expected" "$temp_stderr_expected" "${local_args[@]}"
- ok $? "$test_name"
-}
-
-function test_with_stream_msg_cs_with_packets {
- with_stream_msgs_cs="true"
- with_packet_msgs="true"
-
- # Baseline (without trimming)
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
- run_test "" ""
-
- # Trim begin at a time before what the clock class can represent
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
- run_test 50 ""
-
- # Trim begin before stream beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
- run_test 10050 ""
-
- # Trim begin before packet beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [150 10,150,000,000,000] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
- run_test 10150 ""
-
- # Trim begin before first event
- cat <<- 'END' > "$temp_stdout_expected"
- [250 10,250,000,000,000] {0 0 0} Stream beginning
- [250 10,250,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
- run_test 10250 ""
-
- # Trim begin before second event
- cat <<- 'END' > "$temp_stdout_expected"
- [350 10,350,000,000,000] {0 0 0} Stream beginning
- [350 10,350,000,000,000] {0 0 0} Packet beginning
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
-
- run_test 10350 ""
-
- # Trim begin before packet end
- cat <<- 'END' > "$temp_stdout_expected"
- [850 10,850,000,000,000] {0 0 0} Stream beginning
- [850 10,850,000,000,000] {0 0 0} Packet beginning
- [900 10,900,000,000,000] {0 0 0} Packet end
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
-
- run_test 10850 ""
-
- # Trim begin after everything
- cat <<- 'END' > "$temp_stdout_expected"
- END
-
- run_test 11050 ""
-
- # Trim end after stream end
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 11050
-
- # Trim end after packet end
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [950 10,950,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10950
-
- # Trim end after second event
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [450 10,450,000,000,000] {0 0 0} Packet end
- [450 10,450,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10450
-
- # Trim end after first event
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [350 10,350,000,000,000] {0 0 0} Packet end
- [350 10,350,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10350
-
- # Trim end after packet beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [250 10,250,000,000,000] {0 0 0} Packet end
- [250 10,250,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10250
-
- # Trim end after stream beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [150 10,150,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10150
-
- # Trim end before everything
- cat <<- 'END' > "$temp_stdout_expected"
- END
-
- run_test "" 10050
-
- # Trim end at a time before what the clock class can represent
- cat <<- 'END' > "$temp_stdout_expected"
- END
-
- run_test "" 50
-}
-
-function test_without_stream_msg_cs_with_packets {
- with_stream_msgs_cs="false"
- with_packet_msgs="true"
-
- # Baseline (without trimming)
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [Unknown] {0 0 0} Stream end
- END
- run_test "" ""
-
- # Trim begin at a time before what the clock class can represent
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [Unknown] {0 0 0} Stream end
- END
- run_test 50 ""
-
- # Trim begin before stream beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [Unknown] {0 0 0} Stream end
- END
- run_test 10050 ""
-
- # Trim begin before packet beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [Unknown] {0 0 0} Stream end
- END
- run_test 10150 ""
-
- # Trim begin before first event
- cat <<- 'END' > "$temp_stdout_expected"
- [250 10,250,000,000,000] {0 0 0} Stream beginning
- [250 10,250,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [Unknown] {0 0 0} Stream end
- END
- run_test 10250 ""
-
- # Trim begin before second event
- cat <<- 'END' > "$temp_stdout_expected"
- [350 10,350,000,000,000] {0 0 0} Stream beginning
- [350 10,350,000,000,000] {0 0 0} Packet beginning
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [Unknown] {0 0 0} Stream end
- END
-
- run_test 10350 ""
-
- # Trim begin before packet end
- cat <<- 'END' > "$temp_stdout_expected"
- [850 10,850,000,000,000] {0 0 0} Stream beginning
- [850 10,850,000,000,000] {0 0 0} Packet beginning
- [900 10,900,000,000,000] {0 0 0} Packet end
- [Unknown] {0 0 0} Stream end
- END
-
- run_test 10850 ""
-
- # Trim begin after everything
- cat <<- 'END' > "$temp_stdout_expected"
- END
-
- run_test 11050 ""
-
- # Trim end after stream end
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [Unknown] {0 0 0} Stream end
- END
-
- run_test "" 11050
-
- # Trim end after packet end
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [900 10,900,000,000,000] {0 0 0} Packet end
- [Unknown] {0 0 0} Stream end
- END
-
- run_test "" 10950
-
- # Trim end after second event
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [450 10,450,000,000,000] {0 0 0} Packet end
- [450 10,450,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10450
-
- # Trim end after first event
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [350 10,350,000,000,000] {0 0 0} Packet end
- [350 10,350,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10350
-
- # Trim end after packet beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [200 10,200,000,000,000] {0 0 0} Packet beginning
- [250 10,250,000,000,000] {0 0 0} Packet end
- [250 10,250,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10250
-
- # Trim end after stream beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [Unknown] {0 0 0} Stream end
- END
-
- run_test "" 10150
-
- # Trim end before everything
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [Unknown] {0 0 0} Stream end
- END
-
- run_test "" 10050
-
- # Trim end at a time before what the clock class can represent
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [Unknown] {0 0 0} Stream end
- END
-
- run_test "" 50
-}
-
-function test_with_stream_msg_cs_without_packets {
- with_stream_msgs_cs="true"
- with_packet_msgs="false"
-
- # Baseline (without trimming)
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
- run_test "" ""
-
- # Trim begin at a time before what the clock class can represent
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
- run_test 50 ""
-
- # Trim begin before stream beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
- run_test 10050 ""
-
- # Trim begin before first event
- cat <<- 'END' > "$temp_stdout_expected"
- [250 10,250,000,000,000] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
- run_test 10250 ""
-
- # Trim begin before second event
- cat <<- 'END' > "$temp_stdout_expected"
- [350 10,350,000,000,000] {0 0 0} Stream beginning
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
-
- run_test 10350 ""
-
- # Trim begin before packet end
- cat <<- 'END' > "$temp_stdout_expected"
- [850 10,850,000,000,000] {0 0 0} Stream beginning
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
-
- run_test 10850 ""
-
- # Trim begin after everything
- cat <<- 'END' > "$temp_stdout_expected"
- END
-
- run_test 11050 ""
-
- # Trim end after stream end
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [1000 11,000,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 11050
-
- # Trim end after packet end
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [950 10,950,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10950
-
- # Trim end after second event
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [450 10,450,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10450
-
- # Trim end after first event
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [350 10,350,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10350
-
- # Trim end after packet beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [250 10,250,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10250
-
- # Trim end after stream beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [100 10,100,000,000,000] {0 0 0} Stream beginning
- [150 10,150,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10150
-
- # Trim end before everything
- cat <<- 'END' > "$temp_stdout_expected"
- END
-
- run_test "" 10050
-
- # Trim end at a time before what the clock class can represent
- cat <<- 'END' > "$temp_stdout_expected"
- END
-
- run_test "" 50
-}
-
-function test_without_stream_msg_cs_without_packets {
- with_stream_msgs_cs="false"
- with_packet_msgs="false"
-
- # Baseline (without trimming)
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [Unknown] {0 0 0} Stream end
- END
- run_test "" ""
-
- # Trim begin at a time before what the clock class can represent
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [Unknown] {0 0 0} Stream end
- END
- run_test 50 ""
-
- # Trim begin before stream beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [Unknown] {0 0 0} Stream end
- END
- run_test 10050 ""
-
- # Trim begin before second event
- cat <<- 'END' > "$temp_stdout_expected"
- [350 10,350,000,000,000] {0 0 0} Stream beginning
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [Unknown] {0 0 0} Stream end
- END
-
- run_test 10350 ""
-
- # Trim begin after everything
- cat <<- 'END' > "$temp_stdout_expected"
- END
-
- run_test 11050 ""
-
- # Trim end after stream end
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [400 10,400,000,000,000] {0 0 0} Event `event 2` (1)
- [Unknown] {0 0 0} Stream end
- END
-
- run_test "" 11050
-
- # Trim end after first event
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [300 10,300,000,000,000] {0 0 0} Event `event 1` (0)
- [350 10,350,000,000,000] {0 0 0} Stream end
- END
-
- run_test "" 10350
-
- # Trim end after stream beginning
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [Unknown] {0 0 0} Stream end
- END
-
- run_test "" 10150
-
- # Trim end at a time before what the clock class can represent
- cat <<- 'END' > "$temp_stdout_expected"
- [Unknown] {0 0 0} Stream beginning
- [Unknown] {0 0 0} Stream end
- END
-
- run_test "" 50
-}
-
-test_with_stream_msg_cs_with_packets
-test_without_stream_msg_cs_with_packets
-test_with_stream_msg_cs_without_packets
-test_without_stream_msg_cs_without_packets
-
-# Do not `rm` $temp_stderr_expected because it's set to `/dev/null` right now
-# and that would print an error.
-rm -f "$temp_stdout_expected"
SUBDIRS = succeed
dist_check_SCRIPTS = \
- test_assume_single_trace \
- test_stream_names
+ test-assume-single-trace.sh \
+ test-stream-names.sh
# SPDX-License-Identifier: MIT
-dist_check_SCRIPTS = test_succeed
+dist_check_SCRIPTS = test-succeed.sh
# CTF trace generators
GEN_TRACE_LDADD = \
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
+#
+
+# This test validates that a `src.ctf.fs` component successfully reads
+# specific CTF traces and creates the expected messages.
+#
+# Such CTF traces to open either exist (in `tests/ctf-traces/succeed`)
+# or are generated by this test using local trace generators.
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
+fi
+
+# shellcheck source=../../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/sink.ctf.fs/succeed"
+this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
+expect_dir="$BT_TESTS_DATADIR/$this_dir_relative"
+succeed_traces="$BT_CTF_TRACES_PATH/succeed"
+
+test_ctf_single() {
+ local name="$1"
+ local in_trace_dir="$2"
+ local temp_out_trace_dir
+
+ temp_out_trace_dir="$(mktemp -d)"
+
+ diag "Converting trace '$name' to CTF through 'sink.ctf.fs'"
+ "$BT_TESTS_BT2_BIN" >/dev/null "$in_trace_dir" -o ctf -w "$temp_out_trace_dir"
+ ret=$?
+ ok $ret "'sink.ctf.fs' component succeeds with input trace '$name'"
+ converted_test_name="Converted trace '$name' gives the expected output"
+
+ if [ $ret -eq 0 ]; then
+ bt_diff_details_ctf_single "$expect_dir/trace-$name.expect" \
+ "$temp_out_trace_dir" \
+ '-p' 'with-uuid=no,with-trace-name=no,with-stream-name=no'
+ ok $? "$converted_test_name"
+ else
+ fail "$converted_test_name"
+ fi
+
+ rm -rf "$temp_out_trace_dir"
+}
+
+test_ctf_existing_single() {
+ local name="$1"
+ local trace_dir="$succeed_traces/$name"
+
+ test_ctf_single "$name" "$trace_dir"
+}
+
+test_ctf_gen_single() {
+ local name="$1"
+ local temp_gen_trace_dir
+
+ temp_gen_trace_dir="$(mktemp -d)"
+
+ diag "Generating trace '$name'"
+
+ if ! "$this_dir_build/gen-trace-$name" "$temp_gen_trace_dir"; then
+ # this is not part of the test itself; it must not fail
+ echo "ERROR: \"$this_dir_build/gen-trace-$name" "$temp_gen_trace_dir\" failed" >&2
+ rm -rf "$temp_gen_trace_dir"
+ exit 1
+ fi
+
+ test_ctf_single "$name" "$temp_gen_trace_dir"
+ rm -rf "$temp_gen_trace_dir"
+}
+
+plan_tests 14
+
+test_ctf_gen_single float
+test_ctf_gen_single double
+test_ctf_existing_single meta-variant-no-underscore
+test_ctf_existing_single meta-variant-one-underscore
+test_ctf_existing_single meta-variant-reserved-keywords
+test_ctf_existing_single meta-variant-same-with-underscore
+test_ctf_existing_single meta-variant-two-underscores
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
-#
-
-# This test validates that a `src.ctf.fs` component successfully reads
-# specific CTF traces and creates the expected messages.
-#
-# Such CTF traces to open either exist (in `tests/ctf-traces/succeed`)
-# or are generated by this test using local trace generators.
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
-fi
-
-# shellcheck source=../../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/sink.ctf.fs/succeed"
-this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
-expect_dir="$BT_TESTS_DATADIR/$this_dir_relative"
-succeed_traces="$BT_CTF_TRACES_PATH/succeed"
-
-test_ctf_single() {
- local name="$1"
- local in_trace_dir="$2"
- local temp_out_trace_dir
-
- temp_out_trace_dir="$(mktemp -d)"
-
- diag "Converting trace '$name' to CTF through 'sink.ctf.fs'"
- "$BT_TESTS_BT2_BIN" >/dev/null "$in_trace_dir" -o ctf -w "$temp_out_trace_dir"
- ret=$?
- ok $ret "'sink.ctf.fs' component succeeds with input trace '$name'"
- converted_test_name="Converted trace '$name' gives the expected output"
-
- if [ $ret -eq 0 ]; then
- bt_diff_details_ctf_single "$expect_dir/trace-$name.expect" \
- "$temp_out_trace_dir" \
- '-p' 'with-uuid=no,with-trace-name=no,with-stream-name=no'
- ok $? "$converted_test_name"
- else
- fail "$converted_test_name"
- fi
-
- rm -rf "$temp_out_trace_dir"
-}
-
-test_ctf_existing_single() {
- local name="$1"
- local trace_dir="$succeed_traces/$name"
-
- test_ctf_single "$name" "$trace_dir"
-}
-
-test_ctf_gen_single() {
- local name="$1"
- local temp_gen_trace_dir
-
- temp_gen_trace_dir="$(mktemp -d)"
-
- diag "Generating trace '$name'"
-
- if ! "$this_dir_build/gen-trace-$name" "$temp_gen_trace_dir"; then
- # this is not part of the test itself; it must not fail
- echo "ERROR: \"$this_dir_build/gen-trace-$name" "$temp_gen_trace_dir\" failed" >&2
- rm -rf "$temp_gen_trace_dir"
- exit 1
- fi
-
- test_ctf_single "$name" "$temp_gen_trace_dir"
- rm -rf "$temp_gen_trace_dir"
-}
-
-plan_tests 14
-
-test_ctf_gen_single float
-test_ctf_gen_single double
-test_ctf_existing_single meta-variant-no-underscore
-test_ctf_existing_single meta-variant-one-underscore
-test_ctf_existing_single meta-variant-reserved-keywords
-test_ctf_existing_single meta-variant-same-with-underscore
-test_ctf_existing_single meta-variant-two-underscores
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2020 EfficiOS Inc.
+#
+
+# This file tests the assume-single-trace parameter of sink.ctf.fs.
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+# Directory containing the Python test source.
+data_dir="$BT_TESTS_DATADIR/plugins/sink.ctf.fs/assume-single-trace"
+
+temp_stdout=$(mktemp)
+temp_expected_stdout=$(mktemp)
+temp_stderr=$(mktemp)
+temp_output_dir=$(mktemp -d)
+
+trace_dir="$temp_output_dir/the-trace"
+
+plan_tests 7
+
+bt_cli "$temp_stdout" "$temp_stderr" \
+ "--plugin-path=${data_dir}" \
+ -c src.foo.TheSource \
+ -c sink.ctf.fs -p "path=\"${trace_dir}\"" -p 'assume-single-trace=true'
+ok "$?" "run sink.ctf.fs with assume-single-trace=true"
+
+# Check stdout.
+if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
+ echo "Created CTF trace \`$(cygpath -m "${trace_dir}")\`." > "$temp_expected_stdout"
+else
+ echo "Created CTF trace \`${trace_dir}\`." > "$temp_expected_stdout"
+fi
+bt_diff "$temp_expected_stdout" "$temp_stdout"
+ok "$?" "expected message on stdout"
+
+# Check stderr.
+bt_diff "/dev/null" "$temp_stderr"
+ok "$?" "stderr is empty"
+
+# Verify only the expected files exist.
+files=("$trace_dir"/*)
+num_files=${#files[@]}
+is "$num_files" "2" "expected number of files in output directory"
+
+test -f "$trace_dir/metadata"
+ok "$?" "metadata file exists"
+
+test -f "$trace_dir/the-stream"
+ok "$?" "the-stream file exists"
+
+# Read back the output trace to make sure it's properly formed.
+echo "the-event: " > "$temp_expected_stdout"
+bt_diff_cli "$temp_expected_stdout" /dev/null "$trace_dir"
+ok "$?" "read back output trace"
+
+rm -f "$temp_stdout"
+rm -f "$temp_stderr"
+rm -f "$temp_expected_stdout"
+rm -f "$trace_dir/metadata"
+rm -f "$trace_dir/the-stream"
+rmdir "$trace_dir"
+rmdir "$temp_output_dir"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2020 EfficiOS Inc.
+#
+
+# This file tests corner cases related to stream names:
+#
+# - two streams with the same name
+# - a stream named "metadata"
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+# Directory containing the Python test source.
+data_dir="$BT_TESTS_DATADIR/plugins/sink.ctf.fs/stream-names"
+
+temp_stdout=$(mktemp)
+temp_expected_stdout=$(mktemp)
+temp_stderr=$(mktemp)
+temp_output_dir=$(mktemp -d)
+trace_dir="$temp_output_dir/trace"
+
+plan_tests 9
+
+bt_cli "$temp_stdout" "$temp_stderr" \
+ "--plugin-path=${data_dir}" \
+ -c src.foo.TheSource \
+ -c sink.ctf.fs -p "path=\"${temp_output_dir}\""
+ok "$?" "run babeltrace"
+
+# Check stdout.
+if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
+ # shellcheck disable=SC2028
+ echo "Created CTF trace \`$(cygpath -m "${temp_output_dir}")\\trace\`." > "$temp_expected_stdout"
+else
+ echo "Created CTF trace \`${trace_dir}\`." > "$temp_expected_stdout"
+fi
+bt_diff "$temp_expected_stdout" "$temp_stdout"
+ok "$?" "expected message on stdout"
+
+# Check stderr.
+bt_diff "/dev/null" "$temp_stderr"
+ok "$?" "stderr is empty"
+
+# Verify only the expected files exist.
+files=("$trace_dir"/*)
+num_files=${#files[@]}
+is "$num_files" "4" "expected number of files in output directory"
+
+test -f "$trace_dir/metadata"
+ok "$?" "metadata file exists"
+
+test -f "$trace_dir/metadata-0"
+ok "$?" "metadata-0 file exists"
+
+test -f "$trace_dir/the-stream"
+ok "$?" "the-stream file exists"
+
+test -f "$trace_dir/the-stream-0"
+ok "$?" "the-stream-0 file exists"
+
+# Read back the output trace to make sure it's properly formed.
+cat <<- 'END' > "$temp_expected_stdout"
+the-event:
+the-event:
+the-event:
+END
+bt_diff_cli "$temp_expected_stdout" /dev/null "$trace_dir"
+ok "$?" "read back output trace"
+
+rm -f "$temp_stdout"
+rm -f "$temp_stderr"
+rm -f "$temp_expected_stdout"
+rm -f "$trace_dir/metadata"
+rm -f "$trace_dir/metadata-0"
+rm -f "$trace_dir/the-stream"
+rm -f "$trace_dir/the-stream-0"
+rmdir "$trace_dir"
+rmdir "$temp_output_dir"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2020 EfficiOS Inc.
-#
-
-# This file tests the assume-single-trace parameter of sink.ctf.fs.
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-# Directory containing the Python test source.
-data_dir="$BT_TESTS_DATADIR/plugins/sink.ctf.fs/assume-single-trace"
-
-temp_stdout=$(mktemp)
-temp_expected_stdout=$(mktemp)
-temp_stderr=$(mktemp)
-temp_output_dir=$(mktemp -d)
-
-trace_dir="$temp_output_dir/the-trace"
-
-plan_tests 7
-
-bt_cli "$temp_stdout" "$temp_stderr" \
- "--plugin-path=${data_dir}" \
- -c src.foo.TheSource \
- -c sink.ctf.fs -p "path=\"${trace_dir}\"" -p 'assume-single-trace=true'
-ok "$?" "run sink.ctf.fs with assume-single-trace=true"
-
-# Check stdout.
-if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
- echo "Created CTF trace \`$(cygpath -m "${trace_dir}")\`." > "$temp_expected_stdout"
-else
- echo "Created CTF trace \`${trace_dir}\`." > "$temp_expected_stdout"
-fi
-bt_diff "$temp_expected_stdout" "$temp_stdout"
-ok "$?" "expected message on stdout"
-
-# Check stderr.
-bt_diff "/dev/null" "$temp_stderr"
-ok "$?" "stderr is empty"
-
-# Verify only the expected files exist.
-files=("$trace_dir"/*)
-num_files=${#files[@]}
-is "$num_files" "2" "expected number of files in output directory"
-
-test -f "$trace_dir/metadata"
-ok "$?" "metadata file exists"
-
-test -f "$trace_dir/the-stream"
-ok "$?" "the-stream file exists"
-
-# Read back the output trace to make sure it's properly formed.
-echo "the-event: " > "$temp_expected_stdout"
-bt_diff_cli "$temp_expected_stdout" /dev/null "$trace_dir"
-ok "$?" "read back output trace"
-
-rm -f "$temp_stdout"
-rm -f "$temp_stderr"
-rm -f "$temp_expected_stdout"
-rm -f "$trace_dir/metadata"
-rm -f "$trace_dir/the-stream"
-rmdir "$trace_dir"
-rmdir "$temp_output_dir"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2020 EfficiOS Inc.
-#
-
-# This file tests corner cases related to stream names:
-#
-# - two streams with the same name
-# - a stream named "metadata"
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-# Directory containing the Python test source.
-data_dir="$BT_TESTS_DATADIR/plugins/sink.ctf.fs/stream-names"
-
-temp_stdout=$(mktemp)
-temp_expected_stdout=$(mktemp)
-temp_stderr=$(mktemp)
-temp_output_dir=$(mktemp -d)
-trace_dir="$temp_output_dir/trace"
-
-plan_tests 9
-
-bt_cli "$temp_stdout" "$temp_stderr" \
- "--plugin-path=${data_dir}" \
- -c src.foo.TheSource \
- -c sink.ctf.fs -p "path=\"${temp_output_dir}\""
-ok "$?" "run babeltrace"
-
-# Check stdout.
-if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
- # shellcheck disable=SC2028
- echo "Created CTF trace \`$(cygpath -m "${temp_output_dir}")\\trace\`." > "$temp_expected_stdout"
-else
- echo "Created CTF trace \`${trace_dir}\`." > "$temp_expected_stdout"
-fi
-bt_diff "$temp_expected_stdout" "$temp_stdout"
-ok "$?" "expected message on stdout"
-
-# Check stderr.
-bt_diff "/dev/null" "$temp_stderr"
-ok "$?" "stderr is empty"
-
-# Verify only the expected files exist.
-files=("$trace_dir"/*)
-num_files=${#files[@]}
-is "$num_files" "4" "expected number of files in output directory"
-
-test -f "$trace_dir/metadata"
-ok "$?" "metadata file exists"
-
-test -f "$trace_dir/metadata-0"
-ok "$?" "metadata-0 file exists"
-
-test -f "$trace_dir/the-stream"
-ok "$?" "the-stream file exists"
-
-test -f "$trace_dir/the-stream-0"
-ok "$?" "the-stream-0 file exists"
-
-# Read back the output trace to make sure it's properly formed.
-cat <<- 'END' > "$temp_expected_stdout"
-the-event:
-the-event:
-the-event:
-END
-bt_diff_cli "$temp_expected_stdout" /dev/null "$trace_dir"
-ok "$?" "read back output trace"
-
-rm -f "$temp_stdout"
-rm -f "$temp_stderr"
-rm -f "$temp_expected_stdout"
-rm -f "$trace_dir/metadata"
-rm -f "$trace_dir/metadata-0"
-rm -f "$trace_dir/the-stream"
-rm -f "$trace_dir/the-stream-0"
-rmdir "$trace_dir"
-rmdir "$temp_output_dir"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
+#
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
+fi
+
+# shellcheck source=../../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/sink.text.details/succeed"
+expect_dir="$BT_TESTS_DATADIR/$this_dir_relative"
+
+test_details() {
+ local test_name="$1"
+ local trace_name="$2"
+ shift 2
+ local details_args=("$@")
+ local trace_dir="$BT_CTF_TRACES_PATH/succeed/$trace_name"
+ local expect_path="$expect_dir/$test_name.expect"
+
+ bt_diff_cli "$expect_path" /dev/null \
+ "$trace_dir" -p trace-name=the-trace \
+ -c sink.text.details "${details_args[@]+${details_args[@]}}"
+ ok $? "'$test_name' test has the expected output"
+}
+
+# This is used for the moment because the source is `src.ctf.fs` and
+# such a component can make its stream names contain absolute paths.
+test_details_no_stream_name() {
+ local test_name="$1"
+ local trace_name="$2"
+ shift 2
+ local details_args=("$@")
+
+ test_details "$test_name" "$trace_name" \
+ "${details_args[@]+${details_args[@]}}" -p with-stream-name=no
+}
+
+plan_tests 12
+
+test_details_no_stream_name default wk-heartbeat-u
+test_details_no_stream_name default-compact wk-heartbeat-u -p compact=yes
+test_details_no_stream_name default-compact-without-metadata wk-heartbeat-u -p compact=yes,with-metadata=no
+test_details_no_stream_name default-compact-without-time wk-heartbeat-u -p compact=yes,with-time=no
+test_details_no_stream_name default-without-data wk-heartbeat-u -p with-data=no
+test_details_no_stream_name default-without-data-without-metadata wk-heartbeat-u -p with-data=no,with-metadata=no
+test_details_no_stream_name default-without-metadata wk-heartbeat-u -p with-metadata=no
+test_details_no_stream_name default-without-names wk-heartbeat-u -p with-stream-name=no,with-trace-name=no,with-stream-class-name=no
+test_details_no_stream_name default-without-time wk-heartbeat-u -p with-time=no
+test_details_no_stream_name default-without-trace-name wk-heartbeat-u -p with-trace-name=no
+test_details_no_stream_name default-without-uuid wk-heartbeat-u -p with-uuid=no
+test_details_no_stream_name no-packet-context no-packet-context
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
-#
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
-fi
-
-# shellcheck source=../../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/sink.text.details/succeed"
-expect_dir="$BT_TESTS_DATADIR/$this_dir_relative"
-
-test_details() {
- local test_name="$1"
- local trace_name="$2"
- shift 2
- local details_args=("$@")
- local trace_dir="$BT_CTF_TRACES_PATH/succeed/$trace_name"
- local expect_path="$expect_dir/$test_name.expect"
-
- bt_diff_cli "$expect_path" /dev/null \
- "$trace_dir" -p trace-name=the-trace \
- -c sink.text.details "${details_args[@]+${details_args[@]}}"
- ok $? "'$test_name' test has the expected output"
-}
-
-# This is used for the moment because the source is `src.ctf.fs` and
-# such a component can make its stream names contain absolute paths.
-test_details_no_stream_name() {
- local test_name="$1"
- local trace_name="$2"
- shift 2
- local details_args=("$@")
-
- test_details "$test_name" "$trace_name" \
- "${details_args[@]+${details_args[@]}}" -p with-stream-name=no
-}
-
-plan_tests 12
-
-test_details_no_stream_name default wk-heartbeat-u
-test_details_no_stream_name default-compact wk-heartbeat-u -p compact=yes
-test_details_no_stream_name default-compact-without-metadata wk-heartbeat-u -p compact=yes,with-metadata=no
-test_details_no_stream_name default-compact-without-time wk-heartbeat-u -p compact=yes,with-time=no
-test_details_no_stream_name default-without-data wk-heartbeat-u -p with-data=no
-test_details_no_stream_name default-without-data-without-metadata wk-heartbeat-u -p with-data=no,with-metadata=no
-test_details_no_stream_name default-without-metadata wk-heartbeat-u -p with-metadata=no
-test_details_no_stream_name default-without-names wk-heartbeat-u -p with-stream-name=no,with-trace-name=no,with-stream-class-name=no
-test_details_no_stream_name default-without-time wk-heartbeat-u -p with-time=no
-test_details_no_stream_name default-without-trace-name wk-heartbeat-u -p with-trace-name=no
-test_details_no_stream_name default-without-uuid wk-heartbeat-u -p with-uuid=no
-test_details_no_stream_name no-packet-context no-packet-context
dist_check_SCRIPTS = \
- test_pretty_python \
- test_enum
+ test-pretty-python.sh \
+ test-enum.sh
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2020 Geneviève Bastien <gbastien@versatic.net>
+#
+# This file tests pretty printing in details some event classes that are
+# not all covered by the main babeltrace tests with traces.
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+data_dir="$BT_TESTS_DATADIR/plugins/sink.text.pretty"
+temp_stdout_expected_file=$(mktemp -t test-pretty-expected-stdout.XXXXXX)
+
+plan_tests 31
+
+function compare_enum_sorted
+{
+ local expected_file="$1"
+ local actual_file="$2"
+
+ # The order in which enum labels are printed by a `sink.text.pretty`
+ # component directly depends on the order in which mappings were added
+ # to the enum field class in the source component. This order should
+ # not be relied on when testing. Relying on it caused problems with
+ # Python component classes because different versions of Python sort
+ # data structures differently (e.g. dictionaries are insertion sorted
+ # since Python 3.7).
+
+ run_python_bt2 "${BT_TESTS_PYTHON_BIN}" "${BT_TESTS_SRCDIR}/utils/python/split_sort_compare.py" \
+ "$(cat "$expected_file")" "$(cat "$actual_file")"
+}
+
+function run_test
+{
+ local test_name=$1
+ local expected_to_fail="$2"
+ local value="$3"
+ local expected_stdout_file="$4"
+ local actual_stdout_file
+ local actual_stderr_file
+ local ret=0
+ local local_args=(
+ "--plugin-path" "$data_dir"
+ "-c" "src.test-pretty.TheSourceOfProblems"
+ "-p" "enum-values=\"$enum_values\""
+ "-p" "value=$value"
+ "-p" "enum-signed=$enum_signed"
+ "-c" "sink.text.pretty"
+ "-p" "print-enum-flags=true"
+ )
+
+ actual_stdout_file="$(mktemp -t actual-pretty-stdout.XXXXXX)"
+ actual_stderr_file="$(mktemp -t actual-pretty-stderr.XXXXXX)"
+
+ bt_cli "$actual_stdout_file" "$actual_stderr_file" "${local_args[@]}"
+
+ compare_enum_sorted "$expected_stdout_file" "$actual_stdout_file"
+ ret_stdout=$?
+
+ bt_diff /dev/null "$actual_stderr_file"
+ ret_stderr=$?
+
+ if ((ret_stdout != 0 || ret_stderr != 0)); then
+ ret=1
+ fi
+
+ rm -f "$actual_stdout_file" "$actual_stderr_file"
+
+ if [ "$expected_to_fail" = "1" ]; then
+ isnt $ret 0 "$test_name signed=$enum_signed with value=$value doesn't match as expected"
+ else
+ ok $ret "$test_name signed=$enum_signed with value=$value matches"
+ fi
+
+}
+
+function test_normal_enum {
+ test_name="Normal enum"
+ enum_signed="$1"
+ enum_values="single,1,1 single2,2,2 single3,4,4 range,4,8 range2,15,20"
+
+ # Hit a single value
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "single" : container = 1 ) }
+ END
+ run_test "$test_name" 0 1 "$temp_stdout_expected_file"
+
+ # Hit a single range
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "range" : container = 7 ) }
+ END
+ run_test "$test_name" 0 7 "$temp_stdout_expected_file"
+
+ # Hit a range and a value
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( { "single3", "range" } : container = 4 ) }
+ END
+ run_test "$test_name" 0 4 "$temp_stdout_expected_file"
+
+ # Hit a range and a value
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( { "NOT_A_LABEL", "DOESNT_EXIST" } : container = 4 ) }
+ END
+ run_test "$test_name" 1 4 "$temp_stdout_expected_file"
+
+ # Unknown
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( <unknown> : container = 21 ) }
+ END
+ run_test "$test_name" 0 21 "$temp_stdout_expected_file"
+
+ # Unknown but with bits with a value, but range larger than 1 element
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( <unknown> : container = 12 ) }
+ END
+ run_test "$test_name" 0 12 "$temp_stdout_expected_file"
+
+ # Unknown value of 0
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( <unknown> : container = 0 ) }
+ END
+ run_test "$test_name" 0 0 "$temp_stdout_expected_file"
+}
+
+function test_normal_enum_negative {
+ test_name="Normal enum with negative value"
+ enum_signed="true"
+ enum_values="zero,0,0 single,1,1 single2,2,2 single3,4,4 range,4,8 negative,-1,-1 rangeNegative,-6,-2"
+
+ # Hit a single negative value
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "negative" : container = -1 ) }
+ END
+ run_test "$test_name" 0 -1 "$temp_stdout_expected_file"
+
+ # Hit a single negative range
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "rangeNegative" : container = -6 ) }
+ END
+ run_test "$test_name" 0 -6 "$temp_stdout_expected_file"
+
+ # Unknown
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( <unknown> : container = -7 ) }
+ END
+ run_test "$test_name" 0 -7 "$temp_stdout_expected_file"
+
+ # value of 0
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "zero" : container = 0 ) }
+ END
+ run_test "$test_name" 0 0 "$temp_stdout_expected_file"
+}
+
+function test_bit_flag_enum {
+ test_name="Bit flag enum"
+ enum_signed="false"
+ enum_values="bit0,1,1 bit0bis,1,1 bit1,2,2 bit3,4,4 bit4,8,8 bit5,16,16 bit5,32,32"
+
+ # Single value hit
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "bit1" : container = 2 ) }
+ END
+ run_test "$test_name" 0 2 "$temp_stdout_expected_file"
+
+ # Multiple flags set
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "bit3" | "bit4" : container = 12 ) }
+ END
+ run_test "$test_name" 0 12 "$temp_stdout_expected_file"
+
+ # Some unknown bit
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( <unknown> : container = 68 ) }
+ END
+ run_test "$test_name" 0 68 "$temp_stdout_expected_file"
+
+ # Multiple labels for bit 0
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( { "bit0", "bit0bis" } : container = 1 ) }
+ END
+ run_test "$test_name" 0 1 "$temp_stdout_expected_file"
+
+ # Two labels for bit 0 and one label for bit 1
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( { "bit0", "bit0bis" } | "bit1" : container = 3 ) }
+ END
+ run_test "$test_name" 0 3 "$temp_stdout_expected_file"
+
+ # Single label for bit 0
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "bit5" | "bit5" : container = 48 ) }
+ END
+ run_test "$test_name" 0 48 "$temp_stdout_expected_file"
+
+ # negative value
+ enum_signed="true"
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( <unknown> : container = -1 ) }
+ END
+ run_test "$test_name" 0 -1 "$temp_stdout_expected_file"
+}
+
+function test_mixed_enum {
+ test_name="Mixed enum bits at beginning"
+ enum_signed="false"
+ enum_values="bit0,1,1 bit1,2,2 bit2,4,4 bit3,8,8 bit4,16,16 range,32,44 singleValue,45,45"
+
+ # Value with bit fields
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "bit0" | "bit1" | "bit2" | "bit3" | "bit4" : container = 31 ) }
+ END
+ run_test "$test_name" 0 31 "$temp_stdout_expected_file"
+
+ # A value with some bit flags set, but within another range
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "range" : container = 36 ) }
+ END
+ run_test "$test_name" 0 36 "$temp_stdout_expected_file"
+
+ # A value with some bit flags set, but corresponding to another value
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "singleValue" : container = 45 ) }
+ END
+ run_test "$test_name" 0 45 "$temp_stdout_expected_file"
+
+ # Value above the ranges
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( <unknown> : container = 46 ) }
+ END
+ run_test "$test_name" 0 46 "$temp_stdout_expected_file"
+
+ # Since low values are often powers of 2, they may be considered bit flags too
+ test_name="Mixed enum bits at end"
+ enum_signed="false"
+ enum_values="val1,1,1 val2,2,2 val3,3,3 val4,4,4 val5,5,5 bit3,8,8 bit4,16,16 bit5,32,32"
+
+ # Value with bit fields
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "bit4" : container = 16 ) }
+ END
+ run_test "$test_name" 0 16 "$temp_stdout_expected_file"
+
+ # Value with a bit field set both at beginning and end
+ cat <<- 'END' > "$temp_stdout_expected_file"
+ with_enum: { enum_field = ( "val1" | "bit4" : container = 17 ) }
+ END
+ run_test "$test_name" 0 17 "$temp_stdout_expected_file"
+}
+
+# Enumerations tests
+test_normal_enum "false"
+test_normal_enum "true"
+test_normal_enum_negative
+test_bit_flag_enum
+test_mixed_enum
+
+rm -f "$temp_stdout_expected_file"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+run_python_bt2_test "${BT_TESTS_SRCDIR}/plugins/sink.text.pretty" "test_*"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2020 Geneviève Bastien <gbastien@versatic.net>
-#
-# This file tests pretty printing in details some event classes that are
-# not all covered by the main babeltrace tests with traces.
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-data_dir="$BT_TESTS_DATADIR/plugins/sink.text.pretty"
-temp_stdout_expected_file=$(mktemp -t test_pretty_expected_stdout.XXXXXX)
-
-plan_tests 31
-
-function compare_enum_sorted
-{
- local expected_file="$1"
- local actual_file="$2"
-
- # The order in which enum labels are printed by a `sink.text.pretty`
- # component directly depends on the order in which mappings were added
- # to the enum field class in the source component. This order should
- # not be relied on when testing. Relying on it caused problems with
- # Python component classes because different versions of Python sort
- # data structures differently (e.g. dictionaries are insertion sorted
- # since Python 3.7).
-
- run_python_bt2 "${BT_TESTS_PYTHON_BIN}" "${BT_TESTS_SRCDIR}/utils/python/split_sort_compare.py" \
- "$(cat "$expected_file")" "$(cat "$actual_file")"
-}
-
-function run_test
-{
- local test_name=$1
- local expected_to_fail="$2"
- local value="$3"
- local expected_stdout_file="$4"
- local actual_stdout_file
- local actual_stderr_file
- local ret=0
- local local_args=(
- "--plugin-path" "$data_dir"
- "-c" "src.test-pretty.TheSourceOfProblems"
- "-p" "enum-values=\"$enum_values\""
- "-p" "value=$value"
- "-p" "enum-signed=$enum_signed"
- "-c" "sink.text.pretty"
- "-p" "print-enum-flags=true"
- )
-
- actual_stdout_file="$(mktemp -t actual_pretty_stdout.XXXXXX)"
- actual_stderr_file="$(mktemp -t actual_pretty_stderr.XXXXXX)"
-
- bt_cli "$actual_stdout_file" "$actual_stderr_file" "${local_args[@]}"
-
- compare_enum_sorted "$expected_stdout_file" "$actual_stdout_file"
- ret_stdout=$?
-
- bt_diff /dev/null "$actual_stderr_file"
- ret_stderr=$?
-
- if ((ret_stdout != 0 || ret_stderr != 0)); then
- ret=1
- fi
-
- rm -f "$actual_stdout_file" "$actual_stderr_file"
-
- if [ "$expected_to_fail" = "1" ]; then
- isnt $ret 0 "$test_name signed=$enum_signed with value=$value doesn't match as expected"
- else
- ok $ret "$test_name signed=$enum_signed with value=$value matches"
- fi
-
-}
-
-function test_normal_enum {
- test_name="Normal enum"
- enum_signed="$1"
- enum_values="single,1,1 single2,2,2 single3,4,4 range,4,8 range2,15,20"
-
- # Hit a single value
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "single" : container = 1 ) }
- END
- run_test "$test_name" 0 1 "$temp_stdout_expected_file"
-
- # Hit a single range
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "range" : container = 7 ) }
- END
- run_test "$test_name" 0 7 "$temp_stdout_expected_file"
-
- # Hit a range and a value
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( { "single3", "range" } : container = 4 ) }
- END
- run_test "$test_name" 0 4 "$temp_stdout_expected_file"
-
- # Hit a range and a value
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( { "NOT_A_LABEL", "DOESNT_EXIST" } : container = 4 ) }
- END
- run_test "$test_name" 1 4 "$temp_stdout_expected_file"
-
- # Unknown
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( <unknown> : container = 21 ) }
- END
- run_test "$test_name" 0 21 "$temp_stdout_expected_file"
-
- # Unknown but with bits with a value, but range larger than 1 element
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( <unknown> : container = 12 ) }
- END
- run_test "$test_name" 0 12 "$temp_stdout_expected_file"
-
- # Unknown value of 0
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( <unknown> : container = 0 ) }
- END
- run_test "$test_name" 0 0 "$temp_stdout_expected_file"
-}
-
-function test_normal_enum_negative {
- test_name="Normal enum with negative value"
- enum_signed="true"
- enum_values="zero,0,0 single,1,1 single2,2,2 single3,4,4 range,4,8 negative,-1,-1 rangeNegative,-6,-2"
-
- # Hit a single negative value
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "negative" : container = -1 ) }
- END
- run_test "$test_name" 0 -1 "$temp_stdout_expected_file"
-
- # Hit a single negative range
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "rangeNegative" : container = -6 ) }
- END
- run_test "$test_name" 0 -6 "$temp_stdout_expected_file"
-
- # Unknown
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( <unknown> : container = -7 ) }
- END
- run_test "$test_name" 0 -7 "$temp_stdout_expected_file"
-
- # value of 0
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "zero" : container = 0 ) }
- END
- run_test "$test_name" 0 0 "$temp_stdout_expected_file"
-}
-
-function test_bit_flag_enum {
- test_name="Bit flag enum"
- enum_signed="false"
- enum_values="bit0,1,1 bit0bis,1,1 bit1,2,2 bit3,4,4 bit4,8,8 bit5,16,16 bit5,32,32"
-
- # Single value hit
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "bit1" : container = 2 ) }
- END
- run_test "$test_name" 0 2 "$temp_stdout_expected_file"
-
- # Multiple flags set
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "bit3" | "bit4" : container = 12 ) }
- END
- run_test "$test_name" 0 12 "$temp_stdout_expected_file"
-
- # Some unknown bit
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( <unknown> : container = 68 ) }
- END
- run_test "$test_name" 0 68 "$temp_stdout_expected_file"
-
- # Multiple labels for bit 0
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( { "bit0", "bit0bis" } : container = 1 ) }
- END
- run_test "$test_name" 0 1 "$temp_stdout_expected_file"
-
- # Two labels for bit 0 and one label for bit 1
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( { "bit0", "bit0bis" } | "bit1" : container = 3 ) }
- END
- run_test "$test_name" 0 3 "$temp_stdout_expected_file"
-
- # Single label for bit 0
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "bit5" | "bit5" : container = 48 ) }
- END
- run_test "$test_name" 0 48 "$temp_stdout_expected_file"
-
- # negative value
- enum_signed="true"
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( <unknown> : container = -1 ) }
- END
- run_test "$test_name" 0 -1 "$temp_stdout_expected_file"
-}
-
-function test_mixed_enum {
- test_name="Mixed enum bits at beginning"
- enum_signed="false"
- enum_values="bit0,1,1 bit1,2,2 bit2,4,4 bit3,8,8 bit4,16,16 range,32,44 singleValue,45,45"
-
- # Value with bit fields
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "bit0" | "bit1" | "bit2" | "bit3" | "bit4" : container = 31 ) }
- END
- run_test "$test_name" 0 31 "$temp_stdout_expected_file"
-
- # A value with some bit flags set, but within another range
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "range" : container = 36 ) }
- END
- run_test "$test_name" 0 36 "$temp_stdout_expected_file"
-
- # A value with some bit flags set, but corresponding to another value
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "singleValue" : container = 45 ) }
- END
- run_test "$test_name" 0 45 "$temp_stdout_expected_file"
-
- # Value above the ranges
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( <unknown> : container = 46 ) }
- END
- run_test "$test_name" 0 46 "$temp_stdout_expected_file"
-
- # Since low values are often powers of 2, they may be considered bit flags too
- test_name="Mixed enum bits at end"
- enum_signed="false"
- enum_values="val1,1,1 val2,2,2 val3,3,3 val4,4,4 val5,5,5 bit3,8,8 bit4,16,16 bit5,32,32"
-
- # Value with bit fields
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "bit4" : container = 16 ) }
- END
- run_test "$test_name" 0 16 "$temp_stdout_expected_file"
-
- # Value with a bit field set both at beginning and end
- cat <<- 'END' > "$temp_stdout_expected_file"
- with_enum: { enum_field = ( "val1" | "bit4" : container = 17 ) }
- END
- run_test "$test_name" 0 17 "$temp_stdout_expected_file"
-}
-
-# Enumerations tests
-test_normal_enum "false"
-test_normal_enum "true"
-test_normal_enum_negative
-test_bit_flag_enum
-test_mixed_enum
-
-rm -f "$temp_stdout_expected_file"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-run_python_bt2_test "${BT_TESTS_SRCDIR}/plugins/sink.text.pretty" "test_*"
SUBDIRS = succeed
dist_check_SCRIPTS = \
- fail/test_fail \
- query/test_query_metadata_info \
- query/test_query_support_info \
+ fail/test-fail.sh \
+ query/test-query-metadata-info.sh \
+ query/test-query-support-info.sh \
query/test_query_support_info.py \
- query/test_query_trace_info \
+ query/test-query-trace-info.sh \
query/test_query_trace_info.py \
- test_deterministic_ordering
+ test-deterministic-ordering.sh
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 EfficiOS Inc.
+#
+
+# This test validates that a `src.ctf.fs` component handles gracefully invalid
+# CTF traces and produces the expected error message.
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
+fi
+
+# shellcheck source=../../../utils/utils.sh
+source "$UTILSSH"
+
+fail_trace_dir="$BT_CTF_TRACES_PATH/fail"
+
+stdout_file=$(mktemp -t test-ctf-fail-stdout.XXXXXX)
+stderr_file=$(mktemp -t test-ctf-fail-stderr.XXXXXX)
+data_dir="${BT_TESTS_SRCDIR}/data/plugins/src.ctf.fs/fail"
+
+test_fail() {
+ local name="$1"
+ local expected_stdout_file="$2"
+ local expected_error_msg="$3"
+
+ bt_cli "${stdout_file}" "${stderr_file}" \
+ -c sink.text.details -p "with-trace-name=no,with-stream-name=no" "${fail_trace_dir}/${name}"
+ isnt $? 0 "Trace ${name}: babeltrace exits with an error"
+
+ bt_diff "${expected_stdout_file}" "${stdout_file}"
+ ok $? "Trace ${name}: babeltrace produces the expected stdout"
+
+ # The expected error message will likely be found in the error stream
+ # even if Babeltrace aborts (e.g. hits an assert). Check that the
+ # Babeltrace CLI finishes gracefully by checking that the error stream
+ # contains an error stack printed by the CLI.
+ grep --silent "^CAUSED BY " "${stderr_file}"
+ ok $? "Trace ${name}: babeltrace produces an error stack"
+
+ grep --silent "${expected_error_msg}" "${stderr_file}"
+ ok $? "Trace ${name}: babeltrace produces the expected error message"
+}
+
+
+plan_tests 20
+
+test_fail \
+ "invalid-packet-size/trace" \
+ "/dev/null" \
+ "Failed to index CTF stream file '.*channel0_3'"
+
+test_fail \
+ "valid-events-then-invalid-events" \
+ "${data_dir}/valid-events-then-invalid-events.expect" \
+ "No event class with ID of event class ID to use in stream class: .*stream-class-id=0, event-class-id=255"
+
+test_fail \
+ "metadata-syntax-error" \
+ "/dev/null" \
+ "^ At line 3 in metadata stream: syntax error, unexpected CTF_RSBRAC: token=\"]\""
+
+test_fail \
+ "invalid-sequence-length-field-class" \
+ "/dev/null" \
+ "Sequence field class's length field class is not an unsigned integer field class: "
+
+test_fail \
+ "invalid-variant-selector-field-class" \
+ "/dev/null" \
+ "Variant field class's tag field class is not an enumeration field class: "
+
+rm -f "${stdout_file}" "${stderr_file}"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 EfficiOS Inc.
-#
-
-# This test validates that a `src.ctf.fs` component handles gracefully invalid
-# CTF traces and produces the expected error message.
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
-fi
-
-# shellcheck source=../../../utils/utils.sh
-source "$UTILSSH"
-
-fail_trace_dir="$BT_CTF_TRACES_PATH/fail"
-
-stdout_file=$(mktemp -t test_ctf_fail_stdout.XXXXXX)
-stderr_file=$(mktemp -t test_ctf_fail_stderr.XXXXXX)
-data_dir="${BT_TESTS_SRCDIR}/data/plugins/src.ctf.fs/fail"
-
-test_fail() {
- local name="$1"
- local expected_stdout_file="$2"
- local expected_error_msg="$3"
-
- bt_cli "${stdout_file}" "${stderr_file}" \
- -c sink.text.details -p "with-trace-name=no,with-stream-name=no" "${fail_trace_dir}/${name}"
- isnt $? 0 "Trace ${name}: babeltrace exits with an error"
-
- bt_diff "${expected_stdout_file}" "${stdout_file}"
- ok $? "Trace ${name}: babeltrace produces the expected stdout"
-
- # The expected error message will likely be found in the error stream
- # even if Babeltrace aborts (e.g. hits an assert). Check that the
- # Babeltrace CLI finishes gracefully by checking that the error stream
- # contains an error stack printed by the CLI.
- grep --silent "^CAUSED BY " "${stderr_file}"
- ok $? "Trace ${name}: babeltrace produces an error stack"
-
- grep --silent "${expected_error_msg}" "${stderr_file}"
- ok $? "Trace ${name}: babeltrace produces the expected error message"
-}
-
-
-plan_tests 20
-
-test_fail \
- "invalid-packet-size/trace" \
- "/dev/null" \
- "Failed to index CTF stream file '.*channel0_3'"
-
-test_fail \
- "valid-events-then-invalid-events" \
- "${data_dir}/valid-events-then-invalid-events.expect" \
- "No event class with ID of event class ID to use in stream class: .*stream-class-id=0, event-class-id=255"
-
-test_fail \
- "metadata-syntax-error" \
- "/dev/null" \
- "^ At line 3 in metadata stream: syntax error, unexpected CTF_RSBRAC: token=\"]\""
-
-test_fail \
- "invalid-sequence-length-field-class" \
- "/dev/null" \
- "Sequence field class's length field class is not an unsigned integer field class: "
-
-test_fail \
- "invalid-variant-selector-field-class" \
- "/dev/null" \
- "Variant field class's tag field class is not an enumeration field class: "
-
-rm -f "${stdout_file}" "${stderr_file}"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+# Copyright (C) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
+#
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
+fi
+
+# shellcheck source=../../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/src.ctf.fs/query"
+succeed_trace_dir="$BT_CTF_TRACES_PATH/succeed"
+expect_dir="$BT_TESTS_DATADIR/$this_dir_relative"
+
+test_query_metadata_info() {
+ local name="$1"
+ local ret=0
+ local trace_path="$succeed_trace_dir/$name"
+ local expected_stdout="$expect_dir/metadata-info-$name.expect"
+ local temp_stdout_output_file
+ local temp_stderr_output_file
+ local query=("query" "src.ctf.fs" "metadata-info" "--params" "path=\"$trace_path\"")
+
+ temp_stdout_output_file="$(mktemp -t actual-stdout.XXXXXX)"
+ temp_stderr_output_file="$(mktemp -t actual-stderr.XXXXXX)"
+
+ bt_cli "$temp_stdout_output_file" "$temp_stderr_output_file" \
+ "${query[@]}"
+
+ bt_diff "$expected_stdout" "$temp_stdout_output_file"
+ ret_stdout=$?
+
+ bt_diff /dev/null "$temp_stderr_output_file"
+ ret_stderr=$?
+
+ if ((ret_stdout != 0 || ret_stderr != 0)); then
+ ret=1
+ fi
+
+ ok $ret "Trace '$name' \`metadata-info\` query gives the expected output"
+ rm -f "$temp_stdout_output_file" "$temp_stderr_output_file"
+}
+
+test_non_existent_trace_dir() {
+ local empty_dir
+ local stdout_file
+ local stderr_file
+ local query
+
+ empty_dir=$(mktemp -d)
+ stdout_file="$(mktemp -t actual-stdout.XXXXXX)"
+ stderr_file="$(mktemp -t actual-stderr.XXXXXX)"
+ query=("query" "src.ctf.fs" "metadata-info" "--params" "path=\"$empty_dir\"")
+
+ bt_cli "$stdout_file" "$stderr_file" \
+ "${query[@]}"
+ isnt $? 0 "non existent trace dir: babeltrace exits with an error"
+
+ bt_diff "/dev/null" "${stdout_file}"
+ ok $? "non existent trace dir: babeltrace produces the expected stdout"
+
+ grep --silent "^CAUSED BY " "${stderr_file}"
+ ok $? "non existent trace dir: babeltrace produces an error stack"
+
+ grep --silent "Failed to open metadata file: No such file or directory: path=\".*metadata\"" \
+ "${stderr_file}"
+ ok $? "non existent trace dir: babeltrace produces the expected error message"
+
+ rm -f "${stdout_file}" "${stderr_file}"
+}
+
+plan_tests 7
+test_query_metadata_info succeed1
+test_non_existent_trace_dir
+test_query_metadata_info lf-metadata
+test_query_metadata_info crlf-metadata
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
+fi
+
+# shellcheck source=../../../utils/utils.sh
+source "$UTILSSH"
+
+run_python_bt2_test "${BT_TESTS_SRCDIR}/plugins/src.ctf.fs/query" test_query_support_info.py
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
+fi
+
+# shellcheck source=../../../utils/utils.sh
+source "$UTILSSH"
+
+run_python_bt2_test "${BT_TESTS_SRCDIR}/plugins/src.ctf.fs/query" test_query_trace_info.py
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-# Copyright (C) 2019 Francis Deslauriers <francis.deslauriers@efficios.com>
-#
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
-fi
-
-# shellcheck source=../../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/src.ctf.fs/query"
-succeed_trace_dir="$BT_CTF_TRACES_PATH/succeed"
-expect_dir="$BT_TESTS_DATADIR/$this_dir_relative"
-
-test_query_metadata_info() {
- local name="$1"
- local ret=0
- local trace_path="$succeed_trace_dir/$name"
- local expected_stdout="$expect_dir/metadata-info-$name.expect"
- local temp_stdout_output_file
- local temp_stderr_output_file
- local query=("query" "src.ctf.fs" "metadata-info" "--params" "path=\"$trace_path\"")
-
- temp_stdout_output_file="$(mktemp -t actual_stdout.XXXXXX)"
- temp_stderr_output_file="$(mktemp -t actual_stderr.XXXXXX)"
-
- bt_cli "$temp_stdout_output_file" "$temp_stderr_output_file" \
- "${query[@]}"
-
- bt_diff "$expected_stdout" "$temp_stdout_output_file"
- ret_stdout=$?
-
- bt_diff /dev/null "$temp_stderr_output_file"
- ret_stderr=$?
-
- if ((ret_stdout != 0 || ret_stderr != 0)); then
- ret=1
- fi
-
- ok $ret "Trace '$name' \`metadata-info\` query gives the expected output"
- rm -f "$temp_stdout_output_file" "$temp_stderr_output_file"
-}
-
-test_non_existent_trace_dir() {
- local empty_dir
- local stdout_file
- local stderr_file
- local query
-
- empty_dir=$(mktemp -d)
- stdout_file="$(mktemp -t actual_stdout.XXXXXX)"
- stderr_file="$(mktemp -t actual_stderr.XXXXXX)"
- query=("query" "src.ctf.fs" "metadata-info" "--params" "path=\"$empty_dir\"")
-
- bt_cli "$stdout_file" "$stderr_file" \
- "${query[@]}"
- isnt $? 0 "non existent trace dir: babeltrace exits with an error"
-
- bt_diff "/dev/null" "${stdout_file}"
- ok $? "non existent trace dir: babeltrace produces the expected stdout"
-
- grep --silent "^CAUSED BY " "${stderr_file}"
- ok $? "non existent trace dir: babeltrace produces an error stack"
-
- grep --silent "Failed to open metadata file: No such file or directory: path=\".*metadata\"" \
- "${stderr_file}"
- ok $? "non existent trace dir: babeltrace produces the expected error message"
-
- rm -f "${stdout_file}" "${stderr_file}"
-}
-
-plan_tests 7
-test_query_metadata_info succeed1
-test_non_existent_trace_dir
-test_query_metadata_info lf-metadata
-test_query_metadata_info crlf-metadata
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
-fi
-
-# shellcheck source=../../../utils/utils.sh
-source "$UTILSSH"
-
-run_python_bt2_test "${BT_TESTS_SRCDIR}/plugins/src.ctf.fs/query" test_query_support_info.py
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
-fi
-
-# shellcheck source=../../../utils/utils.sh
-source "$UTILSSH"
-
-run_python_bt2_test "${BT_TESTS_SRCDIR}/plugins/src.ctf.fs/query" test_query_trace_info.py
# SPDX-License-Identifier: MIT
-dist_check_SCRIPTS = test_succeed
+dist_check_SCRIPTS = test-succeed.sh
# CTF trace generators
GEN_TRACE_LDADD = \
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
+#
+
+# This test validates that a `src.ctf.fs` component successfully reads
+# specific CTF traces and creates the expected messages.
+#
+# Such CTF traces to open either exist (in `tests/ctf-traces/succeed`)
+# or are generated by this test using local trace generators.
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
+fi
+
+# shellcheck source=../../../utils/utils.sh
+source "$UTILSSH"
+
+this_dir_relative="plugins/src.ctf.fs/succeed"
+this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
+succeed_trace_dir="$BT_CTF_TRACES_PATH/succeed"
+expect_dir="$BT_TESTS_DATADIR/$this_dir_relative"
+
+test_ctf_common_details_args=("-p" "with-trace-name=no,with-stream-name=no")
+
+test_ctf_gen_single() {
+ name="$1"
+
+ diag "Generating trace '$name'"
+ bt_diff_details_ctf_gen_single "$this_dir_build/gen-trace-$name" \
+ "$expect_dir/trace-$name.expect" \
+ "${test_ctf_common_details_args[@]}" "-p" "with-uuid=no"
+ ok $? "Generated trace '$name' gives the expected output"
+}
+
+test_ctf_single() {
+ name="$1"
+
+ bt_diff_details_ctf_single "$expect_dir/trace-$name.expect" \
+ "$succeed_trace_dir/$name" "${test_ctf_common_details_args[@]}"
+ ok $? "Trace '$name' gives the expected output"
+}
+
+test_packet_end() {
+ local name="$1"
+ local expected_stdout="$expect_dir/trace-$name.expect"
+ local ret=0
+ local ret_stdout
+ local ret_stderr
+ local details_comp=("-c" "sink.text.details")
+ local details_args=("-p" "with-trace-name=no,with-stream-name=no,with-metadata=no,compact=yes")
+ local temp_stdout_output_file
+ local temp_greped_stdout_output_file
+ local temp_stderr_output_file
+
+ temp_stdout_output_file="$(mktemp -t actual-stdout.XXXXXX)"
+ temp_greped_stdout_output_file="$(mktemp -t greped-stdout.XXXXXX)"
+ temp_stderr_output_file="$(mktemp -t actual-stderr.XXXXXX)"
+
+ bt_cli "$temp_stdout_output_file" "$temp_stderr_output_file" \
+ "$succeed_trace_dir/$name" "${details_comp[@]}" \
+ "${details_args[@]}"
+
+ "$BT_TESTS_GREP_BIN" "Packet end" "$temp_stdout_output_file" > "$temp_greped_stdout_output_file"
+
+ bt_diff "$expected_stdout" "$temp_greped_stdout_output_file"
+ ret_stdout=$?
+
+ bt_diff /dev/null "$temp_stderr_output_file"
+ ret_stderr=$?
+
+ if ((ret_stdout != 0 || ret_stderr != 0)); then
+ ret=1
+ fi
+
+ ok $ret "Trace '$name' gives the expected output"
+ rm -f "$temp_stdout_output_file" "$temp_stderr_output_file" "$temp_greped_stdout_output_file"
+}
+
+test_force_origin_unix_epoch() {
+ local name1="$1"
+ local name2="$2"
+ local expected_stdout="$expect_dir/trace-$name1-$name2.expect"
+ local ret=0
+ local ret_stdout
+ local ret_stderr
+ local src_ctf_fs_args=("-p" "force-clock-class-origin-unix-epoch=true")
+ local details_comp=("-c" "sink.text.details")
+ local details_args=("-p" "with-trace-name=no,with-stream-name=no,with-metadata=yes,compact=yes")
+ local temp_stdout_output_file
+ local temp_stderr_output_file
+
+ temp_stdout_output_file="$(mktemp -t actual-stdout.XXXXXX)"
+ temp_stderr_output_file="$(mktemp -t actual-stderr.XXXXXX)"
+
+ bt_cli "$temp_stdout_output_file" "$temp_stderr_output_file" \
+ "$succeed_trace_dir/$name1" "${src_ctf_fs_args[@]}" \
+ "$succeed_trace_dir/$name2" "${src_ctf_fs_args[@]}" \
+ "${details_comp[@]}" "${details_args[@]}"
+
+ bt_diff "$expected_stdout" "$temp_stdout_output_file"
+ ret_stdout=$?
+
+ if ((ret_stdout != 0)); then
+ ret=1
+ fi
+
+ ok $ret "Trace '$name1' and '$name2' give the expected stdout"
+
+ bt_diff /dev/null "$temp_stderr_output_file"
+ ret_stderr=$?
+
+ if ((ret_stderr != 0)); then
+ ret=1
+ fi
+
+ ok $ret "Trace '$name1' and '$name2' give the expected stderr"
+
+ rm -f "$temp_stdout_output_file" "$temp_stderr_output_file"
+}
+
+plan_tests 13
+
+test_force_origin_unix_epoch 2packets barectf-event-before-packet
+test_ctf_gen_single simple
+test_ctf_single smalltrace
+test_ctf_single 2packets
+test_ctf_single barectf-event-before-packet
+test_ctf_single session-rotation
+test_ctf_single lttng-tracefile-rotation
+test_ctf_single array-align-elem
+test_ctf_single struct-array-align-elem
+test_ctf_single meta-ctx-sequence
+test_packet_end lttng-event-after-packet
+test_packet_end lttng-crash
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
-#
-
-# This test validates that a `src.ctf.fs` component successfully reads
-# specific CTF traces and creates the expected messages.
-#
-# Such CTF traces to open either exist (in `tests/ctf-traces/succeed`)
-# or are generated by this test using local trace generators.
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../../utils/utils.sh"
-fi
-
-# shellcheck source=../../../utils/utils.sh
-source "$UTILSSH"
-
-this_dir_relative="plugins/src.ctf.fs/succeed"
-this_dir_build="$BT_TESTS_BUILDDIR/$this_dir_relative"
-succeed_trace_dir="$BT_CTF_TRACES_PATH/succeed"
-expect_dir="$BT_TESTS_DATADIR/$this_dir_relative"
-
-test_ctf_common_details_args=("-p" "with-trace-name=no,with-stream-name=no")
-
-test_ctf_gen_single() {
- name="$1"
-
- diag "Generating trace '$name'"
- bt_diff_details_ctf_gen_single "$this_dir_build/gen-trace-$name" \
- "$expect_dir/trace-$name.expect" \
- "${test_ctf_common_details_args[@]}" "-p" "with-uuid=no"
- ok $? "Generated trace '$name' gives the expected output"
-}
-
-test_ctf_single() {
- name="$1"
-
- bt_diff_details_ctf_single "$expect_dir/trace-$name.expect" \
- "$succeed_trace_dir/$name" "${test_ctf_common_details_args[@]}"
- ok $? "Trace '$name' gives the expected output"
-}
-
-test_packet_end() {
- local name="$1"
- local expected_stdout="$expect_dir/trace-$name.expect"
- local ret=0
- local ret_stdout
- local ret_stderr
- local details_comp=("-c" "sink.text.details")
- local details_args=("-p" "with-trace-name=no,with-stream-name=no,with-metadata=no,compact=yes")
- local temp_stdout_output_file
- local temp_greped_stdout_output_file
- local temp_stderr_output_file
-
- temp_stdout_output_file="$(mktemp -t actual_stdout.XXXXXX)"
- temp_greped_stdout_output_file="$(mktemp -t greped_stdout.XXXXXX)"
- temp_stderr_output_file="$(mktemp -t actual_stderr.XXXXXX)"
-
- bt_cli "$temp_stdout_output_file" "$temp_stderr_output_file" \
- "$succeed_trace_dir/$name" "${details_comp[@]}" \
- "${details_args[@]}"
-
- "$BT_TESTS_GREP_BIN" "Packet end" "$temp_stdout_output_file" > "$temp_greped_stdout_output_file"
-
- bt_diff "$expected_stdout" "$temp_greped_stdout_output_file"
- ret_stdout=$?
-
- bt_diff /dev/null "$temp_stderr_output_file"
- ret_stderr=$?
-
- if ((ret_stdout != 0 || ret_stderr != 0)); then
- ret=1
- fi
-
- ok $ret "Trace '$name' gives the expected output"
- rm -f "$temp_stdout_output_file" "$temp_stderr_output_file" "$temp_greped_stdout_output_file"
-}
-
-test_force_origin_unix_epoch() {
- local name1="$1"
- local name2="$2"
- local expected_stdout="$expect_dir/trace-$name1-$name2.expect"
- local ret=0
- local ret_stdout
- local ret_stderr
- local src_ctf_fs_args=("-p" "force-clock-class-origin-unix-epoch=true")
- local details_comp=("-c" "sink.text.details")
- local details_args=("-p" "with-trace-name=no,with-stream-name=no,with-metadata=yes,compact=yes")
- local temp_stdout_output_file
- local temp_stderr_output_file
-
- temp_stdout_output_file="$(mktemp -t actual_stdout.XXXXXX)"
- temp_stderr_output_file="$(mktemp -t actual_stderr.XXXXXX)"
-
- bt_cli "$temp_stdout_output_file" "$temp_stderr_output_file" \
- "$succeed_trace_dir/$name1" "${src_ctf_fs_args[@]}" \
- "$succeed_trace_dir/$name2" "${src_ctf_fs_args[@]}" \
- "${details_comp[@]}" "${details_args[@]}"
-
- bt_diff "$expected_stdout" "$temp_stdout_output_file"
- ret_stdout=$?
-
- if ((ret_stdout != 0)); then
- ret=1
- fi
-
- ok $ret "Trace '$name1' and '$name2' give the expected stdout"
-
- bt_diff /dev/null "$temp_stderr_output_file"
- ret_stderr=$?
-
- if ((ret_stderr != 0)); then
- ret=1
- fi
-
- ok $ret "Trace '$name1' and '$name2' give the expected stderr"
-
- rm -f "$temp_stdout_output_file" "$temp_stderr_output_file"
-}
-
-plan_tests 13
-
-test_force_origin_unix_epoch 2packets barectf-event-before-packet
-test_ctf_gen_single simple
-test_ctf_single smalltrace
-test_ctf_single 2packets
-test_ctf_single barectf-event-before-packet
-test_ctf_single session-rotation
-test_ctf_single lttng-tracefile-rotation
-test_ctf_single array-align-elem
-test_ctf_single struct-array-align-elem
-test_ctf_single meta-ctx-sequence
-test_packet_end lttng-event-after-packet
-test_packet_end lttng-crash
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Efficios, Inc.
+#
+
+# Test the deterministic behavior of the src.ctf.fs component versus the
+# ordering of the given input paths.
+#
+# In presence of multiple copies of the same packet, we want it to pick the
+# copy of the packet to read in a deterministic fashion.
+#
+# This test is written assuming the specific implementation of the src.ctf.fs
+# component class, which sorts its input paths lexicographically.
+#
+# There are three traces (a-corrupted, b-not-corrupted and c-corrupted) with the
+# same UUID and the same packet, except that this packet is corrupted in
+# a-corrupted and c-corrupted. In these cases, there is an event with an
+# invalid id. When reading these corrupted packets, we expect babeltrace to
+# emit an error.
+#
+# When reading a-corrupted and b-not-corrupted together, the copy of the packet
+# from a-corrupted is read, and babeltrace exits with an error.
+#
+# When reading b-not-corrupted and c-corrupted together, the copy of the packet
+# from b-not-corrupted is read, and babeltrace executes successfully.
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+traces_dir="${BT_CTF_TRACES_PATH}/deterministic-ordering"
+trace_a_corrupted="${traces_dir}/a-corrupted"
+trace_b_not_corrupted="${traces_dir}/b-not-corrupted"
+trace_c_corrupted="${traces_dir}/c-corrupted"
+
+if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
+ # The MSYS2 shell makes a mess trying to convert the Unix-like paths
+ # to Windows-like paths, so just disable the automatic conversion and
+ # do it by hand.
+ export MSYS2_ARG_CONV_EXCL="*"
+ trace_a_corrupted=$(cygpath -m "${trace_a_corrupted}")
+ trace_b_not_corrupted=$(cygpath -m "${trace_b_not_corrupted}")
+ trace_c_corrupted=$(cygpath -m "${trace_c_corrupted}")
+fi
+
+stdout_file=$(mktemp -t test-deterministic-ordering-stdout.XXXXXX)
+stderr_file=$(mktemp -t test-deterministic-ordering-stderr.XXXXXX)
+
+expect_failure() {
+ local test_name
+ local inputs
+
+ test_name="$1"
+ inputs="$2"
+
+ bt_cli "${stdout_file}" "${stderr_file}" \
+ -c src.ctf.fs -p "inputs=[${inputs}]"
+ isnt 0 "$?" "${test_name}: exit status is not 0"
+
+ grep --silent "^ERROR: " "${stderr_file}"
+ ok "$?" "${test_name}: error stack is produced"
+
+ grep --silent "No event class with ID of event class ID to use in stream class" "${stderr_file}"
+ ok "$?" "${test_name}: expected error message is present"
+}
+
+expect_success() {
+ local test_name
+ local inputs
+
+ test_name="$1"
+ inputs="$2"
+
+ bt_cli "${stdout_file}" "${stderr_file}" \
+ -c src.ctf.fs -p "inputs=[${inputs}]" \
+ -c sink.text.details -p 'with-trace-name=no,with-stream-name=no,with-metadata=no,compact=yes'
+ ok "$?" "${test_name}: exit status is 0"
+
+ bt_diff "${traces_dir}/b-c.expect" "${stdout_file}"
+ ok "$?" "${test_name}: expected output is produced"
+}
+
+plan_tests 10
+
+# Trace with corrupted packet comes first lexicographically, expect a failure.
+
+expect_failure "ab" "\"${trace_a_corrupted}\",\"${trace_b_not_corrupted}\""
+expect_failure "ba" "\"${trace_b_not_corrupted}\",\"${trace_a_corrupted}\""
+
+# Trace with non-corrupted packet comes first lexicographically, expect a success.
+
+expect_success "bc" "\"${trace_b_not_corrupted}\",\"${trace_c_corrupted}\""
+expect_success "cb" "\"${trace_c_corrupted}\",\"${trace_b_not_corrupted}\""
+
+rm -f "${stdout_file}" "${stderr_file}"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Efficios, Inc.
-#
-
-# Test the deterministic behavior of the src.ctf.fs component versus the
-# ordering of the given input paths.
-#
-# In presence of multiple copies of the same packet, we want it to pick the
-# copy of the packet to read in a deterministic fashion.
-#
-# This test is written assuming the specific implementation of the src.ctf.fs
-# component class, which sorts its input paths lexicographically.
-#
-# There are three traces (a-corrupted, b-not-corrupted and c-corrupted) with the
-# same UUID and the same packet, except that this packet is corrupted in
-# a-corrupted and c-corrupted. In these cases, there is an event with an
-# invalid id. When reading these corrupted packets, we expect babeltrace to
-# emit an error.
-#
-# When reading a-corrupted and b-not-corrupted together, the copy of the packet
-# from a-corrupted is read, and babeltrace exits with an error.
-#
-# When reading b-not-corrupted and c-corrupted together, the copy of the packet
-# from b-not-corrupted is read, and babeltrace executes successfully.
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-traces_dir="${BT_CTF_TRACES_PATH}/deterministic-ordering"
-trace_a_corrupted="${traces_dir}/a-corrupted"
-trace_b_not_corrupted="${traces_dir}/b-not-corrupted"
-trace_c_corrupted="${traces_dir}/c-corrupted"
-
-if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
- # The MSYS2 shell makes a mess trying to convert the Unix-like paths
- # to Windows-like paths, so just disable the automatic conversion and
- # do it by hand.
- export MSYS2_ARG_CONV_EXCL="*"
- trace_a_corrupted=$(cygpath -m "${trace_a_corrupted}")
- trace_b_not_corrupted=$(cygpath -m "${trace_b_not_corrupted}")
- trace_c_corrupted=$(cygpath -m "${trace_c_corrupted}")
-fi
-
-stdout_file=$(mktemp -t test_deterministic_ordering_stdout.XXXXXX)
-stderr_file=$(mktemp -t test_deterministic_ordering_stderr.XXXXXX)
-
-expect_failure() {
- local test_name
- local inputs
-
- test_name="$1"
- inputs="$2"
-
- bt_cli "${stdout_file}" "${stderr_file}" \
- -c src.ctf.fs -p "inputs=[${inputs}]"
- isnt 0 "$?" "${test_name}: exit status is not 0"
-
- grep --silent "^ERROR: " "${stderr_file}"
- ok "$?" "${test_name}: error stack is produced"
-
- grep --silent "No event class with ID of event class ID to use in stream class" "${stderr_file}"
- ok "$?" "${test_name}: expected error message is present"
-}
-
-expect_success() {
- local test_name
- local inputs
-
- test_name="$1"
- inputs="$2"
-
- bt_cli "${stdout_file}" "${stderr_file}" \
- -c src.ctf.fs -p "inputs=[${inputs}]" \
- -c sink.text.details -p 'with-trace-name=no,with-stream-name=no,with-metadata=no,compact=yes'
- ok "$?" "${test_name}: exit status is 0"
-
- bt_diff "${traces_dir}/b-c.expect" "${stdout_file}"
- ok "$?" "${test_name}: expected output is produced"
-}
-
-plan_tests 10
-
-# Trace with corrupted packet comes first lexicographically, expect a failure.
-
-expect_failure "ab" "\"${trace_a_corrupted}\",\"${trace_b_not_corrupted}\""
-expect_failure "ba" "\"${trace_b_not_corrupted}\",\"${trace_a_corrupted}\""
-
-# Trace with non-corrupted packet comes first lexicographically, expect a success.
-
-expect_success "bc" "\"${trace_b_not_corrupted}\",\"${trace_c_corrupted}\""
-expect_success "cb" "\"${trace_c_corrupted}\",\"${trace_b_not_corrupted}\""
-
-rm -f "${stdout_file}" "${stderr_file}"
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
+#
+
+# This test validates that a `src.ctf.lttng-live` component successfully does
+# various tasks that a `src.ctf.lttng-live` component is expected to do, like
+# listing tracing sessions and receiving live traces / producing the expected
+# messages out of it.
+#
+# A mock LTTng live server is used to feed data to the component.
+
+SH_TAP=1
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../../utils/utils.sh"
+fi
+
+# shellcheck source=../../utils/utils.sh
+source "$UTILSSH"
+
+function cleanup ()
+{
+ # Disable trap for SIGTERM since the following kill to the
+ # pidgroup will be SIGTERM. Otherwise it loops.
+ # The '-' before the pid number ($$) indicates 'kill' to signal the
+ # whole process group.
+ trap - SIGTERM && kill -- -$$
+}
+
+# Ensure that background child jobs are killed on SIGINT/SIGTERM
+trap cleanup SIGINT SIGTERM
+
+this_dir_relative="plugins/src.ctf.lttng-live"
+test_data_dir="$BT_TESTS_DATADIR/$this_dir_relative"
+trace_dir="$BT_CTF_TRACES_PATH"
+
+if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
+ # Same as the above, but in Windows form (C:\foo\bar) instead of Unix form
+ # (/c/foo/bar).
+ trace_dir_native=$(cygpath -w "${trace_dir}")
+else
+ trace_dir_native="${trace_dir}"
+fi
+
+lttng_live_server() {
+ local pid_file="$1"
+ local retcode_file="$2"
+ shift 2
+ local server_args=("$@")
+
+ local server_script="$test_data_dir/lttng_live_server.py"
+
+ # start server
+ diag "$BT_TESTS_PYTHON_BIN $server_script ${server_args[*]}"
+ run_python "$BT_TESTS_PYTHON_BIN" "$server_script" "${server_args[@]}" 1>&2 &
+
+ # write PID to file
+ echo $! > "$pid_file"
+
+ # wait for server to exit
+ wait
+
+ # write return code to file
+ echo $? > "$retcode_file"
+}
+
+kill_lttng_live_server() {
+ local pid_file="$1"
+
+ if [ ! -s "$pid_file" ]; then
+ return
+ fi
+
+ kill -9 "$(cat "$pid_file")"
+}
+
+get_cli_output_with_lttng_live_server() {
+ local cli_args_template="$1"
+ local cli_stdout_file="$2"
+ local cli_stderr_file="$3"
+ local port_file="$4"
+ local trace_path_prefix="$5"
+ shift 5
+ local server_args=("$@")
+
+ local i
+ local ret
+ local port
+ local cli_args
+ local server_pid_file
+ local server_retcode_file
+
+ server_args+=(--port-file "$port_file" --trace-path-prefix "$trace_path_prefix")
+ server_pid_file="$(mktemp -t test-live-server-pid.XXXXXX)"
+ server_retcode_file="$(mktemp -t test-live-server-ret.XXXXX)"
+
+ diag "Starting LTTng live server mockup"
+
+ # This starts the server, which eventually writes its listening
+ # port number to the `$port_file` file. The lttng_live_server()
+ # function itself writes the server's PID to the
+ # `$server_pid_file` file. When the server exits,
+ # lttng_live_server() writes its return code to the
+ # `$server_retcode_file` file.
+ lttng_live_server "$server_pid_file" "$server_retcode_file" "${server_args[@]}" &
+
+ # Get port number
+ i=0
+ while [ ! -s "$port_file" ]; do
+ sleep .1
+
+ # Timeout of 30 seconds
+ if [ "$i" -eq "300" ]; then
+ # too long, kill it
+ kill_lttng_live_server "$server_pid_file"
+ wait
+ rm -f "$server_pid_file"
+ rm -f "$server_retcode_file"
+ return 1
+ fi
+
+ i=$((i + 1))
+ done
+
+ port=$(<"$port_file")
+
+ diag "LTTng live port is $port"
+
+ cli_args=${cli_args_template//@PORT@/$port}
+
+ # Split argument string by spaces into an array.
+ IFS=' ' read -ra cli_args <<< "$cli_args"
+
+ if ! bt_cli "$cli_stdout_file" "$cli_stderr_file" "${cli_args[@]}"; then
+ # CLI failed: cancel everything else
+ kill_lttng_live_server "$server_pid_file"
+ wait
+ rm -f "$server_pid_file"
+ rm -f "$server_retcode_file"
+ return 1
+ fi
+
+ # get server's return code
+ i=0
+ while [ ! -s "$server_retcode_file" ]; do
+ sleep .1
+
+ # Timeout of 30 seconds
+ if [ "$i" -eq "300" ]; then
+ # too long, kill it
+ kill_lttng_live_server "$server_pid_file"
+ wait
+ rm -f "$server_pid_file"
+ rm -f "$server_retcode_file"
+ return 1
+ fi
+
+ i=$((i + 1))
+ done
+
+ wait
+
+ ret=$(<"$server_retcode_file")
+
+ rm -f "$server_pid_file"
+ rm -f "$server_retcode_file"
+ return "$ret"
+}
+
+run_test() {
+ local test_text="$1"
+ local cli_args_template="$2"
+ local expected_stdout="$3"
+ local expected_stderr="$4"
+ local trace_path_prefix="$5"
+ shift 5
+ local server_args=("$@")
+
+ local cli_stderr
+ local cli_stdout
+ local port_file
+ local port
+
+ cli_stderr="$(mktemp -t test-live-stderr.XXXXXX)"
+ cli_stdout="$(mktemp -t test-live-stdout.XXXXXX)"
+ port_file="$(mktemp -t test-live-server-port.XXXXXX)"
+
+ get_cli_output_with_lttng_live_server "$cli_args_template" "$cli_stdout" \
+ "$cli_stderr" "$port_file" "$trace_path_prefix" "${server_args[@]}"
+ port=$(<"$port_file")
+
+ bt_diff "$expected_stdout" "$cli_stdout"
+ ok $? "$test_text - stdout"
+ bt_diff "$expected_stderr" "$cli_stderr"
+ ok $? "$test_text - stderr"
+
+ rm -f "$cli_stderr"
+ rm -f "$cli_stdout"
+ rm -f "$port_file"
+}
+
+test_list_sessions() {
+ # Test the basic listing of sessions.
+ # Ensure that a multi-domain trace is seen as a single session.
+ # run_test() is not used here because the port is needed to craft the
+ # expected output.
+
+ local port
+ local port_file
+ local tmp_stdout_expected
+ local template_expected
+
+ local test_text="CLI prints the expected session list"
+ local cli_args_template="-i lttng-live net://localhost:@PORT@"
+ local server_args=("$test_data_dir/list-sessions.json")
+
+ template_expected=$(<"$test_data_dir/cli-list-sessions.expect")
+ cli_stderr="$(mktemp -t test-live-list-sessions-stderr.XXXXXX)"
+ cli_stdout="$(mktemp -t test-live-list-sessions-stdout.XXXXXX)"
+ port_file="$(mktemp -t test-live-list-sessions-server-port.XXXXXX)"
+ tmp_stdout_expected="$(mktemp -t test-live-list-sessions-stdout-expected.XXXXXX)"
+
+ get_cli_output_with_lttng_live_server "$cli_args_template" "$cli_stdout" \
+ "$cli_stderr" "$port_file" "$trace_dir_native" "${server_args[@]}"
+ port=$(<"$port_file")
+
+ # Craft the expected output. This is necessary since the port number
+ # (random) of a "relayd" is present in the output.
+ template_expected=${template_expected//@PORT@/$port}
+
+ echo "$template_expected" > "$tmp_stdout_expected"
+
+ bt_diff "$tmp_stdout_expected" "$cli_stdout"
+ ok $? "$test_text - stdout"
+ bt_diff "/dev/null" "$cli_stderr"
+ ok $? "$test_text - stderr"
+
+ rm -f "$cli_stderr"
+ rm -f "$cli_stdout"
+ rm -f "$port_file"
+ rm -f "$tmp_stdout_expected"
+}
+
+test_base() {
+ # Attach and consume data from a multi packets ust session with no
+ # discarded events.
+ local test_text="CLI attach and fetch from single-domains session - no discarded events"
+ local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/trace-with-index -c sink.text.details"
+ local server_args=("$test_data_dir/base.json")
+ local expected_stdout="${test_data_dir}/cli-base.expect"
+ local expected_stderr="/dev/null"
+
+ run_test "$test_text" "$cli_args_template" "$expected_stdout" \
+ "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
+}
+
+test_multi_domains() {
+ # Attach and consume data from a multi-domains session with discarded
+ # events.
+ local test_text="CLI attach and fetch from multi-domains session - discarded events"
+ local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/multi-domains -c sink.text.details"
+ local server_args=("${test_data_dir}/multi-domains.json")
+ local expected_stdout="$test_data_dir/cli-multi-domains.expect"
+ local expected_stderr="/dev/null"
+
+ run_test "$test_text" "$cli_args_template" "$expected_stdout" \
+ "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
+}
+
+test_rate_limited() {
+ # Attach and consume data from a multi packets ust session with no
+ # discarded events. Enforce a server side limit on the stream data
+ # requests size. Ensure that babeltrace respect the returned size and that
+ # many requests per packet works as expected.
+ # The packet size of the test trace is 4k. Limit requests to 1k.
+ local test_text="CLI many requests per packet"
+ local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/trace-with-index -c sink.text.details"
+ local server_args=(--max-query-data-response-size 1024 "$test_data_dir/rate-limited.json")
+ local expected_stdout="${test_data_dir}/cli-base.expect"
+ local expected_stderr="/dev/null"
+
+ run_test "$test_text" "$cli_args_template" "$expected_stdout" \
+ "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
+}
+
+test_compare_to_ctf_fs() {
+ # Compare the details text sink or ctf.fs and ctf.lttng-live to ensure
+ # that the trace is parsed the same way.
+ # Do the same with the session swapped on the relayd side. This validate
+ # that ordering is consistent between live and ctf fs.
+ local test_text="CLI src.ctf.fs vs src.ctf.lttng-live"
+ local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/multi-domains -c sink.text.details --params with-trace-name=false,with-stream-name=false"
+ local server_args=("$test_data_dir/multi-domains.json")
+ local server_args_inverse=("$test_data_dir/multi-domains-inverse.json")
+ local expected_stdout
+ local expected_stderr
+
+ expected_stdout="$(mktemp -t test-live-compare-stdout-expected.XXXXXX)"
+ expected_stderr="$(mktemp -t test-live-compare-stderr-expected.XXXXXX)"
+
+ bt_cli "$expected_stdout" "$expected_stderr" "${trace_dir}/succeed/multi-domains" -c sink.text.details --params "with-trace-name=false,with-stream-name=false"
+ bt_remove_cr "${expected_stdout}"
+ bt_remove_cr "${expected_stderr}"
+ run_test "$test_text" "$cli_args_template" "$expected_stdout" \
+ "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
+ diag "Inverse session order from lttng-relayd"
+ run_test "$test_text" "$cli_args_template" "$expected_stdout" \
+ "$expected_stderr" "$trace_dir_native" "${server_args_inverse[@]}"
+
+ rm -f "$expected_stdout"
+ rm -f "$expected_stderr"
+}
+
+test_inactivity_discarded_packet() {
+ # Attach and consume data from a multi-packet trace with discarded
+ # packets and emit an inactivity beacon during the discarded packets
+ # period.
+ #
+ # | pkt seq:0 |<-------discarded packets------>| pkt seq:8 |
+ # 0 20 121 140
+ #
+ # This test was introduced to cover the following bug:
+ #
+ # When reading this type of trace locally, the CTF source is expected
+ # to introduce a "Discarded packets" message between packets 0 and 8.
+ # The timestamps of this message are [pkt0.end_ts, pkt8.begin_ts].
+ #
+ # In the context of a live source, the tracer could report an inactivity
+ # period during the interval of the "Discarded packets" message.
+ # Those messages eventually translate into a
+ # "Iterator inactivity" message with a timestamp set at the end of the
+ # inactivity period.
+ #
+ # If the tracer reports an inactivity period that ends at a point
+ # between pkt0 and pkt7 (resulting in an "Iterator inactivity" message),
+ # the live source could send a "Discarded packets" message that starts
+ # before the preceding "Iterator inactivity" message. This would break
+ # the monotonicity constraint of the graph.
+ local test_text="CLI attach and fetch from single-domains session - inactivity discarded packet"
+ local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/7-lost-between-2-with-index -c sink.text.details"
+ local server_args=("$test_data_dir/inactivity-discarded-packet.json")
+ local expected_stdout="$test_data_dir/inactivity-discarded-packet.expect"
+ local expected_stderr="/dev/null"
+
+ run_test "$test_text" "$cli_args_template" "$expected_stdout" \
+ "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
+}
+
+test_split_metadata() {
+ # Consume a metadata stream sent in two parts. This testcase tests the
+ # behaviour of Babeltrace when the tracing session was cleared (lttng
+ # clear) but the metadata is not yet available to the relay. In such
+ # cases, when asked for metadata, the relay will return the
+ # `LTTNG_VIEWER_METADATA_OK` status and a data length of 0. The viewer
+ # need to consider such case as a request to retry fetching metadata.
+ #
+ # This testcase emulates such behaviour by adding empty metadata
+ # packets.
+
+ local test_text="CLI attach and fetch from single-domain session - Receive metadata in two sections separated by a empty section"
+ local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/split-metadata -c sink.text.details"
+ local server_args=("$test_data_dir/split-metadata.json")
+ local expected_stdout="${test_data_dir}/split-metadata.expect"
+ local expected_stderr="/dev/null"
+
+ run_test "$test_text" "$cli_args_template" "$expected_stdout" \
+ "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
+}
+
+test_stored_values() {
+ # Split metadata, where the new metadata requires additional stored
+ # value slots in CTF message iterators.
+ local test_text="split metadata requiring additionnal stored values"
+ local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/stored-values -c sink.text.details"
+ local server_args=("$test_data_dir/stored-values.json")
+ local expected_stdout="${test_data_dir}/stored-values.expect"
+ local expected_stderr="/dev/null"
+ local tmp_dir
+
+ tmp_dir=$(mktemp -d -t 'test-stored-value.XXXXXXX')
+
+ # Generate test trace.
+ gen_mctf_trace "${trace_dir}/live/stored-values.mctf" "$tmp_dir/stored-values"
+
+ run_test "$test_text" "$cli_args_template" "$expected_stdout" \
+ "$expected_stderr" "$tmp_dir" "${server_args[@]}"
+
+ rm -rf "$tmp_dir"
+}
+
+plan_tests 18
+
+test_list_sessions
+test_base
+test_multi_domains
+test_rate_limited
+test_compare_to_ctf_fs
+test_inactivity_discarded_packet
+test_split_metadata
+test_stored_values
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2019 Philippe Proulx <pproulx@efficios.com>
-#
-
-# This test validates that a `src.ctf.lttng-live` component successfully does
-# various tasks that a `src.ctf.lttng-live` component is expected to do, like
-# listing tracing sessions and receiving live traces / producing the expected
-# messages out of it.
-#
-# A mock LTTng live server is used to feed data to the component.
-
-SH_TAP=1
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../../utils/utils.sh"
-fi
-
-# shellcheck source=../../utils/utils.sh
-source "$UTILSSH"
-
-function cleanup ()
-{
- # Disable trap for SIGTERM since the following kill to the
- # pidgroup will be SIGTERM. Otherwise it loops.
- # The '-' before the pid number ($$) indicates 'kill' to signal the
- # whole process group.
- trap - SIGTERM && kill -- -$$
-}
-
-# Ensure that background child jobs are killed on SIGINT/SIGTERM
-trap cleanup SIGINT SIGTERM
-
-this_dir_relative="plugins/src.ctf.lttng-live"
-test_data_dir="$BT_TESTS_DATADIR/$this_dir_relative"
-trace_dir="$BT_CTF_TRACES_PATH"
-
-if [ "$BT_TESTS_OS_TYPE" = "mingw" ]; then
- # Same as the above, but in Windows form (C:\foo\bar) instead of Unix form
- # (/c/foo/bar).
- trace_dir_native=$(cygpath -w "${trace_dir}")
-else
- trace_dir_native="${trace_dir}"
-fi
-
-lttng_live_server() {
- local pid_file="$1"
- local retcode_file="$2"
- shift 2
- local server_args=("$@")
-
- local server_script="$test_data_dir/lttng_live_server.py"
-
- # start server
- diag "$BT_TESTS_PYTHON_BIN $server_script ${server_args[*]}"
- run_python "$BT_TESTS_PYTHON_BIN" "$server_script" "${server_args[@]}" 1>&2 &
-
- # write PID to file
- echo $! > "$pid_file"
-
- # wait for server to exit
- wait
-
- # write return code to file
- echo $? > "$retcode_file"
-}
-
-kill_lttng_live_server() {
- local pid_file="$1"
-
- if [ ! -s "$pid_file" ]; then
- return
- fi
-
- kill -9 "$(cat "$pid_file")"
-}
-
-get_cli_output_with_lttng_live_server() {
- local cli_args_template="$1"
- local cli_stdout_file="$2"
- local cli_stderr_file="$3"
- local port_file="$4"
- local trace_path_prefix="$5"
- shift 5
- local server_args=("$@")
-
- local i
- local ret
- local port
- local cli_args
- local server_pid_file
- local server_retcode_file
-
- server_args+=(--port-file "$port_file" --trace-path-prefix "$trace_path_prefix")
- server_pid_file="$(mktemp -t test_live_server_pid.XXXXXX)"
- server_retcode_file="$(mktemp -t test_live_server_ret.XXXXX)"
-
- diag "Starting LTTng live server mockup"
-
- # This starts the server, which eventually writes its listening
- # port number to the `$port_file` file. The lttng_live_server()
- # function itself writes the server's PID to the
- # `$server_pid_file` file. When the server exits,
- # lttng_live_server() writes its return code to the
- # `$server_retcode_file` file.
- lttng_live_server "$server_pid_file" "$server_retcode_file" "${server_args[@]}" &
-
- # Get port number
- i=0
- while [ ! -s "$port_file" ]; do
- sleep .1
-
- # Timeout of 30 seconds
- if [ "$i" -eq "300" ]; then
- # too long, kill it
- kill_lttng_live_server "$server_pid_file"
- wait
- rm -f "$server_pid_file"
- rm -f "$server_retcode_file"
- return 1
- fi
-
- i=$((i + 1))
- done
-
- port=$(<"$port_file")
-
- diag "LTTng live port is $port"
-
- cli_args=${cli_args_template//@PORT@/$port}
-
- # Split argument string by spaces into an array.
- IFS=' ' read -ra cli_args <<< "$cli_args"
-
- if ! bt_cli "$cli_stdout_file" "$cli_stderr_file" "${cli_args[@]}"; then
- # CLI failed: cancel everything else
- kill_lttng_live_server "$server_pid_file"
- wait
- rm -f "$server_pid_file"
- rm -f "$server_retcode_file"
- return 1
- fi
-
- # get server's return code
- i=0
- while [ ! -s "$server_retcode_file" ]; do
- sleep .1
-
- # Timeout of 30 seconds
- if [ "$i" -eq "300" ]; then
- # too long, kill it
- kill_lttng_live_server "$server_pid_file"
- wait
- rm -f "$server_pid_file"
- rm -f "$server_retcode_file"
- return 1
- fi
-
- i=$((i + 1))
- done
-
- wait
-
- ret=$(<"$server_retcode_file")
-
- rm -f "$server_pid_file"
- rm -f "$server_retcode_file"
- return "$ret"
-}
-
-run_test() {
- local test_text="$1"
- local cli_args_template="$2"
- local expected_stdout="$3"
- local expected_stderr="$4"
- local trace_path_prefix="$5"
- shift 5
- local server_args=("$@")
-
- local cli_stderr
- local cli_stdout
- local port_file
- local port
-
- cli_stderr="$(mktemp -t test_live_stderr.XXXXXX)"
- cli_stdout="$(mktemp -t test_live_stdout.XXXXXX)"
- port_file="$(mktemp -t test_live_server_port.XXXXXX)"
-
- get_cli_output_with_lttng_live_server "$cli_args_template" "$cli_stdout" \
- "$cli_stderr" "$port_file" "$trace_path_prefix" "${server_args[@]}"
- port=$(<"$port_file")
-
- bt_diff "$expected_stdout" "$cli_stdout"
- ok $? "$test_text - stdout"
- bt_diff "$expected_stderr" "$cli_stderr"
- ok $? "$test_text - stderr"
-
- rm -f "$cli_stderr"
- rm -f "$cli_stdout"
- rm -f "$port_file"
-}
-
-test_list_sessions() {
- # Test the basic listing of sessions.
- # Ensure that a multi-domain trace is seen as a single session.
- # run_test() is not used here because the port is needed to craft the
- # expected output.
-
- local port
- local port_file
- local tmp_stdout_expected
- local template_expected
-
- local test_text="CLI prints the expected session list"
- local cli_args_template="-i lttng-live net://localhost:@PORT@"
- local server_args=("$test_data_dir/list_sessions.json")
-
- template_expected=$(<"$test_data_dir/cli-list-sessions.expect")
- cli_stderr="$(mktemp -t test_live_list_sessions_stderr.XXXXXX)"
- cli_stdout="$(mktemp -t test_live_list_sessions_stdout.XXXXXX)"
- port_file="$(mktemp -t test_live_list_sessions_server_port.XXXXXX)"
- tmp_stdout_expected="$(mktemp -t test_live_list_sessions_stdout_expected.XXXXXX)"
-
- get_cli_output_with_lttng_live_server "$cli_args_template" "$cli_stdout" \
- "$cli_stderr" "$port_file" "$trace_dir_native" "${server_args[@]}"
- port=$(<"$port_file")
-
- # Craft the expected output. This is necessary since the port number
- # (random) of a "relayd" is present in the output.
- template_expected=${template_expected//@PORT@/$port}
-
- echo "$template_expected" > "$tmp_stdout_expected"
-
- bt_diff "$tmp_stdout_expected" "$cli_stdout"
- ok $? "$test_text - stdout"
- bt_diff "/dev/null" "$cli_stderr"
- ok $? "$test_text - stderr"
-
- rm -f "$cli_stderr"
- rm -f "$cli_stdout"
- rm -f "$port_file"
- rm -f "$tmp_stdout_expected"
-}
-
-test_base() {
- # Attach and consume data from a multi packets ust session with no
- # discarded events.
- local test_text="CLI attach and fetch from single-domains session - no discarded events"
- local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/trace-with-index -c sink.text.details"
- local server_args=("$test_data_dir/base.json")
- local expected_stdout="${test_data_dir}/cli-base.expect"
- local expected_stderr="/dev/null"
-
- run_test "$test_text" "$cli_args_template" "$expected_stdout" \
- "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
-}
-
-test_multi_domains() {
- # Attach and consume data from a multi-domains session with discarded
- # events.
- local test_text="CLI attach and fetch from multi-domains session - discarded events"
- local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/multi-domains -c sink.text.details"
- local server_args=("${test_data_dir}/multi_domains.json")
- local expected_stdout="$test_data_dir/cli-multi-domains.expect"
- local expected_stderr="/dev/null"
-
- run_test "$test_text" "$cli_args_template" "$expected_stdout" \
- "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
-}
-
-test_rate_limited() {
- # Attach and consume data from a multi packets ust session with no
- # discarded events. Enforce a server side limit on the stream data
- # requests size. Ensure that babeltrace respect the returned size and that
- # many requests per packet works as expected.
- # The packet size of the test trace is 4k. Limit requests to 1k.
- local test_text="CLI many requests per packet"
- local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/trace-with-index -c sink.text.details"
- local server_args=(--max-query-data-response-size 1024 "$test_data_dir/rate_limited.json")
- local expected_stdout="${test_data_dir}/cli-base.expect"
- local expected_stderr="/dev/null"
-
- run_test "$test_text" "$cli_args_template" "$expected_stdout" \
- "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
-}
-
-test_compare_to_ctf_fs() {
- # Compare the details text sink or ctf.fs and ctf.lttng-live to ensure
- # that the trace is parsed the same way.
- # Do the same with the session swapped on the relayd side. This validate
- # that ordering is consistent between live and ctf fs.
- local test_text="CLI src.ctf.fs vs src.ctf.lttng-live"
- local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/multi-domains -c sink.text.details --params with-trace-name=false,with-stream-name=false"
- local server_args=("$test_data_dir/multi_domains.json")
- local server_args_inverse=("$test_data_dir/multi_domains_inverse.json")
- local expected_stdout
- local expected_stderr
-
- expected_stdout="$(mktemp -t test_live_compare_stdout_expected.XXXXXX)"
- expected_stderr="$(mktemp -t test_live_compare_stderr_expected.XXXXXX)"
-
- bt_cli "$expected_stdout" "$expected_stderr" "${trace_dir}/succeed/multi-domains" -c sink.text.details --params "with-trace-name=false,with-stream-name=false"
- bt_remove_cr "${expected_stdout}"
- bt_remove_cr "${expected_stderr}"
- run_test "$test_text" "$cli_args_template" "$expected_stdout" \
- "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
- diag "Inverse session order from lttng-relayd"
- run_test "$test_text" "$cli_args_template" "$expected_stdout" \
- "$expected_stderr" "$trace_dir_native" "${server_args_inverse[@]}"
-
- rm -f "$expected_stdout"
- rm -f "$expected_stderr"
-}
-
-test_inactivity_discarded_packet() {
- # Attach and consume data from a multi-packet trace with discarded
- # packets and emit an inactivity beacon during the discarded packets
- # period.
- #
- # | pkt seq:0 |<-------discarded packets------>| pkt seq:8 |
- # 0 20 121 140
- #
- # This test was introduced to cover the following bug:
- #
- # When reading this type of trace locally, the CTF source is expected
- # to introduce a "Discarded packets" message between packets 0 and 8.
- # The timestamps of this message are [pkt0.end_ts, pkt8.begin_ts].
- #
- # In the context of a live source, the tracer could report an inactivity
- # period during the interval of the "Discarded packets" message.
- # Those messages eventually translate into a
- # "Iterator inactivity" message with a timestamp set at the end of the
- # inactivity period.
- #
- # If the tracer reports an inactivity period that ends at a point
- # between pkt0 and pkt7 (resulting in an "Iterator inactivity" message),
- # the live source could send a "Discarded packets" message that starts
- # before the preceding "Iterator inactivity" message. This would break
- # the monotonicity constraint of the graph.
- local test_text="CLI attach and fetch from single-domains session - inactivity discarded packet"
- local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/7_lost_between_2_with_index -c sink.text.details"
- local server_args=("$test_data_dir/inactivity_discarded_packet.json")
- local expected_stdout="$test_data_dir/inactivity_discarded_packet.expect"
- local expected_stderr="/dev/null"
-
- run_test "$test_text" "$cli_args_template" "$expected_stdout" \
- "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
-}
-
-test_split_metadata() {
- # Consume a metadata stream sent in two parts. This testcase tests the
- # behaviour of Babeltrace when the tracing session was cleared (lttng
- # clear) but the metadata is not yet available to the relay. In such
- # cases, when asked for metadata, the relay will return the
- # `LTTNG_VIEWER_METADATA_OK` status and a data length of 0. The viewer
- # need to consider such case as a request to retry fetching metadata.
- #
- # This testcase emulates such behaviour by adding empty metadata
- # packets.
-
- local test_text="CLI attach and fetch from single-domain session - Receive metadata in two sections separated by a empty section"
- local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/split_metadata -c sink.text.details"
- local server_args=("$test_data_dir/split_metadata.json")
- local expected_stdout="${test_data_dir}/split_metadata.expect"
- local expected_stderr="/dev/null"
-
- run_test "$test_text" "$cli_args_template" "$expected_stdout" \
- "$expected_stderr" "$trace_dir_native" "${server_args[@]}"
-}
-
-test_stored_values() {
- # Split metadata, where the new metadata requires additional stored
- # value slots in CTF message iterators.
- local test_text="split metadata requiring additionnal stored values"
- local cli_args_template="-i lttng-live net://localhost:@PORT@/host/hostname/stored_values -c sink.text.details"
- local server_args=("$test_data_dir/stored_values.json")
- local expected_stdout="${test_data_dir}/stored_values.expect"
- local expected_stderr="/dev/null"
- local tmp_dir
-
- tmp_dir=$(mktemp -d -t 'test_stored_value.XXXXXXX')
-
- # Generate test trace.
- gen_mctf_trace "${trace_dir}/live/stored_values.mctf" "$tmp_dir/stored_values"
-
- run_test "$test_text" "$cli_args_template" "$expected_stdout" \
- "$expected_stderr" "$tmp_dir" "${server_args[@]}"
-
- rm -rf "$tmp_dir"
-}
-
-plan_tests 18
-
-test_list_sessions
-test_base
-test_multi_domains
-test_rate_limited
-test_compare_to_ctf_fs
-test_inactivity_discarded_packet
-test_split_metadata
-test_stored_values
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
+#
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+export PYTHON_PLUGIN_PROVIDER_TEST_PLUGIN_PATH="${BT_TESTS_SRCDIR}/python-plugin-provider/bt_plugin_test_python_plugin_provider.py"
+
+run_python_bt2_test \
+ "${BT_TESTS_SRCDIR}/python-plugin-provider" \
+ test_python_plugin_provider.py
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
-#
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-export PYTHON_PLUGIN_PROVIDER_TEST_PLUGIN_PATH="${BT_TESTS_SRCDIR}/python-plugin-provider/bt_plugin_test_python_plugin_provider.py"
-
-run_python_bt2_test \
- "${BT_TESTS_SRCDIR}/python-plugin-provider" \
- test_python_plugin_provider.py
EXTRA_DIST = python
dist_check_SCRIPTS = \
- run_python_bt2 \
+ run-python-bt2.sh \
tap-driver.sh \
utils.sh
--- /dev/null
+#!/bin/bash
+#
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
+# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
+#
+
+# Execute a shell command in the appropriate environment to have access to the
+# bt2 Python bindings. For example, one could use it to run a specific Python
+# binding test case with:
+#
+# $ tests/utils/run_python_bt2 python3 ./tests/utils/python/testrunner.py \
+# -t test_value.MapValueTestCase.test_deepcopy \
+# ./tests/bindings/python/bt2
+
+if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
+ UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
+else
+ UTILSSH="$(dirname "$0")/../utils/utils.sh"
+fi
+
+# shellcheck source=../utils/utils.sh
+source "$UTILSSH"
+
+usage() {
+ echo "Usage: run_python_bt2 [PYTHON_BIN] ..."
+ echo ""
+ echo "Run a binary with the python environment set to use the 'bt2' module"
+ echo "from the build system prior to installation."
+ echo ""
+ echo "When building out of tree export the BT_TESTS_BUILDDIR variable with"
+ echo "the path to the built 'tests' directory."
+}
+
+if [ -z "$*" ]; then
+ usage
+ exit 1
+fi
+
+# Sanity check that the BT_TESTS_BUILDDIR value makes sense.
+if [ ! -f "$BT_TESTS_BUILDDIR/Makefile" ]; then
+ fold -w 80 -s <<- END
+ $0: BT_TESTS_BUILDDIR does not point to a valid directory (\`$BT_TESTS_BUILDDIR/Makefile\` does not exist).
+
+ If building out-of-tree, set BT_TESTS_BUILDDIR to point to the \`tests\` directory in the build tree.
+ END
+ exit 1
+fi
+
+run_python_bt2 "${@}"
+++ /dev/null
-#!/bin/bash
-#
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# Copyright (C) 2017 Philippe Proulx <pproulx@efficios.com>
-# Copyright (C) 2019 Simon Marchi <simon.marchi@efficios.com>
-#
-
-# Execute a shell command in the appropriate environment to have access to the
-# bt2 Python bindings. For example, one could use it to run a specific Python
-# binding test case with:
-#
-# $ tests/utils/run_python_bt2 python3 ./tests/utils/python/testrunner.py \
-# -t test_value.MapValueTestCase.test_deepcopy \
-# ./tests/bindings/python/bt2
-
-if [ -n "${BT_TESTS_SRCDIR:-}" ]; then
- UTILSSH="$BT_TESTS_SRCDIR/utils/utils.sh"
-else
- UTILSSH="$(dirname "$0")/../utils/utils.sh"
-fi
-
-# shellcheck source=../utils/utils.sh
-source "$UTILSSH"
-
-usage() {
- echo "Usage: run_python_bt2 [PYTHON_BIN] ..."
- echo ""
- echo "Run a binary with the python environment set to use the 'bt2' module"
- echo "from the build system prior to installation."
- echo ""
- echo "When building out of tree export the BT_TESTS_BUILDDIR variable with"
- echo "the path to the built 'tests' directory."
-}
-
-if [ -z "$*" ]; then
- usage
- exit 1
-fi
-
-# Sanity check that the BT_TESTS_BUILDDIR value makes sense.
-if [ ! -f "$BT_TESTS_BUILDDIR/Makefile" ]; then
- fold -w 80 -s <<- END
- $0: BT_TESTS_BUILDDIR does not point to a valid directory (\`$BT_TESTS_BUILDDIR/Makefile\` does not exist).
-
- If building out-of-tree, set BT_TESTS_BUILDDIR to point to the \`tests\` directory in the build tree.
- END
- exit 1
-fi
-
-run_python_bt2 "${@}"
local ret_stdout
local ret_stderr
- temp_stdout_output_file="$(mktemp -t actual_stdout.XXXXXX)"
- temp_stderr_output_file="$(mktemp -t actual_stderr.XXXXXX)"
+ temp_stdout_output_file="$(mktemp -t actual-stdout.XXXXXX)"
+ temp_stderr_output_file="$(mktemp -t actual-stderr.XXXXXX)"
# Run the CLI to get a detailed file.
bt_cli "$temp_stdout_output_file" "$temp_stderr_output_file" "${args[@]}"