From: Philippe Proulx Date: Sun, 29 Oct 2023 16:32:11 +0000 (-0400) Subject: tests: normalize names of files and more X-Git-Url: http://git.efficios.com/?p=babeltrace.git;a=commitdiff_plain;h=7132b8384f798e2d9d00fee07bba3a56b4ace039 tests: normalize names of files and more The current naming situation is somewhat of a mess in the `tests` directory, making it difficult to deduce (or write) a convention. Use hyphens to separate words as much as possible, following what we usually like for source file names (see `tree src`). Pretty much the only things remaining with underscores are Python file names because of the `import` constraints and because it's Python's own convention. Also make all shell scripts have the `.sh` extension. This makes any worthy editor highlight the shell syntax correctly and tells you immediately it's not a compiled ("binary") executable. I'd prefer `.bash` for Bash code, but I don't think we need to go as far. Signed-off-by: Philippe Proulx Change-Id: I43cd279d78c240a7e3686ad8afd6759bad9f575f Reviewed-on: https://review.lttng.org/c/babeltrace/+/11170 Tested-by: jenkins Reviewed-by: Simon Marchi CI-Build: Simon Marchi --- diff --git a/.gitignore b/.gitignore index 70a284b2..c63fcaf0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,18 +1,18 @@ -/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 diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc index 5435ff6e..23808c04 100644 --- a/CONTRIBUTING.adoc +++ b/CONTRIBUTING.adoc @@ -1491,7 +1491,7 @@ tests to run in, so nothing more is needed. 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 @@ -1500,15 +1500,16 @@ want to run tests. ---- $ 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 <> which needs to know the +`run-python-bt2.sh` uses <> 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: @@ -1517,10 +1518,10 @@ $ export BT_TESTS_BUILDDIR=/path/to/build/babeltrace/tests ---- 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 @@ -1566,13 +1567,13 @@ To run all the `bt2` Python package tests: * 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' ---- @@ -1582,7 +1583,7 @@ To run **all the tests** in a test module (for example, * 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 ---- @@ -1592,7 +1593,7 @@ To run a **specific test case** (for example, `RealValueTestCase` within * 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 ---- @@ -1602,7 +1603,7 @@ To run a **specific test** (for example, * 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 ---- diff --git a/tests/Makefile.am b/tests/Makefile.am index 844baa25..baed64e6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -13,6 +13,7 @@ EXTRA_DIST = $(srcdir)/data \ 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 \ @@ -30,7 +31,6 @@ dist_check_SCRIPTS = \ 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 \ @@ -38,134 +38,134 @@ dist_check_SCRIPTS = \ 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)' \ diff --git a/tests/bindings/python/bt2/test-python-bt2.sh b/tests/bindings/python/bt2/test-python-bt2.sh new file mode 100755 index 00000000..a32362f3 --- /dev/null +++ b/tests/bindings/python/bt2/test-python-bt2.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2017 Philippe Proulx +# + +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_*" diff --git a/tests/bindings/python/bt2/test_python_bt2 b/tests/bindings/python/bt2/test_python_bt2 deleted file mode 100755 index a32362f3..00000000 --- a/tests/bindings/python/bt2/test_python_bt2 +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2017 Philippe Proulx -# - -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_*" diff --git a/tests/bitfield/Makefile.am b/tests/bitfield/Makefile.am index 42cbc284..f9f3d9e5 100644 --- a/tests/bitfield/Makefile.am +++ b/tests/bitfield/Makefile.am @@ -2,9 +2,9 @@ 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 diff --git a/tests/bitfield/test-bitfield.c b/tests/bitfield/test-bitfield.c new file mode 100644 index 00000000..f0b44821 --- /dev/null +++ b/tests/bitfield/test-bitfield.c @@ -0,0 +1,754 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2010-2019 Mathieu Desnoyers + * + * BabelTrace - bitfield test program + */ + +#include "compat/bitfield.h" +#include +#include +#include + +#include + +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(); +} diff --git a/tests/bitfield/test_bitfield.c b/tests/bitfield/test_bitfield.c deleted file mode 100644 index f0b44821..00000000 --- a/tests/bitfield/test_bitfield.c +++ /dev/null @@ -1,754 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (C) 2010-2019 Mathieu Desnoyers - * - * BabelTrace - bitfield test program - */ - -#include "compat/bitfield.h" -#include -#include -#include - -#include - -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(); -} diff --git a/tests/cli/convert/test-auto-source-discovery-grouping.sh b/tests/cli/convert/test-auto-source-discovery-grouping.sh new file mode 100755 index 00000000..e476c96c --- /dev/null +++ b/tests/cli/convert/test-auto-source-discovery-grouping.sh @@ -0,0 +1,46 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Simon Marchi +# + +# 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" diff --git a/tests/cli/convert/test-auto-source-discovery-log-level.sh b/tests/cli/convert/test-auto-source-discovery-log-level.sh new file mode 100755 index 00000000..56df66fa --- /dev/null +++ b/tests/cli/convert/test-auto-source-discovery-log-level.sh @@ -0,0 +1,146 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Simon Marchi +# + +# 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" < "$expected_file" < "$expected_file" < "$expected_file" < +# + +# 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" < "$expected_file" < "$expected_file" < "$expected_file" < +# + +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}" diff --git a/tests/cli/convert/test_auto_source_discovery_grouping b/tests/cli/convert/test_auto_source_discovery_grouping deleted file mode 100755 index e476c96c..00000000 --- a/tests/cli/convert/test_auto_source_discovery_grouping +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Simon Marchi -# - -# 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" diff --git a/tests/cli/convert/test_auto_source_discovery_log_level b/tests/cli/convert/test_auto_source_discovery_log_level deleted file mode 100755 index 56df66fa..00000000 --- a/tests/cli/convert/test_auto_source_discovery_log_level +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Simon Marchi -# - -# 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" < "$expected_file" < "$expected_file" < "$expected_file" < -# - -# 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" < "$expected_file" < "$expected_file" < "$expected_file" < -# - -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}" diff --git a/tests/cli/list-plugins/test-list-plugins.sh b/tests/cli/list-plugins/test-list-plugins.sh new file mode 100755 index 00000000..a0720ace --- /dev/null +++ b/tests/cli/list-plugins/test-list-plugins.sh @@ -0,0 +1,66 @@ +#!/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}" diff --git a/tests/cli/list-plugins/test_list_plugins b/tests/cli/list-plugins/test_list_plugins deleted file mode 100755 index 595eb4db..00000000 --- a/tests/cli/list-plugins/test_list_plugins +++ /dev/null @@ -1,66 +0,0 @@ -#!/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}" diff --git a/tests/cli/params/test-params.sh b/tests/cli/params/test-params.sh new file mode 100755 index 00000000..22ef5401 --- /dev/null +++ b/tests/cli/params/test-params.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Simon Marchi +# + +# 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" diff --git a/tests/cli/params/test_params b/tests/cli/params/test_params deleted file mode 100755 index 22ef5401..00000000 --- a/tests/cli/params/test_params +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Simon Marchi -# - -# 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" diff --git a/tests/cli/query/test-query.sh b/tests/cli/query/test-query.sh new file mode 100755 index 00000000..170749ab --- /dev/null +++ b/tests/cli/query/test-query.sh @@ -0,0 +1,91 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Simon Marchi +# + +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" diff --git a/tests/cli/query/test_query b/tests/cli/query/test_query deleted file mode 100755 index e44d6777..00000000 --- a/tests/cli/query/test_query +++ /dev/null @@ -1,91 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Simon Marchi -# - -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" diff --git a/tests/cli/test-exit-status.sh b/tests/cli/test-exit-status.sh new file mode 100755 index 00000000..adfce3c3 --- /dev/null +++ b/tests/cli/test-exit-status.sh @@ -0,0 +1,92 @@ +#!/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 diff --git a/tests/cli/test-help.sh b/tests/cli/test-help.sh new file mode 100755 index 00000000..dabd0c2b --- /dev/null +++ b/tests/cli/test-help.sh @@ -0,0 +1,101 @@ +#!/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}" diff --git a/tests/cli/test-intersection.sh b/tests/cli/test-intersection.sh new file mode 100755 index 00000000..32a63d58 --- /dev/null +++ b/tests/cli/test-intersection.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2015 Julien Desfossez +# + +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}" diff --git a/tests/cli/test-output-ctf-metadata.sh b/tests/cli/test-output-ctf-metadata.sh new file mode 100755 index 00000000..f85fc053 --- /dev/null +++ b/tests/cli/test-output-ctf-metadata.sh @@ -0,0 +1,36 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Simon Marchi +# + +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" diff --git a/tests/cli/test-output-path-ctf-non-lttng-trace.sh b/tests/cli/test-output-path-ctf-non-lttng-trace.sh new file mode 100755 index 00000000..d589dbe1 --- /dev/null +++ b/tests/cli/test-output-path-ctf-non-lttng-trace.sh @@ -0,0 +1,54 @@ +#!/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}" diff --git a/tests/cli/test-packet-seq-num.sh b/tests/cli/test-packet-seq-num.sh new file mode 100755 index 00000000..89a830e5 --- /dev/null +++ b/tests/cli/test-packet-seq-num.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2015 Julien Desfossez +# + +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" diff --git a/tests/cli/test-trace-copy.sh b/tests/cli/test-trace-copy.sh new file mode 100755 index 00000000..e8c9b2c8 --- /dev/null +++ b/tests/cli/test-trace-copy.sh @@ -0,0 +1,81 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2017 Julien Desfossez +# + +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 diff --git a/tests/cli/test-trace-read.sh b/tests/cli/test-trace-read.sh new file mode 100755 index 00000000..474015e0 --- /dev/null +++ b/tests/cli/test-trace-read.sh @@ -0,0 +1,39 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2013 Christian Babeux +# + +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 diff --git a/tests/cli/test-trimmer.sh b/tests/cli/test-trimmer.sh new file mode 100755 index 00000000..4b415b47 --- /dev/null +++ b/tests/cli/test-trimmer.sh @@ -0,0 +1,209 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2017 Julien Desfossez +# + +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}" diff --git a/tests/cli/test_exit_status b/tests/cli/test_exit_status deleted file mode 100755 index 905a2eb3..00000000 --- a/tests/cli/test_exit_status +++ /dev/null @@ -1,92 +0,0 @@ -#!/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 diff --git a/tests/cli/test_help b/tests/cli/test_help deleted file mode 100755 index dca6cfe5..00000000 --- a/tests/cli/test_help +++ /dev/null @@ -1,101 +0,0 @@ -#!/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}" diff --git a/tests/cli/test_intersection b/tests/cli/test_intersection deleted file mode 100755 index df0f6504..00000000 --- a/tests/cli/test_intersection +++ /dev/null @@ -1,84 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2015 Julien Desfossez -# - -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}" diff --git a/tests/cli/test_output_ctf_metadata b/tests/cli/test_output_ctf_metadata deleted file mode 100755 index 8296506b..00000000 --- a/tests/cli/test_output_ctf_metadata +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Simon Marchi -# - -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" diff --git a/tests/cli/test_output_path_ctf_non_lttng_trace b/tests/cli/test_output_path_ctf_non_lttng_trace deleted file mode 100755 index fc0158bf..00000000 --- a/tests/cli/test_output_path_ctf_non_lttng_trace +++ /dev/null @@ -1,54 +0,0 @@ -#!/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}" diff --git a/tests/cli/test_packet_seq_num b/tests/cli/test_packet_seq_num deleted file mode 100755 index 341a9c26..00000000 --- a/tests/cli/test_packet_seq_num +++ /dev/null @@ -1,69 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2015 Julien Desfossez -# - -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" diff --git a/tests/cli/test_trace_copy b/tests/cli/test_trace_copy deleted file mode 100755 index e8c9b2c8..00000000 --- a/tests/cli/test_trace_copy +++ /dev/null @@ -1,81 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2017 Julien Desfossez -# - -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 diff --git a/tests/cli/test_trace_read b/tests/cli/test_trace_read deleted file mode 100755 index 474015e0..00000000 --- a/tests/cli/test_trace_read +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2013 Christian Babeux -# - -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 diff --git a/tests/cli/test_trimmer b/tests/cli/test_trimmer deleted file mode 100755 index 4b415b47..00000000 --- a/tests/cli/test_trimmer +++ /dev/null @@ -1,209 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2017 Julien Desfossez -# - -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}" diff --git a/tests/ctf-writer/Makefile.am b/tests/ctf-writer/Makefile.am index c6c3ebab..807f54db 100644 --- a/tests/ctf-writer/Makefile.am +++ b/tests/ctf-writer/Makefile.am @@ -2,9 +2,9 @@ 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 \ @@ -13,4 +13,4 @@ ctf_writer_LDADD = \ $(top_builddir)/src/logging/liblogging.la -dist_check_SCRIPTS = test_ctf_writer +dist_check_SCRIPTS = test-ctf-writer.sh diff --git a/tests/ctf-writer/ctf-writer.c b/tests/ctf-writer/ctf-writer.c new file mode 100644 index 00000000..0b979ace --- /dev/null +++ b/tests/ctf-writer/ctf-writer.c @@ -0,0 +1,2067 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2013-2017 Jérémie Galarneau + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "compat/stdlib.h" +#include +#include "compat/limits.h" +#include "compat/stdio.h" +#include +#include "common/assert.h" +#include "common/uuid.h" +#include +#include "tap/tap.h" +#include +#include +#include "common.h" + +#ifdef __FreeBSD__ +/* Required for WIFEXITED and WEXITSTATUS */ +#include +#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(); +} diff --git a/tests/ctf-writer/ctf_writer.c b/tests/ctf-writer/ctf_writer.c deleted file mode 100644 index 0b979ace..00000000 --- a/tests/ctf-writer/ctf_writer.c +++ /dev/null @@ -1,2067 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (C) 2013-2017 Jérémie Galarneau - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "compat/stdlib.h" -#include -#include "compat/limits.h" -#include "compat/stdio.h" -#include -#include "common/assert.h" -#include "common/uuid.h" -#include -#include "tap/tap.h" -#include -#include -#include "common.h" - -#ifdef __FreeBSD__ -/* Required for WIFEXITED and WEXITSTATUS */ -#include -#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(); -} diff --git a/tests/ctf-writer/test-ctf-writer.sh b/tests/ctf-writer/test-ctf-writer.sh new file mode 100755 index 00000000..38a41927 --- /dev/null +++ b/tests/ctf-writer/test-ctf-writer.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2013 Jérémie Galarneau +# + +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" diff --git a/tests/ctf-writer/test_ctf_writer b/tests/ctf-writer/test_ctf_writer deleted file mode 100755 index 7616b691..00000000 --- a/tests/ctf-writer/test_ctf_writer +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2013 Jérémie Galarneau -# - -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" diff --git a/tests/data/cli/exit-status/bt_plugin_test_cli_exit_status.py b/tests/data/cli/exit-status/bt_plugin_test_cli_exit_status.py new file mode 100644 index 00000000..37f48baf --- /dev/null +++ b/tests/data/cli/exit-status/bt_plugin_test_cli_exit_status.py @@ -0,0 +1,48 @@ +# 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"]}) diff --git a/tests/data/cli/exit_status/bt_plugin_test_cli_exit_status.py b/tests/data/cli/exit_status/bt_plugin_test_cli_exit_status.py deleted file mode 100644 index 327d052b..00000000 --- a/tests/data/cli/exit_status/bt_plugin_test_cli_exit_status.py +++ /dev/null @@ -1,48 +0,0 @@ -# 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"]}) diff --git a/tests/data/cli/test-output-ctf-metadata.ref b/tests/data/cli/test-output-ctf-metadata.ref new file mode 100644 index 00000000..01dbf3f0 --- /dev/null +++ b/tests/data/cli/test-output-ctf-metadata.ref @@ -0,0 +1,111 @@ +/* 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 { + 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 { + 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; + }; +}; + + diff --git a/tests/data/cli/test_output_ctf_metadata.ref b/tests/data/cli/test_output_ctf_metadata.ref deleted file mode 100644 index 01dbf3f0..00000000 --- a/tests/data/cli/test_output_ctf_metadata.ref +++ /dev/null @@ -1,111 +0,0 @@ -/* 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 { - 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 { - 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; - }; -}; - - diff --git a/tests/data/ctf-traces/live/split-metadata/channel0_0 b/tests/data/ctf-traces/live/split-metadata/channel0_0 new file mode 100644 index 00000000..c8e9ddbe Binary files /dev/null and b/tests/data/ctf-traces/live/split-metadata/channel0_0 differ diff --git a/tests/data/ctf-traces/live/split-metadata/index/channel0_0.idx b/tests/data/ctf-traces/live/split-metadata/index/channel0_0.idx new file mode 100644 index 00000000..399ec45a Binary files /dev/null and b/tests/data/ctf-traces/live/split-metadata/index/channel0_0.idx differ diff --git a/tests/data/ctf-traces/live/split-metadata/metadata b/tests/data/ctf-traces/live/split-metadata/metadata new file mode 100644 index 00000000..b61a4e1c --- /dev/null +++ b/tests/data/ctf-traces/live/split-metadata/metadata @@ -0,0 +1,119 @@ +/* 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 { + 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 { + 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 { + }; +}; diff --git a/tests/data/ctf-traces/live/split_metadata/channel0_0 b/tests/data/ctf-traces/live/split_metadata/channel0_0 deleted file mode 100644 index c8e9ddbe..00000000 Binary files a/tests/data/ctf-traces/live/split_metadata/channel0_0 and /dev/null differ diff --git a/tests/data/ctf-traces/live/split_metadata/index/channel0_0.idx b/tests/data/ctf-traces/live/split_metadata/index/channel0_0.idx deleted file mode 100644 index 399ec45a..00000000 Binary files a/tests/data/ctf-traces/live/split_metadata/index/channel0_0.idx and /dev/null differ diff --git a/tests/data/ctf-traces/live/split_metadata/metadata b/tests/data/ctf-traces/live/split_metadata/metadata deleted file mode 100644 index b61a4e1c..00000000 --- a/tests/data/ctf-traces/live/split_metadata/metadata +++ /dev/null @@ -1,119 +0,0 @@ -/* 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 { - 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 { - 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 { - }; -}; diff --git a/tests/data/ctf-traces/live/stored-values.mctf b/tests/data/ctf-traces/live/stored-values.mctf new file mode 100644 index 00000000..0f617f7c --- /dev/null +++ b/tests/data/ctf-traces/live/stored-values.mctf @@ -0,0 +1,92 @@ +--- 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) + + [ 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 + +{ p1_ts = 10 } +{ p2_ts = 20 } + + +m:packet(p1_ts, 1) + + + +m:packet(p2_ts, 2) + + +--- 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) diff --git a/tests/data/ctf-traces/live/stored_values.mctf b/tests/data/ctf-traces/live/stored_values.mctf deleted file mode 100644 index 0f617f7c..00000000 --- a/tests/data/ctf-traces/live/stored_values.mctf +++ /dev/null @@ -1,92 +0,0 @@ ---- 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) - - [ 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 - -{ p1_ts = 10 } -{ p2_ts = 20 } - - -m:packet(p1_ts, 1) - - - -m:packet(p2_ts, 2) - - ---- 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) diff --git a/tests/data/ctf-traces/packet-seq-num/2-lost-before-last/metadata b/tests/data/ctf-traces/packet-seq-num/2-lost-before-last/metadata new file mode 100644 index 00000000..36e26cdf --- /dev/null +++ b/tests/data/ctf-traces/packet-seq-num/2-lost-before-last/metadata @@ -0,0 +1,58 @@ +/* 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); +}; + diff --git a/tests/data/ctf-traces/packet-seq-num/2-lost-before-last/test_stream_0 b/tests/data/ctf-traces/packet-seq-num/2-lost-before-last/test_stream_0 new file mode 100644 index 00000000..50d36a46 Binary files /dev/null and b/tests/data/ctf-traces/packet-seq-num/2-lost-before-last/test_stream_0 differ diff --git a/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-1/metadata b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-1/metadata new file mode 100644 index 00000000..525405e2 --- /dev/null +++ b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-1/metadata @@ -0,0 +1,58 @@ +/* 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); +}; + diff --git a/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-1/test_stream_0 b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-1/test_stream_0 new file mode 100644 index 00000000..1b362cd4 Binary files /dev/null and b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-1/test_stream_0 differ diff --git a/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-1/test_stream_1 b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-1/test_stream_1 new file mode 100644 index 00000000..d5114d90 Binary files /dev/null and b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-1/test_stream_1 differ diff --git a/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-2/metadata b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-2/metadata new file mode 100644 index 00000000..680d9103 --- /dev/null +++ b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-2/metadata @@ -0,0 +1,58 @@ +/* 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); +}; + diff --git a/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-2/test_stream_0 b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-2/test_stream_0 new file mode 100644 index 00000000..b0beb6b4 Binary files /dev/null and b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-2/test_stream_0 differ diff --git a/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-2/test_stream_1 b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-2/test_stream_1 new file mode 100644 index 00000000..1ad83201 Binary files /dev/null and b/tests/data/ctf-traces/packet-seq-num/2-streams-lost-in-2/test_stream_1 differ diff --git a/tests/data/ctf-traces/packet-seq-num/7-lost-between-2-with-index/index/stream_0.idx b/tests/data/ctf-traces/packet-seq-num/7-lost-between-2-with-index/index/stream_0.idx new file mode 100644 index 00000000..e06d92fb Binary files /dev/null and b/tests/data/ctf-traces/packet-seq-num/7-lost-between-2-with-index/index/stream_0.idx differ diff --git a/tests/data/ctf-traces/packet-seq-num/7-lost-between-2-with-index/metadata b/tests/data/ctf-traces/packet-seq-num/7-lost-between-2-with-index/metadata new file mode 100644 index 00000000..37a30308 --- /dev/null +++ b/tests/data/ctf-traces/packet-seq-num/7-lost-between-2-with-index/metadata @@ -0,0 +1,48 @@ +/* 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; +}; + diff --git a/tests/data/ctf-traces/packet-seq-num/7-lost-between-2-with-index/stream_0 b/tests/data/ctf-traces/packet-seq-num/7-lost-between-2-with-index/stream_0 new file mode 100644 index 00000000..fdfe9e1d Binary files /dev/null and b/tests/data/ctf-traces/packet-seq-num/7-lost-between-2-with-index/stream_0 differ diff --git a/tests/data/ctf-traces/packet-seq-num/no-lost-not-starting-at-0/metadata b/tests/data/ctf-traces/packet-seq-num/no-lost-not-starting-at-0/metadata new file mode 100644 index 00000000..c8f5783d --- /dev/null +++ b/tests/data/ctf-traces/packet-seq-num/no-lost-not-starting-at-0/metadata @@ -0,0 +1,58 @@ +/* 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); +}; + diff --git a/tests/data/ctf-traces/packet-seq-num/no-lost-not-starting-at-0/test_stream_0 b/tests/data/ctf-traces/packet-seq-num/no-lost-not-starting-at-0/test_stream_0 new file mode 100644 index 00000000..f9639a3a Binary files /dev/null and b/tests/data/ctf-traces/packet-seq-num/no-lost-not-starting-at-0/test_stream_0 differ diff --git a/tests/data/ctf-traces/packet-seq-num/no-lost/metadata b/tests/data/ctf-traces/packet-seq-num/no-lost/metadata new file mode 100644 index 00000000..d562061a --- /dev/null +++ b/tests/data/ctf-traces/packet-seq-num/no-lost/metadata @@ -0,0 +1,58 @@ +/* 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); +}; + diff --git a/tests/data/ctf-traces/packet-seq-num/no-lost/test_stream_0 b/tests/data/ctf-traces/packet-seq-num/no-lost/test_stream_0 new file mode 100644 index 00000000..15821fb1 Binary files /dev/null and b/tests/data/ctf-traces/packet-seq-num/no-lost/test_stream_0 differ diff --git a/tests/data/ctf-traces/packet_seq_num/2_lost_before_last/metadata b/tests/data/ctf-traces/packet_seq_num/2_lost_before_last/metadata deleted file mode 100644 index 36e26cdf..00000000 --- a/tests/data/ctf-traces/packet_seq_num/2_lost_before_last/metadata +++ /dev/null @@ -1,58 +0,0 @@ -/* 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); -}; - diff --git a/tests/data/ctf-traces/packet_seq_num/2_lost_before_last/test_stream_0 b/tests/data/ctf-traces/packet_seq_num/2_lost_before_last/test_stream_0 deleted file mode 100644 index 50d36a46..00000000 Binary files a/tests/data/ctf-traces/packet_seq_num/2_lost_before_last/test_stream_0 and /dev/null differ diff --git a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_1/metadata b/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_1/metadata deleted file mode 100644 index 525405e2..00000000 --- a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_1/metadata +++ /dev/null @@ -1,58 +0,0 @@ -/* 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); -}; - diff --git a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_1/test_stream_0 b/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_1/test_stream_0 deleted file mode 100644 index 1b362cd4..00000000 Binary files a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_1/test_stream_0 and /dev/null differ diff --git a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_1/test_stream_1 b/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_1/test_stream_1 deleted file mode 100644 index d5114d90..00000000 Binary files a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_1/test_stream_1 and /dev/null differ diff --git a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_2/metadata b/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_2/metadata deleted file mode 100644 index 680d9103..00000000 --- a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_2/metadata +++ /dev/null @@ -1,58 +0,0 @@ -/* 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); -}; - diff --git a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_2/test_stream_0 b/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_2/test_stream_0 deleted file mode 100644 index b0beb6b4..00000000 Binary files a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_2/test_stream_0 and /dev/null differ diff --git a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_2/test_stream_1 b/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_2/test_stream_1 deleted file mode 100644 index 1ad83201..00000000 Binary files a/tests/data/ctf-traces/packet_seq_num/2_streams_lost_in_2/test_stream_1 and /dev/null differ diff --git a/tests/data/ctf-traces/packet_seq_num/7_lost_between_2_with_index/index/stream_0.idx b/tests/data/ctf-traces/packet_seq_num/7_lost_between_2_with_index/index/stream_0.idx deleted file mode 100644 index e06d92fb..00000000 Binary files a/tests/data/ctf-traces/packet_seq_num/7_lost_between_2_with_index/index/stream_0.idx and /dev/null differ diff --git a/tests/data/ctf-traces/packet_seq_num/7_lost_between_2_with_index/metadata b/tests/data/ctf-traces/packet_seq_num/7_lost_between_2_with_index/metadata deleted file mode 100644 index 37a30308..00000000 --- a/tests/data/ctf-traces/packet_seq_num/7_lost_between_2_with_index/metadata +++ /dev/null @@ -1,48 +0,0 @@ -/* 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; -}; - diff --git a/tests/data/ctf-traces/packet_seq_num/7_lost_between_2_with_index/stream_0 b/tests/data/ctf-traces/packet_seq_num/7_lost_between_2_with_index/stream_0 deleted file mode 100644 index fdfe9e1d..00000000 Binary files a/tests/data/ctf-traces/packet_seq_num/7_lost_between_2_with_index/stream_0 and /dev/null differ diff --git a/tests/data/ctf-traces/packet_seq_num/no_lost/metadata b/tests/data/ctf-traces/packet_seq_num/no_lost/metadata deleted file mode 100644 index d562061a..00000000 --- a/tests/data/ctf-traces/packet_seq_num/no_lost/metadata +++ /dev/null @@ -1,58 +0,0 @@ -/* 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); -}; - diff --git a/tests/data/ctf-traces/packet_seq_num/no_lost/test_stream_0 b/tests/data/ctf-traces/packet_seq_num/no_lost/test_stream_0 deleted file mode 100644 index 15821fb1..00000000 Binary files a/tests/data/ctf-traces/packet_seq_num/no_lost/test_stream_0 and /dev/null differ diff --git a/tests/data/ctf-traces/packet_seq_num/no_lost_not_starting_at_0/metadata b/tests/data/ctf-traces/packet_seq_num/no_lost_not_starting_at_0/metadata deleted file mode 100644 index c8f5783d..00000000 --- a/tests/data/ctf-traces/packet_seq_num/no_lost_not_starting_at_0/metadata +++ /dev/null @@ -1,58 +0,0 @@ -/* 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); -}; - diff --git a/tests/data/ctf-traces/packet_seq_num/no_lost_not_starting_at_0/test_stream_0 b/tests/data/ctf-traces/packet_seq_num/no_lost_not_starting_at_0/test_stream_0 deleted file mode 100644 index f9639a3a..00000000 Binary files a/tests/data/ctf-traces/packet_seq_num/no_lost_not_starting_at_0/test_stream_0 and /dev/null differ diff --git a/tests/data/ctf-traces/succeed/debug-info/channel0_0 b/tests/data/ctf-traces/succeed/debug-info/channel0_0 index 35b979b2..1186c4bc 100644 Binary files a/tests/data/ctf-traces/succeed/debug-info/channel0_0 and b/tests/data/ctf-traces/succeed/debug-info/channel0_0 differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/Makefile b/tests/data/plugins/flt.lttng-utils.debug-info/Makefile index 28208052..d51a7231 100644 --- a/tests/data/plugins/flt.lttng-utils.debug-info/Makefile +++ b/tests/data/plugins/flt.lttng-utils.debug-info/Makefile @@ -4,10 +4,10 @@ BUILD_ID=$(BUILD_ID_PREFIX)$(BUILD_ID_SUFFIX) 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) @@ -15,30 +15,30 @@ 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: diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/README.md b/tests/data/plugins/flt.lttng-utils.debug-info/README.md index 6d20c5cb..177ba572 100644 --- a/tests/data/plugins/flt.lttng-utils.debug-info/README.md +++ b/tests/data/plugins/flt.lttng-utils.debug-info/README.md @@ -8,12 +8,12 @@ files used to generate them. 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 @@ -40,28 +40,28 @@ To regenerate them, you can use the included Makefile or follow these steps: $ 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 @@ -72,25 +72,25 @@ to do the debug-info resolution. You can generate such trace by following these 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 @@ -100,9 +100,9 @@ steps: 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" } diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/bt_plugin_test_debug_info.py b/tests/data/plugins/flt.lttng-utils.debug-info/bt_plugin_test_debug_info.py index efbdb8e3..295e674e 100644 --- a/tests/data/plugins/flt.lttng-utils.debug-info/bt_plugin_test_debug_info.py +++ b/tests/data/plugins/flt.lttng-utils.debug-info/bt_plugin_test_debug_info.py @@ -7,7 +7,7 @@ import math import bt2 -bt2.register_plugin(__name__, "test_debug_info") +bt2.register_plugin(__name__, "test-debug-info") class CompleteIter(bt2._UserMessageIterator): diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug new file mode 100755 index 00000000..ba371f5d Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build-id/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build-id/libhello-so new file mode 100755 index 00000000..218e6685 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build-id/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug deleted file mode 100755 index ba371f5d..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build_id/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build_id/libhello_so deleted file mode 100755 index 218e6685..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/build_id/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug-link/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug-link/libhello-so new file mode 100755 index 00000000..2b76ed5a Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug-link/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug-link/libhello-so.debug b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug-link/libhello-so.debug new file mode 100755 index 00000000..1ede7704 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug-link/libhello-so.debug differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug_link/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug_link/libhello_so deleted file mode 100755 index 4dcfdc50..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug_link/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug_link/libhello_so.debug b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug_link/libhello_so.debug deleted file mode 100755 index 1ede7704..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/debug_link/libhello_so.debug and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/dwarf-full/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/dwarf-full/libhello-so new file mode 100755 index 00000000..08390c8f Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/dwarf-full/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/dwarf_full/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/dwarf_full/libhello_so deleted file mode 100755 index 08390c8f..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/dwarf_full/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/elf-only/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/elf-only/libhello-so new file mode 100755 index 00000000..84c31e25 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/elf-only/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/elf_only/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/elf_only/libhello_so deleted file mode 100755 index 84c31e25..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/i386-linux-gnu/elf_only/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug new file mode 100755 index 00000000..6fa14992 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build-id/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build-id/libhello-so new file mode 100755 index 00000000..49c62499 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build-id/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug deleted file mode 100755 index 6fa14992..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build_id/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build_id/libhello_so deleted file mode 100755 index 49c62499..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/build_id/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug-link/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug-link/libhello-so new file mode 100755 index 00000000..b3ac626c Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug-link/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug-link/libhello-so.debug b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug-link/libhello-so.debug new file mode 100755 index 00000000..a95eed28 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug-link/libhello-so.debug differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug_link/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug_link/libhello_so deleted file mode 100755 index 23efdc8b..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug_link/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug_link/libhello_so.debug b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug_link/libhello_so.debug deleted file mode 100755 index a95eed28..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/debug_link/libhello_so.debug and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/dwarf-full/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/dwarf-full/libhello-so new file mode 100755 index 00000000..ef39d51e Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/dwarf-full/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/dwarf_full/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/dwarf_full/libhello_so deleted file mode 100755 index ef39d51e..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/dwarf_full/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/elf-only/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/elf-only/libhello-so new file mode 100755 index 00000000..d1e7322b Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/elf-only/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/elf_only/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/elf_only/libhello_so deleted file mode 100755 index d1e7322b..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc-linux-gnu/elf_only/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug new file mode 100755 index 00000000..b419832f Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build-id/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build-id/libhello-so new file mode 100755 index 00000000..f740eb0c Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build-id/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug deleted file mode 100755 index b419832f..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build_id/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build_id/libhello_so deleted file mode 100755 index f740eb0c..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/build_id/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug-link/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug-link/libhello-so new file mode 100755 index 00000000..1d08451e Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug-link/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug-link/libhello-so.debug b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug-link/libhello-so.debug new file mode 100755 index 00000000..86364a3b Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug-link/libhello-so.debug differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug_link/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug_link/libhello_so deleted file mode 100755 index 01e0c6b4..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug_link/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug_link/libhello_so.debug b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug_link/libhello_so.debug deleted file mode 100755 index 86364a3b..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/debug_link/libhello_so.debug and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/dwarf-full/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/dwarf-full/libhello-so new file mode 100755 index 00000000..3874f118 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/dwarf-full/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/dwarf_full/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/dwarf_full/libhello_so deleted file mode 100755 index 3874f118..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/dwarf_full/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/elf-only/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/elf-only/libhello-so new file mode 100755 index 00000000..067b4720 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/elf-only/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/elf_only/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/elf_only/libhello_so deleted file mode 100755 index 067b4720..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/powerpc64le-linux-gnu/elf_only/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/trace-debug-info.expect b/tests/data/plugins/flt.lttng-utils.debug-info/trace-debug-info.expect index 047ef8f9..e800e9c4 100644 --- a/tests/data/plugins/flt.lttng-utils.debug-info/trace-debug-info.expect +++ b/tests/data/plugins/flt.lttng-utils.debug-info/trace-debug-info.expect @@ -89,7 +89,7 @@ Event `lttng_ust_statedump:bin_info` (Class ID 0): 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 @@ -101,7 +101,7 @@ Event `my_provider:my_first_tracepoint` (Class ID 1): vpid: 9746 ip: 0x7f09:b7f9:a349 debug_info: - bin: libhello_so+0x2349 + bin: libhello-so+0x2349 func: foo+0xd2 src: libhello.c:35 Payload: @@ -115,7 +115,7 @@ Event `my_provider:my_first_tracepoint` (Class ID 1): vpid: 9746 ip: 0x7f09:b7f9:a448 debug_info: - bin: libhello_so+0x2448 + bin: libhello-so+0x2448 func: bar+0xd2 src: libhello.c:41 Payload: diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug new file mode 100755 index 00000000..41e2cfb0 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/build-id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/build-id/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/build-id/libhello-so new file mode 100755 index 00000000..0edfd79b Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/build-id/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/debug-link/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/debug-link/libhello-so new file mode 100755 index 00000000..d3cd3425 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/debug-link/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/debug-link/libhello-so.debug b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/debug-link/libhello-so.debug new file mode 100755 index 00000000..082f5136 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/debug-link/libhello-so.debug differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/dwarf-full/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/dwarf-full/libhello-so new file mode 100755 index 00000000..f8d3e411 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/dwarf-full/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/elf-only/libhello-so b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/elf-only/libhello-so new file mode 100755 index 00000000..bffdaab7 Binary files /dev/null and b/tests/data/plugins/flt.lttng-utils.debug-info/x86-64-linux-gnu/elf-only/libhello-so differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug b/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug deleted file mode 100755 index 41e2cfb0..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/build_id/.build-id/cd/d98cdd87f7fe64c13b6daad553987eafd40cbb.debug and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/build_id/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/build_id/libhello_so deleted file mode 100755 index 0edfd79b..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/build_id/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/debug_link/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/debug_link/libhello_so deleted file mode 100755 index 0c126010..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/debug_link/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/debug_link/libhello_so.debug b/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/debug_link/libhello_so.debug deleted file mode 100755 index 082f5136..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/debug_link/libhello_so.debug and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/dwarf_full/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/dwarf_full/libhello_so deleted file mode 100755 index f8d3e411..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/dwarf_full/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/elf_only/libhello_so b/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/elf_only/libhello_so deleted file mode 100755 index bffdaab7..00000000 Binary files a/tests/data/plugins/flt.lttng-utils.debug-info/x86_64-linux-gnu/elf_only/libhello_so and /dev/null differ diff --git a/tests/data/plugins/flt.utils.muxer/bt_plugin_muxer_test.py b/tests/data/plugins/flt.utils.muxer/bt_plugin_muxer_test.py index 8ac1f1b7..eaf2c9d9 100644 --- a/tests/data/plugins/flt.utils.muxer/bt_plugin_muxer_test.py +++ b/tests/data/plugins/flt.utils.muxer/bt_plugin_muxer_test.py @@ -432,18 +432,18 @@ class DiffInactivityMsgCs: 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") diff --git a/tests/data/plugins/flt.utils.muxer/succeed/basic-timestamp-ordering.expect b/tests/data/plugins/flt.utils.muxer/succeed/basic-timestamp-ordering.expect new file mode 100644 index 00000000..e0cb89a9 --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/basic-timestamp-ordering.expect @@ -0,0 +1,29 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/basic_timestamp_ordering.expect b/tests/data/plugins/flt.utils.muxer/succeed/basic_timestamp_ordering.expect deleted file mode 100644 index e0cb89a9..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/basic_timestamp_ordering.expect +++ /dev/null @@ -1,29 +0,0 @@ -[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff-event-class-id.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff-event-class-id.expect new file mode 100644 index 00000000..bff55c9b --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/diff-event-class-id.expect @@ -0,0 +1,27 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff-event-class-name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff-event-class-name.expect new file mode 100644 index 00000000..3ea13407 --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/diff-event-class-name.expect @@ -0,0 +1,27 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff-inactivity-msg-cs.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff-inactivity-msg-cs.expect new file mode 100644 index 00000000..c018a3e6 --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/diff-inactivity-msg-cs.expect @@ -0,0 +1,19 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-class-id.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-class-id.expect new file mode 100644 index 00000000..b96f250e --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-class-id.expect @@ -0,0 +1,19 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-class-name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-class-name.expect new file mode 100644 index 00000000..6e8e8577 --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-class-name.expect @@ -0,0 +1,21 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-class-no-name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-class-no-name.expect new file mode 100644 index 00000000..b87875d5 --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-class-no-name.expect @@ -0,0 +1,20 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-id.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-id.expect new file mode 100644 index 00000000..46a69812 --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-id.expect @@ -0,0 +1,19 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-name.expect new file mode 100644 index 00000000..86c025c6 --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-name.expect @@ -0,0 +1,21 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-no-name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-no-name.expect new file mode 100644 index 00000000..6e9e43df --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/diff-stream-no-name.expect @@ -0,0 +1,20 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff-trace-name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff-trace-name.expect new file mode 100644 index 00000000..128ac958 --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/diff-trace-name.expect @@ -0,0 +1,19 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff_event_class_id.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff_event_class_id.expect deleted file mode 100644 index bff55c9b..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/diff_event_class_id.expect +++ /dev/null @@ -1,27 +0,0 @@ -[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff_event_class_name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff_event_class_name.expect deleted file mode 100644 index 3ea13407..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/diff_event_class_name.expect +++ /dev/null @@ -1,27 +0,0 @@ -[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff_inactivity_msg_cs.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff_inactivity_msg_cs.expect deleted file mode 100644 index c018a3e6..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/diff_inactivity_msg_cs.expect +++ /dev/null @@ -1,19 +0,0 @@ -[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_class_id.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_class_id.expect deleted file mode 100644 index b96f250e..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_class_id.expect +++ /dev/null @@ -1,19 +0,0 @@ -[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_class_name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_class_name.expect deleted file mode 100644 index 6e8e8577..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_class_name.expect +++ /dev/null @@ -1,21 +0,0 @@ -[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_class_no_name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_class_no_name.expect deleted file mode 100644 index b87875d5..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_class_no_name.expect +++ /dev/null @@ -1,20 +0,0 @@ -[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_id.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_id.expect deleted file mode 100644 index 46a69812..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_id.expect +++ /dev/null @@ -1,19 +0,0 @@ -[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_name.expect deleted file mode 100644 index 86c025c6..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_name.expect +++ /dev/null @@ -1,21 +0,0 @@ -[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_no_name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_no_name.expect deleted file mode 100644 index 6e9e43df..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/diff_stream_no_name.expect +++ /dev/null @@ -1,20 +0,0 @@ -[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/diff_trace_name.expect b/tests/data/plugins/flt.utils.muxer/succeed/diff_trace_name.expect deleted file mode 100644 index 128ac958..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/diff_trace_name.expect +++ /dev/null @@ -1,19 +0,0 @@ -[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/multi-iter-ordering.expect b/tests/data/plugins/flt.utils.muxer/succeed/multi-iter-ordering.expect new file mode 100644 index 00000000..bce10d43 --- /dev/null +++ b/tests/data/plugins/flt.utils.muxer/succeed/multi-iter-ordering.expect @@ -0,0 +1,55 @@ +[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 diff --git a/tests/data/plugins/flt.utils.muxer/succeed/multi_iter_ordering.expect b/tests/data/plugins/flt.utils.muxer/succeed/multi_iter_ordering.expect deleted file mode 100644 index bce10d43..00000000 --- a/tests/data/plugins/flt.utils.muxer/succeed/multi_iter_ordering.expect +++ /dev/null @@ -1,55 +0,0 @@ -[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 diff --git a/tests/data/plugins/src.ctf.lttng-live/inactivity-discarded-packet.expect b/tests/data/plugins/src.ctf.lttng-live/inactivity-discarded-packet.expect new file mode 100644 index 00000000..278818d7 --- /dev/null +++ b/tests/data/plugins/src.ctf.lttng-live/inactivity-discarded-packet.expect @@ -0,0 +1,67 @@ +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 diff --git a/tests/data/plugins/src.ctf.lttng-live/inactivity-discarded-packet.json b/tests/data/plugins/src.ctf.lttng-live/inactivity-discarded-packet.json new file mode 100644 index 00000000..bec5dc9f --- /dev/null +++ b/tests/data/plugins/src.ctf.lttng-live/inactivity-discarded-packet.json @@ -0,0 +1,17 @@ +[ + { + "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 ] + } + } + ] + } +] diff --git a/tests/data/plugins/src.ctf.lttng-live/inactivity_discarded_packet.expect b/tests/data/plugins/src.ctf.lttng-live/inactivity_discarded_packet.expect deleted file mode 100644 index 278818d7..00000000 --- a/tests/data/plugins/src.ctf.lttng-live/inactivity_discarded_packet.expect +++ /dev/null @@ -1,67 +0,0 @@ -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 diff --git a/tests/data/plugins/src.ctf.lttng-live/inactivity_discarded_packet.json b/tests/data/plugins/src.ctf.lttng-live/inactivity_discarded_packet.json deleted file mode 100644 index 47f791e7..00000000 --- a/tests/data/plugins/src.ctf.lttng-live/inactivity_discarded_packet.json +++ /dev/null @@ -1,17 +0,0 @@ -[ - { - "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 ] - } - } - ] - } -] diff --git a/tests/data/plugins/src.ctf.lttng-live/list-sessions.json b/tests/data/plugins/src.ctf.lttng-live/list-sessions.json new file mode 100644 index 00000000..0c0091ca --- /dev/null +++ b/tests/data/plugins/src.ctf.lttng-live/list-sessions.json @@ -0,0 +1,38 @@ +[ + { + "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/" + } + ] + } +] diff --git a/tests/data/plugins/src.ctf.lttng-live/list_sessions.json b/tests/data/plugins/src.ctf.lttng-live/list_sessions.json deleted file mode 100644 index 0c0091ca..00000000 --- a/tests/data/plugins/src.ctf.lttng-live/list_sessions.json +++ /dev/null @@ -1,38 +0,0 @@ -[ - { - "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/" - } - ] - } -] diff --git a/tests/data/plugins/src.ctf.lttng-live/multi-domains-inverse.json b/tests/data/plugins/src.ctf.lttng-live/multi-domains-inverse.json new file mode 100644 index 00000000..71755022 --- /dev/null +++ b/tests/data/plugins/src.ctf.lttng-live/multi-domains-inverse.json @@ -0,0 +1,26 @@ +[ + { + "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/" + } + ] + } +] diff --git a/tests/data/plugins/src.ctf.lttng-live/multi-domains.json b/tests/data/plugins/src.ctf.lttng-live/multi-domains.json new file mode 100644 index 00000000..155cacf9 --- /dev/null +++ b/tests/data/plugins/src.ctf.lttng-live/multi-domains.json @@ -0,0 +1,26 @@ +[ + { + "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/" + } + ] + } +] diff --git a/tests/data/plugins/src.ctf.lttng-live/multi_domains.json b/tests/data/plugins/src.ctf.lttng-live/multi_domains.json deleted file mode 100644 index 155cacf9..00000000 --- a/tests/data/plugins/src.ctf.lttng-live/multi_domains.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "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/" - } - ] - } -] diff --git a/tests/data/plugins/src.ctf.lttng-live/multi_domains_inverse.json b/tests/data/plugins/src.ctf.lttng-live/multi_domains_inverse.json deleted file mode 100644 index 71755022..00000000 --- a/tests/data/plugins/src.ctf.lttng-live/multi_domains_inverse.json +++ /dev/null @@ -1,26 +0,0 @@ -[ - { - "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/" - } - ] - } -] diff --git a/tests/data/plugins/src.ctf.lttng-live/rate-limited.json b/tests/data/plugins/src.ctf.lttng-live/rate-limited.json new file mode 100644 index 00000000..d7022b10 --- /dev/null +++ b/tests/data/plugins/src.ctf.lttng-live/rate-limited.json @@ -0,0 +1,14 @@ +[ + { + "name": "trace-with-index", + "id": 0, + "hostname": "hostname", + "live-timer-freq": 1, + "client-count": 0, + "traces": [ + { + "path": "succeed/trace-with-index/" + } + ] + } +] diff --git a/tests/data/plugins/src.ctf.lttng-live/rate_limited.json b/tests/data/plugins/src.ctf.lttng-live/rate_limited.json deleted file mode 100644 index d7022b10..00000000 --- a/tests/data/plugins/src.ctf.lttng-live/rate_limited.json +++ /dev/null @@ -1,14 +0,0 @@ -[ - { - "name": "trace-with-index", - "id": 0, - "hostname": "hostname", - "live-timer-freq": 1, - "client-count": 0, - "traces": [ - { - "path": "succeed/trace-with-index/" - } - ] - } -] diff --git a/tests/data/plugins/src.ctf.lttng-live/split-metadata.expect b/tests/data/plugins/src.ctf.lttng-live/split-metadata.expect new file mode 100644 index 00000000..17b6ccb4 --- /dev/null +++ b/tests/data/plugins/src.ctf.lttng-live/split-metadata.expect @@ -0,0 +1,84 @@ +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 diff --git a/tests/data/plugins/src.ctf.lttng-live/split-metadata.json b/tests/data/plugins/src.ctf.lttng-live/split-metadata.json new file mode 100644 index 00000000..867e94d7 --- /dev/null +++ b/tests/data/plugins/src.ctf.lttng-live/split-metadata.json @@ -0,0 +1,27 @@ +[ + { + "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 + } + ] + } + ] + } +] diff --git a/tests/data/plugins/src.ctf.lttng-live/split_metadata.expect b/tests/data/plugins/src.ctf.lttng-live/split_metadata.expect deleted file mode 100644 index 17b6ccb4..00000000 --- a/tests/data/plugins/src.ctf.lttng-live/split_metadata.expect +++ /dev/null @@ -1,84 +0,0 @@ -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 diff --git a/tests/data/plugins/src.ctf.lttng-live/split_metadata.json b/tests/data/plugins/src.ctf.lttng-live/split_metadata.json deleted file mode 100644 index 9b5edf22..00000000 --- a/tests/data/plugins/src.ctf.lttng-live/split_metadata.json +++ /dev/null @@ -1,27 +0,0 @@ -[ - { - "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 - } - ] - } - ] - } -] diff --git a/tests/data/plugins/src.ctf.lttng-live/stored-values.expect b/tests/data/plugins/src.ctf.lttng-live/stored-values.expect new file mode 100644 index 00000000..6b5004d5 --- /dev/null +++ b/tests/data/plugins/src.ctf.lttng-live/stored-values.expect @@ -0,0 +1,65 @@ +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 diff --git a/tests/data/plugins/src.ctf.lttng-live/stored-values.json b/tests/data/plugins/src.ctf.lttng-live/stored-values.json new file mode 100644 index 00000000..4d41e8f6 --- /dev/null +++ b/tests/data/plugins/src.ctf.lttng-live/stored-values.json @@ -0,0 +1,25 @@ +[ + { + "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 + } + ] + } + ] + } +] diff --git a/tests/data/plugins/src.ctf.lttng-live/stored_values.expect b/tests/data/plugins/src.ctf.lttng-live/stored_values.expect deleted file mode 100644 index 6b5004d5..00000000 --- a/tests/data/plugins/src.ctf.lttng-live/stored_values.expect +++ /dev/null @@ -1,65 +0,0 @@ -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 diff --git a/tests/data/plugins/src.ctf.lttng-live/stored_values.json b/tests/data/plugins/src.ctf.lttng-live/stored_values.json deleted file mode 100644 index 93161686..00000000 --- a/tests/data/plugins/src.ctf.lttng-live/stored_values.json +++ /dev/null @@ -1,25 +0,0 @@ -[ - { - "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 - } - ] - } - ] - } -] diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am index 903d9a2d..f2c70351 100644 --- a/tests/lib/Makefile.am +++ b/tests/lib/Makefile.am @@ -34,22 +34,22 @@ test_remove_destruction_listener_in_destruction_listener_LDADD = \ $(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 @@ -59,7 +59,7 @@ plugin_SOURCES = plugin.c 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 diff --git a/tests/lib/conds/Makefile.am b/tests/lib/conds/Makefile.am index a3934fe2..2527a32c 100644 --- a/tests/lib/conds/Makefile.am +++ b/tests/lib/conds/Makefile.am @@ -14,4 +14,4 @@ conds_triggers_LDADD = \ noinst_PROGRAMS = conds-triggers -dist_check_SCRIPTS = test_conds test.py +dist_check_SCRIPTS = test-conds.sh test.py diff --git a/tests/lib/conds/test-conds.sh b/tests/lib/conds/test-conds.sh new file mode 100755 index 00000000..af66f6d2 --- /dev/null +++ b/tests/lib/conds/test-conds.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2020 Philippe Proulx + +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 diff --git a/tests/lib/conds/test_conds b/tests/lib/conds/test_conds deleted file mode 100755 index af66f6d2..00000000 --- a/tests/lib/conds/test_conds +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2020 Philippe Proulx - -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 diff --git a/tests/lib/test-bt-uuid.c b/tests/lib/test-bt-uuid.c new file mode 100644 index 00000000..8a0b610f --- /dev/null +++ b/tests/lib/test-bt-uuid.c @@ -0,0 +1,182 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2019 Michael Jeanson + */ + +#include +#include + +#include + +#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(); +} diff --git a/tests/lib/test-bt-values.c b/tests/lib/test-bt-values.c new file mode 100644 index 00000000..cc3cbd9f --- /dev/null +++ b/tests/lib/test-bt-values.c @@ -0,0 +1,1168 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation + * Copyright (C) 2015 Philippe Proulx + * + * Babeltrace value objects tests + */ + +#include +#include "common/assert.h" +#include +#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(); +} diff --git a/tests/lib/test-fields-bin.cpp b/tests/lib/test-fields-bin.cpp new file mode 100644 index 00000000..9899f86e --- /dev/null +++ b/tests/lib/test-fields-bin.cpp @@ -0,0 +1,72 @@ +/* + * 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 + +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(); +} diff --git a/tests/lib/test-fields.sh b/tests/lib/test-fields.sh new file mode 100755 index 00000000..166d4b2b --- /dev/null +++ b/tests/lib/test-fields.sh @@ -0,0 +1,17 @@ +#!/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" diff --git a/tests/lib/test-graph-topo.c b/tests/lib/test-graph-topo.c new file mode 100644 index 00000000..0a0f2bc4 --- /dev/null +++ b/tests/lib/test-graph-topo.c @@ -0,0 +1,720 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2017 Philippe Proulx + */ + +#include +#include "common/assert.h" +#include +#include +#include +#include + +#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(); +} diff --git a/tests/lib/test-plugin.sh b/tests/lib/test-plugin.sh new file mode 100755 index 00000000..b9a3fcda --- /dev/null +++ b/tests/lib/test-plugin.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2017 Philippe Proulx +# + +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" diff --git a/tests/lib/test-remove-destruction-listener-in-destruction-listener.c b/tests/lib/test-remove-destruction-listener-in-destruction-listener.c new file mode 100644 index 00000000..a3827ddf --- /dev/null +++ b/tests/lib/test-remove-destruction-listener-in-destruction-listener.c @@ -0,0 +1,275 @@ +/* + * 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 +#include +#include +#include + +#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(); +} diff --git a/tests/lib/test-simple-sink.c b/tests/lib/test-simple-sink.c new file mode 100644 index 00000000..952b6bf5 --- /dev/null +++ b/tests/lib/test-simple-sink.c @@ -0,0 +1,201 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2019 Philippe Proulx + */ + +#include +#include "common/assert.h" +#include +#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(); +} diff --git a/tests/lib/test-trace-ir-ref.c b/tests/lib/test-trace-ir-ref.c new file mode 100644 index 00000000..70caf29c --- /dev/null +++ b/tests/lib/test-trace-ir-ref.c @@ -0,0 +1,583 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2016 Jérémie Galarneau + * + * Trace IR Reference Count test + */ + +#include +#include "tap/tap.h" +#include +#include "lib/object.h" +#include "compat/stdlib.h" +#include "common/assert.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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(); +} diff --git a/tests/lib/test_bt_uuid.c b/tests/lib/test_bt_uuid.c deleted file mode 100644 index 8a0b610f..00000000 --- a/tests/lib/test_bt_uuid.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (C) 2019 Michael Jeanson - */ - -#include -#include - -#include - -#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(); -} diff --git a/tests/lib/test_bt_values.c b/tests/lib/test_bt_values.c deleted file mode 100644 index cc3cbd9f..00000000 --- a/tests/lib/test_bt_values.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation - * Copyright (C) 2015 Philippe Proulx - * - * Babeltrace value objects tests - */ - -#include -#include "common/assert.h" -#include -#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(); -} diff --git a/tests/lib/test_fields b/tests/lib/test_fields deleted file mode 100755 index 577aa886..00000000 --- a/tests/lib/test_fields +++ /dev/null @@ -1,17 +0,0 @@ -#!/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" diff --git a/tests/lib/test_fields_bin.cpp b/tests/lib/test_fields_bin.cpp deleted file mode 100644 index 9899f86e..00000000 --- a/tests/lib/test_fields_bin.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 - -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(); -} diff --git a/tests/lib/test_graph_topo.c b/tests/lib/test_graph_topo.c deleted file mode 100644 index 0a0f2bc4..00000000 --- a/tests/lib/test_graph_topo.c +++ /dev/null @@ -1,720 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (C) 2017 Philippe Proulx - */ - -#include -#include "common/assert.h" -#include -#include -#include -#include - -#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(); -} diff --git a/tests/lib/test_plugin b/tests/lib/test_plugin deleted file mode 100755 index b9a3fcda..00000000 --- a/tests/lib/test_plugin +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2017 Philippe Proulx -# - -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" diff --git a/tests/lib/test_remove_destruction_listener_in_destruction_listener.c b/tests/lib/test_remove_destruction_listener_in_destruction_listener.c deleted file mode 100644 index a3827ddf..00000000 --- a/tests/lib/test_remove_destruction_listener_in_destruction_listener.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * 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 -#include -#include -#include - -#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(); -} diff --git a/tests/lib/test_simple_sink.c b/tests/lib/test_simple_sink.c deleted file mode 100644 index 952b6bf5..00000000 --- a/tests/lib/test_simple_sink.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (C) 2019 Philippe Proulx - */ - -#include -#include "common/assert.h" -#include -#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(); -} diff --git a/tests/lib/test_trace_ir_ref.c b/tests/lib/test_trace_ir_ref.c deleted file mode 100644 index 70caf29c..00000000 --- a/tests/lib/test_trace_ir_ref.c +++ /dev/null @@ -1,583 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (C) 2016 Jérémie Galarneau - * - * Trace IR Reference Count test - */ - -#include -#include "tap/tap.h" -#include -#include "lib/object.h" -#include "compat/stdlib.h" -#include "common/assert.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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(); -} diff --git a/tests/param-validation/Makefile.am b/tests/param-validation/Makefile.am index 5d6419c1..f43a8870 100644 --- a/tests/param-validation/Makefile.am +++ b/tests/param-validation/Makefile.am @@ -2,8 +2,8 @@ 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 \ diff --git a/tests/param-validation/test-param-validation.c b/tests/param-validation/test-param-validation.c new file mode 100644 index 00000000..fa140104 --- /dev/null +++ b/tests/param-validation/test-param-validation.c @@ -0,0 +1,357 @@ +/* + * 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 +#include +#include + +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(); +} diff --git a/tests/param-validation/test_param_validation.c b/tests/param-validation/test_param_validation.c deleted file mode 100644 index fa140104..00000000 --- a/tests/param-validation/test_param_validation.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * 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 -#include -#include - -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(); -} diff --git a/tests/plugins/flt.lttng-utils.debug-info/Makefile.am b/tests/plugins/flt.lttng-utils.debug-info/Makefile.am index 94310191..42687f3b 100644 --- a/tests/plugins/flt.lttng-utils.debug-info/Makefile.am +++ b/tests/plugins/flt.lttng-utils.debug-info/Makefile.am @@ -5,15 +5,15 @@ AM_CPPFLAGS += -I$(top_srcdir)/tests/utils -I$(top_srcdir)/src/plugins 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 = @@ -22,7 +22,7 @@ if !ENABLE_BUILT_IN_PLUGINS 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 \ @@ -31,7 +31,7 @@ test_dwarf_LDADD = \ $(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 \ @@ -41,5 +41,5 @@ test_bin_info_LDADD = \ $(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 diff --git a/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-i386-linux-gnu.sh b/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-i386-linux-gnu.sh new file mode 100755 index 00000000..3411c12e --- /dev/null +++ b/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-i386-linux-gnu.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2015 Antoine Busque +# Copyright (C) 2019 Michael Jeanson +# + +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 diff --git a/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-powerpc-linux-gnu.sh b/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-powerpc-linux-gnu.sh new file mode 100755 index 00000000..d1716afd --- /dev/null +++ b/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-powerpc-linux-gnu.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2015 Antoine Busque +# Copyright (C) 2019 Michael Jeanson +# + +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 diff --git a/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-powerpc64le-linux-gnu.sh b/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-powerpc64le-linux-gnu.sh new file mode 100755 index 00000000..f118b5f8 --- /dev/null +++ b/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-powerpc64le-linux-gnu.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2015 Antoine Busque +# Copyright (C) 2019 Michael Jeanson +# + +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 diff --git a/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-x86-64-linux-gnu.sh b/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-x86-64-linux-gnu.sh new file mode 100755 index 00000000..d3f35b80 --- /dev/null +++ b/tests/plugins/flt.lttng-utils.debug-info/test-bin-info-x86-64-linux-gnu.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2015 Antoine Busque +# Copyright (C) 2019 Michael Jeanson +# + +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 diff --git a/tests/plugins/flt.lttng-utils.debug-info/test-bin-info.c b/tests/plugins/flt.lttng-utils.debug-info/test-bin-info.c new file mode 100644 index 00000000..cfeba59b --- /dev/null +++ b/tests/plugins/flt.lttng-utils.debug-info/test-bin-info.c @@ -0,0 +1,444 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation + * Copyright (C) 2015 Antoine Busque + * Copyright (C) 2019 Michael Jeanson + * + * Babeltrace SO info tests + */ + +#define BT_LOG_OUTPUT_LEVEL BT_LOG_WARNING +#define BT_LOG_TAG "TEST/BIN-INFO" +#include "logging/log.h" + +#include +#include +#include +#include +#include + +#include "common/macros.h" +#include "common/assert.h" +#include + +#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; +} diff --git a/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-i386-linux-gnu.sh b/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-i386-linux-gnu.sh new file mode 100755 index 00000000..fed378e0 --- /dev/null +++ b/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-i386-linux-gnu.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2015 Antoine Busque +# Copyright (C) 2019 Michael Jeanson +# + +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" diff --git a/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-powerpc-linux-gnu.sh b/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-powerpc-linux-gnu.sh new file mode 100755 index 00000000..f2bbc204 --- /dev/null +++ b/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-powerpc-linux-gnu.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2015 Antoine Busque +# Copyright (C) 2019 Michael Jeanson +# + +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" diff --git a/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-powerpc64le-linux-gnu.sh b/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-powerpc64le-linux-gnu.sh new file mode 100755 index 00000000..6bb28723 --- /dev/null +++ b/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-powerpc64le-linux-gnu.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2015 Antoine Busque +# Copyright (C) 2019 Michael Jeanson +# + +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" diff --git a/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-x86-64-linux-gnu.sh b/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-x86-64-linux-gnu.sh new file mode 100755 index 00000000..c030695e --- /dev/null +++ b/tests/plugins/flt.lttng-utils.debug-info/test-dwarf-x86-64-linux-gnu.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2015 Antoine Busque +# Copyright (C) 2019 Michael Jeanson +# + +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/" diff --git a/tests/plugins/flt.lttng-utils.debug-info/test-dwarf.c b/tests/plugins/flt.lttng-utils.debug-info/test-dwarf.c new file mode 100644 index 00000000..b74eabf4 --- /dev/null +++ b/tests/plugins/flt.lttng-utils.debug-info/test-dwarf.c @@ -0,0 +1,153 @@ +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation + * Copyright (C) 2015 Antoine Busque + * + * Babeltrace bt_dwarf (DWARF utilities) tests + */ + +#include +#include +#include +#include +#include +#include +#include +#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(); +} diff --git a/tests/plugins/flt.lttng-utils.debug-info/test-succeed.sh b/tests/plugins/flt.lttng-utils.debug-info/test-succeed.sh new file mode 100755 index 00000000..430bab3a --- /dev/null +++ b/tests/plugins/flt.lttng-utils.debug-info/test-succeed.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Philippe Proulx +# Copyright (C) 2019 Francis Deslauriers +# + +# 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 diff --git a/tests/plugins/flt.lttng-utils.debug-info/test_bin_info.c b/tests/plugins/flt.lttng-utils.debug-info/test_bin_info.c deleted file mode 100644 index a398faeb..00000000 --- a/tests/plugins/flt.lttng-utils.debug-info/test_bin_info.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation - * Copyright (C) 2015 Antoine Busque - * Copyright (C) 2019 Michael Jeanson - * - * Babeltrace SO info tests - */ - -#define BT_LOG_OUTPUT_LEVEL BT_LOG_WARNING -#define BT_LOG_TAG "TEST/BIN-INFO" -#include "logging/log.h" - -#include -#include -#include -#include -#include - -#include "common/macros.h" -#include "common/assert.h" -#include - -#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; -} diff --git a/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_i386-linux-gnu b/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_i386-linux-gnu deleted file mode 100755 index 2703f3e7..00000000 --- a/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_i386-linux-gnu +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2015 Antoine Busque -# Copyright (C) 2019 Michael Jeanson -# - -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 diff --git a/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_powerpc-linux-gnu b/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_powerpc-linux-gnu deleted file mode 100755 index d8f7ab43..00000000 --- a/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_powerpc-linux-gnu +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2015 Antoine Busque -# Copyright (C) 2019 Michael Jeanson -# - -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 diff --git a/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_powerpc64le-linux-gnu b/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_powerpc64le-linux-gnu deleted file mode 100755 index 60407c50..00000000 --- a/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_powerpc64le-linux-gnu +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2015 Antoine Busque -# Copyright (C) 2019 Michael Jeanson -# - -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 diff --git a/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_x86_64-linux-gnu b/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_x86_64-linux-gnu deleted file mode 100755 index d0e59e28..00000000 --- a/tests/plugins/flt.lttng-utils.debug-info/test_bin_info_x86_64-linux-gnu +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2015 Antoine Busque -# Copyright (C) 2019 Michael Jeanson -# - -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 diff --git a/tests/plugins/flt.lttng-utils.debug-info/test_dwarf.c b/tests/plugins/flt.lttng-utils.debug-info/test_dwarf.c deleted file mode 100644 index 99c584fb..00000000 --- a/tests/plugins/flt.lttng-utils.debug-info/test_dwarf.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0-only - * - * Copyright (C) 2015 EfficiOS Inc. and Linux Foundation - * Copyright (C) 2015 Antoine Busque - * - * Babeltrace bt_dwarf (DWARF utilities) tests - */ - -#include -#include -#include -#include -#include -#include -#include -#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(); -} diff --git a/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_i386-linux-gnu b/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_i386-linux-gnu deleted file mode 100755 index 03380c55..00000000 --- a/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_i386-linux-gnu +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2015 Antoine Busque -# Copyright (C) 2019 Michael Jeanson -# - -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" diff --git a/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_powerpc-linux-gnu b/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_powerpc-linux-gnu deleted file mode 100755 index d60e08c5..00000000 --- a/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_powerpc-linux-gnu +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2015 Antoine Busque -# Copyright (C) 2019 Michael Jeanson -# - -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" diff --git a/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_powerpc64le-linux-gnu b/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_powerpc64le-linux-gnu deleted file mode 100755 index 8656272d..00000000 --- a/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_powerpc64le-linux-gnu +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2015 Antoine Busque -# Copyright (C) 2019 Michael Jeanson -# - -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" diff --git a/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_x86_64-linux-gnu b/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_x86_64-linux-gnu deleted file mode 100755 index 8a7a3ebb..00000000 --- a/tests/plugins/flt.lttng-utils.debug-info/test_dwarf_x86_64-linux-gnu +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2015 Antoine Busque -# Copyright (C) 2019 Michael Jeanson -# - -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/" diff --git a/tests/plugins/flt.lttng-utils.debug-info/test_succeed b/tests/plugins/flt.lttng-utils.debug-info/test_succeed deleted file mode 100755 index 1df6fbb2..00000000 --- a/tests/plugins/flt.lttng-utils.debug-info/test_succeed +++ /dev/null @@ -1,113 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Philippe Proulx -# Copyright (C) 2019 Francis Deslauriers -# - -# 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 diff --git a/tests/plugins/flt.utils.muxer/succeed/Makefile.am b/tests/plugins/flt.utils.muxer/succeed/Makefile.am index c550615d..09965988 100644 --- a/tests/plugins/flt.utils.muxer/succeed/Makefile.am +++ b/tests/plugins/flt.utils.muxer/succeed/Makefile.am @@ -1,4 +1,4 @@ # SPDX-License-Identifier: MIT dist_check_SCRIPTS = \ - test_succeed + test-succeed.sh diff --git a/tests/plugins/flt.utils.muxer/succeed/test-succeed.sh b/tests/plugins/flt.utils.muxer/succeed/test-succeed.sh new file mode 100755 index 00000000..dc6af63a --- /dev/null +++ b/tests/plugins/flt.utils.muxer/succeed/test-succeed.sh @@ -0,0 +1,60 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Francis Deslauriers +# + +# 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 diff --git a/tests/plugins/flt.utils.muxer/succeed/test_succeed b/tests/plugins/flt.utils.muxer/succeed/test_succeed deleted file mode 100755 index 578ac223..00000000 --- a/tests/plugins/flt.utils.muxer/succeed/test_succeed +++ /dev/null @@ -1,60 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Francis Deslauriers -# - -# 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 diff --git a/tests/plugins/flt.utils.trimmer/Makefile.am b/tests/plugins/flt.utils.trimmer/Makefile.am index 47803073..5c369a43 100644 --- a/tests/plugins/flt.utils.trimmer/Makefile.am +++ b/tests/plugins/flt.utils.trimmer/Makefile.am @@ -1,4 +1,4 @@ # SPDX-License-Identifier: MIT dist_check_SCRIPTS = \ - test_trimming + test-trimming.sh diff --git a/tests/plugins/flt.utils.trimmer/test-trimming.sh b/tests/plugins/flt.utils.trimmer/test-trimming.sh new file mode 100755 index 00000000..f46fe31f --- /dev/null +++ b/tests/plugins/flt.utils.trimmer/test-trimming.sh @@ -0,0 +1,625 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Simon Marchi +# + +# 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" diff --git a/tests/plugins/flt.utils.trimmer/test_trimming b/tests/plugins/flt.utils.trimmer/test_trimming deleted file mode 100755 index f46fe31f..00000000 --- a/tests/plugins/flt.utils.trimmer/test_trimming +++ /dev/null @@ -1,625 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Simon Marchi -# - -# 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" diff --git a/tests/plugins/sink.ctf.fs/Makefile.am b/tests/plugins/sink.ctf.fs/Makefile.am index fb488d06..557a355e 100644 --- a/tests/plugins/sink.ctf.fs/Makefile.am +++ b/tests/plugins/sink.ctf.fs/Makefile.am @@ -3,5 +3,5 @@ SUBDIRS = succeed dist_check_SCRIPTS = \ - test_assume_single_trace \ - test_stream_names + test-assume-single-trace.sh \ + test-stream-names.sh diff --git a/tests/plugins/sink.ctf.fs/succeed/Makefile.am b/tests/plugins/sink.ctf.fs/succeed/Makefile.am index f8974f62..d1b90390 100644 --- a/tests/plugins/sink.ctf.fs/succeed/Makefile.am +++ b/tests/plugins/sink.ctf.fs/succeed/Makefile.am @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT -dist_check_SCRIPTS = test_succeed +dist_check_SCRIPTS = test-succeed.sh # CTF trace generators GEN_TRACE_LDADD = \ diff --git a/tests/plugins/sink.ctf.fs/succeed/test-succeed.sh b/tests/plugins/sink.ctf.fs/succeed/test-succeed.sh new file mode 100755 index 00000000..6d47c09e --- /dev/null +++ b/tests/plugins/sink.ctf.fs/succeed/test-succeed.sh @@ -0,0 +1,89 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Philippe Proulx +# + +# 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 diff --git a/tests/plugins/sink.ctf.fs/succeed/test_succeed b/tests/plugins/sink.ctf.fs/succeed/test_succeed deleted file mode 100755 index 6d47c09e..00000000 --- a/tests/plugins/sink.ctf.fs/succeed/test_succeed +++ /dev/null @@ -1,89 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Philippe Proulx -# - -# 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 diff --git a/tests/plugins/sink.ctf.fs/test-assume-single-trace.sh b/tests/plugins/sink.ctf.fs/test-assume-single-trace.sh new file mode 100755 index 00000000..69dfb362 --- /dev/null +++ b/tests/plugins/sink.ctf.fs/test-assume-single-trace.sh @@ -0,0 +1,74 @@ +#!/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" diff --git a/tests/plugins/sink.ctf.fs/test-stream-names.sh b/tests/plugins/sink.ctf.fs/test-stream-names.sh new file mode 100755 index 00000000..e5993c7d --- /dev/null +++ b/tests/plugins/sink.ctf.fs/test-stream-names.sh @@ -0,0 +1,89 @@ +#!/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" diff --git a/tests/plugins/sink.ctf.fs/test_assume_single_trace b/tests/plugins/sink.ctf.fs/test_assume_single_trace deleted file mode 100755 index 69dfb362..00000000 --- a/tests/plugins/sink.ctf.fs/test_assume_single_trace +++ /dev/null @@ -1,74 +0,0 @@ -#!/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" diff --git a/tests/plugins/sink.ctf.fs/test_stream_names b/tests/plugins/sink.ctf.fs/test_stream_names deleted file mode 100755 index e5993c7d..00000000 --- a/tests/plugins/sink.ctf.fs/test_stream_names +++ /dev/null @@ -1,89 +0,0 @@ -#!/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" diff --git a/tests/plugins/sink.text.details/succeed/test-succeed.sh b/tests/plugins/sink.text.details/succeed/test-succeed.sh new file mode 100755 index 00000000..9c21155d --- /dev/null +++ b/tests/plugins/sink.text.details/succeed/test-succeed.sh @@ -0,0 +1,61 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Philippe Proulx +# + +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 diff --git a/tests/plugins/sink.text.details/succeed/test_succeed b/tests/plugins/sink.text.details/succeed/test_succeed deleted file mode 100755 index 9c21155d..00000000 --- a/tests/plugins/sink.text.details/succeed/test_succeed +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Philippe Proulx -# - -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 diff --git a/tests/plugins/sink.text.pretty/Makefile.am b/tests/plugins/sink.text.pretty/Makefile.am index 2eb912ff..4760ef5e 100644 --- a/tests/plugins/sink.text.pretty/Makefile.am +++ b/tests/plugins/sink.text.pretty/Makefile.am @@ -1,3 +1,3 @@ dist_check_SCRIPTS = \ - test_pretty_python \ - test_enum + test-pretty-python.sh \ + test-enum.sh diff --git a/tests/plugins/sink.text.pretty/test-enum.sh b/tests/plugins/sink.text.pretty/test-enum.sh new file mode 100755 index 00000000..f91abb5f --- /dev/null +++ b/tests/plugins/sink.text.pretty/test-enum.sh @@ -0,0 +1,267 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2020 Geneviève Bastien +# +# 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 = ( : 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 = ( : 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 = ( : 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 = ( : 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 = ( : 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 = ( : 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 = ( : 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" diff --git a/tests/plugins/sink.text.pretty/test-pretty-python.sh b/tests/plugins/sink.text.pretty/test-pretty-python.sh new file mode 100755 index 00000000..fe395e77 --- /dev/null +++ b/tests/plugins/sink.text.pretty/test-pretty-python.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2017 Philippe Proulx +# + +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_*" diff --git a/tests/plugins/sink.text.pretty/test_enum b/tests/plugins/sink.text.pretty/test_enum deleted file mode 100755 index 1d6b723d..00000000 --- a/tests/plugins/sink.text.pretty/test_enum +++ /dev/null @@ -1,267 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2020 Geneviève Bastien -# -# 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 = ( : 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 = ( : 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 = ( : 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 = ( : 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 = ( : 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 = ( : 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 = ( : 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" diff --git a/tests/plugins/sink.text.pretty/test_pretty_python b/tests/plugins/sink.text.pretty/test_pretty_python deleted file mode 100755 index fe395e77..00000000 --- a/tests/plugins/sink.text.pretty/test_pretty_python +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2017 Philippe Proulx -# - -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_*" diff --git a/tests/plugins/src.ctf.fs/Makefile.am b/tests/plugins/src.ctf.fs/Makefile.am index 745d8e72..02628d3d 100644 --- a/tests/plugins/src.ctf.fs/Makefile.am +++ b/tests/plugins/src.ctf.fs/Makefile.am @@ -3,10 +3,10 @@ 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 diff --git a/tests/plugins/src.ctf.fs/fail/test-fail.sh b/tests/plugins/src.ctf.fs/fail/test-fail.sh new file mode 100755 index 00000000..ee9e9541 --- /dev/null +++ b/tests/plugins/src.ctf.fs/fail/test-fail.sh @@ -0,0 +1,79 @@ +#!/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}" diff --git a/tests/plugins/src.ctf.fs/fail/test_fail b/tests/plugins/src.ctf.fs/fail/test_fail deleted file mode 100755 index 443db0c5..00000000 --- a/tests/plugins/src.ctf.fs/fail/test_fail +++ /dev/null @@ -1,79 +0,0 @@ -#!/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}" diff --git a/tests/plugins/src.ctf.fs/query/test-query-metadata-info.sh b/tests/plugins/src.ctf.fs/query/test-query-metadata-info.sh new file mode 100755 index 00000000..592a8f7d --- /dev/null +++ b/tests/plugins/src.ctf.fs/query/test-query-metadata-info.sh @@ -0,0 +1,85 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Simon Marchi +# Copyright (C) 2019 Francis Deslauriers +# + +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 diff --git a/tests/plugins/src.ctf.fs/query/test-query-support-info.sh b/tests/plugins/src.ctf.fs/query/test-query-support-info.sh new file mode 100755 index 00000000..51044628 --- /dev/null +++ b/tests/plugins/src.ctf.fs/query/test-query-support-info.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Simon Marchi +# + +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 diff --git a/tests/plugins/src.ctf.fs/query/test-query-trace-info.sh b/tests/plugins/src.ctf.fs/query/test-query-trace-info.sh new file mode 100755 index 00000000..49f316bb --- /dev/null +++ b/tests/plugins/src.ctf.fs/query/test-query-trace-info.sh @@ -0,0 +1,17 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Simon Marchi +# + +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 diff --git a/tests/plugins/src.ctf.fs/query/test_query_metadata_info b/tests/plugins/src.ctf.fs/query/test_query_metadata_info deleted file mode 100755 index 0be2f812..00000000 --- a/tests/plugins/src.ctf.fs/query/test_query_metadata_info +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Simon Marchi -# Copyright (C) 2019 Francis Deslauriers -# - -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 diff --git a/tests/plugins/src.ctf.fs/query/test_query_support_info b/tests/plugins/src.ctf.fs/query/test_query_support_info deleted file mode 100755 index 51044628..00000000 --- a/tests/plugins/src.ctf.fs/query/test_query_support_info +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Simon Marchi -# - -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 diff --git a/tests/plugins/src.ctf.fs/query/test_query_trace_info b/tests/plugins/src.ctf.fs/query/test_query_trace_info deleted file mode 100755 index 49f316bb..00000000 --- a/tests/plugins/src.ctf.fs/query/test_query_trace_info +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Simon Marchi -# - -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 diff --git a/tests/plugins/src.ctf.fs/succeed/Makefile.am b/tests/plugins/src.ctf.fs/succeed/Makefile.am index 906dc7a6..fa91418f 100644 --- a/tests/plugins/src.ctf.fs/succeed/Makefile.am +++ b/tests/plugins/src.ctf.fs/succeed/Makefile.am @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MIT -dist_check_SCRIPTS = test_succeed +dist_check_SCRIPTS = test-succeed.sh # CTF trace generators GEN_TRACE_LDADD = \ diff --git a/tests/plugins/src.ctf.fs/succeed/test-succeed.sh b/tests/plugins/src.ctf.fs/succeed/test-succeed.sh new file mode 100755 index 00000000..65596359 --- /dev/null +++ b/tests/plugins/src.ctf.fs/succeed/test-succeed.sh @@ -0,0 +1,141 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Philippe Proulx +# + +# 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 diff --git a/tests/plugins/src.ctf.fs/succeed/test_succeed b/tests/plugins/src.ctf.fs/succeed/test_succeed deleted file mode 100755 index 81d87593..00000000 --- a/tests/plugins/src.ctf.fs/succeed/test_succeed +++ /dev/null @@ -1,141 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Philippe Proulx -# - -# 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 diff --git a/tests/plugins/src.ctf.fs/test-deterministic-ordering.sh b/tests/plugins/src.ctf.fs/test-deterministic-ordering.sh new file mode 100755 index 00000000..a641eb53 --- /dev/null +++ b/tests/plugins/src.ctf.fs/test-deterministic-ordering.sh @@ -0,0 +1,104 @@ +#!/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}" diff --git a/tests/plugins/src.ctf.fs/test_deterministic_ordering b/tests/plugins/src.ctf.fs/test_deterministic_ordering deleted file mode 100755 index 9eb8b8f6..00000000 --- a/tests/plugins/src.ctf.fs/test_deterministic_ordering +++ /dev/null @@ -1,104 +0,0 @@ -#!/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}" diff --git a/tests/plugins/src.ctf.lttng-live/test-live.sh b/tests/plugins/src.ctf.lttng-live/test-live.sh new file mode 100755 index 00000000..ef30ba1d --- /dev/null +++ b/tests/plugins/src.ctf.lttng-live/test-live.sh @@ -0,0 +1,405 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2019 Philippe Proulx +# + +# 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 diff --git a/tests/plugins/src.ctf.lttng-live/test_live b/tests/plugins/src.ctf.lttng-live/test_live deleted file mode 100755 index e9703fbb..00000000 --- a/tests/plugins/src.ctf.lttng-live/test_live +++ /dev/null @@ -1,405 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2019 Philippe Proulx -# - -# 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 diff --git a/tests/python-plugin-provider/test-python-plugin-provider.sh b/tests/python-plugin-provider/test-python-plugin-provider.sh new file mode 100755 index 00000000..542c1748 --- /dev/null +++ b/tests/python-plugin-provider/test-python-plugin-provider.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2017 Philippe Proulx +# + +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 diff --git a/tests/python-plugin-provider/test_python_plugin_provider b/tests/python-plugin-provider/test_python_plugin_provider deleted file mode 100755 index 542c1748..00000000 --- a/tests/python-plugin-provider/test_python_plugin_provider +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2017 Philippe Proulx -# - -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 diff --git a/tests/utils/Makefile.am b/tests/utils/Makefile.am index acfbfec5..4efae05a 100644 --- a/tests/utils/Makefile.am +++ b/tests/utils/Makefile.am @@ -9,6 +9,6 @@ libtestcommon_la_SOURCES = common.c common.h EXTRA_DIST = python dist_check_SCRIPTS = \ - run_python_bt2 \ + run-python-bt2.sh \ tap-driver.sh \ utils.sh diff --git a/tests/utils/run-python-bt2.sh b/tests/utils/run-python-bt2.sh new file mode 100755 index 00000000..574900a2 --- /dev/null +++ b/tests/utils/run-python-bt2.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# SPDX-License-Identifier: GPL-2.0-only +# +# Copyright (C) 2017 Philippe Proulx +# Copyright (C) 2019 Simon Marchi +# + +# 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 "${@}" diff --git a/tests/utils/run_python_bt2 b/tests/utils/run_python_bt2 deleted file mode 100755 index 574900a2..00000000 --- a/tests/utils/run_python_bt2 +++ /dev/null @@ -1,51 +0,0 @@ -#!/bin/bash -# -# SPDX-License-Identifier: GPL-2.0-only -# -# Copyright (C) 2017 Philippe Proulx -# Copyright (C) 2019 Simon Marchi -# - -# 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 "${@}" diff --git a/tests/utils/utils.sh b/tests/utils/utils.sh index 8bf9df89..937b97e9 100644 --- a/tests/utils/utils.sh +++ b/tests/utils/utils.sh @@ -228,8 +228,8 @@ bt_diff_cli() { 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[@]}"